Task
Enhance builder overview API to include progress percentage, plan phase tracking, and blocked state.
Enhance parseStatusYaml() to also extract:
planPhases: Array<{ id: string; title: string; status: string }> — from plan_phases: YAML blockprotocol: string — already parsed
Enhance BuilderOverview interface with new fields:
exportinterfaceBuilderOverview{// ... existing fields ...protocol: string;planPhases: Array<{id: string;title: string;status: string}>;progress: number;// 0-100 percentageblocked: string|null;// null or gate name: "spec review", "plan review", "PR review"}Add calculateProgress() function:
SPIR has 4 phases: specify → plan → implement → review → complete
phase value | Base % | Sub-progress |
|---|
specify | 0-25% | If gate pending+requested → stuck at 20% |
plan | 25-50% | If gate pending+requested → stuck at 45% |
implement | 50-90% | 50% + (completed_plan_phases / total_plan_phases) × 40% |
review | 90-100% | If gate pending+requested → stuck at 95% |
complete | 100% | Done |
Blocked detection:
- Check each gate: if
status === 'pending' → check if requested_at exists - If requested but not approved → blocked on that gate
- Map gate names:
spec-approval → "spec review", plan-approval → "plan review", pr-ready → "PR review"
Dependencies
Depends on #326 (fix discoverBuilders — needs correct project matching first)
Parent: #323
Task
Enhance builder overview API to include progress percentage, plan phase tracking, and blocked state.
Enhance
parseStatusYaml()to also extract:planPhases: Array<{ id: string; title: string; status: string }>— fromplan_phases:YAML blockprotocol: string— already parsedEnhance
BuilderOverviewinterface with new fields:Add
calculateProgress()function:SPIR has 4 phases: specify → plan → implement → review → complete
phasevaluespecifyplanimplementreviewcompleteBlocked detection:
status === 'pending'→ check ifrequested_atexistsspec-approval→ "spec review",plan-approval→ "plan review",pr-ready→ "PR review"Dependencies
Depends on #326 (fix discoverBuilders — needs correct project matching first)