@code-yeongyu/senpi 2026.9.15 → 2026.9.16-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 (333) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/README.md +1 -1
  3. package/dist/core/agent-session.d.ts +28 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +111 -13
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/compaction/compaction.d.ts.map +1 -1
  8. package/dist/core/compaction/compaction.js +4 -2
  9. package/dist/core/compaction/compaction.js.map +1 -1
  10. package/dist/core/compaction/stream-watchdog.d.ts +56 -2
  11. package/dist/core/compaction/stream-watchdog.d.ts.map +1 -1
  12. package/dist/core/compaction/stream-watchdog.js +93 -15
  13. package/dist/core/compaction/stream-watchdog.js.map +1 -1
  14. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts +6 -0
  15. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts.map +1 -1
  16. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +17 -0
  17. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
  18. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +4 -1
  19. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +31 -0
  21. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
  22. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts +2 -0
  23. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +16 -0
  25. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
  26. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js +19 -8
  28. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js.map +1 -1
  29. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +2 -1
  31. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +13 -1
  33. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +66 -2
  35. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
  36. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  37. package/dist/core/extensions/builtin/compaction/index.js +16 -10
  38. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  39. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/compaction/speculative-summary.js +4 -2
  41. package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -1
  42. package/dist/core/extensions/builtin/compaction/speculative.d.ts +8 -1
  43. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  44. package/dist/core/extensions/builtin/compaction/speculative.js +31 -7
  45. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  46. package/dist/core/extensions/builtin/compaction/transient-failure.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/compaction/transient-failure.js +6 -3
  48. package/dist/core/extensions/builtin/compaction/transient-failure.js.map +1 -1
  49. package/dist/core/extensions/builtin/config-reload/index.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/config-reload/index.js +25 -8
  51. package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
  52. package/dist/core/extensions/builtin/config-reload/watch-engine.d.ts +4 -5
  53. package/dist/core/extensions/builtin/config-reload/watch-engine.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/config-reload/watch-engine.js +14 -18
  55. package/dist/core/extensions/builtin/config-reload/watch-engine.js.map +1 -1
  56. package/dist/core/extensions/builtin/config-reload/watch-event-source.d.ts.map +1 -1
  57. package/dist/core/extensions/builtin/config-reload/watch-event-source.js +32 -9
  58. package/dist/core/extensions/builtin/config-reload/watch-event-source.js.map +1 -1
  59. package/dist/core/extensions/builtin/cursor-cli-oauth/catalog-refresh.d.ts +23 -0
  60. package/dist/core/extensions/builtin/cursor-cli-oauth/catalog-refresh.d.ts.map +1 -0
  61. package/dist/core/extensions/builtin/cursor-cli-oauth/catalog-refresh.js +48 -0
  62. package/dist/core/extensions/builtin/cursor-cli-oauth/catalog-refresh.js.map +1 -0
  63. package/dist/core/extensions/builtin/cursor-cli-oauth/environment.d.ts +13 -0
  64. package/dist/core/extensions/builtin/cursor-cli-oauth/environment.d.ts.map +1 -0
  65. package/dist/core/extensions/builtin/cursor-cli-oauth/environment.js +24 -0
  66. package/dist/core/extensions/builtin/cursor-cli-oauth/environment.js.map +1 -0
  67. package/dist/core/extensions/builtin/cursor-cli-oauth/executable.d.ts +1 -0
  68. package/dist/core/extensions/builtin/cursor-cli-oauth/executable.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/cursor-cli-oauth/executable.js +7 -1
  70. package/dist/core/extensions/builtin/cursor-cli-oauth/executable.js.map +1 -1
  71. package/dist/core/extensions/builtin/cursor-cli-oauth/index.d.ts +2 -0
  72. package/dist/core/extensions/builtin/cursor-cli-oauth/index.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/cursor-cli-oauth/index.js +11 -9
  74. package/dist/core/extensions/builtin/cursor-cli-oauth/index.js.map +1 -1
  75. package/dist/core/extensions/builtin/cursor-cli-oauth/models-probe.d.ts +18 -0
  76. package/dist/core/extensions/builtin/cursor-cli-oauth/models-probe.d.ts.map +1 -0
  77. package/dist/core/extensions/builtin/cursor-cli-oauth/models-probe.js +61 -0
  78. package/dist/core/extensions/builtin/cursor-cli-oauth/models-probe.js.map +1 -0
  79. package/dist/core/extensions/builtin/cursor-cli-oauth/models.d.ts +4 -1
  80. package/dist/core/extensions/builtin/cursor-cli-oauth/models.d.ts.map +1 -1
  81. package/dist/core/extensions/builtin/cursor-cli-oauth/models.js +1 -44
  82. package/dist/core/extensions/builtin/cursor-cli-oauth/models.js.map +1 -1
  83. package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.d.ts +22 -0
  84. package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.d.ts.map +1 -1
  85. package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.js +1 -1
  86. package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.js.map +1 -1
  87. package/dist/core/extensions/builtin/cursor-cli-oauth/transport.d.ts.map +1 -1
  88. package/dist/core/extensions/builtin/cursor-cli-oauth/transport.js +2 -13
  89. package/dist/core/extensions/builtin/cursor-cli-oauth/transport.js.map +1 -1
  90. package/dist/core/extensions/builtin/terminal/monitor-file-digest.d.ts +3 -0
  91. package/dist/core/extensions/builtin/terminal/monitor-file-digest.d.ts.map +1 -0
  92. package/dist/core/extensions/builtin/terminal/monitor-file-digest.js +25 -0
  93. package/dist/core/extensions/builtin/terminal/monitor-file-digest.js.map +1 -0
  94. package/dist/core/extensions/builtin/terminal/monitor-file-watch.d.ts +9 -0
  95. package/dist/core/extensions/builtin/terminal/monitor-file-watch.d.ts.map +1 -0
  96. package/dist/core/extensions/builtin/terminal/monitor-file-watch.js +33 -0
  97. package/dist/core/extensions/builtin/terminal/monitor-file-watch.js.map +1 -0
  98. package/dist/core/extensions/builtin/terminal/monitor-line-buffer.d.ts +6 -0
  99. package/dist/core/extensions/builtin/terminal/monitor-line-buffer.d.ts.map +1 -0
  100. package/dist/core/extensions/builtin/terminal/monitor-line-buffer.js +22 -0
  101. package/dist/core/extensions/builtin/terminal/monitor-line-buffer.js.map +1 -0
  102. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  103. package/dist/core/extensions/builtin/terminal/monitor-registry.js +14 -35
  104. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  105. package/dist/core/extensions/kernel-tools-context.d.ts +13 -0
  106. package/dist/core/extensions/kernel-tools-context.d.ts.map +1 -0
  107. package/dist/core/extensions/kernel-tools-context.js +3 -0
  108. package/dist/core/extensions/kernel-tools-context.js.map +1 -0
  109. package/dist/core/extensions/runner.d.ts +19 -0
  110. package/dist/core/extensions/runner.d.ts.map +1 -1
  111. package/dist/core/extensions/runner.js +103 -1
  112. package/dist/core/extensions/runner.js.map +1 -1
  113. package/dist/core/extensions/types.d.ts +21 -0
  114. package/dist/core/extensions/types.d.ts.map +1 -1
  115. package/dist/core/extensions/types.js.map +1 -1
  116. package/dist/core/keybindings.d.ts +5 -0
  117. package/dist/core/keybindings.d.ts.map +1 -1
  118. package/dist/core/keybindings.js +1 -0
  119. package/dist/core/keybindings.js.map +1 -1
  120. package/dist/core/resource-loader.d.ts.map +1 -1
  121. package/dist/core/resource-loader.js +9 -17
  122. package/dist/core/resource-loader.js.map +1 -1
  123. package/dist/core/retry-fallback/settings.d.ts +3 -0
  124. package/dist/core/retry-fallback/settings.d.ts.map +1 -1
  125. package/dist/core/retry-fallback/settings.js.map +1 -1
  126. package/dist/core/sdk.d.ts.map +1 -1
  127. package/dist/core/sdk.js +1 -0
  128. package/dist/core/sdk.js.map +1 -1
  129. package/dist/core/session-manager.d.ts +30 -1
  130. package/dist/core/session-manager.d.ts.map +1 -1
  131. package/dist/core/session-manager.js +92 -5
  132. package/dist/core/session-manager.js.map +1 -1
  133. package/dist/core/session-resident-store.d.ts +33 -7
  134. package/dist/core/session-resident-store.d.ts.map +1 -1
  135. package/dist/core/session-resident-store.js +163 -14
  136. package/dist/core/session-resident-store.js.map +1 -1
  137. package/dist/core/session-write-reservation.d.ts +6 -0
  138. package/dist/core/session-write-reservation.d.ts.map +1 -1
  139. package/dist/core/session-write-reservation.js +19 -0
  140. package/dist/core/session-write-reservation.js.map +1 -1
  141. package/dist/core/settings-manager.d.ts +35 -1
  142. package/dist/core/settings-manager.d.ts.map +1 -1
  143. package/dist/core/settings-manager.js +62 -0
  144. package/dist/core/settings-manager.js.map +1 -1
  145. package/dist/core/slash-commands.d.ts.map +1 -1
  146. package/dist/core/slash-commands.js +2 -1
  147. package/dist/core/slash-commands.js.map +1 -1
  148. package/dist/core/tools/index.d.ts +1 -1
  149. package/dist/core/tools/index.d.ts.map +1 -1
  150. package/dist/core/tools/index.js +4 -3
  151. package/dist/core/tools/index.js.map +1 -1
  152. package/dist/core/tools/read.d.ts +3 -1
  153. package/dist/core/tools/read.d.ts.map +1 -1
  154. package/dist/core/tools/read.js +16 -2
  155. package/dist/core/tools/read.js.map +1 -1
  156. package/dist/index.d.ts +1 -0
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +1 -0
  159. package/dist/index.js.map +1 -1
  160. package/dist/modes/interactive/components/assistant-render-descriptors.d.ts.map +1 -1
  161. package/dist/modes/interactive/components/assistant-render-descriptors.js +12 -5
  162. package/dist/modes/interactive/components/assistant-render-descriptors.js.map +1 -1
  163. package/dist/modes/interactive/components/extension-input.d.ts +2 -0
  164. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  165. package/dist/modes/interactive/components/extension-input.js +5 -0
  166. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  167. package/dist/modes/interactive/interactive-mode.d.ts +19 -2
  168. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  169. package/dist/modes/interactive/interactive-mode.js +69 -17
  170. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  171. package/dist/modes/interactive/tips/catalog/session-tips.js +1 -1
  172. package/dist/modes/interactive/tips/catalog/session-tips.js.map +1 -1
  173. package/dist/modes/interactive/working-status.d.ts +3 -2
  174. package/dist/modes/interactive/working-status.d.ts.map +1 -1
  175. package/dist/modes/interactive/working-status.js +17 -4
  176. package/dist/modes/interactive/working-status.js.map +1 -1
  177. package/dist/modes/print-mode.d.ts +1 -1
  178. package/dist/modes/print-mode.d.ts.map +1 -1
  179. package/dist/modes/print-mode.js +5 -1
  180. package/dist/modes/print-mode.js.map +1 -1
  181. package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
  182. package/dist/modes/rpc/host-watchdog.js +5 -24
  183. package/dist/modes/rpc/host-watchdog.js.map +1 -1
  184. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  185. package/dist/modes/rpc/rpc-mode.js +3 -8
  186. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  187. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  188. package/dist/modes/rpc/session-command-router.js +3 -0
  189. package/dist/modes/rpc/session-command-router.js.map +1 -1
  190. package/dist/modes/rpc/session-worker-client.d.ts +3 -0
  191. package/dist/modes/rpc/session-worker-client.d.ts.map +1 -1
  192. package/dist/modes/rpc/session-worker-client.js +17 -6
  193. package/dist/modes/rpc/session-worker-client.js.map +1 -1
  194. package/dist/modes/rpc/shutdown.d.ts +3 -0
  195. package/dist/modes/rpc/shutdown.d.ts.map +1 -0
  196. package/dist/modes/rpc/shutdown.js +17 -0
  197. package/dist/modes/rpc/shutdown.js.map +1 -0
  198. package/docs/extensions.md +5 -2
  199. package/docs/keybindings.md +1 -0
  200. package/docs/session-format.md +1 -1
  201. package/docs/sessions.md +3 -3
  202. package/docs/settings.md +31 -1
  203. package/docs/usage.md +1 -1
  204. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +50 -0
  205. package/node_modules/@code-yeongyu/senpi-codemode/README.md +24 -0
  206. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  207. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/http-server.ts +7 -1
  208. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/kernel-tools-protocol.ts +85 -0
  209. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +6 -0
  210. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/agent-bridge.ts +30 -11
  211. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +11 -0
  212. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +10 -0
  213. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/prelude.jl +46 -0
  214. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/runner.jl +1 -1
  215. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +58 -10
  216. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +12 -0
  217. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-context.d.ts +13 -0
  218. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-context.js +7 -0
  219. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-define.d.ts +10 -0
  220. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-define.js +12 -0
  221. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-errors.js +22 -0
  222. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-errors.ts +26 -0
  223. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-host.ts +134 -0
  224. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-naming.js +28 -0
  225. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-parse.d.ts +5 -0
  226. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-parse.js +255 -0
  227. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-pump.js +105 -0
  228. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-registry.d.ts +27 -0
  229. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-registry.js +127 -0
  230. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-schema.js +69 -0
  231. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-types.ts +42 -0
  232. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/prelude.ts +2 -0
  233. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +26 -3
  234. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +20 -8
  235. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-slot.ts +6 -1
  236. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-startup.ts +9 -7
  237. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/workpool.js +37 -0
  238. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/kernel-tools-unavailable.ts +5 -0
  239. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +13 -0
  240. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +57 -3
  241. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/prelude.rb +13 -2
  242. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/workpool.rb +38 -0
  243. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +13 -0
  244. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +9 -1
  245. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt-template.ts +4 -2
  246. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +31 -3
  247. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +36 -71
  248. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/image-resize.ts +52 -0
  249. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/image.ts +37 -72
  250. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/managed-cell.ts +78 -0
  251. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +30 -5
  252. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/run-eval-cell.ts +52 -30
  253. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/terminal-snapshot-store.ts +35 -0
  254. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/tool-result-marshal.ts +23 -0
  255. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +2 -0
  256. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  257. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +30 -3
  258. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  259. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +5 -0
  260. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  261. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
  262. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  263. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
  264. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +51 -12
  265. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
  266. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.d.ts +3 -0
  267. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.d.ts.map +1 -1
  268. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.js +18 -3
  269. package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.js.map +1 -1
  270. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.d.ts +4 -0
  271. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.d.ts.map +1 -0
  272. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.js +268 -0
  273. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.js.map +1 -0
  274. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.d.ts +18 -0
  275. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.d.ts.map +1 -0
  276. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.js +69 -0
  277. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.js.map +1 -0
  278. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.d.ts +27 -0
  279. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.d.ts.map +1 -0
  280. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.js +118 -0
  281. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.js.map +1 -0
  282. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.d.ts +21 -0
  283. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.d.ts.map +1 -0
  284. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.js +24 -0
  285. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.js.map +1 -0
  286. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.d.ts +12 -0
  287. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.d.ts.map +1 -0
  288. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.js +92 -0
  289. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.js.map +1 -0
  290. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.d.ts +47 -0
  291. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.d.ts.map +1 -0
  292. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.js +8 -0
  293. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.js.map +1 -0
  294. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.d.ts +52 -0
  295. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.d.ts.map +1 -0
  296. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.js +155 -0
  297. package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.js.map +1 -0
  298. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +4 -0
  299. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
  300. package/node_modules/@earendil-works/pi-agent-core/dist/index.js +3 -0
  301. package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
  302. package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.d.ts +101 -0
  303. package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.d.ts.map +1 -0
  304. package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.js +178 -0
  305. package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.js.map +1 -0
  306. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +9 -0
  307. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  308. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  309. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  310. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
  311. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  312. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
  313. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  314. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  315. package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
  316. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  317. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  318. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  319. package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
  320. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  321. package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.d.ts +15 -0
  322. package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.d.ts.map +1 -0
  323. package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.js +15 -0
  324. package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.js.map +1 -0
  325. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts +24 -0
  326. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  327. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +92 -0
  328. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  329. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  330. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  331. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  332. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  333. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"session-command-router.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-command-router.ts"],"names":[],"mappings":"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","sourcesContent":["import { VERSION } from \"../../config.ts\";\nimport { buildRpcSessionState } from \"./connection-handler.ts\";\nimport { AUTO_TITLE_SESSIONS_CAPABILITY, MEDIA_PLACEHOLDERS_CAPABILITY } from \"./custom-capability.ts\";\nimport type { RpcCommand, RpcResponse } from \"./rpc-types.ts\";\nimport {\n\tRPC_ERROR_MISSING_SESSION_ID,\n\tRPC_ERROR_OPEN_FAILED,\n\tRPC_ERROR_SESSION_CLOSING,\n\tRPC_ERROR_UNKNOWN_SESSION,\n} from \"./rpc-types.ts\";\nimport { createRpcSessionBinding, type RpcSessionBinding } from \"./session-binding.ts\";\nimport type { SessionEventWriter } from \"./session-event-writer.ts\";\nimport type { OpenRpcSession, RpcSessionLaunchProfile, RpcSessionRegistry } from \"./session-registry.ts\";\nimport { RpcSessionRegistryError } from \"./session-registry.ts\";\n\nconst controls = new Set([\"get_protocol_info\", \"open_session\", \"close_session\", \"list_sessions\"]);\n\n/** Binding factory seam, injectable so host wiring is testable without a full runtime stack. */\nexport type RpcBindingFactory = typeof createRpcSessionBinding;\n\n/**\n * Occupancy policy for the shared multi-session host. All fields are opt-in:\n * a router constructed without a policy keeps today's behavior (sessions live\n * until close_session; the host never self-exits).\n */\nexport interface RpcSessionIdlePolicy {\n\t/** Injectable clock (defaults to Date.now) for deterministic tests. */\n\tnow?: () => number;\n\t/** Evict open sessions whose last routed command or session-owned work settled longer ago than this. */\n\tidleEvictionMs?: number;\n\t/** Invoke onEmptyExit once the registry has stayed empty for this long. */\n\temptyExitMs?: number;\n\t/** Host shutdown hook fired by the empty-exit window; called at most once. */\n\tonEmptyExit?: () => void;\n\t/**\n\t * Consulted every tick before the empty-exit window advances. Returning false\n\t * both blocks the exit and resets the window, so a host with a connected but\n\t * sessionless client stays up instead of exiting under its supervisor.\n\t */\n\tcanExitWhenEmpty?: () => boolean;\n}\n\nfunction error(id: string | undefined, command: string, code: string): RpcResponse {\n\treturn { id, type: \"response\", command, success: false, error: code };\n}\n\n/** Routes control messages and enforces a routing handle for every session command. */\nexport class SessionCommandRouter {\n\tprivate readonly bindings = new Map<string, RpcSessionBinding>();\n\t/** Session handles opened by each connection, with one count per attachment. */\n\tprivate readonly sessionsByConnection = new Map<string, Map<string, number>>();\n\t/** Opens currently awaiting runtime/binding setup, keyed by connection. */\n\tprivate readonly opensByConnection = new Map<string, Set<Promise<void>>>();\n\t/** Connections whose socket has already been detached. */\n\tprivate readonly releasedConnections = new Set<string>();\n\tprivate readonly registry: Pick<\n\t\tRpcSessionRegistry,\n\t\t\"openSession\" | \"peek\" | \"getForCommand\" | \"beginClose\" | \"close\" | \"closeMarked\" | \"list\" | \"size\"\n\t>;\n\tprivate readonly writer: SessionEventWriter;\n\tprivate readonly defaults: Pick<\n\t\tRpcSessionLaunchProfile,\n\t\t\"cwd\" | \"permissionPreset\" | \"creationModel\" | \"initialThinkingLevel\"\n\t>;\n\tprivate readonly createBinding: typeof createRpcSessionBinding;\n\tprivate readonly connectionOptions: Parameters<typeof createRpcSessionBinding>[4];\n\tprivate readonly widths = new Map<string, Map<string, number>>();\n\tprivate readonly pendingCapabilities = new Map<string, string[]>();\n\tprivate readonly finalizations = new Map<string, { promise: Promise<void>; resolve: () => void }>();\n\tprivate readonly idleNow: () => number;\n\tprivate readonly idleEvictionMs: number;\n\tprivate readonly emptyExitMs: number;\n\tprivate readonly onEmptyExit?: () => void;\n\tprivate readonly canExitWhenEmpty?: () => boolean;\n\tprivate sweepTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate emptySince: number | undefined;\n\n\tconstructor(\n\t\tregistry: Pick<\n\t\t\tRpcSessionRegistry,\n\t\t\t\"openSession\" | \"peek\" | \"getForCommand\" | \"beginClose\" | \"close\" | \"closeMarked\" | \"list\" | \"size\"\n\t\t>,\n\t\twriter: SessionEventWriter,\n\t\tdefaults: Pick<RpcSessionLaunchProfile, \"cwd\" | \"permissionPreset\" | \"creationModel\" | \"initialThinkingLevel\">,\n\t\tcreateBinding: typeof createRpcSessionBinding = createRpcSessionBinding,\n\t\tconnectionOptions: Parameters<typeof createRpcSessionBinding>[4] = {},\n\t\tidle?: RpcSessionIdlePolicy,\n\t) {\n\t\tthis.registry = registry;\n\t\tthis.writer = writer;\n\t\tthis.defaults = defaults;\n\t\tthis.createBinding = createBinding;\n\t\tthis.connectionOptions = connectionOptions;\n\t\tthis.idleNow = idle?.now ?? Date.now;\n\t\tthis.idleEvictionMs = idle?.idleEvictionMs ?? Number.POSITIVE_INFINITY;\n\t\tthis.emptyExitMs = idle?.emptyExitMs ?? Number.POSITIVE_INFINITY;\n\t\tthis.onEmptyExit = idle?.onEmptyExit;\n\t\tthis.canExitWhenEmpty = idle?.canExitWhenEmpty;\n\t\tif (Number.isFinite(this.idleEvictionMs) || Number.isFinite(this.emptyExitMs)) {\n\t\t\t// Unref'd: occupancy hygiene must never be the reason the event loop stays open.\n\t\t\tconst tickMs = Math.max(20, Math.min(5_000, Math.min(this.idleEvictionMs, this.emptyExitMs) / 4));\n\t\t\tthis.sweepTimer = setInterval(() => this.sweepIdleSessions(), tickMs);\n\t\t\tthis.sweepTimer.unref?.();\n\t\t}\n\t}\n\n\tasync handle(command: RpcCommand): Promise<RpcResponse | undefined> {\n\t\tif (command.type === \"get_protocol_info\") {\n\t\t\tconst capabilities = new Set([\n\t\t\t\t\"multi_session\",\n\t\t\t\tAUTO_TITLE_SESSIONS_CAPABILITY,\n\t\t\t\tMEDIA_PLACEHOLDERS_CAPABILITY,\n\t\t\t\t...(this.connectionOptions?.capabilities ?? []),\n\t\t\t]);\n\t\t\treturn {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"get_protocol_info\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tprotocolVersion: 1,\n\t\t\t\t\tserverVersion: VERSION,\n\t\t\t\t\tcapabilities: [...capabilities],\n\t\t\t\t\tmode: \"multi\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (command.type === \"list_sessions\")\n\t\t\treturn {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"list_sessions\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { sessions: this.registry.list() },\n\t\t\t};\n\t\tif (command.type === \"open_session\") return this.openWithBarrier(command);\n\t\tif (command.type === \"close_session\") return this.close(command);\n\t\tif (command.type === \"set_client_info\" && !command.sessionId) {\n\t\t\tconst connection = this.writer.currentConnection();\n\t\t\tif (connection !== undefined) {\n\t\t\t\tthis.pendingCapabilities.set(connection, command.capabilities ?? []);\n\t\t\t\tthis.writer.setConnectionCapabilities(connection, command.capabilities ?? []);\n\t\t\t}\n\t\t\treturn { id: command.id, type: \"response\", command: \"set_client_info\", success: true } as RpcResponse;\n\t\t}\n\t\tif (controls.has(command.type)) return undefined;\n\t\tif (!command.sessionId) return error(command.id, command.type, RPC_ERROR_MISSING_SESSION_ID);\n\t\ttry {\n\t\t\tthis.registry.getForCommand(command.sessionId, command.type);\n\t\t\tconst binding = this.bindings.get(command.sessionId);\n\t\t\tif (!binding) return error(command.id, command.type, RPC_ERROR_UNKNOWN_SESSION);\n\t\t\tawait binding.handle(command);\n\t\t\treturn undefined;\n\t\t} catch (cause) {\n\t\t\treturn error(command.id, command.type, this.code(cause));\n\t\t}\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tthis.stopSweep();\n\t\tawait Promise.all(\n\t\t\t[...this.bindings.entries()].map(async ([sessionId, binding]) => {\n\t\t\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: true });\n\t\t\t\tif (!claim) return;\n\t\t\t\tif (claim.finalizer) await this.finalizeClose(sessionId, binding);\n\t\t\t\telse await this.finalizations.get(sessionId)?.promise;\n\t\t\t}),\n\t\t);\n\t\tthis.bindings.clear();\n\t}\n\n\t/**\n\t * One occupancy sweep. Evicts open sessions idle longer than idleEvictionMs,\n\t * where \"idle\" is the COMPLETE session-owned activity contract\n\t * (`AgentSession.isSessionBusy`: agent run, bash, background terminal jobs and\n\t * other published wake sources, compaction, barrier-held session work) - busy\n\t * sessions restart their idle clock instead, so work that outlives a turn is\n\t * never killed. Fires onEmptyExit once the registry has STAYED empty for\n\t * emptyExitMs with the exit permitted; any live session or connected client\n\t * resets that window. Runs on an unref'd interval and is safe to call directly.\n\t */\n\tsweepIdleSessions(): void {\n\t\tconst now = this.idleNow();\n\t\tif (Number.isFinite(this.idleEvictionMs)) {\n\t\t\tfor (const { sessionId, status } of this.registry.list()) {\n\t\t\t\tif (status !== \"open\") continue;\n\t\t\t\tconst entry = this.registry.peek(sessionId);\n\t\t\t\tif (!entry) continue;\n\t\t\t\tif (entry.worker?.busy || entry.runtime?.session.isSessionBusy) {\n\t\t\t\t\t// Session-owned work defers eviction; the window restarts when it settles.\n\t\t\t\t\tentry.lastCommandAt = now;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (now - entry.lastCommandAt >= this.idleEvictionMs) void this.evictIdleSession(sessionId);\n\t\t\t}\n\t\t}\n\t\tif (Number.isFinite(this.emptyExitMs)) {\n\t\t\tif (this.registry.size === 0 && (this.canExitWhenEmpty?.() ?? true)) {\n\t\t\t\tif (this.emptySince === undefined) this.emptySince = now;\n\t\t\t\telse if (now - this.emptySince >= this.emptyExitMs) {\n\t\t\t\t\tthis.stopSweep();\n\t\t\t\t\tthis.onEmptyExit?.();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.emptySince = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Idle-session eviction: the same refcounted close sequence as an explicit\n\t * close_session, draining every attachment because eviction ends the shared\n\t * session, not one client's claim. Races with concurrent lifecycle paths are\n\t * tolerated the same way releaseOwnedSession tolerates them.\n\t */\n\tprivate async evictIdleSession(sessionId: string): Promise<void> {\n\t\t// A failed claim means an explicit close raced us and owns the entry now.\n\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: true });\n\t\tif (!claim) return;\n\t\tconst binding = this.bindings.get(sessionId);\n\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\tthis.forgetSessionOwnership(sessionId);\n\t\tif (claim.finalizer) {\n\t\t\tawait this.finalizeClose(sessionId, binding, () =>\n\t\t\t\tthis.writer.closeSession(sessionId, {\n\t\t\t\t\ttype: \"response\",\n\t\t\t\t\tcommand: \"close_session\",\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: {},\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tawait this.finalizations.get(sessionId)?.promise;\n\t\t}\n\t\t// The runtime is disposed and routing handles are unique per process\n\t\t// epoch, so nothing can emit under this id again: drop the writer's\n\t\t// per-session bookkeeping instead of retaining it for the host's life.\n\t\tthis.writer.forgetSession(sessionId);\n\t}\n\n\t/** Drops per-connection records for a handle the host closed on its own. */\n\tprivate forgetSessionOwnership(sessionId: string): void {\n\t\tfor (const [connection, owned] of this.sessionsByConnection) {\n\t\t\towned.delete(sessionId);\n\t\t\tif (owned.size === 0) this.sessionsByConnection.delete(connection);\n\t\t}\n\t\tthis.widths.delete(sessionId);\n\t}\n\n\tprivate stopSweep(): void {\n\t\tif (this.sweepTimer === undefined) return;\n\t\tclearInterval(this.sweepTimer);\n\t\tthis.sweepTimer = undefined;\n\t}\n\n\tprivate openWithBarrier(command: Extract<RpcCommand, { type: \"open_session\" }>): Promise<RpcResponse | undefined> {\n\t\tconst owner = this.writer.currentConnection();\n\t\tif (owner === undefined) return this.open(command);\n\t\tlet resolveBarrier!: () => void;\n\t\tconst barrier = new Promise<void>((resolve) => {\n\t\t\tresolveBarrier = resolve;\n\t\t});\n\t\tconst opens = this.opensByConnection.get(owner) ?? new Set<Promise<void>>();\n\t\topens.add(barrier);\n\t\tthis.opensByConnection.set(owner, opens);\n\t\treturn this.open(command, owner).finally(() => {\n\t\t\tresolveBarrier();\n\t\t\topens.delete(barrier);\n\t\t\tif (opens.size === 0) this.opensByConnection.delete(owner);\n\t\t});\n\t}\n\n\tprivate async open(\n\t\tcommand: Extract<RpcCommand, { type: \"open_session\" }>,\n\t\towner?: string,\n\t): Promise<RpcResponse | undefined> {\n\t\tlet opened: OpenRpcSession | undefined;\n\t\ttry {\n\t\t\topened = await this.registry.openSession({\n\t\t\t\tcwd: command.cwd ?? this.defaults.cwd,\n\t\t\t\tsessionPath: command.sessionPath,\n\t\t\t\tpermissionPreset: command.permissionPreset ?? this.defaults.permissionPreset,\n\t\t\t\tcreationModel:\n\t\t\t\t\tcommand.provider && command.modelId\n\t\t\t\t\t\t? { provider: command.provider, modelId: command.modelId }\n\t\t\t\t\t\t: this.defaults.creationModel,\n\t\t\t\tinitialThinkingLevel: command.thinkingLevel ?? this.defaults.initialThinkingLevel,\n\t\t\t});\n\t\t\tconst openedSession = opened;\n\t\t\tconst entry = this.registry.getForCommand(openedSession.sessionId, \"open_session\");\n\t\t\tif (owner !== undefined) {\n\t\t\t\tif (!this.writer.hasRegisteredConnectionCapabilities(owner))\n\t\t\t\t\tthis.writer.setConnectionCapabilities(\n\t\t\t\t\t\towner,\n\t\t\t\t\t\tthis.pendingCapabilities.get(owner) ?? this.connectionOptions?.capabilities ?? [],\n\t\t\t\t\t);\n\t\t\t\tthis.writer.attachConnectionToSession(owner, openedSession.sessionId);\n\t\t\t}\n\t\t\t// A client that dies without close_session (terminal closed, SIGKILL, dropped\n\t\t\t// SSH) still holds this handle's attachment and its path reservation. Remember\n\t\t\t// which connection owns it so releaseConnection() can close exactly that.\n\t\t\tif (owner !== undefined) {\n\t\t\t\tconst owned = this.sessionsByConnection.get(owner) ?? new Map<string, number>();\n\t\t\t\towned.set(openedSession.sessionId, (owned.get(openedSession.sessionId) ?? 0) + 1);\n\t\t\t\tthis.sessionsByConnection.set(owner, owned);\n\t\t\t}\n\t\t\tif (!this.bindings.has(openedSession.sessionId)) {\n\t\t\t\tthis.bindings.set(\n\t\t\t\t\topenedSession.sessionId,\n\t\t\t\t\tawait this.createBinding(\n\t\t\t\t\t\topenedSession.sessionId,\n\t\t\t\t\t\tentry,\n\t\t\t\t\t\tthis.writer,\n\t\t\t\t\t\t() => void this.close({ type: \"close_session\", sessionId: openedSession.sessionId }),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...this.connectionOptions,\n\t\t\t\t\t\t\tcapabilities:\n\t\t\t\t\t\t\t\towner !== undefined\n\t\t\t\t\t\t\t\t\t? (this.pendingCapabilities.get(owner) ?? this.connectionOptions?.capabilities ?? [])\n\t\t\t\t\t\t\t\t\t: this.connectionOptions?.capabilities,\n\t\t\t\t\t\t\tsharedWidth: {\n\t\t\t\t\t\t\t\tgetWidth: () => {\n\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId);\n\t\t\t\t\t\t\t\t\treturn widths?.size ? Math.min(...widths.values()) : 80;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetWidth: (connectionId, width) => {\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) {\n\t\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId) ?? new Map<string, number>();\n\t\t\t\t\t\t\t\t\t\twidths.set(connectionId, width);\n\t\t\t\t\t\t\t\t\t\tthis.widths.set(openedSession.sessionId, widths);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tclearWidth: (connectionId) => {\n\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId);\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) widths?.delete(connectionId);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetCapabilities: (connectionId, capabilities) => {\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) {\n\t\t\t\t\t\t\t\t\t\tthis.writer.setConnectionCapabilities(connectionId, capabilities);\n\t\t\t\t\t\t\t\t\t\tthis.pendingCapabilities.set(connectionId, [...capabilities]);\n\t\t\t\t\t\t\t\t\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\thasRenderedComponents: (sessionId) => this.writer.hasCapableConnection(sessionId),\n\n\t\t\t\t\t\t\t\tconnectionId: () => this.writer.currentConnection(),\n\t\t\t\t\t\t\t\tonChange: () => {\n\t\t\t\t\t\t\t\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tif (entry.worker) entry.worker.bindingReady = true;\n\t\t\t\tif (entry.worker)\n\t\t\t\t\tvoid entry.worker.exited.then(async () => {\n\t\t\t\t\t\tawait this.finalizations.get(openedSession.sessionId)?.promise;\n\t\t\t\t\t\tthis.bindings.delete(openedSession.sessionId);\n\t\t\t\t\t\tthis.forgetSessionOwnership(openedSession.sessionId);\n\t\t\t\t\t\tthis.writer.forgetSession(openedSession.sessionId);\n\t\t\t\t\t});\n\t\t\t}\n\t\t\tif (owner !== undefined && this.releasedConnections.has(owner)) {\n\t\t\t\tthis.releaseOwnerAttachment(owner, openedSession.sessionId);\n\t\t\t\tawait this.releaseOwnedSession(openedSession.sessionId);\n\t\t\t}\n\t\t\tconst state =\n\t\t\t\tentry.worker?.snapshot?.state ?? (entry.runtime ? buildRpcSessionState(entry.runtime.session) : undefined);\n\t\t\tif (!state) throw new Error(\"Session state was not created\");\n\t\t\tthis.writer.enqueue(opened.sessionId, {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"open_session\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tsessionId: opened.sessionId,\n\t\t\t\t\tstate,\n\t\t\t\t\t...(opened.attached ? { attached: true } : {}),\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn undefined;\n\t\t} catch (cause) {\n\t\t\tif (opened) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.registry.close(opened.sessionId);\n\t\t\t\t} catch {\n\t\t\t\t\t/* The open rollback has already removed the entry. */\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn error(command.id, \"open_session\", this.code(cause));\n\t\t}\n\t}\n\n\t/**\n\t * Releases every session a dropped connection still owned. Each handle goes through\n\t * the same refcounted close as an explicit close_session, so a session another\n\t * connection is still attached to keeps running and only the last owner tears it down.\n\t */\n\tasync releaseConnection(connectionId: string): Promise<void> {\n\t\tthis.releasedConnections.add(connectionId);\n\t\tthis.writer.clearConnectionCapabilities(connectionId);\n\t\tfor (const sessionId of this.sessionsByConnection.get(connectionId)?.keys() ?? [])\n\t\t\tthis.writer.detachConnectionFromSession(connectionId, sessionId);\n\t\tfor (const widths of this.widths.values()) widths.delete(connectionId);\n\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\tconst opens = this.opensByConnection.get(connectionId);\n\t\tconst owned = this.sessionsByConnection.get(connectionId);\n\t\tthis.sessionsByConnection.delete(connectionId);\n\t\tif (owned === undefined) {\n\t\t\tif (opens) await Promise.all([...opens]);\n\t\t\tthis.releasedConnections.delete(connectionId);\n\t\t\treturn;\n\t\t}\n\t\tawait Promise.all(\n\t\t\t[...owned].map(async ([sessionId, count]) => {\n\t\t\t\tfor (let attachment = 0; attachment < count; attachment++) {\n\t\t\t\t\t// Headless completion contract: a turn survives its client's death and\n\t\t\t\t\t// runs to settlement (the host lifecycle keeps the process alive on\n\t\t\t\t\t// active turns even with zero connections). Releasing mid-turn aborts\n\t\t\t\t\t// the run and seals the session before agent_settled reaches the\n\t\t\t\t\t// lifecycle observer, leaking the busy counter so the host never\n\t\t\t\t\t// idle-exits. Defer - never skip - the release until the turn settles,\n\t\t\t\t\t// so the dropped owner's reservation still frees afterwards.\n\t\t\t\t\tconst live = this.registry.peek(sessionId);\n\t\t\t\t\tconst session = live?.state === \"open\" ? live.runtime?.session : undefined;\n\t\t\t\t\tif (live?.state === \"open\" && live.worker?.snapshot?.streaming) {\n\t\t\t\t\t\tconst unsubscribe = live.worker.subscribeSettled(() => {\n\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\tvoid this.releaseOwnedSession(sessionId).catch((cause: unknown) => {\n\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t`senpi rpc deferred worker release ${sessionId} failed: ${String(cause)}\\n`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (session?.isStreaming) {\n\t\t\t\t\t\tlet released = false;\n\t\t\t\t\t\tconst unsubscribe = session.subscribe((event) => {\n\t\t\t\t\t\t\tif (event.type !== \"agent_settled\" && event.type !== \"agent_idle\") return;\n\t\t\t\t\t\t\tif (released) return;\n\t\t\t\t\t\t\treleased = true;\n\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\tvoid this.releaseOwnedSession(sessionId).catch((cause) => {\n\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t`senpi rpc deferred release for session ${sessionId} failed: ${String(cause)}\\n`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.releaseOwnedSession(sessionId);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t\tif (opens) await Promise.all([...opens]);\n\t\tthis.releasedConnections.delete(connectionId);\n\t}\n\n\t/**\n\t * One owned handle's refcounted close: the same sequence as an explicit\n\t * close_session, tolerant of races with other lifecycle paths (an entry\n\t * already closed or claimed elsewhere is simply skipped). Disposal, pending\n\t * extension-UI cancellation and binding removal happen only when this was the\n\t * LAST attachment (the entry transitioned to \"closing\"): surviving\n\t * attachments keep the shared binding and their event stream.\n\t */\n\tprivate async releaseOwnedSession(sessionId: string): Promise<void> {\n\t\t// A failed claim means the entry is already closed or owned by another path.\n\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: false });\n\t\tif (!claim) return;\n\t\tif (!claim.finalizer) {\n\t\t\tawait this.finalizations.get(sessionId)?.promise;\n\t\t\treturn;\n\t\t}\n\t\tconst binding = this.bindings.get(sessionId);\n\t\t// Pending UI requests are session-owned, not connection-owned: a question\n\t\t// asked through one connection stays answerable by every other attachment.\n\t\t// Cancel them only here, where the refcount has already decided the session\n\t\t// is being torn down, never on any owner drop.\n\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\tawait this.finalizeClose(sessionId, binding);\n\t}\n\n\t/**\n\t * Releases one attachment (or every attachment when draining) and reports\n\t * whether this caller became the finalizer. The join token is installed inside\n\t * the registry callback, before any await, so a close that lands between the\n\t * claim and finalizeClose() always finds a token to wait on instead of\n\t * answering ahead of the terminal records.\n\t */\n\tprivate claimClose(sessionId: string, options: { drainAttachments: boolean }): { finalizer: boolean } {\n\t\tlet finalizer = true;\n\t\tconst onRole = (isFinalizer: boolean): void => {\n\t\t\tfinalizer = isFinalizer;\n\t\t\tif (isFinalizer && !this.finalizations.has(sessionId))\n\t\t\t\tthis.finalizations.set(sessionId, this.createFinalization());\n\t\t};\n\t\tlet entry = this.registry.beginClose(sessionId, onRole);\n\t\twhile (options.drainAttachments && entry.state === \"open\") entry = this.registry.beginClose(sessionId, onRole);\n\t\treturn { finalizer: finalizer && entry.state === \"closing\" };\n\t}\n\n\t/** claimClose() for lifecycle paths that treat a lost race as \"nothing to do\". */\n\tprivate tryClaimClose(\n\t\tsessionId: string,\n\t\toptions: { drainAttachments: boolean },\n\t): { finalizer: boolean } | undefined {\n\t\ttry {\n\t\t\treturn this.claimClose(sessionId, options);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async close(command: Extract<RpcCommand, { type: \"close_session\" }>): Promise<RpcResponse | undefined> {\n\t\tconst response = {\n\t\t\tid: command.id,\n\t\t\ttype: \"response\" as const,\n\t\t\tcommand: \"close_session\" as const,\n\t\t\tsuccess: true as const,\n\t\t\tdata: {},\n\t\t};\n\t\tconst reply = this.writer.reserveCloseResponse(command.sessionId, response);\n\t\tif (!reply) return undefined;\n\t\t// Admission and claiming are synchronous, before any teardown await. A\n\t\t// saturated requester neither releases an attachment nor joins a promise.\n\t\tlet claim: { finalizer: boolean };\n\t\ttry {\n\t\t\tclaim = this.claimClose(command.sessionId, { drainAttachments: false });\n\t\t} catch (cause) {\n\t\t\treply.release();\n\t\t\treturn error(command.id, \"close_session\", this.code(cause));\n\t\t}\n\t\ttry {\n\t\t\tconst owner = this.writer.currentConnection();\n\t\t\tif (owner !== undefined) this.releaseOwnerAttachment(owner, command.sessionId);\n\t\t\tif (claim.finalizer) {\n\t\t\t\tawait this.finalizeClose(command.sessionId, this.bindings.get(command.sessionId), () =>\n\t\t\t\t\treply.complete(true),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait this.finalizations.get(command.sessionId)?.promise;\n\t\t\t\treply.complete(false);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} finally {\n\t\t\treply.release();\n\t\t}\n\t}\n\n\t/** Detaches the closing connection's UI/width state; a rerender failure must not abort the close. */\n\tprivate releaseOwnerAttachment(owner: string, sessionId: string): void {\n\t\tthis.widths.get(sessionId)?.delete(owner);\n\t\tthis.writer.detachConnectionFromSession(owner, sessionId);\n\t\tfor (const binding of this.bindings.values()) {\n\t\t\ttry {\n\t\t\t\tbinding.rerenderComponents?.();\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc rerender after close of session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t}\n\t\tconst owned = this.sessionsByConnection.get(owner);\n\t\tconst count = owned?.get(sessionId);\n\t\tif (!owned || count === undefined) return;\n\t\tif (count === 1) owned.delete(sessionId);\n\t\telse owned.set(sessionId, count - 1);\n\t\tif (owned.size === 0) this.sessionsByConnection.delete(owner);\n\t}\n\n\t/**\n\t * Runs the finalizer side of a close for a handle whose beginClose() made this\n\t * caller the owner: dispose the binding, complete the registry teardown, emit\n\t * the terminal records, then release joiners. Every step is guarded so the join\n\t * token always resolves and a failing binding yields one logged line, never a\n\t * second response or an escaped rejection.\n\t */\n\tprivate async finalizeClose(\n\t\tsessionId: string,\n\t\tbinding: RpcSessionBinding | undefined,\n\t\tterminal?: () => void,\n\t): Promise<void> {\n\t\tconst finalization = this.finalizations.get(sessionId) ?? this.createFinalization();\n\t\tthis.finalizations.set(sessionId, finalization);\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tawait binding?.dispose();\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc binding dispose for session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t\tthis.bindings.delete(sessionId);\n\t\t\ttry {\n\t\t\t\tawait this.registry.closeMarked(sessionId);\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc close for session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t\tterminal?.();\n\t\t} finally {\n\t\t\tfinalization.resolve();\n\t\t\tthis.finalizations.delete(sessionId);\n\t\t}\n\t}\n\n\tprivate createFinalization(): { promise: Promise<void>; resolve: () => void } {\n\t\tlet resolveFinalization: (() => void) | undefined;\n\t\tconst promise = new Promise<void>((resolve) => {\n\t\t\tresolveFinalization = resolve;\n\t\t});\n\t\treturn { promise, resolve: () => resolveFinalization?.() };\n\t}\n\n\tprivate code(cause: unknown): string {\n\t\tif (cause instanceof RpcSessionRegistryError) {\n\t\t\treturn cause.code === RPC_ERROR_OPEN_FAILED ? cause.message : cause.code;\n\t\t}\n\t\tif (cause instanceof Error && [RPC_ERROR_UNKNOWN_SESSION, RPC_ERROR_SESSION_CLOSING].includes(cause.message)) {\n\t\t\treturn cause.message;\n\t\t}\n\t\treturn cause instanceof Error && cause.message\n\t\t\t? `${RPC_ERROR_OPEN_FAILED}: ${cause.message}`\n\t\t\t: RPC_ERROR_UNKNOWN_SESSION;\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-command-router.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-command-router.ts"],"names":[],"mappings":"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","sourcesContent":["import { VERSION } from \"../../config.ts\";\nimport { buildRpcSessionState } from \"./connection-handler.ts\";\nimport { AUTO_TITLE_SESSIONS_CAPABILITY, MEDIA_PLACEHOLDERS_CAPABILITY } from \"./custom-capability.ts\";\nimport type { RpcCommand, RpcResponse } from \"./rpc-types.ts\";\nimport {\n\tRPC_ERROR_MISSING_SESSION_ID,\n\tRPC_ERROR_OPEN_FAILED,\n\tRPC_ERROR_SESSION_CLOSING,\n\tRPC_ERROR_UNKNOWN_SESSION,\n} from \"./rpc-types.ts\";\nimport { createRpcSessionBinding, type RpcSessionBinding } from \"./session-binding.ts\";\nimport type { SessionEventWriter } from \"./session-event-writer.ts\";\nimport type { OpenRpcSession, RpcSessionLaunchProfile, RpcSessionRegistry } from \"./session-registry.ts\";\nimport { RpcSessionRegistryError } from \"./session-registry.ts\";\n\nconst controls = new Set([\"get_protocol_info\", \"open_session\", \"close_session\", \"list_sessions\"]);\n\n/** Binding factory seam, injectable so host wiring is testable without a full runtime stack. */\nexport type RpcBindingFactory = typeof createRpcSessionBinding;\n\n/**\n * Occupancy policy for the shared multi-session host. All fields are opt-in:\n * a router constructed without a policy keeps today's behavior (sessions live\n * until close_session; the host never self-exits).\n */\nexport interface RpcSessionIdlePolicy {\n\t/** Injectable clock (defaults to Date.now) for deterministic tests. */\n\tnow?: () => number;\n\t/** Evict open sessions whose last routed command or session-owned work settled longer ago than this. */\n\tidleEvictionMs?: number;\n\t/** Invoke onEmptyExit once the registry has stayed empty for this long. */\n\temptyExitMs?: number;\n\t/** Host shutdown hook fired by the empty-exit window; called at most once. */\n\tonEmptyExit?: () => void;\n\t/**\n\t * Consulted every tick before the empty-exit window advances. Returning false\n\t * both blocks the exit and resets the window, so a host with a connected but\n\t * sessionless client stays up instead of exiting under its supervisor.\n\t */\n\tcanExitWhenEmpty?: () => boolean;\n}\n\nfunction error(id: string | undefined, command: string, code: string): RpcResponse {\n\treturn { id, type: \"response\", command, success: false, error: code };\n}\n\n/** Routes control messages and enforces a routing handle for every session command. */\nexport class SessionCommandRouter {\n\tprivate readonly bindings = new Map<string, RpcSessionBinding>();\n\t/** Session handles opened by each connection, with one count per attachment. */\n\tprivate readonly sessionsByConnection = new Map<string, Map<string, number>>();\n\t/** Opens currently awaiting runtime/binding setup, keyed by connection. */\n\tprivate readonly opensByConnection = new Map<string, Set<Promise<void>>>();\n\t/** Connections whose socket has already been detached. */\n\tprivate readonly releasedConnections = new Set<string>();\n\tprivate readonly registry: Pick<\n\t\tRpcSessionRegistry,\n\t\t\"openSession\" | \"peek\" | \"getForCommand\" | \"beginClose\" | \"close\" | \"closeMarked\" | \"list\" | \"size\"\n\t>;\n\tprivate readonly writer: SessionEventWriter;\n\tprivate readonly defaults: Pick<\n\t\tRpcSessionLaunchProfile,\n\t\t\"cwd\" | \"permissionPreset\" | \"creationModel\" | \"initialThinkingLevel\"\n\t>;\n\tprivate readonly createBinding: typeof createRpcSessionBinding;\n\tprivate readonly connectionOptions: Parameters<typeof createRpcSessionBinding>[4];\n\tprivate readonly widths = new Map<string, Map<string, number>>();\n\tprivate readonly pendingCapabilities = new Map<string, string[]>();\n\tprivate readonly finalizations = new Map<string, { promise: Promise<void>; resolve: () => void }>();\n\tprivate readonly idleNow: () => number;\n\tprivate readonly idleEvictionMs: number;\n\tprivate readonly emptyExitMs: number;\n\tprivate readonly onEmptyExit?: () => void;\n\tprivate readonly canExitWhenEmpty?: () => boolean;\n\tprivate sweepTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate emptySince: number | undefined;\n\n\tconstructor(\n\t\tregistry: Pick<\n\t\t\tRpcSessionRegistry,\n\t\t\t\"openSession\" | \"peek\" | \"getForCommand\" | \"beginClose\" | \"close\" | \"closeMarked\" | \"list\" | \"size\"\n\t\t>,\n\t\twriter: SessionEventWriter,\n\t\tdefaults: Pick<RpcSessionLaunchProfile, \"cwd\" | \"permissionPreset\" | \"creationModel\" | \"initialThinkingLevel\">,\n\t\tcreateBinding: typeof createRpcSessionBinding = createRpcSessionBinding,\n\t\tconnectionOptions: Parameters<typeof createRpcSessionBinding>[4] = {},\n\t\tidle?: RpcSessionIdlePolicy,\n\t) {\n\t\tthis.registry = registry;\n\t\tthis.writer = writer;\n\t\tthis.defaults = defaults;\n\t\tthis.createBinding = createBinding;\n\t\tthis.connectionOptions = connectionOptions;\n\t\tthis.idleNow = idle?.now ?? Date.now;\n\t\tthis.idleEvictionMs = idle?.idleEvictionMs ?? Number.POSITIVE_INFINITY;\n\t\tthis.emptyExitMs = idle?.emptyExitMs ?? Number.POSITIVE_INFINITY;\n\t\tthis.onEmptyExit = idle?.onEmptyExit;\n\t\tthis.canExitWhenEmpty = idle?.canExitWhenEmpty;\n\t\tif (Number.isFinite(this.idleEvictionMs) || Number.isFinite(this.emptyExitMs)) {\n\t\t\t// Unref'd: occupancy hygiene must never be the reason the event loop stays open.\n\t\t\tconst tickMs = Math.max(20, Math.min(5_000, Math.min(this.idleEvictionMs, this.emptyExitMs) / 4));\n\t\t\tthis.sweepTimer = setInterval(() => this.sweepIdleSessions(), tickMs);\n\t\t\tthis.sweepTimer.unref?.();\n\t\t}\n\t}\n\n\tasync handle(command: RpcCommand): Promise<RpcResponse | undefined> {\n\t\tif (command.type === \"get_protocol_info\") {\n\t\t\tconst capabilities = new Set([\n\t\t\t\t\"multi_session\",\n\t\t\t\tAUTO_TITLE_SESSIONS_CAPABILITY,\n\t\t\t\tMEDIA_PLACEHOLDERS_CAPABILITY,\n\t\t\t\t...(this.connectionOptions?.capabilities ?? []),\n\t\t\t]);\n\t\t\treturn {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"get_protocol_info\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tprotocolVersion: 1,\n\t\t\t\t\tserverVersion: VERSION,\n\t\t\t\t\tcapabilities: [...capabilities],\n\t\t\t\t\tmode: \"multi\",\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (command.type === \"list_sessions\")\n\t\t\treturn {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"list_sessions\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { sessions: this.registry.list() },\n\t\t\t};\n\t\tif (command.type === \"open_session\") return this.openWithBarrier(command);\n\t\tif (command.type === \"close_session\") return this.close(command);\n\t\tif (command.type === \"set_client_info\" && !command.sessionId) {\n\t\t\tconst connection = this.writer.currentConnection();\n\t\t\tif (connection !== undefined) {\n\t\t\t\tthis.pendingCapabilities.set(connection, command.capabilities ?? []);\n\t\t\t\tthis.writer.setConnectionCapabilities(connection, command.capabilities ?? []);\n\t\t\t}\n\t\t\treturn { id: command.id, type: \"response\", command: \"set_client_info\", success: true } as RpcResponse;\n\t\t}\n\t\tif (controls.has(command.type)) return undefined;\n\t\tif (!command.sessionId) return error(command.id, command.type, RPC_ERROR_MISSING_SESSION_ID);\n\t\ttry {\n\t\t\tthis.registry.getForCommand(command.sessionId, command.type);\n\t\t\tconst binding = this.bindings.get(command.sessionId);\n\t\t\tif (!binding) return error(command.id, command.type, RPC_ERROR_UNKNOWN_SESSION);\n\t\t\tawait binding.handle(command);\n\t\t\treturn undefined;\n\t\t} catch (cause) {\n\t\t\treturn error(command.id, command.type, this.code(cause));\n\t\t}\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tthis.stopSweep();\n\t\tawait Promise.all(\n\t\t\t[...this.bindings.entries()].map(async ([sessionId, binding]) => {\n\t\t\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: true });\n\t\t\t\tif (!claim) return;\n\t\t\t\tif (claim.finalizer) await this.finalizeClose(sessionId, binding);\n\t\t\t\telse await this.finalizations.get(sessionId)?.promise;\n\t\t\t}),\n\t\t);\n\t\tthis.bindings.clear();\n\t}\n\n\t/**\n\t * One occupancy sweep. Evicts open sessions idle longer than idleEvictionMs,\n\t * where \"idle\" is the COMPLETE session-owned activity contract\n\t * (`AgentSession.isSessionBusy`: agent run, bash, background terminal jobs and\n\t * other published wake sources, compaction, barrier-held session work) - busy\n\t * sessions restart their idle clock instead, so work that outlives a turn is\n\t * never killed. Fires onEmptyExit once the registry has STAYED empty for\n\t * emptyExitMs with the exit permitted; any live session or connected client\n\t * resets that window. Runs on an unref'd interval and is safe to call directly.\n\t */\n\tsweepIdleSessions(): void {\n\t\tconst now = this.idleNow();\n\t\tif (Number.isFinite(this.idleEvictionMs)) {\n\t\t\tfor (const { sessionId, status } of this.registry.list()) {\n\t\t\t\tif (status !== \"open\") continue;\n\t\t\t\tconst entry = this.registry.peek(sessionId);\n\t\t\t\tif (!entry) continue;\n\t\t\t\tif (entry.worker?.busy || entry.runtime?.session.isSessionBusy) {\n\t\t\t\t\t// Session-owned work defers eviction; the window restarts when it settles.\n\t\t\t\t\tentry.lastCommandAt = now;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (now - entry.lastCommandAt >= this.idleEvictionMs) void this.evictIdleSession(sessionId);\n\t\t\t}\n\t\t}\n\t\tif (Number.isFinite(this.emptyExitMs)) {\n\t\t\tif (this.registry.size === 0 && (this.canExitWhenEmpty?.() ?? true)) {\n\t\t\t\tif (this.emptySince === undefined) this.emptySince = now;\n\t\t\t\telse if (now - this.emptySince >= this.emptyExitMs) {\n\t\t\t\t\tthis.stopSweep();\n\t\t\t\t\tthis.onEmptyExit?.();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.emptySince = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Idle-session eviction: the same refcounted close sequence as an explicit\n\t * close_session, draining every attachment because eviction ends the shared\n\t * session, not one client's claim. Races with concurrent lifecycle paths are\n\t * tolerated the same way releaseOwnedSession tolerates them.\n\t */\n\tprivate async evictIdleSession(sessionId: string): Promise<void> {\n\t\t// A failed claim means an explicit close raced us and owns the entry now.\n\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: true });\n\t\tif (!claim) return;\n\t\tconst binding = this.bindings.get(sessionId);\n\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\tthis.forgetSessionOwnership(sessionId);\n\t\tif (claim.finalizer) {\n\t\t\tawait this.finalizeClose(sessionId, binding, () =>\n\t\t\t\tthis.writer.closeSession(sessionId, {\n\t\t\t\t\ttype: \"response\",\n\t\t\t\t\tcommand: \"close_session\",\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: {},\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tawait this.finalizations.get(sessionId)?.promise;\n\t\t}\n\t\t// The runtime is disposed and routing handles are unique per process\n\t\t// epoch, so nothing can emit under this id again: drop the writer's\n\t\t// per-session bookkeeping instead of retaining it for the host's life.\n\t\tthis.writer.forgetSession(sessionId);\n\t}\n\n\t/** Drops per-connection records for a handle the host closed on its own. */\n\tprivate forgetSessionOwnership(sessionId: string): void {\n\t\tfor (const [connection, owned] of this.sessionsByConnection) {\n\t\t\towned.delete(sessionId);\n\t\t\tif (owned.size === 0) this.sessionsByConnection.delete(connection);\n\t\t}\n\t\tthis.widths.delete(sessionId);\n\t}\n\n\tprivate stopSweep(): void {\n\t\tif (this.sweepTimer === undefined) return;\n\t\tclearInterval(this.sweepTimer);\n\t\tthis.sweepTimer = undefined;\n\t}\n\n\tprivate openWithBarrier(command: Extract<RpcCommand, { type: \"open_session\" }>): Promise<RpcResponse | undefined> {\n\t\tconst owner = this.writer.currentConnection();\n\t\tif (owner === undefined) return this.open(command);\n\t\tlet resolveBarrier!: () => void;\n\t\tconst barrier = new Promise<void>((resolve) => {\n\t\t\tresolveBarrier = resolve;\n\t\t});\n\t\tconst opens = this.opensByConnection.get(owner) ?? new Set<Promise<void>>();\n\t\topens.add(barrier);\n\t\tthis.opensByConnection.set(owner, opens);\n\t\treturn this.open(command, owner).finally(() => {\n\t\t\tresolveBarrier();\n\t\t\topens.delete(barrier);\n\t\t\tif (opens.size === 0) this.opensByConnection.delete(owner);\n\t\t});\n\t}\n\n\tprivate async open(\n\t\tcommand: Extract<RpcCommand, { type: \"open_session\" }>,\n\t\towner?: string,\n\t): Promise<RpcResponse | undefined> {\n\t\tlet opened: OpenRpcSession | undefined;\n\t\ttry {\n\t\t\topened = await this.registry.openSession({\n\t\t\t\tcwd: command.cwd ?? this.defaults.cwd,\n\t\t\t\tsessionPath: command.sessionPath,\n\t\t\t\tpermissionPreset: command.permissionPreset ?? this.defaults.permissionPreset,\n\t\t\t\tcreationModel:\n\t\t\t\t\tcommand.provider && command.modelId\n\t\t\t\t\t\t? { provider: command.provider, modelId: command.modelId }\n\t\t\t\t\t\t: this.defaults.creationModel,\n\t\t\t\tinitialThinkingLevel: command.thinkingLevel ?? this.defaults.initialThinkingLevel,\n\t\t\t});\n\t\t\tconst openedSession = opened;\n\t\t\tconst entry = this.registry.getForCommand(openedSession.sessionId, \"open_session\");\n\t\t\tif (owner !== undefined) {\n\t\t\t\tif (!this.writer.hasRegisteredConnectionCapabilities(owner))\n\t\t\t\t\tthis.writer.setConnectionCapabilities(\n\t\t\t\t\t\towner,\n\t\t\t\t\t\tthis.pendingCapabilities.get(owner) ?? this.connectionOptions?.capabilities ?? [],\n\t\t\t\t\t);\n\t\t\t\tthis.writer.attachConnectionToSession(owner, openedSession.sessionId);\n\t\t\t}\n\t\t\t// A client that dies without close_session (terminal closed, SIGKILL, dropped\n\t\t\t// SSH) still holds this handle's attachment and its path reservation. Remember\n\t\t\t// which connection owns it so releaseConnection() can close exactly that.\n\t\t\tif (owner !== undefined) {\n\t\t\t\tconst owned = this.sessionsByConnection.get(owner) ?? new Map<string, number>();\n\t\t\t\towned.set(openedSession.sessionId, (owned.get(openedSession.sessionId) ?? 0) + 1);\n\t\t\t\tthis.sessionsByConnection.set(owner, owned);\n\t\t\t}\n\t\t\tif (!this.bindings.has(openedSession.sessionId)) {\n\t\t\t\tthis.bindings.set(\n\t\t\t\t\topenedSession.sessionId,\n\t\t\t\t\tawait this.createBinding(\n\t\t\t\t\t\topenedSession.sessionId,\n\t\t\t\t\t\tentry,\n\t\t\t\t\t\tthis.writer,\n\t\t\t\t\t\t() => void this.close({ type: \"close_session\", sessionId: openedSession.sessionId }),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...this.connectionOptions,\n\t\t\t\t\t\t\tcapabilities:\n\t\t\t\t\t\t\t\towner !== undefined\n\t\t\t\t\t\t\t\t\t? (this.pendingCapabilities.get(owner) ?? this.connectionOptions?.capabilities ?? [])\n\t\t\t\t\t\t\t\t\t: this.connectionOptions?.capabilities,\n\t\t\t\t\t\t\tsharedWidth: {\n\t\t\t\t\t\t\t\tgetWidth: () => {\n\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId);\n\t\t\t\t\t\t\t\t\treturn widths?.size ? Math.min(...widths.values()) : 80;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetWidth: (connectionId, width) => {\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) {\n\t\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId) ?? new Map<string, number>();\n\t\t\t\t\t\t\t\t\t\twidths.set(connectionId, width);\n\t\t\t\t\t\t\t\t\t\tthis.widths.set(openedSession.sessionId, widths);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tclearWidth: (connectionId) => {\n\t\t\t\t\t\t\t\t\tconst widths = this.widths.get(openedSession.sessionId);\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) widths?.delete(connectionId);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetCapabilities: (connectionId, capabilities) => {\n\t\t\t\t\t\t\t\t\tif (connectionId !== undefined) {\n\t\t\t\t\t\t\t\t\t\tthis.writer.setConnectionCapabilities(connectionId, capabilities);\n\t\t\t\t\t\t\t\t\t\tthis.pendingCapabilities.set(connectionId, [...capabilities]);\n\t\t\t\t\t\t\t\t\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\thasRenderedComponents: (sessionId) => this.writer.hasCapableConnection(sessionId),\n\n\t\t\t\t\t\t\t\tconnectionId: () => this.writer.currentConnection(),\n\t\t\t\t\t\t\t\tonChange: () => {\n\t\t\t\t\t\t\t\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tif (entry.worker) entry.worker.bindingReady = true;\n\t\t\t\tif (entry.worker)\n\t\t\t\t\tvoid entry.worker.exited.then(async () => {\n\t\t\t\t\t\tawait this.finalizations.get(openedSession.sessionId)?.promise;\n\t\t\t\t\t\tthis.bindings.delete(openedSession.sessionId);\n\t\t\t\t\t\tthis.forgetSessionOwnership(openedSession.sessionId);\n\t\t\t\t\t\tthis.writer.forgetSession(openedSession.sessionId);\n\t\t\t\t\t});\n\t\t\t}\n\t\t\tif (owner !== undefined && this.releasedConnections.has(owner)) {\n\t\t\t\tthis.releaseOwnerAttachment(owner, openedSession.sessionId);\n\t\t\t\tawait this.releaseOwnedSession(openedSession.sessionId);\n\t\t\t}\n\t\t\tconst state =\n\t\t\t\tentry.worker?.snapshot?.state ?? (entry.runtime ? buildRpcSessionState(entry.runtime.session) : undefined);\n\t\t\tif (!state) throw new Error(\"Session state was not created\");\n\t\t\tthis.writer.enqueue(opened.sessionId, {\n\t\t\t\tid: command.id,\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"open_session\",\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tsessionId: opened.sessionId,\n\t\t\t\t\tstate,\n\t\t\t\t\t...(opened.attached ? { attached: true } : {}),\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn undefined;\n\t\t} catch (cause) {\n\t\t\tif (opened) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.registry.close(opened.sessionId);\n\t\t\t\t} catch {\n\t\t\t\t\t/* The open rollback has already removed the entry. */\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn error(command.id, \"open_session\", this.code(cause));\n\t\t}\n\t}\n\n\t/**\n\t * Releases every session a dropped connection still owned. Each handle goes through\n\t * the same refcounted close as an explicit close_session, so a session another\n\t * connection is still attached to keeps running and only the last owner tears it down.\n\t */\n\tasync releaseConnection(connectionId: string): Promise<void> {\n\t\tthis.releasedConnections.add(connectionId);\n\t\tthis.writer.clearConnectionCapabilities(connectionId);\n\t\tfor (const sessionId of this.sessionsByConnection.get(connectionId)?.keys() ?? [])\n\t\t\tthis.writer.detachConnectionFromSession(connectionId, sessionId);\n\t\tfor (const widths of this.widths.values()) widths.delete(connectionId);\n\t\tfor (const binding of this.bindings.values()) binding.rerenderComponents?.();\n\t\tconst opens = this.opensByConnection.get(connectionId);\n\t\tconst owned = this.sessionsByConnection.get(connectionId);\n\t\tthis.sessionsByConnection.delete(connectionId);\n\t\tif (owned === undefined) {\n\t\t\tif (opens) await Promise.all([...opens]);\n\t\t\tthis.releasedConnections.delete(connectionId);\n\t\t\treturn;\n\t\t}\n\t\tawait Promise.all(\n\t\t\t[...owned].map(async ([sessionId, count]) => {\n\t\t\t\tfor (let attachment = 0; attachment < count; attachment++) {\n\t\t\t\t\t// Headless completion contract: a turn survives its client's death and\n\t\t\t\t\t// runs to settlement (the host lifecycle keeps the process alive on\n\t\t\t\t\t// active turns even with zero connections). Releasing mid-turn aborts\n\t\t\t\t\t// the run and seals the session before agent_settled reaches the\n\t\t\t\t\t// lifecycle observer, leaking the busy counter so the host never\n\t\t\t\t\t// idle-exits. Defer - never skip - the release until the turn settles,\n\t\t\t\t\t// so the dropped owner's reservation still frees afterwards.\n\t\t\t\t\tconst live = this.registry.peek(sessionId);\n\t\t\t\t\tconst session = live?.state === \"open\" ? live.runtime?.session : undefined;\n\t\t\t\t\tif (live?.state === \"open\" && live.worker?.snapshot?.streaming) {\n\t\t\t\t\t\tconst unsubscribe = live.worker.subscribeSettled(() => {\n\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\tvoid this.releaseOwnedSession(sessionId).catch((cause: unknown) => {\n\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t`senpi rpc deferred worker release ${sessionId} failed: ${String(cause)}\\n`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (session?.isStreaming) {\n\t\t\t\t\t\tlet released = false;\n\t\t\t\t\t\tconst unsubscribe = session.subscribe((event) => {\n\t\t\t\t\t\t\tif (event.type !== \"agent_settled\" && event.type !== \"agent_idle\") return;\n\t\t\t\t\t\t\tif (released) return;\n\t\t\t\t\t\t\treleased = true;\n\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\tvoid this.releaseOwnedSession(sessionId).catch((cause) => {\n\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t`senpi rpc deferred release for session ${sessionId} failed: ${String(cause)}\\n`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.releaseOwnedSession(sessionId);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t\tif (opens) await Promise.all([...opens]);\n\t\tthis.releasedConnections.delete(connectionId);\n\t}\n\n\t/**\n\t * One owned handle's refcounted close: the same sequence as an explicit\n\t * close_session, tolerant of races with other lifecycle paths (an entry\n\t * already closed or claimed elsewhere is simply skipped). Disposal, pending\n\t * extension-UI cancellation and binding removal happen only when this was the\n\t * LAST attachment (the entry transitioned to \"closing\"): surviving\n\t * attachments keep the shared binding and their event stream.\n\t */\n\tprivate async releaseOwnedSession(sessionId: string): Promise<void> {\n\t\t// A failed claim means the entry is already closed or owned by another path.\n\t\tconst claim = this.tryClaimClose(sessionId, { drainAttachments: false });\n\t\tif (!claim) return;\n\t\tif (!claim.finalizer) {\n\t\t\tawait this.finalizations.get(sessionId)?.promise;\n\t\t\treturn;\n\t\t}\n\t\tconst binding = this.bindings.get(sessionId);\n\t\t// Pending UI requests are session-owned, not connection-owned: a question\n\t\t// asked through one connection stays answerable by every other attachment.\n\t\t// Cancel them only here, where the refcount has already decided the session\n\t\t// is being torn down, never on any owner drop.\n\t\tbinding?.cancelPendingExtensionUiRequests?.();\n\t\tawait this.finalizeClose(sessionId, binding);\n\t}\n\n\t/**\n\t * Releases one attachment (or every attachment when draining) and reports\n\t * whether this caller became the finalizer. The join token is installed inside\n\t * the registry callback, before any await, so a close that lands between the\n\t * claim and finalizeClose() always finds a token to wait on instead of\n\t * answering ahead of the terminal records.\n\t */\n\tprivate claimClose(sessionId: string, options: { drainAttachments: boolean }): { finalizer: boolean } {\n\t\tlet finalizer = true;\n\t\tconst onRole = (isFinalizer: boolean): void => {\n\t\t\tfinalizer = isFinalizer;\n\t\t\tif (isFinalizer && !this.finalizations.has(sessionId))\n\t\t\t\tthis.finalizations.set(sessionId, this.createFinalization());\n\t\t};\n\t\tlet entry = this.registry.beginClose(sessionId, onRole);\n\t\twhile (options.drainAttachments && entry.state === \"open\") entry = this.registry.beginClose(sessionId, onRole);\n\t\treturn { finalizer: finalizer && entry.state === \"closing\" };\n\t}\n\n\t/** claimClose() for lifecycle paths that treat a lost race as \"nothing to do\". */\n\tprivate tryClaimClose(\n\t\tsessionId: string,\n\t\toptions: { drainAttachments: boolean },\n\t): { finalizer: boolean } | undefined {\n\t\ttry {\n\t\t\treturn this.claimClose(sessionId, options);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprivate async close(command: Extract<RpcCommand, { type: \"close_session\" }>): Promise<RpcResponse | undefined> {\n\t\tconst response = {\n\t\t\tid: command.id,\n\t\t\ttype: \"response\" as const,\n\t\t\tcommand: \"close_session\" as const,\n\t\t\tsuccess: true as const,\n\t\t\tdata: {},\n\t\t};\n\t\tconst reply = this.writer.reserveCloseResponse(command.sessionId, response);\n\t\tif (!reply) return undefined;\n\t\t// Admission and claiming are synchronous, before any teardown await. A\n\t\t// saturated requester neither releases an attachment nor joins a promise.\n\t\tlet claim: { finalizer: boolean };\n\t\ttry {\n\t\t\tclaim = this.claimClose(command.sessionId, { drainAttachments: false });\n\t\t} catch (cause) {\n\t\t\treply.release();\n\t\t\treturn error(command.id, \"close_session\", this.code(cause));\n\t\t}\n\t\ttry {\n\t\t\tconst owner = this.writer.currentConnection();\n\t\t\tif (owner !== undefined) this.releaseOwnerAttachment(owner, command.sessionId);\n\t\t\tif (claim.finalizer) {\n\t\t\t\tawait this.finalizeClose(command.sessionId, this.bindings.get(command.sessionId), () =>\n\t\t\t\t\treply.complete(true),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait this.finalizations.get(command.sessionId)?.promise;\n\t\t\t\treply.complete(false);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} finally {\n\t\t\treply.release();\n\t\t}\n\t}\n\n\t/** Detaches the closing connection's UI/width state; a rerender failure must not abort the close. */\n\tprivate releaseOwnerAttachment(owner: string, sessionId: string): void {\n\t\tthis.widths.get(sessionId)?.delete(owner);\n\t\tthis.writer.detachConnectionFromSession(owner, sessionId);\n\t\tfor (const binding of this.bindings.values()) {\n\t\t\ttry {\n\t\t\t\tbinding.rerenderComponents?.();\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc rerender after close of session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t}\n\t\tconst owned = this.sessionsByConnection.get(owner);\n\t\tconst count = owned?.get(sessionId);\n\t\tif (!owned || count === undefined) return;\n\t\tif (count === 1) owned.delete(sessionId);\n\t\telse owned.set(sessionId, count - 1);\n\t\tif (owned.size === 0) this.sessionsByConnection.delete(owner);\n\t}\n\n\t/**\n\t * Runs the finalizer side of a close for a handle whose beginClose() made this\n\t * caller the owner: dispose the binding, complete the registry teardown, emit\n\t * the terminal records, then release joiners. Every step is guarded so the join\n\t * token always resolves and a failing binding yields one logged line, never a\n\t * second response or an escaped rejection.\n\t */\n\tprivate async finalizeClose(\n\t\tsessionId: string,\n\t\tbinding: RpcSessionBinding | undefined,\n\t\tterminal?: () => void,\n\t): Promise<void> {\n\t\tconst finalization = this.finalizations.get(sessionId) ?? this.createFinalization();\n\t\tthis.finalizations.set(sessionId, finalization);\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tawait binding?.dispose();\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc binding dispose for session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t\tthis.bindings.delete(sessionId);\n\t\t\ttry {\n\t\t\t\tawait this.registry.closeMarked(sessionId);\n\t\t\t} catch (cause) {\n\t\t\t\tprocess.stderr.write(`senpi rpc close for session ${sessionId} failed: ${String(cause)}\\n`);\n\t\t\t}\n\t\t\t// closeMarked may return at the grace deadline while ownership remains;\n\t\t\t// terminal records must still observe the exit callback's registry removal.\n\t\t\tawait this.registry.peek(sessionId)?.closeCompletion;\n\t\t\tterminal?.();\n\t\t} finally {\n\t\t\tfinalization.resolve();\n\t\t\tthis.finalizations.delete(sessionId);\n\t\t}\n\t}\n\n\tprivate createFinalization(): { promise: Promise<void>; resolve: () => void } {\n\t\tlet resolveFinalization: (() => void) | undefined;\n\t\tconst promise = new Promise<void>((resolve) => {\n\t\t\tresolveFinalization = resolve;\n\t\t});\n\t\treturn { promise, resolve: () => resolveFinalization?.() };\n\t}\n\n\tprivate code(cause: unknown): string {\n\t\tif (cause instanceof RpcSessionRegistryError) {\n\t\t\treturn cause.code === RPC_ERROR_OPEN_FAILED ? cause.message : cause.code;\n\t\t}\n\t\tif (cause instanceof Error && [RPC_ERROR_UNKNOWN_SESSION, RPC_ERROR_SESSION_CLOSING].includes(cause.message)) {\n\t\t\treturn cause.message;\n\t\t}\n\t\treturn cause instanceof Error && cause.message\n\t\t\t? `${RPC_ERROR_OPEN_FAILED}: ${cause.message}`\n\t\t\t: RPC_ERROR_UNKNOWN_SESSION;\n\t}\n}\n"]}
