@code-yeongyu/senpi 2026.9.28-5 → 2026.9.28-7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/bundle/chunks/{anthropic-messages-GG4ZKS6A.js → anthropic-messages-QOQJCY3F.js} +1 -1
- package/dist/bundle/chunks/{app-server-command-3AJWPHKJ.js → app-server-command-OUTRKHMK.js} +8 -8
- package/dist/bundle/chunks/{chunk-XYGXUFMG.js → chunk-3HCYHGK2.js} +1 -1
- package/dist/bundle/chunks/{chunk-EXUI5D5V.js → chunk-56COAYOU.js} +9 -9
- package/dist/bundle/chunks/{chunk-MMHQLGF2.js → chunk-AIM2YESB.js} +1 -1
- package/dist/bundle/chunks/{chunk-4BDFNRBE.js → chunk-B32PXL7U.js} +1 -1
- package/dist/bundle/chunks/chunk-CEMOA3TF.js +2 -0
- package/dist/bundle/chunks/{chunk-XNIX26QC.js → chunk-DB2X7SOZ.js} +2 -2
- package/dist/bundle/chunks/chunk-E5F5SVZF.js +5 -0
- package/dist/bundle/chunks/{chunk-OHJLQ7BY.js → chunk-F2YU5BZG.js} +1 -1
- package/dist/bundle/chunks/{chunk-BQGVC47Y.js → chunk-FILEUW2D.js} +1 -1
- package/dist/bundle/chunks/{chunk-JGRPPPHS.js → chunk-JASECXGC.js} +1 -1
- package/dist/bundle/chunks/{chunk-YLIS5N3W.js → chunk-JK5LVAOU.js} +1 -1
- package/dist/bundle/chunks/{chunk-KDZAVHA7.js → chunk-L4OOEWAT.js} +2 -2
- package/dist/bundle/chunks/{chunk-Z5NVK72W.js → chunk-LM2UMEX6.js} +1 -1
- package/dist/bundle/chunks/{chunk-C5I2LUOI.js → chunk-SQUUL72H.js} +1 -1
- package/dist/bundle/chunks/{chunk-LEAJXPT2.js → chunk-TOCWAEQB.js} +1 -1
- package/dist/bundle/chunks/{chunk-YEMM3LPR.js → chunk-VW3QZSX3.js} +1 -1
- package/dist/bundle/chunks/{chunk-7SFG425F.js → chunk-Y4CH7LYI.js} +2 -2
- package/dist/bundle/chunks/chunk-YJUO37UX.js +2 -0
- package/dist/bundle/chunks/{cli-main-NUSBF3HE.js → cli-main-26P4V2BK.js} +1 -1
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{help-fast-path-A4S4KOQ6.js → help-fast-path-BOMUI7U3.js} +1 -1
- package/dist/bundle/chunks/{host-command-D2CHSATG.js → host-command-ZVXNTXMN.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle-MPLSJ5NB.js +3 -0
- package/dist/bundle/chunks/host-lifecycle.js +3 -3
- package/dist/bundle/chunks/{interactive-host-runtime-AAK47HIV.js → interactive-host-runtime-Q5EORM6B.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-LSTD6EUQ.js → interactive-mode-OVSKUTVC.js} +1 -1
- package/dist/bundle/chunks/{list-tips-S4U7TKER.js → list-tips-ARO4HRVK.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-5WNZ7XRV.js → multi-session-host-LJNXZRFA.js} +7 -7
- package/dist/bundle/chunks/{openai-completions-DVEOAQK4.js → openai-completions-BHE6TMUP.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-7H2ADNW4.js → openai-responses-OGQ5QORF.js} +1 -1
- package/dist/bundle/chunks/{package-manager-cli-3HZYQYVX.js → package-manager-cli-MJCRY2JU.js} +1 -1
- package/dist/bundle/chunks/{rotation-stream-F36RJ6VP.js → rotation-stream-Q2EVDMUU.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-GMPBEVSL.js → rpc-mode-LY4HAZ5G.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-BYWZGYOJ.js → schedule-command-3ANAEUY6.js} +1 -1
- package/dist/bundle/chunks/{session-picker-6VU2F5VF.js → session-picker-DRM7AGPY.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +37 -37
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.js +2 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/core/extensions/builtin/btw/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/btw/index.js +3 -1
- package/dist/core/extensions/builtin/btw/index.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +2 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/native.d.ts +1 -0
- package/dist/core/extensions/builtin/websearch/websearch/native.d.ts.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/native.js +8 -1
- package/dist/core/extensions/builtin/websearch/websearch/native.js.map +1 -1
- package/dist/main.d.ts +2 -2
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +25 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/app-server/cli-args.d.ts +3 -0
- package/dist/modes/app-server/cli-args.d.ts.map +1 -1
- package/dist/modes/app-server/cli-args.js +25 -4
- package/dist/modes/app-server/cli-args.js.map +1 -1
- package/dist/modes/app-server/daemon/probe.d.ts +1 -0
- package/dist/modes/app-server/daemon/probe.d.ts.map +1 -1
- package/dist/modes/app-server/daemon/probe.js +4 -1
- package/dist/modes/app-server/daemon/probe.js.map +1 -1
- package/dist/modes/app-server/daemon/spawn.d.ts +26 -0
- package/dist/modes/app-server/daemon/spawn.d.ts.map +1 -0
- package/dist/modes/app-server/daemon/spawn.js +112 -0
- package/dist/modes/app-server/daemon/spawn.js.map +1 -0
- package/dist/modes/app-server/daemon.d.ts.map +1 -1
- package/dist/modes/app-server/daemon.js +14 -112
- package/dist/modes/app-server/daemon.js.map +1 -1
- package/dist/modes/app-server/extension-paths.d.ts +7 -0
- package/dist/modes/app-server/extension-paths.d.ts.map +1 -0
- package/dist/modes/app-server/extension-paths.js +10 -0
- package/dist/modes/app-server/extension-paths.js.map +1 -0
- package/dist/modes/app-server/index.d.ts.map +1 -1
- package/dist/modes/app-server/index.js +4 -1
- package/dist/modes/app-server/index.js.map +1 -1
- package/dist/modes/app-server/runtime.d.ts +5 -1
- package/dist/modes/app-server/runtime.d.ts.map +1 -1
- package/dist/modes/app-server/runtime.js +19 -3
- package/dist/modes/app-server/runtime.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/computer-tips.js +1 -1
- package/dist/modes/interactive/tips/catalog/computer-tips.js.map +1 -1
- package/dist/modes/rpc/custom-capability.d.ts +5 -0
- package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
- package/dist/modes/rpc/custom-capability.js +5 -0
- package/dist/modes/rpc/custom-capability.js.map +1 -1
- package/dist/modes/rpc/host-identity-env.d.ts +20 -0
- package/dist/modes/rpc/host-identity-env.d.ts.map +1 -0
- package/dist/modes/rpc/host-identity-env.js +20 -0
- package/dist/modes/rpc/host-identity-env.js.map +1 -0
- package/dist/modes/rpc/host-lifecycle.js +1 -1
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/host-observe-request.d.ts +2 -0
- package/dist/modes/rpc/host-observe-request.d.ts.map +1 -1
- package/dist/modes/rpc/host-observe-request.js +4 -0
- package/dist/modes/rpc/host-observe-request.js.map +1 -1
- package/dist/modes/rpc/host-spawn-environment.js +1 -1
- package/dist/modes/rpc/host-spawn-environment.js.map +1 -1
- package/dist/modes/rpc/host-warm.d.ts +57 -0
- package/dist/modes/rpc/host-warm.d.ts.map +1 -0
- package/dist/modes/rpc/host-warm.js +125 -0
- package/dist/modes/rpc/host-warm.js.map +1 -0
- package/dist/modes/rpc/protocol-identity.d.ts +2 -11
- package/dist/modes/rpc/protocol-identity.d.ts.map +1 -1
- package/dist/modes/rpc/protocol-identity.js +2 -11
- package/dist/modes/rpc/protocol-identity.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +24 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +2 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts +1 -1
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +12 -1
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +6 -2
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +6 -0
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/docs/app-server-daemon.md +1 -1
- package/docs/app-server.md +3 -0
- package/docs/rpc.md +48 -2
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +24 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-endpoint.d.ts +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-endpoint.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-endpoint.js +48 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-endpoint.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-errors.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-errors.js +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/github-copilot-errors.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js +18 -36
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.d.ts +5 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.js +6 -5
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.js +15 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
- package/dist/bundle/chunks/chunk-A4UMPXQF.js +0 -2
- package/dist/bundle/chunks/chunk-HH3KJDWA.js +0 -2
- package/dist/bundle/chunks/chunk-XPJLBOWV.js +0 -5
- package/dist/bundle/chunks/host-lifecycle-S7O5K62Z.js +0 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-lifecycle.js","sourceRoot":"","sources":["../../../src/modes/rpc/host-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * Lifecycle supervisor for the shared RPC socket host started by ensureHost().\n *\n * Process tree:\n *\n * ensureHost() ──detached──▶ host-lifecycle.ts (this supervisor, owns the pidfile)\n * │ byte-proxies the public socket\n * ▼\n * cli-main --mode rpc --listen unix://<public>.internal\n *\n * The supervisor exists to enforce the host lifecycle policy without touching the\n * RPC host itself:\n *\n * - cold start: `transient` (default) means the host lives for the current login\n * session and idle-exits; `persistent` never idle-exits.\n * - idle exit: after a continuous window with zero attached client connections\n * and zero active agent turns, the supervisor tears the host down cleanly\n * (child SIGTERM first so the host flushes pending output and removes its own\n * socket, then pidfile/settings removal mirroring ensureHost's cleanupState).\n *\n * Observability without host changes: proxying the public socket yields the\n * exact connection count, and the supervisor keeps one always-on observer\n * connection to the internal socket. The multi-session host broadcasts every\n * session lifecycle/agent event to every connection, so the observer sees\n * `agent_start`/`agent_settled` for all sessions even when no client is\n * attached. If the observer connection is ever unhealthy, activity is reported\n * as unknown (non-idle), so a broken observer can only keep the host alive,\n * never kill it mid-turn - for one idle window. Past that, unknown has held\n * the host open for as long as idleness itself would have, and it stops\n * counting as busy; the link keeps reconnecting the whole time (#1979).\n *\n * Lifetime binding: the host is spawned with an extra inherited pipe on fd 3\n * whose write end this supervisor holds and never writes to. The kernel closes\n * that end whenever the supervisor dies - including SIGKILL, an OOM kill, or a\n * crash, where no JS handler runs at all - so the host reads EOF and shuts down\n * cleanly, removing the private internal directory. `stopChild()` remains the\n * fast path for orderly shutdowns; the pipe is what makes an orphaned host\n * impossible. `SENPI_RPC_HOST_WATCH_PPID` is passed alongside as a belt-and-\n * braces fallback for platforms where the extra fd is not inherited.\n */\nimport { type ChildProcess, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync, readFileSync, realpathSync, writeSync } from \"node:fs\";\nimport { access, chmod, mkdir, readFile, rename, rm, unlink, writeFile } from \"node:fs/promises\";\nimport { createConnection, createServer, type Server, type Socket } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, extname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { getAgentDir, isBunBinary, isBundledNode } from \"../../config.ts\";\nimport { processIsLive, readProcessStartTime } from \"../app-server/daemon/process.ts\";\nimport { classifyChildExit, noteChildExit } from \"./host-child-exit.ts\";\nimport { ClientOccupancy } from \"./host-client-occupancy.ts\";\nimport {\n\tDEFAULT_HANDOFF_GRACE_MS,\n\tHANDOFF_GRACE_MS_ENV,\n\ttype HostActivity,\n\tIdleExitDecider,\n\tparseIdleExitMs,\n\tresolveHostPolicy,\n} from \"./host-lifecycle-policy.ts\";\n\n// The exit verdict moved to ./host-child-exit.ts with the crash recording it now feeds; it stays\n// exported from here so every existing importer keeps resolving it at its original home.\nexport { classifyChildExit } from \"./host-child-exit.ts\";\n\n// The cold-start/idle-exit policy and its decision core live in ./host-lifecycle-policy.ts; they stay\n// exported from here so every existing importer keeps resolving them at their original home.\nexport {\n\tDEFAULT_HANDOFF_GRACE_MS,\n\tDEFAULT_HOST_IDLE_EXIT_MS,\n\tHANDOFF_GRACE_MS_ENV,\n\tHOST_COLD_START_ENV,\n\tHOST_IDLE_EXIT_MS_ENV,\n\ttype HostActivity,\n\ttype HostColdStart,\n\ttype HostLifecyclePolicy,\n\ttype HostLifecyclePolicyInput,\n\tIdleExitDecider,\n\ttype IdleExitDecision,\n\tparseColdStart,\n\tparseIdleExitMs,\n\tresolveHostPolicy,\n} from \"./host-lifecycle-policy.ts\";\n\nimport { hostCrashCleanupPaths } from \"./host-cleanup-paths.ts\";\nimport { createHostDaemonPaths, generationPaths, HOST_DAEMON_DIR_ENV } from \"./host-daemon-paths.ts\";\nimport { releaseGeneration } from \"./host-daemon-registration.ts\";\nimport { watchForSupersession } from \"./host-supersession.ts\";\nimport {\n\tHOST_CLEANUP_PATHS_ENV,\n\tHOST_PUBLIC_SOCKET_ENV,\n\tHOST_SCRATCH_DIR_ENV,\n\tHOST_WATCH_FD_ENV,\n\tHOST_WATCH_PPID_ENV,\n} from \"./host-watchdog.ts\";\nimport { attachJsonlLineReader, MAX_RPC_LINE_CHARACTERS } from \"./jsonl.ts\";\nimport { activeTurnsForIdleDecision, createObserverLink } from \"./observer-link.ts\";\nimport { HOST_INSTANCE_ID_ENV } from \"./protocol-identity.ts\";\nimport {\n\tMAX_SOCKET_PATH_BYTES,\n\tPUBLIC_SOCKET_IDENTITY_FILE,\n\ttype SocketFileIdentity,\n\tshieldSocketDuringClose,\n\tstatSocketIdentity,\n\tunlinkOwnedSocket,\n\twriteSocketIdentityFile,\n} from \"./socket-ownership.ts\";\nimport {\n\tauthenticateSocket,\n\tcreateSocketSecret,\n\tensureSocketSecret,\n\tresolveSocketTransportAddress,\n\tSOCKET_SECRET_FILE_ENV,\n\tsendSocketHandshake,\n\tsocketSecretPath,\n} from \"./socket-transport.ts\";\n\nconst CHILD_STOP_TIMEOUT_MS = 5_000;\n/** Win32 named-pipe shutdown can leave supervisor handles live after close starts. */\nconst WINDOWS_SUPERVISOR_SHUTDOWN_HARD_EXIT_MS = 2_000;\n\n/**\n * Child stdio slot carrying the supervisor-lifetime pipe. The supervisor holds\n * the write end open and never writes; the kernel closes it when the supervisor\n * dies for ANY reason (SIGKILL, OOM kill, crash), so the host sees EOF on this\n * fd and shuts itself down. Catchable-signal cleanup alone cannot do this.\n */\nconst CHILD_WATCH_FD = 3;\n\n/**\n * The internal hop must stay short enough for sun_path (104 bytes on macOS)\n * regardless of where the public socket lives, and private against other local\n * users, so it gets its own 0700 directory under the OS temp directory.\n *\n * On win32 the directory lives under the caller-supplied rpc-host-daemon\n * directory, which ensureHost() creates but a direct --internal-rpc-host-supervisor\n * launch does not, so the parent is created recursively.\n */\nexport async function createInternalSocketPath(\n\tbaseDir = tmpdir(),\n\tplatform: NodeJS.Platform = process.platform,\n): Promise<{ socket: string; dir?: string; secretPath?: string }> {\n\tif (platform === \"win32\") {\n\t\tconst dir = join(baseDir, `internal-${randomUUID()}`);\n\t\tawait mkdir(dir, { recursive: true, mode: 0o700 });\n\t\treturn {\n\t\t\tsocket: `\\\\\\\\.\\\\pipe\\\\senpi-rpc-internal-${randomUUID()}`,\n\t\t\tdir,\n\t\t\tsecretPath: join(dir, \"secret\"),\n\t\t};\n\t}\n\tconst dir = join(tmpdir(), `senpi-rpc-host-internal-${randomUUID().slice(0, 8)}`);\n\tawait mkdir(dir, { recursive: false, mode: 0o700 });\n\tawait writeFile(\n\t\tjoin(dir, \".owner\"),\n\t\tJSON.stringify({\n\t\t\tpid: process.pid,\n\t\t\tprocessStartTime: await readProcessStartTime(process.pid),\n\t\t\tcreatedAt: Date.now(),\n\t\t}),\n\t\t{ mode: 0o600 },\n\t);\n\treturn { socket: join(dir, \"host.sock\"), dir, secretPath: join(dir, \".secret\") };\n}\n\nexport interface SupervisorLaunch {\n\treadonly socket: string;\n\treadonly hostArgs: readonly string[];\n\t/** Optional runtime command used by rebranded/bundled callers. */\n\treadonly childCommand?: string;\n\treadonly childArgs?: readonly string[];\n\t/** Explicit ownership directory for callers whose environment is not yet branded. */\n\treadonly agentDir?: string;\n\t/**\n\t * Where this supervisor BINDS, when it is a successor generation: `<socket>.next-<gen>`.\n\t * It renames that entry over `socket` once its host answers - and never binds the live\n\t * public path, which belongs to the generation currently serving it.\n\t */\n\treadonly bindSocket?: string;\n\t/**\n\t * The public socket entry this generation is allowed to replace (`<dev>:<ino>`). The rename\n\t * happens only while the path still refers to it: a socket that changed underneath belongs to\n\t * somebody else now, and replacing it would unlink an endpoint this process cannot prove it owns.\n\t */\n\treadonly replaceIdentity?: SocketFileIdentity;\n}\n\n/** Hidden internal launch route: wire-invisible, never advertised by the public CLI surface. */\nexport const INTERNAL_SUPERVISOR_FLAG = \"--internal-rpc-host-supervisor\";\n\n/**\n * Engine-global flags a rebranded wrapper may legitimately prepend when it\n * re-dispatches this binary. `packages/omo-native` injects `--extension <dir>`\n * for every non-early command, which pushed the sentinel off argv[0].\n */\nconst INJECTABLE_PREFIX_FLAGS = new Set([\"--extension\"]);\n\n/**\n * Returns the internal supervisor payload when argv selects that route.\n *\n * The route dispatches when the sentinel is argv[0] OR is preceded only by\n * known injectable prefix flags and their values - the one perturbation\n * wrappers legitimately perform. Everything else disqualifies it: a positional\n * operand, `--`, or an unknown flag before the sentinel all return undefined,\n * so a user-supplied value that happens to equal the sentinel can never reach\n * the supervisor.\n *\n * The skipped prefix is deliberately NOT forwarded to the host: a wrapper\n * re-injects its own prefix on every re-entry, so the host child receives it\n * from the wrapper rather than twice from here.\n */\nexport function findInternalSupervisorArgs(argv: readonly string[]): readonly string[] | undefined {\n\tfor (let index = 0; index < argv.length; index++) {\n\t\tconst arg = argv[index];\n\t\tif (arg === INTERNAL_SUPERVISOR_FLAG) return argv.slice(index + 1);\n\t\t// A prefix flag only counts when its value is actually present.\n\t\tif (!INJECTABLE_PREFIX_FLAGS.has(arg) || index + 1 >= argv.length) return undefined;\n\t\tindex++;\n\t}\n\treturn undefined;\n}\n\n/** `--socket <path>` selects the public socket; every other argument is forwarded to the host CLI. */\nexport function parseSupervisorArgs(argv: readonly string[]): SupervisorLaunch | undefined {\n\tconst hostArgs: string[] = [];\n\tlet socket: string | undefined;\n\tlet childCommand: string | undefined;\n\tlet childArgs: readonly string[] | undefined;\n\tlet agentDir: string | undefined;\n\tlet bindSocket: string | undefined;\n\tlet replaceIdentity: SocketFileIdentity | undefined;\n\tfor (let index = 0; index < argv.length; index++) {\n\t\tconst arg = argv[index];\n\t\tif (arg === \"--socket\" && index + 1 < argv.length) {\n\t\t\tsocket = argv[++index];\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--child-command\" && index + 1 < argv.length) {\n\t\t\tchildCommand = argv[++index];\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--child-args\" && index + 1 < argv.length) {\n\t\t\ttry {\n\t\t\t\tconst parsed: unknown = JSON.parse(argv[++index]);\n\t\t\t\tif (Array.isArray(parsed) && parsed.every((value) => typeof value === \"string\")) childArgs = parsed;\n\t\t\t} catch {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--agent-dir\" && index + 1 < argv.length) {\n\t\t\tagentDir = argv[++index];\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--bind\" && index + 1 < argv.length) {\n\t\t\tbindSocket = argv[++index];\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--replace\" && index + 1 < argv.length) {\n\t\t\treplaceIdentity = parseSocketIdentity(argv[++index]);\n\t\t\tcontinue;\n\t\t}\n\t\thostArgs.push(arg);\n\t}\n\treturn socket === undefined\n\t\t? undefined\n\t\t: { socket, hostArgs, childCommand, childArgs, agentDir, bindSocket, replaceIdentity };\n}\n\n/** `<dev>:<ino>` as the ensure captured it; anything else is no identity at all, never a guess. */\nfunction parseSocketIdentity(value: string): SocketFileIdentity | undefined {\n\tconst match = /^(\\d+):(\\d+)$/.exec(value);\n\treturn match ? { dev: Number(match[1]), ino: Number(match[2]) } : undefined;\n}\n\n/** Resolves the committed CLI entry this supervisor wraps (source tree or built dist). */\nexport function resolveCliMainPath(): string {\n\tconst modulePath = fileURLToPath(import.meta.url);\n\tconst extension = modulePath.endsWith(\".ts\") ? \".ts\" : \".js\";\n\tconst unbundled = resolve(dirname(modulePath), \"..\", \"..\", `cli-main${extension}`);\n\tif (existsSync(unbundled)) return unbundled;\n\t// Bundled, \"..\" twice reaches the PACKAGE ROOT rather than dist/, naming a cli-main that\n\t// was never emitted. Take the entry from the package's own declared bin instead of\n\t// counting directories: it is the one statement of where the CLI lives that holds in\n\t// every layout. Falls back to the old path when nothing is declared, so a caller that\n\t// was working keeps working.\n\treturn resolveDeclaredCliEntry(modulePath) ?? unbundled;\n}\n\n/** The CLI entry declared by the nearest enclosing package.json, when it exists on disk. */\nfunction resolveDeclaredCliEntry(modulePath: string): string | undefined {\n\tlet dir = dirname(modulePath);\n\tfor (let depth = 0; depth < 8; depth += 1) {\n\t\tconst manifestPath = resolve(dir, \"package.json\");\n\t\tif (existsSync(manifestPath)) {\n\t\t\ttry {\n\t\t\t\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as {\n\t\t\t\t\tbin?: Record<string, string> | string;\n\t\t\t\t};\n\t\t\t\tconst declared = manifest.bin;\n\t\t\t\tconst candidates = typeof declared === \"string\" ? [declared] : Object.values(declared ?? {});\n\t\t\t\tfor (const candidate of candidates) {\n\t\t\t\t\tconst entry = resolve(dir, candidate);\n\t\t\t\t\tif (existsSync(entry)) return entry;\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t\treturn undefined;\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n\treturn undefined;\n}\n\n/**\n * Resolves the host child spawn. Explicit child commands (desktop launchers)\n * are forwarded untouched. The default re-enters the committed CLI entry\n * through the runtime, except in compiled standalone binaries, which always\n * boot their embedded entrypoint and would parse a script path as CLI\n * arguments - there the executable itself is the CLI, so the mode flags are\n * passed directly. Exported for tests.\n */\nexport function resolveHostChildLaunch(\n\tlaunch: SupervisorLaunch,\n\tinternalSocket: string,\n\tcompiled: boolean = isBunBinary,\n): { command: string; args: string[] } {\n\tif (launch.childCommand) {\n\t\treturn {\n\t\t\tcommand: launch.childCommand,\n\t\t\targs: [...(launch.childArgs ?? []), \"--listen\", `unix://${internalSocket}`],\n\t\t};\n\t}\n\treturn {\n\t\tcommand: process.execPath,\n\t\targs: [\n\t\t\t...(compiled ? [] : [...process.execArgv, resolveCliMainPath()]),\n\t\t\t\"--mode\",\n\t\t\t\"rpc\",\n\t\t\t\"--multi-session\",\n\t\t\t\"--listen\",\n\t\t\t`unix://${internalSocket}`,\n\t\t\t...launch.hostArgs,\n\t\t],\n\t};\n}\n\n/** Mirrors cross-spawn: survives cmd.exe parsing and `CommandLineToArgvW`. */\nfunction quoteWindowsShellArg(value: string): string {\n\tconst escaped = value\n\t\t.replace(/(\\\\*)\"/g, '$1$1\\\\\"')\n\t\t.replace(/(\\\\*)$/, \"$1$1\")\n\t\t.replace(/([()%!^\"<>&|;,])/g, \"^$1\");\n\treturn `\"${escaped}\"`;\n}\n\n/**\n * Windows refuses to spawn a `.cmd`/`.bat` without a shell, and Node's\n * `shell: true` concatenates argv without escaping it. Escape each original\n * value before adding the surrounding quotes so `.cmd`/`.bat` launchers survive\n * cmd.exe parsing without double-escaping.\n * Exported for tests.\n */\nexport function spawnableChildLaunch(\n\tlaunch: { command: string; args: string[] },\n\tplatform: NodeJS.Platform = process.platform,\n): { command: string; args: string[]; shell: boolean } {\n\tconst extension = extname(launch.command).toLowerCase();\n\tif (platform !== \"win32\" || (extension !== \".cmd\" && extension !== \".bat\")) {\n\t\treturn { ...launch, shell: false };\n\t}\n\treturn {\n\t\tcommand: quoteWindowsShellArg(launch.command),\n\t\targs: launch.args.map(quoteWindowsShellArg),\n\t\tshell: true,\n\t};\n}\n\nexport async function runHostSupervisor(launch: SupervisorLaunch): Promise<void> {\n\tconst paths = createHostDaemonPaths({ socket: launch.socket, agentDir: launch.agentDir ?? getAgentDir() });\n\t// Which generation this supervisor is: the ensure that spawned it says so, and a DIRECT launch\n\t// (the hidden supervisor route, with no ensure behind it) names itself so its child agrees.\n\tconst told = process.env[HOST_INSTANCE_ID_ENV];\n\tconst instanceId = told !== undefined && told.trim() !== \"\" ? told : randomUUID();\n\tconst generation = generationPaths(paths, instanceId);\n\tconst policy = resolveHostPolicy(await readSettingsFile(paths.settingsFile), process.env);\n\tconst publicSocket = launch.socket;\n\t// A successor generation binds its own name and adopts the public one by rename; an ordinary\n\t// start binds the public name directly. Everything downstream - the child's environment, the\n\t// ownership token, the teardown - is expressed in terms of the PUBLIC path either way.\n\tconst bindSocket = launch.bindSocket ?? publicSocket;\n\tconst successor = launch.bindSocket !== undefined;\n\t// Direct-launch contract: the supervisor owns the public secret. ensureHost()\n\t// writes it before spawning, but the hidden --internal-rpc-host-supervisor route\n\t// has no such caller, so a fresh profile would otherwise die reading it (#1370).\n\t// It is provisioned BEFORE the internal hop and the child so a provisioning\n\t// failure leaves no scratch directory and no host process behind.\n\tconst publicSecret = process.platform === \"win32\" ? await ensurePublicSocketSecret(publicSocket) : undefined;\n\tconst internal = await createInternalSocketPath(paths.dir);\n\tconst internalSocket = internal.socket;\n\tconst internalSecretPath = internal.secretPath ?? socketSecretPath(internalSocket);\n\tconst internalSecret = process.platform === \"win32\" ? await createSocketSecret(internalSecretPath) : undefined;\n\tconst clients = new ClientOccupancy(() => decider.update(currentActivity()));\n\tconst busySessions = new Map<string, number>();\n\t// Declared before anything that can reach `currentActivity()`. A client accepted during startup\n\t// asks for the activity snapshot, and a `const` read before its initializer runs is a\n\t// ReferenceError that fails the connection - which is how a successor's first `open_session`\n\t// came back `success: false` during a handoff.\n\tlet observerSocket: Socket | undefined;\n\tconst observerLink = createObserverLink({\n\t\topen: async () => {\n\t\t\tconst secret = internalSecret;\n\t\t\tconst next = createConnection(resolveSocketTransportAddress(internalSocket, process.platform, secret));\n\t\t\tif (secret) sendSocketHandshake(next, secret);\n\t\t\tawait waitForConnect(next, 5_000);\n\t\t\tobserverSocket = next;\n\t\t\tattachJsonlLineReader(next, observeHostEvent, { maxLineLength: MAX_RPC_LINE_CHARACTERS });\n\t\t\treturn {\n\t\t\t\tonLost: (handler) => {\n\t\t\t\t\tnext.once(\"close\", handler);\n\t\t\t\t\tnext.once(\"error\", handler);\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsettled: () => shuttingDown,\n\t\tretryDelayMs: 250,\n\t\tnow: Date.now,\n\t\tsetTimer: (run, ms) => {\n\t\t\tconst timer = setTimeout(run, ms);\n\t\t\ttimer.unref?.();\n\t\t\treturn { cancel: () => clearTimeout(timer) };\n\t\t},\n\t});\n\tlet childExitWatchTimer: ReturnType<typeof setInterval> | undefined;\n\tlet stopSupersessionWatch: (() => void) | undefined;\n\tlet shuttingDown = false;\n\tlet draining = false;\n\tlet handoffGraceTimer: ReturnType<typeof setTimeout> | undefined;\n\tlet shutdownPromise: Promise<never> | undefined;\n\n\tconst childLaunch = spawnableChildLaunch(resolveHostChildLaunch(launch, internalSocket));\n\tconst child = spawn(childLaunch.command, childLaunch.args, {\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t...(launch.agentDir ? { SENPI_CODING_AGENT_DIR: launch.agentDir } : {}),\n\t\t\t// The child binds a PRIVATE socket, so it cannot derive this endpoint's daemon directory\n\t\t\t// from what it listens on: it is told, and it claims its session paths there.\n\t\t\t[HOST_DAEMON_DIR_ENV]: paths.dir,\n\t\t\t[HOST_INSTANCE_ID_ENV]: instanceId,\n\t\t\t[HOST_WATCH_FD_ENV]: String(CHILD_WATCH_FD),\n\t\t\t[HOST_WATCH_PPID_ENV]: String(process.pid),\n\t\t\t...(internal.dir ? { [HOST_SCRATCH_DIR_ENV]: internal.dir } : {}),\n\t\t\t...(internalSecret ? { [SOCKET_SECRET_FILE_ENV]: internalSecretPath } : {}),\n\t\t\t[HOST_CLEANUP_PATHS_ENV]: hostCrashCleanupPaths({\n\t\t\t\tpointerFile: paths.pointerFile,\n\t\t\t\tgenerationPidFile: generation.pidFile,\n\t\t\t\tsettingsFile: paths.settingsFile,\n\t\t\t\tpublicSocket,\n\t\t\t\tsuccessor: Boolean(successor),\n\t\t\t\tplatform: process.platform,\n\t\t\t}).join(\"\\n\"),\n\t\t\t...(process.platform === \"win32\" ? {} : { [HOST_PUBLIC_SOCKET_ENV]: publicSocket }),\n\t\t},\n\t\t// Slot 3 is the lifetime pipe: \"pipe\" gives the child a read end it can\n\t\t// wait on and keeps the write end owned by this process alone.\n\t\tshell: childLaunch.shell,\n\t\tstdio: [\"ignore\", \"ignore\", \"inherit\", \"pipe\"],\n\t\t// The supervisor is spawned detached, so on win32 it owns no console. A\n\t\t// console-subsystem child started from it would allocate a fresh one,\n\t\t// which Windows Terminal renders as an empty window that takes focus.\n\t\t// CREATE_NO_WINDOW gives the child a console with no window instead.\n\t\twindowsHide: true,\n\t});\n\tconst childStartedAt = Date.now();\n\t// Nothing is ever written; the pipe exists purely so its EOF is a reliable\n\t// death notification. Errors on it must not crash the supervisor.\n\tchild.stdio[CHILD_WATCH_FD]?.on(\"error\", () => {});\n\tchild.once(\"exit\", (code, signal) => {\n\t\tif (shuttingDown) return;\n\t\tconst { reason, exitCode } = classifyChildExit(code, signal);\n\t\t// Record BEFORE shutting down: `shutdown` ends in `process.exit`, so anything queued after\n\t\t// it is never reached. Writing is best-effort and never throws into this path.\n\t\tnoteChildExit(paths.dir, code, signal, childStartedAt);\n\t\tvoid shutdown(reason, exitCode);\n\t});\n\n\tconst server = createServer((client) => {\n\t\tconst accept = (): void => {\n\t\t\t// A draining supervisor serves what it already proxies and accepts nothing new. After a\n\t\t\t// handoff the public path resolves to the successor anyway; this covers the connection\n\t\t\t// that raced the rename, and a drain-stop with no successor at all.\n\t\t\tif (shuttingDown || draining) {\n\t\t\t\tclient.destroy();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst internal = createConnection(\n\t\t\t\tresolveSocketTransportAddress(internalSocket, process.platform, internalSecret),\n\t\t\t);\n\t\t\tif (internalSecret) sendSocketHandshake(internal, internalSecret);\n\t\t\t// A readiness exchange can begin and end between ticks: the client is recorded the\n\t\t\t// moment its first request line arrives, before a later tick can reuse the preceding\n\t\t\t// idle window. An observing read (`status`) is never recorded (host-client-occupancy.ts).\n\t\t\tclients.admit(client);\n\t\t\tconst detach = (): void => {\n\t\t\t\tclients.release(client);\n\t\t\t\tdecider.update(currentActivity());\n\t\t\t\tinternal.destroy();\n\t\t\t\tclient.destroy();\n\t\t\t};\n\t\t\tclient.pipe(internal);\n\t\t\tinternal.pipe(client);\n\t\t\tclient.once(\"close\", detach);\n\t\t\tclient.once(\"error\", detach);\n\t\t\t// Let the final lifecycle records drain through the public socket before closing it.\n\t\t\tinternal.once(\"end\", () => client.end(() => client.destroy()));\n\t\t\tinternal.once(\"close\", () => {\n\t\t\t\tif (!internal.readableEnded) detach();\n\t\t\t});\n\t\t\tinternal.once(\"error\", detach);\n\t\t};\n\t\tif (publicSecret) authenticateSocket(client, publicSecret, accept);\n\t\telse accept();\n\t});\n\tserver.once(\"error\", (cause) => {\n\t\tif (!shuttingDown) void shutdown(`public socket listener failed: ${errorMessage(cause)}`, 1);\n\t});\n\n\tconst decider = new IdleExitDecider(\n\t\tpolicy.coldStart === \"persistent\" ? Number.POSITIVE_INFINITY : policy.idleExitMs,\n\t);\n\tconst tickIntervalMs = Math.max(20, Math.min(1_000, policy.idleExitMs / 4));\n\tconst ticker = setInterval(() => {\n\t\tif (!draining && decider.update(currentActivity()) === \"exit\" && clients.unclassifiedCount === 0)\n\t\t\tvoid shutdown(\"idle\", 0);\n\t}, tickIntervalMs);\n\n\tfunction currentActivity(): HostActivity {\n\t\treturn {\n\t\t\tconnections: clients.attachedCount,\n\t\t\tactiveTurns: activeTurnsForIdleDecision({\n\t\t\t\thealthy: observerLink.healthy(),\n\t\t\t\tunhealthySince: observerLink.unhealthySince(),\n\t\t\t\tnow: Date.now(),\n\t\t\t\tunknownGraceMs: decider.idleExitMs,\n\t\t\t\tobservedBusy: countBusySessions(),\n\t\t\t}),\n\t\t};\n\t}\n\n\tfunction countBusySessions(): number {\n\t\tlet busy = 0;\n\t\tfor (const count of busySessions.values()) if (count > 0) busy++;\n\t\treturn busy;\n\t}\n\n\tfunction observeHostEvent(line: string): void {\n\t\tlet event: unknown;\n\t\ttry {\n\t\t\tevent = JSON.parse(line);\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t\tif (typeof event !== \"object\" || event === null) return;\n\t\tconst { type, sessionId } = event as { type?: unknown; sessionId?: unknown };\n\t\tif (typeof sessionId !== \"string\") return;\n\t\tif (type === \"agent_start\") busySessions.set(sessionId, (busySessions.get(sessionId) ?? 0) + 1);\n\t\telse if (type === \"agent_settled\")\n\t\t\tbusySessions.set(sessionId, Math.max(0, (busySessions.get(sessionId) ?? 1) - 1));\n\t\telse return;\n\t\tdecider.update(currentActivity());\n\t}\n\n\tasync function shutdown(reason: string, exitCode: number): Promise<never> {\n\t\t// Single-flight: concurrent triggers (listener error, child exit, signals)\n\t\t// must not process.exit mid-cleanup. Late callers park on this promise while\n\t\t// the first shutdown finishes tearing down and exits.\n\t\tshutdownPromise ??= performShutdown(reason, exitCode);\n\t\treturn shutdownPromise;\n\t}\n\n\tasync function performShutdown(reason: string, exitCode: number): Promise<never> {\n\t\tif (shuttingDown) process.exit(exitCode);\n\t\tshuttingDown = true;\n\t\tclearInterval(ticker);\n\t\tif (handoffGraceTimer) clearTimeout(handoffGraceTimer);\n\t\tif (childExitWatchTimer) clearInterval(childExitWatchTimer);\n\t\tstopSupersessionWatch?.();\n\t\tconst hardExit =\n\t\t\tprocess.platform === \"win32\"\n\t\t\t\t? setTimeout(() => process.exit(exitCode), WINDOWS_SUPERVISOR_SHUTDOWN_HARD_EXIT_MS)\n\t\t\t\t: undefined;\n\t\ttry {\n\t\t\twriteStderrLine(`senpi rpc host supervisor: ${reason} shutdown`);\n\t\t\tclients.destroyAll();\n\t\t\t// libuv unlinks the bound NAME when the listening handle closes - which\n\t\t\t// would delete a newer host's entry renamed over this path. Shield the\n\t\t\t// current entry for the close, then let the ownership check decide. A drained\n\t\t\t// supervisor already closed that handle when it stopped accepting.\n\t\t\tif (!draining) await shieldSocketDuringClose(publicSocket, () => closeServer(server));\n\t\t\t// Unlink the private directory BEFORE the child stop, which can take seconds:\n\t\t\t// an external SIGKILL landing during that wait (ensureHost escalates while\n\t\t\t// replacing a host) would otherwise leave the directory behind. The child\n\t\t\t// keeps serving through its already-open socket fd until it exits, and its\n\t\t\t// own watchdog cleanup makes the removal idempotent.\n\t\t\tif (internal.dir) await rm(internal.dir, { recursive: true, force: true });\n\t\t\tawait stopChild(child);\n\t\t\tobserverLink.stop();\n\t\t\tobserverSocket?.destroy();\n\t\t\tif (publicSocketOwned && process.platform !== \"win32\") {\n\t\t\t\t// Ownership-checked: after a takeover, a newer host may have published\n\t\t\t\t// a fresh entry at this path; only the entry THIS supervisor bound is\n\t\t\t\t// removed. (The host child applies the same rule to its crash path.)\n\t\t\t\tawait unlinkOwnedSocket(publicSocket, publicSocketIdentity, supervisorLog);\n\t\t\t}\n\t\t\t// The registration describes a LIVE host only; the stderr log stays for diagnostics.\n\t\t\t// After a handoff the pointer describes the SUCCESSOR, so this drops only the generation\n\t\t\t// directory of the process that is leaving, and the pointer only while it still names it.\n\t\t\tawait releaseGeneration(paths, { instanceId, pid: process.pid });\n\t\t} finally {\n\t\t\tif (hardExit) clearTimeout(hardExit);\n\t\t\t// Explicitly terminate after every supervisor shutdown trigger. Windows\n\t\t\t// named-pipe handles can outlive their JavaScript wrappers, so cleanup\n\t\t\t// failure must never leave the supervisor resident or the host orphaned.\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t}\n\n\tlet publicSocketOwned = false;\n\tlet publicSocketIdentity: SocketFileIdentity | undefined;\n\tfunction supervisorLog(message: string): void {\n\t\twriteStderrLine(`senpi rpc host supervisor: ${message}`);\n\t}\n\t// Registered before the startup handshake, not after it: the private internal\n\t// directory already exists at this point, so a SIGTERM arriving during host\n\t// startup must run the same cleanup instead of Node's default kill, which\n\t// would leave that directory behind.\n\t/**\n\t * Ask the child to announce and park attached sessions as turns/requests settle. The supervisor\n\t * owns the soft grace from this instant; expiry rescans but NEVER kills busy sessions. Child\n\t * exit ends the supervisor regardless of clients that keep their connections open.\n\t */\n\tfunction drainForHandoff(): void {\n\t\tif (draining || shuttingDown) return;\n\t\tdraining = true;\n\t\tsupervisorLog(\"draining into the next generation\");\n\t\tconst graceMs = parseIdleExitMs(process.env[HANDOFF_GRACE_MS_ENV]) ?? DEFAULT_HANDOFF_GRACE_MS;\n\t\thandoffGraceTimer = setTimeout(() => {\n\t\t\tsupervisorLog(JSON.stringify({ event: \"handoff_grace_expired\", graceMs }));\n\t\t\trequestChildDrain();\n\t\t}, graceMs);\n\t\thandoffGraceTimer.unref();\n\t\t// The listening handle is deliberately NOT closed: libuv unlinks a pipe's bound NAME when it\n\t\t// closes, and after a handoff that name is the successor's entry. Nothing can reach this\n\t\t// listener by path any more (the rename moved the name), and the accept guard above turns\n\t\t// away whatever raced it, so leaving the handle open until exit costs nothing and keeps the\n\t\t// public path continuously answerable - no window where a client finds no socket at all.\n\t\trequestChildDrain();\n\t}\n\tfunction requestChildDrain(): void {\n\t\tif (child.pid !== undefined && child.exitCode === null && child.signalCode === null) {\n\t\t\ttry {\n\t\t\t\tprocess.kill(child.pid, \"SIGUSR1\");\n\t\t\t} catch (cause) {\n\t\t\t\tsupervisorLog(`could not ask the host to drain: ${errorMessage(cause)}`);\n\t\t\t}\n\t\t}\n\t}\n\tregisterSupervisorSignals(shutdown, drainForHandoff);\n\ttry {\n\t\tawait waitForListener(internalSocket, 30_000, internalSecret);\n\t\tawait observerLink.open();\n\t\tawait prepareSocketPath(bindSocket);\n\t\tawait listen(server, bindSocket, publicSecret);\n\t\tpublicSocketOwned = true;\n\t\tif (successor) await adoptPublicSocket(bindSocket, publicSocket, launch.replaceIdentity);\n\t\tpublicSocketIdentity = await statSocketIdentity(publicSocket);\n\t\t// Publish the ownership token inside this supervisor's private scratch\n\t\t// directory (which no replacement supervisor writes): the host child's\n\t\t// crash-path cleanup compares the public path against THIS entry only.\n\t\tif (publicSocketIdentity && internal.dir) {\n\t\t\tawait writeSocketIdentityFile(join(internal.dir, PUBLIC_SOCKET_IDENTITY_FILE), publicSocketIdentity);\n\t\t}\n\t\t// Losing the public entry IS a drain request: nothing can reach this supervisor by path any\n\t\t// more, and the handoff that replaced it may never have signalled (#1893). A name that was\n\t\t// deleted rather than taken over is the same loss with nobody serving the path (#1961).\n\t\tstopSupersessionWatch = watchForSupersession(\n\t\t\t{ path: publicSocket, identity: publicSocketIdentity, settled: () => shuttingDown || draining },\n\t\t\t(loss) => {\n\t\t\t\tsupervisorLog(\n\t\t\t\t\tloss === \"absent\"\n\t\t\t\t\t\t? \"the public socket entry is gone; nothing can reach this generation; draining\"\n\t\t\t\t\t\t: \"another generation owns the public socket; draining this one\",\n\t\t\t\t);\n\t\t\t\tdrainForHandoff();\n\t\t\t},\n\t\t);\n\t} catch (cause) {\n\t\tawait shutdown(`startup failed: ${errorMessage(cause)}`, 1);\n\t}\n\tif (process.platform === \"win32\" && child.pid !== undefined) {\n\t\t// This baseline read sits outside the startup try/catch, and readProcessStartTime\n\t\t// THROWS when the 1s CIM probe fails (execFile's timeout SIGTERMs the PowerShell\n\t\t// child). With no unhandledRejection handler the supervisor died right here on a\n\t\t// loaded runner: it never reached the \"host ready\" line, and the internal host it\n\t\t// owned vanished with it, surfacing downstream as `connect ENOENT` on the pipe and\n\t\t// as `reported dead`. A failed baseline read is UNKNOWN, so the watchdog simply\n\t\t// starts without one and relies on its own comparisons.\n\t\tconst childStartTime = await readProcessStartTime(child.pid, process.platform, 1_000).catch(() => undefined);\n\t\tlet missingIdentityChecks = 0;\n\t\tlet checkingChildIdentity = false;\n\t\tconst checkChildIdentity = (): void => {\n\t\t\tif (shuttingDown || checkingChildIdentity || child.exitCode !== null || child.signalCode !== null) return;\n\t\t\tcheckingChildIdentity = true;\n\t\t\tvoid readProcessStartTime(child.pid!, process.platform, 1_000)\n\t\t\t\t.then((currentStartTime) => {\n\t\t\t\t\t// An absent identity is only believed once kill(pid, 0) agrees the child is\n\t\t\t\t\t// gone. This probe is a 1s PowerShell CIM spawn polled every 500ms, so a\n\t\t\t\t\t// loaded runner produced two consecutive timeouts and this watchdog shut\n\t\t\t\t\t// down a perfectly healthy host (`does not exit while a turn is active`).\n\t\t\t\t\t// A timed-out probe means UNKNOWN, never EXITED.\n\t\t\t\t\tif (currentStartTime === undefined && !processIsLive(child.pid!)) missingIdentityChecks++;\n\t\t\t\t\telse if (currentStartTime !== undefined) missingIdentityChecks = 0;\n\t\t\t\t\tconst identityChanged =\n\t\t\t\t\t\tchildStartTime !== undefined && currentStartTime !== undefined && currentStartTime !== childStartTime;\n\t\t\t\t\tif (identityChanged || missingIdentityChecks >= 2) {\n\t\t\t\t\t\tvoid shutdown(\"rpc host child exit observed by identity watchdog\", 0);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(() => {})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tcheckingChildIdentity = false;\n\t\t\t\t});\n\t\t};\n\t\tchildExitWatchTimer = setInterval(checkChildIdentity, 500);\n\t\tchildExitWatchTimer.unref?.();\n\t}\n\twriteStderrLine(\n\t\t`senpi rpc host ready on unix://${publicSocket} (coldStart=${policy.coldStart}, idleExitMs=${\n\t\t\tpolicy.coldStart === \"persistent\" ? \"never\" : String(policy.idleExitMs)\n\t\t})`,\n\t);\n\tawait new Promise<never>(() => {});\n}\n\n/**\n * External stop (ensureHost replacement, tests, QA) must clean up like idle exit; SIGUSR1 is the\n * gentler request - finish what you are doing and leave - that a generation handoff and\n * `stopHost({ drain: true })` both send. It exists on POSIX only, which is one reason win32 hosts\n * are attach-only: no signal there means anything but \"terminate\".\n */\nfunction registerSupervisorSignals(\n\tshutdown: (reason: string, exitCode: number) => Promise<never>,\n\tdrain: () => void,\n): void {\n\tfor (const signal of process.platform === \"win32\" ? ([\"SIGTERM\"] as const) : ([\"SIGTERM\", \"SIGHUP\"] as const)) {\n\t\tprocess.on(signal, () => {\n\t\t\tvoid shutdown(`signal:${signal}`, signal === \"SIGHUP\" ? 129 : 143);\n\t\t});\n\t}\n\tif (process.platform !== \"win32\") process.on(\"SIGUSR1\", drain);\n}\n\n/**\n * Takes the public name over with a rename, once - and only while - that name still refers to the\n * entry this handoff was decided against. A socket that changed underneath belongs to another\n * process now: replacing it would unlink an endpoint this generation cannot prove it owns, so the\n * successor aborts instead and leaves both the intruder's socket and its own bind entry alone.\n */\nasync function adoptPublicSocket(\n\tbindSocket: string,\n\tpublicSocket: string,\n\texpected: SocketFileIdentity | undefined,\n): Promise<void> {\n\tif (expected === undefined) throw new Error(`${publicSocket}: a generation launch must name the entry it replaces`);\n\tconst current = await statSocketIdentity(publicSocket);\n\tif (current === undefined || current.dev !== expected.dev || current.ino !== expected.ino) {\n\t\tthrow new Error(`${publicSocket}: owned by another socket entry now; refusing to replace it`);\n\t}\n\t// rename(2) is atomic for readers of the path: every connect either reaches the old entry or\n\t// this one, never nothing. The inode this supervisor bound simply answers to a second name.\n\tawait rename(bindSocket, publicSocket);\n}\n\n/**\n * Reuses an existing valid secret - including one ensureHost() just wrote - and\n * creates one (with its parent directories, mode 0600) when it is missing or\n * unusable. Reuse is required, not just an optimization: on win32 the pipe name\n * is derived from the socket path AND the secret, so rotating it here would\n * point this supervisor at a different endpoint than its caller published.\n * A failure names the bootstrap step and the path it could not provision.\n */\nasync function ensurePublicSocketSecret(publicSocket: string): Promise<Buffer> {\n\tconst secretPath = socketSecretPath(publicSocket);\n\ttry {\n\t\treturn await ensureSocketSecret(secretPath);\n\t} catch (cause) {\n\t\tthrow new Error(`senpi rpc host supervisor: cannot provision public socket secret ${secretPath}`, { cause });\n\t}\n}\n\nasync function readSettingsFile(settingsFile: string): Promise<unknown> {\n\ttry {\n\t\treturn JSON.parse(await readFile(settingsFile, \"utf8\"));\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function stopChild(child: ChildProcess): Promise<void> {\n\tif (child.exitCode !== null || child.signalCode !== null) return;\n\ttry {\n\t\tchild.kill(\"SIGTERM\");\n\t} catch {\n\t\treturn;\n\t}\n\tif (await waitForChildExit(child, CHILD_STOP_TIMEOUT_MS)) return;\n\ttry {\n\t\tchild.kill(\"SIGKILL\");\n\t} catch {\n\t\treturn;\n\t}\n\tawait waitForChildExit(child, 2_000);\n}\n\nfunction waitForChildExit(child: ChildProcess, timeoutMs: number): Promise<boolean> {\n\tif (child.exitCode !== null || child.signalCode !== null) return Promise.resolve(true);\n\treturn new Promise((resolve) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tchild.off(\"exit\", onExit);\n\t\t\tresolve(false);\n\t\t}, timeoutMs);\n\t\tconst onExit = (): void => {\n\t\t\tclearTimeout(timer);\n\t\t\tresolve(true);\n\t\t};\n\t\tchild.once(\"exit\", onExit);\n\t});\n}\n\nasync function waitForListener(socketPath: string, timeoutMs: number, secret?: Uint8Array): Promise<void> {\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (Date.now() <= deadline) {\n\t\tif (await canConnect(socketPath, secret)) return;\n\t\tawait delay(50);\n\t}\n\tthrow new Error(`${socketPath}: host did not start listening within ${timeoutMs}ms`);\n}\n\nfunction canConnect(socketPath: string, secret?: Uint8Array): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = createConnection(resolveSocketTransportAddress(socketPath, process.platform, secret));\n\t\tif (secret) sendSocketHandshake(socket, secret);\n\t\tconst settle = (value: boolean): void => {\n\t\t\tsocket.destroy();\n\t\t\tresolve(value);\n\t\t};\n\t\tsocket.once(\"connect\", () => settle(true));\n\t\tsocket.once(\"error\", () => settle(false));\n\t});\n}\n\nfunction waitForConnect(socket: Socket, timeoutMs: number): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tcleanup();\n\t\t\treject(new Error(`observer connection to internal host timed out after ${timeoutMs}ms`));\n\t\t}, timeoutMs);\n\t\tconst onConnect = (): void => {\n\t\t\tcleanup();\n\t\t\tresolve();\n\t\t};\n\t\tconst onError = (cause: Error): void => {\n\t\t\tcleanup();\n\t\t\treject(cause);\n\t\t};\n\t\tconst cleanup = (): void => {\n\t\t\tclearTimeout(timer);\n\t\t\tsocket.off(\"connect\", onConnect);\n\t\t\tsocket.off(\"error\", onError);\n\t\t};\n\t\tsocket.once(\"connect\", onConnect);\n\t\tsocket.once(\"error\", onError);\n\t});\n}\n\nasync function prepareSocketPath(socketPath: string): Promise<void> {\n\tif (process.platform === \"win32\") return;\n\t// A path the kernel would truncate binds a DIFFERENT endpoint than the one every client was\n\t// told about, and the failure surfaces much later as \"the host does not answer\". Refuse here.\n\tif (Buffer.byteLength(socketPath) > MAX_SOCKET_PATH_BYTES) {\n\t\tthrow new Error(\n\t\t\t`${socketPath}: socket path is ${Buffer.byteLength(socketPath)} bytes, over the ${MAX_SOCKET_PATH_BYTES}-byte limit.`,\n\t\t);\n\t}\n\tawait mkdir(dirname(socketPath), { recursive: true, mode: 0o700 });\n\ttry {\n\t\tawait access(socketPath);\n\t} catch (cause) {\n\t\tif (isNodeErrorCode(cause, \"ENOENT\")) return;\n\t\tthrow cause;\n\t}\n\tif (await canConnect(socketPath)) throw new Error(`${socketPath}: address already in use by a live server.`);\n\tawait unlink(socketPath);\n}\n\nfunction listen(server: Server, socketPath: string, secret?: Uint8Array): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tserver.once(\"error\", reject);\n\t\tserver.listen(\n\t\t\t{\n\t\t\t\tpath: resolveSocketTransportAddress(socketPath, process.platform, secret),\n\t\t\t\treadableAll: false,\n\t\t\t\twritableAll: false,\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tserver.off(\"error\", reject);\n\t\t\t\ttry {\n\t\t\t\t\tif (process.platform !== \"win32\" && !socketPath.startsWith(\"\\0\")) await chmod(socketPath, 0o600);\n\t\t\t\t\tresolve();\n\t\t\t\t} catch (cause) {\n\t\t\t\t\treject(cause);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t});\n}\n\nfunction closeServer(server: Server): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tserver.close(() => resolve());\n\t});\n}\n\nfunction writeStderrLine(text: string): void {\n\t// A detached daemon exiting right after an async stderr.write to a file can\n\t// lose the output entirely; write synchronously so diagnostics always land.\n\ttry {\n\t\twriteSync(2, `${text}\\n`);\n\t} catch {\n\t\t/* fd 2 unavailable: nothing more we can do. */\n\t}\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolveDelay) => setTimeout(resolveDelay, ms));\n}\n\nfunction errorMessage(cause: unknown): string {\n\treturn cause instanceof Error ? cause.message : String(cause);\n}\n\nfunction isNodeErrorCode(cause: unknown, code: string): boolean {\n\treturn cause instanceof Error && \"code\" in cause && cause.code === code;\n}\n\nfunction isEntryScript(): boolean {\n\tconst entry = process.argv[1];\n\tif (!entry) return false;\n\ttry {\n\t\treturn fileURLToPath(import.meta.url) === realpathSync(entry);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nif (!isBundledNode && isEntryScript()) {\n\tconst launch = parseSupervisorArgs(process.argv.slice(2));\n\tif (!launch) {\n\t\twriteStderrLine(\"usage: host-lifecycle.ts --socket <path> [host cli args...]\");\n\t\tprocess.exit(2);\n\t}\n\tvoid runHostSupervisor(launch);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"host-lifecycle.js","sourceRoot":"","sources":["../../../src/modes/rpc/host-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * Lifecycle supervisor for the shared RPC socket host started by ensureHost().\n *\n * Process tree:\n *\n * ensureHost() ──detached──▶ host-lifecycle.ts (this supervisor, owns the pidfile)\n * │ byte-proxies the public socket\n * ▼\n * cli-main --mode rpc --listen unix://<public>.internal\n *\n * The supervisor exists to enforce the host lifecycle policy without touching the\n * RPC host itself:\n *\n * - cold start: `transient` (default) means the host lives for the current login\n * session and idle-exits; `persistent` never idle-exits.\n * - idle exit: after a continuous window with zero attached client connections\n * and zero active agent turns, the supervisor tears the host down cleanly\n * (child SIGTERM first so the host flushes pending output and removes its own\n * socket, then pidfile/settings removal mirroring ensureHost's cleanupState).\n *\n * Observability without host changes: proxying the public socket yields the\n * exact connection count, and the supervisor keeps one always-on observer\n * connection to the internal socket. The multi-session host broadcasts every\n * session lifecycle/agent event to every connection, so the observer sees\n * `agent_start`/`agent_settled` for all sessions even when no client is\n * attached. If the observer connection is ever unhealthy, activity is reported\n * as unknown (non-idle), so a broken observer can only keep the host alive,\n * never kill it mid-turn - for one idle window. Past that, unknown has held\n * the host open for as long as idleness itself would have, and it stops\n * counting as busy; the link keeps reconnecting the whole time (#1979).\n *\n * Lifetime binding: the host is spawned with an extra inherited pipe on fd 3\n * whose write end this supervisor holds and never writes to. The kernel closes\n * that end whenever the supervisor dies - including SIGKILL, an OOM kill, or a\n * crash, where no JS handler runs at all - so the host reads EOF and shuts down\n * cleanly, removing the private internal directory. `stopChild()` remains the\n * fast path for orderly shutdowns; the pipe is what makes an orphaned host\n * impossible. `SENPI_RPC_HOST_WATCH_PPID` is passed alongside as a belt-and-\n * braces fallback for platforms where the extra fd is not inherited.\n */\nimport { type ChildProcess, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync, readFileSync, realpathSync, writeSync } from \"node:fs\";\nimport { access, chmod, mkdir, readFile, rename, rm, unlink, writeFile } from \"node:fs/promises\";\nimport { createConnection, createServer, type Server, type Socket } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, extname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { getAgentDir, isBunBinary, isBundledNode } from \"../../config.ts\";\nimport { processIsLive, readProcessStartTime } from \"../app-server/daemon/process.ts\";\nimport { classifyChildExit, noteChildExit } from \"./host-child-exit.ts\";\nimport { ClientOccupancy } from \"./host-client-occupancy.ts\";\nimport {\n\tDEFAULT_HANDOFF_GRACE_MS,\n\tHANDOFF_GRACE_MS_ENV,\n\ttype HostActivity,\n\tIdleExitDecider,\n\tparseIdleExitMs,\n\tresolveHostPolicy,\n} from \"./host-lifecycle-policy.ts\";\n\n// The exit verdict moved to ./host-child-exit.ts with the crash recording it now feeds; it stays\n// exported from here so every existing importer keeps resolving it at its original home.\nexport { classifyChildExit } from \"./host-child-exit.ts\";\n\n// The cold-start/idle-exit policy and its decision core live in ./host-lifecycle-policy.ts; they stay\n// exported from here so every existing importer keeps resolving them at their original home.\nexport {\n\tDEFAULT_HANDOFF_GRACE_MS,\n\tDEFAULT_HOST_IDLE_EXIT_MS,\n\tHANDOFF_GRACE_MS_ENV,\n\tHOST_COLD_START_ENV,\n\tHOST_IDLE_EXIT_MS_ENV,\n\ttype HostActivity,\n\ttype HostColdStart,\n\ttype HostLifecyclePolicy,\n\ttype HostLifecyclePolicyInput,\n\tIdleExitDecider,\n\ttype IdleExitDecision,\n\tparseColdStart,\n\tparseIdleExitMs,\n\tresolveHostPolicy,\n} from \"./host-lifecycle-policy.ts\";\n\nimport { hostCrashCleanupPaths } from \"./host-cleanup-paths.ts\";\nimport { createHostDaemonPaths, generationPaths, HOST_DAEMON_DIR_ENV } from \"./host-daemon-paths.ts\";\nimport { releaseGeneration } from \"./host-daemon-registration.ts\";\nimport { HOST_INSTANCE_ID_ENV } from \"./host-identity-env.ts\";\nimport { watchForSupersession } from \"./host-supersession.ts\";\nimport {\n\tHOST_CLEANUP_PATHS_ENV,\n\tHOST_PUBLIC_SOCKET_ENV,\n\tHOST_SCRATCH_DIR_ENV,\n\tHOST_WATCH_FD_ENV,\n\tHOST_WATCH_PPID_ENV,\n} from \"./host-watchdog.ts\";\nimport { attachJsonlLineReader, MAX_RPC_LINE_CHARACTERS } from \"./jsonl.ts\";\nimport { activeTurnsForIdleDecision, createObserverLink } from \"./observer-link.ts\";\nimport {\n\tMAX_SOCKET_PATH_BYTES,\n\tPUBLIC_SOCKET_IDENTITY_FILE,\n\ttype SocketFileIdentity,\n\tshieldSocketDuringClose,\n\tstatSocketIdentity,\n\tunlinkOwnedSocket,\n\twriteSocketIdentityFile,\n} from \"./socket-ownership.ts\";\nimport {\n\tauthenticateSocket,\n\tcreateSocketSecret,\n\tensureSocketSecret,\n\tresolveSocketTransportAddress,\n\tSOCKET_SECRET_FILE_ENV,\n\tsendSocketHandshake,\n\tsocketSecretPath,\n} from \"./socket-transport.ts\";\n\nconst CHILD_STOP_TIMEOUT_MS = 5_000;\n/** Win32 named-pipe shutdown can leave supervisor handles live after close starts. */\nconst WINDOWS_SUPERVISOR_SHUTDOWN_HARD_EXIT_MS = 2_000;\n\n/**\n * Child stdio slot carrying the supervisor-lifetime pipe. The supervisor holds\n * the write end open and never writes; the kernel closes it when the supervisor\n * dies for ANY reason (SIGKILL, OOM kill, crash), so the host sees EOF on this\n * fd and shuts itself down. Catchable-signal cleanup alone cannot do this.\n */\nconst CHILD_WATCH_FD = 3;\n\n/**\n * The internal hop must stay short enough for sun_path (104 bytes on macOS)\n * regardless of where the public socket lives, and private against other local\n * users, so it gets its own 0700 directory under the OS temp directory.\n *\n * On win32 the directory lives under the caller-supplied rpc-host-daemon\n * directory, which ensureHost() creates but a direct --internal-rpc-host-supervisor\n * launch does not, so the parent is created recursively.\n */\nexport async function createInternalSocketPath(\n\tbaseDir = tmpdir(),\n\tplatform: NodeJS.Platform = process.platform,\n): Promise<{ socket: string; dir?: string; secretPath?: string }> {\n\tif (platform === \"win32\") {\n\t\tconst dir = join(baseDir, `internal-${randomUUID()}`);\n\t\tawait mkdir(dir, { recursive: true, mode: 0o700 });\n\t\treturn {\n\t\t\tsocket: `\\\\\\\\.\\\\pipe\\\\senpi-rpc-internal-${randomUUID()}`,\n\t\t\tdir,\n\t\t\tsecretPath: join(dir, \"secret\"),\n\t\t};\n\t}\n\tconst dir = join(tmpdir(), `senpi-rpc-host-internal-${randomUUID().slice(0, 8)}`);\n\tawait mkdir(dir, { recursive: false, mode: 0o700 });\n\tawait writeFile(\n\t\tjoin(dir, \".owner\"),\n\t\tJSON.stringify({\n\t\t\tpid: process.pid,\n\t\t\tprocessStartTime: await readProcessStartTime(process.pid),\n\t\t\tcreatedAt: Date.now(),\n\t\t}),\n\t\t{ mode: 0o600 },\n\t);\n\treturn { socket: join(dir, \"host.sock\"), dir, secretPath: join(dir, \".secret\") };\n}\n\nexport interface SupervisorLaunch {\n\treadonly socket: string;\n\treadonly hostArgs: readonly string[];\n\t/** Optional runtime command used by rebranded/bundled callers. */\n\treadonly childCommand?: string;\n\treadonly childArgs?: readonly string[];\n\t/** Explicit ownership directory for callers whose environment is not yet branded. */\n\treadonly agentDir?: string;\n\t/**\n\t * Where this supervisor BINDS, when it is a successor generation: `<socket>.next-<gen>`.\n\t * It renames that entry over `socket` once its host answers - and never binds the live\n\t * public path, which belongs to the generation currently serving it.\n\t */\n\treadonly bindSocket?: string;\n\t/**\n\t * The public socket entry this generation is allowed to replace (`<dev>:<ino>`). The rename\n\t * happens only while the path still refers to it: a socket that changed underneath belongs to\n\t * somebody else now, and replacing it would unlink an endpoint this process cannot prove it owns.\n\t */\n\treadonly replaceIdentity?: SocketFileIdentity;\n}\n\n/** Hidden internal launch route: wire-invisible, never advertised by the public CLI surface. */\nexport const INTERNAL_SUPERVISOR_FLAG = \"--internal-rpc-host-supervisor\";\n\n/**\n * Engine-global flags a rebranded wrapper may legitimately prepend when it\n * re-dispatches this binary. `packages/omo-native` injects `--extension <dir>`\n * for every non-early command, which pushed the sentinel off argv[0].\n */\nconst INJECTABLE_PREFIX_FLAGS = new Set([\"--extension\"]);\n\n/**\n * Returns the internal supervisor payload when argv selects that route.\n *\n * The route dispatches when the sentinel is argv[0] OR is preceded only by\n * known injectable prefix flags and their values - the one perturbation\n * wrappers legitimately perform. Everything else disqualifies it: a positional\n * operand, `--`, or an unknown flag before the sentinel all return undefined,\n * so a user-supplied value that happens to equal the sentinel can never reach\n * the supervisor.\n *\n * The skipped prefix is deliberately NOT forwarded to the host: a wrapper\n * re-injects its own prefix on every re-entry, so the host child receives it\n * from the wrapper rather than twice from here.\n */\nexport function findInternalSupervisorArgs(argv: readonly string[]): readonly string[] | undefined {\n\tfor (let index = 0; index < argv.length; index++) {\n\t\tconst arg = argv[index];\n\t\tif (arg === INTERNAL_SUPERVISOR_FLAG) return argv.slice(index + 1);\n\t\t// A prefix flag only counts when its value is actually present.\n\t\tif (!INJECTABLE_PREFIX_FLAGS.has(arg) || index + 1 >= argv.length) return undefined;\n\t\tindex++;\n\t}\n\treturn undefined;\n}\n\n/** `--socket <path>` selects the public socket; every other argument is forwarded to the host CLI. */\nexport function parseSupervisorArgs(argv: readonly string[]): SupervisorLaunch | undefined {\n\tconst hostArgs: string[] = [];\n\tlet socket: string | undefined;\n\tlet childCommand: string | undefined;\n\tlet childArgs: readonly string[] | undefined;\n\tlet agentDir: string | undefined;\n\tlet bindSocket: string | undefined;\n\tlet replaceIdentity: SocketFileIdentity | undefined;\n\tfor (let index = 0; index < argv.length; index++) {\n\t\tconst arg = argv[index];\n\t\tif (arg === \"--socket\" && index + 1 < argv.length) {\n\t\t\tsocket = argv[++index];\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--child-command\" && index + 1 < argv.length) {\n\t\t\tchildCommand = argv[++index];\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--child-args\" && index + 1 < argv.length) {\n\t\t\ttry {\n\t\t\t\tconst parsed: unknown = JSON.parse(argv[++index]);\n\t\t\t\tif (Array.isArray(parsed) && parsed.every((value) => typeof value === \"string\")) childArgs = parsed;\n\t\t\t} catch {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--agent-dir\" && index + 1 < argv.length) {\n\t\t\tagentDir = argv[++index];\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--bind\" && index + 1 < argv.length) {\n\t\t\tbindSocket = argv[++index];\n\t\t\tcontinue;\n\t\t}\n\t\tif (arg === \"--replace\" && index + 1 < argv.length) {\n\t\t\treplaceIdentity = parseSocketIdentity(argv[++index]);\n\t\t\tcontinue;\n\t\t}\n\t\thostArgs.push(arg);\n\t}\n\treturn socket === undefined\n\t\t? undefined\n\t\t: { socket, hostArgs, childCommand, childArgs, agentDir, bindSocket, replaceIdentity };\n}\n\n/** `<dev>:<ino>` as the ensure captured it; anything else is no identity at all, never a guess. */\nfunction parseSocketIdentity(value: string): SocketFileIdentity | undefined {\n\tconst match = /^(\\d+):(\\d+)$/.exec(value);\n\treturn match ? { dev: Number(match[1]), ino: Number(match[2]) } : undefined;\n}\n\n/** Resolves the committed CLI entry this supervisor wraps (source tree or built dist). */\nexport function resolveCliMainPath(): string {\n\tconst modulePath = fileURLToPath(import.meta.url);\n\tconst extension = modulePath.endsWith(\".ts\") ? \".ts\" : \".js\";\n\tconst unbundled = resolve(dirname(modulePath), \"..\", \"..\", `cli-main${extension}`);\n\tif (existsSync(unbundled)) return unbundled;\n\t// Bundled, \"..\" twice reaches the PACKAGE ROOT rather than dist/, naming a cli-main that\n\t// was never emitted. Take the entry from the package's own declared bin instead of\n\t// counting directories: it is the one statement of where the CLI lives that holds in\n\t// every layout. Falls back to the old path when nothing is declared, so a caller that\n\t// was working keeps working.\n\treturn resolveDeclaredCliEntry(modulePath) ?? unbundled;\n}\n\n/** The CLI entry declared by the nearest enclosing package.json, when it exists on disk. */\nfunction resolveDeclaredCliEntry(modulePath: string): string | undefined {\n\tlet dir = dirname(modulePath);\n\tfor (let depth = 0; depth < 8; depth += 1) {\n\t\tconst manifestPath = resolve(dir, \"package.json\");\n\t\tif (existsSync(manifestPath)) {\n\t\t\ttry {\n\t\t\t\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as {\n\t\t\t\t\tbin?: Record<string, string> | string;\n\t\t\t\t};\n\t\t\t\tconst declared = manifest.bin;\n\t\t\t\tconst candidates = typeof declared === \"string\" ? [declared] : Object.values(declared ?? {});\n\t\t\t\tfor (const candidate of candidates) {\n\t\t\t\t\tconst entry = resolve(dir, candidate);\n\t\t\t\t\tif (existsSync(entry)) return entry;\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t\treturn undefined;\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n\treturn undefined;\n}\n\n/**\n * Resolves the host child spawn. Explicit child commands (desktop launchers)\n * are forwarded untouched. The default re-enters the committed CLI entry\n * through the runtime, except in compiled standalone binaries, which always\n * boot their embedded entrypoint and would parse a script path as CLI\n * arguments - there the executable itself is the CLI, so the mode flags are\n * passed directly. Exported for tests.\n */\nexport function resolveHostChildLaunch(\n\tlaunch: SupervisorLaunch,\n\tinternalSocket: string,\n\tcompiled: boolean = isBunBinary,\n): { command: string; args: string[] } {\n\tif (launch.childCommand) {\n\t\treturn {\n\t\t\tcommand: launch.childCommand,\n\t\t\targs: [...(launch.childArgs ?? []), \"--listen\", `unix://${internalSocket}`],\n\t\t};\n\t}\n\treturn {\n\t\tcommand: process.execPath,\n\t\targs: [\n\t\t\t...(compiled ? [] : [...process.execArgv, resolveCliMainPath()]),\n\t\t\t\"--mode\",\n\t\t\t\"rpc\",\n\t\t\t\"--multi-session\",\n\t\t\t\"--listen\",\n\t\t\t`unix://${internalSocket}`,\n\t\t\t...launch.hostArgs,\n\t\t],\n\t};\n}\n\n/** Mirrors cross-spawn: survives cmd.exe parsing and `CommandLineToArgvW`. */\nfunction quoteWindowsShellArg(value: string): string {\n\tconst escaped = value\n\t\t.replace(/(\\\\*)\"/g, '$1$1\\\\\"')\n\t\t.replace(/(\\\\*)$/, \"$1$1\")\n\t\t.replace(/([()%!^\"<>&|;,])/g, \"^$1\");\n\treturn `\"${escaped}\"`;\n}\n\n/**\n * Windows refuses to spawn a `.cmd`/`.bat` without a shell, and Node's\n * `shell: true` concatenates argv without escaping it. Escape each original\n * value before adding the surrounding quotes so `.cmd`/`.bat` launchers survive\n * cmd.exe parsing without double-escaping.\n * Exported for tests.\n */\nexport function spawnableChildLaunch(\n\tlaunch: { command: string; args: string[] },\n\tplatform: NodeJS.Platform = process.platform,\n): { command: string; args: string[]; shell: boolean } {\n\tconst extension = extname(launch.command).toLowerCase();\n\tif (platform !== \"win32\" || (extension !== \".cmd\" && extension !== \".bat\")) {\n\t\treturn { ...launch, shell: false };\n\t}\n\treturn {\n\t\tcommand: quoteWindowsShellArg(launch.command),\n\t\targs: launch.args.map(quoteWindowsShellArg),\n\t\tshell: true,\n\t};\n}\n\nexport async function runHostSupervisor(launch: SupervisorLaunch): Promise<void> {\n\tconst paths = createHostDaemonPaths({ socket: launch.socket, agentDir: launch.agentDir ?? getAgentDir() });\n\t// Which generation this supervisor is: the ensure that spawned it says so, and a DIRECT launch\n\t// (the hidden supervisor route, with no ensure behind it) names itself so its child agrees.\n\tconst told = process.env[HOST_INSTANCE_ID_ENV];\n\tconst instanceId = told !== undefined && told.trim() !== \"\" ? told : randomUUID();\n\tconst generation = generationPaths(paths, instanceId);\n\tconst policy = resolveHostPolicy(await readSettingsFile(paths.settingsFile), process.env);\n\tconst publicSocket = launch.socket;\n\t// A successor generation binds its own name and adopts the public one by rename; an ordinary\n\t// start binds the public name directly. Everything downstream - the child's environment, the\n\t// ownership token, the teardown - is expressed in terms of the PUBLIC path either way.\n\tconst bindSocket = launch.bindSocket ?? publicSocket;\n\tconst successor = launch.bindSocket !== undefined;\n\t// Direct-launch contract: the supervisor owns the public secret. ensureHost()\n\t// writes it before spawning, but the hidden --internal-rpc-host-supervisor route\n\t// has no such caller, so a fresh profile would otherwise die reading it (#1370).\n\t// It is provisioned BEFORE the internal hop and the child so a provisioning\n\t// failure leaves no scratch directory and no host process behind.\n\tconst publicSecret = process.platform === \"win32\" ? await ensurePublicSocketSecret(publicSocket) : undefined;\n\tconst internal = await createInternalSocketPath(paths.dir);\n\tconst internalSocket = internal.socket;\n\tconst internalSecretPath = internal.secretPath ?? socketSecretPath(internalSocket);\n\tconst internalSecret = process.platform === \"win32\" ? await createSocketSecret(internalSecretPath) : undefined;\n\tconst clients = new ClientOccupancy(() => decider.update(currentActivity()));\n\tconst busySessions = new Map<string, number>();\n\t// Declared before anything that can reach `currentActivity()`. A client accepted during startup\n\t// asks for the activity snapshot, and a `const` read before its initializer runs is a\n\t// ReferenceError that fails the connection - which is how a successor's first `open_session`\n\t// came back `success: false` during a handoff.\n\tlet observerSocket: Socket | undefined;\n\tconst observerLink = createObserverLink({\n\t\topen: async () => {\n\t\t\tconst secret = internalSecret;\n\t\t\tconst next = createConnection(resolveSocketTransportAddress(internalSocket, process.platform, secret));\n\t\t\tif (secret) sendSocketHandshake(next, secret);\n\t\t\tawait waitForConnect(next, 5_000);\n\t\t\tobserverSocket = next;\n\t\t\tattachJsonlLineReader(next, observeHostEvent, { maxLineLength: MAX_RPC_LINE_CHARACTERS });\n\t\t\treturn {\n\t\t\t\tonLost: (handler) => {\n\t\t\t\t\tnext.once(\"close\", handler);\n\t\t\t\t\tnext.once(\"error\", handler);\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsettled: () => shuttingDown,\n\t\tretryDelayMs: 250,\n\t\tnow: Date.now,\n\t\tsetTimer: (run, ms) => {\n\t\t\tconst timer = setTimeout(run, ms);\n\t\t\ttimer.unref?.();\n\t\t\treturn { cancel: () => clearTimeout(timer) };\n\t\t},\n\t});\n\tlet childExitWatchTimer: ReturnType<typeof setInterval> | undefined;\n\tlet stopSupersessionWatch: (() => void) | undefined;\n\tlet shuttingDown = false;\n\tlet draining = false;\n\tlet handoffGraceTimer: ReturnType<typeof setTimeout> | undefined;\n\tlet shutdownPromise: Promise<never> | undefined;\n\n\tconst childLaunch = spawnableChildLaunch(resolveHostChildLaunch(launch, internalSocket));\n\tconst child = spawn(childLaunch.command, childLaunch.args, {\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t...(launch.agentDir ? { SENPI_CODING_AGENT_DIR: launch.agentDir } : {}),\n\t\t\t// The child binds a PRIVATE socket, so it cannot derive this endpoint's daemon directory\n\t\t\t// from what it listens on: it is told, and it claims its session paths there.\n\t\t\t[HOST_DAEMON_DIR_ENV]: paths.dir,\n\t\t\t[HOST_INSTANCE_ID_ENV]: instanceId,\n\t\t\t[HOST_WATCH_FD_ENV]: String(CHILD_WATCH_FD),\n\t\t\t[HOST_WATCH_PPID_ENV]: String(process.pid),\n\t\t\t...(internal.dir ? { [HOST_SCRATCH_DIR_ENV]: internal.dir } : {}),\n\t\t\t...(internalSecret ? { [SOCKET_SECRET_FILE_ENV]: internalSecretPath } : {}),\n\t\t\t[HOST_CLEANUP_PATHS_ENV]: hostCrashCleanupPaths({\n\t\t\t\tpointerFile: paths.pointerFile,\n\t\t\t\tgenerationPidFile: generation.pidFile,\n\t\t\t\tsettingsFile: paths.settingsFile,\n\t\t\t\tpublicSocket,\n\t\t\t\tsuccessor: Boolean(successor),\n\t\t\t\tplatform: process.platform,\n\t\t\t}).join(\"\\n\"),\n\t\t\t...(process.platform === \"win32\" ? {} : { [HOST_PUBLIC_SOCKET_ENV]: publicSocket }),\n\t\t},\n\t\t// Slot 3 is the lifetime pipe: \"pipe\" gives the child a read end it can\n\t\t// wait on and keeps the write end owned by this process alone.\n\t\tshell: childLaunch.shell,\n\t\tstdio: [\"ignore\", \"ignore\", \"inherit\", \"pipe\"],\n\t\t// The supervisor is spawned detached, so on win32 it owns no console. A\n\t\t// console-subsystem child started from it would allocate a fresh one,\n\t\t// which Windows Terminal renders as an empty window that takes focus.\n\t\t// CREATE_NO_WINDOW gives the child a console with no window instead.\n\t\twindowsHide: true,\n\t});\n\tconst childStartedAt = Date.now();\n\t// Nothing is ever written; the pipe exists purely so its EOF is a reliable\n\t// death notification. Errors on it must not crash the supervisor.\n\tchild.stdio[CHILD_WATCH_FD]?.on(\"error\", () => {});\n\tchild.once(\"exit\", (code, signal) => {\n\t\tif (shuttingDown) return;\n\t\tconst { reason, exitCode } = classifyChildExit(code, signal);\n\t\t// Record BEFORE shutting down: `shutdown` ends in `process.exit`, so anything queued after\n\t\t// it is never reached. Writing is best-effort and never throws into this path.\n\t\tnoteChildExit(paths.dir, code, signal, childStartedAt);\n\t\tvoid shutdown(reason, exitCode);\n\t});\n\n\tconst server = createServer((client) => {\n\t\tconst accept = (): void => {\n\t\t\t// A draining supervisor serves what it already proxies and accepts nothing new. After a\n\t\t\t// handoff the public path resolves to the successor anyway; this covers the connection\n\t\t\t// that raced the rename, and a drain-stop with no successor at all.\n\t\t\tif (shuttingDown || draining) {\n\t\t\t\tclient.destroy();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst internal = createConnection(\n\t\t\t\tresolveSocketTransportAddress(internalSocket, process.platform, internalSecret),\n\t\t\t);\n\t\t\tif (internalSecret) sendSocketHandshake(internal, internalSecret);\n\t\t\t// A readiness exchange can begin and end between ticks: the client is recorded the\n\t\t\t// moment its first request line arrives, before a later tick can reuse the preceding\n\t\t\t// idle window. An observing read (`status`) is never recorded (host-client-occupancy.ts).\n\t\t\tclients.admit(client);\n\t\t\tconst detach = (): void => {\n\t\t\t\tclients.release(client);\n\t\t\t\tdecider.update(currentActivity());\n\t\t\t\tinternal.destroy();\n\t\t\t\tclient.destroy();\n\t\t\t};\n\t\t\tclient.pipe(internal);\n\t\t\tinternal.pipe(client);\n\t\t\tclient.once(\"close\", detach);\n\t\t\tclient.once(\"error\", detach);\n\t\t\t// Let the final lifecycle records drain through the public socket before closing it.\n\t\t\tinternal.once(\"end\", () => client.end(() => client.destroy()));\n\t\t\tinternal.once(\"close\", () => {\n\t\t\t\tif (!internal.readableEnded) detach();\n\t\t\t});\n\t\t\tinternal.once(\"error\", detach);\n\t\t};\n\t\tif (publicSecret) authenticateSocket(client, publicSecret, accept);\n\t\telse accept();\n\t});\n\tserver.once(\"error\", (cause) => {\n\t\tif (!shuttingDown) void shutdown(`public socket listener failed: ${errorMessage(cause)}`, 1);\n\t});\n\n\tconst decider = new IdleExitDecider(\n\t\tpolicy.coldStart === \"persistent\" ? Number.POSITIVE_INFINITY : policy.idleExitMs,\n\t);\n\tconst tickIntervalMs = Math.max(20, Math.min(1_000, policy.idleExitMs / 4));\n\tconst ticker = setInterval(() => {\n\t\tif (!draining && decider.update(currentActivity()) === \"exit\" && clients.unclassifiedCount === 0)\n\t\t\tvoid shutdown(\"idle\", 0);\n\t}, tickIntervalMs);\n\n\tfunction currentActivity(): HostActivity {\n\t\treturn {\n\t\t\tconnections: clients.attachedCount,\n\t\t\tactiveTurns: activeTurnsForIdleDecision({\n\t\t\t\thealthy: observerLink.healthy(),\n\t\t\t\tunhealthySince: observerLink.unhealthySince(),\n\t\t\t\tnow: Date.now(),\n\t\t\t\tunknownGraceMs: decider.idleExitMs,\n\t\t\t\tobservedBusy: countBusySessions(),\n\t\t\t}),\n\t\t};\n\t}\n\n\tfunction countBusySessions(): number {\n\t\tlet busy = 0;\n\t\tfor (const count of busySessions.values()) if (count > 0) busy++;\n\t\treturn busy;\n\t}\n\n\tfunction observeHostEvent(line: string): void {\n\t\tlet event: unknown;\n\t\ttry {\n\t\t\tevent = JSON.parse(line);\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t\tif (typeof event !== \"object\" || event === null) return;\n\t\tconst { type, sessionId } = event as { type?: unknown; sessionId?: unknown };\n\t\tif (typeof sessionId !== \"string\") return;\n\t\tif (type === \"agent_start\") busySessions.set(sessionId, (busySessions.get(sessionId) ?? 0) + 1);\n\t\telse if (type === \"agent_settled\")\n\t\t\tbusySessions.set(sessionId, Math.max(0, (busySessions.get(sessionId) ?? 1) - 1));\n\t\telse return;\n\t\tdecider.update(currentActivity());\n\t}\n\n\tasync function shutdown(reason: string, exitCode: number): Promise<never> {\n\t\t// Single-flight: concurrent triggers (listener error, child exit, signals)\n\t\t// must not process.exit mid-cleanup. Late callers park on this promise while\n\t\t// the first shutdown finishes tearing down and exits.\n\t\tshutdownPromise ??= performShutdown(reason, exitCode);\n\t\treturn shutdownPromise;\n\t}\n\n\tasync function performShutdown(reason: string, exitCode: number): Promise<never> {\n\t\tif (shuttingDown) process.exit(exitCode);\n\t\tshuttingDown = true;\n\t\tclearInterval(ticker);\n\t\tif (handoffGraceTimer) clearTimeout(handoffGraceTimer);\n\t\tif (childExitWatchTimer) clearInterval(childExitWatchTimer);\n\t\tstopSupersessionWatch?.();\n\t\tconst hardExit =\n\t\t\tprocess.platform === \"win32\"\n\t\t\t\t? setTimeout(() => process.exit(exitCode), WINDOWS_SUPERVISOR_SHUTDOWN_HARD_EXIT_MS)\n\t\t\t\t: undefined;\n\t\ttry {\n\t\t\twriteStderrLine(`senpi rpc host supervisor: ${reason} shutdown`);\n\t\t\tclients.destroyAll();\n\t\t\t// libuv unlinks the bound NAME when the listening handle closes - which\n\t\t\t// would delete a newer host's entry renamed over this path. Shield the\n\t\t\t// current entry for the close, then let the ownership check decide. A drained\n\t\t\t// supervisor already closed that handle when it stopped accepting.\n\t\t\tif (!draining) await shieldSocketDuringClose(publicSocket, () => closeServer(server));\n\t\t\t// Unlink the private directory BEFORE the child stop, which can take seconds:\n\t\t\t// an external SIGKILL landing during that wait (ensureHost escalates while\n\t\t\t// replacing a host) would otherwise leave the directory behind. The child\n\t\t\t// keeps serving through its already-open socket fd until it exits, and its\n\t\t\t// own watchdog cleanup makes the removal idempotent.\n\t\t\tif (internal.dir) await rm(internal.dir, { recursive: true, force: true });\n\t\t\tawait stopChild(child);\n\t\t\tobserverLink.stop();\n\t\t\tobserverSocket?.destroy();\n\t\t\tif (publicSocketOwned && process.platform !== \"win32\") {\n\t\t\t\t// Ownership-checked: after a takeover, a newer host may have published\n\t\t\t\t// a fresh entry at this path; only the entry THIS supervisor bound is\n\t\t\t\t// removed. (The host child applies the same rule to its crash path.)\n\t\t\t\tawait unlinkOwnedSocket(publicSocket, publicSocketIdentity, supervisorLog);\n\t\t\t}\n\t\t\t// The registration describes a LIVE host only; the stderr log stays for diagnostics.\n\t\t\t// After a handoff the pointer describes the SUCCESSOR, so this drops only the generation\n\t\t\t// directory of the process that is leaving, and the pointer only while it still names it.\n\t\t\tawait releaseGeneration(paths, { instanceId, pid: process.pid });\n\t\t} finally {\n\t\t\tif (hardExit) clearTimeout(hardExit);\n\t\t\t// Explicitly terminate after every supervisor shutdown trigger. Windows\n\t\t\t// named-pipe handles can outlive their JavaScript wrappers, so cleanup\n\t\t\t// failure must never leave the supervisor resident or the host orphaned.\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t}\n\n\tlet publicSocketOwned = false;\n\tlet publicSocketIdentity: SocketFileIdentity | undefined;\n\tfunction supervisorLog(message: string): void {\n\t\twriteStderrLine(`senpi rpc host supervisor: ${message}`);\n\t}\n\t// Registered before the startup handshake, not after it: the private internal\n\t// directory already exists at this point, so a SIGTERM arriving during host\n\t// startup must run the same cleanup instead of Node's default kill, which\n\t// would leave that directory behind.\n\t/**\n\t * Ask the child to announce and park attached sessions as turns/requests settle. The supervisor\n\t * owns the soft grace from this instant; expiry rescans but NEVER kills busy sessions. Child\n\t * exit ends the supervisor regardless of clients that keep their connections open.\n\t */\n\tfunction drainForHandoff(): void {\n\t\tif (draining || shuttingDown) return;\n\t\tdraining = true;\n\t\tsupervisorLog(\"draining into the next generation\");\n\t\tconst graceMs = parseIdleExitMs(process.env[HANDOFF_GRACE_MS_ENV]) ?? DEFAULT_HANDOFF_GRACE_MS;\n\t\thandoffGraceTimer = setTimeout(() => {\n\t\t\tsupervisorLog(JSON.stringify({ event: \"handoff_grace_expired\", graceMs }));\n\t\t\trequestChildDrain();\n\t\t}, graceMs);\n\t\thandoffGraceTimer.unref();\n\t\t// The listening handle is deliberately NOT closed: libuv unlinks a pipe's bound NAME when it\n\t\t// closes, and after a handoff that name is the successor's entry. Nothing can reach this\n\t\t// listener by path any more (the rename moved the name), and the accept guard above turns\n\t\t// away whatever raced it, so leaving the handle open until exit costs nothing and keeps the\n\t\t// public path continuously answerable - no window where a client finds no socket at all.\n\t\trequestChildDrain();\n\t}\n\tfunction requestChildDrain(): void {\n\t\tif (child.pid !== undefined && child.exitCode === null && child.signalCode === null) {\n\t\t\ttry {\n\t\t\t\tprocess.kill(child.pid, \"SIGUSR1\");\n\t\t\t} catch (cause) {\n\t\t\t\tsupervisorLog(`could not ask the host to drain: ${errorMessage(cause)}`);\n\t\t\t}\n\t\t}\n\t}\n\tregisterSupervisorSignals(shutdown, drainForHandoff);\n\ttry {\n\t\tawait waitForListener(internalSocket, 30_000, internalSecret);\n\t\tawait observerLink.open();\n\t\tawait prepareSocketPath(bindSocket);\n\t\tawait listen(server, bindSocket, publicSecret);\n\t\tpublicSocketOwned = true;\n\t\tif (successor) await adoptPublicSocket(bindSocket, publicSocket, launch.replaceIdentity);\n\t\tpublicSocketIdentity = await statSocketIdentity(publicSocket);\n\t\t// Publish the ownership token inside this supervisor's private scratch\n\t\t// directory (which no replacement supervisor writes): the host child's\n\t\t// crash-path cleanup compares the public path against THIS entry only.\n\t\tif (publicSocketIdentity && internal.dir) {\n\t\t\tawait writeSocketIdentityFile(join(internal.dir, PUBLIC_SOCKET_IDENTITY_FILE), publicSocketIdentity);\n\t\t}\n\t\t// Losing the public entry IS a drain request: nothing can reach this supervisor by path any\n\t\t// more, and the handoff that replaced it may never have signalled (#1893). A name that was\n\t\t// deleted rather than taken over is the same loss with nobody serving the path (#1961).\n\t\tstopSupersessionWatch = watchForSupersession(\n\t\t\t{ path: publicSocket, identity: publicSocketIdentity, settled: () => shuttingDown || draining },\n\t\t\t(loss) => {\n\t\t\t\tsupervisorLog(\n\t\t\t\t\tloss === \"absent\"\n\t\t\t\t\t\t? \"the public socket entry is gone; nothing can reach this generation; draining\"\n\t\t\t\t\t\t: \"another generation owns the public socket; draining this one\",\n\t\t\t\t);\n\t\t\t\tdrainForHandoff();\n\t\t\t},\n\t\t);\n\t} catch (cause) {\n\t\tawait shutdown(`startup failed: ${errorMessage(cause)}`, 1);\n\t}\n\tif (process.platform === \"win32\" && child.pid !== undefined) {\n\t\t// This baseline read sits outside the startup try/catch, and readProcessStartTime\n\t\t// THROWS when the 1s CIM probe fails (execFile's timeout SIGTERMs the PowerShell\n\t\t// child). With no unhandledRejection handler the supervisor died right here on a\n\t\t// loaded runner: it never reached the \"host ready\" line, and the internal host it\n\t\t// owned vanished with it, surfacing downstream as `connect ENOENT` on the pipe and\n\t\t// as `reported dead`. A failed baseline read is UNKNOWN, so the watchdog simply\n\t\t// starts without one and relies on its own comparisons.\n\t\tconst childStartTime = await readProcessStartTime(child.pid, process.platform, 1_000).catch(() => undefined);\n\t\tlet missingIdentityChecks = 0;\n\t\tlet checkingChildIdentity = false;\n\t\tconst checkChildIdentity = (): void => {\n\t\t\tif (shuttingDown || checkingChildIdentity || child.exitCode !== null || child.signalCode !== null) return;\n\t\t\tcheckingChildIdentity = true;\n\t\t\tvoid readProcessStartTime(child.pid!, process.platform, 1_000)\n\t\t\t\t.then((currentStartTime) => {\n\t\t\t\t\t// An absent identity is only believed once kill(pid, 0) agrees the child is\n\t\t\t\t\t// gone. This probe is a 1s PowerShell CIM spawn polled every 500ms, so a\n\t\t\t\t\t// loaded runner produced two consecutive timeouts and this watchdog shut\n\t\t\t\t\t// down a perfectly healthy host (`does not exit while a turn is active`).\n\t\t\t\t\t// A timed-out probe means UNKNOWN, never EXITED.\n\t\t\t\t\tif (currentStartTime === undefined && !processIsLive(child.pid!)) missingIdentityChecks++;\n\t\t\t\t\telse if (currentStartTime !== undefined) missingIdentityChecks = 0;\n\t\t\t\t\tconst identityChanged =\n\t\t\t\t\t\tchildStartTime !== undefined && currentStartTime !== undefined && currentStartTime !== childStartTime;\n\t\t\t\t\tif (identityChanged || missingIdentityChecks >= 2) {\n\t\t\t\t\t\tvoid shutdown(\"rpc host child exit observed by identity watchdog\", 0);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(() => {})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tcheckingChildIdentity = false;\n\t\t\t\t});\n\t\t};\n\t\tchildExitWatchTimer = setInterval(checkChildIdentity, 500);\n\t\tchildExitWatchTimer.unref?.();\n\t}\n\twriteStderrLine(\n\t\t`senpi rpc host ready on unix://${publicSocket} (coldStart=${policy.coldStart}, idleExitMs=${\n\t\t\tpolicy.coldStart === \"persistent\" ? \"never\" : String(policy.idleExitMs)\n\t\t})`,\n\t);\n\tawait new Promise<never>(() => {});\n}\n\n/**\n * External stop (ensureHost replacement, tests, QA) must clean up like idle exit; SIGUSR1 is the\n * gentler request - finish what you are doing and leave - that a generation handoff and\n * `stopHost({ drain: true })` both send. It exists on POSIX only, which is one reason win32 hosts\n * are attach-only: no signal there means anything but \"terminate\".\n */\nfunction registerSupervisorSignals(\n\tshutdown: (reason: string, exitCode: number) => Promise<never>,\n\tdrain: () => void,\n): void {\n\tfor (const signal of process.platform === \"win32\" ? ([\"SIGTERM\"] as const) : ([\"SIGTERM\", \"SIGHUP\"] as const)) {\n\t\tprocess.on(signal, () => {\n\t\t\tvoid shutdown(`signal:${signal}`, signal === \"SIGHUP\" ? 129 : 143);\n\t\t});\n\t}\n\tif (process.platform !== \"win32\") process.on(\"SIGUSR1\", drain);\n}\n\n/**\n * Takes the public name over with a rename, once - and only while - that name still refers to the\n * entry this handoff was decided against. A socket that changed underneath belongs to another\n * process now: replacing it would unlink an endpoint this generation cannot prove it owns, so the\n * successor aborts instead and leaves both the intruder's socket and its own bind entry alone.\n */\nasync function adoptPublicSocket(\n\tbindSocket: string,\n\tpublicSocket: string,\n\texpected: SocketFileIdentity | undefined,\n): Promise<void> {\n\tif (expected === undefined) throw new Error(`${publicSocket}: a generation launch must name the entry it replaces`);\n\tconst current = await statSocketIdentity(publicSocket);\n\tif (current === undefined || current.dev !== expected.dev || current.ino !== expected.ino) {\n\t\tthrow new Error(`${publicSocket}: owned by another socket entry now; refusing to replace it`);\n\t}\n\t// rename(2) is atomic for readers of the path: every connect either reaches the old entry or\n\t// this one, never nothing. The inode this supervisor bound simply answers to a second name.\n\tawait rename(bindSocket, publicSocket);\n}\n\n/**\n * Reuses an existing valid secret - including one ensureHost() just wrote - and\n * creates one (with its parent directories, mode 0600) when it is missing or\n * unusable. Reuse is required, not just an optimization: on win32 the pipe name\n * is derived from the socket path AND the secret, so rotating it here would\n * point this supervisor at a different endpoint than its caller published.\n * A failure names the bootstrap step and the path it could not provision.\n */\nasync function ensurePublicSocketSecret(publicSocket: string): Promise<Buffer> {\n\tconst secretPath = socketSecretPath(publicSocket);\n\ttry {\n\t\treturn await ensureSocketSecret(secretPath);\n\t} catch (cause) {\n\t\tthrow new Error(`senpi rpc host supervisor: cannot provision public socket secret ${secretPath}`, { cause });\n\t}\n}\n\nasync function readSettingsFile(settingsFile: string): Promise<unknown> {\n\ttry {\n\t\treturn JSON.parse(await readFile(settingsFile, \"utf8\"));\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function stopChild(child: ChildProcess): Promise<void> {\n\tif (child.exitCode !== null || child.signalCode !== null) return;\n\ttry {\n\t\tchild.kill(\"SIGTERM\");\n\t} catch {\n\t\treturn;\n\t}\n\tif (await waitForChildExit(child, CHILD_STOP_TIMEOUT_MS)) return;\n\ttry {\n\t\tchild.kill(\"SIGKILL\");\n\t} catch {\n\t\treturn;\n\t}\n\tawait waitForChildExit(child, 2_000);\n}\n\nfunction waitForChildExit(child: ChildProcess, timeoutMs: number): Promise<boolean> {\n\tif (child.exitCode !== null || child.signalCode !== null) return Promise.resolve(true);\n\treturn new Promise((resolve) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tchild.off(\"exit\", onExit);\n\t\t\tresolve(false);\n\t\t}, timeoutMs);\n\t\tconst onExit = (): void => {\n\t\t\tclearTimeout(timer);\n\t\t\tresolve(true);\n\t\t};\n\t\tchild.once(\"exit\", onExit);\n\t});\n}\n\nasync function waitForListener(socketPath: string, timeoutMs: number, secret?: Uint8Array): Promise<void> {\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (Date.now() <= deadline) {\n\t\tif (await canConnect(socketPath, secret)) return;\n\t\tawait delay(50);\n\t}\n\tthrow new Error(`${socketPath}: host did not start listening within ${timeoutMs}ms`);\n}\n\nfunction canConnect(socketPath: string, secret?: Uint8Array): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = createConnection(resolveSocketTransportAddress(socketPath, process.platform, secret));\n\t\tif (secret) sendSocketHandshake(socket, secret);\n\t\tconst settle = (value: boolean): void => {\n\t\t\tsocket.destroy();\n\t\t\tresolve(value);\n\t\t};\n\t\tsocket.once(\"connect\", () => settle(true));\n\t\tsocket.once(\"error\", () => settle(false));\n\t});\n}\n\nfunction waitForConnect(socket: Socket, timeoutMs: number): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tcleanup();\n\t\t\treject(new Error(`observer connection to internal host timed out after ${timeoutMs}ms`));\n\t\t}, timeoutMs);\n\t\tconst onConnect = (): void => {\n\t\t\tcleanup();\n\t\t\tresolve();\n\t\t};\n\t\tconst onError = (cause: Error): void => {\n\t\t\tcleanup();\n\t\t\treject(cause);\n\t\t};\n\t\tconst cleanup = (): void => {\n\t\t\tclearTimeout(timer);\n\t\t\tsocket.off(\"connect\", onConnect);\n\t\t\tsocket.off(\"error\", onError);\n\t\t};\n\t\tsocket.once(\"connect\", onConnect);\n\t\tsocket.once(\"error\", onError);\n\t});\n}\n\nasync function prepareSocketPath(socketPath: string): Promise<void> {\n\tif (process.platform === \"win32\") return;\n\t// A path the kernel would truncate binds a DIFFERENT endpoint than the one every client was\n\t// told about, and the failure surfaces much later as \"the host does not answer\". Refuse here.\n\tif (Buffer.byteLength(socketPath) > MAX_SOCKET_PATH_BYTES) {\n\t\tthrow new Error(\n\t\t\t`${socketPath}: socket path is ${Buffer.byteLength(socketPath)} bytes, over the ${MAX_SOCKET_PATH_BYTES}-byte limit.`,\n\t\t);\n\t}\n\tawait mkdir(dirname(socketPath), { recursive: true, mode: 0o700 });\n\ttry {\n\t\tawait access(socketPath);\n\t} catch (cause) {\n\t\tif (isNodeErrorCode(cause, \"ENOENT\")) return;\n\t\tthrow cause;\n\t}\n\tif (await canConnect(socketPath)) throw new Error(`${socketPath}: address already in use by a live server.`);\n\tawait unlink(socketPath);\n}\n\nfunction listen(server: Server, socketPath: string, secret?: Uint8Array): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tserver.once(\"error\", reject);\n\t\tserver.listen(\n\t\t\t{\n\t\t\t\tpath: resolveSocketTransportAddress(socketPath, process.platform, secret),\n\t\t\t\treadableAll: false,\n\t\t\t\twritableAll: false,\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tserver.off(\"error\", reject);\n\t\t\t\ttry {\n\t\t\t\t\tif (process.platform !== \"win32\" && !socketPath.startsWith(\"\\0\")) await chmod(socketPath, 0o600);\n\t\t\t\t\tresolve();\n\t\t\t\t} catch (cause) {\n\t\t\t\t\treject(cause);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t});\n}\n\nfunction closeServer(server: Server): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tserver.close(() => resolve());\n\t});\n}\n\nfunction writeStderrLine(text: string): void {\n\t// A detached daemon exiting right after an async stderr.write to a file can\n\t// lose the output entirely; write synchronously so diagnostics always land.\n\ttry {\n\t\twriteSync(2, `${text}\\n`);\n\t} catch {\n\t\t/* fd 2 unavailable: nothing more we can do. */\n\t}\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolveDelay) => setTimeout(resolveDelay, ms));\n}\n\nfunction errorMessage(cause: unknown): string {\n\treturn cause instanceof Error ? cause.message : String(cause);\n}\n\nfunction isNodeErrorCode(cause: unknown, code: string): boolean {\n\treturn cause instanceof Error && \"code\" in cause && cause.code === code;\n}\n\nfunction isEntryScript(): boolean {\n\tconst entry = process.argv[1];\n\tif (!entry) return false;\n\ttry {\n\t\treturn fileURLToPath(import.meta.url) === realpathSync(entry);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nif (!isBundledNode && isEntryScript()) {\n\tconst launch = parseSupervisorArgs(process.argv.slice(2));\n\tif (!launch) {\n\t\twriteStderrLine(\"usage: host-lifecycle.ts --socket <path> [host cli args...]\");\n\t\tprocess.exit(2);\n\t}\n\tvoid runHostSupervisor(launch);\n}\n"]}
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Only the two side-effect-free reads can observe: `observe: true` on any other command is ignored
|
|
11
11
|
* and the connection attaches, so a client cannot hold a session while its host idles out under it.
|
|
12
|
+
* `warm` never attaches, marked or not: it opens nothing, so a host that only received it idles out
|
|
13
|
+
* on its normal deadline (senpi#2314).
|
|
12
14
|
* Hosts that predate the field ignore it (commands are parsed by `type`), so a marked read works
|
|
13
15
|
* against every generation.
|
|
14
16
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-observe-request.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/host-observe-request.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"host-observe-request.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/host-observe-request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,qBAAqB,YAAY,CAAC;AAI/C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAWxD"}
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Only the two side-effect-free reads can observe: `observe: true` on any other command is ignored
|
|
11
11
|
* and the connection attaches, so a client cannot hold a session while its host idles out under it.
|
|
12
|
+
* `warm` never attaches, marked or not: it opens nothing, so a host that only received it idles out
|
|
13
|
+
* on its normal deadline (senpi#2314).
|
|
12
14
|
* Hosts that predate the field ignore it (commands are parsed by `type`), so a marked read works
|
|
13
15
|
* against every generation.
|
|
14
16
|
*/
|
|
@@ -25,6 +27,8 @@ export function isObservingRequest(line) {
|
|
|
25
27
|
if (typeof request !== "object" || request === null || Array.isArray(request))
|
|
26
28
|
return false;
|
|
27
29
|
const record = request;
|
|
30
|
+
if (record.type === "warm")
|
|
31
|
+
return true;
|
|
28
32
|
return record[OBSERVE_REQUEST_FIELD] === true && OBSERVING_COMMANDS.has(record.type);
|
|
29
33
|
}
|
|
30
34
|
//# sourceMappingURL=host-observe-request.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-observe-request.js","sourceRoot":"","sources":["../../../src/modes/rpc/host-observe-request.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"host-observe-request.js","sourceRoot":"","sources":["../../../src/modes/rpc/host-observe-request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAAC;AAE/C,MAAM,kBAAkB,GAAyB,IAAI,GAAG,CAAC,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC,CAAC;AAEjG,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC9C,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACJ,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5F,MAAM,MAAM,GAAG,OAA4C,CAAC;IAC5D,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,MAAM,CAAC,qBAAqB,CAAC,KAAK,IAAI,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACtF,CAAC","sourcesContent":["/**\n * Which public-socket connections count as host activity.\n *\n * The supervisor keeps a host alive while a client is attached, so anything that merely LOOKS at a\n * host - `senpi host status [--all]`, a doctor loop, a runtime panel polling every endpoint - would\n * otherwise reset the idle window on every poll and keep every shard alive forever. A read marks\n * itself with `observe: true`; the supervisor classifies a connection by the requests it sends, and\n * only a connection that sends something other than an observing read becomes an attachment.\n *\n * Only the two side-effect-free reads can observe: `observe: true` on any other command is ignored\n * and the connection attaches, so a client cannot hold a session while its host idles out under it.\n * `warm` never attaches, marked or not: it opens nothing, so a host that only received it idles out\n * on its normal deadline (senpi#2314).\n * Hosts that predate the field ignore it (commands are parsed by `type`), so a marked read works\n * against every generation.\n */\n\nexport const OBSERVE_REQUEST_FIELD = \"observe\";\n\nconst OBSERVING_COMMANDS: ReadonlySet<unknown> = new Set([\"get_protocol_info\", \"list_sessions\"]);\n\nexport function isObservingRequest(line: string): boolean {\n\tlet request: unknown;\n\ttry {\n\t\trequest = JSON.parse(line);\n\t} catch {\n\t\treturn false;\n\t}\n\tif (typeof request !== \"object\" || request === null || Array.isArray(request)) return false;\n\tconst record = request as Readonly<Record<string, unknown>>;\n\tif (record.type === \"warm\") return true;\n\treturn record[OBSERVE_REQUEST_FIELD] === true && OBSERVING_COMMANDS.has(record.type);\n}\n"]}
|
|
@@ -2,8 +2,8 @@ import { ENV_AGENT_DIR, getAgentDir } from "../../config.js";
|
|
|
2
2
|
import { RPC_CLIENT_CAPABILITIES_ENV } from "./custom-capability.js";
|
|
3
3
|
import { daemonEnvironment } from "./host-daemon-env.js";
|
|
4
4
|
import { HOST_DAEMON_DIR_ENV } from "./host-daemon-paths.js";
|
|
5
|
+
import { HOST_GENERATION_ENV, HOST_INSTANCE_ID_ENV } from "./host-identity-env.js";
|
|
5
6
|
import { PINNED_HOST_CLIENT_CAPABILITIES } from "./host-launch.js";
|
|
6
|
-
import { HOST_GENERATION_ENV, HOST_INSTANCE_ID_ENV } from "./protocol-identity.js";
|
|
7
7
|
export function initialHostEnvironment(options) {
|
|
8
8
|
return daemonEnvironment(process.env, options.env, {
|
|
9
9
|
[ENV_AGENT_DIR]: options.agentDir ?? getAgentDir(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-spawn-environment.js","sourceRoot":"","sources":["../../../src/modes/rpc/host-spawn-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAwB,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE
|
|
1
|
+
{"version":3,"file":"host-spawn-environment.js","sourceRoot":"","sources":["../../../src/modes/rpc/host-spawn-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAwB,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAC;AAEnE,MAAM,UAAU,sBAAsB,CAAC,OAMtC;IACA,OAAO,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClD,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,QAAQ,IAAI,WAAW,EAAE;QAClD,CAAC,2BAA2B,CAAC,EAAE,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC;QACxE,yFAAyF;QACzF,6FAA6F;QAC7F,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,UAAU;QAC1C,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;QACjD,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;KACxC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAMxC;IACA,OAAO,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClD,CAAC,2BAA2B,CAAC,EAAE,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC;QACxE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,UAAU;QAC1C,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;QACjD,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;KACxC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { ENV_AGENT_DIR, getAgentDir } from \"../../config.ts\";\nimport { RPC_CLIENT_CAPABILITIES_ENV } from \"./custom-capability.ts\";\nimport { daemonEnvironment } from \"./host-daemon-env.ts\";\nimport { HOST_DAEMON_DIR_ENV, type HostDaemonPaths } from \"./host-daemon-paths.ts\";\nimport { HOST_GENERATION_ENV, HOST_INSTANCE_ID_ENV } from \"./host-identity-env.ts\";\nimport { PINNED_HOST_CLIENT_CAPABILITIES } from \"./host-launch.ts\";\n\nexport function initialHostEnvironment(options: {\n\treadonly agentDir?: string;\n\treadonly env?: Readonly<Record<string, string | null>>;\n\treadonly paths: HostDaemonPaths;\n\treadonly instanceId: string;\n\treadonly generation: number;\n}): NodeJS.ProcessEnv {\n\treturn daemonEnvironment(process.env, options.env, {\n\t\t[ENV_AGENT_DIR]: options.agentDir ?? getAgentDir(),\n\t\t[RPC_CLIENT_CAPABILITIES_ENV]: PINNED_HOST_CLIENT_CAPABILITIES.join(\",\"),\n\t\t// Always SET, never inherited: two generations claiming one instance id make the handoff\n\t\t// completion signal - the instance id changing on the public socket - impossible to observe.\n\t\t[HOST_INSTANCE_ID_ENV]: options.instanceId,\n\t\t[HOST_GENERATION_ENV]: String(options.generation),\n\t\t[HOST_DAEMON_DIR_ENV]: options.paths.dir,\n\t});\n}\n\nexport function successorHostEnvironment(options: {\n\treadonly agentDir?: string;\n\treadonly env?: Readonly<Record<string, string | null>>;\n\treadonly paths: HostDaemonPaths;\n\treadonly instanceId: string;\n\treadonly generation: number;\n}): NodeJS.ProcessEnv {\n\treturn daemonEnvironment(process.env, options.env, {\n\t\t[RPC_CLIENT_CAPABILITIES_ENV]: PINNED_HOST_CLIENT_CAPABILITIES.join(\",\"),\n\t\t...(options.agentDir ? { [ENV_AGENT_DIR]: options.agentDir } : {}),\n\t\t[HOST_INSTANCE_ID_ENV]: options.instanceId,\n\t\t[HOST_GENERATION_ENV]: String(options.generation),\n\t\t[HOST_DAEMON_DIR_ENV]: options.paths.dir,\n\t});\n}\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AgentSessionLaunchProfile, CreateAgentSessionRuntimeFactory } from "../../core/agent-session-runtime.ts";
|
|
2
|
+
import type { HostMcpRegistry } from "../../core/extensions/builtin/mcp/host-registry.ts";
|
|
3
|
+
import type { SessionContext, SessionKind } from "../../core/extensions/types.ts";
|
|
4
|
+
import type { RpcCommand, RpcResponse } from "./rpc-types.ts";
|
|
5
|
+
/** What a runtime factory needs to build a session's services without the session. */
|
|
6
|
+
export interface PrepareRuntimeOptions {
|
|
7
|
+
cwd: string;
|
|
8
|
+
agentDir: string;
|
|
9
|
+
mcpRegistry?: HostMcpRegistry;
|
|
10
|
+
launchProfile: Readonly<AgentSessionLaunchProfile>;
|
|
11
|
+
}
|
|
12
|
+
/** A runtime factory that can also build its cwd-bound services alone, for `warm`. */
|
|
13
|
+
export type PreparableRuntimeFactory = CreateAgentSessionRuntimeFactory & {
|
|
14
|
+
readonly prepare?: (options: PrepareRuntimeOptions) => Promise<void>;
|
|
15
|
+
};
|
|
16
|
+
/** The launch inputs that decide which extensions load, and so what a warm prepares. */
|
|
17
|
+
export interface HostWarmProfile {
|
|
18
|
+
cwd: string;
|
|
19
|
+
sessionKind?: SessionKind;
|
|
20
|
+
sessionContext?: SessionContext;
|
|
21
|
+
}
|
|
22
|
+
/** `warmed`: this call (or one it joined) loaded the profile. `already_warm`: an earlier one had. */
|
|
23
|
+
export type HostWarmState = "warmed" | "already_warm";
|
|
24
|
+
export type HostWarm = (profile: HostWarmProfile) => Promise<HostWarmState>;
|
|
25
|
+
/** Coalesces concurrent warms of one profile and answers repeats without loading again. */
|
|
26
|
+
export declare class HostWarmer {
|
|
27
|
+
private readonly warm;
|
|
28
|
+
private readonly loading;
|
|
29
|
+
private readonly load;
|
|
30
|
+
constructor(load: (profile: HostWarmProfile) => Promise<void>);
|
|
31
|
+
run(profile: HostWarmProfile): Promise<HostWarmState>;
|
|
32
|
+
private loadOnce;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The in-process registry's `warm`. The services are built inside their own provider scope, exactly
|
|
36
|
+
* like an open's, and the scope closes when they are dropped, so nothing an extension registered
|
|
37
|
+
* while loading outlives the warm.
|
|
38
|
+
*/
|
|
39
|
+
export declare function createRegistryWarm(prepare: NonNullable<PreparableRuntimeFactory["prepare"]>, host: {
|
|
40
|
+
agentDir: string;
|
|
41
|
+
mcpRegistry?: HostMcpRegistry;
|
|
42
|
+
}): HostWarm;
|
|
43
|
+
type WarmCommand = Extract<RpcCommand, {
|
|
44
|
+
type: "warm";
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Answers one `warm`. The router calls this OUTSIDE its request accounting: a warm holds no session
|
|
48
|
+
* and no path, so neither a drain nor an idle window waits for it.
|
|
49
|
+
*/
|
|
50
|
+
export declare function answerWarm(command: WarmCommand, host: {
|
|
51
|
+
draining: boolean;
|
|
52
|
+
warm: HostWarm | undefined;
|
|
53
|
+
cwd: string;
|
|
54
|
+
hostContext: SessionContext | undefined;
|
|
55
|
+
}): Promise<RpcResponse>;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=host-warm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-warm.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/host-warm.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gCAAgC,EAAE,MAAM,qCAAqC,CAAC;AACvH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oDAAoD,CAAC;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAElF,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAQ9D,sFAAsF;AACtF,MAAM,WAAW,qBAAqB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,aAAa,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC;CACnD;AAED,sFAAsF;AACtF,MAAM,MAAM,wBAAwB,GAAG,gCAAgC,GAAG;IACzE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE,CAAC;AAEF,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;CAChC;AAED,qGAAqG;AACrG,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,cAAc,CAAC;AAEtD,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAU5E,2FAA2F;AAC3F,qBAAa,UAAU;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8C;IAEnE,YAAY,IAAI,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,EAE5D;IAEK,GAAG,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,CAU1D;YAEa,QAAQ;CAYtB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,WAAW,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC,EACzD,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,eAAe,CAAA;CAAE,GACvD,QAAQ,CAyBV;AAED,KAAK,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAMzD;;;GAGG;AACH,wBAAsB,UAAU,CAC/B,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE;IACL,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,cAAc,GAAG,SAAS,CAAC;CACxC,GACC,OAAO,CAAC,WAAW,CAAC,CAsBtB"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `warm`: load what the next `open_session` needs without opening a session (senpi#2314).
|
|
3
|
+
*
|
|
4
|
+
* A fresh host pays a one-time cost on its first session: the extension module graph compiles and
|
|
5
|
+
* the extensions' factories load their runtimes (a task engine, for a `child` role). With one host
|
|
6
|
+
* per session every session paid it. `warm` builds the cwd-bound services an open would build for
|
|
7
|
+
* the same cwd, kind and context - which compiles that graph and runs those factories - and drops
|
|
8
|
+
* them. No `AgentSession` exists, no `session_start` fires, nothing is registered or listed, and
|
|
9
|
+
* the connection that asked stays an observer (`host-observe-request.ts`), so a host that only
|
|
10
|
+
* received `warm` still idles out on its normal deadline.
|
|
11
|
+
*
|
|
12
|
+
* A profile is warmed once per host: a repeat answers `already_warm` without running factories
|
|
13
|
+
* again, and concurrent warms of one profile share a single load.
|
|
14
|
+
*/
|
|
15
|
+
import { access } from "node:fs/promises";
|
|
16
|
+
import { isAbsolute } from "node:path";
|
|
17
|
+
import { ProviderScope, runWithProviderScope } from "@earendil-works/pi-ai/node/provider-scope";
|
|
18
|
+
import { sessionContextError, sessionKindError } from "./rpc-input-validation.js";
|
|
19
|
+
import { RPC_ERROR_INVALID_PATH, RPC_ERROR_INVALID_SESSION_CONTEXT, RPC_ERROR_INVALID_SESSION_KIND, RPC_ERROR_WARM_FAILED, } from "./rpc-types.js";
|
|
20
|
+
/** Distinct profiles a host remembers as warm; the oldest is forgotten past this. */
|
|
21
|
+
const MAX_WARM_PROFILES = 64;
|
|
22
|
+
function profileKey(profile) {
|
|
23
|
+
const context = Object.entries(profile.sessionContext ?? {}).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
24
|
+
return JSON.stringify([profile.cwd, profile.sessionKind ?? "interactive", context]);
|
|
25
|
+
}
|
|
26
|
+
/** Coalesces concurrent warms of one profile and answers repeats without loading again. */
|
|
27
|
+
export class HostWarmer {
|
|
28
|
+
constructor(load) {
|
|
29
|
+
this.warm = new Set();
|
|
30
|
+
this.loading = new Map();
|
|
31
|
+
this.load = load;
|
|
32
|
+
}
|
|
33
|
+
async run(profile) {
|
|
34
|
+
const key = profileKey(profile);
|
|
35
|
+
if (this.warm.has(key))
|
|
36
|
+
return "already_warm";
|
|
37
|
+
let pending = this.loading.get(key);
|
|
38
|
+
if (pending === undefined) {
|
|
39
|
+
pending = this.loadOnce(key, profile);
|
|
40
|
+
this.loading.set(key, pending);
|
|
41
|
+
}
|
|
42
|
+
await pending;
|
|
43
|
+
return "warmed";
|
|
44
|
+
}
|
|
45
|
+
async loadOnce(key, profile) {
|
|
46
|
+
try {
|
|
47
|
+
await this.load(profile);
|
|
48
|
+
this.warm.add(key);
|
|
49
|
+
if (this.warm.size > MAX_WARM_PROFILES) {
|
|
50
|
+
const oldest = this.warm.values().next().value;
|
|
51
|
+
if (oldest !== undefined)
|
|
52
|
+
this.warm.delete(oldest);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
this.loading.delete(key);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The in-process registry's `warm`. The services are built inside their own provider scope, exactly
|
|
62
|
+
* like an open's, and the scope closes when they are dropped, so nothing an extension registered
|
|
63
|
+
* while loading outlives the warm.
|
|
64
|
+
*/
|
|
65
|
+
export function createRegistryWarm(prepare, host) {
|
|
66
|
+
const warmer = new HostWarmer(async (profile) => {
|
|
67
|
+
await access(profile.cwd);
|
|
68
|
+
const launchProfile = {
|
|
69
|
+
cwd: profile.cwd,
|
|
70
|
+
...(profile.sessionKind !== undefined ? { sessionKind: profile.sessionKind } : {}),
|
|
71
|
+
...(profile.sessionContext !== undefined
|
|
72
|
+
? { sessionContext: Object.freeze({ ...profile.sessionContext }) }
|
|
73
|
+
: {}),
|
|
74
|
+
};
|
|
75
|
+
const scope = new ProviderScope();
|
|
76
|
+
try {
|
|
77
|
+
await runWithProviderScope(scope, () => prepare({
|
|
78
|
+
cwd: profile.cwd,
|
|
79
|
+
agentDir: host.agentDir,
|
|
80
|
+
launchProfile: Object.freeze(launchProfile),
|
|
81
|
+
...(host.mcpRegistry !== undefined ? { mcpRegistry: host.mcpRegistry } : {}),
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
scope.close();
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return (profile) => warmer.run(profile);
|
|
89
|
+
}
|
|
90
|
+
function refusal(command, code) {
|
|
91
|
+
return { id: command.id, type: "response", command: "warm", success: false, error: code };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Answers one `warm`. The router calls this OUTSIDE its request accounting: a warm holds no session
|
|
95
|
+
* and no path, so neither a drain nor an idle window waits for it.
|
|
96
|
+
*/
|
|
97
|
+
export async function answerWarm(command, host) {
|
|
98
|
+
if (host.draining)
|
|
99
|
+
return refusal(command, "host_draining");
|
|
100
|
+
const kindError = sessionKindError(command.kind);
|
|
101
|
+
if (kindError)
|
|
102
|
+
return refusal(command, `${RPC_ERROR_INVALID_SESSION_KIND}: ${kindError}`);
|
|
103
|
+
const contextError = sessionContextError(command.context);
|
|
104
|
+
if (contextError)
|
|
105
|
+
return refusal(command, `${RPC_ERROR_INVALID_SESSION_CONTEXT}: ${contextError}`);
|
|
106
|
+
if (host.warm === undefined)
|
|
107
|
+
return { id: command.id, type: "response", command: "warm", success: true, data: { state: "unsupported" } };
|
|
108
|
+
// The same context an open on this host would hand its extensions: the host's identity wins.
|
|
109
|
+
const sessionContext = host.hostContext ? { ...command.context, ...host.hostContext } : command.context;
|
|
110
|
+
const cwd = command.cwd ?? host.cwd;
|
|
111
|
+
if (!isAbsolute(cwd))
|
|
112
|
+
return refusal(command, RPC_ERROR_INVALID_PATH);
|
|
113
|
+
try {
|
|
114
|
+
const state = await host.warm({
|
|
115
|
+
cwd,
|
|
116
|
+
...(command.kind !== undefined ? { sessionKind: command.kind } : {}),
|
|
117
|
+
...(sessionContext !== undefined ? { sessionContext } : {}),
|
|
118
|
+
});
|
|
119
|
+
return { id: command.id, type: "response", command: "warm", success: true, data: { state } };
|
|
120
|
+
}
|
|
121
|
+
catch (cause) {
|
|
122
|
+
return refusal(command, `${RPC_ERROR_WARM_FAILED}: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=host-warm.js.map
|