@code-yeongyu/senpi 2026.9.19 → 2026.9.20

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 (171) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/bundle/chunks/{app-server-command-QK7Q6XK5.js → app-server-command-B35FQUTE.js} +1 -1
  3. package/dist/bundle/chunks/{bun-extension-importer-JQZRPNJH.js → bun-extension-importer-HHH4TV4B.js} +3 -3
  4. package/dist/bundle/chunks/{chunk-YRN3PCTM.js → chunk-DQZB4GVV.js} +4 -4
  5. package/dist/bundle/chunks/{chunk-KKDSBABY.js → chunk-E5R67F7G.js} +38 -38
  6. package/dist/bundle/chunks/{chunk-NARL7XFO.js → chunk-TWGC3TBR.js} +2 -2
  7. package/dist/bundle/chunks/{chunk-RLRLQRI2.js → chunk-V2ZB62DG.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-3FRTRCR6.js → chunk-YXQG2SUX.js} +2 -2
  9. package/dist/bundle/chunks/{chunk-PLZK7ABD.js → chunk-Z4LHCTJ6.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-3Q4WGKFA.js → chunk-ZMFHNH6U.js} +1 -1
  11. package/dist/bundle/chunks/{cli-main-7SG3K4K3.js → cli-main-USVT7JMN.js} +1 -1
  12. package/dist/bundle/chunks/{interactive-host-runtime-AITXUDCT.js → interactive-host-runtime-ELBAZ4LN.js} +1 -1
  13. package/dist/bundle/chunks/{interactive-mode-7MN6GGCG.js → interactive-mode-R6225BKI.js} +1 -1
  14. package/dist/bundle/chunks/{list-tips-KTDNGQUK.js → list-tips-Z7T2ACVU.js} +1 -1
  15. package/dist/bundle/chunks/{multi-session-host-WKX34SOP.js → multi-session-host-QNEBJW2P.js} +3 -3
  16. package/dist/bundle/chunks/{package-manager-cli-CB2X57TD.js → package-manager-cli-4MVJ3JSE.js} +1 -1
  17. package/dist/bundle/chunks/{rpc-mode-CI6V2SBW.js → rpc-mode-CXVDRIBU.js} +1 -1
  18. package/dist/bundle/chunks/{session-picker-DXCITGLS.js → session-picker-6N666KQZ.js} +1 -1
  19. package/dist/bundle/chunks/session-worker.js +67 -67
  20. package/dist/bundle/cli.js +1 -1
  21. package/dist/bundle/index.js +1 -1
  22. package/dist/bundle/rpc-entry.js +1 -1
  23. package/dist/core/agent-session-services.d.ts.map +1 -1
  24. package/dist/core/agent-session-services.js +14 -1
  25. package/dist/core/agent-session-services.js.map +1 -1
  26. package/dist/core/agent-session.d.ts +49 -0
  27. package/dist/core/agent-session.d.ts.map +1 -1
  28. package/dist/core/agent-session.js +290 -44
  29. package/dist/core/agent-session.js.map +1 -1
  30. package/dist/core/extensions/builtin/ask-user/extension.d.ts.map +1 -1
  31. package/dist/core/extensions/builtin/ask-user/extension.js +16 -5
  32. package/dist/core/extensions/builtin/ask-user/extension.js.map +1 -1
  33. package/dist/core/extensions/builtin/ask-user/format.d.ts +5 -0
  34. package/dist/core/extensions/builtin/ask-user/format.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/ask-user/format.js +4 -0
  36. package/dist/core/extensions/builtin/ask-user/format.js.map +1 -1
  37. package/dist/core/extensions/builtin/ask-user/notify.d.ts +2 -0
  38. package/dist/core/extensions/builtin/ask-user/notify.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/ask-user/notify.js +2 -0
  40. package/dist/core/extensions/builtin/ask-user/notify.js.map +1 -1
  41. package/dist/core/extensions/builtin/ask-user/registry.d.ts +15 -2
  42. package/dist/core/extensions/builtin/ask-user/registry.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/ask-user/registry.js +13 -0
  44. package/dist/core/extensions/builtin/ask-user/registry.js.map +1 -1
  45. package/dist/core/extensions/builtin/ask-user/render.d.ts +6 -0
  46. package/dist/core/extensions/builtin/ask-user/render.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/ask-user/render.js +9 -0
  48. package/dist/core/extensions/builtin/ask-user/render.js.map +1 -1
  49. package/dist/core/extensions/builtin/ask-user/resume.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/ask-user/resume.js +59 -24
  51. package/dist/core/extensions/builtin/ask-user/resume.js.map +1 -1
  52. package/dist/core/extensions/builtin/ask-user/tool.d.ts +1 -1
  53. package/dist/core/extensions/builtin/ask-user/tool.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/ask-user/tool.js +98 -17
  55. package/dist/core/extensions/builtin/ask-user/tool.js.map +1 -1
  56. package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts +18 -0
  57. package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/compaction/model-usability-budget.js +16 -8
  59. package/dist/core/extensions/builtin/compaction/model-usability-budget.js.map +1 -1
  60. package/dist/core/extensions/builtin/compaction/switch-admission.d.ts +23 -0
  61. package/dist/core/extensions/builtin/compaction/switch-admission.d.ts.map +1 -0
  62. package/dist/core/extensions/builtin/compaction/switch-admission.js +19 -0
  63. package/dist/core/extensions/builtin/compaction/switch-admission.js.map +1 -0
  64. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/goal/index.js +10 -0
  66. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  67. package/dist/core/extensions/bun-extension-commonjs.d.ts +1 -1
  68. package/dist/core/extensions/bun-extension-commonjs.d.ts.map +1 -1
  69. package/dist/core/extensions/bun-extension-commonjs.js +3 -3
  70. package/dist/core/extensions/bun-extension-commonjs.js.map +1 -1
  71. package/dist/core/extensions/bun-extension-importer.d.ts.map +1 -1
  72. package/dist/core/extensions/bun-extension-importer.js +4 -1
  73. package/dist/core/extensions/bun-extension-importer.js.map +1 -1
  74. package/dist/core/extensions/bun-extension-registry.d.ts.map +1 -1
  75. package/dist/core/extensions/bun-extension-registry.js +5 -9
  76. package/dist/core/extensions/bun-extension-registry.js.map +1 -1
  77. package/dist/core/resolved-paths-memo.d.ts +31 -0
  78. package/dist/core/resolved-paths-memo.d.ts.map +1 -0
  79. package/dist/core/resolved-paths-memo.js +57 -0
  80. package/dist/core/resolved-paths-memo.js.map +1 -0
  81. package/dist/core/resource-loader.d.ts +4 -1
  82. package/dist/core/resource-loader.d.ts.map +1 -1
  83. package/dist/core/resource-loader.js +25 -12
  84. package/dist/core/resource-loader.js.map +1 -1
  85. package/dist/core/retry-fallback/settings.d.ts +10 -2
  86. package/dist/core/retry-fallback/settings.d.ts.map +1 -1
  87. package/dist/core/retry-fallback/settings.js +28 -6
  88. package/dist/core/retry-fallback/settings.js.map +1 -1
  89. package/dist/core/skill-discovery.d.ts.map +1 -1
  90. package/dist/core/skill-discovery.js +11 -1
  91. package/dist/core/skill-discovery.js.map +1 -1
  92. package/dist/main.d.ts +10 -0
  93. package/dist/main.d.ts.map +1 -1
  94. package/dist/main.js +19 -2
  95. package/dist/main.js.map +1 -1
  96. package/dist/modes/interactive/components/ask-user-answer-chip.d.ts +2 -5
  97. package/dist/modes/interactive/components/ask-user-answer-chip.d.ts.map +1 -1
  98. package/dist/modes/interactive/components/ask-user-answer-chip.js +1 -4
  99. package/dist/modes/interactive/components/ask-user-answer-chip.js.map +1 -1
  100. package/dist/modes/interactive/components/assistant-message.d.ts +2 -0
  101. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/assistant-message.js +8 -0
  103. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  104. package/dist/modes/interactive/components/assistant-render-descriptors.d.ts +1 -0
  105. package/dist/modes/interactive/components/assistant-render-descriptors.d.ts.map +1 -1
  106. package/dist/modes/interactive/components/assistant-render-descriptors.js +4 -0
  107. package/dist/modes/interactive/components/assistant-render-descriptors.js.map +1 -1
  108. package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
  109. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  110. package/dist/modes/interactive/components/status-indicator.js +15 -2
  111. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  112. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  113. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  114. package/dist/modes/interactive/interactive-mode.js +81 -6
  115. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  116. package/dist/modes/interactive/provider-error-presentation.d.ts +18 -0
  117. package/dist/modes/interactive/provider-error-presentation.d.ts.map +1 -0
  118. package/dist/modes/interactive/provider-error-presentation.js +100 -0
  119. package/dist/modes/interactive/provider-error-presentation.js.map +1 -0
  120. package/dist/modes/rpc/rpc-types.d.ts +18 -0
  121. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  122. package/dist/modes/rpc/rpc-types.js.map +1 -1
  123. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  124. package/dist/modes/rpc/session-command-router.js +14 -0
  125. package/dist/modes/rpc/session-command-router.js.map +1 -1
  126. package/dist/modes/rpc/session-event-writer.d.ts +9 -1
  127. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  128. package/dist/modes/rpc/session-event-writer.js +21 -0
  129. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  130. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  131. package/dist/modes/rpc/session-registry.js +9 -2
  132. package/dist/modes/rpc/session-registry.js.map +1 -1
  133. package/dist/modes/rpc/session-worker-requests.d.ts +10 -1
  134. package/dist/modes/rpc/session-worker-requests.d.ts.map +1 -1
  135. package/dist/modes/rpc/session-worker-requests.js +8 -2
  136. package/dist/modes/rpc/session-worker-requests.js.map +1 -1
  137. package/dist/modes/rpc/session-worker-requests.test.d.ts +2 -0
  138. package/dist/modes/rpc/session-worker-requests.test.d.ts.map +1 -0
  139. package/dist/modes/rpc/session-worker-requests.test.js +44 -0
  140. package/dist/modes/rpc/session-worker-requests.test.js.map +1 -0
  141. package/docs/rpc.md +7 -0
  142. package/docs/settings.md +1 -1
  143. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +24 -0
  144. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  145. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  146. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  147. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  148. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  149. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  150. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  151. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  152. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  153. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  154. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  155. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  156. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  157. package/node_modules/@earendil-works/pi-tui/dist/native-module-path.d.ts.map +1 -1
  158. package/node_modules/@earendil-works/pi-tui/dist/native-module-path.js +26 -3
  159. package/node_modules/@earendil-works/pi-tui/dist/native-module-path.js.map +1 -1
  160. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.d.ts.map +1 -1
  161. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js +13 -6
  162. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js.map +1 -1
  163. package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.d.ts.map +1 -1
  164. package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.js +11 -3
  165. package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.js.map +1 -1
  166. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +15 -2
  167. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  168. package/node_modules/@earendil-works/pi-tui/dist/tui.js +45 -2
  169. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  170. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  171. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"session-command-router.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-command-router.ts"],"names":[],"mappings":"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","sourcesContent":["import { VERSION } from \"../../config.ts\";\nimport { buildRpcSessionState } from \"./connection-handler.ts\";\nimport {\n\tAUTO_TITLE_PER_SESSION_CAPABILITY,\n\tAUTO_TITLE_SESSIONS_CAPABILITY,\n\tMEDIA_PLACEHOLDERS_CAPABILITY,\n\tRETAIN_ON_DISCONNECT_CAPABILITY,\n\tSESSION_CONTEXT_CAPABILITY,\n\tSESSION_KIND_CAPABILITY,\n} from \"./custom-capability.ts\";\nimport { protocolIdentity } from \"./protocol-identity.ts\";\nimport { sessionAutoTitleError, sessionContextError, sessionKindError } from \"./rpc-input-validation.ts\";\nimport type { RpcCommand, RpcResponse, RpcSessionClosedReason } from \"./rpc-types.ts\";\nimport {\n\tRPC_ERROR_INVALID_LAUNCH_PROFILE,\n\tRPC_ERROR_INVALID_SESSION_CONTEXT,\n\tRPC_ERROR_INVALID_SESSION_KIND,\n\tRPC_ERROR_MISSING_SESSION_ID,\n\tRPC_ERROR_OPEN_FAILED,\n\tRPC_ERROR_SESSION_CLOSING,\n\tRPC_ERROR_UNKNOWN_SESSION,\n} from \"./rpc-types.ts\";\nimport { runWithSessionAttribution } from \"./session-attribution.ts\";\nimport { createRpcSessionBinding, type RpcSessionBinding } from \"./session-binding.ts\";\nimport type { SessionEventWriter } from \"./session-event-writer.ts\";\nimport type { OpenRpcSession, RpcSessionLaunchProfile, RpcSessionRegistry } from \"./session-registry.ts\";\nimport { RpcSessionRegistryError } from \"./session-registry.ts\";\n\nconst controls = new Set([\"get_protocol_info\", \"open_session\", \"close_session\", \"list_sessions\"]);\n\n/** How often a draining host re-checks whether the work it is waiting for has settled. */\nconst DRAIN_SWEEP_MS = 50;\n\n/** Binding factory seam, injectable so host wiring is testable without a full runtime stack. */\nexport type RpcBindingFactory = typeof createRpcSessionBinding;\n\n/**\n * Occupancy policy for the shared multi-session host. All fields are opt-in:\n * a router constructed without a policy keeps today's behavior (sessions live\n * until close_session; the host never self-exits).\n */\nexport interface RpcSessionIdlePolicy {\n\t/** Injectable clock (defaults to Date.now) for deterministic tests. */\n\tnow?: () => number;\n\t/** Evict open sessions whose last routed command or session-owned work settled longer ago than this. */\n\tidleEvictionMs?: number;\n\t/** Invoke onEmptyExit once the registry has stayed empty for this long. */\n\temptyExitMs?: number;\n\t/** Host shutdown hook fired by the empty-exit window; called at most once. */\n\tonEmptyExit?: () => void;\n\t/**\n\t * Consulted every tick before the empty-exit window advances. Returning false\n\t * both blocks the exit and resets the window, so a host with a connected but\n\t * sessionless client stays up instead of exiting under its supervisor.\n\t */\n\tcanExitWhenEmpty?: () => boolean;\n}\n\n/**\n * How one caller claims a close. `detach` (a client going away) is the only mode a\n * retained session may answer by staying open, so it is unrepresentable together\n * with `drainAttachments` - draining ENDS the session and must always reach zero.\n */\ntype CloseClaimOptions = { drainAttachments: true; detach?: never } | { drainAttachments: false; detach?: boolean };\n\nfunction error(\n\tid: string | undefined,\n\tcommand: string,\n\tcode: string,\n\tdata?: Readonly<Record<string, unknown>>,\n): RpcResponse {\n\t// `errorData` carries what a client has to ACT on (who holds a path, when to retry); the\n\t// stable code stays the string every existing client already switches on.\n\treturn {\n\t\tid,\n\t\ttype: \"response\",\n\t\tcommand,\n\t\tsuccess: false,\n\t\terror: code,\n\t\t...(data && { errorCode: code, errorData: data }),\n\t};\n}\n\n/** Routes control messages and enforces a routing handle for every session command. */\nexport class SessionCommandRouter {\n\tprivate readonly bindings = new Map<string, RpcSessionBinding>();\n\t/** Session handles opened by each connection, with one count per attachment. */\n\tprivate readonly sessionsByConnection = new Map<string, Map<string, number>>();\n\t/** Opens currently awaiting runtime/binding setup, keyed by connection. */\n\tprivate readonly opensByConnection = new Map<string, Set<Promise<void>>>();\n\t/** Connections whose socket has already been detached. */\n\tprivate readonly releasedConnections = new Set<string>();\n\tprivate readonly registry: Pick<\n\t\tRpcSessionRegistry,\n\t\t\"openSession\" | \"peek\" | \"getForCommand\" | \"beginClose\" | \"close\" | \"closeMarked\" | \"list\" | \"size\"\n\t>;\n\tprivate readonly writer: SessionEventWriter;\n\tprivate readonly defaults: Pick<\n\t\tRpcSessionLaunchProfile,\n\t\t\"cwd\" | \"permissionPreset\" | \"creationModel\" | \"initialThinkingLevel\"\n\t>;\n\tprivate readonly createBinding: typeof createRpcSessionBinding;\n\tprivate readonly connectionOptions: Parameters<typeof createRpcSessionBinding>[4];\n\tprivate readonly widths = new Map<string, Map<string, number>>();\n\tprivate readonly pendingCapabilities = new Map<string, string[]>();\n\tprivate readonly finalizations = new Map<string, { promise: Promise<void>; resolve: () => void }>();\n\tprivate readonly idleNow: () => number;\n\tprivate readonly idleEvictionMs: number;\n\tprivate readonly emptyExitMs: number;\n\tprivate readonly onEmptyExit?: () => void;\n\tprivate readonly canExitWhenEmpty?: () => boolean;\n\tprivate sweepTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate drainTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate draining = false;\n\tprivate emptySince: number | undefined;\n\t/** Halves the idle window while the host reports memory pressure; never refuses work. */\n\tprivate memoryPressure = false;\n\n\tconstructor(\n\t\tregistry: Pick<\n\t\t\tRpcSessionRegistry,\n\t\t\t\"openSession\" | \"peek\" | \"getForCommand\" | \"beginClose\" | \"close\" | \"closeMarked\" | \"list\" | \"size\"\n\t\t>,\n\t\twriter: SessionEventWriter,\n\t\tdefaults: Pick<RpcSessionLaunchProfile, \"cwd\" | \"permissionPreset\" | \"creationModel\" | \"initialThinkingLevel\">,\n\t\tcreateBinding: typeof createRpcSessionBinding = createRpcSessionBinding,\n\t\tconnectionOptions: Parameters<typeof createRpcSessionBinding>[4] = {},\n\t\tidle?: RpcSessionIdlePolicy,\n\t) {\n\t\tthis.registry = registry;\n\t\tthis.writer = writer;\n\t\tthis.defaults = defaults;\n\t\tthis.createBinding = createBinding;\n\t\tthis.connectionOptions = connectionOptions;\n\t\tthis.idleNow = idle?.now ?? Date.now;\n\t\tthis.idleEvictionMs = idle?.idleEvictionMs ?? Number.POSITIVE_INFINITY;\n\t\tthis.emptyExitMs = idle?.emptyExitMs ?? Number.POSITIVE_INFINITY;\n\t\tthis.onEmptyExit = idle?.onEmptyExit;\n\t\tthis.canExitWhenEmpty = idle?.canExitWhenEmpty;\n\t\tif (Number.isFinite(this.idleEvictionMs) || Number.isFinite(this.emptyExitMs)) {\n\t\t\t// Unref'd: occupancy hygiene must never be the reason the event loop stays open.\n\t\t\tconst tickMs = Math.max(20, Math.min(5_000, Math.min(this.idleEvictionMs, this.emptyExitMs) / 4));\n\t\t\tthis.sweepTimer = setInterval(() => this.sweepIdleSessions(), tickMs);\n\t\t\tthis.sweepTimer.unref?.();\n\t\t}\n\t}\n\n\t/** Live sessions the host holds, including ones opening or closing. */\n\tget sessionCount(): number {\n\t\treturn this.registry.size;\n\t}\n\n\t/**\n\t * Hand this host's work to the next generation: park every session the moment it has no client\n\t * attached and nothing running, and leave as soon as none is left. A drain ENDS no work - a\n\t * session mid-turn keeps running, and a session a client is still attached to keeps serving it -\n\t * which is what separates an upgrade from a kill.\n\t */\n\tbeginDrain(): void {\n\t\tif (this.draining) return;\n\t\tthis.draining = true;\n\t\tthis.sweepDrain();\n\t\tif (this.drainTimer !== undefined) return;\n\t\t// Unref'd: a draining host must never be the reason the event loop stays open.\n\t\tthis.drainTimer = setInterval(() => this.sweepDrain(), DRAIN_SWEEP_MS);\n\t\tthis.drainTimer.unref?.();\n\t}\n\n\t/** One drain pass: park what has settled, and exit once the host holds nothing. */\n\tprivate sweepDrain(): void {\n\t\tfor (const { sessionId, status } of this.registry.list()) {\n\t\t\tif (status !== \"open\") continue;\n\t\t\tconst entry = this.registry.peek(sessionId);\n\t\t\tif (!entry || entry.attachments > 0) continue;\n\t\t\t// Session-owned work outlives its client; the park waits for it exactly as the idle\n\t\t\t// sweep does, and the next pass picks the session up once it settles.\n\t\t\tif (entry.worker?.busy || entry.runtime?.session.isSessionBusy) continue;\n\t\t\tvoid this.evictIdleSession(sessionId, \"handoff_parked\");\n\t\t}\n\t\tif (this.registry.size > 0) return;\n\t\tif (this.drainTimer !== undefined) {\n\t\t\tclearInterval(this.drainTimer);\n\t\t\tthis.drainTimer = undefined;\n\t\t}\n\t\tthis.stopSweep();\n\t\tthis.onEmptyExit?.();\n\t}\n\n\t/**\n\t * Raised by the host's memory sampler. Under pressure idle sessions are parked at\n\t * HALF the configured window, which returns their memory to the process sooner.\n\t * Deliberately the only lever: the host never refuses or kills a session for memory.\n\t */\n\tsetMemoryPressure(pressure: boolean): void {\n\t\tthis.memoryPressure = pressure;\n\t}\n\n\t/**\n\t * Every routed command runs inside its session's attribution scope, so a stall the\n\t * loop-lag watchdog observes right after this dispatch can name the session that\n\t * caused it - and anything the command starts inherits the attribution.\n\t */\n\thandle(command: RpcCommand): Promise<RpcResponse | undefined> {\n\t\tconst sessionId = \"sessionId\" in command ? command.sessionId : undefined;\n\t\treturn runWithSessionAttribution({ sessionId }, () => this.dispatch(command));\n\t}\n\n\tprivate async dispatch(command: RpcCommand): Promise<RpcResponse | undefined> {\n\t\tif (command.type === \"get_protocol_info\") {\n\t\t\tconst capabilities = new Set([\n\t\t\t\t\"multi_session\",\n\t\t\t\tAUTO_TITLE_SESSIONS_CAPABILITY,\n\t\t\t\tMEDIA_PLACEHOLDERS_CAPABILITY,\n\t\t\t\t// Host capabilities, not client opt-ins: only a multi-session host owns the\n\t\t\t\t// attachment refcount `open_session.retain_on_disconnect` detaches from, the\n\t\t\t\t// per-session launch profile `context`/`auto_title` travel on, and the session\n\t\t\t\t// listing `kind` filters.\n\t\t\t\tRETAIN_ON_DISCONNECT_CAPABILITY,\n\t\t\t\tSESSION_CONTEXT_CAPABILITY,\n\t\t\t\tSESSION_KIND_CAPABILITY,\n\t\t\t\tAUTO_TITLE_PER_SESSION_CAPABILITY,\n\t\t\t\t...(this.connectionOptions?.capabilities ?? []),\n\t\t\t]);\n\t\t\treturn {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"get_protocol_info\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tprotocolVersion: 1,\n\t\t\t\t\tserverVersion: VERSION,\n\t\t\t\t\tcapabilities: [...capabilities],\n\t\t\t\t\tmode: \"multi\",\n\t\t\t\t\t...protocolIdentity(),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (command.type === \"list_sessions\") {\n\t\t\t// Worker sessions are machine-driven work: a client sees them only by asking, and\n\t\t\t// the opaque context blob travels only on that listing, never to every connection.\n\t\t\tconst rows = this.registry.list();\n\t\t\tconst sessions =\n\t\t\t\tcommand.include_workers === true\n\t\t\t\t\t? rows\n\t\t\t\t\t: rows.filter((row) => row.kind !== \"worker\").map(({ context: _context, ...row }) => row);\n\t\t\treturn {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"list_sessions\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { sessions },\n\t\t\t};\n\t\t}\n\t\tif (command.type === \"open_session\") return this.openWithBarrier(command);\n\t\tif (command.type === \"close_session\") return this.close(command);\n\t\tif (command.type === \"set_client_info\" && !command.sessionId) {\n\t\t\tconst connection = this.writer.currentConnection();\n\t\t\tif (connection !== undefined) {\n\t\t\t\tthis.pendingCapabilities.set(connection, command.capabilities ?? []);\n\t\t\t\tthis.writer.setConnectionCapabilities(connection, command.capabilities ?? []);\n\t\t\t}\n\t\t\treturn { id: command.id, type: \"response\", command: \"set_client_info\", success: true } as RpcResponse;\n\t\t}\n\t\tif (controls.has(command.type)) return undefined;\n\t\tif (!command.sessionId) return error(command.id, command.type, RPC_ERROR_MISSING_SESSION_ID);\n\t\ttry {\n\t\t\tthis.registry.getForCommand(command.sessionId, command.type);\n\t\t\tconst binding = this.bindings.get(command.sessionId);\n\t\t\tif (!binding) return error(command.id, command.type, RPC_ERROR_UNKNOWN_SESSION);\n\t\t\tawait binding.handle(command);\n\t\t\treturn undefined;\n\t\t} catch (cause) {\n\t\t\treturn error(command.id, command.type, this.code(cause));\n\t\t}\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tthis.stopSweep();\n\t\tawait Promise.all(\n\t\t\t[...this.bindings.entries()].map(async ([sessionId, binding]) => {\n\t\t\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: true });\n\t\t\t\tif (!claim) return;\n\t\t\t\tif (claim.finalizer) {\n\t\t\t\t\tawait this.finalizeClose(sessionId, binding, () =>\n\t\t\t\t\t\tthis.writer.closeSession(\n\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t{ type: \"response\", command: \"close_session\", success: true, data: {} },\n\t\t\t\t\t\t\t\"host_shutdown\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else await this.finalizations.get(sessionId)?.promise;\n\t\t\t\tthis.writer.forgetSession(sessionId);\n\t\t\t}),\n\t\t);\n\t\tthis.bindings.clear();\n\t}\n\n\t/**\n\t * One occupancy sweep. Evicts open sessions idle longer than idleEvictionMs,\n\t * where \"idle\" is the COMPLETE session-owned activity contract\n\t * (`AgentSession.isSessionBusy`: agent run, bash, background terminal jobs and\n\t * other published wake sources, compaction, barrier-held session work) - busy\n\t * sessions restart their idle clock instead, so work that outlives a turn is\n\t * never killed. While the host reports memory pressure the window is HALVED, so an\n\t * idle session's memory returns to the process sooner. Fires onEmptyExit once the\n\t * registry has STAYED empty for emptyExitMs with the exit permitted; any live session\n\t * or connected client resets that window. Runs on an unref'd interval and is safe to\n\t * call directly.\n\t */\n\tsweepIdleSessions(): void {\n\t\tconst now = this.idleNow();\n\t\tconst idleEvictionMs = this.memoryPressure ? this.idleEvictionMs / 2 : this.idleEvictionMs;\n\t\tif (Number.isFinite(idleEvictionMs)) {\n\t\t\tfor (const { sessionId, status } of this.registry.list()) {\n\t\t\t\tif (status !== \"open\") continue;\n\t\t\t\tconst entry = this.registry.peek(sessionId);\n\t\t\t\tif (!entry) continue;\n\t\t\t\tif (entry.worker?.busy || entry.runtime?.session.isSessionBusy) {\n\t\t\t\t\t// Session-owned work defers eviction; the window restarts when it settles.\n\t\t\t\t\tentry.lastCommandAt = now;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (now - entry.lastCommandAt >= idleEvictionMs) void this.evictIdleSession(sessionId);\n\t\t\t}\n\t\t}\n\t\tif (Number.isFinite(this.emptyExitMs)) {\n\t\t\tif (this.registry.size === 0 && (this.canExitWhenEmpty?.() ?? true)) {\n\t\t\t\tif (this.emptySince === undefined) this.emptySince = now;\n\t\t\t\telse if (now - this.emptySince >= this.emptyExitMs) {\n\t\t\t\t\tthis.stopSweep();\n\t\t\t\t\tthis.onEmptyExit?.();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.emptySince = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Idle-session eviction: the same refcounted close sequence as an explicit\n\t * close_session, draining every attachment because eviction ends the shared\n\t * session, not one client's claim. Races with concurrent lifecycle paths are\n\t * tolerated the same way releaseOwnedSession tolerates them.\n\t *\n\t * Evicting a RETAINED session is a PARK, not a close: that session was opened to\n\t * outlive its clients, so the terminal record names the file it reopens by\n\t * (`session_parked`) instead of reporting a close nobody requested. The teardown\n\t * itself is identical - retention never outlives the idle window.\n\t */\n\tprivate async evictIdleSession(sessionId: string, reason?: RpcSessionClosedReason): Promise<void> {\n\t\t// Read before the claim: the entry is gone once the teardown completes, and a park\n\t\t// record without the session's path would not be actionable (so a retained session\n\t\t// with no file to reopen by ends as an ordinary close).\n\t\tconst retained = this.registry.peek(sessionId);\n\t\tconst parkedPath = retained?.retainOnDisconnect === true ? retained.sessionPath : undefined;\n\t\t// A failed claim means an explicit close raced us and owns the entry now.\n\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: true });\n\t\tif (!claim) return;\n\t\tconst binding = this.bindings.get(sessionId);\n\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\tthis.forgetSessionOwnership(sessionId);\n\t\tif (claim.finalizer) {\n\t\t\tawait this.finalizeClose(sessionId, binding, () =>\n\t\t\t\t// A drain names ITS reason on the close record. An idle sweep of a RETAINED\n\t\t\t\t// session parks instead: the file reopens by path. Anything else is a close.\n\t\t\t\tparkedPath !== undefined && reason === undefined\n\t\t\t\t\t? this.writer.parkSession(sessionId, parkedPath)\n\t\t\t\t\t: this.writer.closeSession(\n\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t{ type: \"response\", command: \"close_session\", success: true, data: {} },\n\t\t\t\t\t\t\treason ?? \"idle_evicted\",\n\t\t\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tawait this.finalizations.get(sessionId)?.promise;\n\t\t}\n\t\t// The runtime is disposed and routing handles are unique per process\n\t\t// epoch, so nothing can emit under this id again: drop the writer's\n\t\t// per-session bookkeeping instead of retaining it for the host's life.\n\t\tthis.writer.forgetSession(sessionId);\n\t}\n\n\t/** Drops per-connection records for a handle the host closed on its own. */\n\tprivate forgetSessionOwnership(sessionId: string): void {\n\t\tfor (const [connection, owned] of this.sessionsByConnection) {\n\t\t\towned.delete(sessionId);\n\t\t\tif (owned.size === 0) this.sessionsByConnection.delete(connection);\n\t\t}\n\t\tthis.widths.delete(sessionId);\n\t}\n\n\tprivate stopSweep(): void {\n\t\tif (this.sweepTimer === undefined) return;\n\t\tclearInterval(this.sweepTimer);\n\t\tthis.sweepTimer = undefined;\n\t}\n\n\tprivate openWithBarrier(command: Extract<RpcCommand, { type: \"open_session\" }>): Promise<RpcResponse | undefined> {\n\t\tconst owner = this.writer.currentConnection();\n\t\tif (owner === undefined) return this.open(command);\n\t\tlet resolveBarrier!: () => void;\n\t\tconst barrier = new Promise<void>((resolve) => {\n\t\t\tresolveBarrier = resolve;\n\t\t});\n\t\tconst opens = this.opensByConnection.get(owner) ?? new Set<Promise<void>>();\n\t\topens.add(barrier);\n\t\tthis.opensByConnection.set(owner, opens);\n\t\treturn this.open(command, owner).finally(() => {\n\t\t\tresolveBarrier();\n\t\t\topens.delete(barrier);\n\t\t\tif (opens.size === 0) this.opensByConnection.delete(owner);\n\t\t});\n\t}\n\n\tprivate async open(\n\t\tcommand: Extract<RpcCommand, { type: \"open_session\" }>,\n\t\towner?: string,\n\t): Promise<RpcResponse | undefined> {\n\t\t// The opaque per-session inputs are parsed HERE, at the wire boundary, so the\n\t\t// registry, the runtime and the extensions downstream receive values already\n\t\t// proven to satisfy every documented cap.\n\t\tconst kindError = sessionKindError(command.kind);\n\t\tif (kindError) return error(command.id, \"open_session\", `${RPC_ERROR_INVALID_SESSION_KIND}: ${kindError}`);\n\t\tconst contextError = sessionContextError(command.context);\n\t\tif (contextError)\n\t\t\treturn error(command.id, \"open_session\", `${RPC_ERROR_INVALID_SESSION_CONTEXT}: ${contextError}`);\n\t\tconst autoTitleError = sessionAutoTitleError(command.auto_title);\n\t\tif (autoTitleError)\n\t\t\treturn error(command.id, \"open_session\", `${RPC_ERROR_INVALID_LAUNCH_PROFILE}: ${autoTitleError}`);\n\t\tlet opened: OpenRpcSession | undefined;\n\t\ttry {\n\t\t\topened = await this.registry.openSession(\n\t\t\t\t{\n\t\t\t\t\tcwd: command.cwd ?? this.defaults.cwd,\n\t\t\t\t\tsessionPath: command.sessionPath,\n\t\t\t\t\tpermissionPreset: command.permissionPreset ?? this.defaults.permissionPreset,\n\t\t\t\t\tcreationModel:\n\t\t\t\t\t\tcommand.provider && command.modelId\n\t\t\t\t\t\t\t? { provider: command.provider, modelId: command.modelId }\n\t\t\t\t\t\t\t: this.defaults.creationModel,\n\t\t\t\t\tinitialThinkingLevel: command.thinkingLevel ?? this.defaults.initialThinkingLevel,\n\t\t\t\t\tsessionKind: command.kind,\n\t\t\t\t\tsessionContext: command.context,\n\t\t\t\t\t...(typeof command.auto_title === \"boolean\" ? { autoTitle: command.auto_title } : {}),\n\t\t\t\t},\n\t\t\t\t// Host lifecycle policy, deliberately outside the immutable launch profile.\n\t\t\t\t{ retainOnDisconnect: command.retain_on_disconnect === true },\n\t\t\t);\n\t\t\tconst openedSession = opened;\n\t\t\tconst entry = this.registry.getForCommand(openedSession.sessionId, \"open_session\");\n\t\t\tthis.writer.setSessionKind(openedSession.sessionId, entry.kind);\n\t\t\tif (owner !== undefined) {\n\t\t\t\tif (!this.writer.hasRegisteredConnectionCapabilities(owner))\n\t\t\t\t\tthis.writer.setConnectionCapabilities(\n\t\t\t\t\t\towner,\n\t\t\t\t\t\tthis.pendingCapabilities.get(owner) ?? this.connectionOptions?.capabilities ?? [],\n\t\t\t\t\t);\n\t\t\t\tthis.writer.attachConnectionToSession(owner, openedSession.sessionId);\n\t\t\t}\n\t\t\t// A client that dies without close_session (terminal closed, SIGKILL, dropped\n\t\t\t// SSH) still holds this handle's attachment and its path reservation. Remember\n\t\t\t// which connection owns it so releaseConnection() can close exactly that.\n\t\t\tif (owner !== undefined) {\n\t\t\t\tconst owned = this.sessionsByConnection.get(owner) ?? new Map<string, number>();\n\t\t\t\towned.set(openedSession.sessionId, (owned.get(openedSession.sessionId) ?? 0) + 1);\n\t\t\t\tthis.sessionsByConnection.set(owner, owned);\n\t\t\t}\n\t\t\tif (!this.bindings.has(openedSession.sessionId)) {\n\t\t\t\tthis.bindings.set(\n\t\t\t\t\topenedSession.sessionId,\n\t\t\t\t\tawait this.createBinding(\n\t\t\t\t\t\topenedSession.sessionId,\n\t\t\t\t\t\tentry,\n\t\t\t\t\t\tthis.writer,\n\t\t\t\t\t\t() => void this.close({ type: \"close_session\", sessionId: openedSession.sessionId }),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...this.connectionOptions,\n\t\t\t\t\t\t\tcapabilities:\n\t\t\t\t\t\t\t\towner !== undefined\n\t\t\t\t\t\t\t\t\t? (this.pendingCapabilities.get(owner) ?? this.connectionOptions?.capabilities ?? [])\n\t\t\t\t\t\t\t\t\t: this.connectionOptions?.capabilities,\n\t\t\t\t\t\t\tsharedWidth: {\n\t\t\t\t\t\t\t\tgetWidth: () => {\n\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId);\n\t\t\t\t\t\t\t\t\treturn widths?.size ? Math.min(...widths.values()) : 80;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetWidth: (connectionId, width) => {\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) {\n\t\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId) ?? new Map<string, number>();\n\t\t\t\t\t\t\t\t\t\twidths.set(connectionId, width);\n\t\t\t\t\t\t\t\t\t\tthis.widths.set(openedSession.sessionId, widths);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tclearWidth: (connectionId) => {\n\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId);\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) widths?.delete(connectionId);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetCapabilities: (connectionId, capabilities) => {\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) {\n\t\t\t\t\t\t\t\t\t\tthis.writer.setConnectionCapabilities(connectionId, capabilities);\n\t\t\t\t\t\t\t\t\t\tthis.pendingCapabilities.set(connectionId, [...capabilities]);\n\t\t\t\t\t\t\t\t\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\thasRenderedComponents: (sessionId) => this.writer.hasCapableConnection(sessionId),\n\n\t\t\t\t\t\t\t\tconnectionId: () => this.writer.currentConnection(),\n\t\t\t\t\t\t\t\tonChange: () => {\n\t\t\t\t\t\t\t\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tif (entry.worker) entry.worker.bindingReady = true;\n\t\t\t\tif (entry.worker)\n\t\t\t\t\tvoid entry.worker.exited.then(async () => {\n\t\t\t\t\t\tawait this.finalizations.get(openedSession.sessionId)?.promise;\n\t\t\t\t\t\tthis.bindings.delete(openedSession.sessionId);\n\t\t\t\t\t\tthis.forgetSessionOwnership(openedSession.sessionId);\n\t\t\t\t\t\tthis.writer.forgetSession(openedSession.sessionId);\n\t\t\t\t\t});\n\t\t\t}\n\t\t\tif (owner !== undefined && this.releasedConnections.has(owner)) {\n\t\t\t\tthis.releaseOwnerAttachment(owner, openedSession.sessionId);\n\t\t\t\tawait this.releaseOwnedSession(openedSession.sessionId);\n\t\t\t}\n\t\t\tconst state =\n\t\t\t\tentry.worker?.snapshot?.state ?? (entry.runtime ? buildRpcSessionState(entry.runtime.session) : undefined);\n\t\t\tif (!state) throw new Error(\"Session state was not created\");\n\t\t\tthis.writer.enqueue(opened.sessionId, {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"open_session\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tsessionId: opened.sessionId,\n\t\t\t\t\tstate,\n\t\t\t\t\t...(opened.attached ? { attached: true } : {}),\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn undefined;\n\t\t} catch (cause) {\n\t\t\tif (opened) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.registry.close(opened.sessionId);\n\t\t\t\t} catch {\n\t\t\t\t\t/* The open rollback has already removed the entry. */\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn error(command.id, \"open_session\", this.code(cause), this.detail(cause));\n\t\t}\n\t}\n\n\t/**\n\t * Releases every session a dropped connection still owned. Each handle goes through\n\t * the same refcounted close as an explicit close_session, so a session another\n\t * connection is still attached to keeps running and only the last owner tears it down.\n\t */\n\tasync releaseConnection(connectionId: string): Promise<void> {\n\t\tthis.releasedConnections.add(connectionId);\n\t\tthis.writer.clearConnectionCapabilities(connectionId);\n\t\tfor (const sessionId of this.sessionsByConnection.get(connectionId)?.keys() ?? [])\n\t\t\tthis.writer.detachConnectionFromSession(connectionId, sessionId);\n\t\tfor (const widths of this.widths.values()) widths.delete(connectionId);\n\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\tconst opens = this.opensByConnection.get(connectionId);\n\t\tconst owned = this.sessionsByConnection.get(connectionId);\n\t\tthis.sessionsByConnection.delete(connectionId);\n\t\tif (owned === undefined) {\n\t\t\tif (opens) await Promise.all([...opens]);\n\t\t\tthis.releasedConnections.delete(connectionId);\n\t\t\treturn;\n\t\t}\n\t\tawait Promise.all(\n\t\t\t[...owned].map(async ([sessionId, count]) => {\n\t\t\t\tfor (let attachment = 0; attachment < count; attachment++) {\n\t\t\t\t\t// Headless completion contract: a turn survives its client's death and\n\t\t\t\t\t// runs to settlement (the host lifecycle keeps the process alive on\n\t\t\t\t\t// active turns even with zero connections). Releasing mid-turn aborts\n\t\t\t\t\t// the run and seals the session before agent_settled reaches the\n\t\t\t\t\t// lifecycle observer, leaking the busy counter so the host never\n\t\t\t\t\t// idle-exits. Defer - never skip - the release until the turn settles,\n\t\t\t\t\t// so the dropped owner's reservation still frees afterwards.\n\t\t\t\t\t//\n\t\t\t\t\t// A retained session is never closed by a drop, so it has nothing to defer:\n\t\t\t\t\t// release the attachment now - the client is already gone and must not keep\n\t\t\t\t\t// counting - and let the turn run to settlement on its own.\n\t\t\t\t\tconst live = this.registry.peek(sessionId);\n\t\t\t\t\tconst retained = live?.retainOnDisconnect === true;\n\t\t\t\t\tconst session = live?.state === \"open\" ? live.runtime?.session : undefined;\n\t\t\t\t\tif (!retained && live?.state === \"open\" && live.worker?.snapshot?.streaming) {\n\t\t\t\t\t\tconst unsubscribe = live.worker.subscribeSettled(() => {\n\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\tvoid this.releaseOwnedSession(sessionId).catch((cause: unknown) => {\n\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t`senpi rpc deferred worker release ${sessionId} failed: ${String(cause)}\\n`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!retained && session?.isStreaming) {\n\t\t\t\t\t\tlet released = false;\n\t\t\t\t\t\tconst unsubscribe = session.subscribe((event) => {\n\t\t\t\t\t\t\tif (event.type !== \"agent_settled\" && event.type !== \"agent_idle\") return;\n\t\t\t\t\t\t\tif (released) return;\n\t\t\t\t\t\t\treleased = true;\n\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\tvoid this.releaseOwnedSession(sessionId).catch((cause) => {\n\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t`senpi rpc deferred release for session ${sessionId} failed: ${String(cause)}\\n`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.releaseOwnedSession(sessionId);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t\tif (opens) await Promise.all([...opens]);\n\t\tthis.releasedConnections.delete(connectionId);\n\t}\n\n\t/**\n\t * One owned handle's refcounted close: the same sequence as an explicit\n\t * close_session, tolerant of races with other lifecycle paths (an entry\n\t * already closed or claimed elsewhere is simply skipped), except that it claims\n\t * a DETACH: a retained entry keeps running at zero attachments instead of\n\t * closing, so this path releases the client's claim without ending the session.\n\t * Disposal, pending\n\t * extension-UI cancellation and binding removal happen only when this was the\n\t * LAST attachment (the entry transitioned to \"closing\"): surviving\n\t * attachments keep the shared binding and their event stream.\n\t */\n\tprivate async releaseOwnedSession(sessionId: string): Promise<void> {\n\t\t// A failed claim means the entry is already closed or owned by another path.\n\t\t// A retained entry answers the detach by staying open: no finalizer, nothing to join.\n\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: false, detach: true });\n\t\tif (!claim) return;\n\t\tif (!claim.finalizer) {\n\t\t\tawait this.finalizations.get(sessionId)?.promise;\n\t\t\treturn;\n\t\t}\n\t\tconst binding = this.bindings.get(sessionId);\n\t\t// Pending UI requests are session-owned, not connection-owned: a question\n\t\t// asked through one connection stays answerable by every other attachment.\n\t\t// Cancel them only here, where the refcount has already decided the session\n\t\t// is being torn down, never on any owner drop.\n\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\tawait this.finalizeClose(sessionId, binding);\n\t}\n\n\t/**\n\t * Releases one attachment (or every attachment when draining) and reports\n\t * whether this caller became the finalizer. The join token is installed inside\n\t * the registry callback, before any await, so a close that lands between the\n\t * claim and finalizeClose() always finds a token to wait on instead of\n\t * answering ahead of the terminal records.\n\t */\n\tprivate claimClose(sessionId: string, options: CloseClaimOptions): { finalizer: boolean } {\n\t\tlet finalizer = true;\n\t\tconst onRole = (isFinalizer: boolean): void => {\n\t\t\tfinalizer = isFinalizer;\n\t\t\tif (isFinalizer && !this.finalizations.has(sessionId))\n\t\t\t\tthis.finalizations.set(sessionId, this.createFinalization());\n\t\t};\n\t\tlet entry = this.registry.beginClose(sessionId, onRole, { detach: options.detach });\n\t\twhile (options.drainAttachments && entry.state === \"open\") entry = this.registry.beginClose(sessionId, onRole);\n\t\treturn { finalizer: finalizer && entry.state === \"closing\" };\n\t}\n\n\t/** claimClose() for lifecycle paths that treat a lost race as \"nothing to do\". */\n\tprivate tryClaimClose(sessionId: string, options: CloseClaimOptions): { finalizer: boolean } | undefined {\n\t\ttry {\n\t\t\treturn this.claimClose(sessionId, options);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async close(command: Extract<RpcCommand, { type: \"close_session\" }>): Promise<RpcResponse | undefined> {\n\t\tconst response = {\n\t\t\tid: command.id,\n\t\t\ttype: \"response\" as const,\n\t\t\tcommand: \"close_session\" as const,\n\t\t\tsuccess: true as const,\n\t\t\tdata: {},\n\t\t};\n\t\t// A close releases the CALLER's attachment, and routing handles are public on a\n\t\t// shared host (`list_sessions` publishes every one of them), so ownership - not\n\t\t// knowledge of the handle - authorizes it: a connection that never attached holds\n\t\t// no attachment, and answering it would release another client's claim and could\n\t\t// tear down a session it never opened. A host with no per-connection identity\n\t\t// (stdio) has no ownership to check and keeps answering every close as before.\n\t\tconst owner = this.writer.currentConnection();\n\t\tif (owner !== undefined && this.sessionsByConnection.get(owner)?.has(command.sessionId) !== true)\n\t\t\treturn error(command.id, \"close_session\", RPC_ERROR_UNKNOWN_SESSION);\n\t\tconst reply = this.writer.reserveCloseResponse(command.sessionId, response);\n\t\tif (!reply) return undefined;\n\t\t// Admission and claiming are synchronous, before any teardown await. A\n\t\t// saturated requester neither releases an attachment nor joins a promise.\n\t\tlet claim: { finalizer: boolean };\n\t\ttry {\n\t\t\tclaim = this.claimClose(command.sessionId, { drainAttachments: false });\n\t\t} catch (cause) {\n\t\t\treply.release();\n\t\t\treturn error(command.id, \"close_session\", this.code(cause));\n\t\t}\n\t\ttry {\n\t\t\tif (owner !== undefined) this.releaseOwnerAttachment(owner, command.sessionId);\n\t\t\tif (claim.finalizer) {\n\t\t\t\tawait this.finalizeClose(command.sessionId, this.bindings.get(command.sessionId), () =>\n\t\t\t\t\treply.complete(true, \"client_close\"),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait this.finalizations.get(command.sessionId)?.promise;\n\t\t\t\treply.complete(false);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} finally {\n\t\t\treply.release();\n\t\t}\n\t}\n\n\t/** Detaches the closing connection's UI/width state; a rerender failure must not abort the close. */\n\tprivate releaseOwnerAttachment(owner: string, sessionId: string): void {\n\t\tthis.widths.get(sessionId)?.delete(owner);\n\t\tthis.writer.detachConnectionFromSession(owner, sessionId);\n\t\tfor (const binding of this.bindings.values()) {\n\t\t\ttry {\n\t\t\t\tbinding.rerenderComponents?.();\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc rerender after close of session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t}\n\t\tconst owned = this.sessionsByConnection.get(owner);\n\t\tconst count = owned?.get(sessionId);\n\t\tif (!owned || count === undefined) return;\n\t\tif (count === 1) owned.delete(sessionId);\n\t\telse owned.set(sessionId, count - 1);\n\t\tif (owned.size === 0) this.sessionsByConnection.delete(owner);\n\t}\n\n\t/**\n\t * Runs the finalizer side of a close for a handle whose beginClose() made this\n\t * caller the owner: dispose the binding, complete the registry teardown, emit\n\t * the terminal records, then release joiners. Every step is guarded so the join\n\t * token always resolves and a failing binding yields one logged line, never a\n\t * second response or an escaped rejection.\n\t */\n\tprivate async finalizeClose(\n\t\tsessionId: string,\n\t\tbinding: RpcSessionBinding | undefined,\n\t\tterminal?: () => void,\n\t): Promise<void> {\n\t\tconst finalization = this.finalizations.get(sessionId) ?? this.createFinalization();\n\t\tthis.finalizations.set(sessionId, finalization);\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tawait binding?.dispose();\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc binding dispose for session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t\tthis.bindings.delete(sessionId);\n\t\t\ttry {\n\t\t\t\tawait this.registry.closeMarked(sessionId);\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc close for session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t\t// closeMarked may return at the grace deadline while ownership remains;\n\t\t\t// terminal records must still observe the exit callback's registry removal.\n\t\t\tawait this.registry.peek(sessionId)?.closeCompletion;\n\t\t\tterminal?.();\n\t\t} finally {\n\t\t\tfinalization.resolve();\n\t\t\tthis.finalizations.delete(sessionId);\n\t\t}\n\t}\n\n\tprivate createFinalization(): { promise: Promise<void>; resolve: () => void } {\n\t\tlet resolveFinalization: (() => void) | undefined;\n\t\tconst promise = new Promise<void>((resolve) => {\n\t\t\tresolveFinalization = resolve;\n\t\t});\n\t\treturn { promise, resolve: () => resolveFinalization?.() };\n\t}\n\n\t/** The machine-readable half of a refusal, when the registry attached one. */\n\tprivate detail(cause: unknown): Readonly<Record<string, unknown>> | undefined {\n\t\treturn cause instanceof RpcSessionRegistryError ? cause.detail : undefined;\n\t}\n\n\tprivate code(cause: unknown): string {\n\t\tif (cause instanceof RpcSessionRegistryError) {\n\t\t\treturn cause.code === RPC_ERROR_OPEN_FAILED ? cause.message : cause.code;\n\t\t}\n\t\tif (cause instanceof Error && [RPC_ERROR_UNKNOWN_SESSION, RPC_ERROR_SESSION_CLOSING].includes(cause.message)) {\n\t\t\treturn cause.message;\n\t\t}\n\t\treturn cause instanceof Error && cause.message\n\t\t\t? `${RPC_ERROR_OPEN_FAILED}: ${cause.message}`\n\t\t\t: RPC_ERROR_UNKNOWN_SESSION;\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-command-router.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-command-router.ts"],"names":[],"mappings":"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","sourcesContent":["import { VERSION } from \"../../config.ts\";\nimport { buildRpcSessionState } from \"./connection-handler.ts\";\nimport {\n\tAUTO_TITLE_PER_SESSION_CAPABILITY,\n\tAUTO_TITLE_SESSIONS_CAPABILITY,\n\tMEDIA_PLACEHOLDERS_CAPABILITY,\n\tRETAIN_ON_DISCONNECT_CAPABILITY,\n\tSESSION_CONTEXT_CAPABILITY,\n\tSESSION_KIND_CAPABILITY,\n} from \"./custom-capability.ts\";\nimport { protocolIdentity } from \"./protocol-identity.ts\";\nimport { sessionAutoTitleError, sessionContextError, sessionKindError } from \"./rpc-input-validation.ts\";\nimport type { RpcCommand, RpcResponse, RpcSessionClosedReason } from \"./rpc-types.ts\";\nimport {\n\tRPC_ERROR_INVALID_LAUNCH_PROFILE,\n\tRPC_ERROR_INVALID_SESSION_CONTEXT,\n\tRPC_ERROR_INVALID_SESSION_KIND,\n\tRPC_ERROR_MISSING_SESSION_ID,\n\tRPC_ERROR_OPEN_FAILED,\n\tRPC_ERROR_SESSION_CLOSING,\n\tRPC_ERROR_UNKNOWN_SESSION,\n} from \"./rpc-types.ts\";\nimport { runWithSessionAttribution } from \"./session-attribution.ts\";\nimport { createRpcSessionBinding, type RpcSessionBinding } from \"./session-binding.ts\";\nimport type { SessionEventWriter } from \"./session-event-writer.ts\";\nimport type { OpenRpcSession, RpcSessionLaunchProfile, RpcSessionRegistry } from \"./session-registry.ts\";\nimport { RpcSessionRegistryError } from \"./session-registry.ts\";\n\nconst controls = new Set([\"get_protocol_info\", \"open_session\", \"close_session\", \"list_sessions\"]);\n\n/** How often a draining host re-checks whether the work it is waiting for has settled. */\nconst DRAIN_SWEEP_MS = 50;\n\n/** Binding factory seam, injectable so host wiring is testable without a full runtime stack. */\nexport type RpcBindingFactory = typeof createRpcSessionBinding;\n\n/**\n * Occupancy policy for the shared multi-session host. All fields are opt-in:\n * a router constructed without a policy keeps today's behavior (sessions live\n * until close_session; the host never self-exits).\n */\nexport interface RpcSessionIdlePolicy {\n\t/** Injectable clock (defaults to Date.now) for deterministic tests. */\n\tnow?: () => number;\n\t/** Evict open sessions whose last routed command or session-owned work settled longer ago than this. */\n\tidleEvictionMs?: number;\n\t/** Invoke onEmptyExit once the registry has stayed empty for this long. */\n\temptyExitMs?: number;\n\t/** Host shutdown hook fired by the empty-exit window; called at most once. */\n\tonEmptyExit?: () => void;\n\t/**\n\t * Consulted every tick before the empty-exit window advances. Returning false\n\t * both blocks the exit and resets the window, so a host with a connected but\n\t * sessionless client stays up instead of exiting under its supervisor.\n\t */\n\tcanExitWhenEmpty?: () => boolean;\n}\n\n/**\n * How one caller claims a close. `detach` (a client going away) is the only mode a\n * retained session may answer by staying open, so it is unrepresentable together\n * with `drainAttachments` - draining ENDS the session and must always reach zero.\n */\ntype CloseClaimOptions = { drainAttachments: true; detach?: never } | { drainAttachments: false; detach?: boolean };\n\nfunction error(\n\tid: string | undefined,\n\tcommand: string,\n\tcode: string,\n\tdata?: Readonly<Record<string, unknown>>,\n): RpcResponse {\n\t// `errorData` carries what a client has to ACT on (who holds a path, when to retry); the\n\t// stable code stays the string every existing client already switches on.\n\treturn {\n\t\tid,\n\t\ttype: \"response\",\n\t\tcommand,\n\t\tsuccess: false,\n\t\terror: code,\n\t\t...(data && { errorCode: code, errorData: data }),\n\t};\n}\n\n/** Routes control messages and enforces a routing handle for every session command. */\nexport class SessionCommandRouter {\n\tprivate readonly bindings = new Map<string, RpcSessionBinding>();\n\t/** Session handles opened by each connection, with one count per attachment. */\n\tprivate readonly sessionsByConnection = new Map<string, Map<string, number>>();\n\t/** Opens currently awaiting runtime/binding setup, keyed by connection. */\n\tprivate readonly opensByConnection = new Map<string, Set<Promise<void>>>();\n\t/** Connections whose socket has already been detached. */\n\tprivate readonly releasedConnections = new Set<string>();\n\tprivate readonly registry: Pick<\n\t\tRpcSessionRegistry,\n\t\t\"openSession\" | \"peek\" | \"getForCommand\" | \"beginClose\" | \"close\" | \"closeMarked\" | \"list\" | \"size\"\n\t>;\n\tprivate readonly writer: SessionEventWriter;\n\tprivate readonly defaults: Pick<\n\t\tRpcSessionLaunchProfile,\n\t\t\"cwd\" | \"permissionPreset\" | \"creationModel\" | \"initialThinkingLevel\"\n\t>;\n\tprivate readonly createBinding: typeof createRpcSessionBinding;\n\tprivate readonly connectionOptions: Parameters<typeof createRpcSessionBinding>[4];\n\tprivate readonly widths = new Map<string, Map<string, number>>();\n\tprivate readonly pendingCapabilities = new Map<string, string[]>();\n\tprivate readonly finalizations = new Map<string, { promise: Promise<void>; resolve: () => void }>();\n\tprivate readonly idleNow: () => number;\n\tprivate readonly idleEvictionMs: number;\n\tprivate readonly emptyExitMs: number;\n\tprivate readonly onEmptyExit?: () => void;\n\tprivate readonly canExitWhenEmpty?: () => boolean;\n\tprivate sweepTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate drainTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate draining = false;\n\tprivate emptySince: number | undefined;\n\t/** Halves the idle window while the host reports memory pressure; never refuses work. */\n\tprivate memoryPressure = false;\n\n\tconstructor(\n\t\tregistry: Pick<\n\t\t\tRpcSessionRegistry,\n\t\t\t\"openSession\" | \"peek\" | \"getForCommand\" | \"beginClose\" | \"close\" | \"closeMarked\" | \"list\" | \"size\"\n\t\t>,\n\t\twriter: SessionEventWriter,\n\t\tdefaults: Pick<RpcSessionLaunchProfile, \"cwd\" | \"permissionPreset\" | \"creationModel\" | \"initialThinkingLevel\">,\n\t\tcreateBinding: typeof createRpcSessionBinding = createRpcSessionBinding,\n\t\tconnectionOptions: Parameters<typeof createRpcSessionBinding>[4] = {},\n\t\tidle?: RpcSessionIdlePolicy,\n\t) {\n\t\tthis.registry = registry;\n\t\tthis.writer = writer;\n\t\tthis.defaults = defaults;\n\t\tthis.createBinding = createBinding;\n\t\tthis.connectionOptions = connectionOptions;\n\t\tthis.idleNow = idle?.now ?? Date.now;\n\t\tthis.idleEvictionMs = idle?.idleEvictionMs ?? Number.POSITIVE_INFINITY;\n\t\tthis.emptyExitMs = idle?.emptyExitMs ?? Number.POSITIVE_INFINITY;\n\t\tthis.onEmptyExit = idle?.onEmptyExit;\n\t\tthis.canExitWhenEmpty = idle?.canExitWhenEmpty;\n\t\tif (Number.isFinite(this.idleEvictionMs) || Number.isFinite(this.emptyExitMs)) {\n\t\t\t// Unref'd: occupancy hygiene must never be the reason the event loop stays open.\n\t\t\tconst tickMs = Math.max(20, Math.min(5_000, Math.min(this.idleEvictionMs, this.emptyExitMs) / 4));\n\t\t\tthis.sweepTimer = setInterval(() => this.sweepIdleSessions(), tickMs);\n\t\t\tthis.sweepTimer.unref?.();\n\t\t}\n\t}\n\n\t/** Live sessions the host holds, including ones opening or closing. */\n\tget sessionCount(): number {\n\t\treturn this.registry.size;\n\t}\n\n\t/**\n\t * Hand this host's work to the next generation: park every session the moment it has no client\n\t * attached and nothing running, and leave as soon as none is left. A drain ENDS no work - a\n\t * session mid-turn keeps running, and a session a client is still attached to keeps serving it -\n\t * which is what separates an upgrade from a kill.\n\t */\n\tbeginDrain(): void {\n\t\tif (this.draining) return;\n\t\tthis.draining = true;\n\t\tthis.sweepDrain();\n\t\tif (this.drainTimer !== undefined) return;\n\t\t// Unref'd: a draining host must never be the reason the event loop stays open.\n\t\tthis.drainTimer = setInterval(() => this.sweepDrain(), DRAIN_SWEEP_MS);\n\t\tthis.drainTimer.unref?.();\n\t}\n\n\t/** One drain pass: park what has settled, and exit once the host holds nothing. */\n\tprivate sweepDrain(): void {\n\t\tfor (const { sessionId, status } of this.registry.list()) {\n\t\t\tif (status !== \"open\") continue;\n\t\t\tconst entry = this.registry.peek(sessionId);\n\t\t\tif (!entry || entry.attachments > 0) continue;\n\t\t\t// Session-owned work outlives its client; the park waits for it exactly as the idle\n\t\t\t// sweep does, and the next pass picks the session up once it settles.\n\t\t\tif (entry.worker?.busy || entry.runtime?.session.isSessionBusy) continue;\n\t\t\tvoid this.evictIdleSession(sessionId, \"handoff_parked\");\n\t\t}\n\t\tif (this.registry.size > 0) return;\n\t\tif (this.drainTimer !== undefined) {\n\t\t\tclearInterval(this.drainTimer);\n\t\t\tthis.drainTimer = undefined;\n\t\t}\n\t\tthis.stopSweep();\n\t\tthis.onEmptyExit?.();\n\t}\n\n\t/**\n\t * Raised by the host's memory sampler. Under pressure idle sessions are parked at\n\t * HALF the configured window, which returns their memory to the process sooner.\n\t * Deliberately the only lever: the host never refuses or kills a session for memory.\n\t */\n\tsetMemoryPressure(pressure: boolean): void {\n\t\tthis.memoryPressure = pressure;\n\t}\n\n\t/**\n\t * Every routed command runs inside its session's attribution scope, so a stall the\n\t * loop-lag watchdog observes right after this dispatch can name the session that\n\t * caused it - and anything the command starts inherits the attribution.\n\t */\n\thandle(command: RpcCommand): Promise<RpcResponse | undefined> {\n\t\tconst sessionId = \"sessionId\" in command ? command.sessionId : undefined;\n\t\treturn runWithSessionAttribution({ sessionId }, () => this.dispatch(command));\n\t}\n\n\tprivate async dispatch(command: RpcCommand): Promise<RpcResponse | undefined> {\n\t\tif (command.type === \"get_protocol_info\") {\n\t\t\tconst capabilities = new Set([\n\t\t\t\t\"multi_session\",\n\t\t\t\tAUTO_TITLE_SESSIONS_CAPABILITY,\n\t\t\t\tMEDIA_PLACEHOLDERS_CAPABILITY,\n\t\t\t\t// Host capabilities, not client opt-ins: only a multi-session host owns the\n\t\t\t\t// attachment refcount `open_session.retain_on_disconnect` detaches from, the\n\t\t\t\t// per-session launch profile `context`/`auto_title` travel on, and the session\n\t\t\t\t// listing `kind` filters.\n\t\t\t\tRETAIN_ON_DISCONNECT_CAPABILITY,\n\t\t\t\tSESSION_CONTEXT_CAPABILITY,\n\t\t\t\tSESSION_KIND_CAPABILITY,\n\t\t\t\tAUTO_TITLE_PER_SESSION_CAPABILITY,\n\t\t\t\t...(this.connectionOptions?.capabilities ?? []),\n\t\t\t]);\n\t\t\treturn {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"get_protocol_info\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tprotocolVersion: 1,\n\t\t\t\t\tserverVersion: VERSION,\n\t\t\t\t\tcapabilities: [...capabilities],\n\t\t\t\t\tmode: \"multi\",\n\t\t\t\t\t...protocolIdentity(),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (command.type === \"list_sessions\") {\n\t\t\t// Worker sessions are machine-driven work: a client sees them only by asking, and\n\t\t\t// the opaque context blob travels only on that listing, never to every connection.\n\t\t\tconst rows = this.registry.list();\n\t\t\tconst sessions =\n\t\t\t\tcommand.include_workers === true\n\t\t\t\t\t? rows\n\t\t\t\t\t: rows.filter((row) => row.kind !== \"worker\").map(({ context: _context, ...row }) => row);\n\t\t\treturn {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"list_sessions\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { sessions },\n\t\t\t};\n\t\t}\n\t\tif (command.type === \"open_session\") return this.openWithBarrier(command);\n\t\tif (command.type === \"close_session\") return this.close(command);\n\t\tif (command.type === \"set_client_info\" && !command.sessionId) {\n\t\t\tconst connection = this.writer.currentConnection();\n\t\t\tif (connection !== undefined) {\n\t\t\t\tthis.pendingCapabilities.set(connection, command.capabilities ?? []);\n\t\t\t\tthis.writer.setConnectionCapabilities(connection, command.capabilities ?? []);\n\t\t\t}\n\t\t\treturn { id: command.id, type: \"response\", command: \"set_client_info\", success: true } as RpcResponse;\n\t\t}\n\t\tif (controls.has(command.type)) return undefined;\n\t\tif (!command.sessionId) return error(command.id, command.type, RPC_ERROR_MISSING_SESSION_ID);\n\t\ttry {\n\t\t\tthis.registry.getForCommand(command.sessionId, command.type);\n\t\t\tconst binding = this.bindings.get(command.sessionId);\n\t\t\tif (!binding) return error(command.id, command.type, RPC_ERROR_UNKNOWN_SESSION);\n\t\t\tawait binding.handle(command);\n\t\t\treturn undefined;\n\t\t} catch (cause) {\n\t\t\treturn error(command.id, command.type, this.code(cause));\n\t\t}\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tthis.stopSweep();\n\t\tawait Promise.all(\n\t\t\t[...this.bindings.entries()].map(async ([sessionId, binding]) => {\n\t\t\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: true });\n\t\t\t\tif (!claim) return;\n\t\t\t\tif (claim.finalizer) {\n\t\t\t\t\tawait this.finalizeClose(sessionId, binding, () =>\n\t\t\t\t\t\tthis.writer.closeSession(\n\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t{ type: \"response\", command: \"close_session\", success: true, data: {} },\n\t\t\t\t\t\t\t\"host_shutdown\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else await this.finalizations.get(sessionId)?.promise;\n\t\t\t\tthis.writer.forgetSession(sessionId);\n\t\t\t}),\n\t\t);\n\t\tthis.bindings.clear();\n\t}\n\n\t/**\n\t * One occupancy sweep. Evicts open sessions idle longer than idleEvictionMs,\n\t * where \"idle\" is the COMPLETE session-owned activity contract\n\t * (`AgentSession.isSessionBusy`: agent run, bash, background terminal jobs and\n\t * other published wake sources, compaction, barrier-held session work) - busy\n\t * sessions restart their idle clock instead, so work that outlives a turn is\n\t * never killed. While the host reports memory pressure the window is HALVED, so an\n\t * idle session's memory returns to the process sooner. Fires onEmptyExit once the\n\t * registry has STAYED empty for emptyExitMs with the exit permitted; any live session\n\t * or connected client resets that window. Runs on an unref'd interval and is safe to\n\t * call directly.\n\t */\n\tsweepIdleSessions(): void {\n\t\tconst now = this.idleNow();\n\t\tconst idleEvictionMs = this.memoryPressure ? this.idleEvictionMs / 2 : this.idleEvictionMs;\n\t\tif (Number.isFinite(idleEvictionMs)) {\n\t\t\tfor (const { sessionId, status } of this.registry.list()) {\n\t\t\t\tif (status !== \"open\") continue;\n\t\t\t\tconst entry = this.registry.peek(sessionId);\n\t\t\t\tif (!entry) continue;\n\t\t\t\tif (entry.worker?.busy || entry.runtime?.session.isSessionBusy) {\n\t\t\t\t\t// Session-owned work defers eviction; the window restarts when it settles.\n\t\t\t\t\tentry.lastCommandAt = now;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (now - entry.lastCommandAt >= idleEvictionMs) void this.evictIdleSession(sessionId);\n\t\t\t}\n\t\t}\n\t\tif (Number.isFinite(this.emptyExitMs)) {\n\t\t\tif (this.registry.size === 0 && (this.canExitWhenEmpty?.() ?? true)) {\n\t\t\t\tif (this.emptySince === undefined) this.emptySince = now;\n\t\t\t\telse if (now - this.emptySince >= this.emptyExitMs) {\n\t\t\t\t\tthis.stopSweep();\n\t\t\t\t\tthis.onEmptyExit?.();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.emptySince = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Idle-session eviction: the same refcounted close sequence as an explicit\n\t * close_session, draining every attachment because eviction ends the shared\n\t * session, not one client's claim. Races with concurrent lifecycle paths are\n\t * tolerated the same way releaseOwnedSession tolerates them.\n\t *\n\t * Evicting a RETAINED session is a PARK, not a close: that session was opened to\n\t * outlive its clients, so the terminal record names the file it reopens by\n\t * (`session_parked`) instead of reporting a close nobody requested. The teardown\n\t * itself is identical - retention never outlives the idle window.\n\t */\n\tprivate async evictIdleSession(sessionId: string, reason?: RpcSessionClosedReason): Promise<void> {\n\t\t// Read before the claim: the entry is gone once the teardown completes, and a park\n\t\t// record without the session's path would not be actionable (so a retained session\n\t\t// with no file to reopen by ends as an ordinary close).\n\t\tconst retained = this.registry.peek(sessionId);\n\t\tconst parkedPath = retained?.retainOnDisconnect === true ? retained.sessionPath : undefined;\n\t\t// A failed claim means an explicit close raced us and owns the entry now.\n\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: true });\n\t\tif (!claim) return;\n\t\tconst binding = this.bindings.get(sessionId);\n\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\tthis.forgetSessionOwnership(sessionId);\n\t\tif (claim.finalizer) {\n\t\t\tawait this.finalizeClose(sessionId, binding, () =>\n\t\t\t\t// A drain names ITS reason on the close record. An idle sweep of a RETAINED\n\t\t\t\t// session parks instead: the file reopens by path. Anything else is a close.\n\t\t\t\tparkedPath !== undefined && reason === undefined\n\t\t\t\t\t? this.writer.parkSession(sessionId, parkedPath)\n\t\t\t\t\t: this.writer.closeSession(\n\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t{ type: \"response\", command: \"close_session\", success: true, data: {} },\n\t\t\t\t\t\t\treason ?? \"idle_evicted\",\n\t\t\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tawait this.finalizations.get(sessionId)?.promise;\n\t\t}\n\t\t// The runtime is disposed and routing handles are unique per process\n\t\t// epoch, so nothing can emit under this id again: drop the writer's\n\t\t// per-session bookkeeping instead of retaining it for the host's life.\n\t\tthis.writer.forgetSession(sessionId);\n\t}\n\n\t/** Drops per-connection records for a handle the host closed on its own. */\n\tprivate forgetSessionOwnership(sessionId: string): void {\n\t\tfor (const [connection, owned] of this.sessionsByConnection) {\n\t\t\towned.delete(sessionId);\n\t\t\tif (owned.size === 0) this.sessionsByConnection.delete(connection);\n\t\t}\n\t\tthis.widths.delete(sessionId);\n\t}\n\n\tprivate stopSweep(): void {\n\t\tif (this.sweepTimer === undefined) return;\n\t\tclearInterval(this.sweepTimer);\n\t\tthis.sweepTimer = undefined;\n\t}\n\n\tprivate openWithBarrier(command: Extract<RpcCommand, { type: \"open_session\" }>): Promise<RpcResponse | undefined> {\n\t\tconst owner = this.writer.currentConnection();\n\t\tif (owner === undefined) return this.open(command);\n\t\tlet resolveBarrier!: () => void;\n\t\tconst barrier = new Promise<void>((resolve) => {\n\t\t\tresolveBarrier = resolve;\n\t\t});\n\t\tconst opens = this.opensByConnection.get(owner) ?? new Set<Promise<void>>();\n\t\t// Every open already accepted anywhere on this host, not just on this connection: the\n\t\t// in-process runtime serves them on ONE loop, so the wait this caller faces is the total.\n\t\tlet inFlight = 0;\n\t\tfor (const pending of this.opensByConnection.values()) inFlight += pending.size;\n\t\topens.add(barrier);\n\t\tthis.opensByConnection.set(owner, opens);\n\t\t// Before the open reaches the loop: a client that later hits its deadline can then say\n\t\t// where it was queued instead of reporting a bare timeout (senpi#1844).\n\t\tif (command.id !== undefined)\n\t\t\tthis.writer.sendOpenQueued(owner, {\n\t\t\t\ttype: \"queued\",\n\t\t\t\tfor_request: command.id,\n\t\t\t\tposition: inFlight + 1,\n\t\t\t\tin_flight: inFlight,\n\t\t\t});\n\t\treturn this.open(command, owner).finally(() => {\n\t\t\tresolveBarrier();\n\t\t\topens.delete(barrier);\n\t\t\tif (opens.size === 0) this.opensByConnection.delete(owner);\n\t\t});\n\t}\n\n\tprivate async open(\n\t\tcommand: Extract<RpcCommand, { type: \"open_session\" }>,\n\t\towner?: string,\n\t): Promise<RpcResponse | undefined> {\n\t\t// The opaque per-session inputs are parsed HERE, at the wire boundary, so the\n\t\t// registry, the runtime and the extensions downstream receive values already\n\t\t// proven to satisfy every documented cap.\n\t\tconst kindError = sessionKindError(command.kind);\n\t\tif (kindError) return error(command.id, \"open_session\", `${RPC_ERROR_INVALID_SESSION_KIND}: ${kindError}`);\n\t\tconst contextError = sessionContextError(command.context);\n\t\tif (contextError)\n\t\t\treturn error(command.id, \"open_session\", `${RPC_ERROR_INVALID_SESSION_CONTEXT}: ${contextError}`);\n\t\tconst autoTitleError = sessionAutoTitleError(command.auto_title);\n\t\tif (autoTitleError)\n\t\t\treturn error(command.id, \"open_session\", `${RPC_ERROR_INVALID_LAUNCH_PROFILE}: ${autoTitleError}`);\n\t\tlet opened: OpenRpcSession | undefined;\n\t\ttry {\n\t\t\topened = await this.registry.openSession(\n\t\t\t\t{\n\t\t\t\t\tcwd: command.cwd ?? this.defaults.cwd,\n\t\t\t\t\tsessionPath: command.sessionPath,\n\t\t\t\t\tpermissionPreset: command.permissionPreset ?? this.defaults.permissionPreset,\n\t\t\t\t\tcreationModel:\n\t\t\t\t\t\tcommand.provider && command.modelId\n\t\t\t\t\t\t\t? { provider: command.provider, modelId: command.modelId }\n\t\t\t\t\t\t\t: this.defaults.creationModel,\n\t\t\t\t\tinitialThinkingLevel: command.thinkingLevel ?? this.defaults.initialThinkingLevel,\n\t\t\t\t\tsessionKind: command.kind,\n\t\t\t\t\tsessionContext: command.context,\n\t\t\t\t\t...(typeof command.auto_title === \"boolean\" ? { autoTitle: command.auto_title } : {}),\n\t\t\t\t},\n\t\t\t\t// Host lifecycle policy, deliberately outside the immutable launch profile.\n\t\t\t\t{ retainOnDisconnect: command.retain_on_disconnect === true },\n\t\t\t);\n\t\t\tconst openedSession = opened;\n\t\t\tconst entry = this.registry.getForCommand(openedSession.sessionId, \"open_session\");\n\t\t\tthis.writer.setSessionKind(openedSession.sessionId, entry.kind);\n\t\t\tif (owner !== undefined) {\n\t\t\t\tif (!this.writer.hasRegisteredConnectionCapabilities(owner))\n\t\t\t\t\tthis.writer.setConnectionCapabilities(\n\t\t\t\t\t\towner,\n\t\t\t\t\t\tthis.pendingCapabilities.get(owner) ?? this.connectionOptions?.capabilities ?? [],\n\t\t\t\t\t);\n\t\t\t\tthis.writer.attachConnectionToSession(owner, openedSession.sessionId);\n\t\t\t}\n\t\t\t// A client that dies without close_session (terminal closed, SIGKILL, dropped\n\t\t\t// SSH) still holds this handle's attachment and its path reservation. Remember\n\t\t\t// which connection owns it so releaseConnection() can close exactly that.\n\t\t\tif (owner !== undefined) {\n\t\t\t\tconst owned = this.sessionsByConnection.get(owner) ?? new Map<string, number>();\n\t\t\t\towned.set(openedSession.sessionId, (owned.get(openedSession.sessionId) ?? 0) + 1);\n\t\t\t\tthis.sessionsByConnection.set(owner, owned);\n\t\t\t}\n\t\t\tif (!this.bindings.has(openedSession.sessionId)) {\n\t\t\t\tthis.bindings.set(\n\t\t\t\t\topenedSession.sessionId,\n\t\t\t\t\tawait this.createBinding(\n\t\t\t\t\t\topenedSession.sessionId,\n\t\t\t\t\t\tentry,\n\t\t\t\t\t\tthis.writer,\n\t\t\t\t\t\t() => void this.close({ type: \"close_session\", sessionId: openedSession.sessionId }),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...this.connectionOptions,\n\t\t\t\t\t\t\tcapabilities:\n\t\t\t\t\t\t\t\towner !== undefined\n\t\t\t\t\t\t\t\t\t? (this.pendingCapabilities.get(owner) ?? this.connectionOptions?.capabilities ?? [])\n\t\t\t\t\t\t\t\t\t: this.connectionOptions?.capabilities,\n\t\t\t\t\t\t\tsharedWidth: {\n\t\t\t\t\t\t\t\tgetWidth: () => {\n\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId);\n\t\t\t\t\t\t\t\t\treturn widths?.size ? Math.min(...widths.values()) : 80;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetWidth: (connectionId, width) => {\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) {\n\t\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId) ?? new Map<string, number>();\n\t\t\t\t\t\t\t\t\t\twidths.set(connectionId, width);\n\t\t\t\t\t\t\t\t\t\tthis.widths.set(openedSession.sessionId, widths);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tclearWidth: (connectionId) => {\n\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId);\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) widths?.delete(connectionId);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetCapabilities: (connectionId, capabilities) => {\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) {\n\t\t\t\t\t\t\t\t\t\tthis.writer.setConnectionCapabilities(connectionId, capabilities);\n\t\t\t\t\t\t\t\t\t\tthis.pendingCapabilities.set(connectionId, [...capabilities]);\n\t\t\t\t\t\t\t\t\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\thasRenderedComponents: (sessionId) => this.writer.hasCapableConnection(sessionId),\n\n\t\t\t\t\t\t\t\tconnectionId: () => this.writer.currentConnection(),\n\t\t\t\t\t\t\t\tonChange: () => {\n\t\t\t\t\t\t\t\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tif (entry.worker) entry.worker.bindingReady = true;\n\t\t\t\tif (entry.worker)\n\t\t\t\t\tvoid entry.worker.exited.then(async () => {\n\t\t\t\t\t\tawait this.finalizations.get(openedSession.sessionId)?.promise;\n\t\t\t\t\t\tthis.bindings.delete(openedSession.sessionId);\n\t\t\t\t\t\tthis.forgetSessionOwnership(openedSession.sessionId);\n\t\t\t\t\t\tthis.writer.forgetSession(openedSession.sessionId);\n\t\t\t\t\t});\n\t\t\t}\n\t\t\tif (owner !== undefined && this.releasedConnections.has(owner)) {\n\t\t\t\tthis.releaseOwnerAttachment(owner, openedSession.sessionId);\n\t\t\t\tawait this.releaseOwnedSession(openedSession.sessionId);\n\t\t\t}\n\t\t\tconst state =\n\t\t\t\tentry.worker?.snapshot?.state ?? (entry.runtime ? buildRpcSessionState(entry.runtime.session) : undefined);\n\t\t\tif (!state) throw new Error(\"Session state was not created\");\n\t\t\tthis.writer.enqueue(opened.sessionId, {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"open_session\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tsessionId: opened.sessionId,\n\t\t\t\t\tstate,\n\t\t\t\t\t...(opened.attached ? { attached: true } : {}),\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn undefined;\n\t\t} catch (cause) {\n\t\t\tif (opened) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.registry.close(opened.sessionId);\n\t\t\t\t} catch {\n\t\t\t\t\t/* The open rollback has already removed the entry. */\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn error(command.id, \"open_session\", this.code(cause), this.detail(cause));\n\t\t}\n\t}\n\n\t/**\n\t * Releases every session a dropped connection still owned. Each handle goes through\n\t * the same refcounted close as an explicit close_session, so a session another\n\t * connection is still attached to keeps running and only the last owner tears it down.\n\t */\n\tasync releaseConnection(connectionId: string): Promise<void> {\n\t\tthis.releasedConnections.add(connectionId);\n\t\tthis.writer.clearConnectionCapabilities(connectionId);\n\t\tfor (const sessionId of this.sessionsByConnection.get(connectionId)?.keys() ?? [])\n\t\t\tthis.writer.detachConnectionFromSession(connectionId, sessionId);\n\t\tfor (const widths of this.widths.values()) widths.delete(connectionId);\n\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\tconst opens = this.opensByConnection.get(connectionId);\n\t\tconst owned = this.sessionsByConnection.get(connectionId);\n\t\tthis.sessionsByConnection.delete(connectionId);\n\t\tif (owned === undefined) {\n\t\t\tif (opens) await Promise.all([...opens]);\n\t\t\tthis.releasedConnections.delete(connectionId);\n\t\t\treturn;\n\t\t}\n\t\tawait Promise.all(\n\t\t\t[...owned].map(async ([sessionId, count]) => {\n\t\t\t\tfor (let attachment = 0; attachment < count; attachment++) {\n\t\t\t\t\t// Headless completion contract: a turn survives its client's death and\n\t\t\t\t\t// runs to settlement (the host lifecycle keeps the process alive on\n\t\t\t\t\t// active turns even with zero connections). Releasing mid-turn aborts\n\t\t\t\t\t// the run and seals the session before agent_settled reaches the\n\t\t\t\t\t// lifecycle observer, leaking the busy counter so the host never\n\t\t\t\t\t// idle-exits. Defer - never skip - the release until the turn settles,\n\t\t\t\t\t// so the dropped owner's reservation still frees afterwards.\n\t\t\t\t\t//\n\t\t\t\t\t// A retained session is never closed by a drop, so it has nothing to defer:\n\t\t\t\t\t// release the attachment now - the client is already gone and must not keep\n\t\t\t\t\t// counting - and let the turn run to settlement on its own.\n\t\t\t\t\tconst live = this.registry.peek(sessionId);\n\t\t\t\t\tconst retained = live?.retainOnDisconnect === true;\n\t\t\t\t\tconst session = live?.state === \"open\" ? live.runtime?.session : undefined;\n\t\t\t\t\tif (!retained && live?.state === \"open\" && live.worker?.snapshot?.streaming) {\n\t\t\t\t\t\tconst unsubscribe = live.worker.subscribeSettled(() => {\n\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\tvoid this.releaseOwnedSession(sessionId).catch((cause: unknown) => {\n\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t`senpi rpc deferred worker release ${sessionId} failed: ${String(cause)}\\n`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!retained && session?.isStreaming) {\n\t\t\t\t\t\tlet released = false;\n\t\t\t\t\t\tconst unsubscribe = session.subscribe((event) => {\n\t\t\t\t\t\t\tif (event.type !== \"agent_settled\" && event.type !== \"agent_idle\") return;\n\t\t\t\t\t\t\tif (released) return;\n\t\t\t\t\t\t\treleased = true;\n\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\tvoid this.releaseOwnedSession(sessionId).catch((cause) => {\n\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t`senpi rpc deferred release for session ${sessionId} failed: ${String(cause)}\\n`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.releaseOwnedSession(sessionId);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t\tif (opens) await Promise.all([...opens]);\n\t\tthis.releasedConnections.delete(connectionId);\n\t}\n\n\t/**\n\t * One owned handle's refcounted close: the same sequence as an explicit\n\t * close_session, tolerant of races with other lifecycle paths (an entry\n\t * already closed or claimed elsewhere is simply skipped), except that it claims\n\t * a DETACH: a retained entry keeps running at zero attachments instead of\n\t * closing, so this path releases the client's claim without ending the session.\n\t * Disposal, pending\n\t * extension-UI cancellation and binding removal happen only when this was the\n\t * LAST attachment (the entry transitioned to \"closing\"): surviving\n\t * attachments keep the shared binding and their event stream.\n\t */\n\tprivate async releaseOwnedSession(sessionId: string): Promise<void> {\n\t\t// A failed claim means the entry is already closed or owned by another path.\n\t\t// A retained entry answers the detach by staying open: no finalizer, nothing to join.\n\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: false, detach: true });\n\t\tif (!claim) return;\n\t\tif (!claim.finalizer) {\n\t\t\tawait this.finalizations.get(sessionId)?.promise;\n\t\t\treturn;\n\t\t}\n\t\tconst binding = this.bindings.get(sessionId);\n\t\t// Pending UI requests are session-owned, not connection-owned: a question\n\t\t// asked through one connection stays answerable by every other attachment.\n\t\t// Cancel them only here, where the refcount has already decided the session\n\t\t// is being torn down, never on any owner drop.\n\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\tawait this.finalizeClose(sessionId, binding);\n\t}\n\n\t/**\n\t * Releases one attachment (or every attachment when draining) and reports\n\t * whether this caller became the finalizer. The join token is installed inside\n\t * the registry callback, before any await, so a close that lands between the\n\t * claim and finalizeClose() always finds a token to wait on instead of\n\t * answering ahead of the terminal records.\n\t */\n\tprivate claimClose(sessionId: string, options: CloseClaimOptions): { finalizer: boolean } {\n\t\tlet finalizer = true;\n\t\tconst onRole = (isFinalizer: boolean): void => {\n\t\t\tfinalizer = isFinalizer;\n\t\t\tif (isFinalizer && !this.finalizations.has(sessionId))\n\t\t\t\tthis.finalizations.set(sessionId, this.createFinalization());\n\t\t};\n\t\tlet entry = this.registry.beginClose(sessionId, onRole, { detach: options.detach });\n\t\twhile (options.drainAttachments && entry.state === \"open\") entry = this.registry.beginClose(sessionId, onRole);\n\t\treturn { finalizer: finalizer && entry.state === \"closing\" };\n\t}\n\n\t/** claimClose() for lifecycle paths that treat a lost race as \"nothing to do\". */\n\tprivate tryClaimClose(sessionId: string, options: CloseClaimOptions): { finalizer: boolean } | undefined {\n\t\ttry {\n\t\t\treturn this.claimClose(sessionId, options);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async close(command: Extract<RpcCommand, { type: \"close_session\" }>): Promise<RpcResponse | undefined> {\n\t\tconst response = {\n\t\t\tid: command.id,\n\t\t\ttype: \"response\" as const,\n\t\t\tcommand: \"close_session\" as const,\n\t\t\tsuccess: true as const,\n\t\t\tdata: {},\n\t\t};\n\t\t// A close releases the CALLER's attachment, and routing handles are public on a\n\t\t// shared host (`list_sessions` publishes every one of them), so ownership - not\n\t\t// knowledge of the handle - authorizes it: a connection that never attached holds\n\t\t// no attachment, and answering it would release another client's claim and could\n\t\t// tear down a session it never opened. A host with no per-connection identity\n\t\t// (stdio) has no ownership to check and keeps answering every close as before.\n\t\tconst owner = this.writer.currentConnection();\n\t\tif (owner !== undefined && this.sessionsByConnection.get(owner)?.has(command.sessionId) !== true)\n\t\t\treturn error(command.id, \"close_session\", RPC_ERROR_UNKNOWN_SESSION);\n\t\tconst reply = this.writer.reserveCloseResponse(command.sessionId, response);\n\t\tif (!reply) return undefined;\n\t\t// Admission and claiming are synchronous, before any teardown await. A\n\t\t// saturated requester neither releases an attachment nor joins a promise.\n\t\tlet claim: { finalizer: boolean };\n\t\ttry {\n\t\t\tclaim = this.claimClose(command.sessionId, { drainAttachments: false });\n\t\t} catch (cause) {\n\t\t\treply.release();\n\t\t\treturn error(command.id, \"close_session\", this.code(cause));\n\t\t}\n\t\ttry {\n\t\t\tif (owner !== undefined) this.releaseOwnerAttachment(owner, command.sessionId);\n\t\t\tif (claim.finalizer) {\n\t\t\t\tawait this.finalizeClose(command.sessionId, this.bindings.get(command.sessionId), () =>\n\t\t\t\t\treply.complete(true, \"client_close\"),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait this.finalizations.get(command.sessionId)?.promise;\n\t\t\t\treply.complete(false);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} finally {\n\t\t\treply.release();\n\t\t}\n\t}\n\n\t/** Detaches the closing connection's UI/width state; a rerender failure must not abort the close. */\n\tprivate releaseOwnerAttachment(owner: string, sessionId: string): void {\n\t\tthis.widths.get(sessionId)?.delete(owner);\n\t\tthis.writer.detachConnectionFromSession(owner, sessionId);\n\t\tfor (const binding of this.bindings.values()) {\n\t\t\ttry {\n\t\t\t\tbinding.rerenderComponents?.();\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc rerender after close of session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t}\n\t\tconst owned = this.sessionsByConnection.get(owner);\n\t\tconst count = owned?.get(sessionId);\n\t\tif (!owned || count === undefined) return;\n\t\tif (count === 1) owned.delete(sessionId);\n\t\telse owned.set(sessionId, count - 1);\n\t\tif (owned.size === 0) this.sessionsByConnection.delete(owner);\n\t}\n\n\t/**\n\t * Runs the finalizer side of a close for a handle whose beginClose() made this\n\t * caller the owner: dispose the binding, complete the registry teardown, emit\n\t * the terminal records, then release joiners. Every step is guarded so the join\n\t * token always resolves and a failing binding yields one logged line, never a\n\t * second response or an escaped rejection.\n\t */\n\tprivate async finalizeClose(\n\t\tsessionId: string,\n\t\tbinding: RpcSessionBinding | undefined,\n\t\tterminal?: () => void,\n\t): Promise<void> {\n\t\tconst finalization = this.finalizations.get(sessionId) ?? this.createFinalization();\n\t\tthis.finalizations.set(sessionId, finalization);\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tawait binding?.dispose();\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc binding dispose for session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t\tthis.bindings.delete(sessionId);\n\t\t\ttry {\n\t\t\t\tawait this.registry.closeMarked(sessionId);\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc close for session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t\t// closeMarked may return at the grace deadline while ownership remains;\n\t\t\t// terminal records must still observe the exit callback's registry removal.\n\t\t\tawait this.registry.peek(sessionId)?.closeCompletion;\n\t\t\tterminal?.();\n\t\t} finally {\n\t\t\tfinalization.resolve();\n\t\t\tthis.finalizations.delete(sessionId);\n\t\t}\n\t}\n\n\tprivate createFinalization(): { promise: Promise<void>; resolve: () => void } {\n\t\tlet resolveFinalization: (() => void) | undefined;\n\t\tconst promise = new Promise<void>((resolve) => {\n\t\t\tresolveFinalization = resolve;\n\t\t});\n\t\treturn { promise, resolve: () => resolveFinalization?.() };\n\t}\n\n\t/** The machine-readable half of a refusal, when the registry attached one. */\n\tprivate detail(cause: unknown): Readonly<Record<string, unknown>> | undefined {\n\t\treturn cause instanceof RpcSessionRegistryError ? cause.detail : undefined;\n\t}\n\n\tprivate code(cause: unknown): string {\n\t\tif (cause instanceof RpcSessionRegistryError) {\n\t\t\treturn cause.code === RPC_ERROR_OPEN_FAILED ? cause.message : cause.code;\n\t\t}\n\t\tif (cause instanceof Error && [RPC_ERROR_UNKNOWN_SESSION, RPC_ERROR_SESSION_CLOSING].includes(cause.message)) {\n\t\t\treturn cause.message;\n\t\t}\n\t\treturn cause instanceof Error && cause.message\n\t\t\t? `${RPC_ERROR_OPEN_FAILED}: ${cause.message}`\n\t\t\t: RPC_ERROR_UNKNOWN_SESSION;\n\t}\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { SessionKind } from "../../core/extensions/types.ts";
2
- import type { RpcHostMemoryPressureEvent, RpcHostStalledEvent, RpcSessionClosedReason } from "./rpc-types.ts";
2
+ import type { RpcHostMemoryPressureEvent, RpcHostStalledEvent, RpcOpenQueuedEvent, RpcSessionClosedReason } from "./rpc-types.ts";
3
3
  import { type SessionEventWriterConnection } from "./session-event-fanout.ts";
4
4
  export { RENDERED_COMPONENT_RECORD, type SessionEventWriterConnection } from "./session-event-fanout.ts";
5
5
  type RawWriter = (chunk: string) => void;
@@ -89,6 +89,14 @@ export declare class SessionEventWriter {
89
89
  * with a routing handle by the writer: `host_stalled` carries the handle it blames,
90
90
  * and `host_memory_pressure` belongs to the process, not to a session.
91
91
  */
92
+ /**
93
+ * Tell ONE opener where it sits in the open queue, before its open reaches the loop.
94
+ *
95
+ * Sent to the opening connection only: a queue position is about that caller's request, not
96
+ * about the host. If the connection is gone the record is dropped rather than queued - a
97
+ * position is worthless to a client that already left.
98
+ */
99
+ sendOpenQueued(connection: string, record: RpcOpenQueuedEvent): void;
92
100
  broadcastHostRecord(record: RpcHostStalledEvent | RpcHostMemoryPressureEvent): void;
93
101
  /**
94
102
  * Prevent subsequent records for a session and append its terminal response.
@@ -1 +1 @@
1
- {"version":3,"file":"session-event-writer.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/session-event-writer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAIlE,OAAO,KAAK,EACX,0BAA0B,EAC1B,mBAAmB,EAEnB,sBAAsB,EAEtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAGN,KAAK,4BAA4B,EACjC,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,yBAAyB,EAAE,KAAK,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAUzG,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AACzC,KAAK,kBAAkB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9C,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AAsB3D,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAC7D,eAAO,MAAM,8BAA8B,OAAO,CAAC;AAqCnD;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmC;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyD;IACtF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,8FAA8F;IAC9F,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAY;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAqB;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAC,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,CAA0C;IAC3D,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuC;IAC3E,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,kBAAkB,CAAK;IAE/B,IAAI,uBAAuB,IAAI,MAAM,CAEpC;IAED,IAAI,sBAAsB,IAAI,MAAM,CAEnC;IAED,YAAY,QAAQ,EAAE,SAAS,EAAE,aAAa,CAAC,EAAE,cAAc,EAAE;IACjE,YAAY,QAAQ,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,aAAa,CAAC,EAAE,cAAc,EAAE;IAe1G,IAAI,mBAAmB,IAAI,MAAM,CAMhC;IAED,IAAI,kBAAkB,IAAI,MAAM,CAQ/B;IAED,kBAAkB,CACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,4BAA4B,EACxC,OAAO,GAAE;QAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAC1E,IAAI,CAEN;IAED,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAErC;IAED,yBAAyB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAE7D;IAED,2BAA2B,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAE/D;IAED,yBAAyB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAE3E;IAED,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE5C;IAED,mCAAmC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEvD;IAED,yBAAyB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAEnE;IAED,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/C;IAED;;;;;OAKG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAGzD;IAED,+EAA+E;IAC/E,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAE9C;IAED,iFAAiF;IACjF,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAEtC;IAED,yFAAyF;IACzF,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAyDjD;IAED;;;;;;;;;OASG;IACH,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3D;IAED,wFAAwF;IACxF,OAAO,CAAC,aAAa;IAWrB,2EAA2E;IAC3E,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB3C;IAED;;;;;OAKG;IACH,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,0BAA0B,GAAG,IAAI,CAyBlF;IAED;;;;OAIG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAiBvF;IAED;;;;;;;;;;OAUG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAUxD;IAED;;;;OAIG;IACH,oBAAoB,CACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,SAAI,GACT;QAAE,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,sBAAsB,KAAK,IAAI,CAAA;KAAE,GAAG,SAAS,CAkD7G;IAED,0EAA0E;IAC1E,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE/D;IAED,OAAO,CAAC,oBAAoB;IAS5B;;;;;OAKG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAIrC;IAED,kEAAkE;IAClE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBrB;YAEa,eAAe;YAWf,gBAAgB;IAuC9B,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;IAoC3B,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAE,SAAS;CAIlB"}
1
+ {"version":3,"file":"session-event-writer.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/session-event-writer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAIlE,OAAO,KAAK,EACX,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAElB,sBAAsB,EAEtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAGN,KAAK,4BAA4B,EACjC,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,yBAAyB,EAAE,KAAK,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAUzG,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AACzC,KAAK,kBAAkB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9C,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AAsB3D,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAC7D,eAAO,MAAM,8BAA8B,OAAO,CAAC;AAqCnD;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmC;IACrE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyD;IACtF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,8FAA8F;IAC9F,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAY;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAqB;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAC,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,CAA0C;IAC3D,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuC;IAC3E,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,kBAAkB,CAAK;IAE/B,IAAI,uBAAuB,IAAI,MAAM,CAEpC;IAED,IAAI,sBAAsB,IAAI,MAAM,CAEnC;IAED,YAAY,QAAQ,EAAE,SAAS,EAAE,aAAa,CAAC,EAAE,cAAc,EAAE;IACjE,YAAY,QAAQ,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,aAAa,CAAC,EAAE,cAAc,EAAE;IAe1G,IAAI,mBAAmB,IAAI,MAAM,CAMhC;IAED,IAAI,kBAAkB,IAAI,MAAM,CAQ/B;IAED,kBAAkB,CACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,4BAA4B,EACxC,OAAO,GAAE;QAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAC1E,IAAI,CAEN;IAED,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAErC;IAED,yBAAyB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAE7D;IAED,2BAA2B,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAE/D;IAED,yBAAyB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAE3E;IAED,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE5C;IAED,mCAAmC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEvD;IAED,yBAAyB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAEnE;IAED,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/C;IAED;;;;;OAKG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAGzD;IAED,+EAA+E;IAC/E,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAE9C;IAED,iFAAiF;IACjF,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAEtC;IAED,yFAAyF;IACzF,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAyDjD;IAED;;;;;;;;;OASG;IACH,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3D;IAED,wFAAwF;IACxF,OAAO,CAAC,aAAa;IAWrB,2EAA2E;IAC3E,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB3C;IAED;;;;;OAKG;IACH;;;;;;OAMG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAYnE;IAED,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,0BAA0B,GAAG,IAAI,CAyBlF;IAED;;;;OAIG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAiBvF;IAED;;;;;;;;;;OAUG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAUxD;IAED;;;;OAIG;IACH,oBAAoB,CACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,SAAI,GACT;QAAE,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,sBAAsB,KAAK,IAAI,CAAA;KAAE,GAAG,SAAS,CAkD7G;IAED,0EAA0E;IAC1E,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE/D;IAED,OAAO,CAAC,oBAAoB;IAS5B;;;;;OAKG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAIrC;IAED,kEAAkE;IAClE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBrB;YAEa,eAAe;YAWf,gBAAgB;IAuC9B,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;IAoC3B,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAE,SAAS;CAIlB"}
@@ -249,6 +249,27 @@ export class SessionEventWriter {
249
249
  * with a routing handle by the writer: `host_stalled` carries the handle it blames,
250
250
  * and `host_memory_pressure` belongs to the process, not to a session.
251
251
  */
252
+ /**
253
+ * Tell ONE opener where it sits in the open queue, before its open reaches the loop.
254
+ *
255
+ * Sent to the opening connection only: a queue position is about that caller's request, not
256
+ * about the host. If the connection is gone the record is dropped rather than queued - a
257
+ * position is worthless to a client that already left.
258
+ */
259
+ sendOpenQueued(connection, record) {
260
+ // Reconstruct so desktop `refresh-senpi-events.ts` sees a literal `type:` site in this file.
261
+ const wire = {
262
+ type: "queued",
263
+ for_request: record.for_request,
264
+ position: record.position,
265
+ in_flight: record.in_flight,
266
+ };
267
+ const target = this.fanout.get(connection);
268
+ if (target === undefined)
269
+ return;
270
+ target.actor.enqueue(serializeJsonLine(wire));
271
+ this.requestFlush();
272
+ }
252
273
  broadcastHostRecord(record) {
253
274
  // Reconstruct so desktop `refresh-senpi-events.ts` sees literal `type:` sites in this file.
254
275
  let wire;