import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; import { ChildProcess } from "node:child_process"; import { watch } from "node:fs"; import { z } from "zod"; import { lock } from "proper-lockfile"; //#region src/server/index.d.ts declare function createServer(): Server; //#endregion //#region src/transports/stdio.d.ts /** * Stdio transport handler for MCP server * Used for command-line and direct integrations */ declare class StdioTransportHandler { private server; private transport; constructor(server: Server); start(): Promise; stop(): Promise; } //#endregion //#region src/schemas/index.d.ts declare const WorkflowInputSchema: z.ZodObject<{ description: z.ZodOptional; required: z.ZodOptional; default: z.ZodOptional; type: z.ZodOptional; options: z.ZodOptional>; }, z.core.$strip>; declare const MatrixEntrySchema: z.ZodRecord; declare const StepCommandMapSchema: z.ZodRecord; declare const StepCommandSchema: z.ZodUnion]>; declare const StrategySchema: z.ZodObject<{ 'fail-fast': z.ZodOptional; matrix: z.ZodOptional>>; }, z.core.$loose>>; }, z.core.$strip>; declare const StepSchema: z.ZodObject<{ name: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>; declare const ServiceDefSchema: z.ZodObject<{ name: z.ZodString; run: z.ZodString; env: z.ZodOptional>>; 'working-directory': z.ZodOptional; 'ready-check': z.ZodOptional>; 'ready-timeout': z.ZodOptional; host: z.ZodOptional; port: z.ZodOptional; 'port-range': z.ZodOptional>; 'service-type': z.ZodOptional>; }, z.core.$strip>; declare const PreBlockSchema: z.ZodObject<{ services: z.ZodOptional>>; 'working-directory': z.ZodOptional; 'ready-check': z.ZodOptional>; 'ready-timeout': z.ZodOptional; host: z.ZodOptional; port: z.ZodOptional; 'port-range': z.ZodOptional>; 'service-type': z.ZodOptional>; }, z.core.$strip>>>; steps: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>; declare const JobHookBlockSchema: z.ZodObject<{ steps: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>; declare const JobSchema: z.ZodObject<{ 'runs-on': z.ZodOptional; needs: z.ZodOptional]>>; extends: z.ZodOptional]>>; description: z.ZodOptional; strategy: z.ZodOptional; matrix: z.ZodOptional>>; }, z.core.$loose>>; }, z.core.$strip>>; steps: z.ZodArray; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; preJob: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; postJob: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; env: z.ZodOptional>>; if: z.ZodOptional; 'system-prompt': z.ZodOptional; context: z.ZodOptional; }, z.core.$strip>; declare const RepairTriageSchema: z.ZodObject<{ description: z.ZodOptional; env: z.ZodOptional>>; if: z.ZodOptional; steps: z.ZodArray; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; 'runs-on': z.ZodOptional; strategy: z.ZodOptional; matrix: z.ZodOptional>>; }, z.core.$loose>>; }, z.core.$strip>>; preJob: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; postJob: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; 'system-prompt': z.ZodOptional; context: z.ZodOptional; }, z.core.$strip>; declare const AgentDecisionTriggerSchema: z.ZodObject<{ steps: z.ZodArray; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>; declare const WorktreeHookSchema: z.ZodObject<{ steps: z.ZodArray; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>; declare const WorktreeConfigSchema: z.ZodObject<{ beforeCreate: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; afterCreate: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; beforeCompleted: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; afterCompleted: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; }, z.core.$strip>; declare const WorkflowKeybindingsSchema: z.ZodObject<{ STOP: z.ZodOptional; }, z.core.$strip>; declare const RunDirectoryEntrySchema: z.ZodObject<{ path: z.ZodString; kind: z.ZodEnum<{ file: "file"; directory: "directory"; }>; description: z.ZodString; 'produced-by': z.ZodOptional>; 'initial-content': z.ZodOptional; }, z.core.$strip>; declare const RunDirectorySchema: z.ZodObject<{ description: z.ZodString; entries: z.ZodArray; description: z.ZodString; 'produced-by': z.ZodOptional>; 'initial-content': z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>; declare const WorkflowSchema: z.ZodObject<{ name: z.ZodOptional; tags: z.ZodOptional>; workspace: z.ZodOptional; runner: z.ZodOptional; 'default-runner': z.ZodOptional; imports: z.ZodOptional>; 'system-prompt': z.ZodOptional; 'max-workflows': z.ZodOptional; 'launch-command': z.ZodOptional; launcher: z.ZodOptional>; keybindings: z.ZodOptional; }, z.core.$strip>>; 'run-directory': z.ZodOptional; description: z.ZodString; 'produced-by': z.ZodOptional>; 'initial-content': z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; on: z.ZodOptional; required: z.ZodOptional; default: z.ZodOptional; type: z.ZodOptional; options: z.ZodOptional>; }, z.core.$strip>>>; }, z.core.$strip>>>; agent_decision: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; }, z.core.$loose>>; env: z.ZodOptional>>; pre: z.ZodOptional>>; 'working-directory': z.ZodOptional; 'ready-check': z.ZodOptional>; 'ready-timeout': z.ZodOptional; host: z.ZodOptional; port: z.ZodOptional; 'port-range': z.ZodOptional>; 'service-type': z.ZodOptional>; }, z.core.$strip>>>; steps: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; post: z.ZodOptional>>; 'working-directory': z.ZodOptional; 'ready-check': z.ZodOptional>; 'ready-timeout': z.ZodOptional; host: z.ZodOptional; port: z.ZodOptional; 'port-range': z.ZodOptional>; 'service-type': z.ZodOptional>; }, z.core.$strip>>>; steps: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; repair: z.ZodOptional; env: z.ZodOptional>>; if: z.ZodOptional; steps: z.ZodArray; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; 'runs-on': z.ZodOptional; strategy: z.ZodOptional; matrix: z.ZodOptional>>; }, z.core.$loose>>; }, z.core.$strip>>; preJob: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; postJob: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; 'system-prompt': z.ZodOptional; context: z.ZodOptional; }, z.core.$strip>>; worktree: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; afterCreate: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; beforeCompleted: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; afterCompleted: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; }, z.core.$strip>>; jobs: z.ZodRecord; needs: z.ZodOptional]>>; extends: z.ZodOptional]>>; description: z.ZodOptional; strategy: z.ZodOptional; matrix: z.ZodOptional>>; }, z.core.$loose>>; }, z.core.$strip>>; steps: z.ZodArray; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>; preJob: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; postJob: z.ZodOptional; uses: z.ZodOptional; run: z.ZodOptional]>>; interactiveRun: z.ZodOptional]>>; artifacts: z.ZodOptional>; 'timeout-minutes': z.ZodOptional; env: z.ZodOptional>>; with: z.ZodOptional>; 'working-directory': z.ZodOptional; if: z.ZodOptional; 'continue-on-error': z.ZodOptional; 'timeout-retries': z.ZodOptional; 'pause-policy': z.ZodOptional>; id: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; env: z.ZodOptional>>; if: z.ZodOptional; 'system-prompt': z.ZodOptional; context: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>; declare const WorkflowStageSchema: z.ZodEnum<{ error: "error"; running: "running"; completed: "completed"; }>; declare const WorkflowOutcomeSchema: z.ZodEnum<{ success: "success"; skipped: "skipped"; failed: "failed"; interrupted: "interrupted"; }>; /** * One line of the run progress log. * * Append-only NDJSON in the run directory, because a run is a detached process * and anything held in its memory is invisible to every other process and lost * on crash. A reader can tail this to know which job and step a run is on, * which the run record cannot express: it carries only a stage. */ declare const WorkflowExecutionStateSchema: z.ZodEnum<{ running: "running"; pause_requested: "pause_requested"; paused: "paused"; resume_requested: "resume_requested"; }>; declare const WorkflowResumeModeSchema: z.ZodEnum<{ "replay-current": "replay-current"; "continue-next": "continue-next"; }>; declare const WorkflowExecutionCursorSchema: z.ZodObject<{ attempt: z.ZodOptional; executionGeneration: z.ZodNumber; revision: z.ZodOptional; job: z.ZodOptional; matrixIndex: z.ZodOptional; phase: z.ZodString; requestId: z.ZodOptional; resumeMode: z.ZodEnum<{ "replay-current": "replay-current"; "continue-next": "continue-next"; }>; stepIndex: z.ZodOptional; stepName: z.ZodOptional; }, z.core.$strip>; declare const WorkflowProgressEventSchema: z.ZodObject<{ at: z.ZodString; index: z.ZodOptional; job: z.ZodString; reason: z.ZodOptional; status: z.ZodEnum<{ running: "running"; completed: "completed"; skipped: "skipped"; failed: "failed"; pause_requested: "pause_requested"; paused: "paused"; resumed: "resumed"; }>; step: z.ZodOptional; total: z.ZodOptional; type: z.ZodEnum<{ job: "job"; step: "step"; }>; }, z.core.$strip>; declare const WorkflowRepairStatusSchema: z.ZodEnum<{ pending: "pending"; active: "active"; resolved: "resolved"; superseded: "superseded"; rejected: "rejected"; }>; declare const WorkflowRepairJobStatusSchema: z.ZodEnum<{ running: "running"; completed: "completed"; skipped: "skipped"; failed: "failed"; interrupted: "interrupted"; pending: "pending"; }>; declare const WorkflowRepairJobAttemptSchema: z.ZodObject<{ attempt: z.ZodNumber; finishedAt: z.ZodOptional; startedAt: z.ZodString; status: z.ZodEnum<{ running: "running"; completed: "completed"; failed: "failed"; interrupted: "interrupted"; }>; workflowRunId: z.ZodOptional; }, z.core.$strip>; declare const WorkflowRepairJobSchema: z.ZodObject<{ attempts: z.ZodArray; startedAt: z.ZodString; status: z.ZodEnum<{ running: "running"; completed: "completed"; failed: "failed"; interrupted: "interrupted"; }>; workflowRunId: z.ZodOptional; }, z.core.$strip>>; jobName: z.ZodString; status: z.ZodEnum<{ running: "running"; completed: "completed"; skipped: "skipped"; failed: "failed"; interrupted: "interrupted"; pending: "pending"; }>; }, z.core.$strip>; declare const WorkflowRepairRoutingFallbackSchema: z.ZodObject<{ reason: z.ZodEnum<{ unknown: "unknown"; missing: "missing"; }>; requestedTarget: z.ZodOptional; resolvedTarget: z.ZodString; }, z.core.$strip>; declare const WorkflowRepairRecordSchema: z.ZodObject<{ createdAt: z.ZodString; fixCycle: z.ZodNumber; issueFile: z.ZodString; jobs: z.ZodArray; startedAt: z.ZodString; status: z.ZodEnum<{ running: "running"; completed: "completed"; failed: "failed"; interrupted: "interrupted"; }>; workflowRunId: z.ZodOptional; }, z.core.$strip>>; jobName: z.ZodString; status: z.ZodEnum<{ running: "running"; completed: "completed"; skipped: "skipped"; failed: "failed"; interrupted: "interrupted"; pending: "pending"; }>; }, z.core.$strip>>; rejectedAt: z.ZodOptional; repairId: z.ZodString; resolvedAt: z.ZodOptional; restartFrom: z.ZodString; routingFallback: z.ZodOptional; requestedTarget: z.ZodOptional; resolvedTarget: z.ZodString; }, z.core.$strip>>; schemaVersion: z.ZodLiteral<1>; scopeJobs: z.ZodArray; status: z.ZodEnum<{ pending: "pending"; active: "active"; resolved: "resolved"; superseded: "superseded"; rejected: "rejected"; }>; supersededAt: z.ZodOptional; supersededBy: z.ZodOptional; updatedAt: z.ZodString; verificationJob: z.ZodString; }, z.core.$strip>; declare const WorkflowLauncherMetadataSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{ originSurfaceId: z.ZodOptional; originWorkspaceId: z.ZodOptional; surfaceId: z.ZodOptional; type: z.ZodLiteral<"cmux">; workspaceId: z.ZodString; }, z.core.$strip>, z.ZodObject<{ originPaneId: z.ZodOptional; originSessionId: z.ZodOptional; originSurfaceId: z.ZodOptional; originWorkspaceId: z.ZodOptional; paneId: z.ZodOptional; sessionId: z.ZodOptional; sessionName: z.ZodString; type: z.ZodLiteral<"tmux">; windowId: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ pid: z.ZodOptional; type: z.ZodLiteral<"native">; }, z.core.$strip>], "type">; declare const WorkflowRunRecordSchema: z.ZodObject<{ activeRepairId: z.ZodOptional; cliAgent: z.ZodOptional; continueOnError: z.ZodOptional; displayName: z.ZodString; dryRun: z.ZodBoolean; env: z.ZodOptional>; executionCursor: z.ZodOptional; executionGeneration: z.ZodNumber; revision: z.ZodOptional; job: z.ZodOptional; matrixIndex: z.ZodOptional; phase: z.ZodString; requestId: z.ZodOptional; resumeMode: z.ZodEnum<{ "replay-current": "replay-current"; "continue-next": "continue-next"; }>; stepIndex: z.ZodOptional; stepName: z.ZodOptional; }, z.core.$strip>>; executionState: z.ZodOptional>; errorMessage: z.ZodOptional; exitCode: z.ZodOptional; failedJob: z.ZodOptional; finishedAt: z.ZodOptional; fixLoopCycle: z.ZodOptional; inputs: z.ZodOptional>; job: z.ZodOptional; keepWorktree: z.ZodOptional; launcher: z.ZodOptional; originWorkspaceId: z.ZodOptional; surfaceId: z.ZodOptional; type: z.ZodLiteral<"cmux">; workspaceId: z.ZodString; }, z.core.$strip>, z.ZodObject<{ originPaneId: z.ZodOptional; originSessionId: z.ZodOptional; originSurfaceId: z.ZodOptional; originWorkspaceId: z.ZodOptional; paneId: z.ZodOptional; sessionId: z.ZodOptional; sessionName: z.ZodString; type: z.ZodLiteral<"tmux">; windowId: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ pid: z.ZodOptional; type: z.ZodLiteral<"native">; }, z.core.$strip>], "type">>; originalRepoPath: z.ZodOptional; outcome: z.ZodOptional>; pid: z.ZodOptional; prompt: z.ZodOptional; runner: z.ZodOptional; runId: z.ZodOptional; runKey: z.ZodString; secretFile: z.ZodOptional; skipLaunch: z.ZodOptional; stale: z.ZodOptional; staleReason: z.ZodOptional; stage: z.ZodEnum<{ error: "error"; running: "running"; completed: "completed"; }>; startedAt: z.ZodString; statusFile: z.ZodOptional; failureReason: z.ZodOptional; worktreeBranch: z.ZodOptional; worktreePath: z.ZodOptional; workflowPath: z.ZodString; workflowId: z.ZodOptional; workflowName: z.ZodOptional; runDirectory: z.ZodOptional; description: z.ZodString; 'produced-by': z.ZodOptional>; 'initial-content': z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; workspace: z.ZodString; effectiveStage: z.ZodOptional>; effectiveOutcome: z.ZodOptional>; }, z.core.$strip>; declare const WorkflowRunHandleSchema: z.ZodObject<{ changelogPath: z.ZodString; contextPath: z.ZodString; displayName: z.ZodString; pauseRequestPath: z.ZodOptional; recordPath: z.ZodString; runDir: z.ZodString; runId: z.ZodString; runKey: z.ZodString; stopRequestPath: z.ZodString; workspace: z.ZodString; }, z.core.$strip>; type WorkflowExecutionCursor = z.infer; type WorkflowExecutionState = z.infer; type WorkflowInput = z.infer; type MatrixEntry = z.infer; type StepCommandMap = z.infer; type StepCommand = z.infer; type Strategy = z.infer; type Step = z.infer; type ServiceDef = z.infer; type PreBlock = z.infer; type JobHookBlock = z.infer; type Job = z.infer; type RepairTriage = z.infer; type AgentDecisionTrigger = z.infer; type WorktreeHook = z.infer; type WorktreeConfig = z.infer; type WorkflowKeybindings = z.infer; type RunDirectoryEntry = z.infer; type RunDirectory = z.infer; type Workflow = z.infer; type WorkflowStage = z.infer; type WorkflowOutcome = z.infer; type WorkflowRepairStatus = z.infer; type WorkflowResumeMode = z.infer; type WorkflowRepairJobStatus = z.infer; type WorkflowRepairJobAttempt = z.infer; type WorkflowRepairJob = z.infer; type WorkflowRepairRoutingFallback = z.infer; type WorkflowProgressEvent = z.infer; type WorkflowRepairRecord = z.infer; type WorkflowLauncherMetadata = z.infer; type WorkflowLauncherType = WorkflowLauncherMetadata['type']; type WorkflowRunRecord = z.infer; type WorkflowRunHandle = z.infer; //#endregion //#region src/types/tool-types.d.ts /** * Tool definition for MCP */ interface ToolDefinition { name: string; description: string; inputSchema: Record; } /** * Base tool interface following MCP SDK patterns */ interface Tool { getDefinition(): ToolDefinition; getInputSchema(): z.ZodObject; execute(input: TInput): Promise; } interface RunningService { name: string; process: ChildProcess; env?: Record; release?: () => Promise; } interface InterpolationContext { inputs: Map; matrix: MatrixEntry; secrets: Map; env: Record; } interface StepRunOptions { cliAgent?: string; runner?: string; dryRun: boolean; continueOnError: boolean; stopRequestPath?: string; workflowDir: string; onStepStarted?: (stepName: string, index: number, total: number, matrixIndex?: number, attempt?: number) => Promise | void; onExecutionStateChange?: (state: 'paused' | 'resumed', stepName: string) => Promise | void; } interface Logger { info: (message: string) => void; error: (message: string) => void; warn: (message: string) => void; event?: (level: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal', name: string, options?: { attributes?: Record; exception?: unknown; }) => Promise; flush?: () => Promise; } //#endregion //#region src/services/WorkflowRegistryService.d.ts interface WorkflowRegistryCreateRunInput { activeRepairId?: string; cliAgent?: string; continueOnError?: boolean; displayName: string; dryRun: boolean; env?: Record; job?: string; keepWorktree?: boolean; inputs?: Record; launcher?: WorkflowLauncherMetadata; prompt?: string; pid?: number; /** Required capability when promoting a terminal error run for recovery. */ recoveryClaimId?: string; runner?: string; runDirectory?: RunDirectory; secretFile?: string; skipLaunch?: boolean; statusFile?: string; workflowPath: string; workflowId?: string; workflowName?: string; workflowWorkspace?: string; workspace?: string; } interface WorkflowRegistryFinalizeRunInput { errorMessage?: string; exitCode?: number; failedJob?: string; failureReason?: string; fixLoopCycle?: number; originalRepoPath?: string; outcome?: WorkflowOutcome; stage: Exclude; worktreeBranch?: string; worktreePath?: string; } interface WorkflowRegistryRepairStateInput { activeRepairId?: string | null; fixLoopCycle?: number; } interface WorkflowRegistryListRunsPageInput { page?: number; pageSize?: number; workspace?: string; /** * Applied before pagination, so `total`, `totalPages`, and `hasNextPage` * describe the filtered set rather than the whole registry. */ filter?: (record: WorkflowRunRecord) => boolean; } interface WorkflowRegistryListRunsPage { hasNextPage: boolean; hasPreviousPage: boolean; items: WorkflowRunRecord[]; page: number; pageSize: number; total: number; totalPages: number; } interface WorkflowStopRequest { reason?: string; requestedAt: string; runId: string; schemaVersion: 1; } interface WorkflowPauseRequest { action: 'pause'; schemaVersion: 1; reason?: string; requestId: string; requestedAt: string; revision: number; runId: string; } interface WorkflowResumeRequest { action: 'resume'; schemaVersion: 1; requestId: string; requestedAt: string; revision: number; runId: string; } interface WorkflowRecoveryClaim { claimId: string; claimedAt: string; ownerSessionId?: string; pid: number; } /** * Filesystem-backed registry for workflow runs. */ declare class WorkflowRegistryService { private readonly homeDir; private readonly recoveryClaimTtlMs; private readonly lockRecoveryClaim; constructor(homeDir?: string, recoveryClaimTtlMs?: number, lockRecoveryClaim?: typeof lock); /** * Resolve the effective workspace from CLI/tool input or workflow YAML metadata. */ resolveWorkspace(explicitWorkspace?: string, workflowWorkspace?: string): string; /** * Create or resume a workflow run in the `running` stage for its workspace. */ createRun(input: WorkflowRegistryCreateRunInput): Promise; /** * Finalize a workflow run by moving it into a terminal stage and updating metadata. */ finalizeRun(handle: WorkflowRunHandle, input: WorkflowRegistryFinalizeRunInput): Promise; /** * Request graceful interruption for a running workflow. */ requestStop(workspace: string | undefined, runKey: string, reason: string | undefined, expectedRunId: string): Promise; requestPause(workspace: string | undefined, runKey: string, reason: string | undefined, expectedRunId: string): Promise; requestResume(workspace: string | undefined, runKey: string, expectedRunId: string): Promise; readPauseRequest(handle: WorkflowRunHandle): Promise; updateExecutionState(handle: WorkflowRunHandle, executionState: WorkflowExecutionState, executionCursor?: WorkflowExecutionCursor, expectedRevision?: number): Promise; updateExecutionCursor(handle: WorkflowRunHandle, patch: Partial): Promise; clearPauseRequest(handle: WorkflowRunHandle): Promise; markFinalizing(handle: WorkflowRunHandle): Promise; /** * Check whether a workflow run has been asked to stop. */ hasStopRequest(handle: WorkflowRunHandle): Promise; private assertNotFinalizing; private assertCurrentRun; private getRunningHandle; private writeAtomic; /** Publish complete JSON without ever exposing a partially written capability. */ private writeExclusiveJson; private writeControlRequest; /** * Read a run record from disk. */ readRunRecord(recordPath: string): Promise; /** * Claim one terminal failed run for recovery. * * Exclusive creation is the cross-process compare-and-set: exactly one Pi or * CLI process may advance from inspection to replay. The claim file moves * with the run directory and is removed when createRun promotes the record. */ claimRunRecovery(workspace: string | undefined, runKey: string, ownerSessionId?: string): Promise; /** * Consume a claim handed from an embedding process to one recovery process. * * The caller-controlled claim ID is only a capability reference: ownership * comes from the pre-existing registry claim. Exclusive adoption prevents * replaying the same capability in two launcher processes. */ adoptRunRecoveryClaim(workspace: string | undefined, runKey: string, claimId: string): Promise; /** Release a claim when recovery validation fails before replay starts. */ releaseRunRecoveryClaim(workspace: string | undefined, runKey: string, claimId: string): Promise; private acquireRecoveryClaimLock; /** Verify the exact adopted capability before moving error state to running. */ private assertRecoveryPromotion; /** * Reclaim a claim when its launcher lease expired or its claimant died. An * adopted claim is protected while its adopting process remains alive. */ private reclaimAbandonedRecoveryClaim; private readRecoveryClaim; private readRecoveryAdoption; /** * Read a workflow run by workspace, stage, and run key. */ readRunByKey(workspace: string | undefined, stage: WorkflowStage, runKey: string): Promise; /** * Read a terminal fix.md artifact from a staged run without mutating it. */ readRunFixContent(workspace: string | undefined, stage: WorkflowStage, runKey: string): Promise; /** * Read one durable repair record from a staged workflow run. */ readRunRepair(workspace: string | undefined, stage: WorkflowStage, runKey: string, repairId: string): Promise; /** * Persist the active repair pointer and fix-cycle progress on a running record. */ updateRepairState(handle: WorkflowRunHandle, input: WorkflowRegistryRepairStateInput): Promise; /** * List workflow runs across all workspaces or a single workspace. */ listRuns(workspace?: string): Promise; /** * List workflow runs as a stable page sorted by latest activity first. */ listRunsPage(input?: WorkflowRegistryListRunsPageInput): Promise; /** * Count live (non-stale) running workflows in a workspace. */ countRunningWorkflows(workspace: string): Promise; /** * Persist every dead running process in a workspace as an interrupted run. * The operation is idempotent and is only invoked by an explicit reconcile * request or before a new workflow is dispatched. */ reconcileStaleRuns(workspace?: string): Promise; /** * Ensure the stage directories exist for the workspace. */ private ensureWorkspaceStructure; /** * Find the current stage for an existing run key. */ private findRunStage; /** * Read every run record within a workspace's stage directories. */ private listWorkspaceRuns; /** * Resolve the run stage, first converting dead running records into * interrupted terminal records so reruns are unblocked. */ private findReusableRunStage; /** * Read a running record for status displays without mutating it on disk. * If the recorded PID is gone, mark the returned record as stale but keep * the persisted state untouched so the original failure metadata is not * destroyed by a read-only status query. */ private inspectRunningRecord; /** * Read a running record for stale reconciliation. Malformed records cannot * be safely converted to terminal records, so they are skipped consistently * with list/count operations instead of blocking unrelated workflow runs. */ private inspectReconcilableRunningRecord; /** * Read a run record for status listing. Invalid persisted records are * skipped explicitly by returning null so callers do not need to suppress * exceptions inline. */ private readListableRunRecord; /** * Convert a stale running record into an interrupted error record when its * recorded PID is no longer alive. */ private reconcileStaleRunningRecord; /** * Enumerate known workspace directory names. */ private listWorkspaceNames; /** * Order runs by latest activity across all stages. */ private compareRunRecordsByLatest; /** * Persist a run record with stable formatting. */ private writeRunRecord; /** * Validate the persisted run record shape before returning it to callers. */ private validateRunRecord; /** * Resolve the directory for a workspace-scoped run stage. */ private getRunStageDirectory; /** * Resolve the directory for a single run inside a stage. */ private getRunDirectory; /** * Directory holding a run's artifacts, derived from a listed record. * * A record carries workspace, stage, and run key but not its own path, so a * reader that wants an artifact such as the progress log would otherwise have * to reconstruct the layout itself and drift from it. */ runDirectoryFor(record: Pick): string; /** * The directory every workspace lives under. * * Exposed so an observer can watch exactly what this service writes. Deriving * it independently would let the two drift, and a watcher pointed at the * wrong tree reports nothing rather than failing. */ workspacesDirectory(): string; /** * Test whether a path exists while preserving unexpected filesystem errors. */ private pathExists; /** * Remove a file when present without masking other filesystem failures. */ private removeFileIfExists; /** * Normalize a user-supplied workspace or run name into a safe directory key. */ private slugifySegment; /** * Check whether a locally tracked process still exists. */ private isProcessAlive; } //#endregion //#region src/tools/ControlWorkflowTool.d.ts declare const ControlWorkflowInputSchema: z.ZodObject<{ action: z.ZodEnum<{ pause: "pause"; resume: "resume"; stop: "stop"; }>; expectedRunId: z.ZodString; reason: z.ZodOptional; runKey: z.ZodString; workspace: z.ZodOptional; }, z.core.$strip>; type ControlWorkflowInput = z.input; declare class ControlWorkflowTool implements Tool { private readonly registry; static readonly TOOL_NAME = "control_workflow"; private readonly control; constructor(registry?: WorkflowRegistryService); getInputSchema(): z.ZodObject<{ action: z.ZodEnum<{ pause: "pause"; resume: "resume"; stop: "stop"; }>; expectedRunId: z.ZodString; reason: z.ZodOptional; runKey: z.ZodString; workspace: z.ZodOptional; }, z.core.$strip>; getDefinition(): ToolDefinition; execute(input: ControlWorkflowInput): Promise; } //#endregion //#region src/services/RunDirectoryService/types.d.ts type RunDirectoryEntryStatus = 'missing' | 'initial' | 'populated' | 'empty' | 'incompatible' | 'inaccessible'; type RunDirectoryEntryRelation = 'built-in' | 'input' | 'output' | 'future' | 'shared'; interface RunDirectoryInspectedEntry { description: string; fingerprint?: string; kind: RunDirectoryEntry['kind']; path: string; producedBy: string[]; relation: RunDirectoryEntryRelation; status: RunDirectoryEntryStatus; } interface RunDirectoryInspection { description: string; entries: RunDirectoryInspectedEntry[]; jobName?: string; runDir: string; } interface RunDirectoryWarning { message: string; path: string; status: RunDirectoryEntryStatus; } interface RunDirectorySnapshot { fingerprints: Record; } interface StepArtifactSnapshot { fingerprint?: string; path: string; } interface StepArtifactWarning { path: string; status: 'empty' | 'inaccessible' | 'missing' | 'unchanged'; } interface RunDirectoryInspectOptions { jobName?: string; jobOrder?: string[]; planned?: boolean; } //#endregion //#region src/services/RunDirectoryService/RunDirectoryService.d.ts declare class RunDirectoryService { materialize(runDir: string, declaration: RunDirectory | undefined, dryRun?: boolean): Promise; inspect(runDir: string, declaration: RunDirectory | undefined, options?: RunDirectoryInspectOptions): Promise; snapshot(inspection: RunDirectoryInspection): RunDirectorySnapshot; snapshotStepArtifacts(runDir: string, paths: string[]): Promise; findStepArtifactWarnings(runDir: string, snapshots: StepArtifactSnapshot[]): Promise; findWarnings(jobName: string, declaration: RunDirectory | undefined, before: RunDirectorySnapshot, after: RunDirectoryInspection): RunDirectoryWarning[]; formatInspection(inspection: RunDirectoryInspection): string; private inspectEntry; private resolveRelation; private resolveStatus; private fingerprint; private hash; private resolveEntryPath; } //#endregion //#region src/services/WorkflowControlService.d.ts type WorkflowControlAction = 'pause' | 'resume' | 'stop'; type WorkflowControlRequest = WorkflowPauseRequest | WorkflowResumeRequest | WorkflowStopRequest; interface WorkflowControlInput { action: WorkflowControlAction; expectedRunId: string; reason?: string; runKey: string; workspace?: string; } declare class WorkflowControlService { private readonly registry; constructor(registry?: WorkflowRegistryService); request(input: WorkflowControlInput): Promise; requestPause(workspace: string | undefined, runKey: string, reason: string | undefined, expectedRunId: string): Promise; requestResume(workspace: string | undefined, runKey: string, expectedRunId: string): Promise; requestStop(workspace: string | undefined, runKey: string, reason: string | undefined, expectedRunId: string): Promise; } //#endregion //#region src/errors/WorkflowInterruptedError.d.ts interface WorkflowInterruptContext { phase: string; jobName?: string; stepName?: string; commandPreview?: string; source?: string; } //#endregion //#region src/services/BackgroundServiceManager.d.ts declare class BackgroundServiceManager { private logger; private runningServices; private readonly processRegistry; private readonly portRegistry; constructor(logger: Logger); private resolveWorkingDirectory; getRunningServices(): RunningService[]; startService(service: ServiceDef, baseEnv: Record, workflowDir: string, dryRun: boolean): Promise; waitForServiceReady(service: ServiceDef, workflowDir: string, baseEnv: Record, shouldAbort?: () => boolean): Promise; stopAll(): Promise; } //#endregion //#region src/services/CodexQuotaService.d.ts /** * CodexQuotaService * * DESIGN PATTERNS: * - Service pattern for business logic encapsulation * - Single responsibility principle * * CODING STANDARDS: * - Use async/await for asynchronous operations * - Throw descriptive errors for error cases * - Keep methods focused and well-named * - Document complex logic with comments * * AVOID: * - Mixing concerns (keep focused on single domain) * - Direct tool implementation (services should be tool-agnostic) */ declare const PRIMARY_WINDOW: "primary"; declare const SECONDARY_WINDOW: "secondary"; type CodexQuotaWindowKind = typeof PRIMARY_WINDOW | typeof SECONDARY_WINDOW; interface CodexQuotaBlock { limitId: string; limitName: string; resetAfterSeconds: number | null; resetAt: number; usedPercent: number; window: CodexQuotaWindowKind; windowSeconds: number | null; } interface CodexQuotaStatus { blockingLimit: CodexQuotaBlock | null; planType: string | null; } interface CodexQuotaServiceDeps { codexHome?: string; fetchFn?: typeof fetch; now?: () => number; readTextFile?: (path: string) => Promise; } declare class CodexQuotaService { private readonly codexHome; private readonly fetchFn; private readonly now; private readonly readTextFile; constructor(deps?: CodexQuotaServiceDeps); isCodexCommand(command: string, _sourceAgentKey?: string): boolean; getQuotaStatus(): Promise; private readAuthFile; private readChatgptBaseUrl; private buildUsageUrl; private normalizeBaseUrl; private readOptionalTextFile; private findBlockingLimit; private collectBlockingLimit; } //#endregion //#region src/services/WorkflowParserService.d.ts declare class WorkflowParserService { generateHumanReadableId(): string; parseWorkflowFile(workflowPath: string): Workflow; /** * Resolve `imports` references in a workflow. * Import paths are resolved relative to the importing workflow file. * Imported files provide base sections that the main workflow can override: * - env: merged (main overrides imported) * - pre.steps: imported steps prepended before main steps * - pre.services: imported services prepended before main services * - post.steps: imported steps prepended before main steps * - post.services: imported services prepended before main services * - worktree: imported hooks used as defaults, main overrides per-hook * - jobs: imported template jobs (dot-prefixed) merged in, main overrides * - system-prompt: concatenated (imported + main) * Imports are processed in order; later imports override earlier ones. * Circular imports are detected and throw an error. */ resolveImports(workflow: Workflow, workflowPath: string, visited?: Set): void; private mergeRunDirectories; /** * Resolve `extends` references in jobs. * Dot-prefixed jobs (e.g. `.ios-prebuild`) are shared templates. * When a job has `extends: .template-name`, it merges: * - steps: template steps prepended before job steps * - preJob.steps: template steps prepended before job preJob steps * - postJob.steps: template steps prepended before job postJob steps * - env: merged (job overrides template) * - system-prompt: concatenated (template + job) * - all other fields: job overrides template * Template jobs are removed from the jobs map after resolution. */ resolveExtends(workflow: Workflow): void; /** * Merge a single template into a job. * Called once per template when a job extends multiple templates. */ private applyTemplate; private mergeJobHookSteps; private assignJobHookSteps; loadSecrets(secretFile: string): Map; interpolate(template: string, context: InterpolationContext): string; isActionSkipped(uses: string): boolean; resolveJobOrder(jobs: Record, targetJob: string | null): string[]; expandMatrix(job: Job): MatrixEntry[]; } //#endregion //#region src/services/StepRunnerService.d.ts /** * Executes workflow steps in child processes and tracks the active process so * the workflow runner can interrupt it safely. * * Runtime configuration: * - Environment precedence is `process.env` -> workflow/job env -> step env. * - Child commands run through `/bin/zsh` to match local workflow execution. * - `FORCE_COLOR=1` is injected so tool output keeps ANSI formatting. */ declare class StepRunnerService { private parser; private logger; private quotaService; private watchStatusFile; private runDirectoryService; private ownsTerminal; private activeStep; private lastInteractiveReap; private interruptedSignal; private activeQuotaWait; /** * Create a step runner bound to the workflow parser and shared logger. * * `ownsTerminal` is false when the runner is embedded in a host that owns the * terminal itself, which is the Pi extension: there stdin is the TUI's * keyboard and stdout is its screen. A runner that does not own the terminal * must not hand a step's stdin to it, and must not `stty` or reset it * afterwards, however cooperative the intent. */ constructor(parser: WorkflowParserService, logger: Logger, quotaService?: Pick, watchStatusFile?: typeof watch, runDirectoryService?: RunDirectoryService, ownsTerminal?: boolean); /** * Clear a previous workflow's shutdown state before starting a new run. */ resetInterruption(): void; /** * Stop the active step process during workflow shutdown. */ stopActiveStep(signal: NodeJS.Signals): void; /** * Execute a single workflow step and stream its output to the workflow logger. * * The runner interpolates the final command before execution, resolves the * working directory relative to the workflow root, and merges step-scoped * environment variables over the inherited process environment. */ runStep(step: Step, context: InterpolationContext, options: StepRunOptions): Promise; private logStepLifecycle; /** * Spawn a child shell for the step command and normalize its termination * into a typed result. */ private executeCommand; /** * Build interruption metadata for downstream workflow error handling. */ private createInterruptContext; /** * Render a safe summary of the spawn failure cause for operator logs. */ private formatSpawnError; private resolveStepCommand; private resolveExactAgentCommand; private resolveStringCommand; private resolveFirstMappedCommand; private resolveMissingExplicitRunner; private collectMappedRunnerKeys; private resolveRunner; private formatStepDisplay; private withInteractiveTerminalTitle; private escapeShellArg; private shouldRetryForCodexQuota; private waitForCodexQuotaAvailability; private readCodexQuotaStatus; private waitForQuotaDelay; private waitForDelay; private formatQuotaError; /** * Resolve the per-step timeout from workflow YAML into milliseconds. */ private resolveTimeoutMs; /** * Resolve the per-step timeout retry count from workflow YAML. */ private resolveTimeoutRetries; /** * Format timeout durations for operator-facing logs. */ private formatTimeoutMs; /** * Send SIGTERM to the active step's process group to clean up orphaned * background processes (e.g. http servers spawned during manual testing). * Silently ignores ESRCH when the group has already exited. */ private cleanupProcessGroup; private isProcessGroupAlive; private waitForProcessGroupToExit; /** * Best-effort cleanup for interactive commands that inherit the terminal. * These commands are intentionally not detached, so keep an explicit PID * snapshot before signaling; once the shell exits, descendants may be * re-parented and no longer discoverable from the shell PID. */ private cleanupInteractiveProcessTree; /** * Re-signal the live interactive descendants until none remain or `budgetMs` * elapses, re-walking the process tree each round. An interactive TUI keeps * spawning and re-parenting descendants (MCP servers, browser/render helpers) * that a single snapshot misses; group-signalling also reaps members spawned * after the snapshot. Returns as soon as the tree is empty so the common, * already-exited case adds no latency. */ private reapInteractiveTree; /** * Operator-tunable SIGTERM→SIGKILL grace per teardown phase. Defaults to the * process-exit wait so ordinary interactive steps see no behaviour change. */ private interactiveKillGraceMs; /** * SIGTERM→SIGKILL grace on the completion path (status file signalled `YES`). * Deliberately longer than the timeout-path `FORCE_KILL_GRACE_PERIOD_MS` so an * interactive agent can flush its final telemetry batch (e.g. Claude Code's * OTEL Stop-hook events) before SIGKILL. A fast graceful exit still settles * immediately, so this only adds latency when a child lingers. Operator-tunable * via `WORKFLOW_STEP_FORCE_KILL_GRACE_MS`; defaults to STEP_COMPLETION_KILL_GRACE_MS. */ private stepCompletionKillGraceMs; /** Resolve a pid to its `ps` command line so survivors are identifiable. */ private describeProcess; /** * Append a forensic record for an interactive run to a capped JSON log so a * session that does not exit is self-diagnosing (which signal completed it and * what survived). Best-effort: logging never affects step control flow. */ private recordInteractiveCompletion; private interactiveReapLogPath; private readInteractiveCompletionLog; private captureInteractiveProcessOwnership; private collectInteractiveProcessIds; private snapshotProcessTree; private signalProcessIds; /** * Resolve the distinct process-group ids owned by the given pids, excluding * the runner's own group so a `kill(-pgid)` can never terminate this process. * * Interactive TUIs such as Claude Code make themselves process-group leaders * (pid === pgid) and spawn descendants into that group. Reaping by pid alone * leaves anything spawned after the one-shot tree snapshot alive, which keeps * the interactive session running after the Stop hook signalled completion. */ private collectInteractiveProcessGroupIds; private signalProcessGroups; private uniqueLiveProcessIds; private isProcessAlive; private waitForProcessIdsToExit; /** * Signal the active step, preferring the detached process group so shell * pipelines shut down as a unit before falling back to the shell process. * * @param signal POSIX signal used to interrupt the running step. * @returns `true` when a signal was dispatched successfully, otherwise `false`. */ private killActiveStep; /** * Create an empty temp file that the Claude Code Stop hook will write * YES to when the agent finishes its turn. The path is injected into * WORKFLOW_STATUS_FILE so the hook can locate it directly — no fallback * marker file is used. */ private createStatusFile; /** * Race interactive step execution against agent completion and workflow stop files. * When the file contains YES, SIGTERM the step process and wait for * it to exit before returning `status_completed`. Escalates to SIGKILL * if the process ignores SIGTERM. The next job must not start until * the child process tree has fully exited. */ private raceInteractiveCompletion; private raceStopRequest; private hasCurrentStopRequest; private readControlAction; private markPaused; private waitForResume; private writeControlRecord; private captureTerminalState; private restoreTerminalState; /** * Remove the temp status file and the well-known marker file after step completion. */ private cleanupStatusFile; } //#endregion //#region src/services/JobRunnerService.d.ts declare class JobRunnerService { private parser; private stepRunner; private logger; private runDirectoryService; constructor(parser: WorkflowParserService, stepRunner: StepRunnerService, logger: Logger, runDirectoryService?: RunDirectoryService); runJob(jobName: string, job: Job, context: { inputs: Map; secrets: Map; workflowEnv: Record; workflowSystemPrompt?: string; jobOrder: string[]; allJobs: Record; repairTriage?: boolean; activeRepairIssue?: string; /** Job that raised the active repair, when this job is inside its scope. */ activeRepairVerificationJob?: string; allowRepairTerminalStop?: boolean; runDirectory?: RunDirectory; onPromptAssembled?: (assembly: { jobName: string; matrix: MatrixEntry; prompt: string; }) => void; }, options: { cliAgent?: string; runner?: string; dryRun: boolean; continueOnError: boolean; stopRequestPath?: string; workflowDir: string; maxRetries: number; onStepStarted?: (stepName: string, index: number, total: number, matrixIndex?: number, attempt?: number) => Promise | void; onExecutionStateChange?: (state: 'paused' | 'resumed', stepName: string) => Promise | void; }): Promise; private reportRunDirectoryWarnings; /** * Run steps in order, recording each transition. * * The recorder is built from the environment rather than threaded through the * call chain: WORKFLOW_RUN_DIR and the job name are already there for * telemetry, and a run without a run directory records nothing. */ private runStepSequence; private buildLifecycleAttributes; } //#endregion //#region src/services/TriggerService.d.ts /** * Handles trigger-specific setup before the workflow job graph starts. */ declare class TriggerService { private stepRunner; private logger; private activePrompt; private activePromptSignal; /** * Create a trigger handler bound to the step runner used for trigger steps * and the workflow logger used for user-facing output. */ constructor(stepRunner: StepRunnerService, logger: Logger); /** * Check whether a path exists without throwing when it is absent. */ private pathExists; /** * Clear the cancellation state retained from a previous workflow run. */ resetInterruption(): void; /** * Abort an active interactive prompt so the workflow can unwind quickly. */ abortActivePrompt(signal: NodeJS.Signals): void; /** * Collect prompt context for workflows triggered by `user_prompt`. * * Uses `workflowEnv.CONTEXT_FILE` when present to read or persist the prompt, * and writes the final prompt to `workflowEnv.USER_PROMPT` for downstream * job execution. */ handleUserPrompt(workflow: Workflow, cliPrompt: string | null, workflowEnv: Record, workflowDir: string, dryRun: boolean): Promise; /** * Execute `agent_decision` steps that decide whether the workflow should proceed. * * Reads and writes workflow context via `workflowEnv.CONTEXT_FILE`, and * copies CLI prompt content into `workflowEnv.HEARTBEAT_PROMPT` when supplied. */ handleAgentDecision(workflow: Workflow, workflowEnv: Record, inputs: Map, secrets: Map, options: StepRunOptions, prompt: string | null): Promise; } //#endregion //#region src/services/WorkflowRepairService.d.ts interface CreateWorkflowRepairInput { emittingJob: string; fixContent: string; fixCycle: number; invalidTarget?: string; jobOrder: string[]; restartFrom?: string; runDir: string; } declare class WorkflowRepairService { createRepair(input: CreateWorkflowRepairInput): Promise; readRepair(runDir: string, repairId: string): Promise; activateRepair(runDir: string, repair: WorkflowRepairRecord): Promise; resolveRepair(runDir: string, repair: WorkflowRepairRecord): Promise; supersedeRepair(runDir: string, repair: WorkflowRepairRecord, supersededBy: string): Promise; startJob(runDir: string, repair: WorkflowRepairRecord, jobName: string, workflowRunId?: string): Promise; finishJob(runDir: string, repair: WorkflowRepairRecord, jobName: string, status: Exclude): Promise; /** * Mark scope jobs the run jumped over as skipped. * * A forward jump inside an active repair leaves jobs that never ran and never * will for this repair. They carry no attempt: an attempt records an * execution, and none happened. Recording the decision keeps recovery honest — * `resolveRecoveryStart` would otherwise resume at a job the repair * deliberately passed by. */ skipJobs(runDir: string, repair: WorkflowRepairRecord, jobNames: string[]): Promise; resolveRecoveryStart(repair: WorkflowRepairRecord): string; private resolveRoute; private fallbackRestartIndex; private allocateIssueDirectory; private writeStatus; private writeRepair; private repairPath; } //#endregion //#region src/services/WorktreeService.d.ts declare class WorktreeService { private stepRunner; private logger; constructor(stepRunner: StepRunnerService, logger: Logger); getWorktreeBranchName(workflowName: string): string; createWorktree(repoRoot: string, workflowName: string): string; removeWorktree(repoRoot: string, worktreePath: string): void; private cleanupWorktreePath; private isRegisteredWorktree; runHook(hook: WorktreeHook, cwd: string, baseEnv: Record, inputs: Map, secrets: Map, options: { cliAgent?: string; runner?: string; dryRun: boolean; continueOnError: boolean; stopRequestPath?: string; onStepStarted?: (stepName: string, index: number, total: number, matrixIndex?: number, attempt?: number) => Promise | void; onExecutionStateChange?: (state: 'paused' | 'resumed', stepName: string) => Promise | void; }): Promise; } //#endregion //#region src/services/RunWorkflowService.d.ts interface RunWorkflowInput { cliAgent?: string; runner?: string; workflowPath: string; job?: string; inputs?: Record; env?: Record; secretFile?: string; dryRun?: boolean; continueOnError?: boolean; keepWorktree?: boolean; launcher?: WorkflowLauncherType; prompt?: string; name?: string; workspace?: string; skipLaunch?: boolean; statusFile?: string; recovery?: { activeRepairId?: string; /** Omitted only for a read-only recovery dry run. */ claimId?: string; originalJob?: string; originalRepoPath?: string; runKey: string; startJob?: string; worktreeBranch?: string; worktreePath?: string; }; } interface RunWorkflowResult { exitCode: number; output: string; } /** * Optional collaborators for `RunWorkflowService`. * * Supplying these allows tests and higher-level callers to replace concrete * orchestration services without changing the public command API. */ interface RunWorkflowDependencies { /** * Stdio handed to `launch-command` delegation. * * The CLI owns its terminal, so it inherits and lets the launcher paint on * it. An embedded host does not: inside the Pi extension stdout is the TUI's * screen and stdin is its keyboard, and inside the stdio MCP server stdout is * the JSON-RPC stream. Those hosts pass `pipe` so the child gets neither. */ launchStdio?: 'inherit' | 'pipe'; /** * Launcher identity to persist instead of inferring one from this process. * * An embedded host can itself run inside cmux or tmux without that host * terminal being the workflow's launcher. It supplies `native` so readers do * not later scrape or foreground the host application's own terminal. */ launcherMetadata?: WorkflowLauncherMetadata; /** * Whether this process owns the terminal its steps would write to. * * The same distinction `launchStdio` draws, applied to the steps themselves. * `launchStdio` only covers the `launch-command` child; a step spawned by * `StepRunnerService` still reaches the terminal, and an interactive one also * runs `stty` over it. An embedded host passes false to keep both away. */ ownsTerminal?: boolean; parser?: WorkflowParserService; serviceManager?: BackgroundServiceManager; stepRunner?: StepRunnerService; jobRunner?: JobRunnerService; triggerService?: TriggerService; worktreeService?: WorktreeService; registry?: WorkflowRegistryService; repairService?: WorkflowRepairService; runDirectoryService?: RunDirectoryService; } /** * Orchestrates local workflow execution, including triggers, jobs, services, * worktree lifecycle, and graceful interruption handling. */ declare class RunWorkflowService { private logger; private parser; private serviceManager; private stepRunner; private jobRunner; private triggerService; private worktreeService; private registry; private repairService; private runDirectoryService; private outputLines; private interruptedSignal; private launchStdio; private launcherMetadata; /** * Create a workflow runner with an optional logger and overridable * collaborators for tests or alternate orchestration behavior. */ constructor(logger?: Logger, dependencies?: RunWorkflowDependencies); /** * Run the workflow from trigger preparation through cleanup. */ run(input: RunWorkflowInput): Promise; /** * Trigger the same interruption cleanup path used by process signal handlers. * * The optional context records where shutdown started so subsequent * `WorkflowInterruptedError` instances carry structured diagnostics. */ interrupt(signal: NodeJS.Signals, context?: WorkflowInterruptContext): void; /** * Check whether workflow shutdown has been requested. */ private isInterrupted; /** * Build the standard process-style result for an interrupted workflow run. */ private createInterruptedResult; /** * Extract the restart-from job name from fix.md YAML frontmatter. * Returns the parsed target and any invalid target for caller logging. */ private parseFixRestartFrom; /** * Extract the proceed-to job name from proceed.md YAML frontmatter. * * Frontmatter only, with no fall back to job names mentioned in the body the * way fix.md routing does. A mis-routed restart costs re-run time; a * mis-routed forward jump silently drops jobs that were supposed to run, so a * request this parser cannot read exactly is one the caller should ignore. */ private parseProceedTo; /** * Check whether a file-system path exists while preserving non-ENOENT errors. */ private pathExists; /** * Give background services a short async window to finish booting. */ private waitForServiceStartup; private resolveWorkflowRunner; private resolveRunner; /** * Execute the workflow after signal handlers are installed. */ private executeWorkflow; /** * Ephemeral paths let recovery dry runs assemble prompts against copied * evidence without moving or writing the terminal registry directory. */ private createRecoveryDryRunHandle; private writeDryRunWorkflowArtifact; /** * Resolve the effective exit code and outcome for a settled run. * Shared by the post block env and registry finalization so they cannot drift. */ private resolveRunOutcome; /** * Persist the terminal stage for a workflow run after execution completes. */ private finalizeRegistryRun; private buildLifecycleAttributes; /** * Write a terminal workflow record to a caller-provided completion file. */ private writeWorkflowStatusFile; private appendRepairReferenceToContext; /** * Why a proceed.md request cannot be honored, or undefined when it can. * * Every rejection is advisory: the run falls back to plain job order, which is * always a correct way to finish a repair. Failing the run over a bad forward * jump would turn an optimization into a hazard. */ private proceedRejectionReason; private appendProceedNoteToContext; private setRepairEnvironment; private clearRepairEnvironment; private updateRepairReferenceStatus; private resolveCliPath; private buildLaunchEnvironment; /** * Create a short command for launcher integrations such as cmux. * * The real invocation is written to a temp script so user-controlled values * like prompts are parsed by only the script shell, not by every launch layer. */ private createLaunchScriptCommand; private buildLauncherOriginExports; private resolveLauncherMetadata; private readTmuxIdentity; /** * Reconstruct the CLI command string for launch-command delegation, * adding --skip-launch to prevent infinite recursion. */ private buildLaunchCliCommand; /** * Return the last non-empty log line for failed run metadata. */ private lastMeaningfulOutputLine; /** * Run pre-services and setup steps before job execution begins. */ /** * Run the `launch-command` delegation and wait for it to settle. * * Asynchronous rather than `execSync` because this is not always the CLI. In * the Pi extension the workflow engine runs inside the TUI's own process, and * a synchronous spawn freezes its event loop for the whole launch: measured at * roughly a second, most of it `pnpm exec` resolution, during which nothing * repaints and no keystroke is read. `run()` is already async, so blocking * bought nothing to begin with. */ private spawnLaunchCommand; /** * Run a phase block, recording its start and however it settles. * * Wraps rather than annotating each exit: between them the two blocks return * from six places and can also throw, and a phase that starts without ever * finishing reads as permanently running to everything downstream. */ private recordPhase; private runPreBlock; /** * Run post-cleanup services and steps after the main workflow path settles. */ private runPostBlock; } //#endregion //#region src/services/WorkflowProgressService.d.ts declare const PROGRESS_FILENAME = "progress.ndjson"; /** * Job names the engine records for the `pre:` and `post:` blocks. * * Those blocks are not jobs, but they run steps and a reader wants to see them, * so they are recorded as pseudo-jobs under these reserved names. Exported so a * reader can tell a phase from a real job without hardcoding the strings the * writer happens to use. Worktree hooks are deliberately absent: they record no * progress at all, so nothing can report them. */ declare const PHASE_JOB_PRE = "pre"; declare const PHASE_JOB_POST = "post"; /** Whether a recorded job is a real job or one of the two phase blocks. */ type WorkflowRunPhase = 'job' | typeof PHASE_JOB_POST | typeof PHASE_JOB_PRE; /** Classify a recorded job name as a phase block or a real job. */ declare function workflowRunPhase(job: string): WorkflowRunPhase; /** * Read a run's progress log. * * Malformed lines are skipped rather than throwing: a reader may catch the file * mid-append, and a torn final line is expected rather than exceptional. */ declare function readWorkflowProgress(runDir: string, read?: (path: string) => Promise): Promise; /** Whatever a run has appended since a given byte offset, and the new offset. */ interface WorkflowProgressTail { events: WorkflowProgressEvent[]; offset: number; } /** Bytes from `offset` to the end of file, and where each end sat. */ type ProgressTailReader = (path: string, offset: number) => Promise<{ end: number; start: number; text: string; } | undefined>; /** * Read only what a run has appended since the last call. * * The whole-file `readWorkflowProgress` re-parses from byte zero every time, * which is fine once and wasteful on a timer: a watcher asking a live run for * its latest transition pays for every transition that came before it. * * Only whole lines are consumed. A reader routinely catches the file * mid-append, and the bytes of a torn line have to stay unread so the next call * sees the finished line instead of dropping it. */ declare function readWorkflowProgressFrom(runDir: string, offset?: number, read?: ProgressTailReader): Promise; /** Every state a recorded job or step can be in. */ type WorkflowProgressStatus = 'completed' | 'failed' | 'pause_requested' | 'paused' | 'resumed' | 'running' | 'skipped'; interface WorkflowProgressStep { name: string; status: WorkflowProgressStatus; reason?: string; } interface WorkflowProgressJob { name: string; status: WorkflowProgressStatus; steps: WorkflowProgressStep[]; index?: number; total?: number; reason?: string; } /** * Fold the event log into the current job tree. * * Later events win, so a job that started and later failed reads as failed. * This is what a progress view renders: completed jobs collapse, the running * one expands. */ declare function summarizeWorkflowProgress(events: WorkflowProgressEvent[]): WorkflowProgressJob[]; /** The job and step a run is on right now, for a one-line status. */ declare function currentWorkflowPosition(jobs: WorkflowProgressJob[]): { job: string; step?: string; index?: number; total?: number; } | undefined; //#endregion //#region src/services/WorkflowRunObserverService/types.d.ts /** Shared by every event: which run, and its record as last read. */ interface WorkflowRunEvent { record: WorkflowRunRecord; runKey: string; workspace: string; } interface WorkflowRunJobEvent extends WorkflowRunEvent { /** When the run recorded the transition, not when it was observed. */ at: string; index?: number; job: string; /** `pre` and `post` are phase blocks the engine records as pseudo-jobs. */ phase: WorkflowRunPhase; reason?: string; status: WorkflowProgressStatus; total?: number; } interface WorkflowRunStepEvent extends WorkflowRunEvent { at: string; job: string; phase: WorkflowRunPhase; reason?: string; status: WorkflowProgressStatus; step: string; } interface WorkflowRunFinishedEvent extends WorkflowRunEvent { errorMessage?: string; failedJob?: string; outcome?: WorkflowOutcome; stage: WorkflowStage; } interface WorkflowRunObserverEventMap { job: WorkflowRunJobEvent; /** The run reached a terminal stage. Emitted once, then the run is dropped. */ runFinished: WorkflowRunFinishedEvent; /** First sighting of a run, including runs already going when observing began. */ runStarted: WorkflowRunEvent; /** The record changed: execution state, staleness, repair pointer, stage. */ runUpdated: WorkflowRunEvent; step: WorkflowRunStepEvent; } type WorkflowRunObserverEventName = keyof WorkflowRunObserverEventMap; type WorkflowRunObserverHandler = (event: WorkflowRunObserverEventMap[TName]) => void; /** Removes one subscription. Safe to call more than once. */ type WorkflowRunUnsubscribe = () => void; /** * Watches the registry directory for changes. * * Injected so a test can drive it directly. Real filesystem notifications are * coalesced and occasionally dropped, which makes them impossible to assert on * and is why the reconcile sweep, not this, is what makes the observer correct. */ type WorkflowWatchFactory = (path: string, onChange: () => void) => WorkflowWatchHandle; interface WorkflowWatchHandle { close: () => void; } interface WorkflowRunObserverOptions { /** Coalescing window for filesystem notifications, which arrive in bursts. */ debounceMs?: number; /** * Which runs to report. The registry is shared by every repository and every * session on the machine, so a caller that owns a subset says so here. */ recordFilter?: (record: WorkflowRunRecord) => boolean; /** Safety-net sweep, independent of whether any notification arrived. */ reconcileIntervalMs?: number; watch?: WorkflowWatchFactory; } //#endregion //#region src/services/WorkflowRunObserverService/WorkflowRunObserverService.d.ts /** * Watch a run directory tree and report what changes. * * Not named a control service on purpose: it only observes. Lifecycle control * already exists as `WorkflowControlService`, and the two are brought together * by `createRunControl` rather than merged here. */ declare class WorkflowRunObserverService { private readonly registry; private readonly options; private debounce; private disposed; private readonly handlers; private reconciling; private readonly seen; /** Epoch ms observing began, which is the line between history and news. */ private startedAt; private sweepQueued; private timer; private watcher; constructor(registry: WorkflowRegistryService, options?: WorkflowRunObserverOptions); on(name: TName, handler: WorkflowRunObserverHandler): WorkflowRunUnsubscribe; /** * Begin observing, reporting the runs already in flight. * * Awaits the first sweep so a caller that subscribes and then asks "what is * running" gets an answer rather than a race. */ start(): Promise; /** Sweep now, rather than waiting for the interval. */ refresh(): Promise; dispose(): void; /** * Watch the registry tree, tolerating a tree that is not there yet. * * Re-attempted on every sweep, because the directory is created by whichever * process registers the first run, which may well be later than this. */ private attachWatcher; /** * Coalesce a burst of notifications into one sweep. * * A single appended progress line can produce several notifications, and a * stage transition renames a directory, which produces more. */ private scheduleSweep; /** * List, diff, emit. * * Serialised, because two overlapping sweeps would both read the same * progress bytes and report every transition twice. A sweep requested while * one is running is remembered and run once afterwards, so the change that * prompted it is never simply dropped. */ private reconcile; private sweep; /** * Whether a run this observer never saw running finished on its watch. * * The discriminator between a run that began and ended inside one sweep, * which is news, and one that finished last week, which is not. An * unparseable timestamp counts as history: replaying an old run is worse than * missing an odd one. */ private finishedWhileObserving; /** * Report the transitions a run appended since the last sweep. * * The record's own stage resolves the directory, so a run that moved from * `running` to `completed` between sweeps is read at its new path without the * observer tracking the rename. */ private drainProgress; /** * Deliver to subscribers, absorbing their failures. * * A subscriber that throws is a rendering bug in somebody else's extension, * and it must not stop the sweep or starve every other subscriber. */ private emit; } /** * The identity a run keeps across stage moves. * * `runId` when the record carries one; runs predating it fall back to the pair * that is unique within a workspace. */ declare function runIdentity(record: Pick): string; //#endregion //#region src/tools/ListWorkflowStatusesTool.d.ts declare const ListWorkflowStatusesInputSchema: z.ZodObject<{ reconcile: z.ZodOptional; page: z.ZodOptional; pageSize: z.ZodOptional; workspace: z.ZodOptional; }, z.core.$strip>; type ListWorkflowStatusesToolInput = z.input; /** * MCP tool wrapper around `WorkflowRegistryService.listRuns`. */ declare class ListWorkflowStatusesTool implements Tool { private registry; private options; static readonly TOOL_NAME = "list_workflow_statuses"; /** * `recordFilter` narrows what this tool instance can see at all — it is a * host-level scope (the Pi extension passes a session filter), not a caller * input, which is why it lives here and not in the input schema. */ constructor(registry?: WorkflowRegistryService, options?: { recordFilter?: (record: WorkflowRunRecord) => boolean; }); getInputSchema(): z.ZodObject<{ reconcile: z.ZodOptional; page: z.ZodOptional; pageSize: z.ZodOptional; workspace: z.ZodOptional; }, z.core.$strip>; /** * Return the MCP tool definition and input schema. */ getDefinition(): ToolDefinition; /** * Execute the registry query and return JSON text for the caller. */ execute(input?: ListWorkflowStatusesToolInput): Promise; } //#endregion //#region src/tools/ListWorkflowsTool.d.ts declare const ListWorkflowsInputSchema: z.ZodObject<{ directory: z.ZodOptional; filter: z.ZodOptional; page: z.ZodOptional; pageSize: z.ZodOptional; tags: z.ZodOptional>; }, z.core.$strip>; type ListWorkflowsToolInput = z.input; declare class ListWorkflowsTool implements Tool { static readonly TOOL_NAME = "list_workflows"; getInputSchema(): z.ZodObject<{ directory: z.ZodOptional; filter: z.ZodOptional; page: z.ZodOptional; pageSize: z.ZodOptional; tags: z.ZodOptional>; }, z.core.$strip>; getDefinition(): ToolDefinition; execute(input?: ListWorkflowsToolInput): Promise; } //#endregion //#region src/services/RecoverWorkflowService/types.d.ts /** * Input for recovering a failed workflow run. */ interface RecoverWorkflowInput { dryRun?: boolean; /** Registry-issued capability adopted by a delegated recovery process. */ recoveryClaimId?: string; runKey: string; runner?: string; workspace?: string; } /** * Result returned by RecoverWorkflowService operations. */ type RecoverWorkflowResult = RunWorkflowResult; //#endregion //#region src/services/RecoverWorkflowService/RecoverWorkflowService.d.ts /** * RecoverWorkflowService reconstructs and replays failed workflow runs. */ declare class RecoverWorkflowService { private registry; private runner; private parser; private repairService; /** * Creates a new RecoverWorkflowService instance. * * A delegated replay gets the owner from its registry-issued recovery claim, * so a CLI caller cannot choose another Pi session's identity. */ constructor(registry?: WorkflowRegistryService, runner?: RunWorkflowService, parser?: WorkflowParserService, repairService?: WorkflowRepairService); /** * Recover a failed workflow run from registry metadata. */ recover(input: RecoverWorkflowInput): Promise; /** Trusted embedding entry point; owner identity is never part of MCP/CLI input. */ recoverForSession(input: RecoverWorkflowInput, ownerSessionId: string): Promise; private recoverWithOwner; private recoverClaimed; private parseTerminalFix; } //#endregion //#region src/tools/RecoverWorkflowTool.d.ts declare const RecoverWorkflowInputSchema: z.ZodObject<{ dryRun: z.ZodOptional; job: z.ZodOptional; runKey: z.ZodString; runner: z.ZodOptional; workspace: z.ZodOptional; }, z.core.$strip>; type RecoverWorkflowToolInput = z.input; declare class RecoverWorkflowTool implements Tool { private service; private readonly ownerSessionId?; static readonly TOOL_NAME = "recover_workflow"; constructor(service?: RecoverWorkflowService, ownerSessionId?: (() => string | undefined) | undefined); getInputSchema(): z.ZodObject<{ dryRun: z.ZodOptional; job: z.ZodOptional; runKey: z.ZodString; runner: z.ZodOptional; workspace: z.ZodOptional; }, z.core.$strip>; getDefinition(): ToolDefinition; execute(input: RecoverWorkflowToolInput): Promise; } //#endregion //#region src/tools/RunWorkflowTool.d.ts declare const RunWorkflowInputSchema: z.ZodObject<{ workflowPath: z.ZodString; runner: z.ZodOptional; cliAgent: z.ZodOptional; job: z.ZodOptional; inputs: z.ZodOptional>; env: z.ZodOptional>; secretFile: z.ZodOptional; launcher: z.ZodOptional>; dryRun: z.ZodOptional; continueOnError: z.ZodOptional; keepWorktree: z.ZodOptional; prompt: z.ZodOptional; name: z.ZodOptional; workspace: z.ZodOptional; statusFile: z.ZodOptional; }, z.core.$strip>; type RunWorkflowToolInput = z.infer; /** * MCP tool wrapper around `RunWorkflowService`. */ declare class RunWorkflowTool implements Tool { private service; static readonly TOOL_NAME = "run_workflow"; constructor(service?: RunWorkflowService); getInputSchema(): z.ZodObject<{ workflowPath: z.ZodString; runner: z.ZodOptional; cliAgent: z.ZodOptional; job: z.ZodOptional; inputs: z.ZodOptional>; env: z.ZodOptional>; secretFile: z.ZodOptional; launcher: z.ZodOptional>; dryRun: z.ZodOptional; continueOnError: z.ZodOptional; keepWorktree: z.ZodOptional; prompt: z.ZodOptional; name: z.ZodOptional; workspace: z.ZodOptional; statusFile: z.ZodOptional; }, z.core.$strip>; /** * Return the MCP tool definition and input schema. */ getDefinition(): ToolDefinition; /** * Execute a workflow run and convert the result into MCP tool content. */ execute(input: RunWorkflowToolInput): Promise; } //#endregion //#region src/tools/StopWorkflowTool.d.ts declare const StopWorkflowInputSchema: z.ZodObject<{ expectedRunId: z.ZodString; reason: z.ZodOptional; runKey: z.ZodString; workspace: z.ZodOptional; }, z.core.$strip>; type StopWorkflowToolInput = z.input; declare class StopWorkflowTool implements Tool { private registry; static readonly TOOL_NAME = "stop_workflow"; constructor(registry?: WorkflowRegistryService); getInputSchema(): z.ZodObject<{ expectedRunId: z.ZodString; reason: z.ZodOptional; runKey: z.ZodString; workspace: z.ZodOptional; }, z.core.$strip>; getDefinition(): ToolDefinition; execute(input: StopWorkflowToolInput): Promise; } //#endregion //#region src/embeddedWorkflowFeature.d.ts interface EmbeddedWorkflowFeatureOptions { registry?: WorkflowRegistryService; runService?: RunWorkflowService; } interface RecoverWorkflowToolOptions { ownerSessionId?: () => string | undefined; } /** * Observation and lifecycle control for runs, in one handle. * * A host embedding this feature usually does not run the workflow: a workflow * declaring `launch-command` is handed to a terminal launcher and executes in * another process entirely. Everything it can know therefore comes from what * that process leaves in the registry, which is what the observer half reads. * The control half is the pre-existing request-file mechanism, brought in here * so a host holds one object rather than a reader and a controller. */ interface WorkflowRunControl { /** Subscribe to one lifecycle channel. Returns its own unsubscribe. */ on(name: TName, handler: WorkflowRunObserverHandler): WorkflowRunUnsubscribe; pause(runKey: string, expectedRunId: string, workspace?: string, reason?: string): Promise; /** Sweep now instead of waiting for a notification or the interval. */ refresh(): Promise; resume(runKey: string, expectedRunId: string, workspace?: string): Promise; /** Begin observing and report the runs already in flight. */ start(): Promise; stop(runKey: string, expectedRunId: string, workspace?: string, reason?: string): Promise; dispose(): void; } interface EmbeddedWorkflowFeature { registry: WorkflowRegistryService; parser: WorkflowParserService; runService: RunWorkflowService; recoverService: RunWorkflowService; runTool: RunWorkflowTool; listWorkflowsTool: ListWorkflowsTool; createListStatusesTool(options?: { recordFilter?: (record: WorkflowRunRecord) => boolean; }): ListWorkflowStatusesTool; createRecoverTool(options?: RecoverWorkflowToolOptions): RecoverWorkflowTool; createControlTool(): ControlWorkflowTool; createRunControl(options?: WorkflowRunObserverOptions): WorkflowRunControl; createStopTool(): StopWorkflowTool; } declare function createEmbeddedWorkflowFeature(options?: EmbeddedWorkflowFeatureOptions): EmbeddedWorkflowFeature; //#endregion export { type AgentDecisionTrigger, ControlWorkflowTool, type EmbeddedWorkflowFeature, type EmbeddedWorkflowFeatureOptions, InterpolationContext, type Job, type JobHookBlock, Logger, type MatrixEntry, PHASE_JOB_POST, PHASE_JOB_PRE, PROGRESS_FILENAME, type PreBlock, type ProgressTailReader, type RecoverWorkflowToolOptions, type RepairTriage, type RunDirectory, type RunDirectoryEntry, RunDirectoryService, RunningService, type ServiceDef, StdioTransportHandler, type Step, type StepCommand, type StepCommandMap, StepRunOptions, type Strategy, Tool, ToolDefinition, type Workflow, type WorkflowControlAction, type WorkflowControlInput, type WorkflowControlRequest, WorkflowControlService, type WorkflowExecutionCursor, type WorkflowExecutionState, type WorkflowInput, type WorkflowKeybindings, type WorkflowLauncherMetadata, type WorkflowLauncherType, type WorkflowOutcome, type WorkflowPauseRequest, type WorkflowProgressEvent, type WorkflowProgressJob, type WorkflowProgressStatus, type WorkflowProgressStep, type WorkflowProgressTail, WorkflowRegistryService, type WorkflowRepairJob, type WorkflowRepairJobAttempt, type WorkflowRepairJobStatus, type WorkflowRepairRecord, type WorkflowRepairRoutingFallback, type WorkflowRepairStatus, type WorkflowResumeMode, type WorkflowResumeRequest, type WorkflowRunControl, type WorkflowRunEvent, type WorkflowRunFinishedEvent, type WorkflowRunHandle, type WorkflowRunJobEvent, type WorkflowRunObserverEventMap, type WorkflowRunObserverEventName, type WorkflowRunObserverHandler, type WorkflowRunObserverOptions, WorkflowRunObserverService, type WorkflowRunPhase, type WorkflowRunRecord, type WorkflowRunStepEvent, type WorkflowRunUnsubscribe, type WorkflowStage, type WorkflowStopRequest, type WorkflowWatchFactory, type WorkflowWatchHandle, type WorktreeConfig, type WorktreeHook, createEmbeddedWorkflowFeature, createServer, currentWorkflowPosition, readWorkflowProgress, readWorkflowProgressFrom, runIdentity, summarizeWorkflowProgress, workflowRunPhase };