@code-yeongyu/senpi 2026.9.2-4 → 2026.9.3-2

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 (254) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/core/agent-session.d.ts +2 -5
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +32 -29
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  7. package/dist/core/dynamic-prompt/build.js +2 -5
  8. package/dist/core/dynamic-prompt/build.js.map +1 -1
  9. package/dist/core/dynamic-prompt/index.d.ts +1 -2
  10. package/dist/core/dynamic-prompt/index.d.ts.map +1 -1
  11. package/dist/core/dynamic-prompt/index.js +1 -2
  12. package/dist/core/dynamic-prompt/index.js.map +1 -1
  13. package/dist/core/dynamic-prompt/intent-gate.d.ts.map +1 -1
  14. package/dist/core/dynamic-prompt/intent-gate.js +9 -24
  15. package/dist/core/dynamic-prompt/intent-gate.js.map +1 -1
  16. package/dist/core/dynamic-prompt/policies.d.ts.map +1 -1
  17. package/dist/core/dynamic-prompt/policies.js +3 -7
  18. package/dist/core/dynamic-prompt/policies.js.map +1 -1
  19. package/dist/core/dynamic-prompt/style.d.ts.map +1 -1
  20. package/dist/core/dynamic-prompt/style.js +6 -8
  21. package/dist/core/dynamic-prompt/style.js.map +1 -1
  22. package/dist/core/dynamic-prompt/verification.js +1 -1
  23. package/dist/core/dynamic-prompt/verification.js.map +1 -1
  24. package/dist/core/dynamic-prompt/working-task.d.ts +2 -0
  25. package/dist/core/dynamic-prompt/working-task.d.ts.map +1 -0
  26. package/dist/core/dynamic-prompt/working-task.js +10 -0
  27. package/dist/core/dynamic-prompt/working-task.js.map +1 -0
  28. package/dist/core/extensions/builtin/bash-timeout/index.d.ts +1 -1
  29. package/dist/core/extensions/builtin/bash-timeout/index.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/bash-timeout/index.js +7 -1
  31. package/dist/core/extensions/builtin/bash-timeout/index.js.map +1 -1
  32. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts +11 -7
  33. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/bash-timeout/timeout.js +4 -8
  35. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  36. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.d.ts.map +1 -1
  37. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js +9 -17
  38. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js.map +1 -1
  39. package/dist/core/extensions/builtin/claude-sdk-oauth/content-blocks.d.ts +3 -0
  40. package/dist/core/extensions/builtin/claude-sdk-oauth/content-blocks.d.ts.map +1 -0
  41. package/dist/core/extensions/builtin/claude-sdk-oauth/content-blocks.js +80 -0
  42. package/dist/core/extensions/builtin/claude-sdk-oauth/content-blocks.js.map +1 -0
  43. package/dist/core/extensions/builtin/claude-sdk-oauth/errors.d.ts +17 -0
  44. package/dist/core/extensions/builtin/claude-sdk-oauth/errors.d.ts.map +1 -1
  45. package/dist/core/extensions/builtin/claude-sdk-oauth/errors.js +51 -1
  46. package/dist/core/extensions/builtin/claude-sdk-oauth/errors.js.map +1 -1
  47. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts +1 -0
  48. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts.map +1 -1
  49. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.js +11 -0
  50. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.js.map +1 -1
  51. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts.map +1 -1
  52. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js +6 -1
  53. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -1
  54. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.d.ts.map +1 -1
  55. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.js +2 -23
  56. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.js.map +1 -1
  57. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +2 -0
  58. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
  59. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +15 -1
  60. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
  61. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts +1 -1
  62. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts.map +1 -1
  63. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js +1 -0
  64. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js.map +1 -1
  65. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts +6 -1
  66. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
  67. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +1 -0
  68. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
  69. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.d.ts.map +1 -1
  70. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js +19 -3
  71. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js.map +1 -1
  72. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts +1 -0
  73. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts.map +1 -1
  74. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js +1 -0
  75. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js.map +1 -1
  76. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -1
  77. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +7 -14
  78. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -1
  79. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.d.ts.map +1 -1
  80. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js +23 -6
  81. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js.map +1 -1
  82. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.d.ts.map +1 -1
  83. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js +4 -2
  84. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js.map +1 -1
  85. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -1
  86. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js +13 -6
  87. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -1
  88. package/dist/core/extensions/builtin/config-reload/watch-event-source.d.ts +1 -1
  89. package/dist/core/extensions/builtin/config-reload/watch-event-source.d.ts.map +1 -1
  90. package/dist/core/extensions/builtin/config-reload/watch-event-source.js +27 -9
  91. package/dist/core/extensions/builtin/config-reload/watch-event-source.js.map +1 -1
  92. package/dist/core/extensions/builtin/eval-only-routing.d.ts +10 -0
  93. package/dist/core/extensions/builtin/eval-only-routing.d.ts.map +1 -0
  94. package/dist/core/extensions/builtin/eval-only-routing.js +16 -0
  95. package/dist/core/extensions/builtin/eval-only-routing.js.map +1 -0
  96. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.d.ts.map +1 -1
  97. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js +1 -3
  98. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js.map +1 -1
  99. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js +1 -11
  101. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js.map +1 -1
  102. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js +2 -2
  103. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js.map +1 -1
  104. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js +3 -3
  105. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js.map +1 -1
  106. package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.d.ts.map +1 -1
  107. package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js +56 -43
  108. package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js.map +1 -1
  109. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +4 -15
  110. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts.map +1 -1
  111. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +12 -21
  112. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js.map +1 -1
  113. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.d.ts +1 -1
  114. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.d.ts.map +1 -1
  115. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js +2 -11
  116. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js.map +1 -1
  117. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.d.ts +1 -1
  118. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.d.ts.map +1 -1
  119. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.js +2 -11
  120. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.js.map +1 -1
  121. package/dist/core/extensions/builtin/prompt-preset/glm-5.d.ts +4 -0
  122. package/dist/core/extensions/builtin/prompt-preset/glm-5.d.ts.map +1 -0
  123. package/dist/core/extensions/builtin/prompt-preset/glm-5.js +16 -0
  124. package/dist/core/extensions/builtin/prompt-preset/glm-5.js.map +1 -0
  125. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +1 -5
  126. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
  127. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +1 -6
  128. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  129. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -1
  130. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +60 -76
  131. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
  132. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  133. package/dist/core/extensions/builtin/terminal/extension.js +13 -5
  134. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  135. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts +4 -3
  136. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
  137. package/dist/core/extensions/builtin/terminal/monitor-notify.js +18 -18
  138. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
  139. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +7 -0
  140. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  141. package/dist/core/extensions/builtin/terminal/monitor-registry.js +37 -8
  142. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  143. package/dist/core/extensions/builtin/terminal/monitor-status.js +1 -1
  144. package/dist/core/extensions/builtin/terminal/monitor-status.js.map +1 -1
  145. package/dist/core/extensions/builtin/terminal/prompt.d.ts +13 -2
  146. package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
  147. package/dist/core/extensions/builtin/terminal/prompt.js +31 -16
  148. package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
  149. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
  150. package/dist/core/extensions/builtin/terminal/tools/bash-output.js +14 -2
  151. package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
  152. package/dist/core/extensions/builtin/terminal/tools/context.d.ts +2 -0
  153. package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
  154. package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
  155. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
  156. package/dist/core/extensions/builtin/terminal/tools/monitor.js +27 -10
  157. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
  158. package/dist/core/settings-manager.d.ts +0 -4
  159. package/dist/core/settings-manager.d.ts.map +1 -1
  160. package/dist/core/settings-manager.js +0 -6
  161. package/dist/core/settings-manager.js.map +1 -1
  162. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  163. package/dist/modes/rpc/connection-handler.js +13 -10
  164. package/dist/modes/rpc/connection-handler.js.map +1 -1
  165. package/dist/modes/rpc/host-ensure.d.ts +6 -0
  166. package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
  167. package/dist/modes/rpc/host-ensure.js +15 -4
  168. package/dist/modes/rpc/host-ensure.js.map +1 -1
  169. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
  170. package/dist/modes/rpc/host-lifecycle.js +16 -4
  171. package/dist/modes/rpc/host-lifecycle.js.map +1 -1
  172. package/dist/modes/rpc/login-prompts.d.ts +24 -0
  173. package/dist/modes/rpc/login-prompts.d.ts.map +1 -0
  174. package/dist/modes/rpc/login-prompts.js +44 -0
  175. package/dist/modes/rpc/login-prompts.js.map +1 -0
  176. package/dist/modes/rpc/multi-session-host.d.ts +3 -0
  177. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  178. package/dist/modes/rpc/multi-session-host.js +3 -0
  179. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  180. package/dist/modes/rpc/rpc-mode.d.ts +1 -1
  181. package/dist/modes/rpc/rpc-mode.js +1 -1
  182. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  183. package/dist/modes/rpc/session-command-router.d.ts +22 -0
  184. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  185. package/dist/modes/rpc/session-command-router.js +132 -94
  186. package/dist/modes/rpc/session-command-router.js.map +1 -1
  187. package/dist/modes/rpc/session-event-fanout.d.ts +3 -1
  188. package/dist/modes/rpc/session-event-fanout.d.ts.map +1 -1
  189. package/dist/modes/rpc/session-event-fanout.js +14 -1
  190. package/dist/modes/rpc/session-event-fanout.js.map +1 -1
  191. package/dist/modes/rpc/session-event-writer.d.ts +2 -0
  192. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  193. package/dist/modes/rpc/session-event-writer.js +16 -2
  194. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  195. package/dist/modes/rpc/session-registry.d.ts +9 -8
  196. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  197. package/dist/modes/rpc/session-registry.js +14 -42
  198. package/dist/modes/rpc/session-registry.js.map +1 -1
  199. package/dist/modes/rpc/session-teardown.d.ts +12 -0
  200. package/dist/modes/rpc/session-teardown.d.ts.map +1 -0
  201. package/dist/modes/rpc/session-teardown.js +117 -0
  202. package/dist/modes/rpc/session-teardown.js.map +1 -0
  203. package/docs/rpc.md +38 -5
  204. package/docs/settings.md +4 -26
  205. package/docs/terminal-tools.md +26 -6
  206. package/docs/windows.md +1 -1
  207. package/node_modules/@anthropic-ai/claude-agent-sdk/bridge.d.ts +18 -1
  208. package/node_modules/@anthropic-ai/claude-agent-sdk/bridge.mjs +155 -106
  209. package/node_modules/@anthropic-ai/claude-agent-sdk/browser-sdk.js +144 -83
  210. package/node_modules/@anthropic-ai/claude-agent-sdk/manifest.json +21 -32
  211. package/node_modules/@anthropic-ai/claude-agent-sdk/manifest.zst.json +25 -36
  212. package/node_modules/@anthropic-ai/claude-agent-sdk/package.json +2 -2
  213. package/node_modules/@anthropic-ai/claude-agent-sdk/sdk-tools.d.ts +93 -31
  214. package/node_modules/@anthropic-ai/claude-agent-sdk/sdk.d.ts +473 -31
  215. package/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs +140 -93
  216. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +26 -0
  217. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  218. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +17 -0
  219. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +6 -0
  220. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.d.ts +10 -0
  221. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.js +126 -0
  222. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +14 -6
  223. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +2 -0
  224. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +1 -0
  225. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  226. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +5 -0
  227. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +8 -0
  229. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.d.ts +8 -0
  231. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.d.ts.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.js.map +1 -1
  233. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  234. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  235. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google-vertex.json +1 -1
  236. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
  237. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  238. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  239. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  240. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  241. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  242. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  243. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  244. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  245. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  246. package/package.json +16 -16
  247. package/dist/core/dynamic-prompt/exploration.d.ts +0 -2
  248. package/dist/core/dynamic-prompt/exploration.d.ts.map +0 -1
  249. package/dist/core/dynamic-prompt/exploration.js +0 -6
  250. package/dist/core/dynamic-prompt/exploration.js.map +0 -1
  251. package/dist/core/dynamic-prompt/parallel-tools.d.ts +0 -2
  252. package/dist/core/dynamic-prompt/parallel-tools.d.ts.map +0 -1
  253. package/dist/core/dynamic-prompt/parallel-tools.js +0 -8
  254. package/dist/core/dynamic-prompt/parallel-tools.js.map +0 -1
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Bridge OAuth login prompts onto the RPC extension UI dialog channel.
3
+ *
4
+ * Providers whose flow needs mid-flow input (a pasted authorization code, an
5
+ * account choice) call `interaction.prompt(...)`, which AuthStorage routes to
6
+ * `onPrompt`/`onSelect`. Over RPC those become `extension_ui_request` dialogs
7
+ * the client answers with `extension_ui_response`.
8
+ *
9
+ * Cancellation has two independent sources and both must release the dialog:
10
+ * the login-wide signal (login_cancel, or the login having settled) and the
11
+ * per-prompt `AuthPrompt.signal` a provider aborts when an out-of-band step
12
+ * wins the race — e.g. `loginAnthropic` racing a manual-code prompt against
13
+ * its local callback server. A released dialog rejects with "Login cancelled",
14
+ * matching the interactive TUI.
15
+ *
16
+ * Only the prompt text, placeholder, and option labels cross the wire; the
17
+ * client's answer is consumed in-process and never echoed back.
18
+ */
19
+ export function createRpcLoginPromptCallbacks(ui, signal) {
20
+ const dialogSignalFor = (promptSignal) => promptSignal ? AbortSignal.any([signal, promptSignal]) : signal;
21
+ return {
22
+ async onPrompt(prompt) {
23
+ const dialogSignal = dialogSignalFor(prompt.signal);
24
+ if (dialogSignal.aborted)
25
+ throw new Error("Login cancelled");
26
+ const value = await ui.input(prompt.message, prompt.placeholder, { signal: dialogSignal });
27
+ if (dialogSignal.aborted || value === undefined)
28
+ throw new Error("Login cancelled");
29
+ return value;
30
+ },
31
+ async onSelect(prompt) {
32
+ const dialogSignal = dialogSignalFor(prompt.signal);
33
+ if (dialogSignal.aborted)
34
+ throw new Error("Login cancelled");
35
+ const value = await ui.select(prompt.message, prompt.options.map((option) => option.label), { signal: dialogSignal });
36
+ if (dialogSignal.aborted)
37
+ throw new Error("Login cancelled");
38
+ if (value === undefined)
39
+ return undefined;
40
+ return prompt.options.find((option) => option.label === value)?.id;
41
+ },
42
+ };
43
+ }
44
+ //# sourceMappingURL=login-prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login-prompts.js","sourceRoot":"","sources":["../../../src/modes/rpc/login-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,MAAM,UAAU,6BAA6B,CAC5C,EAAgD,EAChD,MAAmB;IAEnB,MAAM,eAAe,GAAG,CAAC,YAAqC,EAAe,EAAE,CAC9E,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAEjE,OAAO;QACN,KAAK,CAAC,QAAQ,CAAC,MAAM;YACpB,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACpD,IAAI,YAAY,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC7D,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;YAC3F,IAAI,YAAY,CAAC,OAAO,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACpF,OAAO,KAAK,CAAC;QACd,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,MAAM;YACpB,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACpD,IAAI,YAAY,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC7D,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,MAAM,CAC5B,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAC5C,EAAE,MAAM,EAAE,YAAY,EAAE,CACxB,CAAC;YACF,IAAI,YAAY,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC7D,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC1C,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,EAAE,CAAC;QACpE,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["/**\n * Bridge OAuth login prompts onto the RPC extension UI dialog channel.\n *\n * Providers whose flow needs mid-flow input (a pasted authorization code, an\n * account choice) call `interaction.prompt(...)`, which AuthStorage routes to\n * `onPrompt`/`onSelect`. Over RPC those become `extension_ui_request` dialogs\n * the client answers with `extension_ui_response`.\n *\n * Cancellation has two independent sources and both must release the dialog:\n * the login-wide signal (login_cancel, or the login having settled) and the\n * per-prompt `AuthPrompt.signal` a provider aborts when an out-of-band step\n * wins the race — e.g. `loginAnthropic` racing a manual-code prompt against\n * its local callback server. A released dialog rejects with \"Login cancelled\",\n * matching the interactive TUI.\n *\n * Only the prompt text, placeholder, and option labels cross the wire; the\n * client's answer is consumed in-process and never echoed back.\n */\n\nimport type { OAuthLoginCallbacks } from \"@earendil-works/pi-ai\";\nimport type { ExtensionUIContext } from \"../../core/extensions/types.ts\";\n\ntype RpcLoginPromptCallbacks = Pick<OAuthLoginCallbacks, \"onPrompt\" | \"onSelect\">;\n\nexport function createRpcLoginPromptCallbacks(\n\tui: Pick<ExtensionUIContext, \"input\" | \"select\">,\n\tsignal: AbortSignal,\n): RpcLoginPromptCallbacks {\n\tconst dialogSignalFor = (promptSignal: AbortSignal | undefined): AbortSignal =>\n\t\tpromptSignal ? AbortSignal.any([signal, promptSignal]) : signal;\n\n\treturn {\n\t\tasync onPrompt(prompt) {\n\t\t\tconst dialogSignal = dialogSignalFor(prompt.signal);\n\t\t\tif (dialogSignal.aborted) throw new Error(\"Login cancelled\");\n\t\t\tconst value = await ui.input(prompt.message, prompt.placeholder, { signal: dialogSignal });\n\t\t\tif (dialogSignal.aborted || value === undefined) throw new Error(\"Login cancelled\");\n\t\t\treturn value;\n\t\t},\n\n\t\tasync onSelect(prompt) {\n\t\t\tconst dialogSignal = dialogSignalFor(prompt.signal);\n\t\t\tif (dialogSignal.aborted) throw new Error(\"Login cancelled\");\n\t\t\tconst value = await ui.select(\n\t\t\t\tprompt.message,\n\t\t\t\tprompt.options.map((option) => option.label),\n\t\t\t\t{ signal: dialogSignal },\n\t\t\t);\n\t\t\tif (dialogSignal.aborted) throw new Error(\"Login cancelled\");\n\t\t\tif (value === undefined) return undefined;\n\t\t\treturn prompt.options.find((option) => option.label === value)?.id;\n\t\t},\n\t};\n}\n"]}
@@ -21,6 +21,8 @@ export declare const RPC_SESSION_IDLE_EVICTION_MS_ENV = "SENPI_RPC_SESSION_IDLE_
21
21
  export declare const RPC_MAX_SESSIONS_ENV = "SENPI_RPC_MAX_SESSIONS";
