@ponythewhite/base-context 1.0.9 → 1.0.11

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 (80) hide show
  1. package/CHANGELOG.md +19 -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/{bundled-modules-5JRM6P4T.js → bundled-modules-PEFT72QN.js} +2 -2
  6. package/dist/bundle/{chunk-VVI3UKGR.js → chunk-JZHGOOFM.js} +87 -57
  7. package/dist/bundle/{chunk-NEHLB7JV.js → chunk-TOOVREMP.js} +596 -102
  8. package/dist/bundle/{cli-main-YUDBEYE2.js → cli-main-BRXGYTGK.js} +2 -2
  9. package/dist/bundle/cli.js +1 -1
  10. package/dist/bundle/{main-ZLGGAAGU.js → main-POUXGEL6.js} +2 -2
  11. package/dist/core/agent-session.d.ts +0 -1
  12. package/dist/core/agent-session.d.ts.map +1 -1
  13. package/dist/core/agent-session.js +85 -45
  14. package/dist/core/agent-session.js.map +1 -1
  15. package/dist/core/canonical-context.d.ts +19 -3
  16. package/dist/core/canonical-context.d.ts.map +1 -1
  17. package/dist/core/canonical-context.js +245 -39
  18. package/dist/core/canonical-context.js.map +1 -1
  19. package/dist/core/context-epoch-copy.d.ts +1 -1
  20. package/dist/core/context-epoch-copy.d.ts.map +1 -1
  21. package/dist/core/context-epoch-copy.js +18 -7
  22. package/dist/core/context-epoch-copy.js.map +1 -1
  23. package/dist/core/context-epoch.d.ts +18 -3
  24. package/dist/core/context-epoch.d.ts.map +1 -1
  25. package/dist/core/context-epoch.js +13 -2
  26. package/dist/core/context-epoch.js.map +1 -1
  27. package/dist/core/context-tree.d.ts +1 -1
  28. package/dist/core/context-tree.d.ts.map +1 -1
  29. package/dist/core/context-tree.js +98 -8
  30. package/dist/core/context-tree.js.map +1 -1
  31. package/dist/core/history-index-worker.d.ts.map +1 -1
  32. package/dist/core/history-index-worker.js +59 -6
  33. package/dist/core/history-index-worker.js.map +1 -1
  34. package/dist/core/history-index.d.ts +17 -0
  35. package/dist/core/history-index.d.ts.map +1 -1
  36. package/dist/core/history-index.js +22 -0
  37. package/dist/core/history-index.js.map +1 -1
  38. package/dist/core/inference-coordinator.d.ts.map +1 -1
  39. package/dist/core/inference-coordinator.js +5 -1
  40. package/dist/core/inference-coordinator.js.map +1 -1
  41. package/dist/core/public-context.d.ts.map +1 -1
  42. package/dist/core/public-context.js +20 -8
  43. package/dist/core/public-context.js.map +1 -1
  44. package/dist/core/request-view-selection.d.ts +2 -1
  45. package/dist/core/request-view-selection.d.ts.map +1 -1
  46. package/dist/core/request-view-selection.js +29 -2
  47. package/dist/core/request-view-selection.js.map +1 -1
  48. package/dist/core/session-fork-messages.d.ts +5 -0
  49. package/dist/core/session-fork-messages.d.ts.map +1 -1
  50. package/dist/core/session-fork-messages.js +44 -0
  51. package/dist/core/session-fork-messages.js.map +1 -1
  52. package/dist/core/session-history-index.d.ts +5 -0
  53. package/dist/core/session-history-index.d.ts.map +1 -1
  54. package/dist/core/session-history-index.js +7 -0
  55. package/dist/core/session-history-index.js.map +1 -1
  56. package/dist/core/session-manager.d.ts +2 -0
  57. package/dist/core/session-manager.d.ts.map +1 -1
  58. package/dist/core/session-manager.js +155 -13
  59. package/dist/core/session-manager.js.map +1 -1
  60. package/dist/core/session-tree.d.ts +9 -0
  61. package/dist/core/session-tree.d.ts.map +1 -1
  62. package/dist/core/session-tree.js +71 -11
  63. package/dist/core/session-tree.js.map +1 -1
  64. package/dist/modes/agent-connection/in-process-agent-connection.d.ts.map +1 -1
  65. package/dist/modes/agent-connection/in-process-agent-connection.js +4 -4
  66. package/dist/modes/agent-connection/in-process-agent-connection.js.map +1 -1
  67. package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
  68. package/dist/modes/daemon/daemon-mode.js +19 -34
  69. package/dist/modes/daemon/daemon-mode.js.map +1 -1
  70. package/dist/modes/daemon/daemon-socket.d.ts +5 -0
  71. package/dist/modes/daemon/daemon-socket.d.ts.map +1 -1
  72. package/dist/modes/daemon/daemon-socket.js +19 -0
  73. package/dist/modes/daemon/daemon-socket.js.map +1 -1
  74. package/dist/modes/daemon/daemon-supervisor.d.ts.map +1 -1
  75. package/dist/modes/daemon/daemon-supervisor.js +6 -7
  76. package/dist/modes/daemon/daemon-supervisor.js.map +1 -1
  77. package/dist/modes/daemon/daemon-worker-client.d.ts.map +1 -1
  78. package/dist/modes/daemon/daemon-worker-client.js +5 -5
  79. package/dist/modes/daemon/daemon-worker-client.js.map +1 -1
  80. package/package.json +4 -4