@@ -30,6 +30,7 @@ export declare class SessionWorkerClient {
30
30
  private readonly listeners;
31
31
  private readonly controls;
32
32
  private latestDisplay?;
33
+ private terminalFailure?;
33
34
  private readonly callbacks;
34
35
  constructor(callbacks: SessionWorkerCallbacks);
35
36
  prepare(configuration: CliRuntimeConfiguration, profile: RpcSessionLaunchProfile): Promise<string>;
@@ -45,5 +46,7 @@ export declare class SessionWorkerClient {
45
46
  private post;
46
47
  private receive;
47
48
  private fail;
49
+ /** Terminal close records observe completed registry removal, including worker failure. */
50
+ private publishTerminalFailure;
48
51
  }
49
52
  //# sourceMappingURL=session-worker-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-worker-client.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/session-worker-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAGX,iBAAiB,EAEjB,cAAc,EACd,MAAM,8BAA8B,CAAC;AAKtC,iFAAiF;AACjF,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,CAAC;IAC7C,uEAAuE;IACvE,SAAS,EAAE,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IAClD,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AASD,qBAAa,mBAAmB;IAC/B,QAAQ,CAAC,MAAM,SAIb;IACF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,wEAAwE;IACxE,YAAY,UAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGvB;IACF,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,UAAU,CAAC,CAAgC;IACnD,OAAO,CAAC,MAAM,CAAC,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,OAAO,CAAkE;IACjF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAC/D,OAAO,CAAC,aAAa,CAAC,CAAoD;IAE1E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IAEnD,YAAY,SAAS,EAAE,sBAAsB,EAe5C;IAEK,OAAO,CAAC,aAAa,EAAE,uBAAuB,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvG;IAEK,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAKtC;IAEK,IAAI,CACT,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,kBAAkB,EAC1B,YAAY,EAAE,MAAM,IAAI,EACxB,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,cAAc,GAAG,aAAa,CAAC,GACjE,OAAO,CAAC,iBAAiB,CAAC,CAqB5B;IAED,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAGjD;IAED,2FAA2F;IAC3F,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpC;IAED,UAAU,IAAI,IAAI,CAIjB;IAED,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,OAAO;IAoFf,OAAO,CAAC,IAAI;CAcZ"}
1
+ {"version":3,"file":"session-worker-client.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/session-worker-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAGX,iBAAiB,EAEjB,cAAc,EACd,MAAM,8BAA8B,CAAC;AAKtC,iFAAiF;AACjF,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,CAAC;IAC7C,uEAAuE;IACvE,SAAS,EAAE,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IAClD,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AASD,qBAAa,mBAAmB;IAC/B,QAAQ,CAAC,MAAM,SAIb;IACF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,wEAAwE;IACxE,YAAY,UAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGvB;IACF,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,UAAU,CAAC,CAAgC;IACnD,OAAO,CAAC,MAAM,CAAC,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,OAAO,CAAkE;IACjF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAC/D,OAAO,CAAC,aAAa,CAAC,CAAoD;IAC1E,OAAO,CAAC,eAAe,CAAC,CAAS;IAEjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IAEnD,YAAY,SAAS,EAAE,sBAAsB,EAgB5C;IAEK,OAAO,CAAC,aAAa,EAAE,uBAAuB,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvG;IAEK,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAKtC;IAEK,IAAI,CACT,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,kBAAkB,EAC1B,YAAY,EAAE,MAAM,IAAI,EACxB,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,cAAc,GAAG,aAAa,CAAC,GACjE,OAAO,CAAC,iBAAiB,CAAC,CAqB5B;IAED,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAGjD;IAED,2FAA2F;IAC3F,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpC;IAED,UAAU,IAAI,IAAI,CAIjB;IAED,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,OAAO;IAoFf,OAAO,CAAC,IAAI;IAUZ,2FAA2F;IAC3F,OAAO,CAAC,sBAAsB;CAa9B"}
@@ -30,6 +30,7 @@ export class SessionWorkerClient {
30
30
  this.requests.close(new Error("session_worker_exited"));
31
31
  this.listeners.clear();
32
32
  callbacks.exit();
33
+ this.publishTerminalFailure();
33
34
  resolve();
34
35
  });
