@code-yeongyu/senpi 2026.9.28-2 → 2026.9.28-3

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 (72) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/bundle/chunks/{app-server-command-H6LFICZ2.js → app-server-command-JTHJ2U7J.js} +1 -1
  3. package/dist/bundle/chunks/{chunk-LSW7QSLV.js → chunk-6XBT6OGS.js} +36 -34
  4. package/dist/bundle/chunks/chunk-OP3QMR6B.js +8 -0
  5. package/dist/bundle/chunks/{cli-main-GYRTYPMG.js → cli-main-Z2Y55XHU.js} +1 -1
  6. package/dist/bundle/chunks/{interactive-mode-LX665HTP.js → interactive-mode-A3EYB6DW.js} +1 -1
  7. package/dist/bundle/chunks/{multi-session-host-MFTUM6XQ.js → multi-session-host-HM2UJ4ER.js} +2 -2
  8. package/dist/bundle/chunks/{package-manager-cli-6IAE5WG3.js → package-manager-cli-T7Q4AZKX.js} +1 -1
  9. package/dist/bundle/chunks/{rpc-mode-XN3HNZMH.js → rpc-mode-ROB6IG6J.js} +1 -1
  10. package/dist/bundle/chunks/session-worker.js +140 -138
  11. package/dist/bundle/cli.js +1 -1
  12. package/dist/bundle/index.js +1 -1
  13. package/dist/bundle/rpc-entry.js +1 -1
  14. package/dist/core/webview/bun-chrome.d.ts +15 -0
  15. package/dist/core/webview/bun-chrome.d.ts.map +1 -0
  16. package/dist/core/webview/bun-chrome.js +91 -0
  17. package/dist/core/webview/bun-chrome.js.map +1 -0
  18. package/dist/core/webview/native-webview.d.ts +16 -0
  19. package/dist/core/webview/native-webview.d.ts.map +1 -0
  20. package/dist/core/webview/native-webview.js +15 -0
  21. package/dist/core/webview/native-webview.js.map +1 -0
  22. package/dist/core/webview/webview-broker.d.ts +27 -0
  23. package/dist/core/webview/webview-broker.d.ts.map +1 -0
  24. package/dist/core/webview/webview-broker.js +120 -0
  25. package/dist/core/webview/webview-broker.js.map +1 -0
  26. package/dist/core/webview/webview-client.d.ts +19 -0
  27. package/dist/core/webview/webview-client.d.ts.map +1 -0
  28. package/dist/core/webview/webview-client.js +135 -0
  29. package/dist/core/webview/webview-client.js.map +1 -0
  30. package/dist/core/webview/webview-service.d.ts +26 -0
  31. package/dist/core/webview/webview-service.d.ts.map +1 -0
  32. package/dist/core/webview/webview-service.js +102 -0
  33. package/dist/core/webview/webview-service.js.map +1 -0
  34. package/dist/core/webview/webview-wire.d.ts +76 -0
  35. package/dist/core/webview/webview-wire.d.ts.map +1 -0
  36. package/dist/core/webview/webview-wire.js +57 -0
  37. package/dist/core/webview/webview-wire.js.map +1 -0
  38. package/dist/index.d.ts +1 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +2 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/modes/rpc/session-worker-client.d.ts +2 -0
  43. package/dist/modes/rpc/session-worker-client.d.ts.map +1 -1
  44. package/dist/modes/rpc/session-worker-client.js +7 -1
  45. package/dist/modes/rpc/session-worker-client.js.map +1 -1
  46. package/dist/modes/rpc/session-worker.js +3 -1
  47. package/dist/modes/rpc/session-worker.js.map +1 -1
  48. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +14 -0
  49. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  50. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +14 -0
  51. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +2 -1
  52. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/local-module-loader.ts +2 -0
  53. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/webview-host.ts +59 -0
  54. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +17 -0
  55. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-host.ts +2 -1
  56. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +2 -1
  57. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-slot.ts +14 -5
  58. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-webview-client.js +79 -0
  59. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-webview.js +204 -0
  60. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +2 -0
  61. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/runtime-apis.md +1 -0
  62. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  63. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  64. package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -1
  65. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  66. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  67. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  68. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  69. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  70. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  71. package/package.json +7 -7
  72. package/dist/bundle/chunks/chunk-KOPTADA3.js +0 -8
