@ponythewhite/base-context 1.0.13 → 1.0.15

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.
Files changed (83) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/base-context-runtime/pyproject.toml +1 -1
  3. package/dist/base-context-runtime/uv.lock +1 -1
  4. package/dist/build-info.json +1 -1
  5. package/dist/bundle/amazon-bedrock.js +3 -3
  6. package/dist/bundle/{anthropic-BJVPUMPB.js → anthropic-AXUXEET7.js} +1 -1
  7. package/dist/bundle/{azure-openai-responses-ERRMAXK6.js → azure-openai-responses-J3NTJKEO.js} +2 -2
  8. package/dist/bundle/{bundled-modules-URKVA3UB.js → bundled-modules-O67MEO74.js} +5 -5
  9. package/dist/bundle/{chunk-FOGKLC7V.js → chunk-72LSQYUV.js} +1 -1
  10. package/dist/bundle/{chunk-TXVF6Q5H.js → chunk-DGO66I3L.js} +87 -51
  11. package/dist/bundle/{chunk-MUFZODP5.js → chunk-EGFIZABJ.js} +1 -1
  12. package/dist/bundle/{chunk-AEMRBMI2.js → chunk-IEM74GZ5.js} +9 -9
  13. package/dist/bundle/{chunk-25VYRAC6.js → chunk-JKKXN6JE.js} +72 -0
  14. package/dist/bundle/{chunk-TKOBEJ5E.js → chunk-RQFC34FM.js} +151 -51
  15. package/dist/bundle/{chunk-Q6UAHLII.js → chunk-V6LOBH6X.js} +2 -2
  16. package/dist/bundle/{cli-main-ZTJM5EEH.js → cli-main-2RER6PBE.js} +4 -4
  17. package/dist/bundle/cli.js +1 -1
  18. package/dist/bundle/{google-4GA4YMUX.js → google-QLKV2ZLC.js} +2 -2
  19. package/dist/bundle/{google-vertex-7AMALD7D.js → google-vertex-UGLUZV6B.js} +2 -2
  20. package/dist/bundle/{main-53I74INO.js → main-YERLD3T4.js} +5 -5
  21. package/dist/bundle/{mistral-74BXMNRM.js → mistral-2ITSLHYF.js} +1 -1
  22. package/dist/bundle/{openai-codex-responses-COXNC4IH.js → openai-codex-responses-FRREQXS3.js} +5 -4
  23. package/dist/bundle/{openai-completions-BCSA5Q6S.js → openai-completions-HF6UPPLW.js} +1 -1
  24. package/dist/bundle/{openai-responses-ONCIZSJS.js → openai-responses-LRTMBDFW.js} +2 -2
  25. package/dist/core/agent-session.d.ts.map +1 -1
  26. package/dist/core/agent-session.js +42 -25
  27. package/dist/core/agent-session.js.map +1 -1
  28. package/dist/core/autonomous.d.ts +2 -0
  29. package/dist/core/autonomous.d.ts.map +1 -1
  30. package/dist/core/autonomous.js +4 -0
  31. package/dist/core/autonomous.js.map +1 -1
  32. package/dist/core/canonical-context.d.ts.map +1 -1
  33. package/dist/core/canonical-context.js +7 -0
  34. package/dist/core/canonical-context.js.map +1 -1
  35. package/dist/core/compaction/compaction.d.ts +1 -1
  36. package/dist/core/compaction/compaction.d.ts.map +1 -1
  37. package/dist/core/compaction/compaction.js +11 -9
  38. package/dist/core/compaction/compaction.js.map +1 -1
  39. package/dist/core/inference-coordinator.d.ts.map +1 -1
  40. package/dist/core/inference-coordinator.js +13 -2
  41. package/dist/core/inference-coordinator.js.map +1 -1
  42. package/dist/core/kernel/repl-manager.d.ts.map +1 -1
  43. package/dist/core/kernel/repl-manager.js +5 -0
  44. package/dist/core/kernel/repl-manager.js.map +1 -1
  45. package/dist/core/public-context.d.ts.map +1 -1
  46. package/dist/core/public-context.js +2 -0
  47. package/dist/core/public-context.js.map +1 -1
  48. package/dist/core/session-manager.d.ts +8 -0
  49. package/dist/core/session-manager.d.ts.map +1 -1
  50. package/dist/core/session-manager.js +57 -0
  51. package/dist/core/session-manager.js.map +1 -1
  52. package/dist/core/view-units.d.ts.map +1 -1
  53. package/dist/core/view-units.js +3 -0
  54. package/dist/core/view-units.js.map +1 -1
  55. package/dist/main.d.ts.map +1 -1
  56. package/dist/main.js +1 -1
  57. package/dist/main.js.map +1 -1
  58. package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
  59. package/dist/modes/daemon/daemon-mode.js +21 -20
  60. package/dist/modes/daemon/daemon-mode.js.map +1 -1
  61. package/dist/modes/daemon/daemon-supervisor.d.ts.map +1 -1
  62. package/dist/modes/daemon/daemon-supervisor.js +11 -5
  63. package/dist/modes/daemon/daemon-supervisor.js.map +1 -1
  64. package/dist/modes/daemon/daemon-worker-client.d.ts +1 -0
  65. package/dist/modes/daemon/daemon-worker-client.d.ts.map +1 -1
  66. package/dist/modes/daemon/daemon-worker-client.js +8 -0
  67. package/dist/modes/daemon/daemon-worker-client.js.map +1 -1
  68. package/dist/modes/daemon/daemon-worker-protocol.d.ts +3 -0
  69. package/dist/modes/daemon/daemon-worker-protocol.d.ts.map +1 -1
  70. package/dist/modes/daemon/daemon-worker-protocol.js +2 -0
  71. package/dist/modes/daemon/daemon-worker-protocol.js.map +1 -1
  72. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  73. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  74. package/dist/modes/interactive/interactive-mode.js +29 -4
  75. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  76. package/dist/modes/print-mode.d.ts.map +1 -1
  77. package/dist/modes/print-mode.js +24 -21
  78. package/dist/modes/print-mode.js.map +1 -1
  79. package/docs/json.md +14 -1
  80. package/docs/long-running-agents.md +23 -2
  81. package/docs/providers.md +17 -0
  82. package/docs/upstream-1.0.15.md +83 -0
  83. package/package.json +4 -4
@@ -58,6 +58,7 @@ export declare class DaemonWorkerClient {
58
58
  private emitDirectOutbound;
59
59
  private directCloseError;
60
60
  private rejectAll;
61
+ private clearSocketReference;
61
62
  private notifyClosed;
62
63
  }
