// Dependency graph drill-in — layered DAG, critical path in spruce function DepsGraph({ onOpenIssue }) { const DS = window.CommiTeaDesignSystem_20e63b; const { Tag, Icon } = DS; const g = window.CT_DATA.deps; const PAD = 14, COLW = 206, ROWH = 106, NW = 176, NH = 84; const X = (c) => PAD + c * COLW; const Y = (r) => PAD + r * ROWH; const maxCol = g.milestone.col; const maxRow = Math.max(...g.nodes.map((n) => n.row), g.milestone.row); const W = PAD * 2 + maxCol * COLW + NW; const H = PAD * 2 + maxRow * ROWH + NH; const MSW = 158, MSH = 44; const pos = {}; g.nodes.forEach((n) => { pos[n.id] = { x: X(n.col), y: Y(n.row), w: NW, h: NH }; }); pos['ms'] = { x: X(g.milestone.col), y: Y(g.milestone.row) + (NH - MSH) / 2, w: MSW, h: MSH }; const edgePath = (e) => { const a = pos[e.from], b = pos[e.to]; const x1 = a.x + a.w, y1 = a.y + a.h / 2; const x2 = b.x, y2 = b.y + b.h / 2; const dx = Math.max(28, (x2 - x1) / 2); return `M ${x1} ${y1} C ${x1 + dx} ${y1}, ${x2 - dx} ${y2}, ${x2 - 5} ${y2}`; }; const STATES = { done: { icon: 'circle-check', color: 'var(--ok)', label: 'done' }, steeping: { icon: 'clock', color: 'var(--warn)', label: 'steeping' }, review: { icon: 'git-pull-request', color: 'var(--info)', label: 'in review' }, triage: { icon: 'circle-dot', color: 'var(--ink-3)', label: 'triage' }, diagnosis: { icon: 'circle-dashed', color: 'var(--ink-3)', label: 'diagnosis' }, }; const Node = ({ n }) => { const st = STATES[n.state]; const crit = g.critical.includes(n.id); return (
onOpenIssue({ id: n.id, title: n.title, labels: n.tags, rationale: n.rationale, days: n.state === 'steeping' ? n.days : undefined })} style={{ position: 'absolute', left: pos[n.id].x, top: pos[n.id].y, width: NW, height: NH, background: n.state === 'done' ? 'var(--paper-2)' : 'var(--surface-card)', border: `1px solid ${crit ? 'var(--spruce-5)' : 'var(--line-1)'}`, boxShadow: crit ? 'var(--shadow-1), inset 2px 0 0 var(--accent)' : 'var(--shadow-1)', borderRadius: 'var(--radius-2)', padding: '9px 11px', cursor: 'pointer', display: 'flex', flexDirection: 'column', gap: 6, opacity: n.state === 'done' ? 0.72 : 1, transition: 'border-color var(--duration-fast) var(--ease-out)', }} onMouseEnter={(e) => { e.currentTarget.style.borderColor = crit ? 'var(--accent)' : 'var(--line-2)'; }} onMouseLeave={(e) => { e.currentTarget.style.borderColor = crit ? 'var(--spruce-5)' : 'var(--line-1)'; }} >
{n.title}
#{n.id} {st.label}{n.state === 'steeping' && n.days ? ` ${n.days}` : ''} {n.tags.filter((t) => t.startsWith('p/')).map((t) => ( {t} ))}
); }; return (
{/* legend */}
critical path blocks unattached: {g.unattached.map((i) => `#${i}`).join(' · ')}
{/* graph canvas */}
{g.edges.map((e, i) => ( ))} {g.nodes.map((n) => )} {/* milestone terminal */}
{g.milestone.name} due {g.milestone.due}

Four issues sit on the critical path, and #87 is the cork in the bottle. Remove it and everything pours.

); } Object.assign(window, { DepsGraph });