@@ -1 +1 @@
1
- {"version":3,"file":"session-worker-client.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { Worker } from \"node:worker_threads\";\nimport { isBunBinary } from \"../../config.ts\";\nimport type { CliRuntimeConfiguration } from \"../../main.ts\";\nimport type { RpcConnectionOptions } from \"./connection-handler.ts\";\nimport type { RpcSessionBinding } from \"./session-binding.ts\";\nimport type { SessionEventWriter } from \"./session-event-writer.ts\";\nimport type { RpcSessionLaunchProfile } from \"./session-registry.ts\";\nimport type {\n\tHostToSessionWorker,\n\tSessionWorkerToHost,\n\tSessionWriteGrant,\n\tWorkerDisplay,\n\tWorkerSnapshot,\n} from \"./session-worker-protocol.ts\";\n\nimport { SessionWorkerRequests, type WorkerRequestInput } from \"./session-worker-requests.ts\";\nimport { acknowledge, acknowledgeGrant, respondDisplay } from \"./session-worker-signals.ts\";\n\n/** Lifecycle hooks the owning registry installs on every worker it allocates. */\nexport interface SessionWorkerCallbacks {\n\treserve: (path: string) => SessionWriteGrant;\n\t/** Every snapshot republishes which paths this worker still writes. */\n\treconcile: (livePaths: readonly string[]) => void;\n\texit: () => void;\n\tfailure: (error: string) => void;\n}\n\n/** Bun wrapper builders define the worker entry name relative to their explicit --root. */\ndeclare const SENPI_RPC_SESSION_WORKER_ENTRY: string | undefined;\nconst compiledWorkerEntry =\n\ttypeof SENPI_RPC_SESSION_WORKER_ENTRY === \"string\"\n\t\t? SENPI_RPC_SESSION_WORKER_ENTRY\n\t\t: \"./src/modes/rpc/session-worker.ts\";\n\nexport class SessionWorkerClient {\n\treadonly worker = new Worker(\n\t\tisBunBinary\n\t\t\t? fileURLToPath(new URL(compiledWorkerEntry, import.meta.url)).replaceAll(\"\\\\\", \"/\")\n\t\t\t: new URL(import.meta.url.endsWith(\".ts\") ? \"./session-worker.ts\" : \"./session-worker.js\", import.meta.url),\n\t);\n\treadonly exited: Promise<void>;\n\tsnapshot?: WorkerSnapshot;\n\t/** Main marks this only after installing the unique routing binding. */\n\tbindingReady = false;\n\tprivate readonly requests = new SessionWorkerRequests(\n\t\t(message) => this.worker.postMessage(message),\n\t\t() => this.fail(\"session_worker_request_timeout\"),\n\t);\n\tprivate stopped = false;\n\tprivate displayRevision = 0;\n\tprivate closeTimer?: ReturnType<typeof setTimeout>;\n\tprivate writer?: SessionEventWriter;\n\tprivate sessionId?: string;\n\tprivate requestClose?: () => void;\n\tprivate options: Pick<RpcConnectionOptions, \"capabilities\" | \"sharedWidth\"> = {};\n\tprivate readonly listeners = new Set<() => void>();\n\tprivate readonly controls = new Set<\"display\" | \"cancel_ui\">();\n\tprivate latestDisplay?: Extract<HostToSessionWorker, { type: \"display\" }>;\n\tprivate terminalFailure?: string;\n\n\tprivate readonly callbacks: SessionWorkerCallbacks;\n\n\tconstructor(callbacks: SessionWorkerCallbacks) {\n\t\tthis.callbacks = callbacks;\n\t\tthis.exited = new Promise((resolve) => {\n\t\t\tthis.worker.once(\"exit\", () => {\n\t\t\t\tif (!this.stopped && !this.closeTimer) this.fail(\"session_worker_exited\");\n\t\t\t\tthis.stopped = true;\n\t\t\t\tif (this.closeTimer) clearTimeout(this.closeTimer);\n\t\t\t\tthis.requests.close(new Error(\"session_worker_exited\"));\n\t\t\t\tthis.listeners.clear();\n\t\t\t\tcallbacks.exit();\n\t\t\t\tthis.publishTerminalFailure();\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t\tthis.worker.on(\"message\", (message: SessionWorkerToHost) => this.receive(message));\n\t\tthis.worker.on(\"error\", (error: unknown) => this.fail(error instanceof Error ? error.message : String(error)));\n\t}\n\n\tasync prepare(configuration: CliRuntimeConfiguration, profile: RpcSessionLaunchProfile): Promise<string> {\n\t\tconst result = await this.request({ type: \"prepare\", configuration, profile });\n\t\tif (result.type !== \"prepared\") throw new Error(\"Invalid worker prepare response\");\n\t\treturn result.sessionPath;\n\t}\n\n\tasync commit(): Promise<WorkerSnapshot> {\n\t\tconst result = await this.request({ type: \"commit\" });\n\t\tif (result.type !== \"ready\") throw new Error(\"Invalid worker commit response\");\n\t\tthis.snapshot = result.snapshot;\n\t\treturn result.snapshot;\n\t}\n\n\tasync bind(\n\t\tsessionId: string,\n\t\twriter: SessionEventWriter,\n\t\trequestClose: () => void,\n\t\toptions: Pick<RpcConnectionOptions, \"capabilities\" | \"sharedWidth\">,\n\t): Promise<RpcSessionBinding> {\n\t\tthis.sessionId = sessionId;\n\t\tthis.writer = writer;\n\t\tthis.requestClose = requestClose;\n\t\tthis.options = options;\n\t\tawait this.request({ type: \"bind\", sessionId, display: this.display(), connection: writer.currentConnection() });\n\t\treturn {\n\t\t\thandle: async (command) => {\n\t\t\t\tawait this.request({\n\t\t\t\t\ttype: \"command\",\n\t\t\t\t\tcommand,\n\t\t\t\t\tconnection: writer.currentConnection(),\n\t\t\t\t\tdisplay: this.display(),\n\t\t\t\t});\n\t\t\t},\n\t\t\tcancelPendingExtensionUiRequests: () => this.post({ type: \"cancel_ui\" }),\n\t\t\trerenderComponents: () => this.post({ type: \"display\", display: this.display() }),\n\t\t\tdispose: async () => {\n\t\t\t\tthis.post({ type: \"cancel_ui\" });\n\t\t\t},\n\t\t};\n\t}\n\n\tget busy(): boolean {\n\t\treturn this.requests.activeCount > 0 || this.snapshot?.busy === true;\n\t}\n\n\tget handoffBusy(): boolean {\n\t\treturn this.requests.activeCount > 0 || (this.snapshot?.handoffBusy ?? this.snapshot?.busy) === true;\n\t}\n\n\tsubscribeSettled(listener: () => void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\t/** Deadline requests termination, but only the actual exit callback releases ownership. */\n\tclose(graceMs: number): Promise<void> {\n\t\tif (this.stopped || this.closeTimer) return this.exited;\n\t\tthis.post({ type: \"close\" });\n\t\tthis.closeTimer = setTimeout(() => this.quarantine(), graceMs);\n\t\treturn this.exited;\n\t}\n\n\tquarantine(): void {\n\t\tthis.stopped = true;\n\t\tthis.requests.close(new Error(\"session_closing\"));\n\t\tvoid this.worker.terminate();\n\t}\n\n\tprivate display(): WorkerDisplay {\n\t\treturn {\n\t\t\trevision: ++this.displayRevision,\n\t\t\twidth: this.options.sharedWidth?.getWidth() ?? 80,\n\t\t\trendered: this.options.sharedWidth?.hasRenderedComponents?.(this.sessionId ?? \"\") ?? false,\n\t\t\tcapabilities: this.options.capabilities ?? [],\n\t\t};\n\t}\n\n\tprivate request(message: WorkerRequestInput): ReturnType<SessionWorkerRequests[\"request\"]> {\n\t\treturn this.requests.request(message);\n\t}\n\n\tprivate post(message: HostToSessionWorker): void {\n\t\tif (this.stopped) return;\n\t\tif (message.type === \"display\" || message.type === \"cancel_ui\") {\n\t\t\tif (this.controls.has(message.type)) {\n\t\t\t\tif (message.type === \"display\") this.latestDisplay = message;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.controls.add(message.type);\n\t\t}\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tprivate receive(message: SessionWorkerToHost): void {\n\t\tif (this.stopped) {\n\t\t\tif (\"signal\" in message) acknowledge(message.signal, false);\n\t\t\treturn;\n\t\t}\n\t\tswitch (message.type) {\n\t\t\tcase \"prepared\":\n\t\t\tcase \"ready\":\n\t\t\tcase \"result\": {\n\t\t\t\tthis.requests.receive(message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"reserve\":\n\t\t\t\tacknowledgeGrant(message.signal, this.callbacks.reserve(message.path));\n\t\t\t\treturn;\n\t\t\tcase \"snapshot\":\n\t\t\t\tthis.snapshot = message.snapshot;\n\t\t\t\tthis.callbacks.reconcile(message.snapshot.liveSessionPaths);\n\t\t\t\tacknowledge(message.signal, true);\n\t\t\t\tif (message.settled) for (const listener of [...this.listeners]) listener();\n\t\t\t\treturn;\n\t\t\tcase \"control_done\": {\n\t\t\t\tthis.controls.delete(message.control);\n\t\t\t\tif (message.control === \"display\" && this.latestDisplay) {\n\t\t\t\t\tconst latest = this.latestDisplay;\n\t\t\t\t\tthis.latestDisplay = undefined;\n\t\t\t\t\tthis.post(latest);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"output\": {\n\t\t\t\tconst writer = this.writer;\n\t\t\t\tconst sessionId = this.sessionId;\n\t\t\t\tif (!writer || !sessionId || this.stopped) {\n\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Identity and activity commit before publication; clients may attach or disconnect on that event.\n\t\t\t\tif (message.snapshot) {\n\t\t\t\t\tthis.snapshot = message.snapshot;\n\t\t\t\t\tthis.callbacks.reconcile(message.snapshot.liveSessionPaths);\n\t\t\t\t} else if (this.snapshot)\n\t\t\t\t\tthis.snapshot = {\n\t\t\t\t\t\t...this.snapshot,\n\t\t\t\t\t\t...message.activity,\n\t\t\t\t\t\tstate: { ...this.snapshot.state, isStreaming: message.activity.streaming },\n\t\t\t\t\t};\n\t\t\t\tconst enqueue = () => {\n\t\t\t\t\tif (!writer.enqueue(sessionId, message.record)) {\n\t\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\t\tthis.fail(\"session_output_overflow_or_closed\");\n\t\t\t\t\t\treturn Promise.reject(new Error(\"session_output_overflow_or_closed\"));\n\t\t\t\t\t}\n\t\t\t\t\treturn writer.waitForSessionBackpressure(sessionId);\n\t\t\t\t};\n\t\t\t\tconst consumed =\n\t\t\t\t\tmessage.connection === undefined ? enqueue() : writer.withConnection(message.connection, enqueue);\n\t\t\t\tvoid consumed.then(\n\t\t\t\t\t() => acknowledge(message.signal, true),\n\t\t\t\t\t(cause: unknown) => {\n\t\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\t\tthis.fail(cause instanceof Error ? cause.message : String(cause));\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"width\":\n\t\t\t\tthis.options.sharedWidth?.setWidth(message.connection, message.width);\n\t\t\t\tthis.options.sharedWidth?.onChange?.();\n\t\t\t\trespondDisplay(message.signal, this.display());\n\t\t\t\treturn;\n\t\t\tcase \"capabilities\":\n\t\t\t\tthis.options.sharedWidth?.setCapabilities?.(message.connection, message.capabilities);\n\t\t\t\trespondDisplay(message.signal, this.display());\n\t\t\t\treturn;\n\t\t\tcase \"request_close\":\n\t\t\t\tthis.requestClose?.();\n\t\t\t\treturn;\n\t\t\tcase \"failure\":\n\t\t\t\tthis.fail(message.error);\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate fail(error: string): void {\n\t\tif (this.stopped) return;\n\t\tthis.callbacks.failure(error);\n\t\tthis.terminalFailure = error;\n\t\tif (this.writer && this.sessionId) {\n\t\t\tthis.writer.enqueue(this.sessionId, { type: \"session_error\", error });\n\t\t}\n\t\tthis.quarantine();\n\t}\n\n\t/** Terminal close records observe completed registry removal, including worker failure. */\n\tprivate publishTerminalFailure(): void {\n\t\tconst error = this.terminalFailure;\n\t\tconst writer = this.writer;\n\t\tconst sessionId = this.sessionId;\n\t\tif (error === undefined || !writer || !sessionId) return;\n\t\tthis.terminalFailure = undefined;\n\t\twriter.closeSession(\n\t\t\tsessionId,\n\t\t\t{\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"close_session\",\n\t\t\t\tsuccess: false,\n\t\t\t\terror,\n\t\t\t},\n\t\t\t\"error\",\n\t\t);\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-worker-client.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { Worker } from \"node:worker_threads\";\nimport { isBunBinary } from \"../../config.ts\";\nimport { createWebViewBroker } from \"../../core/webview/webview-broker.ts\";\nimport type { CliRuntimeConfiguration } from \"../../main.ts\";\nimport type { RpcConnectionOptions } from \"./connection-handler.ts\";\nimport type { RpcSessionBinding } from \"./session-binding.ts\";\nimport type { SessionEventWriter } from \"./session-event-writer.ts\";\nimport type { RpcSessionLaunchProfile } from \"./session-registry.ts\";\nimport type {\n\tHostToSessionWorker,\n\tSessionWorkerToHost,\n\tSessionWriteGrant,\n\tWorkerDisplay,\n\tWorkerSnapshot,\n} from \"./session-worker-protocol.ts\";\n\nimport { SessionWorkerRequests, type WorkerRequestInput } from \"./session-worker-requests.ts\";\nimport { acknowledge, acknowledgeGrant, respondDisplay } from \"./session-worker-signals.ts\";\n\n/** Lifecycle hooks the owning registry installs on every worker it allocates. */\nexport interface SessionWorkerCallbacks {\n\treserve: (path: string) => SessionWriteGrant;\n\t/** Every snapshot republishes which paths this worker still writes. */\n\treconcile: (livePaths: readonly string[]) => void;\n\texit: () => void;\n\tfailure: (error: string) => void;\n}\n\n/** Bun wrapper builders define the worker entry name relative to their explicit --root. */\ndeclare const SENPI_RPC_SESSION_WORKER_ENTRY: string | undefined;\nconst compiledWorkerEntry =\n\ttypeof SENPI_RPC_SESSION_WORKER_ENTRY === \"string\"\n\t\t? SENPI_RPC_SESSION_WORKER_ENTRY\n\t\t: \"./src/modes/rpc/session-worker.ts\";\n\nexport class SessionWorkerClient {\n\t/** The worker's own route to the main-thread Bun.WebView service; released when the worker exits. */\n\tprivate readonly webviewBroker = createWebViewBroker();\n\treadonly worker = new Worker(\n\t\tisBunBinary\n\t\t\t? fileURLToPath(new URL(compiledWorkerEntry, import.meta.url)).replaceAll(\"\\\\\", \"/\")\n\t\t\t: new URL(import.meta.url.endsWith(\".ts\") ? \"./session-worker.ts\" : \"./session-worker.js\", import.meta.url),\n\t\tthis.webviewBroker\n\t\t\t? { workerData: { webviewBroker: this.webviewBroker.port }, transferList: [this.webviewBroker.port] }\n\t\t\t: {},\n\t);\n\treadonly exited: Promise<void>;\n\tsnapshot?: WorkerSnapshot;\n\t/** Main marks this only after installing the unique routing binding. */\n\tbindingReady = false;\n\tprivate readonly requests = new SessionWorkerRequests(\n\t\t(message) => this.worker.postMessage(message),\n\t\t() => this.fail(\"session_worker_request_timeout\"),\n\t);\n\tprivate stopped = false;\n\tprivate displayRevision = 0;\n\tprivate closeTimer?: ReturnType<typeof setTimeout>;\n\tprivate writer?: SessionEventWriter;\n\tprivate sessionId?: string;\n\tprivate requestClose?: () => void;\n\tprivate options: Pick<RpcConnectionOptions, \"capabilities\" | \"sharedWidth\"> = {};\n\tprivate readonly listeners = new Set<() => void>();\n\tprivate readonly controls = new Set<\"display\" | \"cancel_ui\">();\n\tprivate latestDisplay?: Extract<HostToSessionWorker, { type: \"display\" }>;\n\tprivate terminalFailure?: string;\n\n\tprivate readonly callbacks: SessionWorkerCallbacks;\n\n\tconstructor(callbacks: SessionWorkerCallbacks) {\n\t\tthis.callbacks = callbacks;\n\t\tthis.exited = new Promise((resolve) => {\n\t\t\tthis.worker.once(\"exit\", () => {\n\t\t\t\tif (!this.stopped && !this.closeTimer) this.fail(\"session_worker_exited\");\n\t\t\t\tthis.stopped = true;\n\t\t\t\tif (this.closeTimer) clearTimeout(this.closeTimer);\n\t\t\t\tthis.requests.close(new Error(\"session_worker_exited\"));\n\t\t\t\tvoid this.webviewBroker?.dispose();\n\t\t\t\tthis.listeners.clear();\n\t\t\t\tcallbacks.exit();\n\t\t\t\tthis.publishTerminalFailure();\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t\tthis.worker.on(\"message\", (message: SessionWorkerToHost) => this.receive(message));\n\t\tthis.worker.on(\"error\", (error: unknown) => this.fail(error instanceof Error ? error.message : String(error)));\n\t}\n\n\tasync prepare(configuration: CliRuntimeConfiguration, profile: RpcSessionLaunchProfile): Promise<string> {\n\t\tconst result = await this.request({ type: \"prepare\", configuration, profile });\n\t\tif (result.type !== \"prepared\") throw new Error(\"Invalid worker prepare response\");\n\t\treturn result.sessionPath;\n\t}\n\n\tasync commit(): Promise<WorkerSnapshot> {\n\t\tconst result = await this.request({ type: \"commit\" });\n\t\tif (result.type !== \"ready\") throw new Error(\"Invalid worker commit response\");\n\t\tthis.snapshot = result.snapshot;\n\t\treturn result.snapshot;\n\t}\n\n\tasync bind(\n\t\tsessionId: string,\n\t\twriter: SessionEventWriter,\n\t\trequestClose: () => void,\n\t\toptions: Pick<RpcConnectionOptions, \"capabilities\" | \"sharedWidth\">,\n\t): Promise<RpcSessionBinding> {\n\t\tthis.sessionId = sessionId;\n\t\tthis.writer = writer;\n\t\tthis.requestClose = requestClose;\n\t\tthis.options = options;\n\t\tawait this.request({ type: \"bind\", sessionId, display: this.display(), connection: writer.currentConnection() });\n\t\treturn {\n\t\t\thandle: async (command) => {\n\t\t\t\tawait this.request({\n\t\t\t\t\ttype: \"command\",\n\t\t\t\t\tcommand,\n\t\t\t\t\tconnection: writer.currentConnection(),\n\t\t\t\t\tdisplay: this.display(),\n\t\t\t\t});\n\t\t\t},\n\t\t\tcancelPendingExtensionUiRequests: () => this.post({ type: \"cancel_ui\" }),\n\t\t\trerenderComponents: () => this.post({ type: \"display\", display: this.display() }),\n\t\t\tdispose: async () => {\n\t\t\t\tthis.post({ type: \"cancel_ui\" });\n\t\t\t},\n\t\t};\n\t}\n\n\tget busy(): boolean {\n\t\treturn this.requests.activeCount > 0 || this.snapshot?.busy === true;\n\t}\n\n\tget handoffBusy(): boolean {\n\t\treturn this.requests.activeCount > 0 || (this.snapshot?.handoffBusy ?? this.snapshot?.busy) === true;\n\t}\n\n\tsubscribeSettled(listener: () => void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\t/** Deadline requests termination, but only the actual exit callback releases ownership. */\n\tclose(graceMs: number): Promise<void> {\n\t\tif (this.stopped || this.closeTimer) return this.exited;\n\t\tthis.post({ type: \"close\" });\n\t\tthis.closeTimer = setTimeout(() => this.quarantine(), graceMs);\n\t\treturn this.exited;\n\t}\n\n\tquarantine(): void {\n\t\tthis.stopped = true;\n\t\tthis.requests.close(new Error(\"session_closing\"));\n\t\tvoid this.worker.terminate();\n\t}\n\n\tprivate display(): WorkerDisplay {\n\t\treturn {\n\t\t\trevision: ++this.displayRevision,\n\t\t\twidth: this.options.sharedWidth?.getWidth() ?? 80,\n\t\t\trendered: this.options.sharedWidth?.hasRenderedComponents?.(this.sessionId ?? \"\") ?? false,\n\t\t\tcapabilities: this.options.capabilities ?? [],\n\t\t};\n\t}\n\n\tprivate request(message: WorkerRequestInput): ReturnType<SessionWorkerRequests[\"request\"]> {\n\t\treturn this.requests.request(message);\n\t}\n\n\tprivate post(message: HostToSessionWorker): void {\n\t\tif (this.stopped) return;\n\t\tif (message.type === \"display\" || message.type === \"cancel_ui\") {\n\t\t\tif (this.controls.has(message.type)) {\n\t\t\t\tif (message.type === \"display\") this.latestDisplay = message;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.controls.add(message.type);\n\t\t}\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tprivate receive(message: SessionWorkerToHost): void {\n\t\tif (this.stopped) {\n\t\t\tif (\"signal\" in message) acknowledge(message.signal, false);\n\t\t\treturn;\n\t\t}\n\t\tswitch (message.type) {\n\t\t\tcase \"prepared\":\n\t\t\tcase \"ready\":\n\t\t\tcase \"result\": {\n\t\t\t\tthis.requests.receive(message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"reserve\":\n\t\t\t\tacknowledgeGrant(message.signal, this.callbacks.reserve(message.path));\n\t\t\t\treturn;\n\t\t\tcase \"snapshot\":\n\t\t\t\tthis.snapshot = message.snapshot;\n\t\t\t\tthis.callbacks.reconcile(message.snapshot.liveSessionPaths);\n\t\t\t\tacknowledge(message.signal, true);\n\t\t\t\tif (message.settled) for (const listener of [...this.listeners]) listener();\n\t\t\t\treturn;\n\t\t\tcase \"control_done\": {\n\t\t\t\tthis.controls.delete(message.control);\n\t\t\t\tif (message.control === \"display\" && this.latestDisplay) {\n\t\t\t\t\tconst latest = this.latestDisplay;\n\t\t\t\t\tthis.latestDisplay = undefined;\n\t\t\t\t\tthis.post(latest);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"output\": {\n\t\t\t\tconst writer = this.writer;\n\t\t\t\tconst sessionId = this.sessionId;\n\t\t\t\tif (!writer || !sessionId || this.stopped) {\n\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Identity and activity commit before publication; clients may attach or disconnect on that event.\n\t\t\t\tif (message.snapshot) {\n\t\t\t\t\tthis.snapshot = message.snapshot;\n\t\t\t\t\tthis.callbacks.reconcile(message.snapshot.liveSessionPaths);\n\t\t\t\t} else if (this.snapshot)\n\t\t\t\t\tthis.snapshot = {\n\t\t\t\t\t\t...this.snapshot,\n\t\t\t\t\t\t...message.activity,\n\t\t\t\t\t\tstate: { ...this.snapshot.state, isStreaming: message.activity.streaming },\n\t\t\t\t\t};\n\t\t\t\tconst enqueue = () => {\n\t\t\t\t\tif (!writer.enqueue(sessionId, message.record)) {\n\t\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\t\tthis.fail(\"session_output_overflow_or_closed\");\n\t\t\t\t\t\treturn Promise.reject(new Error(\"session_output_overflow_or_closed\"));\n\t\t\t\t\t}\n\t\t\t\t\treturn writer.waitForSessionBackpressure(sessionId);\n\t\t\t\t};\n\t\t\t\tconst consumed =\n\t\t\t\t\tmessage.connection === undefined ? enqueue() : writer.withConnection(message.connection, enqueue);\n\t\t\t\tvoid consumed.then(\n\t\t\t\t\t() => acknowledge(message.signal, true),\n\t\t\t\t\t(cause: unknown) => {\n\t\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\t\tthis.fail(cause instanceof Error ? cause.message : String(cause));\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"width\":\n\t\t\t\tthis.options.sharedWidth?.setWidth(message.connection, message.width);\n\t\t\t\tthis.options.sharedWidth?.onChange?.();\n\t\t\t\trespondDisplay(message.signal, this.display());\n\t\t\t\treturn;\n\t\t\tcase \"capabilities\":\n\t\t\t\tthis.options.sharedWidth?.setCapabilities?.(message.connection, message.capabilities);\n\t\t\t\trespondDisplay(message.signal, this.display());\n\t\t\t\treturn;\n\t\t\tcase \"request_close\":\n\t\t\t\tthis.requestClose?.();\n\t\t\t\treturn;\n\t\t\tcase \"failure\":\n\t\t\t\tthis.fail(message.error);\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate fail(error: string): void {\n\t\tif (this.stopped) return;\n\t\tthis.callbacks.failure(error);\n\t\tthis.terminalFailure = error;\n\t\tif (this.writer && this.sessionId) {\n\t\t\tthis.writer.enqueue(this.sessionId, { type: \"session_error\", error });\n\t\t}\n\t\tthis.quarantine();\n\t}\n\n\t/** Terminal close records observe completed registry removal, including worker failure. */\n\tprivate publishTerminalFailure(): void {\n\t\tconst error = this.terminalFailure;\n\t\tconst writer = this.writer;\n\t\tconst sessionId = this.sessionId;\n\t\tif (error === undefined || !writer || !sessionId) return;\n\t\tthis.terminalFailure = undefined;\n\t\twriter.closeSession(\n\t\t\tsessionId,\n\t\t\t{\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"close_session\",\n\t\t\t\tsuccess: false,\n\t\t\t\terror,\n\t\t\t},\n\t\t\t\"error\",\n\t\t);\n\t}\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { existsSync, realpathSync } from "node:fs";
3
3
  import { basename, dirname, join, resolve } from "node:path";
4
- import { parentPort } from "node:worker_threads";
4
+ import { parentPort, workerData } from "node:worker_threads";
5
5
  import { runWithProviderScope } from "@earendil-works/pi-ai/node/provider-scope";
6
6
  import { isBunBinary } from "../../config.js";
7
7
  import { WAKE_SOURCE_STATE_EVENT } from "../../core/extensions/builtin/monitor-state-event.js";
@@ -9,6 +9,7 @@ import { takeOverStdout } from "../../core/output-guard.js";
9
9
  import { getDefaultSessionDir } from "../../core/session-manager.js";
10
10
  import { liveSessionWritePaths } from "../../core/session-write-reservation.js";
11
11
  import { SettingsManager } from "../../core/settings-manager.js";
12
+ import { registerWebViewBroker } from "../../core/webview/webview-broker.js";
12
13
  import { createCliRuntimeFactory } from "../../main.js";
13
14
  import { initTheme } from "../interactive/theme/theme.js";
14
15
  import { buildRpcSessionState } from "./connection-handler.js";
@@ -23,6 +24,7 @@ if (isBunBinary) {
23
24
  registerBunRuntimeModules();
24
25
  }
25
26
  takeOverStdout();
27
+ registerWebViewBroker(Reflect.get(Object(workerData), "webviewBroker"));
26
28
  const port = parentPort;
27
29
  if (!port)
28
30
  throw new Error("Session worker requires a parent port");
@@ -1 +1 @@
1
- {"version":3,"file":"session-worker.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-worker.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { parentPort } from \"node:worker_threads\";\nimport { runWithProviderScope } from \"@earendil-works/pi-ai/node/provider-scope\";\nimport { isBunBinary } from \"../../config.ts\";\nimport { WAKE_SOURCE_STATE_EVENT } from \"../../core/extensions/builtin/monitor-state-event.ts\";\nimport { takeOverStdout } from \"../../core/output-guard.ts\";\nimport { getDefaultSessionDir } from \"../../core/session-manager.ts\";\nimport { liveSessionWritePaths } from \"../../core/session-write-reservation.ts\";\nimport { SettingsManager } from \"../../core/settings-manager.ts\";\nimport { createCliRuntimeFactory } from \"../../main.ts\";\nimport { initTheme } from \"../interactive/theme/theme.ts\";\nimport { buildRpcSessionState } from \"./connection-handler.ts\";\nimport { isHandoffBusy } from \"./handoff-activity.ts\";\nimport { createRpcSessionBinding, type RpcSessionBinding } from \"./session-binding.ts\";\nimport { SessionEventWriter } from \"./session-event-writer.ts\";\nimport { type RpcSessionEntry, RpcSessionRegistry } from \"./session-registry.ts\";\nimport { createWorkerCredit } from \"./session-worker-credit.ts\";\nimport {\n\ttype HostToSessionWorker,\n\tSESSION_WORKER_LIMITS,\n\ttype SessionWorkerToHost,\n\ttype WorkerDisplay,\n\ttype WorkerSnapshot,\n} from \"./session-worker-protocol.ts\";\n\nif (isBunBinary) {\n\tconst { registerBunRuntimeModules } = await import(\"../../bun/runtime-modules.ts\");\n\tregisterBunRuntimeModules();\n}\n\ntakeOverStdout();\nconst port = parentPort;\nif (!port) throw new Error(\"Session worker requires a parent port\");\nconst send = (message: SessionWorkerToHost): void => port.postMessage(message);\n\nfunction failWorker(error: string): never {\n\tsend({ type: \"failure\", error });\n\tprocess.exit(1);\n}\n\nfunction canonicalPath(path: string): string {\n\tconst absolute = resolve(path);\n\treturn existsSync(absolute) ? realpathSync(absolute) : join(realpathSync(dirname(absolute)), basename(absolute));\n}\n\nconst { exchange, installWriteReservation } = createWorkerCredit(send, failWorker);\ninstallWriteReservation(canonicalPath);\n\nclass WorkerEventWriter extends SessionEventWriter {\n\tconstructor() {\n\t\tsuper(() => {});\n\t}\n\toverride enqueue(_sessionId: string, record: object): boolean {\n\t\tif (Buffer.byteLength(JSON.stringify(record)) > SESSION_WORKER_LIMITS.outputBytes)\n\t\t\tfailWorker(\"session_worker_output_limit\");\n\t\tconst session = entry?.runtime?.session;\n\t\tif (!session) throw new Error(\"Session output preceded runtime creation\");\n\t\tconst activity = {\n\t\t\tbusy: session.isSessionBusy,\n\t\t\thandoffBusy: isHandoffBusy(session.activitySnapshot),\n\t\t\tstreaming: session.isStreaming,\n\t\t};\n\t\tconst replacement =\n\t\t\t\"type\" in record &&\n\t\t\t(record.type === \"session_replaced\" ||\n\t\t\t\trecord.type === \"question_resolved\" ||\n\t\t\t\trecord.type === \"question_updated\" ||\n\t\t\t\t(record.type === \"extension_ui_request\" && \"method\" in record && record.method === \"question\"))\n\t\t\t\t? snapshot()\n\t\t\t\t: undefined;\n\t\tif (replacement && Buffer.byteLength(JSON.stringify(replacement)) > SESSION_WORKER_LIMITS.outputBytes)\n\t\t\tfailWorker(\"session_worker_snapshot_limit\");\n\t\texchange((signal) => ({\n\t\t\ttype: \"output\",\n\t\t\trecord,\n\t\t\tconnection: this.currentConnection(),\n\t\t\tsignal,\n\t\t\tactivity,\n\t\t\tsnapshot: replacement,\n\t\t}));\n\t\treturn true;\n\t}\n}\n\nconst writer = new WorkerEventWriter();\nlet prepared: Extract<HostToSessionWorker, { type: \"prepare\" }> | undefined;\nlet registry: RpcSessionRegistry | undefined;\nlet entry: RpcSessionEntry | undefined;\nlet binding: RpcSessionBinding | undefined;\nlet display: WorkerDisplay = { revision: 0, width: 80, rendered: false, capabilities: [] };\nlet closing = false;\nlet unsubscribe: (() => void) | undefined;\nlet unsubscribeWake: (() => void) | undefined;\n\nfunction applyDisplay(next: WorkerDisplay): boolean {\n\tif (next.revision < display.revision) return false;\n\tdisplay = next;\n\treturn true;\n}\n\nfunction updateDisplay(message: (signal: SharedArrayBuffer) => SessionWorkerToHost): void {\n\tconst signal = new SharedArrayBuffer(24);\n\texchange(message, \"session_worker_display_denied\", signal);\n\tconst values = new Float64Array(signal);\n\tapplyDisplay({\n\t\t...display,\n\t\twidth: values[1],\n\t\trevision: values[2],\n\t\trendered: Atomics.load(new Int32Array(signal), 1) === 1,\n\t});\n}\n\nfunction publishSnapshot(settled = false): void {\n\tconst value = snapshot();\n\tif (Buffer.byteLength(JSON.stringify(value)) > SESSION_WORKER_LIMITS.outputBytes)\n\t\tfailWorker(\"session_worker_snapshot_limit\");\n\texchange((signal) => ({ type: \"snapshot\", snapshot: value, signal, settled }));\n}\n\nfunction subscribeSession(): void {\n\tunsubscribe?.();\n\tunsubscribeWake?.();\n\tunsubscribeWake = entry?.runtime?.session.extensionRunner.onBusEvent(WAKE_SOURCE_STATE_EVENT, () =>\n\t\tpublishSnapshot(),\n\t);\n\tunsubscribe = entry?.runtime?.session.subscribe((event) =>\n\t\tpublishSnapshot(event.type === \"agent_settled\" || event.type === \"agent_idle\"),\n\t);\n}\n\nfunction snapshot(): WorkerSnapshot {\n\tif (!entry?.runtime) throw new Error(\"Session runtime is not ready\");\n\tconst session = entry.runtime.session;\n\tconst sessionPath = session.sessionFile ? canonicalPath(session.sessionFile) : undefined;\n\t// The host releases every granted path this list omits, so it must name each writer\n\t// still alive in this isolate, plus the session the runtime currently writes.\n\tconst live = new Set(liveSessionWritePaths().map(canonicalPath));\n\tif (sessionPath) live.add(sessionPath);\n\treturn {\n\t\tstate: buildRpcSessionState(session),\n\t\tsessionPath,\n\t\tliveSessionPaths: [...live],\n\t\tbusy: session.isSessionBusy,\n\t\thandoffBusy: isHandoffBusy(session.activitySnapshot),\n\t\tstreaming: session.isStreaming,\n\t};\n}\n\nasync function handle(message: HostToSessionWorker): Promise<void> {\n\tswitch (message.type) {\n\t\tcase \"prepare\": {\n\t\t\tif (prepared) throw new Error(\"Session worker already prepared\");\n\t\t\tconst path =\n\t\t\t\tmessage.profile.sessionPath ??\n\t\t\t\tjoin(\n\t\t\t\t\tgetDefaultSessionDir(message.profile.cwd, message.configuration.agentDir),\n\t\t\t\t\t`${new Date().toISOString().replace(/[:.]/g, \"-\")}_${randomUUID()}.jsonl`,\n\t\t\t\t);\n\t\t\tprepared = { ...message, profile: { ...message.profile, sessionPath: canonicalPath(path) } };\n\t\t\tsend({ type: \"prepared\", request: message.request, sessionPath: canonicalPath(path) });\n\t\t\treturn;\n\t\t}\n\t\tcase \"commit\": {\n\t\t\tif (!prepared || registry) throw new Error(\"Invalid session commit\");\n\t\t\tconst startupSettingsManager = SettingsManager.create(\n\t\t\t\tprepared.configuration.cwd,\n\t\t\t\tprepared.configuration.agentDir,\n\t\t\t);\n\t\t\tconst factory = createCliRuntimeFactory(prepared.configuration, { startupSettingsManager });\n\t\t\tinitTheme(startupSettingsManager.getTheme(), false);\n\t\t\tregistry = new RpcSessionRegistry({ agentDir: prepared.configuration.agentDir, createRuntime: factory });\n\t\t\tconst opened = await registry.openSession(prepared.profile);\n\t\t\tentry = registry.getForCommand(opened.sessionId, \"open_session\");\n\t\t\tsend({ type: \"ready\", request: message.request, snapshot: snapshot() });\n\t\t\treturn;\n\t\t}\n\t\tcase \"bind\": {\n\t\t\tif (!entry || binding) throw new Error(\"Invalid session binding\");\n\t\t\tdisplay = message.display;\n\t\t\tconst bindingEntry = entry;\n\t\t\tconst createBinding = () =>\n\t\t\t\tcreateRpcSessionBinding(message.sessionId, bindingEntry, writer, () => send({ type: \"request_close\" }), {\n\t\t\t\t\tcapabilities: display.capabilities,\n\t\t\t\t\tsharedWidth: {\n\t\t\t\t\t\tgetWidth: () => display.width,\n\t\t\t\t\t\tsetWidth: (connection, width) =>\n\t\t\t\t\t\t\tupdateDisplay((signal) => ({ type: \"width\", connection, width, signal })),\n\t\t\t\t\t\tonChange: () => binding?.rerenderComponents?.(),\n\t\t\t\t\t\tclearWidth: () => {},\n\t\t\t\t\t\tconnectionId: () => writer.currentConnection(),\n\t\t\t\t\t\thasRenderedComponents: () => display.rendered,\n\t\t\t\t\t\tsetCapabilities: (connection, capabilities) => {\n\t\t\t\t\t\t\tupdateDisplay((signal) => ({ type: \"capabilities\", connection, capabilities, signal }));\n\t\t\t\t\t\t\tbinding?.rerenderComponents?.();\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\tbinding = await (message.connection === undefined\n\t\t\t\t? createBinding()\n\t\t\t\t: writer.withConnection(message.connection, createBinding));\n\t\t\tconst rebind = entry.rebindSession;\n\t\t\tentry.rebindSession = async (session) => {\n\t\t\t\tawait rebind?.(session);\n\t\t\t\tsubscribeSession();\n\t\t\t};\n\t\t\tentry.runtime?.setRebindSession(entry.rebindSession);\n\t\t\tsubscribeSession();\n\t\t\tpublishSnapshot();\n\t\t\tsend({ type: \"result\", request: message.request });\n\t\t\treturn;\n\t\t}\n\t\tcase \"command\": {\n\t\t\tconst privileged =\n\t\t\t\t\"type\" in message.command &&\n\t\t\t\t[\"abort\", \"abort_bash\", \"extension_ui_response\", \"extension_ui_progress\"].includes(\n\t\t\t\t\tString(message.command.type),\n\t\t\t\t);\n\t\t\tif (!binding || (closing && !privileged)) throw new Error(\"session_closing\");\n\t\t\tapplyDisplay(message.display);\n\t\t\tconst activeBinding = binding;\n\t\t\tawait (message.connection === undefined\n\t\t\t\t? activeBinding.handle(message.command)\n\t\t\t\t: writer.withConnection(message.connection, () => activeBinding.handle(message.command)));\n\t\t\tpublishSnapshot();\n\t\t\tsend({ type: \"result\", request: message.request });\n\t\t\treturn;\n\t\t}\n\t\tcase \"display\":\n\t\t\tif (applyDisplay(message.display)) binding?.rerenderComponents?.();\n\t\t\tsend({ type: \"control_done\", control: \"display\" });\n\t\t\treturn;\n\t\tcase \"cancel_ui\":\n\t\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\t\tsend({ type: \"control_done\", control: \"cancel_ui\" });\n\t\t\treturn;\n\t\tcase \"close\":\n\t\t\tclosing = true;\n\t\t\tunsubscribe?.();\n\t\t\tunsubscribeWake?.();\n\t\t\tawait binding?.dispose();\n\t\t\tif (entry?.runtime) {\n\t\t\t\tconst current = entry;\n\t\t\t\tawait runWithProviderScope(current.scope, async () => {\n\t\t\t\t\tawait current.runtime?.session.abort();\n\t\t\t\t\tawait current.runtime?.session.waitForIdle();\n\t\t\t\t\tawait current.runtime?.dispose();\n\t\t\t\t\tawait current.scope.close();\n\t\t\t\t});\n\t\t\t}\n\t\t\tprocess.exit(0);\n\t}\n}\n\nport.on(\"message\", (message: HostToSessionWorker) => {\n\tvoid handle(message).catch((cause: unknown) => {\n\t\tconst error = cause instanceof Error ? cause.message : String(cause);\n\t\tif (error.startsWith(\"session_worker_\")) {\n\t\t\tsend({ type: \"failure\", error });\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (\"request\" in message) send({ type: \"result\", request: message.request, error });\n\t\telse {\n\t\t\tsend({ type: \"failure\", error });\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n});\n"]}
1
+ {"version":3,"file":"session-worker.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-worker.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { parentPort, workerData } from \"node:worker_threads\";\nimport { runWithProviderScope } from \"@earendil-works/pi-ai/node/provider-scope\";\nimport { isBunBinary } from \"../../config.ts\";\nimport { WAKE_SOURCE_STATE_EVENT } from \"../../core/extensions/builtin/monitor-state-event.ts\";\nimport { takeOverStdout } from \"../../core/output-guard.ts\";\nimport { getDefaultSessionDir } from \"../../core/session-manager.ts\";\nimport { liveSessionWritePaths } from \"../../core/session-write-reservation.ts\";\nimport { SettingsManager } from \"../../core/settings-manager.ts\";\nimport { registerWebViewBroker } from \"../../core/webview/webview-broker.ts\";\nimport { createCliRuntimeFactory } from \"../../main.ts\";\nimport { initTheme } from \"../interactive/theme/theme.ts\";\nimport { buildRpcSessionState } from \"./connection-handler.ts\";\nimport { isHandoffBusy } from \"./handoff-activity.ts\";\nimport { createRpcSessionBinding, type RpcSessionBinding } from \"./session-binding.ts\";\nimport { SessionEventWriter } from \"./session-event-writer.ts\";\nimport { type RpcSessionEntry, RpcSessionRegistry } from \"./session-registry.ts\";\nimport { createWorkerCredit } from \"./session-worker-credit.ts\";\nimport {\n\ttype HostToSessionWorker,\n\tSESSION_WORKER_LIMITS,\n\ttype SessionWorkerToHost,\n\ttype WorkerDisplay,\n\ttype WorkerSnapshot,\n} from \"./session-worker-protocol.ts\";\n\nif (isBunBinary) {\n\tconst { registerBunRuntimeModules } = await import(\"../../bun/runtime-modules.ts\");\n\tregisterBunRuntimeModules();\n}\n\ntakeOverStdout();\nregisterWebViewBroker(Reflect.get(Object(workerData), \"webviewBroker\"));\nconst port = parentPort;\nif (!port) throw new Error(\"Session worker requires a parent port\");\nconst send = (message: SessionWorkerToHost): void => port.postMessage(message);\n\nfunction failWorker(error: string): never {\n\tsend({ type: \"failure\", error });\n\tprocess.exit(1);\n}\n\nfunction canonicalPath(path: string): string {\n\tconst absolute = resolve(path);\n\treturn existsSync(absolute) ? realpathSync(absolute) : join(realpathSync(dirname(absolute)), basename(absolute));\n}\n\nconst { exchange, installWriteReservation } = createWorkerCredit(send, failWorker);\ninstallWriteReservation(canonicalPath);\n\nclass WorkerEventWriter extends SessionEventWriter {\n\tconstructor() {\n\t\tsuper(() => {});\n\t}\n\toverride enqueue(_sessionId: string, record: object): boolean {\n\t\tif (Buffer.byteLength(JSON.stringify(record)) > SESSION_WORKER_LIMITS.outputBytes)\n\t\t\tfailWorker(\"session_worker_output_limit\");\n\t\tconst session = entry?.runtime?.session;\n\t\tif (!session) throw new Error(\"Session output preceded runtime creation\");\n\t\tconst activity = {\n\t\t\tbusy: session.isSessionBusy,\n\t\t\thandoffBusy: isHandoffBusy(session.activitySnapshot),\n\t\t\tstreaming: session.isStreaming,\n\t\t};\n\t\tconst replacement =\n\t\t\t\"type\" in record &&\n\t\t\t(record.type === \"session_replaced\" ||\n\t\t\t\trecord.type === \"question_resolved\" ||\n\t\t\t\trecord.type === \"question_updated\" ||\n\t\t\t\t(record.type === \"extension_ui_request\" && \"method\" in record && record.method === \"question\"))\n\t\t\t\t? snapshot()\n\t\t\t\t: undefined;\n\t\tif (replacement && Buffer.byteLength(JSON.stringify(replacement)) > SESSION_WORKER_LIMITS.outputBytes)\n\t\t\tfailWorker(\"session_worker_snapshot_limit\");\n\t\texchange((signal) => ({\n\t\t\ttype: \"output\",\n\t\t\trecord,\n\t\t\tconnection: this.currentConnection(),\n\t\t\tsignal,\n\t\t\tactivity,\n\t\t\tsnapshot: replacement,\n\t\t}));\n\t\treturn true;\n\t}\n}\n\nconst writer = new WorkerEventWriter();\nlet prepared: Extract<HostToSessionWorker, { type: \"prepare\" }> | undefined;\nlet registry: RpcSessionRegistry | undefined;\nlet entry: RpcSessionEntry | undefined;\nlet binding: RpcSessionBinding | undefined;\nlet display: WorkerDisplay = { revision: 0, width: 80, rendered: false, capabilities: [] };\nlet closing = false;\nlet unsubscribe: (() => void) | undefined;\nlet unsubscribeWake: (() => void) | undefined;\n\nfunction applyDisplay(next: WorkerDisplay): boolean {\n\tif (next.revision < display.revision) return false;\n\tdisplay = next;\n\treturn true;\n}\n\nfunction updateDisplay(message: (signal: SharedArrayBuffer) => SessionWorkerToHost): void {\n\tconst signal = new SharedArrayBuffer(24);\n\texchange(message, \"session_worker_display_denied\", signal);\n\tconst values = new Float64Array(signal);\n\tapplyDisplay({\n\t\t...display,\n\t\twidth: values[1],\n\t\trevision: values[2],\n\t\trendered: Atomics.load(new Int32Array(signal), 1) === 1,\n\t});\n}\n\nfunction publishSnapshot(settled = false): void {\n\tconst value = snapshot();\n\tif (Buffer.byteLength(JSON.stringify(value)) > SESSION_WORKER_LIMITS.outputBytes)\n\t\tfailWorker(\"session_worker_snapshot_limit\");\n\texchange((signal) => ({ type: \"snapshot\", snapshot: value, signal, settled }));\n}\n\nfunction subscribeSession(): void {\n\tunsubscribe?.();\n\tunsubscribeWake?.();\n\tunsubscribeWake = entry?.runtime?.session.extensionRunner.onBusEvent(WAKE_SOURCE_STATE_EVENT, () =>\n\t\tpublishSnapshot(),\n\t);\n\tunsubscribe = entry?.runtime?.session.subscribe((event) =>\n\t\tpublishSnapshot(event.type === \"agent_settled\" || event.type === \"agent_idle\"),\n\t);\n}\n\nfunction snapshot(): WorkerSnapshot {\n\tif (!entry?.runtime) throw new Error(\"Session runtime is not ready\");\n\tconst session = entry.runtime.session;\n\tconst sessionPath = session.sessionFile ? canonicalPath(session.sessionFile) : undefined;\n\t// The host releases every granted path this list omits, so it must name each writer\n\t// still alive in this isolate, plus the session the runtime currently writes.\n\tconst live = new Set(liveSessionWritePaths().map(canonicalPath));\n\tif (sessionPath) live.add(sessionPath);\n\treturn {\n\t\tstate: buildRpcSessionState(session),\n\t\tsessionPath,\n\t\tliveSessionPaths: [...live],\n\t\tbusy: session.isSessionBusy,\n\t\thandoffBusy: isHandoffBusy(session.activitySnapshot),\n\t\tstreaming: session.isStreaming,\n\t};\n}\n\nasync function handle(message: HostToSessionWorker): Promise<void> {\n\tswitch (message.type) {\n\t\tcase \"prepare\": {\n\t\t\tif (prepared) throw new Error(\"Session worker already prepared\");\n\t\t\tconst path =\n\t\t\t\tmessage.profile.sessionPath ??\n\t\t\t\tjoin(\n\t\t\t\t\tgetDefaultSessionDir(message.profile.cwd, message.configuration.agentDir),\n\t\t\t\t\t`${new Date().toISOString().replace(/[:.]/g, \"-\")}_${randomUUID()}.jsonl`,\n\t\t\t\t);\n\t\t\tprepared = { ...message, profile: { ...message.profile, sessionPath: canonicalPath(path) } };\n\t\t\tsend({ type: \"prepared\", request: message.request, sessionPath: canonicalPath(path) });\n\t\t\treturn;\n\t\t}\n\t\tcase \"commit\": {\n\t\t\tif (!prepared || registry) throw new Error(\"Invalid session commit\");\n\t\t\tconst startupSettingsManager = SettingsManager.create(\n\t\t\t\tprepared.configuration.cwd,\n\t\t\t\tprepared.configuration.agentDir,\n\t\t\t);\n\t\t\tconst factory = createCliRuntimeFactory(prepared.configuration, { startupSettingsManager });\n\t\t\tinitTheme(startupSettingsManager.getTheme(), false);\n\t\t\tregistry = new RpcSessionRegistry({ agentDir: prepared.configuration.agentDir, createRuntime: factory });\n\t\t\tconst opened = await registry.openSession(prepared.profile);\n\t\t\tentry = registry.getForCommand(opened.sessionId, \"open_session\");\n\t\t\tsend({ type: \"ready\", request: message.request, snapshot: snapshot() });\n\t\t\treturn;\n\t\t}\n\t\tcase \"bind\": {\n\t\t\tif (!entry || binding) throw new Error(\"Invalid session binding\");\n\t\t\tdisplay = message.display;\n\t\t\tconst bindingEntry = entry;\n\t\t\tconst createBinding = () =>\n\t\t\t\tcreateRpcSessionBinding(message.sessionId, bindingEntry, writer, () => send({ type: \"request_close\" }), {\n\t\t\t\t\tcapabilities: display.capabilities,\n\t\t\t\t\tsharedWidth: {\n\t\t\t\t\t\tgetWidth: () => display.width,\n\t\t\t\t\t\tsetWidth: (connection, width) =>\n\t\t\t\t\t\t\tupdateDisplay((signal) => ({ type: \"width\", connection, width, signal })),\n\t\t\t\t\t\tonChange: () => binding?.rerenderComponents?.(),\n\t\t\t\t\t\tclearWidth: () => {},\n\t\t\t\t\t\tconnectionId: () => writer.currentConnection(),\n\t\t\t\t\t\thasRenderedComponents: () => display.rendered,\n\t\t\t\t\t\tsetCapabilities: (connection, capabilities) => {\n\t\t\t\t\t\t\tupdateDisplay((signal) => ({ type: \"capabilities\", connection, capabilities, signal }));\n\t\t\t\t\t\t\tbinding?.rerenderComponents?.();\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\tbinding = await (message.connection === undefined\n\t\t\t\t? createBinding()\n\t\t\t\t: writer.withConnection(message.connection, createBinding));\n\t\t\tconst rebind = entry.rebindSession;\n\t\t\tentry.rebindSession = async (session) => {\n\t\t\t\tawait rebind?.(session);\n\t\t\t\tsubscribeSession();\n\t\t\t};\n\t\t\tentry.runtime?.setRebindSession(entry.rebindSession);\n\t\t\tsubscribeSession();\n\t\t\tpublishSnapshot();\n\t\t\tsend({ type: \"result\", request: message.request });\n\t\t\treturn;\n\t\t}\n\t\tcase \"command\": {\n\t\t\tconst privileged =\n\t\t\t\t\"type\" in message.command &&\n\t\t\t\t[\"abort\", \"abort_bash\", \"extension_ui_response\", \"extension_ui_progress\"].includes(\n\t\t\t\t\tString(message.command.type),\n\t\t\t\t);\n\t\t\tif (!binding || (closing && !privileged)) throw new Error(\"session_closing\");\n\t\t\tapplyDisplay(message.display);\n\t\t\tconst activeBinding = binding;\n\t\t\tawait (message.connection === undefined\n\t\t\t\t? activeBinding.handle(message.command)\n\t\t\t\t: writer.withConnection(message.connection, () => activeBinding.handle(message.command)));\n\t\t\tpublishSnapshot();\n\t\t\tsend({ type: \"result\", request: message.request });\n\t\t\treturn;\n\t\t}\n\t\tcase \"display\":\n\t\t\tif (applyDisplay(message.display)) binding?.rerenderComponents?.();\n\t\t\tsend({ type: \"control_done\", control: \"display\" });\n\t\t\treturn;\n\t\tcase \"cancel_ui\":\n\t\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\t\tsend({ type: \"control_done\", control: \"cancel_ui\" });\n\t\t\treturn;\n\t\tcase \"close\":\n\t\t\tclosing = true;\n\t\t\tunsubscribe?.();\n\t\t\tunsubscribeWake?.();\n\t\t\tawait binding?.dispose();\n\t\t\tif (entry?.runtime) {\n\t\t\t\tconst current = entry;\n\t\t\t\tawait runWithProviderScope(current.scope, async () => {\n\t\t\t\t\tawait current.runtime?.session.abort();\n\t\t\t\t\tawait current.runtime?.session.waitForIdle();\n\t\t\t\t\tawait current.runtime?.dispose();\n\t\t\t\t\tawait current.scope.close();\n\t\t\t\t});\n\t\t\t}\n\t\t\tprocess.exit(0);\n\t}\n}\n\nport.on(\"message\", (message: HostToSessionWorker) => {\n\tvoid handle(message).catch((cause: unknown) => {\n\t\tconst error = cause instanceof Error ? cause.message : String(cause);\n\t\tif (error.startsWith(\"session_worker_\")) {\n\t\t\tsend({ type: \"failure\", error });\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (\"request\" in message) send({ type: \"result\", request: message.request, error });\n\t\telse {\n\t\t\tsend({ type: \"failure\", error });\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n});\n"]}
@@ -12,6 +12,20 @@
12
12
 
