/** * Exit watching for broker-spawned agents (Phase 3). * * A locally-spawned child reports its death through `child.on("exit")`; a * broker-spawned process is the SUPERVISOR's child, so the MCP has no handle to * wait on. Communication is strictly one-way (MCP → supervisor — hard * criterion), so the supervisor cannot push the event either. Instead this * watcher polls. * * Liveness is JOB-based, keyed on the THREAD — never the raw pid the broker * returned at spawn. On Windows both claude.exe and copilot.exe are LAUNCHERS: * they fork the real agent (a node child with a different pid) into the thread's * job, then the launcher exits. Watching the launcher pid is the liveness * regression this replaces — it fired a bogus "exited" the moment the launcher * died, decommissioning the still-working child. The worker is "exited" only * when its JOB has drained (`/proc/alive?threadId=`), which the broker confirms * by recording a terminal ledger row once no member remains. * * Degradation: broker unreachable → "cannot confirm → treat alive" (the * audited-safe direction); the watch is kept, never resolved. A slow cold start * (~50s for Copilot) keeps its launcher as a live job member, so it reports * alive throughout; a first-connect grace additionally refuses to resolve an * UNCONFIRMED "gone" until it elapses, so the degraded no-job path can't misfire * during a slow start. A broker-CONFIRMED exit resolves immediately regardless. * A watched thread is only resolved ONCE. */ export interface WatchedSpawn { /** The pid the broker returned at spawn (may be a launcher that has since * forked-and-exited) — used only for logging; liveness is by threadId. */ pid: number; threadId: number; onExit: (exitCode: number | null) => void; } /** Register a broker-spawned thread for exit detection. Keyed by threadId. */ export declare function watchBrokerSpawnExit(entry: WatchedSpawn): void; /** Test hooks. */ export declare function stopExitWatcher(): void; export declare function sweepOnceForTest(): Promise; export declare function watchedCountForTest(): number; /** Shrink (or restore, with null) the first-connect grace so grace-path tests * don't wait 90s. */ export declare function setExitWatchGraceForTest(ms: number | null): void; //# sourceMappingURL=spawn-exit-watcher.d.ts.map