/** * dispatch-fork-core — the shared fork + IPC settle + host-RPC supervisor for the * ADR-0054 out-of-process external-tool worker (M4-C / M4-D / M4-F). * * Both supervisors fork the SAME internal `__tool-command-worker` subcommand and * settle on the SAME `ToolCommandResult` shape: * - `dispatch-external-tool-command.ts` runs an external tool's COMMAND; * - `dispatch-external-tool-hook.ts` (M4-F) runs a LIFECYCLE HOOK. * * They differ only in the {@link ToolCommandWorkerSpec} they marshal (a * `commandName` vs a `hook`) and how they replay the result. This module owns the * common machinery so neither duplicates it: marshal the spec to a temp file, * fork the CLI binary as the worker subcommand (full bootstrap re-runs * worker-local), enforce a wall-clock timeout, serve mid-run host-RPC upcalls * against the REAL host `ToolCliContext`, and resolve the worker's result (or * reject with a structured {@link ToolError}). * * The host remains the ONLY process that performs the privileged effect; a worker * fault (throw / `process.exit` / crash / timeout / fork failure) becomes a * structured parent-side {@link ToolError} — the host never crashes and external * runtime NEVER falls back to in-host execution (ADR-0054 trust tier). */ import { type ToolError, type ToolProvenance } from '@opensip-cli/core'; import { type DispatchHostCtx } from './dispatch-replay-result.js'; import type { ToolCommandResult, ToolCommandWorkerSpec } from './tool-command-dispatch-types.js'; import type { ExternalAdapterProgressEvent } from '@opensip-cli/external-tool-adapter'; /** Default supervisor wall-clock timeout for one forked worker run (ms). */ export declare const DEFAULT_DISPATCH_TIMEOUT_MS = 120000; /** The internal worker subcommand the supervisor forks the CLI binary into. */ export declare const WORKER_SUBCOMMAND = "__tool-command-worker"; /** Resolve the package dir for an external tool, or fail with a structured error. */ export declare function requirePackageDir(provenance: ToolProvenance): string; /** * Marshal a worker spec to a temp file, fork the worker, enforce the timeout, and * resolve the worker's {@link ToolCommandResult}. The temp dir is always cleaned * up. `cliScript` defaults to the running CLI entry; tests point it at the dist * entry. `cwd` defaults to the spec's `opts.cwd` (or `process.cwd()`). */ export declare function runWorkerSpec(args: { readonly spec: ToolCommandWorkerSpec; readonly ctx: DispatchHostCtx; readonly cwd: string; readonly cliScript?: string; readonly timeoutMs?: number; readonly onAdapterProgress?: (event: ExternalAdapterProgressEvent) => void; }): Promise; /** * Build a structured supervisor-side dispatch error, logged with its failure * class. `code` is the worker error's canonical exit-class `ToolErrorCode` (when * the worker threw a typed `ToolError`); it preserves the typed exit code across * the fork boundary, which flattens the prototype chain. Reconstruction order: * * 1. `config-invalid` → `ConfigurationError` (exit 2). The frozen config * contract — set for a thrown `ConfigurationError` (binary-not-found / * no-project / baseline-missing) AND for the deep-config-pass failure. * 2. a recognized canonical `code` → that subclass (NotFound → 3, Network → 4, * Validation/Configuration → 2, PluginIncompatible → 5, Timeout → 1). * 3. otherwise → `SystemError` (exit 1) — genuine worker/transport faults * (`spawn` / `exit_nonzero` / `rpc_flood` / `timeout` / `ipc_error`). */ interface DispatchErrorInput { readonly spec: ToolCommandWorkerSpec; readonly message: string; readonly failureClass: string; readonly stderrTail?: string; readonly code?: string; readonly detailCode?: string; } export declare function dispatchError({ spec, message, failureClass, stderrTail, code, detailCode, }: DispatchErrorInput): ToolError; export {}; //# sourceMappingURL=dispatch-fork-core.d.ts.map