35
36
  });
@@ -202,16 +203,26 @@ export class SessionWorkerClient {
202
203
  if (this.stopped)
203
204
  return;
204
205
  this.callbacks.failure(error);
206
+ this.terminalFailure = error;
205
207
  if (this.writer && this.sessionId) {
206
208
  this.writer.enqueue(this.sessionId, { type: "session_error", error });
207
- this.writer.closeSession(this.sessionId, {
208
- type: "response",
209
- command: "close_session",
210
- success: false,
211
- error,
212
- });
213
209
  }
214
210
  this.quarantine();
215
211
  }
212
+ /** Terminal close records observe completed registry removal, including worker failure. */
213
+ publishTerminalFailure() {
214
+ const error = this.terminalFailure;
215
+ const writer = this.writer;
216
+ const sessionId = this.sessionId;
217
+ if (error === undefined || !writer || !sessionId)
218
+ return;
219
+ this.terminalFailure = undefined;
220
+ writer.closeSession(sessionId, {
221
+ type: "response",
222
+ command: "close_session",
223
+ success: false,
224
+ error,
225
+ });
226
+ }
216
227
  }
217
228
  //# sourceMappingURL=session-worker-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-worker-client.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { Worker } from \"node:worker_threads\";\nimport { isBunBinary } from \"../../config.ts\";\nimport type { CliRuntimeConfiguration } from \"../../main.ts\";\nimport type { RpcConnectionOptions } from \"./connection-handler.ts\";\nimport type { RpcSessionBinding } from \"./session-binding.ts\";\nimport type { SessionEventWriter } from \"./session-event-writer.ts\";\nimport type { RpcSessionLaunchProfile } from \"./session-registry.ts\";\nimport type {\n\tHostToSessionWorker,\n\tSessionWorkerToHost,\n\tSessionWriteGrant,\n\tWorkerDisplay,\n\tWorkerSnapshot,\n} from \"./session-worker-protocol.ts\";\n\nimport { SessionWorkerRequests, type WorkerRequestInput } from \"./session-worker-requests.ts\";\nimport { acknowledge, acknowledgeGrant, respondDisplay } from \"./session-worker-signals.ts\";\n\n/** Lifecycle hooks the owning registry installs on every worker it allocates. */\nexport interface SessionWorkerCallbacks {\n\treserve: (path: string) => SessionWriteGrant;\n\t/** Every snapshot republishes which paths this worker still writes. */\n\treconcile: (livePaths: readonly string[]) => void;\n\texit: () => void;\n\tfailure: (error: string) => void;\n}\n\n/** Bun wrapper builders define the worker entry name relative to their explicit --root. */\ndeclare const SENPI_RPC_SESSION_WORKER_ENTRY: string | undefined;\nconst compiledWorkerEntry =\n\ttypeof SENPI_RPC_SESSION_WORKER_ENTRY === \"string\"\n\t\t? SENPI_RPC_SESSION_WORKER_ENTRY\n\t\t: \"./src/modes/rpc/session-worker.ts\";\n\nexport class SessionWorkerClient {\n\treadonly worker = new Worker(\n\t\tisBunBinary\n\t\t\t? fileURLToPath(new URL(compiledWorkerEntry, import.meta.url)).replaceAll(\"\\\\\", \"/\")\n\t\t\t: new URL(import.meta.url.endsWith(\".ts\") ? \"./session-worker.ts\" : \"./session-worker.js\", import.meta.url),\n\t);\n\treadonly exited: Promise<void>;\n\tsnapshot?: WorkerSnapshot;\n\t/** Main marks this only after installing the unique routing binding. */\n\tbindingReady = false;\n\tprivate readonly requests = new SessionWorkerRequests(\n\t\t(message) => this.worker.postMessage(message),\n\t\t() => this.fail(\"session_worker_request_timeout\"),\n\t);\n\tprivate stopped = false;\n\tprivate displayRevision = 0;\n\tprivate closeTimer?: ReturnType<typeof setTimeout>;\n\tprivate writer?: SessionEventWriter;\n\tprivate sessionId?: string;\n\tprivate requestClose?: () => void;\n\tprivate options: Pick<RpcConnectionOptions, \"capabilities\" | \"sharedWidth\"> = {};\n\tprivate readonly listeners = new Set<() => void>();\n\tprivate readonly controls = new Set<\"display\" | \"cancel_ui\">();\n\tprivate latestDisplay?: Extract<HostToSessionWorker, { type: \"display\" }>;\n\n\tprivate readonly callbacks: SessionWorkerCallbacks;\n\n\tconstructor(callbacks: SessionWorkerCallbacks) {\n\t\tthis.callbacks = callbacks;\n\t\tthis.exited = new Promise((resolve) => {\n\t\t\tthis.worker.once(\"exit\", () => {\n\t\t\t\tif (!this.stopped && !this.closeTimer) this.fail(\"session_worker_exited\");\n\t\t\t\tthis.stopped = true;\n\t\t\t\tif (this.closeTimer) clearTimeout(this.closeTimer);\n\t\t\t\tthis.requests.close(new Error(\"session_worker_exited\"));\n\t\t\t\tthis.listeners.clear();\n\t\t\t\tcallbacks.exit();\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t\tthis.worker.on(\"message\", (message: SessionWorkerToHost) => this.receive(message));\n\t\tthis.worker.on(\"error\", (error: unknown) => this.fail(error instanceof Error ? error.message : String(error)));\n\t}\n\n\tasync prepare(configuration: CliRuntimeConfiguration, profile: RpcSessionLaunchProfile): Promise<string> {\n\t\tconst result = await this.request({ type: \"prepare\", configuration, profile });\n\t\tif (result.type !== \"prepared\") throw new Error(\"Invalid worker prepare response\");\n\t\treturn result.sessionPath;\n\t}\n\n\tasync commit(): Promise<WorkerSnapshot> {\n\t\tconst result = await this.request({ type: \"commit\" });\n\t\tif (result.type !== \"ready\") throw new Error(\"Invalid worker commit response\");\n\t\tthis.snapshot = result.snapshot;\n\t\treturn result.snapshot;\n\t}\n\n\tasync bind(\n\t\tsessionId: string,\n\t\twriter: SessionEventWriter,\n\t\trequestClose: () => void,\n\t\toptions: Pick<RpcConnectionOptions, \"capabilities\" | \"sharedWidth\">,\n\t): Promise<RpcSessionBinding> {\n\t\tthis.sessionId = sessionId;\n\t\tthis.writer = writer;\n\t\tthis.requestClose = requestClose;\n\t\tthis.options = options;\n\t\tawait this.request({ type: \"bind\", sessionId, display: this.display(), connection: writer.currentConnection() });\n\t\treturn {\n\t\t\thandle: async (command) => {\n\t\t\t\tawait this.request({\n\t\t\t\t\ttype: \"command\",\n\t\t\t\t\tcommand,\n\t\t\t\t\tconnection: writer.currentConnection(),\n\t\t\t\t\tdisplay: this.display(),\n\t\t\t\t});\n\t\t\t},\n\t\t\tcancelPendingExtensionUiRequests: () => this.post({ type: \"cancel_ui\" }),\n\t\t\trerenderComponents: () => this.post({ type: \"display\", display: this.display() }),\n\t\t\tdispose: async () => {\n\t\t\t\tthis.post({ type: \"cancel_ui\" });\n\t\t\t},\n\t\t};\n\t}\n\n\tget busy(): boolean {\n\t\treturn this.requests.activeCount > 0 || this.snapshot?.busy === true;\n\t}\n\n\tsubscribeSettled(listener: () => void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\t/** Deadline requests termination, but only the actual exit callback releases ownership. */\n\tclose(graceMs: number): Promise<void> {\n\t\tif (this.stopped || this.closeTimer) return this.exited;\n\t\tthis.post({ type: \"close\" });\n\t\tthis.closeTimer = setTimeout(() => this.quarantine(), graceMs);\n\t\treturn this.exited;\n\t}\n\n\tquarantine(): void {\n\t\tthis.stopped = true;\n\t\tthis.requests.close(new Error(\"session_closing\"));\n\t\tvoid this.worker.terminate();\n\t}\n\n\tprivate display(): WorkerDisplay {\n\t\treturn {\n\t\t\trevision: ++this.displayRevision,\n\t\t\twidth: this.options.sharedWidth?.getWidth() ?? 80,\n\t\t\trendered: this.options.sharedWidth?.hasRenderedComponents?.(this.sessionId ?? \"\") ?? false,\n\t\t\tcapabilities: this.options.capabilities ?? [],\n\t\t};\n\t}\n\n\tprivate request(message: WorkerRequestInput): ReturnType<SessionWorkerRequests[\"request\"]> {\n\t\treturn this.requests.request(message);\n\t}\n\n\tprivate post(message: HostToSessionWorker): void {\n\t\tif (this.stopped) return;\n\t\tif (message.type === \"display\" || message.type === \"cancel_ui\") {\n\t\t\tif (this.controls.has(message.type)) {\n\t\t\t\tif (message.type === \"display\") this.latestDisplay = message;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.controls.add(message.type);\n\t\t}\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tprivate receive(message: SessionWorkerToHost): void {\n\t\tif (this.stopped) {\n\t\t\tif (\"signal\" in message) acknowledge(message.signal, false);\n\t\t\treturn;\n\t\t}\n\t\tswitch (message.type) {\n\t\t\tcase \"prepared\":\n\t\t\tcase \"ready\":\n\t\t\tcase \"result\": {\n\t\t\t\tthis.requests.receive(message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"reserve\":\n\t\t\t\tacknowledgeGrant(message.signal, this.callbacks.reserve(message.path));\n\t\t\t\treturn;\n\t\t\tcase \"snapshot\":\n\t\t\t\tthis.snapshot = message.snapshot;\n\t\t\t\tthis.callbacks.reconcile(message.snapshot.liveSessionPaths);\n\t\t\t\tacknowledge(message.signal, true);\n\t\t\t\tif (message.settled) for (const listener of [...this.listeners]) listener();\n\t\t\t\treturn;\n\t\t\tcase \"control_done\": {\n\t\t\t\tthis.controls.delete(message.control);\n\t\t\t\tif (message.control === \"display\" && this.latestDisplay) {\n\t\t\t\t\tconst latest = this.latestDisplay;\n\t\t\t\t\tthis.latestDisplay = undefined;\n\t\t\t\t\tthis.post(latest);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"output\": {\n\t\t\t\tconst writer = this.writer;\n\t\t\t\tconst sessionId = this.sessionId;\n\t\t\t\tif (!writer || !sessionId || this.stopped) {\n\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Identity and activity commit before publication; clients may attach or disconnect on that event.\n\t\t\t\tif (message.snapshot) {\n\t\t\t\t\tthis.snapshot = message.snapshot;\n\t\t\t\t\tthis.callbacks.reconcile(message.snapshot.liveSessionPaths);\n\t\t\t\t} else if (this.snapshot)\n\t\t\t\t\tthis.snapshot = {\n\t\t\t\t\t\t...this.snapshot,\n\t\t\t\t\t\t...message.activity,\n\t\t\t\t\t\tstate: { ...this.snapshot.state, isStreaming: message.activity.streaming },\n\t\t\t\t\t};\n\t\t\t\tconst enqueue = () => {\n\t\t\t\t\tif (!writer.enqueue(sessionId, message.record)) {\n\t\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\t\tthis.fail(\"session_output_overflow_or_closed\");\n\t\t\t\t\t\treturn Promise.reject(new Error(\"session_output_overflow_or_closed\"));\n\t\t\t\t\t}\n\t\t\t\t\treturn writer.waitForSessionBackpressure(sessionId);\n\t\t\t\t};\n\t\t\t\tconst consumed =\n\t\t\t\t\tmessage.connection === undefined ? enqueue() : writer.withConnection(message.connection, enqueue);\n\t\t\t\tvoid consumed.then(\n\t\t\t\t\t() => acknowledge(message.signal, true),\n\t\t\t\t\t(cause: unknown) => {\n\t\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\t\tthis.fail(cause instanceof Error ? cause.message : String(cause));\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"width\":\n\t\t\t\tthis.options.sharedWidth?.setWidth(message.connection, message.width);\n\t\t\t\tthis.options.sharedWidth?.onChange?.();\n\t\t\t\trespondDisplay(message.signal, this.display());\n\t\t\t\treturn;\n\t\t\tcase \"capabilities\":\n\t\t\t\tthis.options.sharedWidth?.setCapabilities?.(message.connection, message.capabilities);\n\t\t\t\trespondDisplay(message.signal, this.display());\n\t\t\t\treturn;\n\t\t\tcase \"request_close\":\n\t\t\t\tthis.requestClose?.();\n\t\t\t\treturn;\n\t\t\tcase \"failure\":\n\t\t\t\tthis.fail(message.error);\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate fail(error: string): void {\n\t\tif (this.stopped) return;\n\t\tthis.callbacks.failure(error);\n\t\tif (this.writer && this.sessionId) {\n\t\t\tthis.writer.enqueue(this.sessionId, { type: \"session_error\", error });\n\t\t\tthis.writer.closeSession(this.sessionId, {\n\t\t\t\ttype: \"response\",\n\t\t\t\tcommand: \"close_session\",\n\t\t\t\tsuccess: false,\n\t\t\t\terror,\n\t\t\t});\n\t\t}\n\t\tthis.quarantine();\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-worker-client.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-worker-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { Worker } from \"node:worker_threads\";\nimport { isBunBinary } from \"../../config.ts\";\nimport type { CliRuntimeConfiguration } from \"../../main.ts\";\nimport type { RpcConnectionOptions } from \"./connection-handler.ts\";\nimport type { RpcSessionBinding } from \"./session-binding.ts\";\nimport type { SessionEventWriter } from \"./session-event-writer.ts\";\nimport type { RpcSessionLaunchProfile } from \"./session-registry.ts\";\nimport type {\n\tHostToSessionWorker,\n\tSessionWorkerToHost,\n\tSessionWriteGrant,\n\tWorkerDisplay,\n\tWorkerSnapshot,\n} from \"./session-worker-protocol.ts\";\n\nimport { SessionWorkerRequests, type WorkerRequestInput } from \"./session-worker-requests.ts\";\nimport { acknowledge, acknowledgeGrant, respondDisplay } from \"./session-worker-signals.ts\";\n\n/** Lifecycle hooks the owning registry installs on every worker it allocates. */\nexport interface SessionWorkerCallbacks {\n\treserve: (path: string) => SessionWriteGrant;\n\t/** Every snapshot republishes which paths this worker still writes. */\n\treconcile: (livePaths: readonly string[]) => void;\n\texit: () => void;\n\tfailure: (error: string) => void;\n}\n\n/** Bun wrapper builders define the worker entry name relative to their explicit --root. */\ndeclare const SENPI_RPC_SESSION_WORKER_ENTRY: string | undefined;\nconst compiledWorkerEntry =\n\ttypeof SENPI_RPC_SESSION_WORKER_ENTRY === \"string\"\n\t\t? SENPI_RPC_SESSION_WORKER_ENTRY\n\t\t: \"./src/modes/rpc/session-worker.ts\";\n\nexport class SessionWorkerClient {\n\treadonly worker = new Worker(\n\t\tisBunBinary\n\t\t\t? fileURLToPath(new URL(compiledWorkerEntry, import.meta.url)).replaceAll(\"\\\\\", \"/\")\n\t\t\t: new URL(import.meta.url.endsWith(\".ts\") ? \"./session-worker.ts\" : \"./session-worker.js\", import.meta.url),\n\t);\n\treadonly exited: Promise<void>;\n\tsnapshot?: WorkerSnapshot;\n\t/** Main marks this only after installing the unique routing binding. */\n\tbindingReady = false;\n\tprivate readonly requests = new SessionWorkerRequests(\n\t\t(message) => this.worker.postMessage(message),\n\t\t() => this.fail(\"session_worker_request_timeout\"),\n\t);\n\tprivate stopped = false;\n\tprivate displayRevision = 0;\n\tprivate closeTimer?: ReturnType<typeof setTimeout>;\n\tprivate writer?: SessionEventWriter;\n\tprivate sessionId?: string;\n\tprivate requestClose?: () => void;\n\tprivate options: Pick<RpcConnectionOptions, \"capabilities\" | \"sharedWidth\"> = {};\n\tprivate readonly listeners = new Set<() => void>();\n\tprivate readonly controls = new Set<\"display\" | \"cancel_ui\">();\n\tprivate latestDisplay?: Extract<HostToSessionWorker, { type: \"display\" }>;\n\tprivate terminalFailure?: string;\n\n\tprivate readonly callbacks: SessionWorkerCallbacks;\n\n\tconstructor(callbacks: SessionWorkerCallbacks) {\n\t\tthis.callbacks = callbacks;\n\t\tthis.exited = new Promise((resolve) => {\n\t\t\tthis.worker.once(\"exit\", () => {\n\t\t\t\tif (!this.stopped && !this.closeTimer) this.fail(\"session_worker_exited\");\n\t\t\t\tthis.stopped = true;\n\t\t\t\tif (this.closeTimer) clearTimeout(this.closeTimer);\n\t\t\t\tthis.requests.close(new Error(\"session_worker_exited\"));\n\t\t\t\tthis.listeners.clear();\n\t\t\t\tcallbacks.exit();\n\t\t\t\tthis.publishTerminalFailure();\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t\tthis.worker.on(\"message\", (message: SessionWorkerToHost) => this.receive(message));\n\t\tthis.worker.on(\"error\", (error: unknown) => this.fail(error instanceof Error ? error.message : String(error)));\n\t}\n\n\tasync prepare(configuration: CliRuntimeConfiguration, profile: RpcSessionLaunchProfile): Promise<string> {\n\t\tconst result = await this.request({ type: \"prepare\", configuration, profile });\n\t\tif (result.type !== \"prepared\") throw new Error(\"Invalid worker prepare response\");\n\t\treturn result.sessionPath;\n\t}\n\n\tasync commit(): Promise<WorkerSnapshot> {\n\t\tconst result = await this.request({ type: \"commit\" });\n\t\tif (result.type !== \"ready\") throw new Error(\"Invalid worker commit response\");\n\t\tthis.snapshot = result.snapshot;\n\t\treturn result.snapshot;\n\t}\n\n\tasync bind(\n\t\tsessionId: string,\n\t\twriter: SessionEventWriter,\n\t\trequestClose: () => void,\n\t\toptions: Pick<RpcConnectionOptions, \"capabilities\" | \"sharedWidth\">,\n\t): Promise<RpcSessionBinding> {\n\t\tthis.sessionId = sessionId;\n\t\tthis.writer = writer;\n\t\tthis.requestClose = requestClose;\n\t\tthis.options = options;\n\t\tawait this.request({ type: \"bind\", sessionId, display: this.display(), connection: writer.currentConnection() });\n\t\treturn {\n\t\t\thandle: async (command) => {\n\t\t\t\tawait this.request({\n\t\t\t\t\ttype: \"command\",\n\t\t\t\t\tcommand,\n\t\t\t\t\tconnection: writer.currentConnection(),\n\t\t\t\t\tdisplay: this.display(),\n\t\t\t\t});\n\t\t\t},\n\t\t\tcancelPendingExtensionUiRequests: () => this.post({ type: \"cancel_ui\" }),\n\t\t\trerenderComponents: () => this.post({ type: \"display\", display: this.display() }),\n\t\t\tdispose: async () => {\n\t\t\t\tthis.post({ type: \"cancel_ui\" });\n\t\t\t},\n\t\t};\n\t}\n\n\tget busy(): boolean {\n\t\treturn this.requests.activeCount > 0 || this.snapshot?.busy === true;\n\t}\n\n\tsubscribeSettled(listener: () => void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\t/** Deadline requests termination, but only the actual exit callback releases ownership. */\n\tclose(graceMs: number): Promise<void> {\n\t\tif (this.stopped || this.closeTimer) return this.exited;\n\t\tthis.post({ type: \"close\" });\n\t\tthis.closeTimer = setTimeout(() => this.quarantine(), graceMs);\n\t\treturn this.exited;\n\t}\n\n\tquarantine(): void {\n\t\tthis.stopped = true;\n\t\tthis.requests.close(new Error(\"session_closing\"));\n\t\tvoid this.worker.terminate();\n\t}\n\n\tprivate display(): WorkerDisplay {\n\t\treturn {\n\t\t\trevision: ++this.displayRevision,\n\t\t\twidth: this.options.sharedWidth?.getWidth() ?? 80,\n\t\t\trendered: this.options.sharedWidth?.hasRenderedComponents?.(this.sessionId ?? \"\") ?? false,\n\t\t\tcapabilities: this.options.capabilities ?? [],\n\t\t};\n\t}\n\n\tprivate request(message: WorkerRequestInput): ReturnType<SessionWorkerRequests[\"request\"]> {\n\t\treturn this.requests.request(message);\n\t}\n\n\tprivate post(message: HostToSessionWorker): void {\n\t\tif (this.stopped) return;\n\t\tif (message.type === \"display\" || message.type === \"cancel_ui\") {\n\t\t\tif (this.controls.has(message.type)) {\n\t\t\t\tif (message.type === \"display\") this.latestDisplay = message;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.controls.add(message.type);\n\t\t}\n\t\tthis.worker.postMessage(message);\n\t}\n\n\tprivate receive(message: SessionWorkerToHost): void {\n\t\tif (this.stopped) {\n\t\t\tif (\"signal\" in message) acknowledge(message.signal, false);\n\t\t\treturn;\n\t\t}\n\t\tswitch (message.type) {\n\t\t\tcase \"prepared\":\n\t\t\tcase \"ready\":\n\t\t\tcase \"result\": {\n\t\t\t\tthis.requests.receive(message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"reserve\":\n\t\t\t\tacknowledgeGrant(message.signal, this.callbacks.reserve(message.path));\n\t\t\t\treturn;\n\t\t\tcase \"snapshot\":\n\t\t\t\tthis.snapshot = message.snapshot;\n\t\t\t\tthis.callbacks.reconcile(message.snapshot.liveSessionPaths);\n\t\t\t\tacknowledge(message.signal, true);\n\t\t\t\tif (message.settled) for (const listener of [...this.listeners]) listener();\n\t\t\t\treturn;\n\t\t\tcase \"control_done\": {\n\t\t\t\tthis.controls.delete(message.control);\n\t\t\t\tif (message.control === \"display\" && this.latestDisplay) {\n\t\t\t\t\tconst latest = this.latestDisplay;\n\t\t\t\t\tthis.latestDisplay = undefined;\n\t\t\t\t\tthis.post(latest);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"output\": {\n\t\t\t\tconst writer = this.writer;\n\t\t\t\tconst sessionId = this.sessionId;\n\t\t\t\tif (!writer || !sessionId || this.stopped) {\n\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Identity and activity commit before publication; clients may attach or disconnect on that event.\n\t\t\t\tif (message.snapshot) {\n\t\t\t\t\tthis.snapshot = message.snapshot;\n\t\t\t\t\tthis.callbacks.reconcile(message.snapshot.liveSessionPaths);\n\t\t\t\t} else if (this.snapshot)\n\t\t\t\t\tthis.snapshot = {\n\t\t\t\t\t\t...this.snapshot,\n\t\t\t\t\t\t...message.activity,\n\t\t\t\t\t\tstate: { ...this.snapshot.state, isStreaming: message.activity.streaming },\n\t\t\t\t\t};\n\t\t\t\tconst enqueue = () => {\n\t\t\t\t\tif (!writer.enqueue(sessionId, message.record)) {\n\t\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\t\tthis.fail(\"session_output_overflow_or_closed\");\n\t\t\t\t\t\treturn Promise.reject(new Error(\"session_output_overflow_or_closed\"));\n\t\t\t\t\t}\n\t\t\t\t\treturn writer.waitForSessionBackpressure(sessionId);\n\t\t\t\t};\n\t\t\t\tconst consumed =\n\t\t\t\t\tmessage.connection === undefined ? enqueue() : writer.withConnection(message.connection, enqueue);\n\t\t\t\tvoid consumed.then(\n\t\t\t\t\t() => acknowledge(message.signal, true),\n\t\t\t\t\t(cause: unknown) => {\n\t\t\t\t\t\tacknowledge(message.signal, false);\n\t\t\t\t\t\tthis.fail(cause instanceof Error ? cause.message : String(cause));\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"width\":\n\t\t\t\tthis.options.sharedWidth?.setWidth(message.connection, message.width);\n\t\t\t\tthis.options.sharedWidth?.onChange?.();\n\t\t\t\trespondDisplay(message.signal, this.display());\n\t\t\t\treturn;\n\t\t\tcase \"capabilities\":\n\t\t\t\tthis.options.sharedWidth?.setCapabilities?.(message.connection, message.capabilities);\n\t\t\t\trespondDisplay(message.signal, this.display());\n\t\t\t\treturn;\n\t\t\tcase \"request_close\":\n\t\t\t\tthis.requestClose?.();\n\t\t\t\treturn;\n\t\t\tcase \"failure\":\n\t\t\t\tthis.fail(message.error);\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\tprivate fail(error: string): void {\n\t\tif (this.stopped) return;\n\t\tthis.callbacks.failure(error);\n\t\tthis.terminalFailure = error;\n\t\tif (this.writer && this.sessionId) {\n\t\t\tthis.writer.enqueue(this.sessionId, { type: \"session_error\", error });\n\t\t}\n\t\tthis.quarantine();\n\t}\n\n\t/** Terminal close records observe completed registry removal, including worker failure. */\n\tprivate publishTerminalFailure(): void {\n\t\tconst error = this.terminalFailure;\n\t\tconst writer = this.writer;\n\t\tconst sessionId = this.sessionId;\n\t\tif (error === undefined || !writer || !sessionId) return;\n\t\tthis.terminalFailure = undefined;\n\t\twriter.closeSession(sessionId, {\n\t\t\ttype: \"response\",\n\t\t\tcommand: \"close_session\",\n\t\t\tsuccess: false,\n\t\t\terror,\n\t\t});\n\t}\n}\n"]}
