/** * Execution detection — mirrors {@link PortDetector} (core/port-detector.ts). * * A run can start two ways in the harness, and this catches both: * 1. The CLI prints `✓ Started execution ` (`sapiom agents run`). * 2. The coding agent starts the run via the MCP run tool — the common path — * whose result carries the id as an `executionId` field * (`"executionId":""` / `executionId: `). * The detector is fed the SAME tool.call output PortDetector is (server/index.ts * `onNormalizedEvent`, including the tool RESPONSE summary), so an MCP-triggered * run is caught without changing how runs are triggered. It fires `onExecution` * once per distinct (session, executionId); the integrator wires that to * broadcast `{ type: "execution.started", … }` on /ws/events. * * Same streaming-safe design as PortDetector: a match touching the very end of * the buffered text is held back (the id may still be growing in the next * chunk) and finalized by `flush()`, which the integrator calls right after * feeding a discrete, already-complete string (one tool.call field). */ /** * Pure parser: every execution id announced in a chunk of CLI/tool output, in * order (empty when the chunk announces none). This is the mutation-tested * core — the {@link ExecutionDetector} class only adds streaming buffering and * per-session dedupe on top of it. */ export declare function parseExecutionIds(text: string): string[]; /** Where a detected run executes. Only `"prod"` is emitted today: the CLI's * `Started execution` line is the prod-run announcement; local runs are * rendered from their final result, not polled (see the design). */ export type ExecutionTarget = "prod" | "local"; export interface ExecutionDetectorDeps { onExecution(harnessSessionId: string, executionId: string, target: ExecutionTarget): void; } /** * Stateful, streaming-safe, and dedupes per (session, executionId) so a run id * that reappears in output only ever fires `onExecution` once for the session's * lifetime. `reset()` clears a session's state on exit so a reused session id * starts clean. */ export declare class ExecutionDetector { private readonly deps; private readonly buffers; private readonly seen; constructor(deps: ExecutionDetectorDeps); feed(chunk: string, harnessSessionId: string): void; /** * Finalizes whatever's held back for a session, immediately. Call this right * after `feed()` whenever the fed text is a discrete, complete string (one * tool.call field): without it, an id landing at the very end — the common * shape "✓ Started execution exec_123" — would be held pending forever, since * no "next chunk" is coming. */ flush(harnessSessionId: string): void; /** Drops buffered/dedupe state for a session — call on session exit so a * reused session id starts clean. */ reset(harnessSessionId: string): void; private tryEmit; } //# sourceMappingURL=execution-detector.d.ts.map