import type { BoberConfig } from "../config/schema.js"; import type { PipelineResult } from "../orchestrator/pipeline.js"; export interface RunProgress { completed: number; total: number; currentSprint?: string; iteration?: number; } export interface RunResult { success: boolean; completedSprints: number; failedSprints: number; duration: number; } export interface RunState { runId: string; task: string; status: "running" | "completed" | "failed" | "aborted" | "input-required" | "paused"; startedAt: string; completedAt?: string; abortedAt?: string; abortReason?: string; progress: RunProgress; result?: RunResult; error?: string; projectRoot: string; specId?: string; /** Sprint 4: when this run was launched via runInWorktree(), the absolute * path of the git worktree the pipeline executed in. Undefined for in-place * runs (the existing bober_run path). */ worktreePath?: string; /** Sprint 4: the git branch the worktree was created on. Undefined for * in-place runs. */ branch?: string; /** Checkpoint id the run is paused at, awaiting human input. */ pendingCheckpointId?: string; /** Human-readable prompt surfaced for the pending checkpoint. */ pendingPrompt?: string; /** ISO timestamp the run entered 'input-required'. */ pendingSince?: string; /** ISO timestamp the run was soft-paused. */ pausedAt?: string; } /** * Optional parameters for startRun(). * All fields are optional for back-compatibility with existing 3-arg callers. */ export interface StartRunOptions { /** Pre-computed runId. When omitted, RunManager generates one with randomUUID(). */ runId?: string; /** When the run is executed inside a git worktree, the absolute path of that worktree. */ worktreePath?: string; /** Branch the worktree was created on. */ branch?: string; } export declare class RunManager { private runs; /** * Check whether ANY pipeline run is currently in 'running' status. * * Back-compat: preserves the existing boolean contract used by * bober_run and all other tool callers. */ isRunning(): boolean; /** * Return the most-recently-started run, or null if no runs exist. * * Back-compat: when only one run exists this is identical to the * old `return this.activeRun` behavior. When multiple runs exist * the most-recently-started one is returned (sorted by startedAt desc). */ getStatus(): RunState | null; /** * Return the RunState for a specific runId, or null if not found. */ getRun(runId: string): RunState | null; /** * Return all runs currently in 'running' status. */ listActiveRuns(): RunState[]; /** * Abort a run by setting its status to 'aborted' with the given reason. * Persists the new state to disk (best-effort; logs on failure). */ abortRun(runId: string, reason: string): void; /** * Return ALL known runs regardless of status. * Used by bober_list_active_runs for status-filtered listing. */ listAllRuns(): RunState[]; /** * Start a new pipeline run as a fire-and-forget promise. * * Does NOT throw when another run is already in progress — concurrent * runs are now supported. Callers that want to enforce one-at-a-time * behavior should check isRunning() themselves (bober_run tool does * this to preserve existing UX). * * Writes the initial state.json synchronously (await) before returning * so disk state is visible immediately after startRun() returns. * * Returns the new runId. * * The optional `pipelineFn` parameter exists for testing only. */ startRun(task: string, projectRoot: string, config: BoberConfig, pipelineFn?: (task: string, projectRoot: string, config: BoberConfig) => Promise, opts?: StartRunOptions): Promise; /** * Load all run state files from .bober/runs/ on startup. * * Populates the in-memory map from disk. Any run with status='running' * is reconciled to status='failed' with error='orchestrator crashed * before completion' — it cannot still be running if the process just * started. * * Skips malformed state.json files with a warn log (does not throw). */ load(projectRoot: string): Promise; } export declare const runManager: RunManager; //# sourceMappingURL=run-manager.d.ts.map