/** Default wall-clock budget for the ConPTY probe. A healthy allocation * returns in well under a second; 15s is generous headroom that still bounds * the freeze. Overridable via env for tests (and as an escape hatch). */ export declare const PTY_PROBE_TIMEOUT_MS: number; export type PtyProbeOutcome = "healthy" | "inconclusive" | "wedged"; export interface PtyProbeResult { outcome: PtyProbeOutcome; /** Human-readable context for logs / the SKIP message. */ detail?: string; } /** Minimal surface of a worker the probe drives. `node:worker_threads`'s * `Worker` satisfies it; tests inject a fake. */ export interface ProbeWorkerLike { on(event: "message", cb: (msg: any) => void): void; on(event: "error", cb: (err: any) => void): void; on(event: "exit", cb: (code: number) => void): void; terminate(): Promise | void; } /** * Probe whether a new ConPTY can be allocated in this process without wedging. * Never rejects — every failure mode maps to an outcome the caller can act on. * * @param opts.ptyModulePath Absolute path to the node-pty backend the worker * should load (resolved on the main thread; the worker can't run the async * heavy-dep resolver itself). * @param opts.timeoutMs Budget before a non-responding probe is declared * "wedged". Defaults to {@link PTY_PROBE_TIMEOUT_MS}. * @param opts.createWorker Injectable worker factory (tests). */ export declare function probePtyAllocation(opts: { ptyModulePath: string; timeoutMs?: number; createWorker?: (data: { ptyModulePath: string; }) => ProbeWorkerLike; }): Promise; /** * Verify the PTY backend is PHYSICALLY on disk before any spawn, healing a * pruned install by force-reinstalling — issue #501's actual mechanism. * * A mid-run JIT `npm install` of another heavy dep used to prune node-pty's * files from the runtime cache while the module stayed loaded (the OS-locked * .node binary survives; the JS support files node-pty needs at spawn time do * not). The stale resolution + ESM caches then serve the in-memory module * without touching disk, and the next `pty.spawn` freezes the process inside * a native wait. So "the module loaded" is NOT sufficient — the resolved path * must exist on disk, and when it doesn't we reinstall (same paths → the * already-loaded module's support files are back) rather than proceed onto a * spawn we know can wedge. If the reinstall can't produce the files, throw * the `NODE_PTY_UNAVAILABLE`-tagged error so runShell degrades to SKIPPED. * * All collaborators are injectable for tests; `exists` defaults to * `fs.existsSync`. */ export declare function ensurePtyBackendOnDisk(opts: { resolvePath: () => string | null; reinstall: () => Promise; exists?: (p: string) => boolean; }): Promise; /** * Windows-only gate for the `tty` spawn path. Probes ConPTY allocation and, if * it is wedged (the #501 freeze signature), throws a `NODE_PTY_UNAVAILABLE`- * tagged error so the caller (runShell) degrades the step to SKIPPED instead of * hanging. Returns (no-op) on non-Windows, when no backend path resolved, or * when the probe is healthy/inconclusive — the caller then proceeds to the * direct spawn. * * `platform` and `probe` are injectable so the gate is unit-testable on any host. */ export declare function assertConptyAllocatable(opts: { ptyModulePath: string | null | undefined; platform?: string; probe?: (o: { ptyModulePath: string; }) => Promise; }): Promise; //# sourceMappingURL=ptyWatchdog.d.ts.map