@@ -0,0 +1,3 @@
1
+ /** Process shutdown entry shared by EOF, signals and transport failures. */
2
+ export declare function createRpcShutdown(dispose: (signal?: NodeJS.Signals) => Promise<void>, exit: (code: number) => never): (exitCode?: number, signal?: NodeJS.Signals) => Promise<never>;
3
+ //# sourceMappingURL=shutdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/shutdown.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,EACnD,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,GAC3B,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAYhE"}
@@ -0,0 +1,17 @@
1
+ /** Process shutdown entry shared by EOF, signals and transport failures. */
2
+ export function createRpcShutdown(dispose, exit) {
3
+ let pending;
4
+ let code = 0;
5
+ return (exitCode = 0, signal) => {
6
+ if (code === 0)
7
+ code = exitCode;
8
+ if (pending)
9
+ return pending;
10
+ pending = (async () => {
11
+ await dispose(signal);
12
+ return exit(code);
13
+ })();
14
+ return pending;
15
+ };
16
+ }
17
+ //# sourceMappingURL=shutdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../src/modes/rpc/shutdown.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAChC,OAAmD,EACnD,IAA6B;IAE7B,IAAI,OAAmC,CAAC;IACxC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,MAAuB,EAAkB,EAAE;QAChE,IAAI,IAAI,KAAK,CAAC;YAAE,IAAI,GAAG,QAAQ,CAAC;QAChC,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;QAC5B,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;YACrB,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;YACtB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,OAAO,CAAC;IAChB,CAAC,CAAC;AACH,CAAC","sourcesContent":["/** Process shutdown entry shared by EOF, signals and transport failures. */\nexport function createRpcShutdown(\n\tdispose: (signal?: NodeJS.Signals) => Promise<void>,\n\texit: (code: number) => never,\n): (exitCode?: number, signal?: NodeJS.Signals) => Promise<never> {\n\tlet pending: Promise<never> | undefined;\n\tlet code = 0;\n\treturn (exitCode = 0, signal?: NodeJS.Signals): Promise<never> => {\n\t\tif (code === 0) code = exitCode;\n\t\tif (pending) return pending;\n\t\tpending = (async () => {\n\t\t\tawait dispose(signal);\n\t\t\treturn exit(code);\n\t\t})();\n\t\treturn pending;\n\t};\n}\n"]}
@@ -379,7 +379,7 @@ user sends another prompt ◄─────────────────
379
379
  ├─► session_start { reason: "reload" }
