import type { Logger } from '../types/logger.js'; import type { TaskNode } from '../types/task-graph.js'; import type { GoalOptions, PhaseExecutionContext, PhaseGraph, PhaseNode, PhaseProgress } from './types.js'; export interface PhaseOrchestratorOptions extends GoalOptions { graph: PhaseGraph; ctx: PhaseExecutionContext; /** Structured logger. Defaults to noOpLogger (silent). */ logger?: Logger | undefined; } /** * PhaseOrchestrator - dependency-aware engine for running phases autonomously. * * Features: * - Automatically starts the next phase as each phase completes in autonomous mode * - Supports parallel phases with parallelizable=true * - Assigns and releases agents * - Integrates with the event bus * - Supports pause and resume */ export declare class PhaseOrchestrator { private graph; private ctx; private opts; private events; private stopped; private paused; private runningPhases; private tickInterval; private trackerCache; private taskRetryCounts; private readonly worktrees?; private readonly logger; /** Per-phase worktree handles, keyed by phase id. */ private readonly phaseWorktrees; /** Serializes all merges back to the base branch (one at a time). */ private mergeQueue; /** Per-phase merge promise, so a phase merges only after its deps do. */ private readonly phaseMergePromise; constructor(opts: PhaseOrchestratorOptions); /** * Start the full phase flow. * In autonomous mode, starts root phases and automatically starts the next phase when they finish. */ start(): Promise; /** * Make a (possibly resumed) graph runnable. A graph loaded from disk after an * interrupted run can carry transient state from the dead process: phases left * `running` and tasks left `in_progress`. The scheduler only starts `pending` * phases (getReadyPhases) and only runs `pending` tasks (getExecutableTasks), * so without this a resumed phase/task would stall forever. Reset that * transient state to `pending`; terminal phases (completed/failed/skipped) and * already-completed tasks are untouched, so completed work is never re-run. * For a freshly built graph this is a no-op. */ private normalizeForResume; /** Wait for all pending phase merges, dependency-ordered and globally serialized. */ private drainMerges; /** Pause: active phases continue, but no new phase starts. */ pause(): void; /** Resume: new phases may start again. */ resume(): void; /** Stop completely, including active phases. */ stop(): void; private tick; private startPhase; /** * Run the verification gate for a phase whose tasks all succeeded. Verifies in * the phase's worktree; on failure, runs the repair pass and re-verifies, up to * `maxVerifyAttempts` repairs. Returns the final verdict. When no `verifyPhase` * callback is wired the gate is a no-op and always passes. */ private runVerifyGate; /** Worktree env (cwd/branch) for a phase, or undefined if it runs on the shared tree. */ private worktreeEnv; /** Shared failure bookkeeping for a phase whose tasks ran but the phase failed. */ private failPhaseAfterTasks; /** * A phase whose tasks all succeeded was marked `completed` and queued for * merge, but the merge back into the base branch failed. Its work is NOT * integrated, so correct the graph: move the phase out of `completedPhaseIds` * into `failedPhaseIds` and flip its status to `failed`. Without this the * persisted graph (and the board) would claim the phase succeeded while a * `phase.failed` event fired — an inconsistency that hides un-merged work. * Idempotent: safe to call more than once for the same phase. */ private markPhaseMergeFailed; /** Trim long verifier output so it fits cleanly in an event/error message. */ private truncate; /** * Commit the phase's worktree changes, then enqueue the merge back into the * base branch. Merges run dependency-ordered (a phase merges only after its * `dependsOn` phases) and globally serialized (one at a time) to avoid * concurrent writes to the base tree. */ private commitAndEnqueueMerge; /** * Squash-merge one phase. When a `resolveConflict` callback is wired, a merge * conflict is handed to it (a resolver subagent) before giving up; only if * that fails does the worktree fall to needs-review and the run continues. */ private mergeOne; private shouldAttemptConflictResolution; private setIntegrationMetadata; /** A failed phase keeps its worktree on disk for inspection (no merge). */ private keepWorktreeForReview; private executePhaseTasks; private executeSingleTask; private markTaskCompleted; private markTaskFailed; private getReadyPhases; private getActivePhases; private getExecutableTasks; private getTrackerForPhase; private getFailedTaskCount; private getCompletedTaskCount; private updatePhaseStatus; private isComplete; private onGraphComplete; private onGraphFailed; getProgress(): PhaseProgress; getGraph(): PhaseGraph; isRunning(): boolean; isPaused(): boolean; assignAgent(phaseId: string, agentId: string): void; releaseAgent(phaseId: string, agentId: string): void; /** Find the phase whose task graph currently holds `taskId`. */ findPhaseOfTask(taskId: string): PhaseNode | undefined; /** * Move a task to another phase's task graph. Edges that referenced the task * are dropped (cross-phase dependencies are not modeled). No-op when the task * or target phase is missing, or it is already in the target phase. */ moveTask(taskId: string, toPhaseId: string): boolean; /** (Re)assign a task to a specific agent (or clear with agentName/agentId omitted). */ setTaskAssignee(taskId: string, agentId?: string, agentName?: string): boolean; /** Add a new task to a phase. Returns the created task id, or null if the phase is missing. */ addTask(phaseId: string, spec: { title: string; description?: string | undefined; type?: TaskNode['type'] | undefined; priority?: TaskNode['priority'] | undefined; }): string | null; /** * Requeue a task to `pending` (clearing its retry counter) and nudge a * terminal/paused phase back to `ready` so the loop re-runs it. Backs both the * board's "retry" and "start" affordances. */ requeueTask(taskId: string): boolean; private emit; private createNoopEventBus; private waitWhilePaused; private delay; } //# sourceMappingURL=phase-orchestrator.d.ts.map