13
13
  ### Removed
14
14
 
15
+ ## [2026.9.28-3] - 2026-09-28
16
+
17
+ ### Breaking Changes
18
+
19
+ ### Added
20
+
21
+ ### Changed
22
+
23
+ ### Fixed
24
+
25
+ - `new Bun.WebView()` in a JavaScript eval cell no longer fails with `Bun.WebView with backend "chrome" is only available on the main thread` (every call on Windows and Linux, `backend: "chrome"` on macOS). Cells see a `Bun` whose `WebView` (also through `import { WebView } from "bun"`) hands Chrome-backed views to the process main thread with the same API: navigation, input, `evaluate`, screenshots, `cdp()` and its events, `console` capture, `url`/`title`/`loading`, `close()` and `await using`. The macOS default (WebKit) stays a native view in the kernel worker. `Bun.WebView.closeAll()` in a cell closes only that kernel's views. ([#2248](https://github.com/code-yeongyu/senpi/issues/2248))
26
+
27
+ ### Removed
28
+
15
29
  ## [2026.9.28-2] - 2026-09-28
16
30
 
17
31
  ### Breaking Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-codemode",
3
- "version": "2026.9.28-2",
3
+ "version": "2026.9.28-3",
4
4
  "private": true,
5
5
  "description": "Source-only senpi extension package for codemode evaluation tools",