63
64
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-worker-client.d.ts","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { createConnection, type Socket } from \"node:net\";\nimport { serializeJsonLine } from \"../rpc/jsonl.js\";\nimport { type PrivateFrame, PrivateFramedChannel } from \"../session-worker/private-framing.js\";\nimport {\n\tDaemonCapabilityUnavailableError,\n\ttype DaemonClientMessageListener,\n\ttype DaemonClientRequestOptions,\n\tDaemonSocketClosedError,\n} from \"./daemon-client.js\";\nimport {\n\tDAEMON_COMMAND_COMPATIBILITY,\n\tDAEMON_LEGACY_INSPECTION_PROTOCOL_VERSIONS,\n\tDAEMON_PROTOCOL_NAME,\n\tDAEMON_PROTOCOL_VERSION,\n\ttype DaemonClosingReason,\n\ttype DaemonCommand,\n\ttype DaemonOutbound,\n\ttype DaemonPeerTransportTicket,\n\ttype DaemonResponse,\n\ttype DaemonServerCapability,\n\tgetDaemonCommandCompatibilities,\n\tmeetsDaemonCommandCompatibility,\n\tNATIVE_WORK_COMPATIBILITIES,\n} from \"./daemon-protocol.js\";\nimport {\n\ttype DaemonPeerCommand,\n\ttype DaemonPeerCommandBody,\n\ttype DaemonWorkerCommand,\n\ttype DaemonWorkerCommandBody,\n\ttype DaemonWorkerFrameHeader,\n\tisDaemonWorkerFrameHeader,\n} from \"./daemon-worker-protocol.js\";\n\ntype DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;\ntype DaemonCommandBody = DistributiveOmit<DaemonCommand, \"id\">;\ntype DaemonWorkerWireCommandBody = DaemonCommandBody | DaemonWorkerCommandBody | DaemonPeerCommandBody;\ntype DaemonWorkerWireCommand = DaemonCommand | DaemonWorkerCommand | DaemonPeerCommand;\ntype DaemonWorkerAuthentication = Omit<Extract<DaemonWorkerCommand, { type: \"worker_auth\" }>, \"id\" | \"type\" | \"token\">;\n\nexport type DaemonWorkerFrameListener = (frame: PrivateFrame<DaemonWorkerFrameHeader>) => void;\nexport type DaemonWorkerCloseListener = (error: Error) => void;\ntype DaemonHello = Extract<DaemonOutbound, { type: \"daemon_hello\" }>;\n\nexport class DaemonWorkerAuthenticationError extends Error {}\n\n/** A live incompatible owner is not a dead worker or a retryable probe timeout. */\nexport class DaemonWorkerCompatibilityError extends Error {\n\tconstructor(hello: DaemonHello) {\n\t\tsuper(\n\t\t\t`Daemon worker ${hello.protocol.name} protocol ${hello.protocol.version} cannot provide canonical session ownership, native inference ownership, and bounded invocation output. Keep its live owner intact; update or stop it with its own runtime before recovery.`,\n\t\t);\n\t\tthis.name = \"DaemonWorkerCompatibilityError\";\n\t}\n}\n\n/** A probe (hello/response/connect) timed out; recovery treats the worker as live-but-slow, never dead. */\nexport class DaemonWorkerProbeTimeoutError extends Error {}\n\nexport class DaemonWorkerClient {\n\tprivate socket?: Socket;\n\tprivate channel?: PrivateFramedChannel<DaemonWorkerFrameHeader>;\n\tprivate readonly frameListeners = new Set<DaemonWorkerFrameListener>();\n\tprivate readonly messageListeners = new Set<DaemonClientMessageListener>();\n\tprivate readonly closeListeners = new Set<DaemonWorkerCloseListener>();\n\tprivate readonly pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\tresolve: (response: DaemonResponse) => void;\n\t\t\treject: (error: Error) => void;\n\t\t\ttimeout: ReturnType<typeof setTimeout>;\n\t\t}\n\t>();\n\tprivate requestId = 0;\n\tprivate helloMessage?: DaemonHello;\n\tprivate compatibilityError?: DaemonWorkerCompatibilityError;\n\tprivate directPeer = false;\n\tprivate directClosingReason?: DaemonClosingReason;\n\tprivate readonly helloWaiters = new Set<{\n\t\tresolve: (hello: DaemonHello) => void;\n\t\treject: (error: Error) => void;\n\t\ttimeout: ReturnType<typeof setTimeout>;\n\t}>();\n\n\tconstructor(private readonly socketPath: string) {}\n\n\tget hello(): DaemonHello | undefined {\n\t\treturn this.helloMessage;\n\t}\n\n\tget isConnected(): boolean {\n\t\treturn this.socket !== undefined && !this.socket.destroyed;\n\t}\n\n\tsupportsServerCapability(capability: DaemonServerCapability): boolean {\n\t\treturn this.helloMessage?.serverCapabilities?.includes(capability) === true;\n\t}\n\n\tasync connect(timeoutMs = 3000): Promise<void> {\n\t\tif (this.socket) {\n\t\t\tthrow new Error(\"Daemon worker client is already connected\");\n\t\t}\n\t\tconst socket = createConnection(this.socketPath);\n\t\tthis.socket = socket;\n\t\tthis.channel = new PrivateFramedChannel(socket, isDaemonWorkerFrameHeader);\n\t\tthis.channel.onFrame((frame) => this.handleFrame(frame));\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tcleanup();\n\t\t\t\tsocket.destroy();\n\t\t\t\treject(new Error(`Timed out connecting to daemon worker socket: ${this.socketPath}`));\n\t\t\t}, timeoutMs);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tsocket.off(\"connect\", onConnect);\n\t\t\t\tsocket.off(\"error\", onError);\n\t\t\t};\n\t\t\tconst onConnect = () => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tconst onError = (error: Error) => {\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tsocket.once(\"connect\", onConnect);\n\t\t\tsocket.once(\"error\", onError);\n\t\t});\n\n\t\tsocket.on(\"error\", (error) => this.notifyClosed(socket, this.directCloseError(error)));\n\t\tsocket.on(\"close\", () =>\n\t\t\tthis.notifyClosed(socket, this.directCloseError(new Error(\"Daemon worker socket closed\"))),\n\t\t);\n\t}\n\n\twaitForHello(timeoutMs = 3000): Promise<DaemonHello> {\n\t\tif (this.compatibilityError) return Promise.reject(this.compatibilityError);\n\t\tif (this.helloMessage) {\n\t\t\treturn Promise.resolve(this.helloMessage);\n\t\t}\n\t\tif (!this.socket || this.socket.destroyed) {\n\t\t\treturn Promise.reject(new Error(\"Daemon worker client is not connected\"));\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst waiter = {\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t\ttimeout: setTimeout(() => {\n\t\t\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\t\t\treject(new DaemonWorkerProbeTimeoutError(\"Timed out waiting for daemon worker hello\"));\n\t\t\t\t}, timeoutMs),\n\t\t\t};\n\t\t\tthis.helloWaiters.add(waiter);\n\t\t});\n\t}\n\n\tonFrame(listener: DaemonWorkerFrameListener): () => void {\n\t\tthis.frameListeners.add(listener);\n\t\treturn () => this.frameListeners.delete(listener);\n\t}\n\n\tonMessage(listener: DaemonClientMessageListener): () => void {\n\t\tthis.messageListeners.add(listener);\n\t\treturn () => this.messageListeners.delete(listener);\n\t}\n\n\tonClose(listener: DaemonWorkerCloseListener): () => void {\n\t\tthis.closeListeners.add(listener);\n\t\treturn () => this.closeListeners.delete(listener);\n\t}\n\n\tasync request(\n\t\tcommand: DaemonCommandBody,\n\t\ttimeoutMs = 30_000,\n\t\t// Progress/recovery options are supervisor-transport features; a direct request fails fast instead of replaying (no double execution).\n\t\t_options: DaemonClientRequestOptions = {},\n\t): Promise<DaemonResponse> {\n\t\tconst hello = await this.waitForHello();\n\t\tconst missing = getDaemonCommandCompatibilities(command).find(\n\t\t\t(requirement) => !meetsDaemonCommandCompatibility(hello, requirement),\n\t\t);\n\t\tif (missing) throw new DaemonCapabilityUnavailableError(command.type, missing.capability);\n\t\treturn this.requestWire(command, timeoutMs);\n\t}\n\n\tasync requestWorker(command: DaemonWorkerCommandBody, timeoutMs = 30_000): Promise<DaemonResponse> {\n\t\tawait this.requireNativeOwner();\n\t\tif (command.type === \"worker_deliver_result\") {\n\t\t\tconst requirement = DAEMON_COMMAND_COMPATIBILITY.send_result;\n\t\t\tif (!meetsDaemonCommandCompatibility(await this.waitForHello(), requirement)) {\n\t\t\t\tthrow new DaemonCapabilityUnavailableError(command.type, requirement.capability);\n\t\t\t}\n\t\t}\n\t\treturn this.requestWire(command, timeoutMs);\n\t}\n\n\tprivate async requireNativeOwner(): Promise<void> {\n\t\tconst hello = await this.waitForHello();\n\t\tif (!NATIVE_WORK_COMPATIBILITIES.every((requirement) => meetsDaemonCommandCompatibility(hello, requirement))) {\n\t\t\tthrow new DaemonWorkerCompatibilityError(hello);\n\t\t}\n\t}\n\n\tasync authenticateWorker(\n\t\ttoken: string,\n\t\towner: DaemonWorkerAuthentication,\n\t\ttimeoutMs = 3000,\n\t): Promise<Extract<DaemonResponse, { success: true }>> {\n\t\tconst response = await this.requestWorker({ type: \"worker_auth\", token, ...owner }, timeoutMs);\n\t\tif (!response.success) {\n\t\t\tthrow new DaemonWorkerAuthenticationError(response.error);\n\t\t}\n\t\treturn response;\n\t}\n\n\tasync authenticatePeer(ticket: DaemonPeerTransportTicket, timeoutMs = 3000): Promise<void> {\n\t\tawait this.requireNativeOwner();\n\t\tconst response = await this.requestWire(\n\t\t\t{\n\t\t\t\ttype: \"peer_auth\",\n\t\t\t\tgrantId: ticket.grantId,\n\t\t\t\ttoken: ticket.token,\n\t\t\t\tworkerInstanceId: ticket.workerInstanceId,\n\t\t\t\tpurpose: ticket.purpose,\n\t\t\t},\n\t\t\ttimeoutMs,\n\t\t);\n\t\tif (!response.success) {\n\t\t\tthrow new Error(response.error);\n\t\t}\n\t\tthis.directPeer = true;\n\t}\n\n\tclose(): void {\n\t\tthis.rejectAll(new Error(\"Daemon worker client closed\"));\n\t\tthis.channel?.close();\n\t\tthis.channel = undefined;\n\t\tthis.socket?.destroy();\n\t\tthis.socket = undefined;\n\t\tthis.directPeer = false;\n\t\tthis.directClosingReason = undefined;\n\t}\n\n\tprivate async requestWire(command: DaemonWorkerWireCommandBody, timeoutMs: number): Promise<DaemonResponse> {\n\t\tif (!this.channel || !this.socket || this.socket.destroyed) {\n\t\t\tthrow new Error(\"Daemon worker client is not connected\");\n\t\t}\n\t\tconst id = `worker_${++this.requestId}`;\n\t\tconst fullCommand = { ...command, id } as DaemonWorkerWireCommand;\n\t\tconst response = new Promise<DaemonResponse>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.pending.delete(id);\n\t\t\t\treject(\n\t\t\t\t\tnew DaemonWorkerProbeTimeoutError(`Timed out waiting for daemon worker response to ${command.type}`),\n\t\t\t\t);\n\t\t\t}, timeoutMs);\n\t\t\tthis.pending.set(id, { resolve, reject, timeout });\n\t\t});\n\t\t// A blocked socket write must not postpone the response timeout or connection-close rejection.\n\t\tvoid this.channel\n\t\t\t.send(\n\t\t\t\t{ kind: \"command\", requestId: id, commandType: command.type },\n\t\t\t\tBuffer.from(serializeJsonLine(fullCommand)),\n\t\t\t)\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst pending = this.pending.get(id);\n\t\t\t\tif (pending) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(id);\n\t\t\t\t\tpending.reject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t});\n\t\treturn response;\n\t}\n\n\tprivate handleFrame(frame: PrivateFrame<DaemonWorkerFrameHeader>): void {\n\t\tif (frame.header.kind !== \"outbound\") {\n\t\t\treturn;\n\t\t}\n\t\tif (frame.header.outboundType === \"response\" && frame.header.requestId) {\n\t\t\tconst pending = this.pending.get(frame.header.requestId);\n\t\t\tif (pending) {\n\t\t\t\tlet response: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tresponse = JSON.parse(frame.payload.toString(\"utf8\"));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(frame.header.requestId);\n\t\t\t\t\tpending.reject(new Error(`Invalid daemon worker response: ${String(error)}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (isDaemonResponse(response)) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(frame.header.requestId);\n\t\t\t\t\tpending.resolve(response);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (frame.header.outboundType === \"daemon_hello\") {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(frame.payload.toString(\"utf8\")) as DaemonOutbound;\n\t\t\t\tif (parsed.type === \"daemon_hello\") {\n\t\t\t\t\tif (\n\t\t\t\t\t\tparsed.protocol.name !== DAEMON_PROTOCOL_NAME ||\n\t\t\t\t\t\t(parsed.protocol.version !== DAEMON_PROTOCOL_VERSION &&\n\t\t\t\t\t\t\t!DAEMON_LEGACY_INSPECTION_PROTOCOL_VERSIONS.includes(parsed.protocol.version))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.compatibilityError = new DaemonWorkerCompatibilityError(parsed);\n\t\t\t\t\t\tthis.rejectAll(this.compatibilityError);\n\t\t\t\t\t\tthis.close();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.helloMessage = parsed;\n\t\t\t\t\tfor (const waiter of [...this.helloWaiters]) {\n\t\t\t\t\t\tclearTimeout(waiter.timeout);\n\t\t\t\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\t\t\t\twaiter.resolve(parsed);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Invalid hello payloads are rejected by the timeout.\n\t\t\t}\n\t\t}\n\t\tfor (const listener of this.frameListeners) {\n\t\t\tlistener(frame);\n\t\t}\n\t\tif (this.directPeer && frame.header.outboundType !== \"daemon_hello\" && frame.header.outboundType !== \"response\") {\n\t\t\tthis.emitDirectOutbound(frame);\n\t\t}\n\t}\n\n\t/** A malformed outbound frame closes the direct link (the routed client falls back) instead of throwing into consumers. */\n\tprivate emitDirectOutbound(frame: PrivateFrame<DaemonWorkerFrameHeader>): void {\n\t\tif (frame.header.kind !== \"outbound\") return;\n\t\tlet message: DaemonOutbound;\n\t\ttry {\n\t\t\tif (frame.header.payloadEncoding !== undefined && frame.header.payloadEncoding !== \"jsonl\") {\n\t\t\t\tthrow new Error(`Direct worker sent an unsupported payload encoding: ${frame.header.payloadEncoding}`);\n\t\t\t}\n\t\t\tconst parsed = JSON.parse(frame.payload.toString(\"utf8\")) as unknown;\n\t\t\tif (!parsed || typeof parsed !== \"object\" || typeof (parsed as { type?: unknown }).type !== \"string\") {\n\t\t\t\tthrow new Error(\"Direct worker sent an invalid outbound payload\");\n\t\t\t}\n\t\t\tmessage = parsed as DaemonOutbound;\n\t\t} catch (error) {\n\t\t\tconst socket = this.socket;\n\t\t\tconst directError = this.directCloseError(error instanceof Error ? error : new Error(String(error)));\n\t\t\tif (socket) {\n\t\t\t\tthis.notifyClosed(socket, directError);\n\t\t\t\tsocket.destroy(directError);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"daemon_closing\") {\n\t\t\tthis.directClosingReason = message.reason;\n\t\t}\n\t\tfor (const listener of [...this.messageListeners]) {\n\t\t\tlistener(message);\n\t\t}\n\t}\n\n\tprivate directCloseError(cause: Error): Error {\n\t\treturn this.directPeer\n\t\t\t? new DaemonSocketClosedError(this.socketPath, this.directClosingReason, cause.message)\n\t\t\t: cause;\n\t}\n\n\tprivate rejectAll(error: Error): void {\n\t\tfor (const [id, pending] of this.pending) {\n\t\t\tclearTimeout(pending.timeout);\n\t\t\tpending.reject(error);\n\t\t\tthis.pending.delete(id);\n\t\t}\n\t\tfor (const waiter of [...this.helloWaiters]) {\n\t\t\tclearTimeout(waiter.timeout);\n\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\twaiter.reject(error);\n\t\t}\n\t}\n\n\tprivate notifyClosed(socket: Socket, error: Error): void {\n\t\tif (this.socket !== socket) {\n\t\t\treturn;\n\t\t}\n\t\tthis.socket = undefined;\n\t\tthis.channel = undefined;\n\t\tthis.directPeer = false;\n\t\tthis.directClosingReason = undefined;\n\t\tthis.rejectAll(error);\n\t\tfor (const listener of [...this.closeListeners]) {\n\t\t\tlistener(error);\n\t\t}\n\t}\n}\n\nfunction isDaemonResponse(value: unknown): value is DaemonResponse {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst candidate = value as { type?: unknown; command?: unknown; success?: unknown };\n\treturn (\n\t\tcandidate.type === \"response\" && typeof candidate.command === \"string\" && typeof candidate.success === \"boolean\"\n\t);\n}\n"]}
1
+ {"version":3,"file":"daemon-worker-client.d.ts","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { createConnection, type Socket } from \"node:net\";\nimport { serializeJsonLine } from \"../rpc/jsonl.js\";\nimport { type PrivateFrame, PrivateFramedChannel } from \"../session-worker/private-framing.js\";\nimport {\n\tDaemonCapabilityUnavailableError,\n\ttype DaemonClientMessageListener,\n\ttype DaemonClientRequestOptions,\n\tDaemonSocketClosedError,\n} from \"./daemon-client.js\";\nimport {\n\tDAEMON_COMMAND_COMPATIBILITY,\n\tDAEMON_LEGACY_INSPECTION_PROTOCOL_VERSIONS,\n\tDAEMON_PROTOCOL_NAME,\n\tDAEMON_PROTOCOL_VERSION,\n\ttype DaemonClosingReason,\n\ttype DaemonCommand,\n\ttype DaemonOutbound,\n\ttype DaemonPeerTransportTicket,\n\ttype DaemonResponse,\n\ttype DaemonServerCapability,\n\tgetDaemonCommandCompatibilities,\n\tmeetsDaemonCommandCompatibility,\n\tNATIVE_WORK_COMPATIBILITIES,\n} from \"./daemon-protocol.js\";\nimport {\n\ttype DaemonPeerCommand,\n\ttype DaemonPeerCommandBody,\n\ttype DaemonWorkerCommand,\n\ttype DaemonWorkerCommandBody,\n\ttype DaemonWorkerFrameHeader,\n\tisDaemonWorkerFrameHeader,\n} from \"./daemon-worker-protocol.js\";\n\ntype DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;\ntype DaemonCommandBody = DistributiveOmit<DaemonCommand, \"id\">;\ntype DaemonWorkerWireCommandBody = DaemonCommandBody | DaemonWorkerCommandBody | DaemonPeerCommandBody;\ntype DaemonWorkerWireCommand = DaemonCommand | DaemonWorkerCommand | DaemonPeerCommand;\ntype DaemonWorkerAuthentication = Omit<Extract<DaemonWorkerCommand, { type: \"worker_auth\" }>, \"id\" | \"type\" | \"token\">;\n\nexport type DaemonWorkerFrameListener = (frame: PrivateFrame<DaemonWorkerFrameHeader>) => void;\nexport type DaemonWorkerCloseListener = (error: Error) => void;\ntype DaemonHello = Extract<DaemonOutbound, { type: \"daemon_hello\" }>;\n\nexport class DaemonWorkerAuthenticationError extends Error {}\n\n/** A live incompatible owner is not a dead worker or a retryable probe timeout. */\nexport class DaemonWorkerCompatibilityError extends Error {\n\tconstructor(hello: DaemonHello) {\n\t\tsuper(\n\t\t\t`Daemon worker ${hello.protocol.name} protocol ${hello.protocol.version} cannot provide canonical session ownership, native inference ownership, and bounded invocation output. Keep its live owner intact; update or stop it with its own runtime before recovery.`,\n\t\t);\n\t\tthis.name = \"DaemonWorkerCompatibilityError\";\n\t}\n}\n\n/** A probe (hello/response/connect) timed out; recovery treats the worker as live-but-slow, never dead. */\nexport class DaemonWorkerProbeTimeoutError extends Error {}\n\nexport class DaemonWorkerClient {\n\tprivate socket?: Socket;\n\tprivate channel?: PrivateFramedChannel<DaemonWorkerFrameHeader>;\n\tprivate readonly frameListeners = new Set<DaemonWorkerFrameListener>();\n\tprivate readonly messageListeners = new Set<DaemonClientMessageListener>();\n\tprivate readonly closeListeners = new Set<DaemonWorkerCloseListener>();\n\tprivate readonly pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\tresolve: (response: DaemonResponse) => void;\n\t\t\treject: (error: Error) => void;\n\t\t\ttimeout: ReturnType<typeof setTimeout>;\n\t\t}\n\t>();\n\tprivate requestId = 0;\n\tprivate helloMessage?: DaemonHello;\n\tprivate compatibilityError?: DaemonWorkerCompatibilityError;\n\tprivate directPeer = false;\n\tprivate directClosingReason?: DaemonClosingReason;\n\tprivate readonly helloWaiters = new Set<{\n\t\tresolve: (hello: DaemonHello) => void;\n\t\treject: (error: Error) => void;\n\t\ttimeout: ReturnType<typeof setTimeout>;\n\t}>();\n\n\tconstructor(private readonly socketPath: string) {}\n\n\tget hello(): DaemonHello | undefined {\n\t\treturn this.helloMessage;\n\t}\n\n\tget isConnected(): boolean {\n\t\treturn this.socket !== undefined && !this.socket.destroyed;\n\t}\n\n\tsupportsServerCapability(capability: DaemonServerCapability): boolean {\n\t\treturn this.helloMessage?.serverCapabilities?.includes(capability) === true;\n\t}\n\n\tasync connect(timeoutMs = 3000): Promise<void> {\n\t\tif (this.socket) {\n\t\t\tthrow new Error(\"Daemon worker client is already connected\");\n\t\t}\n\t\tconst socket = createConnection(this.socketPath);\n\t\tthis.socket = socket;\n\t\tthis.channel = new PrivateFramedChannel(socket, isDaemonWorkerFrameHeader);\n\t\tthis.channel.onFrame((frame) => this.handleFrame(frame));\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tcleanup();\n\t\t\t\tthis.clearSocketReference(socket);\n\t\t\t\tsocket.destroy();\n\t\t\t\treject(new Error(`Timed out connecting to daemon worker socket: ${this.socketPath}`));\n\t\t\t}, timeoutMs);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tsocket.off(\"connect\", onConnect);\n\t\t\t\tsocket.off(\"error\", onError);\n\t\t\t};\n\t\t\tconst onConnect = () => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tconst onError = (error: Error) => {\n\t\t\t\tcleanup();\n\t\t\t\tthis.clearSocketReference(socket);\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tsocket.once(\"connect\", onConnect);\n\t\t\tsocket.once(\"error\", onError);\n\t\t});\n\n\t\tsocket.on(\"error\", (error) => this.notifyClosed(socket, this.directCloseError(error)));\n\t\tsocket.on(\"close\", () =>\n\t\t\tthis.notifyClosed(socket, this.directCloseError(new Error(\"Daemon worker socket closed\"))),\n\t\t);\n\t}\n\n\twaitForHello(timeoutMs = 3000): Promise<DaemonHello> {\n\t\tif (this.compatibilityError) return Promise.reject(this.compatibilityError);\n\t\tif (this.helloMessage) {\n\t\t\treturn Promise.resolve(this.helloMessage);\n\t\t}\n\t\tif (!this.socket || this.socket.destroyed) {\n\t\t\treturn Promise.reject(new Error(\"Daemon worker client is not connected\"));\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst waiter = {\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t\ttimeout: setTimeout(() => {\n\t\t\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\t\t\treject(new DaemonWorkerProbeTimeoutError(\"Timed out waiting for daemon worker hello\"));\n\t\t\t\t}, timeoutMs),\n\t\t\t};\n\t\t\tthis.helloWaiters.add(waiter);\n\t\t});\n\t}\n\n\tonFrame(listener: DaemonWorkerFrameListener): () => void {\n\t\tthis.frameListeners.add(listener);\n\t\treturn () => this.frameListeners.delete(listener);\n\t}\n\n\tonMessage(listener: DaemonClientMessageListener): () => void {\n\t\tthis.messageListeners.add(listener);\n\t\treturn () => this.messageListeners.delete(listener);\n\t}\n\n\tonClose(listener: DaemonWorkerCloseListener): () => void {\n\t\tthis.closeListeners.add(listener);\n\t\treturn () => this.closeListeners.delete(listener);\n\t}\n\n\tasync request(\n\t\tcommand: DaemonCommandBody,\n\t\ttimeoutMs = 30_000,\n\t\t// Progress/recovery options are supervisor-transport features; a direct request fails fast instead of replaying (no double execution).\n\t\t_options: DaemonClientRequestOptions = {},\n\t): Promise<DaemonResponse> {\n\t\tconst hello = await this.waitForHello();\n\t\tconst missing = getDaemonCommandCompatibilities(command).find(\n\t\t\t(requirement) => !meetsDaemonCommandCompatibility(hello, requirement),\n\t\t);\n\t\tif (missing) throw new DaemonCapabilityUnavailableError(command.type, missing.capability);\n\t\treturn this.requestWire(command, timeoutMs);\n\t}\n\n\tasync requestWorker(command: DaemonWorkerCommandBody, timeoutMs = 30_000): Promise<DaemonResponse> {\n\t\tawait this.requireNativeOwner();\n\t\tif (command.type === \"worker_deliver_result\") {\n\t\t\tconst requirement = DAEMON_COMMAND_COMPATIBILITY.send_result;\n\t\t\tif (!meetsDaemonCommandCompatibility(await this.waitForHello(), requirement)) {\n\t\t\t\tthrow new DaemonCapabilityUnavailableError(command.type, requirement.capability);\n\t\t\t}\n\t\t}\n\t\treturn this.requestWire(command, timeoutMs);\n\t}\n\n\tprivate async requireNativeOwner(): Promise<void> {\n\t\tconst hello = await this.waitForHello();\n\t\tif (!NATIVE_WORK_COMPATIBILITIES.every((requirement) => meetsDaemonCommandCompatibility(hello, requirement))) {\n\t\t\tthrow new DaemonWorkerCompatibilityError(hello);\n\t\t}\n\t}\n\n\tasync authenticateWorker(\n\t\ttoken: string,\n\t\towner: DaemonWorkerAuthentication,\n\t\ttimeoutMs = 3000,\n\t): Promise<Extract<DaemonResponse, { success: true }>> {\n\t\tconst response = await this.requestWorker({ type: \"worker_auth\", token, ...owner }, timeoutMs);\n\t\tif (!response.success) {\n\t\t\tthrow new DaemonWorkerAuthenticationError(response.error);\n\t\t}\n\t\treturn response;\n\t}\n\n\tasync authenticatePeer(ticket: DaemonPeerTransportTicket, timeoutMs = 3000): Promise<void> {\n\t\tawait this.requireNativeOwner();\n\t\tconst response = await this.requestWire(\n\t\t\t{\n\t\t\t\ttype: \"peer_auth\",\n\t\t\t\tgrantId: ticket.grantId,\n\t\t\t\ttoken: ticket.token,\n\t\t\t\tworkerInstanceId: ticket.workerInstanceId,\n\t\t\t\tpurpose: ticket.purpose,\n\t\t\t},\n\t\t\ttimeoutMs,\n\t\t);\n\t\tif (!response.success) {\n\t\t\tthrow new Error(response.error);\n\t\t}\n\t\tthis.directPeer = true;\n\t}\n\n\tclose(): void {\n\t\tthis.rejectAll(new Error(\"Daemon worker client closed\"));\n\t\tthis.channel?.close();\n\t\tthis.channel = undefined;\n\t\tthis.socket?.destroy();\n\t\tthis.socket = undefined;\n\t\tthis.directPeer = false;\n\t\tthis.directClosingReason = undefined;\n\t}\n\n\tprivate async requestWire(command: DaemonWorkerWireCommandBody, timeoutMs: number): Promise<DaemonResponse> {\n\t\tif (!this.channel || !this.socket || this.socket.destroyed) {\n\t\t\tthrow new Error(\"Daemon worker client is not connected\");\n\t\t}\n\t\tconst id = `worker_${++this.requestId}`;\n\t\tconst fullCommand = { ...command, id } as DaemonWorkerWireCommand;\n\t\tconst response = new Promise<DaemonResponse>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.pending.delete(id);\n\t\t\t\treject(\n\t\t\t\t\tnew DaemonWorkerProbeTimeoutError(`Timed out waiting for daemon worker response to ${command.type}`),\n\t\t\t\t);\n\t\t\t}, timeoutMs);\n\t\t\tthis.pending.set(id, { resolve, reject, timeout });\n\t\t});\n\t\t// A blocked socket write must not postpone the response timeout or connection-close rejection.\n\t\tvoid this.channel\n\t\t\t.send(\n\t\t\t\t{ kind: \"command\", requestId: id, commandType: command.type },\n\t\t\t\tBuffer.from(serializeJsonLine(fullCommand)),\n\t\t\t)\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst pending = this.pending.get(id);\n\t\t\t\tif (pending) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(id);\n\t\t\t\t\tpending.reject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t});\n\t\treturn response;\n\t}\n\n\tprivate handleFrame(frame: PrivateFrame<DaemonWorkerFrameHeader>): void {\n\t\tif (frame.header.kind !== \"outbound\") {\n\t\t\treturn;\n\t\t}\n\t\tif (frame.header.outboundType === \"response\" && frame.header.requestId) {\n\t\t\tconst pending = this.pending.get(frame.header.requestId);\n\t\t\tif (pending) {\n\t\t\t\tlet response: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tresponse = JSON.parse(frame.payload.toString(\"utf8\"));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(frame.header.requestId);\n\t\t\t\t\tpending.reject(new Error(`Invalid daemon worker response: ${String(error)}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (isDaemonResponse(response)) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(frame.header.requestId);\n\t\t\t\t\tpending.resolve(response);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (frame.header.outboundType === \"daemon_hello\") {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(frame.payload.toString(\"utf8\")) as DaemonOutbound;\n\t\t\t\tif (parsed.type === \"daemon_hello\") {\n\t\t\t\t\tif (\n\t\t\t\t\t\tparsed.protocol.name !== DAEMON_PROTOCOL_NAME ||\n\t\t\t\t\t\t(parsed.protocol.version !== DAEMON_PROTOCOL_VERSION &&\n\t\t\t\t\t\t\t!DAEMON_LEGACY_INSPECTION_PROTOCOL_VERSIONS.includes(parsed.protocol.version))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.compatibilityError = new DaemonWorkerCompatibilityError(parsed);\n\t\t\t\t\t\tthis.rejectAll(this.compatibilityError);\n\t\t\t\t\t\tthis.close();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.helloMessage = parsed;\n\t\t\t\t\tfor (const waiter of [...this.helloWaiters]) {\n\t\t\t\t\t\tclearTimeout(waiter.timeout);\n\t\t\t\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\t\t\t\twaiter.resolve(parsed);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Invalid hello payloads are rejected by the timeout.\n\t\t\t}\n\t\t}\n\t\tfor (const listener of this.frameListeners) {\n\t\t\tlistener(frame);\n\t\t}\n\t\tif (this.directPeer && frame.header.outboundType !== \"daemon_hello\" && frame.header.outboundType !== \"response\") {\n\t\t\tthis.emitDirectOutbound(frame);\n\t\t}\n\t}\n\n\t/** A malformed outbound frame closes the direct link (the routed client falls back) instead of throwing into consumers. */\n\tprivate emitDirectOutbound(frame: PrivateFrame<DaemonWorkerFrameHeader>): void {\n\t\tif (frame.header.kind !== \"outbound\") return;\n\t\tlet message: DaemonOutbound;\n\t\ttry {\n\t\t\tif (frame.header.payloadEncoding !== undefined && frame.header.payloadEncoding !== \"jsonl\") {\n\t\t\t\tthrow new Error(`Direct worker sent an unsupported payload encoding: ${frame.header.payloadEncoding}`);\n\t\t\t}\n\t\t\tconst parsed = JSON.parse(frame.payload.toString(\"utf8\")) as unknown;\n\t\t\tif (!parsed || typeof parsed !== \"object\" || typeof (parsed as { type?: unknown }).type !== \"string\") {\n\t\t\t\tthrow new Error(\"Direct worker sent an invalid outbound payload\");\n\t\t\t}\n\t\t\tmessage = parsed as DaemonOutbound;\n\t\t} catch (error) {\n\t\t\tconst socket = this.socket;\n\t\t\tconst directError = this.directCloseError(error instanceof Error ? error : new Error(String(error)));\n\t\t\tif (socket) {\n\t\t\t\tthis.notifyClosed(socket, directError);\n\t\t\t\tsocket.destroy(directError);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"daemon_closing\") {\n\t\t\tthis.directClosingReason = message.reason;\n\t\t}\n\t\tfor (const listener of [...this.messageListeners]) {\n\t\t\tlistener(message);\n\t\t}\n\t}\n\n\tprivate directCloseError(cause: Error): Error {\n\t\treturn this.directPeer\n\t\t\t? new DaemonSocketClosedError(this.socketPath, this.directClosingReason, cause.message)\n\t\t\t: cause;\n\t}\n\n\tprivate rejectAll(error: Error): void {\n\t\tfor (const [id, pending] of this.pending) {\n\t\t\tclearTimeout(pending.timeout);\n\t\t\tpending.reject(error);\n\t\t\tthis.pending.delete(id);\n\t\t}\n\t\tfor (const waiter of [...this.helloWaiters]) {\n\t\t\tclearTimeout(waiter.timeout);\n\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\twaiter.reject(error);\n\t\t}\n\t}\n\n\tprivate clearSocketReference(socket: Socket): void {\n\t\tif (this.socket !== socket) return;\n\t\tthis.socket = undefined;\n\t\tthis.channel = undefined;\n\t}\n\n\tprivate notifyClosed(socket: Socket, error: Error): void {\n\t\tif (this.socket !== socket) {\n\t\t\treturn;\n\t\t}\n\t\tthis.socket = undefined;\n\t\tthis.channel = undefined;\n\t\tthis.directPeer = false;\n\t\tthis.directClosingReason = undefined;\n\t\tthis.rejectAll(error);\n\t\tfor (const listener of [...this.closeListeners]) {\n\t\t\tlistener(error);\n\t\t}\n\t}\n}\n\nfunction isDaemonResponse(value: unknown): value is DaemonResponse {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst candidate = value as { type?: unknown; command?: unknown; success?: unknown };\n\treturn (\n\t\tcandidate.type === \"response\" && typeof candidate.command === \"string\" && typeof candidate.success === \"boolean\"\n\t);\n}\n"]}
@@ -53,6 +53,7 @@ export class DaemonWorkerClient {
53
53
  await new Promise((resolve, reject) => {
54
54
  const timeout = setTimeout(() => {
55
55
  cleanup();
56
+ this.clearSocketReference(socket);
56
57
  socket.destroy();
57
58
  reject(new Error(`Timed out connecting to daemon worker socket: ${this.socketPath}`));
58
59
  }, timeoutMs);
@@ -67,6 +68,7 @@ export class DaemonWorkerClient {
67
68
  };
68
69
  const onError = (error) => {
69
70
  cleanup();
71
+ this.clearSocketReference(socket);
70
72
  reject(error);
71
73
  };
72
74
  socket.once("connect", onConnect);
@@ -293,6 +295,12 @@ export class DaemonWorkerClient {
293
295
  waiter.reject(error);
294
296
  }
295
297
  }
298
+ clearSocketReference(socket) {
299
+ if (this.socket !== socket)
300
+ return;
301
+ this.socket = undefined;
302
+ this.channel = undefined;
303
+ }
296
304
  notifyClosed(socket, error) {
297
305
  if (this.socket !== socket) {
298
306
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-worker-client.js","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { createConnection, type Socket } from \"node:net\";\nimport { serializeJsonLine } from \"../rpc/jsonl.js\";\nimport { type PrivateFrame, PrivateFramedChannel } from \"../session-worker/private-framing.js\";\nimport {\n\tDaemonCapabilityUnavailableError,\n\ttype DaemonClientMessageListener,\n\ttype DaemonClientRequestOptions,\n\tDaemonSocketClosedError,\n} from \"./daemon-client.js\";\nimport {\n\tDAEMON_COMMAND_COMPATIBILITY,\n\tDAEMON_LEGACY_INSPECTION_PROTOCOL_VERSIONS,\n\tDAEMON_PROTOCOL_NAME,\n\tDAEMON_PROTOCOL_VERSION,\n\ttype DaemonClosingReason,\n\ttype DaemonCommand,\n\ttype DaemonOutbound,\n\ttype DaemonPeerTransportTicket,\n\ttype DaemonResponse,\n\ttype DaemonServerCapability,\n\tgetDaemonCommandCompatibilities,\n\tmeetsDaemonCommandCompatibility,\n\tNATIVE_WORK_COMPATIBILITIES,\n} from \"./daemon-protocol.js\";\nimport {\n\ttype DaemonPeerCommand,\n\ttype DaemonPeerCommandBody,\n\ttype DaemonWorkerCommand,\n\ttype DaemonWorkerCommandBody,\n\ttype DaemonWorkerFrameHeader,\n\tisDaemonWorkerFrameHeader,\n} from \"./daemon-worker-protocol.js\";\n\ntype DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;\ntype DaemonCommandBody = DistributiveOmit<DaemonCommand, \"id\">;\ntype DaemonWorkerWireCommandBody = DaemonCommandBody | DaemonWorkerCommandBody | DaemonPeerCommandBody;\ntype DaemonWorkerWireCommand = DaemonCommand | DaemonWorkerCommand | DaemonPeerCommand;\ntype DaemonWorkerAuthentication = Omit<Extract<DaemonWorkerCommand, { type: \"worker_auth\" }>, \"id\" | \"type\" | \"token\">;\n\nexport type DaemonWorkerFrameListener = (frame: PrivateFrame<DaemonWorkerFrameHeader>) => void;\nexport type DaemonWorkerCloseListener = (error: Error) => void;\ntype DaemonHello = Extract<DaemonOutbound, { type: \"daemon_hello\" }>;\n\nexport class DaemonWorkerAuthenticationError extends Error {}\n\n/** A live incompatible owner is not a dead worker or a retryable probe timeout. */\nexport class DaemonWorkerCompatibilityError extends Error {\n\tconstructor(hello: DaemonHello) {\n\t\tsuper(\n\t\t\t`Daemon worker ${hello.protocol.name} protocol ${hello.protocol.version} cannot provide canonical session ownership, native inference ownership, and bounded invocation output. Keep its live owner intact; update or stop it with its own runtime before recovery.`,\n\t\t);\n\t\tthis.name = \"DaemonWorkerCompatibilityError\";\n\t}\n}\n\n/** A probe (hello/response/connect) timed out; recovery treats the worker as live-but-slow, never dead. */\nexport class DaemonWorkerProbeTimeoutError extends Error {}\n\nexport class DaemonWorkerClient {\n\tprivate socket?: Socket;\n\tprivate channel?: PrivateFramedChannel<DaemonWorkerFrameHeader>;\n\tprivate readonly frameListeners = new Set<DaemonWorkerFrameListener>();\n\tprivate readonly messageListeners = new Set<DaemonClientMessageListener>();\n\tprivate readonly closeListeners = new Set<DaemonWorkerCloseListener>();\n\tprivate readonly pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\tresolve: (response: DaemonResponse) => void;\n\t\t\treject: (error: Error) => void;\n\t\t\ttimeout: ReturnType<typeof setTimeout>;\n\t\t}\n\t>();\n\tprivate requestId = 0;\n\tprivate helloMessage?: DaemonHello;\n\tprivate compatibilityError?: DaemonWorkerCompatibilityError;\n\tprivate directPeer = false;\n\tprivate directClosingReason?: DaemonClosingReason;\n\tprivate readonly helloWaiters = new Set<{\n\t\tresolve: (hello: DaemonHello) => void;\n\t\treject: (error: Error) => void;\n\t\ttimeout: ReturnType<typeof setTimeout>;\n\t}>();\n\n\tconstructor(private readonly socketPath: string) {}\n\n\tget hello(): DaemonHello | undefined {\n\t\treturn this.helloMessage;\n\t}\n\n\tget isConnected(): boolean {\n\t\treturn this.socket !== undefined && !this.socket.destroyed;\n\t}\n\n\tsupportsServerCapability(capability: DaemonServerCapability): boolean {\n\t\treturn this.helloMessage?.serverCapabilities?.includes(capability) === true;\n\t}\n\n\tasync connect(timeoutMs = 3000): Promise<void> {\n\t\tif (this.socket) {\n\t\t\tthrow new Error(\"Daemon worker client is already connected\");\n\t\t}\n\t\tconst socket = createConnection(this.socketPath);\n\t\tthis.socket = socket;\n\t\tthis.channel = new PrivateFramedChannel(socket, isDaemonWorkerFrameHeader);\n\t\tthis.channel.onFrame((frame) => this.handleFrame(frame));\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tcleanup();\n\t\t\t\tsocket.destroy();\n\t\t\t\treject(new Error(`Timed out connecting to daemon worker socket: ${this.socketPath}`));\n\t\t\t}, timeoutMs);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tsocket.off(\"connect\", onConnect);\n\t\t\t\tsocket.off(\"error\", onError);\n\t\t\t};\n\t\t\tconst onConnect = () => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tconst onError = (error: Error) => {\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tsocket.once(\"connect\", onConnect);\n\t\t\tsocket.once(\"error\", onError);\n\t\t});\n\n\t\tsocket.on(\"error\", (error) => this.notifyClosed(socket, this.directCloseError(error)));\n\t\tsocket.on(\"close\", () =>\n\t\t\tthis.notifyClosed(socket, this.directCloseError(new Error(\"Daemon worker socket closed\"))),\n\t\t);\n\t}\n\n\twaitForHello(timeoutMs = 3000): Promise<DaemonHello> {\n\t\tif (this.compatibilityError) return Promise.reject(this.compatibilityError);\n\t\tif (this.helloMessage) {\n\t\t\treturn Promise.resolve(this.helloMessage);\n\t\t}\n\t\tif (!this.socket || this.socket.destroyed) {\n\t\t\treturn Promise.reject(new Error(\"Daemon worker client is not connected\"));\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst waiter = {\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t\ttimeout: setTimeout(() => {\n\t\t\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\t\t\treject(new DaemonWorkerProbeTimeoutError(\"Timed out waiting for daemon worker hello\"));\n\t\t\t\t}, timeoutMs),\n\t\t\t};\n\t\t\tthis.helloWaiters.add(waiter);\n\t\t});\n\t}\n\n\tonFrame(listener: DaemonWorkerFrameListener): () => void {\n\t\tthis.frameListeners.add(listener);\n\t\treturn () => this.frameListeners.delete(listener);\n\t}\n\n\tonMessage(listener: DaemonClientMessageListener): () => void {\n\t\tthis.messageListeners.add(listener);\n\t\treturn () => this.messageListeners.delete(listener);\n\t}\n\n\tonClose(listener: DaemonWorkerCloseListener): () => void {\n\t\tthis.closeListeners.add(listener);\n\t\treturn () => this.closeListeners.delete(listener);\n\t}\n\n\tasync request(\n\t\tcommand: DaemonCommandBody,\n\t\ttimeoutMs = 30_000,\n\t\t// Progress/recovery options are supervisor-transport features; a direct request fails fast instead of replaying (no double execution).\n\t\t_options: DaemonClientRequestOptions = {},\n\t): Promise<DaemonResponse> {\n\t\tconst hello = await this.waitForHello();\n\t\tconst missing = getDaemonCommandCompatibilities(command).find(\n\t\t\t(requirement) => !meetsDaemonCommandCompatibility(hello, requirement),\n\t\t);\n\t\tif (missing) throw new DaemonCapabilityUnavailableError(command.type, missing.capability);\n\t\treturn this.requestWire(command, timeoutMs);\n\t}\n\n\tasync requestWorker(command: DaemonWorkerCommandBody, timeoutMs = 30_000): Promise<DaemonResponse> {\n\t\tawait this.requireNativeOwner();\n\t\tif (command.type === \"worker_deliver_result\") {\n\t\t\tconst requirement = DAEMON_COMMAND_COMPATIBILITY.send_result;\n\t\t\tif (!meetsDaemonCommandCompatibility(await this.waitForHello(), requirement)) {\n\t\t\t\tthrow new DaemonCapabilityUnavailableError(command.type, requirement.capability);\n\t\t\t}\n\t\t}\n\t\treturn this.requestWire(command, timeoutMs);\n\t}\n\n\tprivate async requireNativeOwner(): Promise<void> {\n\t\tconst hello = await this.waitForHello();\n\t\tif (!NATIVE_WORK_COMPATIBILITIES.every((requirement) => meetsDaemonCommandCompatibility(hello, requirement))) {\n\t\t\tthrow new DaemonWorkerCompatibilityError(hello);\n\t\t}\n\t}\n\n\tasync authenticateWorker(\n\t\ttoken: string,\n\t\towner: DaemonWorkerAuthentication,\n\t\ttimeoutMs = 3000,\n\t): Promise<Extract<DaemonResponse, { success: true }>> {\n\t\tconst response = await this.requestWorker({ type: \"worker_auth\", token, ...owner }, timeoutMs);\n\t\tif (!response.success) {\n\t\t\tthrow new DaemonWorkerAuthenticationError(response.error);\n\t\t}\n\t\treturn response;\n\t}\n\n\tasync authenticatePeer(ticket: DaemonPeerTransportTicket, timeoutMs = 3000): Promise<void> {\n\t\tawait this.requireNativeOwner();\n\t\tconst response = await this.requestWire(\n\t\t\t{\n\t\t\t\ttype: \"peer_auth\",\n\t\t\t\tgrantId: ticket.grantId,\n\t\t\t\ttoken: ticket.token,\n\t\t\t\tworkerInstanceId: ticket.workerInstanceId,\n\t\t\t\tpurpose: ticket.purpose,\n\t\t\t},\n\t\t\ttimeoutMs,\n\t\t);\n\t\tif (!response.success) {\n\t\t\tthrow new Error(response.error);\n\t\t}\n\t\tthis.directPeer = true;\n\t}\n\n\tclose(): void {\n\t\tthis.rejectAll(new Error(\"Daemon worker client closed\"));\n\t\tthis.channel?.close();\n\t\tthis.channel = undefined;\n\t\tthis.socket?.destroy();\n\t\tthis.socket = undefined;\n\t\tthis.directPeer = false;\n\t\tthis.directClosingReason = undefined;\n\t}\n\n\tprivate async requestWire(command: DaemonWorkerWireCommandBody, timeoutMs: number): Promise<DaemonResponse> {\n\t\tif (!this.channel || !this.socket || this.socket.destroyed) {\n\t\t\tthrow new Error(\"Daemon worker client is not connected\");\n\t\t}\n\t\tconst id = `worker_${++this.requestId}`;\n\t\tconst fullCommand = { ...command, id } as DaemonWorkerWireCommand;\n\t\tconst response = new Promise<DaemonResponse>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.pending.delete(id);\n\t\t\t\treject(\n\t\t\t\t\tnew DaemonWorkerProbeTimeoutError(`Timed out waiting for daemon worker response to ${command.type}`),\n\t\t\t\t);\n\t\t\t}, timeoutMs);\n\t\t\tthis.pending.set(id, { resolve, reject, timeout });\n\t\t});\n\t\t// A blocked socket write must not postpone the response timeout or connection-close rejection.\n\t\tvoid this.channel\n\t\t\t.send(\n\t\t\t\t{ kind: \"command\", requestId: id, commandType: command.type },\n\t\t\t\tBuffer.from(serializeJsonLine(fullCommand)),\n\t\t\t)\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst pending = this.pending.get(id);\n\t\t\t\tif (pending) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(id);\n\t\t\t\t\tpending.reject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t});\n\t\treturn response;\n\t}\n\n\tprivate handleFrame(frame: PrivateFrame<DaemonWorkerFrameHeader>): void {\n\t\tif (frame.header.kind !== \"outbound\") {\n\t\t\treturn;\n\t\t}\n\t\tif (frame.header.outboundType === \"response\" && frame.header.requestId) {\n\t\t\tconst pending = this.pending.get(frame.header.requestId);\n\t\t\tif (pending) {\n\t\t\t\tlet response: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tresponse = JSON.parse(frame.payload.toString(\"utf8\"));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(frame.header.requestId);\n\t\t\t\t\tpending.reject(new Error(`Invalid daemon worker response: ${String(error)}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (isDaemonResponse(response)) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(frame.header.requestId);\n\t\t\t\t\tpending.resolve(response);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (frame.header.outboundType === \"daemon_hello\") {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(frame.payload.toString(\"utf8\")) as DaemonOutbound;\n\t\t\t\tif (parsed.type === \"daemon_hello\") {\n\t\t\t\t\tif (\n\t\t\t\t\t\tparsed.protocol.name !== DAEMON_PROTOCOL_NAME ||\n\t\t\t\t\t\t(parsed.protocol.version !== DAEMON_PROTOCOL_VERSION &&\n\t\t\t\t\t\t\t!DAEMON_LEGACY_INSPECTION_PROTOCOL_VERSIONS.includes(parsed.protocol.version))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.compatibilityError = new DaemonWorkerCompatibilityError(parsed);\n\t\t\t\t\t\tthis.rejectAll(this.compatibilityError);\n\t\t\t\t\t\tthis.close();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.helloMessage = parsed;\n\t\t\t\t\tfor (const waiter of [...this.helloWaiters]) {\n\t\t\t\t\t\tclearTimeout(waiter.timeout);\n\t\t\t\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\t\t\t\twaiter.resolve(parsed);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Invalid hello payloads are rejected by the timeout.\n\t\t\t}\n\t\t}\n\t\tfor (const listener of this.frameListeners) {\n\t\t\tlistener(frame);\n\t\t}\n\t\tif (this.directPeer && frame.header.outboundType !== \"daemon_hello\" && frame.header.outboundType !== \"response\") {\n\t\t\tthis.emitDirectOutbound(frame);\n\t\t}\n\t}\n\n\t/** A malformed outbound frame closes the direct link (the routed client falls back) instead of throwing into consumers. */\n\tprivate emitDirectOutbound(frame: PrivateFrame<DaemonWorkerFrameHeader>): void {\n\t\tif (frame.header.kind !== \"outbound\") return;\n\t\tlet message: DaemonOutbound;\n\t\ttry {\n\t\t\tif (frame.header.payloadEncoding !== undefined && frame.header.payloadEncoding !== \"jsonl\") {\n\t\t\t\tthrow new Error(`Direct worker sent an unsupported payload encoding: ${frame.header.payloadEncoding}`);\n\t\t\t}\n\t\t\tconst parsed = JSON.parse(frame.payload.toString(\"utf8\")) as unknown;\n\t\t\tif (!parsed || typeof parsed !== \"object\" || typeof (parsed as { type?: unknown }).type !== \"string\") {\n\t\t\t\tthrow new Error(\"Direct worker sent an invalid outbound payload\");\n\t\t\t}\n\t\t\tmessage = parsed as DaemonOutbound;\n\t\t} catch (error) {\n\t\t\tconst socket = this.socket;\n\t\t\tconst directError = this.directCloseError(error instanceof Error ? error : new Error(String(error)));\n\t\t\tif (socket) {\n\t\t\t\tthis.notifyClosed(socket, directError);\n\t\t\t\tsocket.destroy(directError);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"daemon_closing\") {\n\t\t\tthis.directClosingReason = message.reason;\n\t\t}\n\t\tfor (const listener of [...this.messageListeners]) {\n\t\t\tlistener(message);\n\t\t}\n\t}\n\n\tprivate directCloseError(cause: Error): Error {\n\t\treturn this.directPeer\n\t\t\t? new DaemonSocketClosedError(this.socketPath, this.directClosingReason, cause.message)\n\t\t\t: cause;\n\t}\n\n\tprivate rejectAll(error: Error): void {\n\t\tfor (const [id, pending] of this.pending) {\n\t\t\tclearTimeout(pending.timeout);\n\t\t\tpending.reject(error);\n\t\t\tthis.pending.delete(id);\n\t\t}\n\t\tfor (const waiter of [...this.helloWaiters]) {\n\t\t\tclearTimeout(waiter.timeout);\n\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\twaiter.reject(error);\n\t\t}\n\t}\n\n\tprivate notifyClosed(socket: Socket, error: Error): void {\n\t\tif (this.socket !== socket) {\n\t\t\treturn;\n\t\t}\n\t\tthis.socket = undefined;\n\t\tthis.channel = undefined;\n\t\tthis.directPeer = false;\n\t\tthis.directClosingReason = undefined;\n\t\tthis.rejectAll(error);\n\t\tfor (const listener of [...this.closeListeners]) {\n\t\t\tlistener(error);\n\t\t}\n\t}\n}\n\nfunction isDaemonResponse(value: unknown): value is DaemonResponse {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst candidate = value as { type?: unknown; command?: unknown; success?: unknown };\n\treturn (\n\t\tcandidate.type === \"response\" && typeof candidate.command === \"string\" && typeof candidate.success === \"boolean\"\n\t);\n}\n"]}
1
+ {"version":3,"file":"daemon-worker-client.js","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { createConnection, type Socket } from \"node:net\";\nimport { serializeJsonLine } from \"../rpc/jsonl.js\";\nimport { type PrivateFrame, PrivateFramedChannel } from \"../session-worker/private-framing.js\";\nimport {\n\tDaemonCapabilityUnavailableError,\n\ttype DaemonClientMessageListener,\n\ttype DaemonClientRequestOptions,\n\tDaemonSocketClosedError,\n} from \"./daemon-client.js\";\nimport {\n\tDAEMON_COMMAND_COMPATIBILITY,\n\tDAEMON_LEGACY_INSPECTION_PROTOCOL_VERSIONS,\n\tDAEMON_PROTOCOL_NAME,\n\tDAEMON_PROTOCOL_VERSION,\n\ttype DaemonClosingReason,\n\ttype DaemonCommand,\n\ttype DaemonOutbound,\n\ttype DaemonPeerTransportTicket,\n\ttype DaemonResponse,\n\ttype DaemonServerCapability,\n\tgetDaemonCommandCompatibilities,\n\tmeetsDaemonCommandCompatibility,\n\tNATIVE_WORK_COMPATIBILITIES,\n} from \"./daemon-protocol.js\";\nimport {\n\ttype DaemonPeerCommand,\n\ttype DaemonPeerCommandBody,\n\ttype DaemonWorkerCommand,\n\ttype DaemonWorkerCommandBody,\n\ttype DaemonWorkerFrameHeader,\n\tisDaemonWorkerFrameHeader,\n} from \"./daemon-worker-protocol.js\";\n\ntype DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;\ntype DaemonCommandBody = DistributiveOmit<DaemonCommand, \"id\">;\ntype DaemonWorkerWireCommandBody = DaemonCommandBody | DaemonWorkerCommandBody | DaemonPeerCommandBody;\ntype DaemonWorkerWireCommand = DaemonCommand | DaemonWorkerCommand | DaemonPeerCommand;\ntype DaemonWorkerAuthentication = Omit<Extract<DaemonWorkerCommand, { type: \"worker_auth\" }>, \"id\" | \"type\" | \"token\">;\n\nexport type DaemonWorkerFrameListener = (frame: PrivateFrame<DaemonWorkerFrameHeader>) => void;\nexport type DaemonWorkerCloseListener = (error: Error) => void;\ntype DaemonHello = Extract<DaemonOutbound, { type: \"daemon_hello\" }>;\n\nexport class DaemonWorkerAuthenticationError extends Error {}\n\n/** A live incompatible owner is not a dead worker or a retryable probe timeout. */\nexport class DaemonWorkerCompatibilityError extends Error {\n\tconstructor(hello: DaemonHello) {\n\t\tsuper(\n\t\t\t`Daemon worker ${hello.protocol.name} protocol ${hello.protocol.version} cannot provide canonical session ownership, native inference ownership, and bounded invocation output. Keep its live owner intact; update or stop it with its own runtime before recovery.`,\n\t\t);\n\t\tthis.name = \"DaemonWorkerCompatibilityError\";\n\t}\n}\n\n/** A probe (hello/response/connect) timed out; recovery treats the worker as live-but-slow, never dead. */\nexport class DaemonWorkerProbeTimeoutError extends Error {}\n\nexport class DaemonWorkerClient {\n\tprivate socket?: Socket;\n\tprivate channel?: PrivateFramedChannel<DaemonWorkerFrameHeader>;\n\tprivate readonly frameListeners = new Set<DaemonWorkerFrameListener>();\n\tprivate readonly messageListeners = new Set<DaemonClientMessageListener>();\n\tprivate readonly closeListeners = new Set<DaemonWorkerCloseListener>();\n\tprivate readonly pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\tresolve: (response: DaemonResponse) => void;\n\t\t\treject: (error: Error) => void;\n\t\t\ttimeout: ReturnType<typeof setTimeout>;\n\t\t}\n\t>();\n\tprivate requestId = 0;\n\tprivate helloMessage?: DaemonHello;\n\tprivate compatibilityError?: DaemonWorkerCompatibilityError;\n\tprivate directPeer = false;\n\tprivate directClosingReason?: DaemonClosingReason;\n\tprivate readonly helloWaiters = new Set<{\n\t\tresolve: (hello: DaemonHello) => void;\n\t\treject: (error: Error) => void;\n\t\ttimeout: ReturnType<typeof setTimeout>;\n\t}>();\n\n\tconstructor(private readonly socketPath: string) {}\n\n\tget hello(): DaemonHello | undefined {\n\t\treturn this.helloMessage;\n\t}\n\n\tget isConnected(): boolean {\n\t\treturn this.socket !== undefined && !this.socket.destroyed;\n\t}\n\n\tsupportsServerCapability(capability: DaemonServerCapability): boolean {\n\t\treturn this.helloMessage?.serverCapabilities?.includes(capability) === true;\n\t}\n\n\tasync connect(timeoutMs = 3000): Promise<void> {\n\t\tif (this.socket) {\n\t\t\tthrow new Error(\"Daemon worker client is already connected\");\n\t\t}\n\t\tconst socket = createConnection(this.socketPath);\n\t\tthis.socket = socket;\n\t\tthis.channel = new PrivateFramedChannel(socket, isDaemonWorkerFrameHeader);\n\t\tthis.channel.onFrame((frame) => this.handleFrame(frame));\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tcleanup();\n\t\t\t\tthis.clearSocketReference(socket);\n\t\t\t\tsocket.destroy();\n\t\t\t\treject(new Error(`Timed out connecting to daemon worker socket: ${this.socketPath}`));\n\t\t\t}, timeoutMs);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tsocket.off(\"connect\", onConnect);\n\t\t\t\tsocket.off(\"error\", onError);\n\t\t\t};\n\t\t\tconst onConnect = () => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tconst onError = (error: Error) => {\n\t\t\t\tcleanup();\n\t\t\t\tthis.clearSocketReference(socket);\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tsocket.once(\"connect\", onConnect);\n\t\t\tsocket.once(\"error\", onError);\n\t\t});\n\n\t\tsocket.on(\"error\", (error) => this.notifyClosed(socket, this.directCloseError(error)));\n\t\tsocket.on(\"close\", () =>\n\t\t\tthis.notifyClosed(socket, this.directCloseError(new Error(\"Daemon worker socket closed\"))),\n\t\t);\n\t}\n\n\twaitForHello(timeoutMs = 3000): Promise<DaemonHello> {\n\t\tif (this.compatibilityError) return Promise.reject(this.compatibilityError);\n\t\tif (this.helloMessage) {\n\t\t\treturn Promise.resolve(this.helloMessage);\n\t\t}\n\t\tif (!this.socket || this.socket.destroyed) {\n\t\t\treturn Promise.reject(new Error(\"Daemon worker client is not connected\"));\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst waiter = {\n\t\t\t\tresolve,\n\t\t\t\treject,\n\t\t\t\ttimeout: setTimeout(() => {\n\t\t\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\t\t\treject(new DaemonWorkerProbeTimeoutError(\"Timed out waiting for daemon worker hello\"));\n\t\t\t\t}, timeoutMs),\n\t\t\t};\n\t\t\tthis.helloWaiters.add(waiter);\n\t\t});\n\t}\n\n\tonFrame(listener: DaemonWorkerFrameListener): () => void {\n\t\tthis.frameListeners.add(listener);\n\t\treturn () => this.frameListeners.delete(listener);\n\t}\n\n\tonMessage(listener: DaemonClientMessageListener): () => void {\n\t\tthis.messageListeners.add(listener);\n\t\treturn () => this.messageListeners.delete(listener);\n\t}\n\n\tonClose(listener: DaemonWorkerCloseListener): () => void {\n\t\tthis.closeListeners.add(listener);\n\t\treturn () => this.closeListeners.delete(listener);\n\t}\n\n\tasync request(\n\t\tcommand: DaemonCommandBody,\n\t\ttimeoutMs = 30_000,\n\t\t// Progress/recovery options are supervisor-transport features; a direct request fails fast instead of replaying (no double execution).\n\t\t_options: DaemonClientRequestOptions = {},\n\t): Promise<DaemonResponse> {\n\t\tconst hello = await this.waitForHello();\n\t\tconst missing = getDaemonCommandCompatibilities(command).find(\n\t\t\t(requirement) => !meetsDaemonCommandCompatibility(hello, requirement),\n\t\t);\n\t\tif (missing) throw new DaemonCapabilityUnavailableError(command.type, missing.capability);\n\t\treturn this.requestWire(command, timeoutMs);\n\t}\n\n\tasync requestWorker(command: DaemonWorkerCommandBody, timeoutMs = 30_000): Promise<DaemonResponse> {\n\t\tawait this.requireNativeOwner();\n\t\tif (command.type === \"worker_deliver_result\") {\n\t\t\tconst requirement = DAEMON_COMMAND_COMPATIBILITY.send_result;\n\t\t\tif (!meetsDaemonCommandCompatibility(await this.waitForHello(), requirement)) {\n\t\t\t\tthrow new DaemonCapabilityUnavailableError(command.type, requirement.capability);\n\t\t\t}\n\t\t}\n\t\treturn this.requestWire(command, timeoutMs);\n\t}\n\n\tprivate async requireNativeOwner(): Promise<void> {\n\t\tconst hello = await this.waitForHello();\n\t\tif (!NATIVE_WORK_COMPATIBILITIES.every((requirement) => meetsDaemonCommandCompatibility(hello, requirement))) {\n\t\t\tthrow new DaemonWorkerCompatibilityError(hello);\n\t\t}\n\t}\n\n\tasync authenticateWorker(\n\t\ttoken: string,\n\t\towner: DaemonWorkerAuthentication,\n\t\ttimeoutMs = 3000,\n\t): Promise<Extract<DaemonResponse, { success: true }>> {\n\t\tconst response = await this.requestWorker({ type: \"worker_auth\", token, ...owner }, timeoutMs);\n\t\tif (!response.success) {\n\t\t\tthrow new DaemonWorkerAuthenticationError(response.error);\n\t\t}\n\t\treturn response;\n\t}\n\n\tasync authenticatePeer(ticket: DaemonPeerTransportTicket, timeoutMs = 3000): Promise<void> {\n\t\tawait this.requireNativeOwner();\n\t\tconst response = await this.requestWire(\n\t\t\t{\n\t\t\t\ttype: \"peer_auth\",\n\t\t\t\tgrantId: ticket.grantId,\n\t\t\t\ttoken: ticket.token,\n\t\t\t\tworkerInstanceId: ticket.workerInstanceId,\n\t\t\t\tpurpose: ticket.purpose,\n\t\t\t},\n\t\t\ttimeoutMs,\n\t\t);\n\t\tif (!response.success) {\n\t\t\tthrow new Error(response.error);\n\t\t}\n\t\tthis.directPeer = true;\n\t}\n\n\tclose(): void {\n\t\tthis.rejectAll(new Error(\"Daemon worker client closed\"));\n\t\tthis.channel?.close();\n\t\tthis.channel = undefined;\n\t\tthis.socket?.destroy();\n\t\tthis.socket = undefined;\n\t\tthis.directPeer = false;\n\t\tthis.directClosingReason = undefined;\n\t}\n\n\tprivate async requestWire(command: DaemonWorkerWireCommandBody, timeoutMs: number): Promise<DaemonResponse> {\n\t\tif (!this.channel || !this.socket || this.socket.destroyed) {\n\t\t\tthrow new Error(\"Daemon worker client is not connected\");\n\t\t}\n\t\tconst id = `worker_${++this.requestId}`;\n\t\tconst fullCommand = { ...command, id } as DaemonWorkerWireCommand;\n\t\tconst response = new Promise<DaemonResponse>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.pending.delete(id);\n\t\t\t\treject(\n\t\t\t\t\tnew DaemonWorkerProbeTimeoutError(`Timed out waiting for daemon worker response to ${command.type}`),\n\t\t\t\t);\n\t\t\t}, timeoutMs);\n\t\t\tthis.pending.set(id, { resolve, reject, timeout });\n\t\t});\n\t\t// A blocked socket write must not postpone the response timeout or connection-close rejection.\n\t\tvoid this.channel\n\t\t\t.send(\n\t\t\t\t{ kind: \"command\", requestId: id, commandType: command.type },\n\t\t\t\tBuffer.from(serializeJsonLine(fullCommand)),\n\t\t\t)\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst pending = this.pending.get(id);\n\t\t\t\tif (pending) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(id);\n\t\t\t\t\tpending.reject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t});\n\t\treturn response;\n\t}\n\n\tprivate handleFrame(frame: PrivateFrame<DaemonWorkerFrameHeader>): void {\n\t\tif (frame.header.kind !== \"outbound\") {\n\t\t\treturn;\n\t\t}\n\t\tif (frame.header.outboundType === \"response\" && frame.header.requestId) {\n\t\t\tconst pending = this.pending.get(frame.header.requestId);\n\t\t\tif (pending) {\n\t\t\t\tlet response: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tresponse = JSON.parse(frame.payload.toString(\"utf8\"));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(frame.header.requestId);\n\t\t\t\t\tpending.reject(new Error(`Invalid daemon worker response: ${String(error)}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (isDaemonResponse(response)) {\n\t\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\t\tthis.pending.delete(frame.header.requestId);\n\t\t\t\t\tpending.resolve(response);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (frame.header.outboundType === \"daemon_hello\") {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(frame.payload.toString(\"utf8\")) as DaemonOutbound;\n\t\t\t\tif (parsed.type === \"daemon_hello\") {\n\t\t\t\t\tif (\n\t\t\t\t\t\tparsed.protocol.name !== DAEMON_PROTOCOL_NAME ||\n\t\t\t\t\t\t(parsed.protocol.version !== DAEMON_PROTOCOL_VERSION &&\n\t\t\t\t\t\t\t!DAEMON_LEGACY_INSPECTION_PROTOCOL_VERSIONS.includes(parsed.protocol.version))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.compatibilityError = new DaemonWorkerCompatibilityError(parsed);\n\t\t\t\t\t\tthis.rejectAll(this.compatibilityError);\n\t\t\t\t\t\tthis.close();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.helloMessage = parsed;\n\t\t\t\t\tfor (const waiter of [...this.helloWaiters]) {\n\t\t\t\t\t\tclearTimeout(waiter.timeout);\n\t\t\t\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\t\t\t\twaiter.resolve(parsed);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Invalid hello payloads are rejected by the timeout.\n\t\t\t}\n\t\t}\n\t\tfor (const listener of this.frameListeners) {\n\t\t\tlistener(frame);\n\t\t}\n\t\tif (this.directPeer && frame.header.outboundType !== \"daemon_hello\" && frame.header.outboundType !== \"response\") {\n\t\t\tthis.emitDirectOutbound(frame);\n\t\t}\n\t}\n\n\t/** A malformed outbound frame closes the direct link (the routed client falls back) instead of throwing into consumers. */\n\tprivate emitDirectOutbound(frame: PrivateFrame<DaemonWorkerFrameHeader>): void {\n\t\tif (frame.header.kind !== \"outbound\") return;\n\t\tlet message: DaemonOutbound;\n\t\ttry {\n\t\t\tif (frame.header.payloadEncoding !== undefined && frame.header.payloadEncoding !== \"jsonl\") {\n\t\t\t\tthrow new Error(`Direct worker sent an unsupported payload encoding: ${frame.header.payloadEncoding}`);\n\t\t\t}\n\t\t\tconst parsed = JSON.parse(frame.payload.toString(\"utf8\")) as unknown;\n\t\t\tif (!parsed || typeof parsed !== \"object\" || typeof (parsed as { type?: unknown }).type !== \"string\") {\n\t\t\t\tthrow new Error(\"Direct worker sent an invalid outbound payload\");\n\t\t\t}\n\t\t\tmessage = parsed as DaemonOutbound;\n\t\t} catch (error) {\n\t\t\tconst socket = this.socket;\n\t\t\tconst directError = this.directCloseError(error instanceof Error ? error : new Error(String(error)));\n\t\t\tif (socket) {\n\t\t\t\tthis.notifyClosed(socket, directError);\n\t\t\t\tsocket.destroy(directError);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"daemon_closing\") {\n\t\t\tthis.directClosingReason = message.reason;\n\t\t}\n\t\tfor (const listener of [...this.messageListeners]) {\n\t\t\tlistener(message);\n\t\t}\n\t}\n\n\tprivate directCloseError(cause: Error): Error {\n\t\treturn this.directPeer\n\t\t\t? new DaemonSocketClosedError(this.socketPath, this.directClosingReason, cause.message)\n\t\t\t: cause;\n\t}\n\n\tprivate rejectAll(error: Error): void {\n\t\tfor (const [id, pending] of this.pending) {\n\t\t\tclearTimeout(pending.timeout);\n\t\t\tpending.reject(error);\n\t\t\tthis.pending.delete(id);\n\t\t}\n\t\tfor (const waiter of [...this.helloWaiters]) {\n\t\t\tclearTimeout(waiter.timeout);\n\t\t\tthis.helloWaiters.delete(waiter);\n\t\t\twaiter.reject(error);\n\t\t}\n\t}\n\n\tprivate clearSocketReference(socket: Socket): void {\n\t\tif (this.socket !== socket) return;\n\t\tthis.socket = undefined;\n\t\tthis.channel = undefined;\n\t}\n\n\tprivate notifyClosed(socket: Socket, error: Error): void {\n\t\tif (this.socket !== socket) {\n\t\t\treturn;\n\t\t}\n\t\tthis.socket = undefined;\n\t\tthis.channel = undefined;\n\t\tthis.directPeer = false;\n\t\tthis.directClosingReason = undefined;\n\t\tthis.rejectAll(error);\n\t\tfor (const listener of [...this.closeListeners]) {\n\t\t\tlistener(error);\n\t\t}\n\t}\n}\n\nfunction isDaemonResponse(value: unknown): value is DaemonResponse {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst candidate = value as { type?: unknown; command?: unknown; success?: unknown };\n\treturn (\n\t\tcandidate.type === \"response\" && typeof candidate.command === \"string\" && typeof candidate.success === \"boolean\"\n\t);\n}\n"]}
@@ -9,6 +9,7 @@ export declare const DAEMON_WORKER_INSTANCE_ID_ENV = "BASE_CONTEXT_INTERNAL_DAEM
9
9
  export declare const DAEMON_WORKER_ACTIVE_SESSION_ID_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_WORKER_ACTIVE_SESSION_ID";
10
10
  export declare const DAEMON_WORKER_SUPERVISOR_SOCKET_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_SOCKET";
11
11
  export declare const DAEMON_WORKER_RECOVERY_JOURNAL_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RECOVERY_JOURNAL";
12
+ export declare const DAEMON_WORKER_RLM_LEDGER_SESSION_DIR_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RLM_LEDGER_SESSION_DIR";
12
13
  export declare const DAEMON_WORKER_STARTUP_GATE_FD_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_WORKER_STARTUP_GATE_FD";
13
14
  export declare const DAEMON_WORKER_STARTUP_GATE_COMMIT = "start\n";
14
15
  export type DaemonWorkerLifecycle = "starting" | "ready" | "recovering" | "stopping" | "failed";
@@ -179,6 +180,8 @@ export interface DaemonWorkerDescriptor {
179
180
  rootSessionId?: string;
180
181
  sessionFile?: string;
181
182
  sessionDir?: string;
183
+ /** Supervisor-assigned journal scope, independent of transcript storage. */
184
+ rlmLedgerSessionDir?: string;
182
185
  createdAt: string;
183
186
  updatedAt: string;
184
187
  lifecycle: DaemonWorkerLifecycle;
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-worker-protocol.d.ts","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-worker-protocol.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,+BAA+B,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAC/G,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAE9E,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAErG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAElG,eAAO,MAAM,sBAAsB,wCAAwC,CAAC;AAC5E,eAAO,MAAM,uBAAuB,8CAA8C,CAAC;AACnF,eAAO,MAAM,6BAA6B,oDAAoD,CAAC;AAC/F,eAAO,MAAM,mCAAmC,0DAA0D,CAAC;AAC3G,eAAO,MAAM,mCAAmC,mDAAmD,CAAC;AACpG,eAAO,MAAM,kCAAkC,yDAAyD,CAAC;AACzG,eAAO,MAAM,iCAAiC,wDAAwD,CAAC;AACvG,eAAO,MAAM,iCAAiC,YAAY,CAAC;AAC3D,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,CAAC;AAGhG,MAAM,MAAM,0BAA0B,GACnC;IACA,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,IAAI,CAAC;CACf,GACD;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAEhC,uFAAuF;AACvF,eAAO,MAAM,+BAA+B,iBAAiB,CAAC;AAE9D,2FAA2F;AAC3F,eAAO,MAAM,uCAAuC,mBAAmB,CAAC;AAExE,uHAAuH;AACvH,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAEnD,MAAM,MAAM,uBAAuB,GAChC;IACA,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACnB,GACD;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAC1E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IAC9C,eAAe,CAAC,EAAE,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;CACtD,CAAC;AAEL,MAAM,WAAW,uBAAuB;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,0BAA0B,GACnC,CAAC,uBAAuB,GAAG;IAAE,EAAE,EAAE,QAAQ,CAAA;CAAE,CAAC,GAC5C,CAAC,uBAAuB,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/D,CAAC,uBAAuB,GAAG;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,GACzF;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5C,MAAM,WAAW,4BAA6B,SAAQ,uBAAuB;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACzC,YAAY,EAAE,4BAA4B,EAAE,CAAC;CAC7C;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,yBAAyB,CAoB9F;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAE7E,MAAM,WAAW,0BAA0B;IAC1C,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,mBAAmB,GAAG,0BAA0B,CAMnG;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAED,qFAAqF;AACrF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;AAElE,MAAM,MAAM,mBAAmB,GAC5B;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,oBAAoB,EAAE,MAAM,CAAC;CAC5B,GACD;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,kBAAkB,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACjD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC7B,GACD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gCAAgC,CAAC;IAAC,KAAK,EAAE,qBAAqB,CAAA;CAAE,GACrF;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,6BAA6B,CAAA;CAAE,GACpD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,yBAAyB,CAAA;CAAE,GAChD;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,gCAAgC,CAAC;IACvC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACb,GACD;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,wBAAwB,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,yBAAyB,CAAC;IAClC,YAAY,CAAC,EAAE,+BAA+B,CAAC;CAC9C,GACD;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,uBAAuB,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,yBAAyB,CAAC;IAClC,YAAY,CAAC,EAAE,+BAA+B,CAAC;CAC9C,GACD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,uBAAuB,CAAA;CAAE,GAC9C;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,GAC7C;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAEjD,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,SAAS,MAAM,QAAQ,GAC7E,QAAQ,SAAS;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,GACpB,KAAK,GACN,KAAK,CAAC;AAET,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,qBAAqB,CAAC;IACjC,aAAa,EAAE,0BAA0B,CAAC;IAC1C,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kGAAkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,sBAAsB,GAAG,sBAAsB,CAuCxG;AAED,wBAAgB,qBAAqB,CAAC,WAAW,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAE3F;AAED,wBAAgB,8BAA8B,CAAC,WAAW,GAAE,MAAM,CAAC,UAAwB,GAAG,IAAI,CAmBjG;AAED,wBAAgB,sBAAsB,CAAC,WAAW,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,SAAS,CAEvG;AAED,wBAAgB,sCAAsC,CAAC,WAAW,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAM3G;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,uBAAuB,CAuB1F","sourcesContent":["import { closeSync, readFileSync } from \"node:fs\";\nimport type { AgentSessionMessageDeliveryMode, AgentSessionMessageSender } from \"../../core/agent-messages.js\";\nimport type { IdleEvictionMinutes } from \"../../core/session-action-store.js\";\n\nexport { SESSION_LEASE_OWNER_ID_ENV, SESSION_LEASES_ENABLED_ENV } from \"../../core/session-lease.js\";\n\nimport type { WorkerRosterEntry } from \"./agent-roster.js\";\nimport type { DaemonClientCapability, DaemonCommand, DaemonOutbound } from \"./daemon-protocol.js\";\n\nexport const DAEMON_WORKER_ROLE_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER\";\nexport const DAEMON_WORKER_TOKEN_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_TOKEN\";\nexport const DAEMON_WORKER_INSTANCE_ID_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_INSTANCE_ID\";\nexport const DAEMON_WORKER_ACTIVE_SESSION_ID_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_ACTIVE_SESSION_ID\";\nexport const DAEMON_WORKER_SUPERVISOR_SOCKET_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_SOCKET\";\nexport const DAEMON_WORKER_RECOVERY_JOURNAL_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RECOVERY_JOURNAL\";\nexport const DAEMON_WORKER_STARTUP_GATE_FD_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_STARTUP_GATE_FD\";\nexport const DAEMON_WORKER_STARTUP_GATE_COMMIT = \"start\\n\";\nexport type DaemonWorkerLifecycle = \"starting\" | \"ready\" | \"recovering\" | \"stopping\" | \"failed\";\n\n// Worker->supervisor roster frames live outside the client-facing DaemonOutbound schema.\nexport type DaemonWorkerRosterOutbound =\n\t| {\n\t\t\ttype: \"roster_delta\";\n\t\t\tentries: WorkerRosterEntry[];\n\t\t\tremovedAgentIds?: string[];\n\t\t\tsnapshot?: true;\n\t }\n\t| { type: \"roster_heartbeat\" };\n\n/** Advertised by new workers in the worker_auth response; absent on legacy workers. */\nexport const DAEMON_WORKER_ROSTER_CAPABILITY = \"agent_roster\";\n\n/** Advertised in the worker_auth response by workers that accept peer transport grants. */\nexport const DAEMON_WORKER_PEER_TRANSPORT_CAPABILITY = \"peer_transport\";\n\n/** Idle keepalive cadence for worker->supervisor roster frames; the supervisor staleness threshold derives from it. */\nexport const ROSTER_HEARTBEAT_INTERVAL_MS = 15_000;\n\nexport type DaemonWorkerFrameHeader =\n\t| {\n\t\t\tkind: \"command\";\n\t\t\trequestId: string;\n\t\t\tcommandType: string;\n\t }\n\t| {\n\t\t\tkind: \"outbound\";\n\t\t\trequestId?: string;\n\t\t\toutboundType: DaemonOutbound[\"type\"] | DaemonWorkerRosterOutbound[\"type\"];\n\t\t\tactiveSessionId?: string;\n\t\t\tsnapshotId?: string;\n\t\t\tsessionEventType?: string;\n\t\t\tpayloadEncoding?: \"jsonl\" | \"assistant-delta\";\n\t\t\tsnapshotPurpose?: \"attach\" | \"replacement\" | \"catchup\";\n\t };\n\nexport interface DaemonRlmCapacityOrigin {\n\tsessionFile?: string;\n\tsessionId: string;\n}\n\nexport type DaemonRlmCapacityOperation =\n\t| (DaemonRlmCapacityOrigin & { op: \"status\" })\n\t| (DaemonRlmCapacityOrigin & { op: \"set\"; maxSubagents: number })\n\t| (DaemonRlmCapacityOrigin & { op: \"reserve\"; reservationId: string; residentRoot?: true })\n\t| { op: \"release\"; reservationId: string };\n\nexport interface DaemonRlmCapacityReservation extends DaemonRlmCapacityOrigin {\n\treservationId: string;\n\tresidentRoot?: true;\n}\n\nexport interface DaemonRlmCapacitySnapshot {\n\treservations: DaemonRlmCapacityReservation[];\n}\n\nexport function isDaemonRlmCapacitySnapshot(value: unknown): value is DaemonRlmCapacitySnapshot {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"reservations\" in value &&\n\t\tArray.isArray(value.reservations) &&\n\t\tvalue.reservations.every(\n\t\t\t(entry: unknown) =>\n\t\t\t\ttypeof entry === \"object\" &&\n\t\t\t\tentry !== null &&\n\t\t\t\t\"reservationId\" in entry &&\n\t\t\t\ttypeof entry.reservationId === \"string\" &&\n\t\t\t\tentry.reservationId.length > 0 &&\n\t\t\t\t\"sessionId\" in entry &&\n\t\t\t\ttypeof entry.sessionId === \"string\" &&\n\t\t\t\tentry.sessionId.length > 0 &&\n\t\t\t\t(!(\"sessionFile\" in entry) || entry.sessionFile === undefined || typeof entry.sessionFile === \"string\") &&\n\t\t\t\t(!(\"residentRoot\" in entry) || entry.residentRoot === undefined || entry.residentRoot === true),\n\t\t)\n\t);\n}\n\nexport type DaemonCreateCommand = Extract<DaemonCommand, { type: \"create\" }>;\n\nexport interface DurableDaemonCreateCommand {\n\ttype: \"create\";\n\tsessionPath?: string;\n\tnoSession?: boolean;\n}\n\nexport function durableDaemonCreateCommand(command: DaemonCreateCommand): DurableDaemonCreateCommand {\n\treturn {\n\t\ttype: \"create\",\n\t\t...(command.sessionPath !== undefined ? { sessionPath: command.sessionPath } : {}),\n\t\t...(command.noSession !== undefined ? { noSession: command.noSession } : {}),\n\t};\n}\n\n/**\n * A single-use, worker-memory-only admission for one direct peer, scoped to one active-session\n * slot (stable across switch_session/new_session/fork) of one worker incarnation. The session pin\n * is a routing/accident guard, not a privilege boundary: ticket holders already hold supervisor\n * access, which can attach to, switch, or kill any session.\n */\nexport interface DaemonWorkerPeerGrant {\n\tgrantId: string;\n\ttoken: string;\n\texpiresAt: string;\n\tpurpose: \"session_client\";\n\tworkerInstanceId: string;\n\tactiveSessionId: string;\n\tissuerGeneration: string;\n}\n\n/** Commands a direct peer may send before it holds an authenticated session role. */\nexport type DaemonPeerCommand = {\n\tid?: string;\n\ttype: \"peer_auth\";\n\tgrantId: string;\n\ttoken: string;\n\tworkerInstanceId: string;\n\tpurpose: \"session_client\";\n};\n\nexport type DaemonPeerCommandBody = Omit<DaemonPeerCommand, \"id\">;\n\nexport type DaemonWorkerCommand =\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_auth\";\n\t\t\ttoken: string;\n\t\t\tworkerInstanceId?: string;\n\t\t\tsupervisorGeneration: string;\n\t\t\tsupervisorPid: number;\n\t\t\tsupervisorProcessStartId?: string;\n\t\t\tsupervisorSocketPath: string;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_subscribe\";\n\t\t\tactiveSessionId: string;\n\t\t\tcapabilities?: readonly DaemonClientCapability[];\n\t\t\tsupportsExtensionUi?: boolean;\n\t }\n\t| { id?: string; type: \"worker_unsubscribe\"; activeSessionId: string }\n\t| { id?: string; type: \"worker_register_peer_transport\"; grant: DaemonWorkerPeerGrant }\n\t| { id?: string; type: \"worker_archive_and_shutdown\" }\n\t| { id?: string; type: \"worker_get_rlm_capacity\" }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_passivate_idle_children\";\n\t\t\tidleEvictionMinutes: IdleEvictionMinutes;\n\t\t\tnow: number;\n\t\t\tlimit: number;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_deliver_message\";\n\t\t\ttargetActiveSessionId: string;\n\t\t\tmessage: string;\n\t\t\tsender: AgentSessionMessageSender;\n\t\t\tdeliveryMode?: AgentSessionMessageDeliveryMode;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_deliver_result\";\n\t\t\ttargetActiveSessionId: string;\n\t\t\tsummary: string;\n\t\t\tfindings: string;\n\t\t\tsender: AgentSessionMessageSender;\n\t\t\tdeliveryMode?: AgentSessionMessageDeliveryMode;\n\t }\n\t| { id?: string; type: \"worker_prepare_update\" }\n\t| { id?: string; type: \"worker_commit_update\" }\n\t| { id?: string; type: \"worker_cancel_update\" };\n\nexport type DaemonWorkerCommandBody = DaemonWorkerCommand extends infer TCommand\n\t? TCommand extends { id?: string }\n\t\t? Omit<TCommand, \"id\">\n\t\t: never\n\t: never;\n\nexport interface DaemonWorkerDescriptor {\n\tversion: 1 | 2;\n\tworkerId: string;\n\tpid: number;\n\tprocessStartId?: string;\n\tsocketPath: string;\n\trecoveryJournalPath: string;\n\torphanProcessJournalPath?: string;\n\tsupervisorSocketPath: string;\n\tauthenticationToken: string;\n\tworkerInstanceId?: string;\n\trootActiveSessionId: string;\n\t/** Stable protocol client that owns this worker. Omitted for resident sessions. */\n\townerClientId?: string;\n\trootSessionId?: string;\n\tsessionFile?: string;\n\tsessionDir?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tlifecycle: DaemonWorkerLifecycle;\n\tcreateCommand: DurableDaemonCreateCommand;\n\tconsecutiveFailures: number;\n\t/** Durable intent written before root termination so replacement supervisors never recover it. */\n\tstopRequestedAt?: string;\n\t/** Complete the root's archived lifecycle state after its process has stopped. */\n\tarchiveOnStop?: boolean;\n\tlastFailureAt?: string;\n\tlastError?: string;\n}\n\nexport function durableDaemonWorkerDescriptor(descriptor: DaemonWorkerDescriptor): DaemonWorkerDescriptor {\n\tconst versionOneCreateCommand = descriptor.createCommand as unknown as { config?: unknown };\n\tconst versionOneConfig =\n\t\tdescriptor.version === 1 &&\n\t\ttypeof versionOneCreateCommand.config === \"object\" &&\n\t\tversionOneCreateCommand.config !== null\n\t\t\t? (versionOneCreateCommand.config as Record<string, unknown>)\n\t\t\t: undefined;\n\tconst sessionDir =\n\t\tdescriptor.sessionDir ??\n\t\t(typeof versionOneConfig?.sessionDir === \"string\" ? versionOneConfig.sessionDir : undefined);\n\treturn {\n\t\tversion: 2,\n\t\tworkerId: descriptor.workerId,\n\t\tpid: descriptor.pid,\n\t\t...(descriptor.processStartId !== undefined ? { processStartId: descriptor.processStartId } : {}),\n\t\tsocketPath: descriptor.socketPath,\n\t\trecoveryJournalPath: descriptor.recoveryJournalPath,\n\t\t...(descriptor.orphanProcessJournalPath !== undefined\n\t\t\t? { orphanProcessJournalPath: descriptor.orphanProcessJournalPath }\n\t\t\t: {}),\n\t\tsupervisorSocketPath: descriptor.supervisorSocketPath,\n\t\tauthenticationToken: descriptor.authenticationToken,\n\t\t...(descriptor.workerInstanceId !== undefined ? { workerInstanceId: descriptor.workerInstanceId } : {}),\n\t\trootActiveSessionId: descriptor.rootActiveSessionId,\n\t\t...(descriptor.ownerClientId !== undefined ? { ownerClientId: descriptor.ownerClientId } : {}),\n\t\t...(descriptor.rootSessionId !== undefined ? { rootSessionId: descriptor.rootSessionId } : {}),\n\t\t...(descriptor.sessionFile !== undefined ? { sessionFile: descriptor.sessionFile } : {}),\n\t\t...(sessionDir !== undefined ? { sessionDir } : {}),\n\t\tcreatedAt: descriptor.createdAt,\n\t\tupdatedAt: descriptor.updatedAt,\n\t\tlifecycle: descriptor.lifecycle,\n\t\tcreateCommand: durableDaemonCreateCommand(descriptor.createCommand),\n\t\tconsecutiveFailures: descriptor.consecutiveFailures,\n\t\t...(descriptor.stopRequestedAt !== undefined ? { stopRequestedAt: descriptor.stopRequestedAt } : {}),\n\t\t...(descriptor.archiveOnStop !== undefined ? { archiveOnStop: descriptor.archiveOnStop } : {}),\n\t\t...(descriptor.lastFailureAt !== undefined ? { lastFailureAt: descriptor.lastFailureAt } : {}),\n\t\t...(descriptor.lifecycle === \"failed\" ? { lastError: \"Waiting for a client with fresh runtime context\" } : {}),\n\t};\n}\n\nexport function isDaemonWorkerProcess(environment: NodeJS.ProcessEnv = process.env): boolean {\n\treturn environment[DAEMON_WORKER_ROLE_ENV] === \"1\";\n}\n\nexport function waitForDaemonWorkerStartupGate(environment: NodeJS.ProcessEnv = process.env): void {\n\tconst rawFd = environment[DAEMON_WORKER_STARTUP_GATE_FD_ENV];\n\tif (rawFd === undefined) {\n\t\treturn;\n\t}\n\tdelete environment[DAEMON_WORKER_STARTUP_GATE_FD_ENV];\n\tconst fd = Number(rawFd);\n\tif (!Number.isInteger(fd) || fd < 3) {\n\t\tthrow new Error(\"Daemon session worker has an invalid startup gate\");\n\t}\n\tlet marker: string;\n\ttry {\n\t\tmarker = readFileSync(fd, \"utf8\");\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\tif (marker !== DAEMON_WORKER_STARTUP_GATE_COMMIT) {\n\t\tthrow new Error(\"Daemon session worker startup was cancelled\");\n\t}\n}\n\nexport function daemonWorkerInstanceId(environment: NodeJS.ProcessEnv = process.env): string | undefined {\n\treturn environment[DAEMON_WORKER_INSTANCE_ID_ENV] || undefined;\n}\n\nexport function requireDaemonWorkerAuthenticationToken(environment: NodeJS.ProcessEnv = process.env): string {\n\tconst token = environment[DAEMON_WORKER_TOKEN_ENV];\n\tif (!token) {\n\t\tthrow new Error(\"Daemon session worker is missing its authentication token\");\n\t}\n\treturn token;\n}\n\nexport function isDaemonWorkerFrameHeader(value: unknown): value is DaemonWorkerFrameHeader {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst candidate = value as Record<string, unknown>;\n\tif (candidate.kind === \"command\") {\n\t\treturn typeof candidate.requestId === \"string\" && typeof candidate.commandType === \"string\";\n\t}\n\treturn (\n\t\tcandidate.kind === \"outbound\" &&\n\t\ttypeof candidate.outboundType === \"string\" &&\n\t\t(candidate.requestId === undefined || typeof candidate.requestId === \"string\") &&\n\t\t(candidate.activeSessionId === undefined || typeof candidate.activeSessionId === \"string\") &&\n\t\t(candidate.snapshotId === undefined || typeof candidate.snapshotId === \"string\") &&\n\t\t(candidate.sessionEventType === undefined || typeof candidate.sessionEventType === \"string\") &&\n\t\t(candidate.snapshotPurpose === undefined ||\n\t\t\tcandidate.snapshotPurpose === \"attach\" ||\n\t\t\tcandidate.snapshotPurpose === \"replacement\" ||\n\t\t\tcandidate.snapshotPurpose === \"catchup\") &&\n\t\t(candidate.payloadEncoding === undefined ||\n\t\t\tcandidate.payloadEncoding === \"jsonl\" ||\n\t\t\tcandidate.payloadEncoding === \"assistant-delta\")\n\t);\n}\n"]}
1
+ {"version":3,"file":"daemon-worker-protocol.d.ts","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-worker-protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import { closeSync, readFileSync } from \"node:fs\";\nimport type { AgentSessionMessageDeliveryMode, AgentSessionMessageSender } from \"../../core/agent-messages.js\";\nimport type { IdleEvictionMinutes } from \"../../core/session-action-store.js\";\n\nexport { SESSION_LEASE_OWNER_ID_ENV, SESSION_LEASES_ENABLED_ENV } from \"../../core/session-lease.js\";\n\nimport type { WorkerRosterEntry } from \"./agent-roster.js\";\nimport type { DaemonClientCapability, DaemonCommand, DaemonOutbound } from \"./daemon-protocol.js\";\n\nexport const DAEMON_WORKER_ROLE_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER\";\nexport const DAEMON_WORKER_TOKEN_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_TOKEN\";\nexport const DAEMON_WORKER_INSTANCE_ID_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_INSTANCE_ID\";\nexport const DAEMON_WORKER_ACTIVE_SESSION_ID_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_ACTIVE_SESSION_ID\";\nexport const DAEMON_WORKER_SUPERVISOR_SOCKET_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_SOCKET\";\nexport const DAEMON_WORKER_RECOVERY_JOURNAL_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RECOVERY_JOURNAL\";\nexport const DAEMON_WORKER_RLM_LEDGER_SESSION_DIR_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RLM_LEDGER_SESSION_DIR\";\nexport const DAEMON_WORKER_STARTUP_GATE_FD_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_STARTUP_GATE_FD\";\nexport const DAEMON_WORKER_STARTUP_GATE_COMMIT = \"start\\n\";\nexport type DaemonWorkerLifecycle = \"starting\" | \"ready\" | \"recovering\" | \"stopping\" | \"failed\";\n\n// Worker->supervisor roster frames live outside the client-facing DaemonOutbound schema.\nexport type DaemonWorkerRosterOutbound =\n\t| {\n\t\t\ttype: \"roster_delta\";\n\t\t\tentries: WorkerRosterEntry[];\n\t\t\tremovedAgentIds?: string[];\n\t\t\tsnapshot?: true;\n\t }\n\t| { type: \"roster_heartbeat\" };\n\n/** Advertised by new workers in the worker_auth response; absent on legacy workers. */\nexport const DAEMON_WORKER_ROSTER_CAPABILITY = \"agent_roster\";\n\n/** Advertised in the worker_auth response by workers that accept peer transport grants. */\nexport const DAEMON_WORKER_PEER_TRANSPORT_CAPABILITY = \"peer_transport\";\n\n/** Idle keepalive cadence for worker->supervisor roster frames; the supervisor staleness threshold derives from it. */\nexport const ROSTER_HEARTBEAT_INTERVAL_MS = 15_000;\n\nexport type DaemonWorkerFrameHeader =\n\t| {\n\t\t\tkind: \"command\";\n\t\t\trequestId: string;\n\t\t\tcommandType: string;\n\t }\n\t| {\n\t\t\tkind: \"outbound\";\n\t\t\trequestId?: string;\n\t\t\toutboundType: DaemonOutbound[\"type\"] | DaemonWorkerRosterOutbound[\"type\"];\n\t\t\tactiveSessionId?: string;\n\t\t\tsnapshotId?: string;\n\t\t\tsessionEventType?: string;\n\t\t\tpayloadEncoding?: \"jsonl\" | \"assistant-delta\";\n\t\t\tsnapshotPurpose?: \"attach\" | \"replacement\" | \"catchup\";\n\t };\n\nexport interface DaemonRlmCapacityOrigin {\n\tsessionFile?: string;\n\tsessionId: string;\n}\n\nexport type DaemonRlmCapacityOperation =\n\t| (DaemonRlmCapacityOrigin & { op: \"status\" })\n\t| (DaemonRlmCapacityOrigin & { op: \"set\"; maxSubagents: number })\n\t| (DaemonRlmCapacityOrigin & { op: \"reserve\"; reservationId: string; residentRoot?: true })\n\t| { op: \"release\"; reservationId: string };\n\nexport interface DaemonRlmCapacityReservation extends DaemonRlmCapacityOrigin {\n\treservationId: string;\n\tresidentRoot?: true;\n}\n\nexport interface DaemonRlmCapacitySnapshot {\n\treservations: DaemonRlmCapacityReservation[];\n}\n\nexport function isDaemonRlmCapacitySnapshot(value: unknown): value is DaemonRlmCapacitySnapshot {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"reservations\" in value &&\n\t\tArray.isArray(value.reservations) &&\n\t\tvalue.reservations.every(\n\t\t\t(entry: unknown) =>\n\t\t\t\ttypeof entry === \"object\" &&\n\t\t\t\tentry !== null &&\n\t\t\t\t\"reservationId\" in entry &&\n\t\t\t\ttypeof entry.reservationId === \"string\" &&\n\t\t\t\tentry.reservationId.length > 0 &&\n\t\t\t\t\"sessionId\" in entry &&\n\t\t\t\ttypeof entry.sessionId === \"string\" &&\n\t\t\t\tentry.sessionId.length > 0 &&\n\t\t\t\t(!(\"sessionFile\" in entry) || entry.sessionFile === undefined || typeof entry.sessionFile === \"string\") &&\n\t\t\t\t(!(\"residentRoot\" in entry) || entry.residentRoot === undefined || entry.residentRoot === true),\n\t\t)\n\t);\n}\n\nexport type DaemonCreateCommand = Extract<DaemonCommand, { type: \"create\" }>;\n\nexport interface DurableDaemonCreateCommand {\n\ttype: \"create\";\n\tsessionPath?: string;\n\tnoSession?: boolean;\n}\n\nexport function durableDaemonCreateCommand(command: DaemonCreateCommand): DurableDaemonCreateCommand {\n\treturn {\n\t\ttype: \"create\",\n\t\t...(command.sessionPath !== undefined ? { sessionPath: command.sessionPath } : {}),\n\t\t...(command.noSession !== undefined ? { noSession: command.noSession } : {}),\n\t};\n}\n\n/**\n * A single-use, worker-memory-only admission for one direct peer, scoped to one active-session\n * slot (stable across switch_session/new_session/fork) of one worker incarnation. The session pin\n * is a routing/accident guard, not a privilege boundary: ticket holders already hold supervisor\n * access, which can attach to, switch, or kill any session.\n */\nexport interface DaemonWorkerPeerGrant {\n\tgrantId: string;\n\ttoken: string;\n\texpiresAt: string;\n\tpurpose: \"session_client\";\n\tworkerInstanceId: string;\n\tactiveSessionId: string;\n\tissuerGeneration: string;\n}\n\n/** Commands a direct peer may send before it holds an authenticated session role. */\nexport type DaemonPeerCommand = {\n\tid?: string;\n\ttype: \"peer_auth\";\n\tgrantId: string;\n\ttoken: string;\n\tworkerInstanceId: string;\n\tpurpose: \"session_client\";\n};\n\nexport type DaemonPeerCommandBody = Omit<DaemonPeerCommand, \"id\">;\n\nexport type DaemonWorkerCommand =\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_auth\";\n\t\t\ttoken: string;\n\t\t\tworkerInstanceId?: string;\n\t\t\tsupervisorGeneration: string;\n\t\t\tsupervisorPid: number;\n\t\t\tsupervisorProcessStartId?: string;\n\t\t\tsupervisorSocketPath: string;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_subscribe\";\n\t\t\tactiveSessionId: string;\n\t\t\tcapabilities?: readonly DaemonClientCapability[];\n\t\t\tsupportsExtensionUi?: boolean;\n\t }\n\t| { id?: string; type: \"worker_unsubscribe\"; activeSessionId: string }\n\t| { id?: string; type: \"worker_register_peer_transport\"; grant: DaemonWorkerPeerGrant }\n\t| { id?: string; type: \"worker_archive_and_shutdown\" }\n\t| { id?: string; type: \"worker_get_rlm_capacity\" }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_passivate_idle_children\";\n\t\t\tidleEvictionMinutes: IdleEvictionMinutes;\n\t\t\tnow: number;\n\t\t\tlimit: number;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_deliver_message\";\n\t\t\ttargetActiveSessionId: string;\n\t\t\tmessage: string;\n\t\t\tsender: AgentSessionMessageSender;\n\t\t\tdeliveryMode?: AgentSessionMessageDeliveryMode;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_deliver_result\";\n\t\t\ttargetActiveSessionId: string;\n\t\t\tsummary: string;\n\t\t\tfindings: string;\n\t\t\tsender: AgentSessionMessageSender;\n\t\t\tdeliveryMode?: AgentSessionMessageDeliveryMode;\n\t }\n\t| { id?: string; type: \"worker_prepare_update\" }\n\t| { id?: string; type: \"worker_commit_update\" }\n\t| { id?: string; type: \"worker_cancel_update\" };\n\nexport type DaemonWorkerCommandBody = DaemonWorkerCommand extends infer TCommand\n\t? TCommand extends { id?: string }\n\t\t? Omit<TCommand, \"id\">\n\t\t: never\n\t: never;\n\nexport interface DaemonWorkerDescriptor {\n\tversion: 1 | 2;\n\tworkerId: string;\n\tpid: number;\n\tprocessStartId?: string;\n\tsocketPath: string;\n\trecoveryJournalPath: string;\n\torphanProcessJournalPath?: string;\n\tsupervisorSocketPath: string;\n\tauthenticationToken: string;\n\tworkerInstanceId?: string;\n\trootActiveSessionId: string;\n\t/** Stable protocol client that owns this worker. Omitted for resident sessions. */\n\townerClientId?: string;\n\trootSessionId?: string;\n\tsessionFile?: string;\n\tsessionDir?: string;\n\t/** Supervisor-assigned journal scope, independent of transcript storage. */\n\trlmLedgerSessionDir?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tlifecycle: DaemonWorkerLifecycle;\n\tcreateCommand: DurableDaemonCreateCommand;\n\tconsecutiveFailures: number;\n\t/** Durable intent written before root termination so replacement supervisors never recover it. */\n\tstopRequestedAt?: string;\n\t/** Complete the root's archived lifecycle state after its process has stopped. */\n\tarchiveOnStop?: boolean;\n\tlastFailureAt?: string;\n\tlastError?: string;\n}\n\nexport function durableDaemonWorkerDescriptor(descriptor: DaemonWorkerDescriptor): DaemonWorkerDescriptor {\n\tconst versionOneCreateCommand = descriptor.createCommand as unknown as { config?: unknown };\n\tconst versionOneConfig =\n\t\tdescriptor.version === 1 &&\n\t\ttypeof versionOneCreateCommand.config === \"object\" &&\n\t\tversionOneCreateCommand.config !== null\n\t\t\t? (versionOneCreateCommand.config as Record<string, unknown>)\n\t\t\t: undefined;\n\tconst sessionDir =\n\t\tdescriptor.sessionDir ??\n\t\t(typeof versionOneConfig?.sessionDir === \"string\" ? versionOneConfig.sessionDir : undefined);\n\treturn {\n\t\tversion: 2,\n\t\tworkerId: descriptor.workerId,\n\t\tpid: descriptor.pid,\n\t\t...(descriptor.processStartId !== undefined ? { processStartId: descriptor.processStartId } : {}),\n\t\tsocketPath: descriptor.socketPath,\n\t\trecoveryJournalPath: descriptor.recoveryJournalPath,\n\t\t...(descriptor.orphanProcessJournalPath !== undefined\n\t\t\t? { orphanProcessJournalPath: descriptor.orphanProcessJournalPath }\n\t\t\t: {}),\n\t\tsupervisorSocketPath: descriptor.supervisorSocketPath,\n\t\tauthenticationToken: descriptor.authenticationToken,\n\t\t...(descriptor.workerInstanceId !== undefined ? { workerInstanceId: descriptor.workerInstanceId } : {}),\n\t\trootActiveSessionId: descriptor.rootActiveSessionId,\n\t\t...(descriptor.ownerClientId !== undefined ? { ownerClientId: descriptor.ownerClientId } : {}),\n\t\t...(descriptor.rootSessionId !== undefined ? { rootSessionId: descriptor.rootSessionId } : {}),\n\t\t...(descriptor.sessionFile !== undefined ? { sessionFile: descriptor.sessionFile } : {}),\n\t\t...(sessionDir !== undefined ? { sessionDir } : {}),\n\t\t...(descriptor.rlmLedgerSessionDir !== undefined ? { rlmLedgerSessionDir: descriptor.rlmLedgerSessionDir } : {}),\n\t\tcreatedAt: descriptor.createdAt,\n\t\tupdatedAt: descriptor.updatedAt,\n\t\tlifecycle: descriptor.lifecycle,\n\t\tcreateCommand: durableDaemonCreateCommand(descriptor.createCommand),\n\t\tconsecutiveFailures: descriptor.consecutiveFailures,\n\t\t...(descriptor.stopRequestedAt !== undefined ? { stopRequestedAt: descriptor.stopRequestedAt } : {}),\n\t\t...(descriptor.archiveOnStop !== undefined ? { archiveOnStop: descriptor.archiveOnStop } : {}),\n\t\t...(descriptor.lastFailureAt !== undefined ? { lastFailureAt: descriptor.lastFailureAt } : {}),\n\t\t...(descriptor.lifecycle === \"failed\" ? { lastError: \"Waiting for a client with fresh runtime context\" } : {}),\n\t};\n}\n\nexport function isDaemonWorkerProcess(environment: NodeJS.ProcessEnv = process.env): boolean {\n\treturn environment[DAEMON_WORKER_ROLE_ENV] === \"1\";\n}\n\nexport function waitForDaemonWorkerStartupGate(environment: NodeJS.ProcessEnv = process.env): void {\n\tconst rawFd = environment[DAEMON_WORKER_STARTUP_GATE_FD_ENV];\n\tif (rawFd === undefined) {\n\t\treturn;\n\t}\n\tdelete environment[DAEMON_WORKER_STARTUP_GATE_FD_ENV];\n\tconst fd = Number(rawFd);\n\tif (!Number.isInteger(fd) || fd < 3) {\n\t\tthrow new Error(\"Daemon session worker has an invalid startup gate\");\n\t}\n\tlet marker: string;\n\ttry {\n\t\tmarker = readFileSync(fd, \"utf8\");\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\tif (marker !== DAEMON_WORKER_STARTUP_GATE_COMMIT) {\n\t\tthrow new Error(\"Daemon session worker startup was cancelled\");\n\t}\n}\n\nexport function daemonWorkerInstanceId(environment: NodeJS.ProcessEnv = process.env): string | undefined {\n\treturn environment[DAEMON_WORKER_INSTANCE_ID_ENV] || undefined;\n}\n\nexport function requireDaemonWorkerAuthenticationToken(environment: NodeJS.ProcessEnv = process.env): string {\n\tconst token = environment[DAEMON_WORKER_TOKEN_ENV];\n\tif (!token) {\n\t\tthrow new Error(\"Daemon session worker is missing its authentication token\");\n\t}\n\treturn token;\n}\n\nexport function isDaemonWorkerFrameHeader(value: unknown): value is DaemonWorkerFrameHeader {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst candidate = value as Record<string, unknown>;\n\tif (candidate.kind === \"command\") {\n\t\treturn typeof candidate.requestId === \"string\" && typeof candidate.commandType === \"string\";\n\t}\n\treturn (\n\t\tcandidate.kind === \"outbound\" &&\n\t\ttypeof candidate.outboundType === \"string\" &&\n\t\t(candidate.requestId === undefined || typeof candidate.requestId === \"string\") &&\n\t\t(candidate.activeSessionId === undefined || typeof candidate.activeSessionId === \"string\") &&\n\t\t(candidate.snapshotId === undefined || typeof candidate.snapshotId === \"string\") &&\n\t\t(candidate.sessionEventType === undefined || typeof candidate.sessionEventType === \"string\") &&\n\t\t(candidate.snapshotPurpose === undefined ||\n\t\t\tcandidate.snapshotPurpose === \"attach\" ||\n\t\t\tcandidate.snapshotPurpose === \"replacement\" ||\n\t\t\tcandidate.snapshotPurpose === \"catchup\") &&\n\t\t(candidate.payloadEncoding === undefined ||\n\t\t\tcandidate.payloadEncoding === \"jsonl\" ||\n\t\t\tcandidate.payloadEncoding === \"assistant-delta\")\n\t);\n}\n"]}
@@ -6,6 +6,7 @@ export const DAEMON_WORKER_INSTANCE_ID_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_WORKE
6
6
  export const DAEMON_WORKER_ACTIVE_SESSION_ID_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_WORKER_ACTIVE_SESSION_ID";