380
380
  └─► resources_discover { reason: "reload" }
381
381
 
382
- /name or pi.setSessionName()
382
+ /rename, /name, or pi.setSessionName()
383
383
  └─► session_info_changed
384
384
 
385
385
  /compact or auto-compaction
@@ -477,7 +477,7 @@ pi.on("session_start", async (event, ctx) => {
477
477
 
478
478
  #### session_info_changed
479
479
 
480
- Fired when the current session display name is set via `/name`, RPC, or `pi.setSessionName()`.
480
+ Fired when the current session display name is set via `/rename`, `/name`, RPC, or `pi.setSessionName()`.
481
481
 
482
482
  ```typescript
483
483
  pi.on("session_info_changed", async (event, ctx) => {
@@ -619,10 +619,13 @@ Fired before a started session runtime is torn down. Use this to clean up resour
619
619
  pi.on("session_shutdown", async (event, ctx) => {
620
620
  // event.reason - "quit" | "reload" | "new" | "resume" | "fork"
621
621
  // event.targetSessionFile - destination session for session replacement flows
622
+ // event.signal - aborted when this handler exceeds the host's shutdown budget
622
623
  // Cleanup, save state, etc.
623
624
  });
624
625
  ```
625
626
 
627
+ The host budgets each handler separately: a handler still running after `sessionShutdownHandlerWarnMs` (default 2000) logs a warning naming the extension, and at `sessionShutdownHandlerTimeoutMs` (default 10000) senpi aborts that handler's `event.signal`, reports an extension error, and continues teardown with the remaining handlers. Keep shutdown work short, and pass `event.signal` to anything that can block (subprocess waits, network calls, lock acquisition) so it stops when the host gives up on it. Both thresholds are settings; `0` disables either half. See [settings.md](settings.md#shutdown-handler-budget).
628
+
626
629
  ### Agent Events
627
630
 
628
631
  #### before_agent_start
@@ -138,6 +138,7 @@ This routing remains configurable through the ordinary action bindings. For exam
138
138
  | `app.session.tree` | *(none)* | Open session tree navigator (`/tree`) |
139
139
  | `app.session.fork` | *(none)* | Fork current session (`/fork`) |
140
140
  | `app.session.resume` | *(none)* | Open session resume picker (`/resume`) |
141
+ | `app.session.renameCurrent` | *(none)* | Rename the current session |
141
142
  | `app.session.togglePath` | `ctrl+p` | Toggle path display |
142
143
  | `app.session.toggleSort` | `ctrl+s` | Toggle sort mode |
143
144
  | `app.session.toggleNamedFilter` | `ctrl+n` | Toggle named-only filter |
@@ -312,7 +312,7 @@ Set `label` to `undefined` to clear a label.
312
312
 
313
313
  ### SessionInfoEntry
314
314
 
315
- Session metadata (e.g., user-defined display name). Set via `/name`, `--name` / `-n`, or `pi.setSessionName()` in extensions.
315
+ Session metadata (e.g., user-defined display name). Set via `/rename` or `/name`, `--name` / `-n`, or `pi.setSessionName()` in extensions.
316
316
 
317
317
  ```json
318
318
  {"type":"session_info","id":"k1l2m3n4","parentId":"j0k1l2m3","timestamp":"2024-12-03T14:35:00.000Z","name":"Refactor auth module"}
package/docs/sessions.md CHANGED
@@ -25,7 +25,7 @@ For the JSONL file format and SessionManager API, see [Session Format](session-f
25
25
  |---------|-------------|
26
26
  | `/resume` | Browse and select previous sessions |
27
27
  | `/new` | Start a new session |
28
- | `/name <name>` | Set the current session display name |
28
+ | `/rename [name]` | Rename the current session (`/name` is an alias) |
29
29
  | `/session` | Show session info |
30
30
  | `/tree` | Navigate the current session tree |
31
31
  | `/fork` | Create a new session from a previous user message |
@@ -51,10 +51,10 @@ When available, senpi uses the `trash` CLI for deletion instead of permanently r
51
51
 
52
52
  ## Naming Sessions
53
53
 
54
- Use `/name <name>` to set a human-readable session name:
54
+ Use `/rename [name]` to set a human-readable session name. With an argument it sets the name immediately; without one it opens an inline editor prefilled with the current name (Enter commits, Esc cancels, empty names are rejected). `/name` is an alias.
55
55
 
56
56
  ```text
57
- /name Refactor auth module
57
+ /rename Refactor auth module
58
58
  ```
59
59
 
60
60
  Set the name at startup with `--name` or `-n`:
package/docs/settings.md CHANGED
@@ -258,6 +258,9 @@ See [compaction.md](compaction.md) for trigger and summarization behavior.
258
258
  | `retry.provider.timeoutMs` | number | `300000` | Provider/SDK request timeout and stream idle timeout in milliseconds |
259
259
  | `retry.provider.streamStartTimeoutMs` | number | `300000` | Maximum wait for the first provider stream event; `0` disables |
260
260
  | `retry.provider.streamRetryTimeoutMs` | number | `30000` | First-request liveness cap after a known provider stream/transport timeout; `0` disables the cap |
261
+ | `retry.provider.minThroughputTokensPerSecond` | number | `8` | Sustained streamed-units floor for an in-progress stream; `0` disables the watchdog |
262
+ | `retry.provider.throughputWindowMs` | number | `20000` | Observation window for that floor; `0` disables the watchdog |
263
+ | `retry.provider.throughputGraceMs` | number | `5000` | Streaming after the first event that is never measured; `0` measures immediately |
261
264
  | `retry.provider.maxRetries` | number | `0` | Provider/SDK retry attempts |
262
265
  | `retry.provider.maxRetryDelayMs` | number | `60000` | Max server-requested delay honored on the same model before the fallback chain engages (60s) |
263
266
 
@@ -269,6 +272,18 @@ After an exact provider stream/transport timeout, `retry.provider.streamRetryTim
269
272
  provider request and defers queued user input from that request. The cap applies only to stream guards that are
270
273
  already enabled, never turns a disabled guard back on, and restores configured timeouts for later requests.
271
274
 
275
+ `streamStartTimeoutMs` bounds the wait for the FIRST event and stops applying once it arrives; `timeoutMs` then
276
+ bounds silence between events. Both are silence detectors, so a provider that keeps answering at a uselessly low
277
+ rate trips neither. The throughput watchdog is the rate half: after the first stream event it ignores
278
+ `retry.provider.throughputGraceMs` of streaming, then measures streamed text and thinking units (about one unit
279
+ per token) over a trailing `retry.provider.throughputWindowMs`. A full window carrying at least 16 units whose
280
+ sustained rate is below `retry.provider.minThroughputTokensPerSecond` aborts the in-flight request with
281
+ `Provider stream throughput degraded: <n> tok/s over <n>s (floor <n> tok/s)`. Time the provider spends executing
282
+ local tools does not count against the window, and the interactive working line shows the live rate
283
+ (`Working (1m 12s • 2.1 tok/s • esc to interrupt)`) while the turn runs. That failure is retryable but never
284
+ spends same-model attempts — replaying the payload cannot make the upstream faster — so it goes straight to the
285
+ fallback chain; with no chain candidate the turn ends with that error instead of continuing to crawl.
286
+
272
287
  Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explicitly needed. Setting it above `0` can make SDK/provider retries handle out-of-usage-limit errors before senpi sees them, which may block the agent until the provider quota resets in some circumstances.
273
288
 
274
289
  ```json
@@ -282,6 +297,9 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
282
297
  "timeoutMs": 3600000,
283
298
  "streamStartTimeoutMs": 300000,
284
299
  "streamRetryTimeoutMs": 30000,
300
+ "minThroughputTokensPerSecond": 8,
301
+ "throughputWindowMs": 20000,
302
+ "throughputGraceMs": 5000,
285
303
  "maxRetries": 0,
286
304
  "maxRetryDelayMs": 60000
287
305
  }
@@ -291,7 +309,7 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
291
309
 
292
310
  #### Model fallback chains
293
311
 
294
- `retry.fallbackChains` maps a primary-model selector to an ordered list of fallback selectors. A selector is `provider/model` with an optional `:thinking-level` suffix, or a bare `model` id that applies to every provider serving that model family. Bare selectors expand against the models you actually have: providers holding an OAuth credential are preferred, then a fixed precedence order, and OpenRouter is never chosen by expansion. Senpi ships bare default chains for `claude-fable-5-1` and `claude-fable-5`, so Fable 5.1 and Fable 5 keep a fallback chain whichever provider serves them; set a key to `[]` to opt out entirely, or set one `provider/claude-fable-5-1` key to override just that provider. For example, this switches Fable 5.1 to Kimi K3 at `max` thinking when an eligible failure occurs:
312
+ `retry.fallbackChains` maps a primary-model selector to an ordered list of fallback selectors. A selector is `provider/model` with an optional `:thinking-level` suffix, or a bare `model` id that applies to every provider serving that model family. Bare selectors expand against the models you actually have: providers holding an OAuth credential are preferred, then a fixed precedence order, and OpenRouter is never chosen by expansion. Fallback chains are explicit user configuration only: Senpi ships no default and no wildcard lane, so a model without a configured chain never enters an implicit fallback lane and a failure that would fall back ends the turn instead. Set a key to `[]` to opt out of a chain you configured at a broader granularity, or set one `provider/claude-fable-5-1` key to override just that provider. For example, this switches Fable 5.1 to Kimi K3 at `max` thinking when an eligible failure occurs:
295
313
 
296
314
  ```json
297
315
  {
@@ -505,6 +523,8 @@ While a question is pending, the terminal title shows `? <header>` unless an act
505
523
  | Setting | Type | Default | Description |
506
524
  |---------|------|---------|-------------|
507
525
  | `sessionDir` | string | - | Directory where session files are stored. Accepts absolute or relative paths, plus `~`. |
526
+ | `sessionShutdownHandlerWarnMs` | number | `2000` | Warn when a single extension's `session_shutdown` handler has run this long. Set to `0` to disable the warning. |
527
+ | `sessionShutdownHandlerTimeoutMs` | number | `10000` | Hard cap for a single extension's `session_shutdown` handler. Set to `0` to disable the cap. |
508
528
 
509
529
  ```json
510
530
  { "sessionDir": ".senpi/sessions" }
@@ -512,6 +532,16 @@ While a question is pending, the terminal title shows `? <header>` unless an act
512
532
 
513
533
  When multiple sources specify a session directory, precedence is `--session-dir`, `SENPI_CODING_AGENT_SESSION_DIR`, then `sessionDir` in settings.json.
514
534
 
535
+ #### Shutdown handler budget
536
+
537
+ senpi bounds each extension's `session_shutdown` handler so one slow extension cannot hold quit, `/reload`, `/new`, `/resume` or a fork hostage. Past `sessionShutdownHandlerWarnMs` it logs one warning naming the extension; at `sessionShutdownHandlerTimeoutMs` it aborts the `signal` that handler received on the event, reports an extension error, and continues teardown with the next handler. The handler itself is not killed - it keeps running until the process exits - so extensions that persist durable state should observe `event.signal`.
538
+
539
+ ```json
540
+ { "sessionShutdownHandlerWarnMs": 2000, "sessionShutdownHandlerTimeoutMs": 10000 }
541
+ ```
542
+
543
+ Only `session_shutdown` is bounded; other extension events (including ask-user and approval dialogs, which may legitimately wait for minutes) are unaffected.
544
+
515
545
  ### Model Cycling
516
546
 
517
547
  | Setting | Type | Default | Description |
package/docs/usage.md CHANGED
@@ -51,7 +51,7 @@ Type `/` in the editor to open command completion. Extensions can register custo
51
51
  | `/settings` | Theme, message delivery, transport, and other preferences |
52
52
  | `/resume` | Pick from previous sessions |
53
53
  | `/new` | Start a new session |
54
- | `/name <name>` | Set session display name |
54
+ | `/rename [name]` | Rename the current session (`/name` is an alias) |
55
55
  | `/session` | Show session file, ID, messages, tokens, and cost |
56
56
  | `/tree` | Jump to any point in the session and continue from there |
57
57
  | `/trust` | Save project trust decision for future sessions |