feat(#232): add /agent replan directive#
Problem#
No directive existed to reset a task's full phase state, close any open PR/branch, and restart from refinement. /agent restart was blocked on active tasks; /agent replan is needed for a clean slate restart regardless of task state.
Task / Link#
Closes #232
Changes#
- Add
'replan'toALLOWED_DIRECTIVESindirective.dto.ts - Add
closePR()anddeleteBranch()toGitHubService(404/422 treated as success) - Add
cleanupLabelsForReplan()toPhaseHooksService(removesrefined,in-review,agent-blocked; addsin-refinement) - Implement full
replanhandler inDirectiveService: validates state, closes PR/branch, resets phases, records event, cleans labels, enqueues refine - Wire
replanintoPhaseRouterService:VALID_DIRECTIVES,resolvePhase()(returns'refine'), directive handling block (no active-process rejection) - Update
DirectiveModuleto importGitHubModule,EventModule,PhaseHooksModule
Notes#
- In-flight Claude runs are not force-killed on replan (PIDs not tracked across service boundary). The phase-router's active-phase guard prevents double-execution; old processes time out naturally.
- Replan on already-in-active-refine tasks is a no-op with an explanatory comment.
- Replan on terminal tasks (
succeeded,failed,complete) is rejected with an explanatory comment.
Testing#
- Unit tests added: replan in
DirectiveService(normal path, no-PR path, already-in-refine guard, terminal-state rejection, PR-close failure tolerance) - Unit tests added:
closePRanddeleteBranchinGitHubService(happy path, 404/422 as success, non-404/422 rethrow) - Unit tests added:
resolvePhasewithreplandirective inPhaseRouterService npm run lint— 0 errors, 0 new warningsnpm run test— 661/661 passingnpm run build— clean