feat: add Orchestrator Loop — phased plan execution with team agents

Adds a new autonomous loop that accepts high-level goals, generates
phased execution plans via AI, and executes them step-by-step with
verification gates between phases.

Core components:
- OrchestratorLoop: state machine (idle→planning→approval→executing→verifying→completed)
- OrchestratorPlanner: plan generation via PlanOrchestrator, Kahn's algorithm phase grouping
- OrchestratorVerifier: phase verification (strict/moderate/lenient modes)
- Prompt templates for phase execution, team delegation, verification, replanning

API (10 endpoints):
- POST start/approve/reject/pause/resume/stop
- GET status/plan
- POST phase/:id/skip, phase/:id/retry

Frontend: orchestrator-panel.js with SSE-driven state, phase progress, task tracking

Tests: 22 tests (18 route + 4 unit), all passing. Typecheck/lint/format clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
arkon
2026-03-21 07:20:18 +01:00
co-authored by Claude Opus 4.6
parent 497ca4891a
commit 61b5ec095c
27 changed files with 4718 additions and 1 deletions
+24
View File
@@ -547,6 +547,30 @@ export class StateStore {
this.save();
}
// ========== Orchestrator Loop State Methods ==========
/** Returns the orchestrator loop state, or null if never initialized. */
getOrchestratorState() {
return this.state.orchestrator ?? null;
}
/** Updates orchestrator loop state (partial merge) and triggers a debounced save. */
setOrchestratorState(orchestrator: Partial<NonNullable<AppState['orchestrator']>>) {
if (this.state.orchestrator) {
this.state.orchestrator = { ...this.state.orchestrator, ...orchestrator };
} else {
// First initialization — caller must provide full state
this.state.orchestrator = orchestrator as NonNullable<AppState['orchestrator']>;
}
this.save();
}
/** Clears orchestrator state and triggers a debounced save. */
clearOrchestratorState() {
this.state.orchestrator = undefined;
this.save();
}
/** Returns the application configuration. */
getConfig() {
return this.state.config;