/** * The batch arm of `run`. * * `kimchi workflow run [--input |@] [--result-out ]` — the * headless CLI host (src/host/cli.ts) runs one workflow to a terminal state in the foreground and * maps the outcome onto the process exit status, so a scheduler (a pod, a CI job) needs nothing but * `$?` to know what happened. The in-session `/workflow run` keeps the same verb for the attended * surface; this module holds the pieces ONLY the batch surface needs on top of the shared * {@link executeRun} lifecycle. * * Three things distinguish a batch run from an attended one, and each is load-bearing: * * - **Blocking, never attended.** `/workflow run` answers a `blocked` run with the inline * questionnaire (spec §10.2); a batch run has no human, so a block IS the outcome — reported, * optionally persisted, and mapped to exit code 2. Nothing about the engine differs; the run * lifecycle is the shared {@link executeRun}. * - **The exit status is the contract** (`exitCodeForStatus`): 0 completed, 2 blocked, 3 cancelled, * 4 crashed or never-started. Codes 0/1 are the conventions everything already uses, so the * workflow vocabulary starts at 2 and stays out of the way. Delivered through `process.exitCode` * rather than `process.exit` — every durable write (the event log, the artifact) has already been * awaited by the time it is set, and a hard exit could strap buffered stderr writes to a pipe. * - **stdout stays machine-clean.** Progress is the plain append-only renderer on stderr * (progress-plain.ts, §8.2), whichever mode the harness happens to be in — the batch surface * exists for the mode matrix's headless rows, so the TUI surfaces have nothing to contribute to * it, and `--result-out` (result-artifact.ts) is what a machine reads off stdout's behalf. */ import type { RunResult } from "../../engine/types.ts"; import type { ActiveRuns } from "../active-runs.ts"; import { type LineWriter } from "../progress-plain.ts"; import type { ProgressFor } from "../progress-sink.ts"; import type { RunStore } from "../types.ts"; import { type CommandCtx, type StartAgent } from "./context.ts"; /** * The status → exit-code contract, centralised here because it is the whole reason the batch * surface exists: schedulers branch on `$?`, and every surface that reports a terminal state must * agree on these numbers. `blocked` (2) is a workflow asking for a human that is not there; * `cancelled` (3) covers both SIGINT/SIGTERM and an engine-level cancel; `crashed` (4) also covers * runs that never started — an unknown workflow, a malformed command line, or a rejected `--input` * fails the JOB the same way an engine crash does. */ export declare function exitCodeForStatus(status: RunResult["status"]): 0 | 2 | 3 | 4; /** * The one surface a batch run renders to: plain, append-only lines on stderr (progress §8), * regardless of the harness mode. No widgets, no cards, nothing on stdout. */ export declare function plainProgressFor(write: LineWriter): ProgressFor; /** A batch run's fully resolved invocation: what `run` parsing produced, with a target present. */ export interface BatchRunArgs { readonly target: string; readonly inputArg: string | undefined; readonly resultOut: string | undefined; } /** * The seams a batch run needs from its process, injectable so the exit-code protocol is testable * without exiting a test runner. Defaults are the real process: `exitCode` (not `process.exit` — * see the module header) and stderr lines. */ export interface BatchRunDeps { readonly exit?: (code: number) => void; /** Warnings (signal notices, artifact write failures). Default: stderr. */ readonly warn?: (line: string) => void; /** Plain progress lines. Default: stderr. */ readonly stderr?: LineWriter; /** Signal source (default: the real process). Injectable so a test can raise SIGINT without signalling anything real. */ readonly signals?: BatchSignalSource; } /** The two verbs of the process EventEmitter a batch run subscribes to — structurally both `process` and a bare `EventEmitter`. */ export interface BatchSignalSource { on(signal: string, handler: () => void): unknown; off(signal: string, handler: () => void): unknown; } /** * One run to its terminal state, with the batch contract on top: resolve and validate exactly like * `run` (any failure there is exit 4), then drive the run in the foreground. SIGINT/SIGTERM take * the engine's graceful cancellation path — the same durable `run-cancelled` + cooperative abort * `/workflow cancel` uses — and the run's eventual `cancelled` result is what exit 3 reports, so * the checkpoint that lets the run be resumed always lands before the process ends. */ export declare function handleBatchRun(ctx: CommandCtx, store: RunStore, activeRuns: ActiveRuns, startAgent: StartAgent, args: BatchRunArgs, deps?: BatchRunDeps): Promise; //# sourceMappingURL=batch.d.ts.map