22
22
  /** Environment override for the empty-host exit window, in milliseconds. */
23
23
  export declare const RPC_HOST_EMPTY_EXIT_MS_ENV = "SENPI_RPC_HOST_EMPTY_EXIT_MS";
24
+ /** Environment override for the graceful close_session teardown window, in milliseconds. */
25
+ export declare const RPC_CLOSE_GRACE_MS_ENV = "SENPI_RPC_CLOSE_GRACE_MS";
24
26
  /** Default idle-eviction window: 30 minutes after a session's last routed command or settled turn. */
25
27
  export declare const DEFAULT_SESSION_IDLE_EVICTION_MS: number;
26
28
  /** Default session cap: an idle session holds a full runtime (~340-510 MB RSS measured). */
@@ -33,6 +35,7 @@ export interface HostIdleOverrides {
33
35
  idleEvictionMs?: number;
34
36
  emptyExitMs?: number;
35
37
  maxSessions?: number;
38
+ closeGraceMs?: number;
36
39
  /** Shutdown hook the empty-exit window invokes; hosts pass their exit path. */
37
40
  onEmptyExit?: () => void;
38
41
  /** Gate consulted before the empty-exit window advances (connected clients block it). */
@@ -1 +1 @@
1
- {"version":3,"file":"multi-session-host.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/multi-session-host.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,qCAAqC,CAAC;AAgB5F,OAAO,EAAE,KAAK,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAU/D,MAAM,WAAW,uBAAuB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,gCAAgC,CAAC;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED,kFAAkF;AAClF,eAAO,MAAM,gCAAgC,uCAAuC,CAAC;AACrF,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAC7D,4EAA4E;AAC5E,eAAO,MAAM,0BAA0B,iCAAiC,CAAC;AACzE,sGAAsG;AACtG,eAAO,MAAM,gCAAgC,QAAc,CAAC;AAC5D,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,0GAA0G;AAC1G,eAAO,MAAM,0BAA0B,QAAc,CAAC;AAItD,kGAAkG;AAClG,MAAM,WAAW,iBAAiB;IACjC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC;CACjC;AAQD,0FAA0F;AAC1F,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,EACjD,SAAS,GAAE,iBAAsB,GAC/B;IAAE,GAAG,EAAE,MAAM,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAWzF;AASD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,KAAK,CAAC,CAG1F;AAED,wBAAgB,cAAc,CAC7B,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,kBAAkB,EAC1B,YAAY,WAA+D,EAC3E,IAAI,GAAE,iBAAsB;;mBAsBA,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;EAiBlD"}
1
+ {"version":3,"file":"multi-session-host.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/multi-session-host.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,qCAAqC,CAAC;AAgB5F,OAAO,EAAE,KAAK,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAU/D,MAAM,WAAW,uBAAuB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,gCAAgC,CAAC;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED,kFAAkF;AAClF,eAAO,MAAM,gCAAgC,uCAAuC,CAAC;AACrF,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAC7D,4EAA4E;AAC5E,eAAO,MAAM,0BAA0B,iCAAiC,CAAC;AACzE,4FAA4F;AAC5F,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AACjE,sGAAsG;AACtG,eAAO,MAAM,gCAAgC,QAAc,CAAC;AAC5D,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,0GAA0G;AAC1G,eAAO,MAAM,0BAA0B,QAAc,CAAC;AAItD,kGAAkG;AAClG,MAAM,WAAW,iBAAiB;IACjC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC;CACjC;AAQD,0FAA0F;AAC1F,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,EACjD,SAAS,GAAE,iBAAsB,GAC/B;IAAE,GAAG,EAAE,MAAM,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAWzF;AASD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,KAAK,CAAC,CAG1F;AAED,wBAAgB,cAAc,CAC7B,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,kBAAkB,EAC1B,YAAY,WAA+D,EAC3E,IAAI,GAAE,iBAAsB;;mBAuBA,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;EAiBlD"}
@@ -19,6 +19,8 @@ export const RPC_SESSION_IDLE_EVICTION_MS_ENV = "SENPI_RPC_SESSION_IDLE_EVICTION
19
19
  export const RPC_MAX_SESSIONS_ENV = "SENPI_RPC_MAX_SESSIONS";
20
20
  /** Environment override for the empty-host exit window, in milliseconds. */
21
21
  export const RPC_HOST_EMPTY_EXIT_MS_ENV = "SENPI_RPC_HOST_EMPTY_EXIT_MS";
22
+ /** Environment override for the graceful close_session teardown window, in milliseconds. */
23
+ export const RPC_CLOSE_GRACE_MS_ENV = "SENPI_RPC_CLOSE_GRACE_MS";
22
24
  /** Default idle-eviction window: 30 minutes after a session's last routed command or settled turn. */
23
25
  export const DEFAULT_SESSION_IDLE_EVICTION_MS = 30 * 60_000;
24
26
  /** Default session cap: an idle session holds a full runtime (~340-510 MB RSS measured). */
@@ -62,6 +64,7 @@ export function createHostCore(options, writer, capabilities = parseClientCapabi
62
64
  createRuntime: options.createRuntime,
63
65
  now: policy.now,
64
66
  maxSessions: policy.maxSessions,
67
+ closeGraceMs: idle.closeGraceMs ?? parseIdleExitMs(process.env[RPC_CLOSE_GRACE_MS_ENV]) ?? 10_000,
65
68
  }), writer, options, options.createBinding, { capabilities }, {
66
69
  now: policy.now,
67
70
  idleEvictionMs: policy.idleEvictionMs,
@@ -1 +1 @@
1
- {"version":3,"file":"multi-session-host.js","sourceRoot":"","sources":["../../../src/modes/rpc/multi-session-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { access, chmod, mkdir, unlink } from \"node:fs/promises\";\nimport { createConnection, createServer, type Server, type Socket } from \"node:net\";\nimport { dirname, join } from \"node:path\";\nimport type { CreateAgentSessionRuntimeFactory } from \"../../core/agent-session-runtime.ts\";\nimport { envValue } from \"../../core/brand.ts\";\nimport {\n\tflushRawStdout,\n\ttakeOverStdout,\n\twaitForRawStdoutBackpressure,\n\twriteRawStdout,\n} from \"../../core/output-guard.ts\";\nimport { killTrackedDetachedChildren } from \"../../utils/shell.ts\";\nimport type { RpcConnectionSink } from \"./connection-handler.ts\";\nimport { parseClientCapabilities } from \"./custom-capability.ts\";\nimport { parseIdleExitMs } from \"./host-lifecycle.ts\";\nimport { armHostWatchdog, readHostWatchdogConfigFromBrandEnv } from \"./host-watchdog.ts\";\nimport { attachJsonlLineReader, MAX_RPC_LINE_CHARACTERS } from \"./jsonl.ts\";\nimport { rpcCommandShapeError } from \"./rpc-input-validation.ts\";\nimport type { RpcCommand, RpcResponse } from \"./rpc-types.ts\";\nimport { type RpcBindingFactory, SessionCommandRouter } from \"./session-command-router.ts\";\nimport { SessionEventWriter } from \"./session-event-writer.ts\";\nimport { RpcSessionRegistry } from \"./session-registry.ts\";\nimport {\n\tauthenticateSocket,\n\tensureSocketSecret,\n\tresolveSocketTransportAddress,\n\tSOCKET_SECRET_FILE_ENV,\n\tsocketSecretPath,\n} from \"./socket-transport.ts\";\n\nexport interface MultiSessionHostOptions {\n\tagentDir: string;\n\tcreateRuntime: CreateAgentSessionRuntimeFactory;\n\tcwd: string;\n\tpermissionPreset?: string;\n\tcreationModel?: { provider: string; modelId: string };\n\tinitialThinkingLevel?: string;\n\tlisten?: string;\n\t/** Test seam: defaults to the real shared-session binding. */\n\tcreateBinding?: RpcBindingFactory;\n}\n\n/** Environment override for the idle-session eviction window, in milliseconds. */\nexport const RPC_SESSION_IDLE_EVICTION_MS_ENV = \"SENPI_RPC_SESSION_IDLE_EVICTION_MS\";\n/** Environment override for the concurrent open-session cap. */\nexport const RPC_MAX_SESSIONS_ENV = \"SENPI_RPC_MAX_SESSIONS\";\n/** Environment override for the empty-host exit window, in milliseconds. */\nexport const RPC_HOST_EMPTY_EXIT_MS_ENV = \"SENPI_RPC_HOST_EMPTY_EXIT_MS\";\n/** Default idle-eviction window: 30 minutes after a session's last routed command or settled turn. */\nexport const DEFAULT_SESSION_IDLE_EVICTION_MS = 30 * 60_000;\n/** Default session cap: an idle session holds a full runtime (~340-510 MB RSS measured). */\nexport const DEFAULT_MAX_SESSIONS = 8;\n/** Default empty-host exit: 15 minutes with zero open sessions, matching the supervisor's idle window. */\nexport const DEFAULT_HOST_EMPTY_EXIT_MS = 15 * 60_000;\n/** Win32 named-pipe close can leave libuv's server callback pending after handles are destroyed. */\nconst WINDOWS_SHUTDOWN_HARD_EXIT_MS = 2_000;\n\n/** Explicit occupancy-policy overrides for createHostCore; tests inject clocks and hooks here. */\nexport interface HostIdleOverrides {\n\tnow?: () => number;\n\tidleEvictionMs?: number;\n\temptyExitMs?: number;\n\tmaxSessions?: number;\n\t/** Shutdown hook the empty-exit window invokes; hosts pass their exit path. */\n\tonEmptyExit?: () => void;\n\t/** Gate consulted before the empty-exit window advances (connected clients block it). */\n\tcanExitWhenEmpty?: () => boolean;\n}\n\nfunction parseSessionCap(value: string | undefined): number | undefined {\n\tif (value === undefined || !/^\\d+$/.test(value.trim())) return undefined;\n\tconst parsed = Number(value.trim());\n\treturn Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\n/** Precedence: explicit overrides beat environment variables beat documented defaults. */\nexport function resolveHostIdlePolicy(\n\tenv: Readonly<Record<string, string | undefined>>,\n\toverrides: HostIdleOverrides = {},\n): { now: () => number; idleEvictionMs: number; emptyExitMs: number; maxSessions: number } {\n\treturn {\n\t\tnow: overrides.now ?? Date.now,\n\t\tidleEvictionMs:\n\t\t\toverrides.idleEvictionMs ??\n\t\t\tparseIdleExitMs(env[RPC_SESSION_IDLE_EVICTION_MS_ENV]) ??\n\t\t\tDEFAULT_SESSION_IDLE_EVICTION_MS,\n\t\temptyExitMs:\n\t\t\toverrides.emptyExitMs ?? parseIdleExitMs(env[RPC_HOST_EMPTY_EXIT_MS_ENV]) ?? DEFAULT_HOST_EMPTY_EXIT_MS,\n\t\tmaxSessions: overrides.maxSessions ?? parseSessionCap(env[RPC_MAX_SESSIONS_ENV]) ?? DEFAULT_MAX_SESSIONS,\n\t};\n}\n\ninterface Connection {\n\treadonly id: string;\n\treadonly sink: RpcConnectionSink;\n\treadonly detach: () => void;\n\treadonly close: () => void;\n}\n\n/**\n * Socket agent events are delivered only to connections attached to their\n * session, tagged with its routing sessionId. Content-free session lifecycle\n * events remain visible to every connection. Responses and extension UI\n * requests remain requester-only; foreign observation uses attach-on-open.\n */\nexport async function runMultiSessionHost(options: MultiSessionHostOptions): Promise<never> {\n\tif (options.listen === undefined || options.listen === \"stdio://\") return runStdioHost(options);\n\treturn runSocketHost(options, resolveSocketPath(options.listen, options.agentDir));\n}\n\nexport function createHostCore(\n\toptions: MultiSessionHostOptions,\n\twriter: SessionEventWriter,\n\tcapabilities = parseClientCapabilities(envValue(\"RPC_CLIENT_CAPABILITIES\")),\n\tidle: HostIdleOverrides = {},\n) {\n\tconst policy = resolveHostIdlePolicy(process.env, idle);\n\tconst router = new SessionCommandRouter(\n\t\tnew RpcSessionRegistry({\n\t\t\tagentDir: options.agentDir,\n\t\t\tcreateRuntime: options.createRuntime,\n\t\t\tnow: policy.now,\n\t\t\tmaxSessions: policy.maxSessions,\n\t\t}),\n\t\twriter,\n\t\toptions,\n\t\toptions.createBinding,\n\t\t{ capabilities },\n\t\t{\n\t\t\tnow: policy.now,\n\t\t\tidleEvictionMs: policy.idleEvictionMs,\n\t\t\temptyExitMs: policy.emptyExitMs,\n\t\t\tonEmptyExit: idle.onEmptyExit,\n\t\t\tcanExitWhenEmpty: idle.canExitWhenEmpty,\n\t\t},\n\t);\n\tconst handle = async (line: string): Promise<void> => {\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(line);\n\t\t} catch (cause) {\n\t\t\tawait writer.enqueueControl(parseError(`Failed to parse command: ${errorMessage(cause)}`));\n\t\t\treturn;\n\t\t}\n\t\tconst shapeError = rpcCommandShapeError(parsed);\n\t\tif (shapeError) {\n\t\t\tawait writer.enqueueControl(parseError(shapeError));\n\t\t\treturn;\n\t\t}\n\t\tconst response = await router.handle(parsed as RpcCommand);\n\t\tif (response) await writer.enqueueControl(response);\n\t};\n\treturn { router, handle };\n}\n\n/** Plain-stdio host with no eagerly-created AgentSessionRuntime. */\nasync function runStdioHost(options: MultiSessionHostOptions): Promise<never> {\n\ttakeOverStdout();\n\tconst sink: RpcConnectionSink = { writeRaw: writeRawStdout, waitForBackpressure: waitForRawStdoutBackpressure };\n\tconst writer = new SessionEventWriter(sink.writeRaw, sink.waitForBackpressure);\n\t// An empty host (no session ever opened, or all closed) must not stay resident\n\t// forever: exit through the normal shutdown path once the window elapses.\n\tconst { router, handle } = createHostCore(options, writer, undefined, {\n\t\tonEmptyExit: () => void shutdown(0),\n\t});\n\tlet shuttingDown = false;\n\tconst shutdown = async (exitCode = 0): Promise<never> => {\n\t\tif (shuttingDown) process.exit(exitCode);\n\t\tshuttingDown = true;\n\t\tdetach();\n\t\tawait router.dispose();\n\t\tawait writer.flush();\n\t\tawait flushRawStdout();\n\t\tprocess.exit(exitCode);\n\t};\n\tconst onEnd = () => void shutdown();\n\tprocess.stdin.on(\"end\", onEnd);\n\tconst detachReader = attachJsonlLineReader(process.stdin, (line) => void handle(line), {\n\t\tmaxLineLength: MAX_RPC_LINE_CHARACTERS,\n\t\tonOversizedLine: () => void writer.enqueueControl(parseError(oversizedLineError())),\n\t});\n\tconst detach = () => {\n\t\tdetachReader();\n\t\tprocess.stdin.off(\"end\", onEnd);\n\t};\n\tregisterShutdownSignals(shutdown);\n\treturn new Promise(() => {});\n}\n\nasync function runSocketHost(options: MultiSessionHostOptions, socketPath: string): Promise<never> {\n\tawait prepareSocketPath(socketPath);\n\tconst writer = new SessionEventWriter(() => {});\n\tconst connections = new Map<string, Connection>();\n\tconst { router, handle } = createHostCore(\n\t\toptions,\n\t\twriter,\n\t\tparseClientCapabilities(envValue(\"RPC_CLIENT_CAPABILITIES\")).filter(\n\t\t\t(capability) => capability !== \"rendered_components\",\n\t\t),\n\t\t// Supervised hosts idle-exit via the supervisor, but a socket host that\n\t\t// outlives its supervisor (or is started bare) still self-exits when empty.\n\t\t// A connected client counts as occupancy even with no session open: exiting\n\t\t// under it would drop its socket and read as a crash to the supervisor.\n\t\t{ onEmptyExit: () => void shutdown(0), canExitWhenEmpty: () => connections.size === 0 },\n\t);\n\tlet nextConnection = 0;\n\tlet shuttingDown = false;\n\tconst secret =\n\t\tprocess.platform === \"win32\"\n\t\t\t? await ensureSocketSecret(process.env[SOCKET_SECRET_FILE_ENV] ?? socketSecretPath(socketPath))\n\t\t\t: undefined;\n\tconst server = createServer((socket) => {\n\t\tconst accept = (): void => {\n\t\t\tconst id = `socket-${++nextConnection}`;\n\t\t\tconst sink = socketSink(socket);\n\t\t\twriter.registerConnection(id, sink);\n\t\t\tconst detachReader = attachJsonlLineReader(\n\t\t\t\tsocket,\n\t\t\t\t(line) => {\n\t\t\t\t\t// Do not serialize awaited commands: extension_ui_response and other\n\t\t\t\t\t// re-entrant frames must be able to resolve a command already awaiting them.\n\t\t\t\t\tvoid writer\n\t\t\t\t\t\t.withConnection(id, () => handle(line))\n\t\t\t\t\t\t.catch((cause) => {\n\t\t\t\t\t\t\tprocess.stderr.write(`senpi rpc connection ${id} failed: ${errorMessage(cause)}\\n`);\n\t\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmaxLineLength: MAX_RPC_LINE_CHARACTERS,\n\t\t\t\t\tonOversizedLine: () => {\n\t\t\t\t\t\tvoid writer\n\t\t\t\t\t\t\t.withConnection(id, () => writer.enqueueControl(parseError(oversizedLineError())))\n\t\t\t\t\t\t\t.catch((cause) =>\n\t\t\t\t\t\t\t\tprocess.stderr.write(`senpi rpc connection ${id} failed: ${errorMessage(cause)}\\n`),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tlet detached = false;\n\t\t\tconst detach = () => {\n\t\t\t\tif (detached) return;\n\t\t\t\tdetached = true;\n\t\t\t\tdetachReader();\n\t\t\t\twriter.unregisterConnection(id);\n\t\t\t\tconnections.delete(id);\n\t\t\t\t// A socket that dies without close_session still owns its sessions' attachments\n\t\t\t\t// and path reservations. Release them on the command chain so this runs after any\n\t\t\t\t// in-flight command for this connection settles, otherwise the path stays pinned\n\t\t\t\t// by a runtime whose client is gone and later resumes attach to that orphan.\n\t\t\t\tvoid router.releaseConnection(id).catch((cause) => {\n\t\t\t\t\tprocess.stderr.write(`senpi rpc connection ${id} release failed: ${errorMessage(cause)}\\n`);\n\t\t\t\t});\n\t\t\t};\n\t\t\tconnections.set(id, { id, sink, detach, close: () => socket.destroy() });\n\t\t\tsocket.once(\"close\", detach);\n\t\t\tsocket.once(\"error\", () => detach());\n\t\t};\n\t\tif (secret) authenticateSocket(socket, secret, accept);\n\t\telse accept();\n\t});\n\tserver.on(\"error\", (cause) => {\n\t\tif (!shuttingDown) process.stderr.write(`senpi rpc socket listener failed: ${errorMessage(cause)}\\n`);\n\t});\n\tconst shutdown = async (exitCode = 0, watchdogCleanup?: Promise<void>): Promise<never> => {\n\t\tif (shuttingDown) process.exit(exitCode);\n\t\tshuttingDown = true;\n\t\t// On Windows, destroying named-pipe sockets does not always make libuv's\n\t\t// server.close callback fire: connected pipe instances can remain in the\n\t\t// kernel after the JavaScript handles are destroyed. Keep the normal drain\n\t\t// path, but never let that platform-specific close stall orphan the host.\n\t\ttry {\n\t\t\tfor (const connection of connections.values()) {\n\t\t\t\tconnection.detach();\n\t\t\t\tconnection.close();\n\t\t\t}\n\t\t\tawait (process.platform === \"win32\"\n\t\t\t\t? Promise.race([closeServer(server), delay(WINDOWS_SHUTDOWN_HARD_EXIT_MS)])\n\t\t\t\t: closeServer(server));\n\t\t\tawait router.dispose();\n\t\t\tawait writer.flush();\n\t\t\tawait removeSocketPath(socketPath);\n\t\t\tif (watchdogCleanup) await watchdogCleanup;\n\t\t} finally {\n\t\t\t// Explicitly terminate after every shutdown trigger. Windows named-pipe\n\t\t\t// handles are not fully controllable from JS, and an unresolved cleanup\n\t\t\t// must not leave this daemon or its public endpoint alive.\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t};\n\tregisterShutdownSignals(shutdown);\n\t// Arm before listen: a supervisor death during the listen transition must\n\t// still close the child and clean its private endpoint.\n\tarmHostWatchdog(readHostWatchdogConfigFromBrandEnv(), (reason, cleanup) => {\n\t\tprocess.stderr.write(`senpi rpc host: ${reason}; shutting down\\n`);\n\t\t// Enter shutdown before killing session-owned child processes. The Windows\n\t\t// tree killer is synchronous, while the shutdown fallback must be armed\n\t\t// before any such cleanup can delay the event loop.\n\t\tvoid shutdown(0, cleanup);\n\t\tsetImmediate(killTrackedDetachedChildren);\n\t});\n\tawait listen(server, socketPath, secret);\n\tprocess.stderr.write(`senpi rpc listening on ${formatSocketAddress(socketPath)}\\n`);\n\n\t// Opt-in only: set by the lifecycle supervisor so this host can never outlive\n\t// it, including when the supervisor is SIGKILLed and runs no handler at all.\n\treturn new Promise(() => {});\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseError(error: string): RpcResponse {\n\treturn { type: \"response\", command: \"parse\", success: false, error };\n}\n\nfunction oversizedLineError(): string {\n\treturn `RPC input line exceeds ${MAX_RPC_LINE_CHARACTERS} characters.`;\n}\n\nfunction errorMessage(cause: unknown): string {\n\treturn cause instanceof Error ? cause.message : String(cause);\n}\n\nfunction resolveSocketPath(value: string, agentDir: string): string {\n\tif (value === \"unix://\") return join(agentDir, \"rpc\", \"rpc.sock\");\n\tif (value.startsWith(\"unix://\")) {\n\t\tconst path = value.slice(\"unix://\".length);\n\t\tif (path.length === 0) return join(agentDir, \"rpc\", \"rpc.sock\");\n\t\tif (path.startsWith(\"@\") && process.platform === \"linux\") return `\\0${path.slice(1)}`;\n\t\treturn path;\n\t}\n\treturn value;\n}\n\nfunction formatSocketAddress(socketPath: string): string {\n\treturn socketPath.startsWith(\"\\0\") ? `unix://@${socketPath.slice(1)}` : `unix://${socketPath}`;\n}\n\nfunction socketSink(socket: Socket): RpcConnectionSink {\n\tlet needsDrain = false;\n\treturn {\n\t\twriteRaw(chunk) {\n\t\t\tif (!socket.destroyed) needsDrain = !socket.write(chunk);\n\t\t},\n\t\twaitForBackpressure() {\n\t\t\tif (socket.destroyed || !needsDrain) return Promise.resolve();\n\t\t\tneedsDrain = false;\n\t\t\treturn new Promise<void>((resolve) => {\n\t\t\t\tconst done = () => {\n\t\t\t\t\tsocket.off(\"drain\", done);\n\t\t\t\t\tsocket.off(\"close\", done);\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t\tsocket.once(\"drain\", done);\n\t\t\t\tsocket.once(\"close\", done);\n\t\t\t});\n\t\t},\n\t};\n}\n\nasync function prepareSocketPath(socketPath: string): Promise<void> {\n\tif (process.platform === \"win32\" || socketPath.startsWith(\"\\0\")) return;\n\tawait mkdir(dirname(socketPath), { recursive: true, mode: 0o700 });\n\ttry {\n\t\tawait access(socketPath);\n\t} catch (cause) {\n\t\tif (isNodeErrorCode(cause, \"ENOENT\")) return;\n\t\tthrow cause;\n\t}\n\tif (await probeSocket(socketPath)) throw new Error(`${socketPath}: address already in use by a live server.`);\n\tawait unlink(socketPath);\n}\n\nfunction probeSocket(socketPath: string): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = createConnection(resolveSocketTransportAddress(socketPath, process.platform));\n\t\tconst settle = (live: boolean) => {\n\t\t\tsocket.destroy();\n\t\t\tresolve(live);\n\t\t};\n\t\tsocket.once(\"connect\", () => settle(true));\n\t\tsocket.once(\"error\", () => settle(false));\n\t\tsocket.setTimeout(1_000, () => settle(false));\n\t});\n}\n\nfunction listen(server: Server, socketPath: string, secret?: Uint8Array): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tserver.once(\"error\", reject);\n\t\tserver.listen(resolveSocketTransportAddress(socketPath, process.platform, secret), async () => {\n\t\t\tserver.off(\"error\", reject);\n\t\t\ttry {\n\t\t\t\tif (process.platform !== \"win32\" && !socketPath.startsWith(\"\\0\")) await chmod(socketPath, 0o600);\n\t\t\t\tresolve();\n\t\t\t} catch (cause) {\n\t\t\t\treject(cause);\n\t\t\t}\n\t\t});\n\t});\n}\n\nfunction closeServer(server: Server): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tserver.close((cause) => (cause ? reject(cause) : resolve()));\n\t});\n}\n\nasync function removeSocketPath(socketPath: string): Promise<void> {\n\tif (process.platform === \"win32\" || socketPath.startsWith(\"\\0\")) return;\n\ttry {\n\t\tawait unlink(socketPath);\n\t} catch (cause) {\n\t\tif (!isNodeErrorCode(cause, \"ENOENT\")) throw cause;\n\t}\n}\n\nfunction isNodeErrorCode(cause: unknown, code: string): boolean {\n\treturn cause instanceof Error && \"code\" in cause && cause.code === code;\n}\n\nfunction registerShutdownSignals(shutdown: (exitCode?: number) => Promise<never>): void {\n\tfor (const signal of process.platform === \"win32\" ? ([\"SIGTERM\"] as const) : ([\"SIGTERM\", \"SIGHUP\"] as const)) {\n\t\tprocess.on(signal, () => {\n\t\t\tkillTrackedDetachedChildren();\n\t\t\tvoid shutdown(signal === \"SIGHUP\" ? 129 : 143);\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"multi-session-host.js","sourceRoot":"","sources":["../../../src/modes/rpc/multi-session-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { access, chmod, mkdir, unlink } from \"node:fs/promises\";\nimport { createConnection, createServer, type Server, type Socket } from \"node:net\";\nimport { dirname, join } from \"node:path\";\nimport type { CreateAgentSessionRuntimeFactory } from \"../../core/agent-session-runtime.ts\";\nimport { envValue } from \"../../core/brand.ts\";\nimport {\n\tflushRawStdout,\n\ttakeOverStdout,\n\twaitForRawStdoutBackpressure,\n\twriteRawStdout,\n} from \"../../core/output-guard.ts\";\nimport { killTrackedDetachedChildren } from \"../../utils/shell.ts\";\nimport type { RpcConnectionSink } from \"./connection-handler.ts\";\nimport { parseClientCapabilities } from \"./custom-capability.ts\";\nimport { parseIdleExitMs } from \"./host-lifecycle.ts\";\nimport { armHostWatchdog, readHostWatchdogConfigFromBrandEnv } from \"./host-watchdog.ts\";\nimport { attachJsonlLineReader, MAX_RPC_LINE_CHARACTERS } from \"./jsonl.ts\";\nimport { rpcCommandShapeError } from \"./rpc-input-validation.ts\";\nimport type { RpcCommand, RpcResponse } from \"./rpc-types.ts\";\nimport { type RpcBindingFactory, SessionCommandRouter } from \"./session-command-router.ts\";\nimport { SessionEventWriter } from \"./session-event-writer.ts\";\nimport { RpcSessionRegistry } from \"./session-registry.ts\";\nimport {\n\tauthenticateSocket,\n\tensureSocketSecret,\n\tresolveSocketTransportAddress,\n\tSOCKET_SECRET_FILE_ENV,\n\tsocketSecretPath,\n} from \"./socket-transport.ts\";\n\nexport interface MultiSessionHostOptions {\n\tagentDir: string;\n\tcreateRuntime: CreateAgentSessionRuntimeFactory;\n\tcwd: string;\n\tpermissionPreset?: string;\n\tcreationModel?: { provider: string; modelId: string };\n\tinitialThinkingLevel?: string;\n\tlisten?: string;\n\t/** Test seam: defaults to the real shared-session binding. */\n\tcreateBinding?: RpcBindingFactory;\n}\n\n/** Environment override for the idle-session eviction window, in milliseconds. */\nexport const RPC_SESSION_IDLE_EVICTION_MS_ENV = \"SENPI_RPC_SESSION_IDLE_EVICTION_MS\";\n/** Environment override for the concurrent open-session cap. */\nexport const RPC_MAX_SESSIONS_ENV = \"SENPI_RPC_MAX_SESSIONS\";\n/** Environment override for the empty-host exit window, in milliseconds. */\nexport const RPC_HOST_EMPTY_EXIT_MS_ENV = \"SENPI_RPC_HOST_EMPTY_EXIT_MS\";\n/** Environment override for the graceful close_session teardown window, in milliseconds. */\nexport const RPC_CLOSE_GRACE_MS_ENV = \"SENPI_RPC_CLOSE_GRACE_MS\";\n/** Default idle-eviction window: 30 minutes after a session's last routed command or settled turn. */\nexport const DEFAULT_SESSION_IDLE_EVICTION_MS = 30 * 60_000;\n/** Default session cap: an idle session holds a full runtime (~340-510 MB RSS measured). */\nexport const DEFAULT_MAX_SESSIONS = 8;\n/** Default empty-host exit: 15 minutes with zero open sessions, matching the supervisor's idle window. */\nexport const DEFAULT_HOST_EMPTY_EXIT_MS = 15 * 60_000;\n/** Win32 named-pipe close can leave libuv's server callback pending after handles are destroyed. */\nconst WINDOWS_SHUTDOWN_HARD_EXIT_MS = 2_000;\n\n/** Explicit occupancy-policy overrides for createHostCore; tests inject clocks and hooks here. */\nexport interface HostIdleOverrides {\n\tnow?: () => number;\n\tidleEvictionMs?: number;\n\temptyExitMs?: number;\n\tmaxSessions?: number;\n\tcloseGraceMs?: number;\n\t/** Shutdown hook the empty-exit window invokes; hosts pass their exit path. */\n\tonEmptyExit?: () => void;\n\t/** Gate consulted before the empty-exit window advances (connected clients block it). */\n\tcanExitWhenEmpty?: () => boolean;\n}\n\nfunction parseSessionCap(value: string | undefined): number | undefined {\n\tif (value === undefined || !/^\\d+$/.test(value.trim())) return undefined;\n\tconst parsed = Number(value.trim());\n\treturn Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\n/** Precedence: explicit overrides beat environment variables beat documented defaults. */\nexport function resolveHostIdlePolicy(\n\tenv: Readonly<Record<string, string | undefined>>,\n\toverrides: HostIdleOverrides = {},\n): { now: () => number; idleEvictionMs: number; emptyExitMs: number; maxSessions: number } {\n\treturn {\n\t\tnow: overrides.now ?? Date.now,\n\t\tidleEvictionMs:\n\t\t\toverrides.idleEvictionMs ??\n\t\t\tparseIdleExitMs(env[RPC_SESSION_IDLE_EVICTION_MS_ENV]) ??\n\t\t\tDEFAULT_SESSION_IDLE_EVICTION_MS,\n\t\temptyExitMs:\n\t\t\toverrides.emptyExitMs ?? parseIdleExitMs(env[RPC_HOST_EMPTY_EXIT_MS_ENV]) ?? DEFAULT_HOST_EMPTY_EXIT_MS,\n\t\tmaxSessions: overrides.maxSessions ?? parseSessionCap(env[RPC_MAX_SESSIONS_ENV]) ?? DEFAULT_MAX_SESSIONS,\n\t};\n}\n\ninterface Connection {\n\treadonly id: string;\n\treadonly sink: RpcConnectionSink;\n\treadonly detach: () => void;\n\treadonly close: () => void;\n}\n\n/**\n * Socket agent events are delivered only to connections attached to their\n * session, tagged with its routing sessionId. Content-free session lifecycle\n * events remain visible to every connection. Responses and extension UI\n * requests remain requester-only; foreign observation uses attach-on-open.\n */\nexport async function runMultiSessionHost(options: MultiSessionHostOptions): Promise<never> {\n\tif (options.listen === undefined || options.listen === \"stdio://\") return runStdioHost(options);\n\treturn runSocketHost(options, resolveSocketPath(options.listen, options.agentDir));\n}\n\nexport function createHostCore(\n\toptions: MultiSessionHostOptions,\n\twriter: SessionEventWriter,\n\tcapabilities = parseClientCapabilities(envValue(\"RPC_CLIENT_CAPABILITIES\")),\n\tidle: HostIdleOverrides = {},\n) {\n\tconst policy = resolveHostIdlePolicy(process.env, idle);\n\tconst router = new SessionCommandRouter(\n\t\tnew RpcSessionRegistry({\n\t\t\tagentDir: options.agentDir,\n\t\t\tcreateRuntime: options.createRuntime,\n\t\t\tnow: policy.now,\n\t\t\tmaxSessions: policy.maxSessions,\n\t\t\tcloseGraceMs: idle.closeGraceMs ?? parseIdleExitMs(process.env[RPC_CLOSE_GRACE_MS_ENV]) ?? 10_000,\n\t\t}),\n\t\twriter,\n\t\toptions,\n\t\toptions.createBinding,\n\t\t{ capabilities },\n\t\t{\n\t\t\tnow: policy.now,\n\t\t\tidleEvictionMs: policy.idleEvictionMs,\n\t\t\temptyExitMs: policy.emptyExitMs,\n\t\t\tonEmptyExit: idle.onEmptyExit,\n\t\t\tcanExitWhenEmpty: idle.canExitWhenEmpty,\n\t\t},\n\t);\n\tconst handle = async (line: string): Promise<void> => {\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(line);\n\t\t} catch (cause) {\n\t\t\tawait writer.enqueueControl(parseError(`Failed to parse command: ${errorMessage(cause)}`));\n\t\t\treturn;\n\t\t}\n\t\tconst shapeError = rpcCommandShapeError(parsed);\n\t\tif (shapeError) {\n\t\t\tawait writer.enqueueControl(parseError(shapeError));\n\t\t\treturn;\n\t\t}\n\t\tconst response = await router.handle(parsed as RpcCommand);\n\t\tif (response) await writer.enqueueControl(response);\n\t};\n\treturn { router, handle };\n}\n\n/** Plain-stdio host with no eagerly-created AgentSessionRuntime. */\nasync function runStdioHost(options: MultiSessionHostOptions): Promise<never> {\n\ttakeOverStdout();\n\tconst sink: RpcConnectionSink = { writeRaw: writeRawStdout, waitForBackpressure: waitForRawStdoutBackpressure };\n\tconst writer = new SessionEventWriter(sink.writeRaw, sink.waitForBackpressure);\n\t// An empty host (no session ever opened, or all closed) must not stay resident\n\t// forever: exit through the normal shutdown path once the window elapses.\n\tconst { router, handle } = createHostCore(options, writer, undefined, {\n\t\tonEmptyExit: () => void shutdown(0),\n\t});\n\tlet shuttingDown = false;\n\tconst shutdown = async (exitCode = 0): Promise<never> => {\n\t\tif (shuttingDown) process.exit(exitCode);\n\t\tshuttingDown = true;\n\t\tdetach();\n\t\tawait router.dispose();\n\t\tawait writer.flush();\n\t\tawait flushRawStdout();\n\t\tprocess.exit(exitCode);\n\t};\n\tconst onEnd = () => void shutdown();\n\tprocess.stdin.on(\"end\", onEnd);\n\tconst detachReader = attachJsonlLineReader(process.stdin, (line) => void handle(line), {\n\t\tmaxLineLength: MAX_RPC_LINE_CHARACTERS,\n\t\tonOversizedLine: () => void writer.enqueueControl(parseError(oversizedLineError())),\n\t});\n\tconst detach = () => {\n\t\tdetachReader();\n\t\tprocess.stdin.off(\"end\", onEnd);\n\t};\n\tregisterShutdownSignals(shutdown);\n\treturn new Promise(() => {});\n}\n\nasync function runSocketHost(options: MultiSessionHostOptions, socketPath: string): Promise<never> {\n\tawait prepareSocketPath(socketPath);\n\tconst writer = new SessionEventWriter(() => {});\n\tconst connections = new Map<string, Connection>();\n\tconst { router, handle } = createHostCore(\n\t\toptions,\n\t\twriter,\n\t\tparseClientCapabilities(envValue(\"RPC_CLIENT_CAPABILITIES\")).filter(\n\t\t\t(capability) => capability !== \"rendered_components\",\n\t\t),\n\t\t// Supervised hosts idle-exit via the supervisor, but a socket host that\n\t\t// outlives its supervisor (or is started bare) still self-exits when empty.\n\t\t// A connected client counts as occupancy even with no session open: exiting\n\t\t// under it would drop its socket and read as a crash to the supervisor.\n\t\t{ onEmptyExit: () => void shutdown(0), canExitWhenEmpty: () => connections.size === 0 },\n\t);\n\tlet nextConnection = 0;\n\tlet shuttingDown = false;\n\tconst secret =\n\t\tprocess.platform === \"win32\"\n\t\t\t? await ensureSocketSecret(process.env[SOCKET_SECRET_FILE_ENV] ?? socketSecretPath(socketPath))\n\t\t\t: undefined;\n\tconst server = createServer((socket) => {\n\t\tconst accept = (): void => {\n\t\t\tconst id = `socket-${++nextConnection}`;\n\t\t\tconst sink = socketSink(socket);\n\t\t\twriter.registerConnection(id, sink);\n\t\t\tconst detachReader = attachJsonlLineReader(\n\t\t\t\tsocket,\n\t\t\t\t(line) => {\n\t\t\t\t\t// Do not serialize awaited commands: extension_ui_response and other\n\t\t\t\t\t// re-entrant frames must be able to resolve a command already awaiting them.\n\t\t\t\t\tvoid writer\n\t\t\t\t\t\t.withConnection(id, () => handle(line))\n\t\t\t\t\t\t.catch((cause) => {\n\t\t\t\t\t\t\tprocess.stderr.write(`senpi rpc connection ${id} failed: ${errorMessage(cause)}\\n`);\n\t\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmaxLineLength: MAX_RPC_LINE_CHARACTERS,\n\t\t\t\t\tonOversizedLine: () => {\n\t\t\t\t\t\tvoid writer\n\t\t\t\t\t\t\t.withConnection(id, () => writer.enqueueControl(parseError(oversizedLineError())))\n\t\t\t\t\t\t\t.catch((cause) =>\n\t\t\t\t\t\t\t\tprocess.stderr.write(`senpi rpc connection ${id} failed: ${errorMessage(cause)}\\n`),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tlet detached = false;\n\t\t\tconst detach = () => {\n\t\t\t\tif (detached) return;\n\t\t\t\tdetached = true;\n\t\t\t\tdetachReader();\n\t\t\t\twriter.unregisterConnection(id);\n\t\t\t\tconnections.delete(id);\n\t\t\t\t// A socket that dies without close_session still owns its sessions' attachments\n\t\t\t\t// and path reservations. Release them on the command chain so this runs after any\n\t\t\t\t// in-flight command for this connection settles, otherwise the path stays pinned\n\t\t\t\t// by a runtime whose client is gone and later resumes attach to that orphan.\n\t\t\t\tvoid router.releaseConnection(id).catch((cause) => {\n\t\t\t\t\tprocess.stderr.write(`senpi rpc connection ${id} release failed: ${errorMessage(cause)}\\n`);\n\t\t\t\t});\n\t\t\t};\n\t\t\tconnections.set(id, { id, sink, detach, close: () => socket.destroy() });\n\t\t\tsocket.once(\"close\", detach);\n\t\t\tsocket.once(\"error\", () => detach());\n\t\t};\n\t\tif (secret) authenticateSocket(socket, secret, accept);\n\t\telse accept();\n\t});\n\tserver.on(\"error\", (cause) => {\n\t\tif (!shuttingDown) process.stderr.write(`senpi rpc socket listener failed: ${errorMessage(cause)}\\n`);\n\t});\n\tconst shutdown = async (exitCode = 0, watchdogCleanup?: Promise<void>): Promise<never> => {\n\t\tif (shuttingDown) process.exit(exitCode);\n\t\tshuttingDown = true;\n\t\t// On Windows, destroying named-pipe sockets does not always make libuv's\n\t\t// server.close callback fire: connected pipe instances can remain in the\n\t\t// kernel after the JavaScript handles are destroyed. Keep the normal drain\n\t\t// path, but never let that platform-specific close stall orphan the host.\n\t\ttry {\n\t\t\tfor (const connection of connections.values()) {\n\t\t\t\tconnection.detach();\n\t\t\t\tconnection.close();\n\t\t\t}\n\t\t\tawait (process.platform === \"win32\"\n\t\t\t\t? Promise.race([closeServer(server), delay(WINDOWS_SHUTDOWN_HARD_EXIT_MS)])\n\t\t\t\t: closeServer(server));\n\t\t\tawait router.dispose();\n\t\t\tawait writer.flush();\n\t\t\tawait removeSocketPath(socketPath);\n\t\t\tif (watchdogCleanup) await watchdogCleanup;\n\t\t} finally {\n\t\t\t// Explicitly terminate after every shutdown trigger. Windows named-pipe\n\t\t\t// handles are not fully controllable from JS, and an unresolved cleanup\n\t\t\t// must not leave this daemon or its public endpoint alive.\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t};\n\tregisterShutdownSignals(shutdown);\n\t// Arm before listen: a supervisor death during the listen transition must\n\t// still close the child and clean its private endpoint.\n\tarmHostWatchdog(readHostWatchdogConfigFromBrandEnv(), (reason, cleanup) => {\n\t\tprocess.stderr.write(`senpi rpc host: ${reason}; shutting down\\n`);\n\t\t// Enter shutdown before killing session-owned child processes. The Windows\n\t\t// tree killer is synchronous, while the shutdown fallback must be armed\n\t\t// before any such cleanup can delay the event loop.\n\t\tvoid shutdown(0, cleanup);\n\t\tsetImmediate(killTrackedDetachedChildren);\n\t});\n\tawait listen(server, socketPath, secret);\n\tprocess.stderr.write(`senpi rpc listening on ${formatSocketAddress(socketPath)}\\n`);\n\n\t// Opt-in only: set by the lifecycle supervisor so this host can never outlive\n\t// it, including when the supervisor is SIGKILLed and runs no handler at all.\n\treturn new Promise(() => {});\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseError(error: string): RpcResponse {\n\treturn { type: \"response\", command: \"parse\", success: false, error };\n}\n\nfunction oversizedLineError(): string {\n\treturn `RPC input line exceeds ${MAX_RPC_LINE_CHARACTERS} characters.`;\n}\n\nfunction errorMessage(cause: unknown): string {\n\treturn cause instanceof Error ? cause.message : String(cause);\n}\n\nfunction resolveSocketPath(value: string, agentDir: string): string {\n\tif (value === \"unix://\") return join(agentDir, \"rpc\", \"rpc.sock\");\n\tif (value.startsWith(\"unix://\")) {\n\t\tconst path = value.slice(\"unix://\".length);\n\t\tif (path.length === 0) return join(agentDir, \"rpc\", \"rpc.sock\");\n\t\tif (path.startsWith(\"@\") && process.platform === \"linux\") return `\\0${path.slice(1)}`;\n\t\treturn path;\n\t}\n\treturn value;\n}\n\nfunction formatSocketAddress(socketPath: string): string {\n\treturn socketPath.startsWith(\"\\0\") ? `unix://@${socketPath.slice(1)}` : `unix://${socketPath}`;\n}\n\nfunction socketSink(socket: Socket): RpcConnectionSink {\n\tlet needsDrain = false;\n\treturn {\n\t\twriteRaw(chunk) {\n\t\t\tif (!socket.destroyed) needsDrain = !socket.write(chunk);\n\t\t},\n\t\twaitForBackpressure() {\n\t\t\tif (socket.destroyed || !needsDrain) return Promise.resolve();\n\t\t\tneedsDrain = false;\n\t\t\treturn new Promise<void>((resolve) => {\n\t\t\t\tconst done = () => {\n\t\t\t\t\tsocket.off(\"drain\", done);\n\t\t\t\t\tsocket.off(\"close\", done);\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t\tsocket.once(\"drain\", done);\n\t\t\t\tsocket.once(\"close\", done);\n\t\t\t});\n\t\t},\n\t};\n}\n\nasync function prepareSocketPath(socketPath: string): Promise<void> {\n\tif (process.platform === \"win32\" || socketPath.startsWith(\"\\0\")) return;\n\tawait mkdir(dirname(socketPath), { recursive: true, mode: 0o700 });\n\ttry {\n\t\tawait access(socketPath);\n\t} catch (cause) {\n\t\tif (isNodeErrorCode(cause, \"ENOENT\")) return;\n\t\tthrow cause;\n\t}\n\tif (await probeSocket(socketPath)) throw new Error(`${socketPath}: address already in use by a live server.`);\n\tawait unlink(socketPath);\n}\n\nfunction probeSocket(socketPath: string): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = createConnection(resolveSocketTransportAddress(socketPath, process.platform));\n\t\tconst settle = (live: boolean) => {\n\t\t\tsocket.destroy();\n\t\t\tresolve(live);\n\t\t};\n\t\tsocket.once(\"connect\", () => settle(true));\n\t\tsocket.once(\"error\", () => settle(false));\n\t\tsocket.setTimeout(1_000, () => settle(false));\n\t});\n}\n\nfunction listen(server: Server, socketPath: string, secret?: Uint8Array): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tserver.once(\"error\", reject);\n\t\tserver.listen(resolveSocketTransportAddress(socketPath, process.platform, secret), async () => {\n\t\t\tserver.off(\"error\", reject);\n\t\t\ttry {\n\t\t\t\tif (process.platform !== \"win32\" && !socketPath.startsWith(\"\\0\")) await chmod(socketPath, 0o600);\n\t\t\t\tresolve();\n\t\t\t} catch (cause) {\n\t\t\t\treject(cause);\n\t\t\t}\n\t\t});\n\t});\n}\n\nfunction closeServer(server: Server): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tserver.close((cause) => (cause ? reject(cause) : resolve()));\n\t});\n}\n\nasync function removeSocketPath(socketPath: string): Promise<void> {\n\tif (process.platform === \"win32\" || socketPath.startsWith(\"\\0\")) return;\n\ttry {\n\t\tawait unlink(socketPath);\n\t} catch (cause) {\n\t\tif (!isNodeErrorCode(cause, \"ENOENT\")) throw cause;\n\t}\n}\n\nfunction isNodeErrorCode(cause: unknown, code: string): boolean {\n\treturn cause instanceof Error && \"code\" in cause && cause.code === code;\n}\n\nfunction registerShutdownSignals(shutdown: (exitCode?: number) => Promise<never>): void {\n\tfor (const signal of process.platform === \"win32\" ? ([\"SIGTERM\"] as const) : ([\"SIGTERM\", \"SIGHUP\"] as const)) {\n\t\tprocess.on(signal, () => {\n\t\t\tkillTrackedDetachedChildren();\n\t\t\tvoid shutdown(signal === \"SIGHUP\" ? 129 : 143);\n\t\t});\n\t}\n}\n"]}
@@ -29,7 +29,7 @@
29
29
  * | ---------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----- |
30
30
  * | `get_protocol_info` | - | `{ protocolVersion: 1, serverVersion, capabilities, mode: "classic"|"multi" }` | Answered in BOTH modes; side-effect-free capability probe. |
31
31
  * | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState, attached?: boolean }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there); `provider`/`modelId` applied only on create (resume restores the session's model); params form the immutable launch profile (D8). |
32
- * | `close_session` | `sessionId` | `{}` | Aborts active work, awaits agent idle + settled persistence, flushes queued events, detaches subscriptions; its response is the LAST record tagged with that handle no events after (test-pinned). |
32
+ * | `close_session` | `sessionId` | `{}` | Aborts active work and awaits teardown for the host grace window, then force-releases; the first closer's response is the LAST record tagged with that handle, while concurrent closes join and receive targeted success responses. |
33
33
  * | `list_sessions` | - | `{ sessions: [{ sessionId, durableSessionId, sessionPath, cwd, name, status }] }` | Includes `opening`/`closing` entries with their status. |
34
34
  * | `get_steering_messages` / `get_follow_up_messages` / `clear_queue` | queue read or clear parameters | host-authoritative queue values | Interactive attach clients must not read bootstrap queues. |
35
35
  * | `abort_branch_summary` / `record_bash_result` / `set_label` | narrow mutation payloads | `{}` | Routes interactive runtime mutations to the owning host session. |
@@ -29,7 +29,7 @@
29
29
  * | ---------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----- |
30
30
  * | `get_protocol_info` | - | `{ protocolVersion: 1, serverVersion, capabilities, mode: "classic"|"multi" }` | Answered in BOTH modes; side-effect-free capability probe. |
31
31
  * | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState, attached?: boolean }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there); `provider`/`modelId` applied only on create (resume restores the session's model); params form the immutable launch profile (D8). |
32
- * | `close_session` | `sessionId` | `{}` | Aborts active work, awaits agent idle + settled persistence, flushes queued events, detaches subscriptions; its response is the LAST record tagged with that handle no events after (test-pinned). |
32
+ * | `close_session` | `sessionId` | `{}` | Aborts active work and awaits teardown for the host grace window, then force-releases; the first closer's response is the LAST record tagged with that handle, while concurrent closes join and receive targeted success responses. |
33
33
  * | `list_sessions` | - | `{ sessions: [{ sessionId, durableSessionId, sessionPath, cwd, name, status }] }` | Includes `opening`/`closing` entries with their status. |
34
34
  * | `get_steering_messages` / `get_follow_up_messages` / `clear_queue` | queue read or clear parameters | host-authoritative queue values | Interactive attach clients must not read bootstrap queues. |
35
35
  * | `abort_branch_summary` / `record_bash_result` / `set_label` | narrow mutation payloads | `{}` | Routes interactive runtime mutations to the owning host session. |
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-mode.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RPC mode: Headless operation with JSON stdin/stdout protocol.\n *\n * Used for embedding the agent in other applications.\n * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.\n *\n * Protocol:\n * - Commands: JSON objects with `type` field, optional `id` for correlation\n * - Responses: JSON objects with `type: \"response\"`, `command`, `success`, and optional `data`/`error`\n * - Events: AgentSessionEvent objects streamed as they occur\n * - Extension UI: Extension UI requests are emitted, client responds with extension_ui_response\n *\n * This is the single-connection stdio host. The RPC command loop, extension-UI\n * bridge, and event subscription live in `connection-handler.ts` so the same\n * logic can also serve a caller-owned RPC transport. This file owns exactly the\n * process-level concerns that a per-connection handler must NOT\n * touch: stdout takeover, stdin wiring, signal handlers, and process exit.\n *\n * ── Multi-session mode (`--multi-session`) ─────────────────────────────────\n *\n * Startup: `senpi --mode rpc --multi-session` → NO default session is constructed\n * (no default `AgentSessionRuntime`, no default extension/watcher load). Classic\n * `senpi --mode rpc` is byte-identical to today. Mode is fixed at process start;\n * there is no runtime transition.\n *\n * D1 normative table (multi-session mode):\n *\n * | Command | Params | Success data | Notes |\n * | ---------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----- |\n * | `get_protocol_info` | - | `{ protocolVersion: 1, serverVersion, capabilities, mode: \"classic\"|\"multi\" }` | Answered in BOTH modes; side-effect-free capability probe. |\n * | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState, attached?: boolean }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there); `provider`/`modelId` applied only on create (resume restores the session's model); params form the immutable launch profile (D8). |\n * | `close_session` | `sessionId` | `{}` | Aborts active work, awaits agent idle + settled persistence, flushes queued events, detaches subscriptions; its response is the LAST record tagged with that handle — no events after (test-pinned). |\n * | `list_sessions` | - | `{ sessions: [{ sessionId, durableSessionId, sessionPath, cwd, name, status }] }` | Includes `opening`/`closing` entries with their status. |\n * | `get_steering_messages` / `get_follow_up_messages` / `clear_queue` | queue read or clear parameters | host-authoritative queue values | Interactive attach clients must not read bootstrap queues. |\n * | `abort_branch_summary` / `record_bash_result` / `set_label` | narrow mutation payloads | `{}` | Routes interactive runtime mutations to the owning host session. |\n * | every existing command | + `sessionId` (REQUIRED in multi mode) | unchanged | Routed to that session. |\n *\n * Identities (D6): response-level `sessionId` = opaque routing handle, unique per\n * process epoch, ephemeral (dies with the child). `state.sessionId` = durable\n * JSONL session identity (what a resume cursor stores today). `list_sessions`\n * exposes both. Clients store both, discard routing handles on child exit, verify\n * only durable ids against cursors.\n *\n * Stable error codes (in the response `error` field, machine-matchable):\n * `unknown_session`, `session_closing`, `session_path_in_use`, `missing_session_id`\n * (session-scoped command without `sessionId` in multi mode), `multi_session_disabled`\n * (`open_session` in classic mode), `invalid_path` (relative `sessionPath`/`cwd`),\n * `open_failed: <detail>`.\n *\n * Tagging: every response/event/`extension_ui_request` belonging to a session\n * carries top-level `sessionId` (routing handle). `get_protocol_info`/\n * `list_sessions` responses are untagged. Classic mode: nothing tagged\n * (byte-identical).\n *\n * Ordering guarantee (D9): strict FIFO per session; one total stdout order;\n * cross-session order unspecified; fair round-robin between sessions' queued\n * complete records; NO cross-session batch coalescing (per-session event buffers;\n * the process-wide single-array coalescer in `event-output-buffer.ts` must not\n * merge records of different sessions into one write). Starvation freedom is NOT\n * promised (single pipe); a giant tool record delays others — bounded only by\n * record completion.\n *\n * Duplicate/idempotency: duplicate `open_session` while a path reservation is\n * held → `session_path_in_use`. `close_session` on unknown/already-closed →\n * `unknown_session` error. Request `id`s are client-owned; the server echoes them\n * without dedup.\n *\n * Full prose docs: `packages/coding-agent/docs/rpc.md` (Multi-session mode).\n */\n\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport { envValue } from \"../../core/brand.ts\";\nimport {\n\tflushRawStdout,\n\ttakeOverStdout,\n\twaitForRawStdoutBackpressure,\n\twriteRawStdout,\n} from \"../../core/output-guard.ts\";\nimport { killTrackedDetachedChildren } from \"../../utils/shell.ts\";\nimport { toJsonEvent } from \"../json-event.ts\";\nimport { createRpcConnectionHandler, type RpcConnectionSink } from \"./connection-handler.ts\";\nimport { parseClientCapabilities } from \"./custom-capability.ts\";\nimport { attachJsonlLineReader, MAX_RPC_LINE_CHARACTERS, serializeJsonLine } from \"./jsonl.ts\";\n\n// Re-export types for consumers\nexport type {\n\tRpcCommand,\n\tRpcExtensionUIRequest,\n\tRpcExtensionUIResponse,\n\tRpcResponse,\n\tRpcSessionState,\n} from \"./rpc-types.ts\";\n\n/**\n * Run in RPC mode.\n * Listens for JSON commands on stdin, outputs events and responses on stdout.\n */\nexport async function runRpcMode(runtimeHost: AgentSessionRuntime): Promise<never> {\n\ttakeOverStdout();\n\n\tconst sink: RpcConnectionSink = {\n\t\twriteRaw: (chunk) => {\n\t\t\tconst linearized = chunk\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.filter((line) => line.length > 0)\n\t\t\t\t.map((line) => {\n\t\t\t\t\tconst value = JSON.parse(line) as { type?: string };\n\t\t\t\t\treturn JSON.stringify(value.type === \"message_update\" ? toJsonEvent(value as AgentSessionEvent) : value);\n\t\t\t\t})\n\t\t\t\t.join(\"\\n\");\n\t\t\twriteRawStdout(linearized.length > 0 ? `${linearized}\\n` : \"\");\n\t\t},\n\t\twaitForBackpressure: waitForRawStdoutBackpressure,\n\t};\n\n\t// Client capability flags reach this single-connection stdio host via the\n\t// SENPI_RPC_CLIENT_CAPABILITIES env var (comma-separated). A launcher can set\n\t// it from a client handshake; a plain stdio client that sets nothing gets\n\t// byte-identical default behavior.\n\tconst capabilities = parseClientCapabilities(envValue(\"RPC_CLIENT_CAPABILITIES\"));\n\tconst handler = createRpcConnectionHandler(runtimeHost, sink, { capabilities });\n\n\tlet shuttingDown = false;\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid shutdown(signal === \"SIGHUP\" ? 129 : 143, signal);\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\tlet detachInput = () => {};\n\n\tasync function shutdown(exitCode = 0, signal?: NodeJS.Signals): Promise<never> {\n\t\tif (shuttingDown) {\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t\tshuttingDown = true;\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait handler.dispose();\n\t\tdetachInput();\n\t\tprocess.stdin.pause();\n\t\tif (signal !== \"SIGTERM\") {\n\t\t\tawait flushRawStdout();\n\t\t}\n\t\tprocess.exit(exitCode);\n\t}\n\n\tconst handleInputLine = async (line: string): Promise<void> => {\n\t\tawait handler.handleInputLine(line);\n\t\tif (handler.isShutdownRequested()) {\n\t\t\tawait shutdown();\n\t\t}\n\t};\n\n\tconst onInputEnd = () => {\n\t\tvoid shutdown();\n\t};\n\tprocess.stdin.on(\"end\", onInputEnd);\n\n\tdetachInput = (() => {\n\t\tconst detachJsonl = attachJsonlLineReader(\n\t\t\tprocess.stdin,\n\t\t\t(line) => {\n\t\t\t\tvoid handleInputLine(line);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmaxLineLength: MAX_RPC_LINE_CHARACTERS,\n\t\t\t\tonOversizedLine: () => {\n\t\t\t\t\twriteRawStdout(\n\t\t\t\t\t\tserializeJsonLine({\n\t\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\t\tcommand: \"parse\",\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: `RPC input line exceeds ${MAX_RPC_LINE_CHARACTERS} characters.`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tvoid waitForRawStdoutBackpressure();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\treturn () => {\n\t\t\tdetachJsonl();\n\t\t\tprocess.stdin.off(\"end\", onInputEnd);\n\t\t};\n\t})();\n\n\t// Keep process alive forever\n\treturn new Promise(() => {});\n}\n"]}
1
+ {"version":3,"file":"rpc-mode.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RPC mode: Headless operation with JSON stdin/stdout protocol.\n *\n * Used for embedding the agent in other applications.\n * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.\n *\n * Protocol:\n * - Commands: JSON objects with `type` field, optional `id` for correlation\n * - Responses: JSON objects with `type: \"response\"`, `command`, `success`, and optional `data`/`error`\n * - Events: AgentSessionEvent objects streamed as they occur\n * - Extension UI: Extension UI requests are emitted, client responds with extension_ui_response\n *\n * This is the single-connection stdio host. The RPC command loop, extension-UI\n * bridge, and event subscription live in `connection-handler.ts` so the same\n * logic can also serve a caller-owned RPC transport. This file owns exactly the\n * process-level concerns that a per-connection handler must NOT\n * touch: stdout takeover, stdin wiring, signal handlers, and process exit.\n *\n * ── Multi-session mode (`--multi-session`) ─────────────────────────────────\n *\n * Startup: `senpi --mode rpc --multi-session` → NO default session is constructed\n * (no default `AgentSessionRuntime`, no default extension/watcher load). Classic\n * `senpi --mode rpc` is byte-identical to today. Mode is fixed at process start;\n * there is no runtime transition.\n *\n * D1 normative table (multi-session mode):\n *\n * | Command | Params | Success data | Notes |\n * | ---------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----- |\n * | `get_protocol_info` | - | `{ protocolVersion: 1, serverVersion, capabilities, mode: \"classic\"|\"multi\" }` | Answered in BOTH modes; side-effect-free capability probe. |\n * | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState, attached?: boolean }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there); `provider`/`modelId` applied only on create (resume restores the session's model); params form the immutable launch profile (D8). |\n * | `close_session` | `sessionId` | `{}` | Aborts active work and awaits teardown for the host grace window, then force-releases; the first closer's response is the LAST record tagged with that handle, while concurrent closes join and receive targeted success responses. |\n * | `list_sessions` | - | `{ sessions: [{ sessionId, durableSessionId, sessionPath, cwd, name, status }] }` | Includes `opening`/`closing` entries with their status. |\n * | `get_steering_messages` / `get_follow_up_messages` / `clear_queue` | queue read or clear parameters | host-authoritative queue values | Interactive attach clients must not read bootstrap queues. |\n * | `abort_branch_summary` / `record_bash_result` / `set_label` | narrow mutation payloads | `{}` | Routes interactive runtime mutations to the owning host session. |\n * | every existing command | + `sessionId` (REQUIRED in multi mode) | unchanged | Routed to that session. |\n *\n * Identities (D6): response-level `sessionId` = opaque routing handle, unique per\n * process epoch, ephemeral (dies with the child). `state.sessionId` = durable\n * JSONL session identity (what a resume cursor stores today). `list_sessions`\n * exposes both. Clients store both, discard routing handles on child exit, verify\n * only durable ids against cursors.\n *\n * Stable error codes (in the response `error` field, machine-matchable):\n * `unknown_session`, `session_closing`, `session_path_in_use`, `missing_session_id`\n * (session-scoped command without `sessionId` in multi mode), `multi_session_disabled`\n * (`open_session` in classic mode), `invalid_path` (relative `sessionPath`/`cwd`),\n * `open_failed: <detail>`.\n *\n * Tagging: every response/event/`extension_ui_request` belonging to a session\n * carries top-level `sessionId` (routing handle). `get_protocol_info`/\n * `list_sessions` responses are untagged. Classic mode: nothing tagged\n * (byte-identical).\n *\n * Ordering guarantee (D9): strict FIFO per session; one total stdout order;\n * cross-session order unspecified; fair round-robin between sessions' queued\n * complete records; NO cross-session batch coalescing (per-session event buffers;\n * the process-wide single-array coalescer in `event-output-buffer.ts` must not\n * merge records of different sessions into one write). Starvation freedom is NOT\n * promised (single pipe); a giant tool record delays others — bounded only by\n * record completion.\n *\n * Duplicate/idempotency: duplicate `open_session` while a path reservation is\n * held → `session_path_in_use`. `close_session` on unknown/already-closed →\n * `unknown_session` error. Request `id`s are client-owned; the server echoes them\n * without dedup.\n *\n * Full prose docs: `packages/coding-agent/docs/rpc.md` (Multi-session mode).\n */\n\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport { envValue } from \"../../core/brand.ts\";\nimport {\n\tflushRawStdout,\n\ttakeOverStdout,\n\twaitForRawStdoutBackpressure,\n\twriteRawStdout,\n} from \"../../core/output-guard.ts\";\nimport { killTrackedDetachedChildren } from \"../../utils/shell.ts\";\nimport { toJsonEvent } from \"../json-event.ts\";\nimport { createRpcConnectionHandler, type RpcConnectionSink } from \"./connection-handler.ts\";\nimport { parseClientCapabilities } from \"./custom-capability.ts\";\nimport { attachJsonlLineReader, MAX_RPC_LINE_CHARACTERS, serializeJsonLine } from \"./jsonl.ts\";\n\n// Re-export types for consumers\nexport type {\n\tRpcCommand,\n\tRpcExtensionUIRequest,\n\tRpcExtensionUIResponse,\n\tRpcResponse,\n\tRpcSessionState,\n} from \"./rpc-types.ts\";\n\n/**\n * Run in RPC mode.\n * Listens for JSON commands on stdin, outputs events and responses on stdout.\n */\nexport async function runRpcMode(runtimeHost: AgentSessionRuntime): Promise<never> {\n\ttakeOverStdout();\n\n\tconst sink: RpcConnectionSink = {\n\t\twriteRaw: (chunk) => {\n\t\t\tconst linearized = chunk\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.filter((line) => line.length > 0)\n\t\t\t\t.map((line) => {\n\t\t\t\t\tconst value = JSON.parse(line) as { type?: string };\n\t\t\t\t\treturn JSON.stringify(value.type === \"message_update\" ? toJsonEvent(value as AgentSessionEvent) : value);\n\t\t\t\t})\n\t\t\t\t.join(\"\\n\");\n\t\t\twriteRawStdout(linearized.length > 0 ? `${linearized}\\n` : \"\");\n\t\t},\n\t\twaitForBackpressure: waitForRawStdoutBackpressure,\n\t};\n\n\t// Client capability flags reach this single-connection stdio host via the\n\t// SENPI_RPC_CLIENT_CAPABILITIES env var (comma-separated). A launcher can set\n\t// it from a client handshake; a plain stdio client that sets nothing gets\n\t// byte-identical default behavior.\n\tconst capabilities = parseClientCapabilities(envValue(\"RPC_CLIENT_CAPABILITIES\"));\n\tconst handler = createRpcConnectionHandler(runtimeHost, sink, { capabilities });\n\n\tlet shuttingDown = false;\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid shutdown(signal === \"SIGHUP\" ? 129 : 143, signal);\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\tlet detachInput = () => {};\n\n\tasync function shutdown(exitCode = 0, signal?: NodeJS.Signals): Promise<never> {\n\t\tif (shuttingDown) {\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t\tshuttingDown = true;\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait handler.dispose();\n\t\tdetachInput();\n\t\tprocess.stdin.pause();\n\t\tif (signal !== \"SIGTERM\") {\n\t\t\tawait flushRawStdout();\n\t\t}\n\t\tprocess.exit(exitCode);\n\t}\n\n\tconst handleInputLine = async (line: string): Promise<void> => {\n\t\tawait handler.handleInputLine(line);\n\t\tif (handler.isShutdownRequested()) {\n\t\t\tawait shutdown();\n\t\t}\n\t};\n\n\tconst onInputEnd = () => {\n\t\tvoid shutdown();\n\t};\n\tprocess.stdin.on(\"end\", onInputEnd);\n\n\tdetachInput = (() => {\n\t\tconst detachJsonl = attachJsonlLineReader(\n\t\t\tprocess.stdin,\n\t\t\t(line) => {\n\t\t\t\tvoid handleInputLine(line);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmaxLineLength: MAX_RPC_LINE_CHARACTERS,\n\t\t\t\tonOversizedLine: () => {\n\t\t\t\t\twriteRawStdout(\n\t\t\t\t\t\tserializeJsonLine({\n\t\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\t\tcommand: \"parse\",\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: `RPC input line exceeds ${MAX_RPC_LINE_CHARACTERS} characters.`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tvoid waitForRawStdoutBackpressure();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\treturn () => {\n\t\t\tdetachJsonl();\n\t\t\tprocess.stdin.off(\"end\", onInputEnd);\n\t\t};\n\t})();\n\n\t// Keep process alive forever\n\treturn new Promise(() => {});\n}\n"]}
@@ -41,6 +41,7 @@ export declare class SessionCommandRouter {
41
41
  private readonly connectionOptions;
42
42
  private readonly widths;
43
43
  private readonly pendingCapabilities;
44
+ private readonly finalizations;
44
45
  private readonly idleNow;
45
46
  private readonly idleEvictionMs;
46
47
  private readonly emptyExitMs;
@@ -89,7 +90,28 @@ export declare class SessionCommandRouter {
89
90
  * and their event stream.
90
91
  */
91
92
  private releaseOwnedSession;
93
+ /**
94
+ * Releases one attachment (or every attachment when draining) and reports
95
+ * whether this caller became the finalizer. The join token is installed inside
96
+ * the registry callback, before any await, so a close that lands between the
97
+ * claim and finalizeClose() always finds a token to wait on instead of
98
+ * answering ahead of the terminal records.
99
+ */
100
+ private claimClose;
101
+ /** claimClose() for lifecycle paths that treat a lost race as "nothing to do". */
102
+ private tryClaimClose;
92
103
  private close;
104
+ /** Detaches the closing connection's UI/width state; a rerender failure must not abort the close. */
105
+ private releaseOwnerAttachment;
106
+ /**
107
+ * Runs the finalizer side of a close for a handle whose beginClose() made this
108
+ * caller the owner: dispose the binding, complete the registry teardown, emit
109
+ * the terminal records, then release joiners. Every step is guarded so the join
110
+ * token always resolves and a failing binding yields one logged line, never a
111
+ * second response or an escaped rejection.
112
+ */
113
+ private finalizeClose;
114
+ private createFinalization;
93
115
  private code;
94
116
  }
95
117
  //# sourceMappingURL=session-command-router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-command-router.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/session-command-router.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAO9D,OAAO,EAAE,uBAAuB,EAA0B,MAAM,sBAAsB,CAAC;AACvF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAGX,uBAAuB,EACvB,kBAAkB,EAClB,MAAM,uBAAuB,CAAC;AAK/B,gGAAgG;AAChG,MAAM,MAAM,iBAAiB,GAAG,OAAO,uBAAuB,CAAC;AAE/D;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACpC,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,wGAAwG;IACxG,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC;CACjC;AAMD,uFAAuF;AACvF,qBAAa,oBAAoB;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IACjE,gFAAgF;IAChF,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA0C;IAC/E,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyC;IAC3E,0DAA0D;IAC1D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGvB;IACF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiC;IAC/D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgD;IAClF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA+B;IACnE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAgB;IAClD,OAAO,CAAC,UAAU,CAA6C;IAC/D,OAAO,CAAC,UAAU,CAAqB;gBAGtC,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,IAAI,CAAC,uBAAuB,EAAE,KAAK,GAAG,kBAAkB,GAAG,eAAe,GAAG,sBAAsB,CAAC,EAC9G,aAAa,GAAE,OAAO,uBAAiD,EACvE,iBAAiB,GAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAC,CAAM,EACrE,IAAI,CAAC,EAAE,oBAAoB;IAoBtB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAmD7D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB9B;;;;;;;;;OASG;IACH,iBAAiB,IAAI,IAAI;IA4BzB;;;;;OAKG;YACW,gBAAgB;IA6B9B,4EAA4E;IAC5E,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,eAAe;YAiBT,IAAI;IA8GlB;;;;OAIG;IACG,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD5D;;;;;;;OAOG;YACW,mBAAmB;YAkBnB,KAAK;IA4CnB,OAAO,CAAC,IAAI;CAWZ"}
1
+ {"version":3,"file":"session-command-router.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/session-command-router.ts"],"names":[],"mappings":"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"}