| 107 | } |
| 108 | |
| 109 | function formatEvent(ev: any): string | null { |
| 110 | switch (ev.type) { |
| 111 | case 'node-start': return ` ▶ ${ev.id} started${ev.role ? ` [${ev.role}]` : ''}`; |
| 112 | case 'node-review': return ` ${ev.passed ? '✓' : '✗'} ${ev.id} QA ${ev.passed ? 'passed' : 'failed'}`; |
| 113 | case 'node-commit': return ` ● ${ev.id} committed`; |
| 114 | case 'node-retry': return ` ↻ ${ev.id} retry ${ev.attempt}: ${ev.blockers.slice(0, 2).join('; ')}`; |
| 115 | case 'node-failed': return ` ✗ ${ev.id} failed: ${ev.error}`; |
| 116 | case 'node-blocked': return ` ⊘ ${ev.id} blocked by ${ev.cause}`; |
| 117 | case 'conflict': return ` ⚠ conflict on ${ev.record.file}`; |
| 118 | default: return null; |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | /** Extract design tokens from tailwind config + CSS :root custom properties. */ |
| 123 | async function extractDesignTokens(cwd: string): Promise<string | undefined> { |