7
7
  export const DAEMON_WORKER_SUPERVISOR_SOCKET_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_SOCKET";
8
8
  export const DAEMON_WORKER_RECOVERY_JOURNAL_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RECOVERY_JOURNAL";
9
+ export const DAEMON_WORKER_RLM_LEDGER_SESSION_DIR_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RLM_LEDGER_SESSION_DIR";
9
10
  export const DAEMON_WORKER_STARTUP_GATE_FD_ENV = "BASE_CONTEXT_INTERNAL_DAEMON_WORKER_STARTUP_GATE_FD";
10
11
  export const DAEMON_WORKER_STARTUP_GATE_COMMIT = "start\n";
11
12
  /** Advertised by new workers in the worker_auth response; absent on legacy workers. */
@@ -64,6 +65,7 @@ export function durableDaemonWorkerDescriptor(descriptor) {
64
65
  ...(descriptor.rootSessionId !== undefined ? { rootSessionId: descriptor.rootSessionId } : {}),
65
66
  ...(descriptor.sessionFile !== undefined ? { sessionFile: descriptor.sessionFile } : {}),
66
67
  ...(sessionDir !== undefined ? { sessionDir } : {}),
68
+ ...(descriptor.rlmLedgerSessionDir !== undefined ? { rlmLedgerSessionDir: descriptor.rlmLedgerSessionDir } : {}),
67
69
  createdAt: descriptor.createdAt,
68
70
  updatedAt: descriptor.updatedAt,
69
71
  lifecycle: descriptor.lifecycle,
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-worker-protocol.js","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-worker-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIlD,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAKrG,MAAM,CAAC,MAAM,sBAAsB,GAAG,qCAAqC,CAAC;AAC5E,MAAM,CAAC,MAAM,uBAAuB,GAAG,2CAA2C,CAAC;AACnF,MAAM,CAAC,MAAM,6BAA6B,GAAG,iDAAiD,CAAC;AAC/F,MAAM,CAAC,MAAM,mCAAmC,GAAG,uDAAuD,CAAC;AAC3G,MAAM,CAAC,MAAM,mCAAmC,GAAG,gDAAgD,CAAC;AACpG,MAAM,CAAC,MAAM,kCAAkC,GAAG,sDAAsD,CAAC;AACzG,MAAM,CAAC,MAAM,iCAAiC,GAAG,qDAAqD,CAAC;AACvG,MAAM,CAAC,MAAM,iCAAiC,GAAG,SAAS,CAAC;AAa3D,uFAAuF;AACvF,MAAM,CAAC,MAAM,+BAA+B,GAAG,cAAc,CAAC;AAE9D,2FAA2F;AAC3F,MAAM,CAAC,MAAM,uCAAuC,GAAG,gBAAgB,CAAC;AAExE,uHAAuH;AACvH,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC;AAuCnD,MAAM,UAAU,2BAA2B,CAAC,KAAc,EAAsC;IAC/F,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,cAAc,IAAI,KAAK;QACvB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC;QACjC,KAAK,CAAC,YAAY,CAAC,KAAK,CACvB,CAAC,KAAc,EAAE,EAAE,CAClB,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACd,eAAe,IAAI,KAAK;YACxB,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ;YACvC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;YAC9B,WAAW,IAAI,KAAK;YACpB,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;YACnC,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;YAC1B,CAAC,CAAC,CAAC,aAAa,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC;YACvG,CAAC,CAAC,CAAC,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC,CAChG,CACD,CAAC;AAAA,CACF;AAUD,MAAM,UAAU,0BAA0B,CAAC,OAA4B,EAA8B;IACpG,OAAO;QACN,IAAI,EAAE,QAAQ;QACd,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5E,CAAC;AAAA,CACF;AAoHD,MAAM,UAAU,6BAA6B,CAAC,UAAkC,EAA0B;IACzG,MAAM,uBAAuB,GAAG,UAAU,CAAC,aAAgD,CAAC;IAC5F,MAAM,gBAAgB,GACrB,UAAU,CAAC,OAAO,KAAK,CAAC;QACxB,OAAO,uBAAuB,CAAC,MAAM,KAAK,QAAQ;QAClD,uBAAuB,CAAC,MAAM,KAAK,IAAI;QACtC,CAAC,CAAE,uBAAuB,CAAC,MAAkC;QAC7D,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,UAAU,GACf,UAAU,CAAC,UAAU;QACrB,CAAC,OAAO,gBAAgB,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC9F,OAAO;QACN,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,GAAG,EAAE,UAAU,CAAC,GAAG;QACnB,GAAG,CAAC,UAAU,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,UAAU,EAAE,UAAU,CAAC,UAAU;QACjC,mBAAmB,EAAE,UAAU,CAAC,mBAAmB;QACnD,GAAG,CAAC,UAAU,CAAC,wBAAwB,KAAK,SAAS;YACpD,CAAC,CAAC,EAAE,wBAAwB,EAAE,UAAU,CAAC,wBAAwB,EAAE;YACnE,CAAC,CAAC,EAAE,CAAC;QACN,oBAAoB,EAAE,UAAU,CAAC,oBAAoB;QACrD,mBAAmB,EAAE,UAAU,CAAC,mBAAmB;QACnD,GAAG,CAAC,UAAU,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvG,mBAAmB,EAAE,UAAU,CAAC,mBAAmB;QACnD,GAAG,CAAC,UAAU,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,GAAG,CAAC,UAAU,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,GAAG,CAAC,UAAU,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,SAAS,EAAE,UAAU,CAAC,SAAS;QAC/B,aAAa,EAAE,0BAA0B,CAAC,UAAU,CAAC,aAAa,CAAC;QACnE,mBAAmB,EAAE,UAAU,CAAC,mBAAmB;QACnD,GAAG,CAAC,UAAU,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpG,GAAG,CAAC,UAAU,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,GAAG,CAAC,UAAU,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,GAAG,CAAC,UAAU,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,iDAAiD,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9G,CAAC;AAAA,CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,WAAW,GAAsB,OAAO,CAAC,GAAG,EAAW;IAC5F,OAAO,WAAW,CAAC,sBAAsB,CAAC,KAAK,GAAG,CAAC;AAAA,CACnD;AAED,MAAM,UAAU,8BAA8B,CAAC,WAAW,GAAsB,OAAO,CAAC,GAAG,EAAQ;IAClG,MAAM,KAAK,GAAG,WAAW,CAAC,iCAAiC,CAAC,CAAC;IAC7D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO;IACR,CAAC;IACD,OAAO,WAAW,CAAC,iCAAiC,CAAC,CAAC;IACtD,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACJ,MAAM,GAAG,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;YAAS,CAAC;QACV,SAAS,CAAC,EAAE,CAAC,CAAC;IACf,CAAC;IACD,IAAI,MAAM,KAAK,iCAAiC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAChE,CAAC;AAAA,CACD;AAED,MAAM,UAAU,sBAAsB,CAAC,WAAW,GAAsB,OAAO,CAAC,GAAG,EAAsB;IACxG,OAAO,WAAW,CAAC,6BAA6B,CAAC,IAAI,SAAS,CAAC;AAAA,CAC/D;AAED,MAAM,UAAU,sCAAsC,CAAC,WAAW,GAAsB,OAAO,CAAC,GAAG,EAAU;IAC5G,MAAM,KAAK,GAAG,WAAW,CAAC,uBAAuB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,MAAM,UAAU,yBAAyB,CAAC,KAAc,EAAoC;IAC3F,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,SAAS,GAAG,KAAgC,CAAC;IACnD,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,OAAO,SAAS,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,SAAS,CAAC,WAAW,KAAK,QAAQ,CAAC;IAC7F,CAAC;IACD,OAAO,CACN,SAAS,CAAC,IAAI,KAAK,UAAU;QAC7B,OAAO,SAAS,CAAC,YAAY,KAAK,QAAQ;QAC1C,CAAC,SAAS,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,SAAS,CAAC,SAAS,KAAK,QAAQ,CAAC;QAC9E,CAAC,SAAS,CAAC,eAAe,KAAK,SAAS,IAAI,OAAO,SAAS,CAAC,eAAe,KAAK,QAAQ,CAAC;QAC1F,CAAC,SAAS,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,SAAS,CAAC,UAAU,KAAK,QAAQ,CAAC;QAChF,CAAC,SAAS,CAAC,gBAAgB,KAAK,SAAS,IAAI,OAAO,SAAS,CAAC,gBAAgB,KAAK,QAAQ,CAAC;QAC5F,CAAC,SAAS,CAAC,eAAe,KAAK,SAAS;YACvC,SAAS,CAAC,eAAe,KAAK,QAAQ;YACtC,SAAS,CAAC,eAAe,KAAK,aAAa;YAC3C,SAAS,CAAC,eAAe,KAAK,SAAS,CAAC;QACzC,CAAC,SAAS,CAAC,eAAe,KAAK,SAAS;YACvC,SAAS,CAAC,eAAe,KAAK,OAAO;YACrC,SAAS,CAAC,eAAe,KAAK,iBAAiB,CAAC,CACjD,CAAC;AAAA,CACF","sourcesContent":["import { closeSync, readFileSync } from \"node:fs\";\nimport type { AgentSessionMessageDeliveryMode, AgentSessionMessageSender } from \"../../core/agent-messages.js\";\nimport type { IdleEvictionMinutes } from \"../../core/session-action-store.js\";\n\nexport { SESSION_LEASE_OWNER_ID_ENV, SESSION_LEASES_ENABLED_ENV } from \"../../core/session-lease.js\";\n\nimport type { WorkerRosterEntry } from \"./agent-roster.js\";\nimport type { DaemonClientCapability, DaemonCommand, DaemonOutbound } from \"./daemon-protocol.js\";\n\nexport const DAEMON_WORKER_ROLE_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER\";\nexport const DAEMON_WORKER_TOKEN_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_TOKEN\";\nexport const DAEMON_WORKER_INSTANCE_ID_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_INSTANCE_ID\";\nexport const DAEMON_WORKER_ACTIVE_SESSION_ID_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_ACTIVE_SESSION_ID\";\nexport const DAEMON_WORKER_SUPERVISOR_SOCKET_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_SOCKET\";\nexport const DAEMON_WORKER_RECOVERY_JOURNAL_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RECOVERY_JOURNAL\";\nexport const DAEMON_WORKER_STARTUP_GATE_FD_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_STARTUP_GATE_FD\";\nexport const DAEMON_WORKER_STARTUP_GATE_COMMIT = \"start\\n\";\nexport type DaemonWorkerLifecycle = \"starting\" | \"ready\" | \"recovering\" | \"stopping\" | \"failed\";\n\n// Worker->supervisor roster frames live outside the client-facing DaemonOutbound schema.\nexport type DaemonWorkerRosterOutbound =\n\t| {\n\t\t\ttype: \"roster_delta\";\n\t\t\tentries: WorkerRosterEntry[];\n\t\t\tremovedAgentIds?: string[];\n\t\t\tsnapshot?: true;\n\t }\n\t| { type: \"roster_heartbeat\" };\n\n/** Advertised by new workers in the worker_auth response; absent on legacy workers. */\nexport const DAEMON_WORKER_ROSTER_CAPABILITY = \"agent_roster\";\n\n/** Advertised in the worker_auth response by workers that accept peer transport grants. */\nexport const DAEMON_WORKER_PEER_TRANSPORT_CAPABILITY = \"peer_transport\";\n\n/** Idle keepalive cadence for worker->supervisor roster frames; the supervisor staleness threshold derives from it. */\nexport const ROSTER_HEARTBEAT_INTERVAL_MS = 15_000;\n\nexport type DaemonWorkerFrameHeader =\n\t| {\n\t\t\tkind: \"command\";\n\t\t\trequestId: string;\n\t\t\tcommandType: string;\n\t }\n\t| {\n\t\t\tkind: \"outbound\";\n\t\t\trequestId?: string;\n\t\t\toutboundType: DaemonOutbound[\"type\"] | DaemonWorkerRosterOutbound[\"type\"];\n\t\t\tactiveSessionId?: string;\n\t\t\tsnapshotId?: string;\n\t\t\tsessionEventType?: string;\n\t\t\tpayloadEncoding?: \"jsonl\" | \"assistant-delta\";\n\t\t\tsnapshotPurpose?: \"attach\" | \"replacement\" | \"catchup\";\n\t };\n\nexport interface DaemonRlmCapacityOrigin {\n\tsessionFile?: string;\n\tsessionId: string;\n}\n\nexport type DaemonRlmCapacityOperation =\n\t| (DaemonRlmCapacityOrigin & { op: \"status\" })\n\t| (DaemonRlmCapacityOrigin & { op: \"set\"; maxSubagents: number })\n\t| (DaemonRlmCapacityOrigin & { op: \"reserve\"; reservationId: string; residentRoot?: true })\n\t| { op: \"release\"; reservationId: string };\n\nexport interface DaemonRlmCapacityReservation extends DaemonRlmCapacityOrigin {\n\treservationId: string;\n\tresidentRoot?: true;\n}\n\nexport interface DaemonRlmCapacitySnapshot {\n\treservations: DaemonRlmCapacityReservation[];\n}\n\nexport function isDaemonRlmCapacitySnapshot(value: unknown): value is DaemonRlmCapacitySnapshot {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"reservations\" in value &&\n\t\tArray.isArray(value.reservations) &&\n\t\tvalue.reservations.every(\n\t\t\t(entry: unknown) =>\n\t\t\t\ttypeof entry === \"object\" &&\n\t\t\t\tentry !== null &&\n\t\t\t\t\"reservationId\" in entry &&\n\t\t\t\ttypeof entry.reservationId === \"string\" &&\n\t\t\t\tentry.reservationId.length > 0 &&\n\t\t\t\t\"sessionId\" in entry &&\n\t\t\t\ttypeof entry.sessionId === \"string\" &&\n\t\t\t\tentry.sessionId.length > 0 &&\n\t\t\t\t(!(\"sessionFile\" in entry) || entry.sessionFile === undefined || typeof entry.sessionFile === \"string\") &&\n\t\t\t\t(!(\"residentRoot\" in entry) || entry.residentRoot === undefined || entry.residentRoot === true),\n\t\t)\n\t);\n}\n\nexport type DaemonCreateCommand = Extract<DaemonCommand, { type: \"create\" }>;\n\nexport interface DurableDaemonCreateCommand {\n\ttype: \"create\";\n\tsessionPath?: string;\n\tnoSession?: boolean;\n}\n\nexport function durableDaemonCreateCommand(command: DaemonCreateCommand): DurableDaemonCreateCommand {\n\treturn {\n\t\ttype: \"create\",\n\t\t...(command.sessionPath !== undefined ? { sessionPath: command.sessionPath } : {}),\n\t\t...(command.noSession !== undefined ? { noSession: command.noSession } : {}),\n\t};\n}\n\n/**\n * A single-use, worker-memory-only admission for one direct peer, scoped to one active-session\n * slot (stable across switch_session/new_session/fork) of one worker incarnation. The session pin\n * is a routing/accident guard, not a privilege boundary: ticket holders already hold supervisor\n * access, which can attach to, switch, or kill any session.\n */\nexport interface DaemonWorkerPeerGrant {\n\tgrantId: string;\n\ttoken: string;\n\texpiresAt: string;\n\tpurpose: \"session_client\";\n\tworkerInstanceId: string;\n\tactiveSessionId: string;\n\tissuerGeneration: string;\n}\n\n/** Commands a direct peer may send before it holds an authenticated session role. */\nexport type DaemonPeerCommand = {\n\tid?: string;\n\ttype: \"peer_auth\";\n\tgrantId: string;\n\ttoken: string;\n\tworkerInstanceId: string;\n\tpurpose: \"session_client\";\n};\n\nexport type DaemonPeerCommandBody = Omit<DaemonPeerCommand, \"id\">;\n\nexport type DaemonWorkerCommand =\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_auth\";\n\t\t\ttoken: string;\n\t\t\tworkerInstanceId?: string;\n\t\t\tsupervisorGeneration: string;\n\t\t\tsupervisorPid: number;\n\t\t\tsupervisorProcessStartId?: string;\n\t\t\tsupervisorSocketPath: string;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_subscribe\";\n\t\t\tactiveSessionId: string;\n\t\t\tcapabilities?: readonly DaemonClientCapability[];\n\t\t\tsupportsExtensionUi?: boolean;\n\t }\n\t| { id?: string; type: \"worker_unsubscribe\"; activeSessionId: string }\n\t| { id?: string; type: \"worker_register_peer_transport\"; grant: DaemonWorkerPeerGrant }\n\t| { id?: string; type: \"worker_archive_and_shutdown\" }\n\t| { id?: string; type: \"worker_get_rlm_capacity\" }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_passivate_idle_children\";\n\t\t\tidleEvictionMinutes: IdleEvictionMinutes;\n\t\t\tnow: number;\n\t\t\tlimit: number;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_deliver_message\";\n\t\t\ttargetActiveSessionId: string;\n\t\t\tmessage: string;\n\t\t\tsender: AgentSessionMessageSender;\n\t\t\tdeliveryMode?: AgentSessionMessageDeliveryMode;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_deliver_result\";\n\t\t\ttargetActiveSessionId: string;\n\t\t\tsummary: string;\n\t\t\tfindings: string;\n\t\t\tsender: AgentSessionMessageSender;\n\t\t\tdeliveryMode?: AgentSessionMessageDeliveryMode;\n\t }\n\t| { id?: string; type: \"worker_prepare_update\" }\n\t| { id?: string; type: \"worker_commit_update\" }\n\t| { id?: string; type: \"worker_cancel_update\" };\n\nexport type DaemonWorkerCommandBody = DaemonWorkerCommand extends infer TCommand\n\t? TCommand extends { id?: string }\n\t\t? Omit<TCommand, \"id\">\n\t\t: never\n\t: never;\n\nexport interface DaemonWorkerDescriptor {\n\tversion: 1 | 2;\n\tworkerId: string;\n\tpid: number;\n\tprocessStartId?: string;\n\tsocketPath: string;\n\trecoveryJournalPath: string;\n\torphanProcessJournalPath?: string;\n\tsupervisorSocketPath: string;\n\tauthenticationToken: string;\n\tworkerInstanceId?: string;\n\trootActiveSessionId: string;\n\t/** Stable protocol client that owns this worker. Omitted for resident sessions. */\n\townerClientId?: string;\n\trootSessionId?: string;\n\tsessionFile?: string;\n\tsessionDir?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tlifecycle: DaemonWorkerLifecycle;\n\tcreateCommand: DurableDaemonCreateCommand;\n\tconsecutiveFailures: number;\n\t/** Durable intent written before root termination so replacement supervisors never recover it. */\n\tstopRequestedAt?: string;\n\t/** Complete the root's archived lifecycle state after its process has stopped. */\n\tarchiveOnStop?: boolean;\n\tlastFailureAt?: string;\n\tlastError?: string;\n}\n\nexport function durableDaemonWorkerDescriptor(descriptor: DaemonWorkerDescriptor): DaemonWorkerDescriptor {\n\tconst versionOneCreateCommand = descriptor.createCommand as unknown as { config?: unknown };\n\tconst versionOneConfig =\n\t\tdescriptor.version === 1 &&\n\t\ttypeof versionOneCreateCommand.config === \"object\" &&\n\t\tversionOneCreateCommand.config !== null\n\t\t\t? (versionOneCreateCommand.config as Record<string, unknown>)\n\t\t\t: undefined;\n\tconst sessionDir =\n\t\tdescriptor.sessionDir ??\n\t\t(typeof versionOneConfig?.sessionDir === \"string\" ? versionOneConfig.sessionDir : undefined);\n\treturn {\n\t\tversion: 2,\n\t\tworkerId: descriptor.workerId,\n\t\tpid: descriptor.pid,\n\t\t...(descriptor.processStartId !== undefined ? { processStartId: descriptor.processStartId } : {}),\n\t\tsocketPath: descriptor.socketPath,\n\t\trecoveryJournalPath: descriptor.recoveryJournalPath,\n\t\t...(descriptor.orphanProcessJournalPath !== undefined\n\t\t\t? { orphanProcessJournalPath: descriptor.orphanProcessJournalPath }\n\t\t\t: {}),\n\t\tsupervisorSocketPath: descriptor.supervisorSocketPath,\n\t\tauthenticationToken: descriptor.authenticationToken,\n\t\t...(descriptor.workerInstanceId !== undefined ? { workerInstanceId: descriptor.workerInstanceId } : {}),\n\t\trootActiveSessionId: descriptor.rootActiveSessionId,\n\t\t...(descriptor.ownerClientId !== undefined ? { ownerClientId: descriptor.ownerClientId } : {}),\n\t\t...(descriptor.rootSessionId !== undefined ? { rootSessionId: descriptor.rootSessionId } : {}),\n\t\t...(descriptor.sessionFile !== undefined ? { sessionFile: descriptor.sessionFile } : {}),\n\t\t...(sessionDir !== undefined ? { sessionDir } : {}),\n\t\tcreatedAt: descriptor.createdAt,\n\t\tupdatedAt: descriptor.updatedAt,\n\t\tlifecycle: descriptor.lifecycle,\n\t\tcreateCommand: durableDaemonCreateCommand(descriptor.createCommand),\n\t\tconsecutiveFailures: descriptor.consecutiveFailures,\n\t\t...(descriptor.stopRequestedAt !== undefined ? { stopRequestedAt: descriptor.stopRequestedAt } : {}),\n\t\t...(descriptor.archiveOnStop !== undefined ? { archiveOnStop: descriptor.archiveOnStop } : {}),\n\t\t...(descriptor.lastFailureAt !== undefined ? { lastFailureAt: descriptor.lastFailureAt } : {}),\n\t\t...(descriptor.lifecycle === \"failed\" ? { lastError: \"Waiting for a client with fresh runtime context\" } : {}),\n\t};\n}\n\nexport function isDaemonWorkerProcess(environment: NodeJS.ProcessEnv = process.env): boolean {\n\treturn environment[DAEMON_WORKER_ROLE_ENV] === \"1\";\n}\n\nexport function waitForDaemonWorkerStartupGate(environment: NodeJS.ProcessEnv = process.env): void {\n\tconst rawFd = environment[DAEMON_WORKER_STARTUP_GATE_FD_ENV];\n\tif (rawFd === undefined) {\n\t\treturn;\n\t}\n\tdelete environment[DAEMON_WORKER_STARTUP_GATE_FD_ENV];\n\tconst fd = Number(rawFd);\n\tif (!Number.isInteger(fd) || fd < 3) {\n\t\tthrow new Error(\"Daemon session worker has an invalid startup gate\");\n\t}\n\tlet marker: string;\n\ttry {\n\t\tmarker = readFileSync(fd, \"utf8\");\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\tif (marker !== DAEMON_WORKER_STARTUP_GATE_COMMIT) {\n\t\tthrow new Error(\"Daemon session worker startup was cancelled\");\n\t}\n}\n\nexport function daemonWorkerInstanceId(environment: NodeJS.ProcessEnv = process.env): string | undefined {\n\treturn environment[DAEMON_WORKER_INSTANCE_ID_ENV] || undefined;\n}\n\nexport function requireDaemonWorkerAuthenticationToken(environment: NodeJS.ProcessEnv = process.env): string {\n\tconst token = environment[DAEMON_WORKER_TOKEN_ENV];\n\tif (!token) {\n\t\tthrow new Error(\"Daemon session worker is missing its authentication token\");\n\t}\n\treturn token;\n}\n\nexport function isDaemonWorkerFrameHeader(value: unknown): value is DaemonWorkerFrameHeader {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst candidate = value as Record<string, unknown>;\n\tif (candidate.kind === \"command\") {\n\t\treturn typeof candidate.requestId === \"string\" && typeof candidate.commandType === \"string\";\n\t}\n\treturn (\n\t\tcandidate.kind === \"outbound\" &&\n\t\ttypeof candidate.outboundType === \"string\" &&\n\t\t(candidate.requestId === undefined || typeof candidate.requestId === \"string\") &&\n\t\t(candidate.activeSessionId === undefined || typeof candidate.activeSessionId === \"string\") &&\n\t\t(candidate.snapshotId === undefined || typeof candidate.snapshotId === \"string\") &&\n\t\t(candidate.sessionEventType === undefined || typeof candidate.sessionEventType === \"string\") &&\n\t\t(candidate.snapshotPurpose === undefined ||\n\t\t\tcandidate.snapshotPurpose === \"attach\" ||\n\t\t\tcandidate.snapshotPurpose === \"replacement\" ||\n\t\t\tcandidate.snapshotPurpose === \"catchup\") &&\n\t\t(candidate.payloadEncoding === undefined ||\n\t\t\tcandidate.payloadEncoding === \"jsonl\" ||\n\t\t\tcandidate.payloadEncoding === \"assistant-delta\")\n\t);\n}\n"]}
1
+ {"version":3,"file":"daemon-worker-protocol.js","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-worker-protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import { closeSync, readFileSync } from \"node:fs\";\nimport type { AgentSessionMessageDeliveryMode, AgentSessionMessageSender } from \"../../core/agent-messages.js\";\nimport type { IdleEvictionMinutes } from \"../../core/session-action-store.js\";\n\nexport { SESSION_LEASE_OWNER_ID_ENV, SESSION_LEASES_ENABLED_ENV } from \"../../core/session-lease.js\";\n\nimport type { WorkerRosterEntry } from \"./agent-roster.js\";\nimport type { DaemonClientCapability, DaemonCommand, DaemonOutbound } from \"./daemon-protocol.js\";\n\nexport const DAEMON_WORKER_ROLE_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER\";\nexport const DAEMON_WORKER_TOKEN_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_TOKEN\";\nexport const DAEMON_WORKER_INSTANCE_ID_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_INSTANCE_ID\";\nexport const DAEMON_WORKER_ACTIVE_SESSION_ID_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_ACTIVE_SESSION_ID\";\nexport const DAEMON_WORKER_SUPERVISOR_SOCKET_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_SOCKET\";\nexport const DAEMON_WORKER_RECOVERY_JOURNAL_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RECOVERY_JOURNAL\";\nexport const DAEMON_WORKER_RLM_LEDGER_SESSION_DIR_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_RLM_LEDGER_SESSION_DIR\";\nexport const DAEMON_WORKER_STARTUP_GATE_FD_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_WORKER_STARTUP_GATE_FD\";\nexport const DAEMON_WORKER_STARTUP_GATE_COMMIT = \"start\\n\";\nexport type DaemonWorkerLifecycle = \"starting\" | \"ready\" | \"recovering\" | \"stopping\" | \"failed\";\n\n// Worker->supervisor roster frames live outside the client-facing DaemonOutbound schema.\nexport type DaemonWorkerRosterOutbound =\n\t| {\n\t\t\ttype: \"roster_delta\";\n\t\t\tentries: WorkerRosterEntry[];\n\t\t\tremovedAgentIds?: string[];\n\t\t\tsnapshot?: true;\n\t }\n\t| { type: \"roster_heartbeat\" };\n\n/** Advertised by new workers in the worker_auth response; absent on legacy workers. */\nexport const DAEMON_WORKER_ROSTER_CAPABILITY = \"agent_roster\";\n\n/** Advertised in the worker_auth response by workers that accept peer transport grants. */\nexport const DAEMON_WORKER_PEER_TRANSPORT_CAPABILITY = \"peer_transport\";\n\n/** Idle keepalive cadence for worker->supervisor roster frames; the supervisor staleness threshold derives from it. */\nexport const ROSTER_HEARTBEAT_INTERVAL_MS = 15_000;\n\nexport type DaemonWorkerFrameHeader =\n\t| {\n\t\t\tkind: \"command\";\n\t\t\trequestId: string;\n\t\t\tcommandType: string;\n\t }\n\t| {\n\t\t\tkind: \"outbound\";\n\t\t\trequestId?: string;\n\t\t\toutboundType: DaemonOutbound[\"type\"] | DaemonWorkerRosterOutbound[\"type\"];\n\t\t\tactiveSessionId?: string;\n\t\t\tsnapshotId?: string;\n\t\t\tsessionEventType?: string;\n\t\t\tpayloadEncoding?: \"jsonl\" | \"assistant-delta\";\n\t\t\tsnapshotPurpose?: \"attach\" | \"replacement\" | \"catchup\";\n\t };\n\nexport interface DaemonRlmCapacityOrigin {\n\tsessionFile?: string;\n\tsessionId: string;\n}\n\nexport type DaemonRlmCapacityOperation =\n\t| (DaemonRlmCapacityOrigin & { op: \"status\" })\n\t| (DaemonRlmCapacityOrigin & { op: \"set\"; maxSubagents: number })\n\t| (DaemonRlmCapacityOrigin & { op: \"reserve\"; reservationId: string; residentRoot?: true })\n\t| { op: \"release\"; reservationId: string };\n\nexport interface DaemonRlmCapacityReservation extends DaemonRlmCapacityOrigin {\n\treservationId: string;\n\tresidentRoot?: true;\n}\n\nexport interface DaemonRlmCapacitySnapshot {\n\treservations: DaemonRlmCapacityReservation[];\n}\n\nexport function isDaemonRlmCapacitySnapshot(value: unknown): value is DaemonRlmCapacitySnapshot {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"reservations\" in value &&\n\t\tArray.isArray(value.reservations) &&\n\t\tvalue.reservations.every(\n\t\t\t(entry: unknown) =>\n\t\t\t\ttypeof entry === \"object\" &&\n\t\t\t\tentry !== null &&\n\t\t\t\t\"reservationId\" in entry &&\n\t\t\t\ttypeof entry.reservationId === \"string\" &&\n\t\t\t\tentry.reservationId.length > 0 &&\n\t\t\t\t\"sessionId\" in entry &&\n\t\t\t\ttypeof entry.sessionId === \"string\" &&\n\t\t\t\tentry.sessionId.length > 0 &&\n\t\t\t\t(!(\"sessionFile\" in entry) || entry.sessionFile === undefined || typeof entry.sessionFile === \"string\") &&\n\t\t\t\t(!(\"residentRoot\" in entry) || entry.residentRoot === undefined || entry.residentRoot === true),\n\t\t)\n\t);\n}\n\nexport type DaemonCreateCommand = Extract<DaemonCommand, { type: \"create\" }>;\n\nexport interface DurableDaemonCreateCommand {\n\ttype: \"create\";\n\tsessionPath?: string;\n\tnoSession?: boolean;\n}\n\nexport function durableDaemonCreateCommand(command: DaemonCreateCommand): DurableDaemonCreateCommand {\n\treturn {\n\t\ttype: \"create\",\n\t\t...(command.sessionPath !== undefined ? { sessionPath: command.sessionPath } : {}),\n\t\t...(command.noSession !== undefined ? { noSession: command.noSession } : {}),\n\t};\n}\n\n/**\n * A single-use, worker-memory-only admission for one direct peer, scoped to one active-session\n * slot (stable across switch_session/new_session/fork) of one worker incarnation. The session pin\n * is a routing/accident guard, not a privilege boundary: ticket holders already hold supervisor\n * access, which can attach to, switch, or kill any session.\n */\nexport interface DaemonWorkerPeerGrant {\n\tgrantId: string;\n\ttoken: string;\n\texpiresAt: string;\n\tpurpose: \"session_client\";\n\tworkerInstanceId: string;\n\tactiveSessionId: string;\n\tissuerGeneration: string;\n}\n\n/** Commands a direct peer may send before it holds an authenticated session role. */\nexport type DaemonPeerCommand = {\n\tid?: string;\n\ttype: \"peer_auth\";\n\tgrantId: string;\n\ttoken: string;\n\tworkerInstanceId: string;\n\tpurpose: \"session_client\";\n};\n\nexport type DaemonPeerCommandBody = Omit<DaemonPeerCommand, \"id\">;\n\nexport type DaemonWorkerCommand =\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_auth\";\n\t\t\ttoken: string;\n\t\t\tworkerInstanceId?: string;\n\t\t\tsupervisorGeneration: string;\n\t\t\tsupervisorPid: number;\n\t\t\tsupervisorProcessStartId?: string;\n\t\t\tsupervisorSocketPath: string;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_subscribe\";\n\t\t\tactiveSessionId: string;\n\t\t\tcapabilities?: readonly DaemonClientCapability[];\n\t\t\tsupportsExtensionUi?: boolean;\n\t }\n\t| { id?: string; type: \"worker_unsubscribe\"; activeSessionId: string }\n\t| { id?: string; type: \"worker_register_peer_transport\"; grant: DaemonWorkerPeerGrant }\n\t| { id?: string; type: \"worker_archive_and_shutdown\" }\n\t| { id?: string; type: \"worker_get_rlm_capacity\" }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_passivate_idle_children\";\n\t\t\tidleEvictionMinutes: IdleEvictionMinutes;\n\t\t\tnow: number;\n\t\t\tlimit: number;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_deliver_message\";\n\t\t\ttargetActiveSessionId: string;\n\t\t\tmessage: string;\n\t\t\tsender: AgentSessionMessageSender;\n\t\t\tdeliveryMode?: AgentSessionMessageDeliveryMode;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"worker_deliver_result\";\n\t\t\ttargetActiveSessionId: string;\n\t\t\tsummary: string;\n\t\t\tfindings: string;\n\t\t\tsender: AgentSessionMessageSender;\n\t\t\tdeliveryMode?: AgentSessionMessageDeliveryMode;\n\t }\n\t| { id?: string; type: \"worker_prepare_update\" }\n\t| { id?: string; type: \"worker_commit_update\" }\n\t| { id?: string; type: \"worker_cancel_update\" };\n\nexport type DaemonWorkerCommandBody = DaemonWorkerCommand extends infer TCommand\n\t? TCommand extends { id?: string }\n\t\t? Omit<TCommand, \"id\">\n\t\t: never\n\t: never;\n\nexport interface DaemonWorkerDescriptor {\n\tversion: 1 | 2;\n\tworkerId: string;\n\tpid: number;\n\tprocessStartId?: string;\n\tsocketPath: string;\n\trecoveryJournalPath: string;\n\torphanProcessJournalPath?: string;\n\tsupervisorSocketPath: string;\n\tauthenticationToken: string;\n\tworkerInstanceId?: string;\n\trootActiveSessionId: string;\n\t/** Stable protocol client that owns this worker. Omitted for resident sessions. */\n\townerClientId?: string;\n\trootSessionId?: string;\n\tsessionFile?: string;\n\tsessionDir?: string;\n\t/** Supervisor-assigned journal scope, independent of transcript storage. */\n\trlmLedgerSessionDir?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tlifecycle: DaemonWorkerLifecycle;\n\tcreateCommand: DurableDaemonCreateCommand;\n\tconsecutiveFailures: number;\n\t/** Durable intent written before root termination so replacement supervisors never recover it. */\n\tstopRequestedAt?: string;\n\t/** Complete the root's archived lifecycle state after its process has stopped. */\n\tarchiveOnStop?: boolean;\n\tlastFailureAt?: string;\n\tlastError?: string;\n}\n\nexport function durableDaemonWorkerDescriptor(descriptor: DaemonWorkerDescriptor): DaemonWorkerDescriptor {\n\tconst versionOneCreateCommand = descriptor.createCommand as unknown as { config?: unknown };\n\tconst versionOneConfig =\n\t\tdescriptor.version === 1 &&\n\t\ttypeof versionOneCreateCommand.config === \"object\" &&\n\t\tversionOneCreateCommand.config !== null\n\t\t\t? (versionOneCreateCommand.config as Record<string, unknown>)\n\t\t\t: undefined;\n\tconst sessionDir =\n\t\tdescriptor.sessionDir ??\n\t\t(typeof versionOneConfig?.sessionDir === \"string\" ? versionOneConfig.sessionDir : undefined);\n\treturn {\n\t\tversion: 2,\n\t\tworkerId: descriptor.workerId,\n\t\tpid: descriptor.pid,\n\t\t...(descriptor.processStartId !== undefined ? { processStartId: descriptor.processStartId } : {}),\n\t\tsocketPath: descriptor.socketPath,\n\t\trecoveryJournalPath: descriptor.recoveryJournalPath,\n\t\t...(descriptor.orphanProcessJournalPath !== undefined\n\t\t\t? { orphanProcessJournalPath: descriptor.orphanProcessJournalPath }\n\t\t\t: {}),\n\t\tsupervisorSocketPath: descriptor.supervisorSocketPath,\n\t\tauthenticationToken: descriptor.authenticationToken,\n\t\t...(descriptor.workerInstanceId !== undefined ? { workerInstanceId: descriptor.workerInstanceId } : {}),\n\t\trootActiveSessionId: descriptor.rootActiveSessionId,\n\t\t...(descriptor.ownerClientId !== undefined ? { ownerClientId: descriptor.ownerClientId } : {}),\n\t\t...(descriptor.rootSessionId !== undefined ? { rootSessionId: descriptor.rootSessionId } : {}),\n\t\t...(descriptor.sessionFile !== undefined ? { sessionFile: descriptor.sessionFile } : {}),\n\t\t...(sessionDir !== undefined ? { sessionDir } : {}),\n\t\t...(descriptor.rlmLedgerSessionDir !== undefined ? { rlmLedgerSessionDir: descriptor.rlmLedgerSessionDir } : {}),\n\t\tcreatedAt: descriptor.createdAt,\n\t\tupdatedAt: descriptor.updatedAt,\n\t\tlifecycle: descriptor.lifecycle,\n\t\tcreateCommand: durableDaemonCreateCommand(descriptor.createCommand),\n\t\tconsecutiveFailures: descriptor.consecutiveFailures,\n\t\t...(descriptor.stopRequestedAt !== undefined ? { stopRequestedAt: descriptor.stopRequestedAt } : {}),\n\t\t...(descriptor.archiveOnStop !== undefined ? { archiveOnStop: descriptor.archiveOnStop } : {}),\n\t\t...(descriptor.lastFailureAt !== undefined ? { lastFailureAt: descriptor.lastFailureAt } : {}),\n\t\t...(descriptor.lifecycle === \"failed\" ? { lastError: \"Waiting for a client with fresh runtime context\" } : {}),\n\t};\n}\n\nexport function isDaemonWorkerProcess(environment: NodeJS.ProcessEnv = process.env): boolean {\n\treturn environment[DAEMON_WORKER_ROLE_ENV] === \"1\";\n}\n\nexport function waitForDaemonWorkerStartupGate(environment: NodeJS.ProcessEnv = process.env): void {\n\tconst rawFd = environment[DAEMON_WORKER_STARTUP_GATE_FD_ENV];\n\tif (rawFd === undefined) {\n\t\treturn;\n\t}\n\tdelete environment[DAEMON_WORKER_STARTUP_GATE_FD_ENV];\n\tconst fd = Number(rawFd);\n\tif (!Number.isInteger(fd) || fd < 3) {\n\t\tthrow new Error(\"Daemon session worker has an invalid startup gate\");\n\t}\n\tlet marker: string;\n\ttry {\n\t\tmarker = readFileSync(fd, \"utf8\");\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\tif (marker !== DAEMON_WORKER_STARTUP_GATE_COMMIT) {\n\t\tthrow new Error(\"Daemon session worker startup was cancelled\");\n\t}\n}\n\nexport function daemonWorkerInstanceId(environment: NodeJS.ProcessEnv = process.env): string | undefined {\n\treturn environment[DAEMON_WORKER_INSTANCE_ID_ENV] || undefined;\n}\n\nexport function requireDaemonWorkerAuthenticationToken(environment: NodeJS.ProcessEnv = process.env): string {\n\tconst token = environment[DAEMON_WORKER_TOKEN_ENV];\n\tif (!token) {\n\t\tthrow new Error(\"Daemon session worker is missing its authentication token\");\n\t}\n\treturn token;\n}\n\nexport function isDaemonWorkerFrameHeader(value: unknown): value is DaemonWorkerFrameHeader {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst candidate = value as Record<string, unknown>;\n\tif (candidate.kind === \"command\") {\n\t\treturn typeof candidate.requestId === \"string\" && typeof candidate.commandType === \"string\";\n\t}\n\treturn (\n\t\tcandidate.kind === \"outbound\" &&\n\t\ttypeof candidate.outboundType === \"string\" &&\n\t\t(candidate.requestId === undefined || typeof candidate.requestId === \"string\") &&\n\t\t(candidate.activeSessionId === undefined || typeof candidate.activeSessionId === \"string\") &&\n\t\t(candidate.snapshotId === undefined || typeof candidate.snapshotId === \"string\") &&\n\t\t(candidate.sessionEventType === undefined || typeof candidate.sessionEventType === \"string\") &&\n\t\t(candidate.snapshotPurpose === undefined ||\n\t\t\tcandidate.snapshotPurpose === \"attach\" ||\n\t\t\tcandidate.snapshotPurpose === \"replacement\" ||\n\t\t\tcandidate.snapshotPurpose === \"catchup\") &&\n\t\t(candidate.payloadEncoding === undefined ||\n\t\t\tcandidate.payloadEncoding === \"jsonl\" ||\n\t\t\tcandidate.payloadEncoding === \"assistant-delta\")\n\t);\n}\n"]}
@@ -320,6 +320,8 @@ export declare class InteractiveMode {
320
320
  private refreshHeartbeatCatalog;
321
321
  private applyHeartbeatCatalog;
322
322
  private getScopedHeartbeats;
323
+ private captureConnectionStateRead;
324
+ private isConnectionStateReadCurrent;
323
325
  private applyConnectionStateSnapshot;
324
326
  private patchConnectionState;
325
327
  private applyOptimisticContextUsage;