6
6
  "type": "module",
@@ -31,14 +31,14 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@babel/parser": "8.0.4",
34
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.28-2",
34
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.28-3",
35
35
  "typebox": "1.3.34"
36
36
  },
37
37
  "peerDependencies": {
38
- "@code-yeongyu/senpi": "2026.9.28-2"
38
+ "@code-yeongyu/senpi": "2026.9.28-3"
39
39
  },
40
40
  "devDependencies": {
41
- "@code-yeongyu/senpi": "2026.9.28-2"
41
+ "@code-yeongyu/senpi": "2026.9.28-3"
42
42
  },
43
43
  "keywords": [
44
44
  "senpi",
@@ -66,6 +66,19 @@ const hostToKernelMessageSchema = Type.Union([
66
66
  Type.Object({
67
67
  type: Type.Literal("close"),
68
68
  }),
69
+ /** JS only: the kernel's private port to the main-thread Bun.WebView service, sent in the transfer list. */
70
+ Type.Object({
71
+ type: Type.Literal("webview-port"),
72
+ requestId: Type.String({ minLength: 1 }),
73
+ ok: Type.Literal(true),
74
+ port: Type.Unknown(),
75
+ }),
76
+ Type.Object({
77
+ type: Type.Literal("webview-port"),
78
+ requestId: Type.String({ minLength: 1 }),
79
+ ok: Type.Literal(false),
80
+ error: bridgeErrorSchema,
81
+ }),
69
82
  ...kernelToolHostToKernelSchemas,
70
83
  ]);
71
84
 
@@ -106,6 +119,7 @@ const kernelToHostMessageSchema = Type.Union([
106
119
  durationMs: Type.Integer({ minimum: 0 }),
107
120
  }),
108
121
  Type.Object({ type: Type.Literal("closed") }),
122
+ Type.Object({ type: Type.Literal("webview-connect"), requestId: Type.String({ minLength: 1 }) }),
109
123
  ...kernelToolKernelToHostSchemas,
110
124
  ]);