@@ -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\ttry {\n\t\t\tawait this.channel.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} catch (error) {\n\t\t\tconst pending = this.pending.get(id);\n\t\t\tif (pending) {\n\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\tthis.pending.delete(id);\n\t\t\t\tpending.reject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t}\n\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":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAwB,MAAM,sCAAsC,CAAC;AAC/F,OAAO,EAEN,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAE/B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAMN,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAI3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGN,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAE5B,MAAM,6BAA6B,CAAC;AAErC,KAAK,gBAAgB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,SAAS,OAAO,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;AACrF,KAAK,iBAAiB,GAAG,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAG/D,KAAK,0BAA0B,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAEvH,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,uBAAuB,CAAC,KAAK,IAAI,CAAC;AAC/F,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAC/D,KAAK,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC,CAAC;AAErE,qBAAa,+BAAgC,SAAQ,KAAK;CAAG;AAE7D,mFAAmF;AACnF,qBAAa,8BAA+B,SAAQ,KAAK;IACxD,YAAY,KAAK,EAAE,WAAW,EAK7B;CACD;AAED,2GAA2G;AAC3G,qBAAa,6BAA8B,SAAQ,KAAK;CAAG;AAE3D,qBAAa,kBAAkB;IAyBlB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAxBvC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAgD;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0C;IAC3E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAOpB;IACJ,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,kBAAkB,CAAC,CAAiC;IAC5D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAIxB;IAEL,YAA6B,UAAU,EAAE,MAAM,EAAI;IAEnD,IAAI,KAAK,IAAI,WAAW,GAAG,SAAS,CAEnC;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,wBAAwB,CAAC,UAAU,EAAE,sBAAsB,GAAG,OAAO,CAEpE;IAEK,OAAO,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC7C;IAED,YAAY,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAmBnD;IAED,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAGvD;IAED,SAAS,CAAC,QAAQ,EAAE,2BAA2B,GAAG,MAAM,IAAI,CAG3D;IAED,OAAO,CAAC,QAAQ,EAAE,yBAAyB,GAAG,MAAM,IAAI,CAGvD;IAEK,OAAO,CACZ,OAAO,EAAE,iBAAiB,EAC1B,SAAS,SAAS,EAElB,QAAQ,GAAE,0BAA+B,GACvC,OAAO,CAAC,cAAc,CAAC,CAOzB;IAEK,aAAa,CAAC,OAAO,EAAE,uBAAuB,EAAE,SAAS,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CASjG;YAEa,kBAAkB;IAO1B,kBAAkB,CACvB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,0BAA0B,EACjC,SAAS,SAAO,GACd,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE;QAAE,OAAO,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC,CAMrD;IAEK,gBAAgB,CAAC,MAAM,EAAE,yBAAyB,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBzF;IAED,KAAK,IAAI,IAAI,CAQZ;YAEa,WAAW;IAgCzB,OAAO,CAAC,WAAW;IAyDnB,2HAA2H;IAC3H,OAAO,CAAC,kBAAkB;IA6B1B,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,YAAY;CAapB","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"]}
@@ -176,17 +176,17 @@ export class DaemonWorkerClient {
176
176
  }, timeoutMs);
177
177
  this.pending.set(id, { resolve, reject, timeout });
178
178
  });
179
- try {
180
- await this.channel.send({ kind: "command", requestId: id, commandType: command.type }, Buffer.from(serializeJsonLine(fullCommand)));
181
- }
182
- catch (error) {
179
+ // A blocked socket write must not postpone the response timeout or connection-close rejection.
180
+ void this.channel
181
+ .send({ kind: "command", requestId: id, commandType: command.type }, Buffer.from(serializeJsonLine(fullCommand)))
182
+ .catch((error) => {
183
183
  const pending = this.pending.get(id);
184
184
  if (pending) {
185
185
  clearTimeout(pending.timeout);
186
186
  this.pending.delete(id);
187
187
  pending.reject(error instanceof Error ? error : new Error(String(error)));
188
188
  }
189
- }
189
+ });
190
190
  return response;
191
191
  }
192
192
  handleFrame(frame) {
@@ -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\ttry {\n\t\t\tawait this.channel.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} catch (error) {\n\t\t\tconst pending = this.pending.get(id);\n\t\t\tif (pending) {\n\t\t\t\tclearTimeout(pending.timeout);\n\t\t\t\tthis.pending.delete(id);\n\t\t\t\tpending.reject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t}\n\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\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ponythewhite/base-context",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Synerise base-context: a coding and research agent with durable context and a persistent Python REPL",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,9 +42,9 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@agentclientprotocol/sdk": "^1.3.0",
45
- "@ponythewhite/base-context-agent": "1.0.9",
46
- "@ponythewhite/base-context-ai": "1.0.9",
47
- "@ponythewhite/base-context-tui": "1.0.9",
45
+ "@ponythewhite/base-context-agent": "1.0.11",
46
+ "@ponythewhite/base-context-ai": "1.0.11",
47
+ "@ponythewhite/base-context-tui": "1.0.11",
48
48
  "@silvia-odwyer/photon-node": "^0.3.4",
49
49
  "chalk": "^5.5.0",
50
50
  "cli-highlight": "^2.1.11",