111
125
 
@@ -1,5 +1,6 @@
1
1
  import { dirname, join } from "node:path";
2
2
  import { fileURLToPath, pathToFileURL } from "node:url";
3
+ import type { MessagePort } from "node:worker_threads";
3
4
  import type { HostToKernelMessage, KernelToHostMessage } from "../../bridge/protocol.ts";
4
5
  import { type CodemodeRuntimeAssetEnvironment, requireCodemodeRuntimeAsset } from "../shared/runtime-asset.ts";
5
6
  import type { JavaScriptKernelMode } from "./kernel-contract.ts";
@@ -18,7 +19,7 @@ export function resolveInlineWorkerEntryUrl(options: JavaScriptInlineWorkerEntry
18
19
 
19
20
  export interface WorkerLike {
20
21
  readonly mode: JavaScriptKernelMode;
21
- postMessage(message: HostToKernelMessage): void;
22
+ postMessage(message: HostToKernelMessage, transfer?: readonly MessagePort[]): void;
22
23
  onMessage(handler: (message: KernelToHostMessage) => void): () => void;
23
24
  onError(handler: (error: Error) => void): () => void;
24
25
  terminate(): Promise<void>;
@@ -77,6 +77,8 @@ function loaderPrelude(context: RuntimeModuleContext): string {
77
77
  "globalThis.__senpi_import__ = async (source, options) => {",
78
78
  " const context = globalThis.__senpi_module_context__;",
79
79
  " const specifier = String(source);",
80
+ " const kernelBun = globalThis[Symbol.for('senpi.kernel.bun')];",
81
+ " if (specifier === 'bun' && kernelBun) return { ...(await import('bun')), WebView: kernelBun.WebView, default: kernelBun };",
80
82
  " const match = /^([a-z][a-z0-9+.-]*):\\/\\/(.*)$/i.exec(specifier);",
81
83
  " let target = specifier;",
82
84
  " if (match) {",
@@ -0,0 +1,59 @@
1
+ import type { MessagePort } from "node:worker_threads";
2
+ import type { WebViewServiceConnection } from "@code-yeongyu/senpi";
3
+ import type { HostToKernelMessage, KernelToHostMessage } from "../../bridge/protocol.ts";
4
+ import { bridgeError } from "./worker-host.ts";
5
+
6
+ export type WebViewConnector = () => Promise<WebViewServiceConnection>;
7
+
8
+ // Loaded on the first WebView a cell asks for, so starting a kernel never pays for the host barrel.
9
+ const connectThroughHost: WebViewConnector = async () => (await import("@code-yeongyu/senpi")).connectWebViewService();
10
+
11
+ /**
12
+ * The WebView clients one worker generation asked for. Chrome-backed `Bun.WebView`s only run on the
13
+ * process main thread, so the worker gets a private port to the main-thread service; retiring the
14
+ * generation (reset, close, crash, timeout) releases every view created through those ports.
15
+ */
16
+ export class KernelWebViewClients {
17
+ readonly #post: (message: HostToKernelMessage, transfer: readonly MessagePort[]) => void;
18
+ readonly #connect: WebViewConnector;
19
+ readonly #connections = new Set<WebViewServiceConnection>();
20
+ #retired = false;
21
+
22
+ constructor(
23
+ post: (message: HostToKernelMessage, transfer: readonly MessagePort[]) => void,
24
+ connect: WebViewConnector = connectThroughHost,
25
+ ) {
26
+ this.#post = post;
27
+ this.#connect = connect;
28
+ }
29
+
30
+ consume(message: KernelToHostMessage): boolean {
31
+ if (message.type !== "webview-connect") return false;
32
+ void this.#grant(message.requestId);
33
+ return true;
34
+ }
35
+
36
+ async release(): Promise<void> {
37
+ this.#retired = true;
38
+ const connections = [...this.#connections];
39
+ this.#connections.clear();
40
+ await Promise.allSettled(connections.map((connection) => connection.release()));
41
+ }
42
+
43
+ async #grant(requestId: string): Promise<void> {
44
+ let connection: WebViewServiceConnection;
45
+ try {
46
+ connection = await this.#connect();
47
+ } catch (error) {
48
+ const cause = error instanceof Error ? error : new Error(String(error));
49
+ if (!this.#retired) this.#post({ type: "webview-port", requestId, ok: false, error: bridgeError(cause) }, []);
50
+ return;
51
+ }
52
+ if (this.#retired) {
53
+ await connection.release();
54
+ return;
55
+ }
56
+ this.#connections.add(connection);
57
+ this.#post({ type: "webview-port", requestId, ok: true, port: connection.port }, [connection.port]);
58
+ }
59
+ }
@@ -3,6 +3,7 @@ import { kernelToolError } from "./kernel-tools-errors.js";
3
3
  import { createKernelToolPump } from "./kernel-tools-pump.js";
4
4
  import { hostDeniedError, hostToolRefusal } from "./kernel-tools-scope.js";
5
5
  import { JsWorkerRuntime } from "./worker-runtime.js";
6
+ import { installKernelWebView } from "./worker-webview.js";
6
7
 
7
8
  // Mirrors INTERRUPT_ACK_OP and CHILD_LIFECYCLE_OP in src/bridge/reserved.ts (this worker file cannot import TypeScript).
8
9
  const INTERRUPT_ACK_OP = "interrupt-ack";
@@ -25,6 +26,7 @@ export function createWorkerCore(transport, options) {
25
26
  let runtime = null;
26
27
  let activeCell = null;
27
28
  const pendingTools = new Map();
29
+ const pendingWebViewPorts = new Map();
28
30
  const nestedInvokes = new Map();
29
31
  const kernelTools = createKernelToolPump({
30
32
  getRuntime: () => runtime,
@@ -73,6 +75,13 @@ export function createWorkerCore(transport, options) {
73
75
  return await promise;
74
76
  }
75
77
 
78
+ function requestWebViewPort() {
79
+ const requestId = crypto.randomUUID();
80
+ const promise = new Promise((resolve, reject) => pendingWebViewPorts.set(requestId, { resolve, reject }));
81
+ emit({ type: "webview-connect", requestId });
82
+ return promise;
83
+ }
84
+
76
85
  function interruptCell(reason) {
77
86
  if (!activeCell || !runtime) return;
78
87
  emit({ type: "status", event: { op: INTERRUPT_ACK_OP, cellId: activeCell.cellId } });
@@ -92,8 +101,16 @@ export function createWorkerCore(transport, options) {
92
101
  runtime?.kernelTools.setCollisionNames(message.hostToolNames ?? [], message.foreignLanguageNames ?? []);
93
102
  return;
94
103
  }
104
+ if (message.type === "webview-port") {
105
+ const pending = pendingWebViewPorts.get(message.requestId);
106
+ pendingWebViewPorts.delete(message.requestId);
107
+ if (message.ok) pending?.resolve(message.port);
108
+ else pending?.reject(errorFromBridge(message.error));
109
+ return;
110
+ }
95
111
  if (message.type === "init") {
96
112
  applySessionEnvironment(message.sessionEnv);
113
+ installKernelWebView(requestWebViewPort);
97
114
  runtime = new JsWorkerRuntime({
98
115
  cwd: options.cwd,
99
116
  parallelPoolWidth: options.parallelPoolWidth,
@@ -88,7 +88,8 @@ export function bridgeError(error: Error): {
88
88
  function wrapNodeWorker(worker: Worker, mode: JavaScriptKernelMode): WorkerLike {
89
89
  return {
90
90
  mode,
91
- postMessage: (message) => worker.postMessage(message),
91
+ postMessage: (message, transfer) =>
92
+ worker.postMessage(message, transfer === undefined ? undefined : [...transfer]),
92
93
  onMessage(handler) {
93
94
  const listener = (message: KernelToHostMessage): void => handler(message);
94
95
  worker.on("message", listener);
@@ -6,6 +6,7 @@ import { encodeDisplayImage, resolveDisplayOps } from "./display-image.js";
6
6
  import { terminateProcessTrees } from "./process-tree.js";
7
7
  import { awaitMaybePromise, indirectEval, wrapUserCode } from "./worker-indirect-eval.js";
8
8
  import { installShellCapture } from "./worker-shell-capture.js";
9
+ import { bindKernelBun } from "./worker-webview.js";
9
10
  import { createWorkpool } from "./workpool.js";
10
11
  import { inKernelToolInvoke } from "./kernel-tools-context.js";
11
12
  import { kernelToolError } from "./kernel-tools-errors.js";
@@ -57,7 +58,7 @@ export class JsWorkerRuntime {
57
58
  ({ prelude, code: cellCode } = prepared);
58
59
  }
59
60
  if (prelude) indirectEval(prelude, `${cellId}:prelude`);
60
- const value = await awaitMaybePromise(indirectEval(wrapUserCode(cellCode), cellId));
61
+ const value = await awaitMaybePromise(indirectEval(bindKernelBun(wrapUserCode(cellCode)), cellId));
61
62
  await this.#drainPendingDisplays();
62
63
  return value;
63
64
  } finally {
@@ -1,8 +1,10 @@
1
+ import type { MessagePort } from "node:worker_threads";
1
2
  import type { HostToKernelMessage, KernelToHostMessage } from "../../bridge/protocol.ts";
2
3
  import type { WorkerLike } from "./inline-worker.ts";
3
4
  import { retireWorker, type WorkerRetirement } from "./interrupt-bounds.ts";
4
5
  import type { JavaScriptKernelMode } from "./kernel-contract.ts";
5
6
  import type { JavaScriptKernelOptions } from "./local-module-loader.ts";
7
+ import { KernelWebViewClients } from "./webview-host.ts";
6
8
  import { WorkerStartupCancelledError } from "./worker-host.ts";
7
9
  import { startWorkerWithInlineFallback } from "./worker-startup.ts";
8
10
 
@@ -17,6 +19,7 @@ export class WorkerSlot {
17
19
  readonly #options: JavaScriptKernelOptions;
18
20
  readonly #listeners: WorkerSlotListeners;
19
21
  #worker: WorkerLike | null = null;
22
+ #webViews: KernelWebViewClients | null = null;
20
23
  #mode: JavaScriptKernelMode = "worker";
21
24
  #generation = 0;
22
25
  #ready: Promise<void> | null = null;
@@ -43,8 +46,8 @@ export class WorkerSlot {
43
46
  return this.#generation;
44
47
  }
45
48
 
46
- postMessage(message: HostToKernelMessage): void {
47
- this.#worker?.postMessage(message);
49
+ postMessage(message: HostToKernelMessage, transfer?: readonly MessagePort[]): void {
50
+ this.#worker?.postMessage(message, transfer);
48
51
  }
49
52
 
50
53
  async ensureReady(): Promise<void> {
@@ -89,16 +92,22 @@ export class WorkerSlot {
89
92
  this.#startupAbort = null;
90
93
  this.#ready = null;
91
94
  const worker = this.#worker;
95
+ const webViews = this.#webViews;
92
96
  this.#worker = null;
93
- if (!worker) return "terminated";
94
- return await retireWorker(worker);
97
+ this.#webViews = null;
98
+ const retirement = worker ? await retireWorker(worker) : "terminated";
99
+ await webViews?.release();
100
+ return retirement;
95
101
  }
96
102
 
97
103
  #publish(worker: WorkerLike, generation: number): void {
98
104
  if (!this.#listeners.isOpen() || generation !== this.#generation) throw new WorkerStartupCancelledError();
99
105
  this.#worker = worker;
106
+ const webViews = new KernelWebViewClients((message, transfer) => worker.postMessage(message, transfer));
107
+ this.#webViews = webViews;
100
108
  worker.onMessage((message) => {
101
- if (this.#isCurrent(worker, generation)) this.#listeners.onMessage(message);
109
+ if (!this.#isCurrent(worker, generation) || webViews.consume(message)) return;
110
+ this.#listeners.onMessage(message);
102
111
  });
103
112
  worker.onError((error) => {
104
113
  if (this.#isCurrent(worker, generation)) this.#listeners.onCrash(error);
@@ -0,0 +1,79 @@
1
+ // The kernel worker's end of its private port to the main-thread Bun.WebView service. Mirrors
2
+ // the message shapes in packages/coding-agent/src/core/webview/webview-wire.ts (this worker file
3
+ // cannot import TypeScript); keep the two in sync.
4
+
5
+ export const DELIVER_EVENT = Symbol("senpi.webview.deliver");
6
+
7
+ export function webViewError(wire) {
8
+ const error = new Error(wire?.message ?? "Bun.WebView request failed");
9
+ if (typeof wire?.name === "string") error.name = wire.name;
10
+ if (typeof wire?.code === "string") error.code = wire.code;
11
+ return error;
12
+ }
13
+
14
+ export class WebViewPortClient {
15
+ #port;
16
+ #pending = new Map();
17
+ #views = new Map();
18
+ #nextId = 1;
19
+ #closed = false;
20
+ #onClosed;
21
+
22
+ constructor(port, onClosed) {
23
+ this.#port = port;
24
+ this.#onClosed = onClosed;
25
+ port.on("message", message => this.#receive(message));
26
+ port.on("close", () => this.#fail(new Error("Bun.WebView service connection closed")));
27
+ }
28
+
29
+ register(viewId, view) {
30
+ this.#views.set(viewId, new WeakRef(view));
31
+ }
32
+
33
+ forget(viewId) {
34
+ this.#views.delete(viewId);
35
+ }
36
+
37
+ request(message) {
38
+ if (this.#closed) return Promise.reject(new Error("Bun.WebView service connection closed"));
39
+ const id = this.#nextId++;
40
+ return new Promise((resolve, reject) => {
41
+ this.#pending.set(id, { resolve, reject });
42
+ try {
43
+ this.#port.postMessage({ ...message, id });
44
+ } catch (error) {
45
+ this.#pending.delete(id);
46
+ reject(error);
47
+ }
48
+ });
49
+ }
50
+
51
+ post(message) {
52
+ if (this.#closed) return;
53
+ try {
54
+ this.#port.postMessage(message);
55
+ } catch {
56
+ // A closed port has already released every view on the service side.
57
+ }
58
+ }
59
+
60
+ #receive(message) {
61
+ if (message?.kind === "reply") {
62
+ const pending = this.#pending.get(message.id);
63
+ if (!pending) return;
64
+ this.#pending.delete(message.id);
65
+ if (message.ok) pending.resolve({ value: message.value, state: message.state });
66
+ else pending.reject(webViewError(message.error));
67
+ return;
68
+ }
69
+ if (message?.kind === "event") this.#views.get(message.viewId)?.deref()?.[DELIVER_EVENT](message.event);
70
+ }
71
+
72
+ #fail(error) {
73
+ if (this.#closed) return;
74
+ this.#closed = true;
75
+ for (const pending of this.#pending.values()) pending.reject(error);
76
+ this.#pending.clear();
77
+ this.#onClosed();
78
+ }
79
+ }