@code-yeongyu/senpi 2026.9.2 → 2026.9.3-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/CHANGELOG.md +188 -2
  2. package/dist/beta/omo-local-update-fingerprint.d.ts.map +1 -1
  3. package/dist/beta/omo-local-update-fingerprint.js +0 -1
  4. package/dist/beta/omo-local-update-fingerprint.js.map +1 -1
  5. package/dist/core/agent-session.d.ts +3 -5
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +39 -33
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  10. package/dist/core/dynamic-prompt/build.js +2 -5
  11. package/dist/core/dynamic-prompt/build.js.map +1 -1
  12. package/dist/core/dynamic-prompt/index.d.ts +1 -2
  13. package/dist/core/dynamic-prompt/index.d.ts.map +1 -1
  14. package/dist/core/dynamic-prompt/index.js +1 -2
  15. package/dist/core/dynamic-prompt/index.js.map +1 -1
  16. package/dist/core/dynamic-prompt/intent-gate.d.ts.map +1 -1
  17. package/dist/core/dynamic-prompt/intent-gate.js +9 -24
  18. package/dist/core/dynamic-prompt/intent-gate.js.map +1 -1
  19. package/dist/core/dynamic-prompt/policies.d.ts.map +1 -1
  20. package/dist/core/dynamic-prompt/policies.js +3 -7
  21. package/dist/core/dynamic-prompt/policies.js.map +1 -1
  22. package/dist/core/dynamic-prompt/style.d.ts.map +1 -1
  23. package/dist/core/dynamic-prompt/style.js +6 -8
  24. package/dist/core/dynamic-prompt/style.js.map +1 -1
  25. package/dist/core/dynamic-prompt/verification.js +1 -1
  26. package/dist/core/dynamic-prompt/verification.js.map +1 -1
  27. package/dist/core/dynamic-prompt/working-task.d.ts +2 -0
  28. package/dist/core/dynamic-prompt/working-task.d.ts.map +1 -0
  29. package/dist/core/dynamic-prompt/working-task.js +10 -0
  30. package/dist/core/dynamic-prompt/working-task.js.map +1 -0
  31. package/dist/core/extensions/builtin/bash-timeout/index.d.ts +1 -1
  32. package/dist/core/extensions/builtin/bash-timeout/index.d.ts.map +1 -1
  33. package/dist/core/extensions/builtin/bash-timeout/index.js +7 -1
  34. package/dist/core/extensions/builtin/bash-timeout/index.js.map +1 -1
  35. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts +11 -7
  36. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts.map +1 -1
  37. package/dist/core/extensions/builtin/bash-timeout/timeout.js +4 -8
  38. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  39. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js +15 -18
  41. package/dist/core/extensions/builtin/claude-sdk-oauth/auth-lane.js.map +1 -1
  42. package/dist/core/extensions/builtin/claude-sdk-oauth/content-blocks.d.ts +3 -0
  43. package/dist/core/extensions/builtin/claude-sdk-oauth/content-blocks.d.ts.map +1 -0
  44. package/dist/core/extensions/builtin/claude-sdk-oauth/content-blocks.js +80 -0
  45. package/dist/core/extensions/builtin/claude-sdk-oauth/content-blocks.js.map +1 -0
  46. package/dist/core/extensions/builtin/claude-sdk-oauth/errors.d.ts +18 -1
  47. package/dist/core/extensions/builtin/claude-sdk-oauth/errors.d.ts.map +1 -1
  48. package/dist/core/extensions/builtin/claude-sdk-oauth/errors.js +57 -1
  49. package/dist/core/extensions/builtin/claude-sdk-oauth/errors.js.map +1 -1
  50. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts +1 -0
  51. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.d.ts.map +1 -1
  52. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.js +13 -0
  53. package/dist/core/extensions/builtin/claude-sdk-oauth/guidance.js.map +1 -1
  54. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts.map +1 -1
  55. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js +6 -1
  56. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -1
  57. package/dist/core/extensions/builtin/claude-sdk-oauth/options.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/claude-sdk-oauth/options.js +6 -2
  59. package/dist/core/extensions/builtin/claude-sdk-oauth/options.js.map +1 -1
  60. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.js +2 -23
  62. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.js.map +1 -1
  63. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts +2 -2
  64. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +30 -24
  66. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
  67. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +2 -0
  68. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +15 -1
  70. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
  71. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts +1 -1
  72. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js +1 -0
  74. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js.map +1 -1
  75. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts +6 -1
  76. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
  77. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +1 -0
  78. package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
  79. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.d.ts.map +1 -1
  80. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js +19 -3
  81. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js.map +1 -1
  82. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts.map +1 -1
  83. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js +31 -13
  84. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js.map +1 -1
  85. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts +1 -0
  86. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js +1 -0
  88. package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js.map +1 -1
  89. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -1
  90. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +8 -14
  91. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -1
  92. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.d.ts.map +1 -1
  93. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js +23 -6
  94. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js.map +1 -1
  95. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.d.ts.map +1 -1
  96. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js +4 -2
  97. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-guidance.js.map +1 -1
  98. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-protocol.d.ts +1 -1
  99. package/dist/core/extensions/builtin/claude-sdk-oauth/stream-protocol.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -1
  101. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js +15 -7
  102. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -1
  103. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts +11 -3
  104. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts.map +1 -1
  105. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js +12 -3
  106. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js.map +1 -1
  107. package/dist/core/extensions/builtin/compaction/extension-wiring.js +1 -1
  108. package/dist/core/extensions/builtin/compaction/extension-wiring.js.map +1 -1
  109. package/dist/core/extensions/builtin/config-reload/watch-event-source.d.ts +1 -1
  110. package/dist/core/extensions/builtin/config-reload/watch-event-source.d.ts.map +1 -1
  111. package/dist/core/extensions/builtin/config-reload/watch-event-source.js +27 -9
  112. package/dist/core/extensions/builtin/config-reload/watch-event-source.js.map +1 -1
  113. package/dist/core/extensions/builtin/eval-only-routing.d.ts +10 -0
  114. package/dist/core/extensions/builtin/eval-only-routing.d.ts.map +1 -0
  115. package/dist/core/extensions/builtin/eval-only-routing.js +16 -0
  116. package/dist/core/extensions/builtin/eval-only-routing.js.map +1 -0
  117. package/dist/core/extensions/builtin/gpt-account.d.ts +3 -0
  118. package/dist/core/extensions/builtin/gpt-account.d.ts.map +1 -0
  119. package/dist/core/extensions/builtin/gpt-account.js +115 -0
  120. package/dist/core/extensions/builtin/gpt-account.js.map +1 -0
  121. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  122. package/dist/core/extensions/builtin/index.js +2 -0
  123. package/dist/core/extensions/builtin/index.js.map +1 -1
  124. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts.map +1 -1
  125. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +52 -50
  126. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -1
  127. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.d.ts.map +1 -1
  128. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +2 -1
  129. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
  130. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.d.ts.map +1 -1
  131. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js +8 -4
  132. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js.map +1 -1
  133. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.d.ts.map +1 -1
  134. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js +2 -6
  135. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js.map +1 -1
  136. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.d.ts.map +1 -1
  137. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js +9 -3
  138. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js.map +1 -1
  139. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.d.ts.map +1 -1
  140. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js +10 -4
  141. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js.map +1 -1
  142. package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.d.ts.map +1 -1
  143. package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js +57 -43
  144. package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js.map +1 -1
  145. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +39 -0
  146. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts.map +1 -0
  147. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +57 -0
  148. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js.map +1 -0
  149. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.d.ts +1 -1
  150. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.d.ts.map +1 -1
  151. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js +2 -11
  152. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js.map +1 -1
  153. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.d.ts +1 -1
  154. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.d.ts.map +1 -1
  155. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.js +2 -11
  156. package/dist/core/extensions/builtin/prompt-preset/glm-5-3.js.map +1 -1
  157. package/dist/core/extensions/builtin/prompt-preset/glm-5.d.ts +4 -0
  158. package/dist/core/extensions/builtin/prompt-preset/glm-5.d.ts.map +1 -0
  159. package/dist/core/extensions/builtin/prompt-preset/glm-5.js +16 -0
  160. package/dist/core/extensions/builtin/prompt-preset/glm-5.js.map +1 -0
  161. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.d.ts.map +1 -1
  162. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js +11 -1
  163. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js.map +1 -1
  164. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts.map +1 -1
  165. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +11 -1
  166. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -1
  167. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -1
  168. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +61 -76
  169. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
  170. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  171. package/dist/core/extensions/builtin/prompt-preset/presets.js +8 -2
  172. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  173. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  174. package/dist/core/extensions/builtin/terminal/extension.js +13 -5
  175. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  176. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts +4 -3
  177. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
  178. package/dist/core/extensions/builtin/terminal/monitor-notify.js +18 -18
  179. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
  180. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +7 -0
  181. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  182. package/dist/core/extensions/builtin/terminal/monitor-registry.js +37 -8
  183. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  184. package/dist/core/extensions/builtin/terminal/monitor-status.js +1 -1
  185. package/dist/core/extensions/builtin/terminal/monitor-status.js.map +1 -1
  186. package/dist/core/extensions/builtin/terminal/prompt.d.ts +13 -2
  187. package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
  188. package/dist/core/extensions/builtin/terminal/prompt.js +31 -16
  189. package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
  190. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
  191. package/dist/core/extensions/builtin/terminal/tools/bash-output.js +14 -2
  192. package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
  193. package/dist/core/extensions/builtin/terminal/tools/context.d.ts +2 -0
  194. package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
  195. package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
  196. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
  197. package/dist/core/extensions/builtin/terminal/tools/monitor.js +27 -10
  198. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
  199. package/dist/core/provider-composer.d.ts.map +1 -1
  200. package/dist/core/provider-composer.js +17 -8
  201. package/dist/core/provider-composer.js.map +1 -1
  202. package/dist/core/settings-manager.d.ts +2 -6
  203. package/dist/core/settings-manager.d.ts.map +1 -1
  204. package/dist/core/settings-manager.js +5 -9
  205. package/dist/core/settings-manager.js.map +1 -1
  206. package/dist/index.d.ts +1 -1
  207. package/dist/index.d.ts.map +1 -1
  208. package/dist/index.js +1 -1
  209. package/dist/index.js.map +1 -1
  210. package/dist/modes/index.d.ts +1 -1
  211. package/dist/modes/index.d.ts.map +1 -1
  212. package/dist/modes/index.js +1 -1
  213. package/dist/modes/index.js.map +1 -1
  214. package/dist/modes/print-mode.d.ts.map +1 -1
  215. package/dist/modes/print-mode.js +9 -0
  216. package/dist/modes/print-mode.js.map +1 -1
  217. package/dist/modes/rpc/connection-handler.d.ts +2 -0
  218. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  219. package/dist/modes/rpc/connection-handler.js +71 -12
  220. package/dist/modes/rpc/connection-handler.js.map +1 -1
  221. package/dist/modes/rpc/custom-capability.d.ts +5 -0
  222. package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
  223. package/dist/modes/rpc/custom-capability.js +5 -0
  224. package/dist/modes/rpc/custom-capability.js.map +1 -1
  225. package/dist/modes/rpc/host-ensure.d.ts +6 -0
  226. package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
  227. package/dist/modes/rpc/host-ensure.js +36 -9
  228. package/dist/modes/rpc/host-ensure.js.map +1 -1
  229. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
  230. package/dist/modes/rpc/host-lifecycle.js +16 -4
  231. package/dist/modes/rpc/host-lifecycle.js.map +1 -1
  232. package/dist/modes/rpc/login-prompts.d.ts +24 -0
  233. package/dist/modes/rpc/login-prompts.d.ts.map +1 -0
  234. package/dist/modes/rpc/login-prompts.js +44 -0
  235. package/dist/modes/rpc/login-prompts.js.map +1 -0
  236. package/dist/modes/rpc/media-placeholders.d.ts +49 -0
  237. package/dist/modes/rpc/media-placeholders.d.ts.map +1 -0
  238. package/dist/modes/rpc/media-placeholders.js +151 -0
  239. package/dist/modes/rpc/media-placeholders.js.map +1 -0
  240. package/dist/modes/rpc/multi-session-host.d.ts +7 -4
  241. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  242. package/dist/modes/rpc/multi-session-host.js +10 -4
  243. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  244. package/dist/modes/rpc/rpc-client.d.ts +16 -0
  245. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  246. package/dist/modes/rpc/rpc-client.js +73 -7
  247. package/dist/modes/rpc/rpc-client.js.map +1 -1
  248. package/dist/modes/rpc/rpc-mode.d.ts +1 -1
  249. package/dist/modes/rpc/rpc-mode.js +1 -1
  250. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  251. package/dist/modes/rpc/rpc-types.d.ts +23 -1
  252. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  253. package/dist/modes/rpc/rpc-types.js +1 -0
  254. package/dist/modes/rpc/rpc-types.js.map +1 -1
  255. package/dist/modes/rpc/session-command-router.d.ts +22 -0
  256. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  257. package/dist/modes/rpc/session-command-router.js +134 -95
  258. package/dist/modes/rpc/session-command-router.js.map +1 -1
  259. package/dist/modes/rpc/session-event-fanout.d.ts +51 -0
  260. package/dist/modes/rpc/session-event-fanout.d.ts.map +1 -0
  261. package/dist/modes/rpc/session-event-fanout.js +170 -0
  262. package/dist/modes/rpc/session-event-fanout.js.map +1 -0
  263. package/dist/modes/rpc/session-event-writer.d.ts +9 -14
  264. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  265. package/dist/modes/rpc/session-event-writer.js +68 -106
  266. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  267. package/dist/modes/rpc/session-registry.d.ts +9 -8
  268. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  269. package/dist/modes/rpc/session-registry.js +14 -42
  270. package/dist/modes/rpc/session-registry.js.map +1 -1
  271. package/dist/modes/rpc/session-teardown.d.ts +12 -0
  272. package/dist/modes/rpc/session-teardown.d.ts.map +1 -0
  273. package/dist/modes/rpc/session-teardown.js +117 -0
  274. package/dist/modes/rpc/session-teardown.js.map +1 -0
  275. package/dist/modes/rpc/socket-event-fanout.d.ts +8 -1
  276. package/dist/modes/rpc/socket-event-fanout.d.ts.map +1 -1
  277. package/dist/modes/rpc/socket-event-fanout.js +32 -9
  278. package/dist/modes/rpc/socket-event-fanout.js.map +1 -1
  279. package/docs/rpc.md +114 -6
  280. package/docs/settings.md +8 -30
  281. package/docs/terminal-tools.md +26 -6
  282. package/docs/windows.md +1 -1
  283. package/node_modules/@anthropic-ai/claude-agent-sdk/bridge.d.ts +18 -1
  284. package/node_modules/@anthropic-ai/claude-agent-sdk/bridge.mjs +155 -106
  285. package/node_modules/@anthropic-ai/claude-agent-sdk/browser-sdk.js +144 -83
  286. package/node_modules/@anthropic-ai/claude-agent-sdk/manifest.json +21 -32
  287. package/node_modules/@anthropic-ai/claude-agent-sdk/manifest.zst.json +25 -36
  288. package/node_modules/@anthropic-ai/claude-agent-sdk/package.json +2 -2
  289. package/node_modules/@anthropic-ai/claude-agent-sdk/sdk-tools.d.ts +93 -31
  290. package/node_modules/@anthropic-ai/claude-agent-sdk/sdk.d.ts +473 -31
  291. package/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs +140 -93
  292. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +83 -0
  293. package/node_modules/@code-yeongyu/senpi-codemode/README.md +4 -2
  294. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  295. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/skill-contribution.ts +43 -9
  296. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +21 -1
  297. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +6 -0
  298. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.d.ts +10 -0
  299. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.js +126 -0
  300. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +24 -7
  301. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/SKILL.md +1 -1
  302. package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/runtime-apis.md +1 -1
  303. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +5 -1
  304. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +3 -0
  305. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts +3 -0
  306. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  307. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -2
  308. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.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/api/anthropic-messages.js +1 -1
  311. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  312. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts +5 -0
  313. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts.map +1 -1
  314. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js +26 -4
  315. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js.map +1 -1
  316. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +16 -3
  317. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
  318. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +40 -6
  319. package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
  320. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.d.ts +8 -0
  321. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.d.ts.map +1 -1
  322. package/node_modules/@earendil-works/pi-ai/dist/compat/extension-oauth-types.js.map +1 -1
  323. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  324. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  325. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google-vertex.json +1 -1
  326. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
  327. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
  328. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  329. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  330. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  331. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  332. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  333. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  334. package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.d.ts.map +1 -1
  335. package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.js +3 -1
  336. package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.js.map +1 -1
  337. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +1 -1
  338. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  339. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  340. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  341. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  342. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  343. package/package.json +16 -16
  344. package/dist/core/dynamic-prompt/exploration.d.ts +0 -2
  345. package/dist/core/dynamic-prompt/exploration.d.ts.map +0 -1
  346. package/dist/core/dynamic-prompt/exploration.js +0 -6
  347. package/dist/core/dynamic-prompt/exploration.js.map +0 -1
  348. package/dist/core/dynamic-prompt/parallel-tools.d.ts +0 -2
  349. package/dist/core/dynamic-prompt/parallel-tools.d.ts.map +0 -1
  350. package/dist/core/dynamic-prompt/parallel-tools.js +0 -8
  351. package/dist/core/dynamic-prompt/parallel-tools.js.map +0 -1
@@ -1,6 +1,9 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { MEDIA_PLACEHOLDERS_CAPABILITY } from "./custom-capability.js";
2
3
  import { serializeJsonLine } from "./jsonl.js";
3
- import { SocketEventSinkActor } from "./socket-event-fanout.js";
4
+ import { omitInlineMedia } from "./media-placeholders.js";
5
+ import { RENDERED_COMPONENT_RECORD, SessionEventFanout, } from "./session-event-fanout.js";
6
+ export { RENDERED_COMPONENT_RECORD } from "./session-event-fanout.js";
4
7
  const MESSAGE_KEY = "message";
5
8
  const COMPACT_DELTA_TYPES = new Set(["text_delta", "thinking_delta", "toolcall_delta"]);
6
9
  function compactDelta(value) {
@@ -22,21 +25,30 @@ function compactDelta(value) {
22
25
  delta: typedEvent.delta,
23
26
  };
24
27
  }
28
+ /** The delta-only form of a compact message_update: cumulative snapshot fields blanked, delta kept. */
29
+ function demoteToDeltaOnly(value) {
30
+ const event = value.assistantMessageEvent;
31
+ return { ...value, message: null, assistantMessageEvent: { ...event, partial: null } };
32
+ }
25
33
  function toolUpdateKey(value) {
26
34
  return value.type === "tool_execution_update" && typeof value.toolCallId === "string"
27
35
  ? `tool:${value.toolCallId}`
28
36
  : undefined;
29
37
  }
30
- export const RENDERED_COMPONENT_RECORD = "__senpiRenderedComponent";
38
+ /**
39
+ * Process-wide stdout scheduler for multi-session RPC mode.
40
+ *
41
+ * Each queue contains complete structured JSONL records for one routing handle.
42
+ * Draining takes one record per queue in round-robin order and waits for stdout
43
+ * backpressure before selecting the next one. A record is deliberately written
44
+ * by itself: coalescing records from different sessions would obscure the
45
+ * scheduling boundary and violate D9.
46
+ */
31
47
  export class SessionEventWriter {
32
48
  constructor(writeRaw, waitOrSchedule, scheduleFlush) {
33
49
  this.queues = new Map();
34
- this.connections = new Map();
35
- this.sessionSnapshots = new Map();
50
+ this.fanout = new SessionEventFanout();
36
51
  this.connectionContext = new AsyncLocalStorage();
37
- this.connectionCapabilities = new Map();
38
- this.connectionSessions = new Map();
39
- this.registeredCapabilityConnections = new Set();
40
52
  this.controlQueue = { latestByKey: new Map(), ready: false };
41
53
  this.readyQueues = [];
42
54
  this.sealedSessions = new Set();
@@ -67,79 +79,32 @@ export class SessionEventWriter {
67
79
  }
68
80
  return bytes;
69
81
  }
70
- registerConnection(id, connection) {
71
- const actor = new SocketEventSinkActor(connection, () => {
72
- if (this.connections.get(id)?.actor === actor) {
73
- this.connections.delete(id);
74
- this.connectionCapabilities.delete(id);
75
- this.connectionSessions.delete(id);
76
- this.registeredCapabilityConnections.delete(id);
77
- }
78
- });
79
- this.connections.set(id, { connection, actor });
80
- this.connectionCapabilities.set(id, new Set());
81
- this.connectionSessions.set(id, new Set());
82
- for (const snapshot of this.sessionSnapshots.values())
83
- for (const record of snapshot)
84
- if (!record.rendered)
85
- actor.enqueue(record.line);
82
+ registerConnection(id, connection, options = {}) {
83
+ this.fanout.registerConnection(id, connection, options);
86
84
  }
87
85
  unregisterConnection(id) {
88
- const registered = this.connections.get(id);
89
- if (!registered)
90
- return;
91
- registered.actor.close();
92
- this.connections.delete(id);
93
- this.connectionCapabilities.delete(id);
94
- this.connectionSessions.delete(id);
95
- this.registeredCapabilityConnections.delete(id);
86
+ this.fanout.unregisterConnection(id);
96
87
  }
97
88
  attachConnectionToSession(id, sessionId) {
98
- if (!this.connections.has(id))
99
- return;
100
- const sessions = this.connectionSessions.get(id) ?? new Set();
101
- sessions.add(sessionId);
102
- this.connectionSessions.set(id, sessions);
103
- if (this.connectionCapabilities.get(id)?.has("rendered_components"))
104
- for (const record of this.sessionSnapshots.get(sessionId) ?? [])
105
- if (record.rendered)
106
- this.connections.get(id).actor.enqueue(record.line);
89
+ this.fanout.attachConnectionToSession(id, sessionId);
107
90
  }
108
91
  detachConnectionFromSession(id, sessionId) {
109
- this.connectionSessions.get(id)?.delete(sessionId);
92
+ this.fanout.detachConnectionFromSession(id, sessionId);
110
93
  }
111
94
  setConnectionCapabilities(id, capabilities) {
112
- const registered = this.connections.get(id);
113
- if (!registered)
114
- return;
115
- const wasCapable = this.connectionCapabilities.get(id)?.has("rendered_components") ?? false;
116
- this.connectionCapabilities.set(id, new Set(capabilities));
117
- this.registeredCapabilityConnections.add(id);
118
- if (!wasCapable && capabilities.includes("rendered_components"))
119
- for (const sessionId of this.connectionSessions.get(id) ?? [])
120
- for (const record of this.sessionSnapshots.get(sessionId) ?? [])
121
- if (record.rendered)
122
- registered.actor.enqueue(record.line);
95
+ this.fanout.setConnectionCapabilities(id, capabilities);
123
96
  }
124
97
  clearConnectionCapabilities(id) {
125
- if (this.connections.has(id)) {
126
- this.connectionCapabilities.set(id, new Set());
127
- this.registeredCapabilityConnections.delete(id);
128
- }
98
+ this.fanout.clearConnectionCapabilities(id);
129
99
  }
130
100
  hasRegisteredConnectionCapabilities(id) {
131
- return this.registeredCapabilityConnections.has(id);
101
+ return this.fanout.hasRegisteredConnectionCapabilities(id);
132
102
  }
133
103
  getConnectionCapabilities(id) {
134
- if (!this.registeredCapabilityConnections.has(id))
135
- return undefined;
136
- return [...(this.connectionCapabilities.get(id) ?? [])];
104
+ return this.fanout.getConnectionCapabilities(id);
137
105
  }
138
106
  hasCapableConnection(sessionId) {
139
- for (const [id, capabilities] of this.connectionCapabilities)
140
- if (capabilities.has("rendered_components") && this.connectionSessions.get(id)?.has(sessionId))
141
- return true;
142
- return false;
107
+ return this.fanout.hasCapableConnection(sessionId);
143
108
  }
144
109
  /** Execute a connection's command with its response destination in context. */
145
110
  withConnection(id, task) {
@@ -149,7 +114,7 @@ export class SessionEventWriter {
149
114
  currentConnection() {
150
115
  return this.connectionContext.getStore();
151
116
  }
152
- /** Queue a session record. Lifecycle/events are broadcast; responses/UI are targeted. */
117
+ /** Queue a session record. Content events target connections attached to the session. */
153
118
  enqueue(sessionId, value) {
154
119
  if (this.sealedSessions.has(sessionId))
155
120
  return false;
@@ -162,23 +127,25 @@ export class SessionEventWriter {
162
127
  const tagged = { ...value, sessionId };
163
128
  const { [RENDERED_COMPONENT_RECORD]: _rendered, ...wireTagged } = tagged;
164
129
  const line = serializeJsonLine(wireTagged);
165
- this.rememberSnapshot(sessionId, tagged, line);
166
- const targets = isTargeted
167
- ? [targetId]
168
- : record[RENDERED_COMPONENT_RECORD] && this.connections.size > 0
169
- ? [...this.connections.keys()].filter((id) => this.connectionCapabilities.get(id)?.has("rendered_components") &&
170
- this.connectionSessions.get(id)?.has(sessionId))
171
- : this.connections.size > 0
172
- ? [...this.connections.keys()]
173
- : [undefined];
130
+ const targets = this.fanout.targets(sessionId, targetId, isTargeted, record[RENDERED_COMPONENT_RECORD] === true, record.type);
131
+ // A record is only walked and re-serialized when a target asked for placeholders;
132
+ // otherwise this is byte-for-byte today's path, with serializeJsonLine called once.
133
+ const hasPlaceholderTarget = targets.some((target) => this.fanout.connectionHas(target, MEDIA_PLACEHOLDERS_CAPABILITY));
134
+ const redacted = hasPlaceholderTarget ? omitInlineMedia(wireTagged) : wireTagged;
135
+ const placeholderLine = redacted === wireTagged ? undefined : serializeJsonLine(redacted);
136
+ if (!isTargeted)
137
+ this.fanout.rememberSnapshot(sessionId, tagged, line, placeholderLine, wireTagged);
174
138
  for (const target of targets) {
175
- if (target !== undefined && !this.connections.has(target))
139
+ if (target !== undefined && !this.fanout.get(target))
176
140
  continue;
177
- const registered = target === undefined ? undefined : this.connections.get(target);
178
- if (registered)
179
- registered.actor.enqueue(line, compactDelta(tagged) && tagged.message !== null ? MESSAGE_KEY : undefined);
141
+ const registered = target === undefined ? undefined : this.fanout.get(target);
142
+ const wants = placeholderLine !== undefined && this.fanout.connectionHas(target, MEDIA_PLACEHOLDERS_CAPABILITY);
143
+ if (registered) {
144
+ const keyed = compactDelta(tagged) !== undefined && tagged.message !== null;
145
+ registered.actor.enqueue(wants ? placeholderLine : line, keyed ? MESSAGE_KEY : undefined, undefined, keyed ? serializeJsonLine(demoteToDeltaOnly(wireTagged)) : undefined);
146
+ }
180
147
  else
181
- this.appendSessionRecord(sessionId, wireTagged, target);
148
+ this.appendSessionRecord(sessionId, wants ? redacted : wireTagged, target);
182
149
  }
183
150
  this.requestFlush();
184
151
  return true;
@@ -188,7 +155,7 @@ export class SessionEventWriter {
188
155
  if (this.failure !== undefined)
189
156
  return Promise.reject(this.failure);
190
157
  const targetId = this.connectionContext.getStore();
191
- const registered = targetId === undefined ? undefined : this.connections.get(targetId);
158
+ const registered = targetId === undefined ? undefined : this.fanout.get(targetId);
192
159
  if (registered) {
193
160
  registered.actor.enqueue(serializeJsonLine(value));
194
161
  return Promise.resolve();
@@ -212,11 +179,23 @@ export class SessionEventWriter {
212
179
  this.sealedSessions.add(sessionId);
213
180
  const targetId = this.connectionContext.getStore();
214
181
  const lifecycle = { type: "session_closed", sessionId };
215
- for (const connectionId of this.connections.keys()) {
216
- this.connections.get(connectionId).actor.enqueue(serializeJsonLine(lifecycle));
217
- }
182
+ if (this.fanout.isEmpty())
183
+ this.appendSessionRecord(sessionId, lifecycle);
184
+ else
185
+ this.fanout.broadcast(serializeJsonLine(lifecycle));
218
186
  const taggedResponse = { ...response, sessionId };
219
- const registered = targetId === undefined ? undefined : this.connections.get(targetId);
187
+ const registered = targetId === undefined ? undefined : this.fanout.get(targetId);
188
+ if (registered)
189
+ registered.actor.enqueue(serializeJsonLine(taggedResponse));
190
+ else
191
+ this.appendSessionRecord(sessionId, taggedResponse, targetId);
192
+ this.requestFlush();
193
+ }
194
+ /** Queue a successful response for a joined close after the terminal lifecycle record. */
195
+ enqueueClosedResponse(sessionId, response) {
196
+ const targetId = this.connectionContext.getStore();
197
+ const taggedResponse = { ...response, sessionId };
198
+ const registered = targetId === undefined ? undefined : this.fanout.get(targetId);
220
199
  if (registered)
221
200
  registered.actor.enqueue(serializeJsonLine(taggedResponse));
222
201
  else
@@ -231,7 +210,7 @@ export class SessionEventWriter {
231
210
  */
232
211
  forgetSession(sessionId) {
233
212
  this.sealedSessions.delete(sessionId);
234
- this.sessionSnapshots.delete(sessionId);
213
+ this.fanout.forgetSession(sessionId);
235
214
  }
236
215
  /** Drain every retained lane and the current in-flight record. */
237
216
  flush() {
@@ -241,7 +220,7 @@ export class SessionEventWriter {
241
220
  if (this.drainPromise)
242
221
  return this.drainPromise;
243
222
  if (this.readyQueues.length === 0)
244
- return Promise.all([...this.connections.values()].map(({ actor }) => actor.flush())).then(() => undefined);
223
+ return Promise.all([...this.fanout.values()].map(({ actor }) => actor.flush())).then(() => undefined);
245
224
  let resolveDrain;
246
225
  let rejectDrain;
247
226
  const drain = new Promise((resolve, reject) => {
@@ -266,7 +245,7 @@ export class SessionEventWriter {
266
245
  do {
267
246
  await this.drainReadyQueues();
268
247
  } while (this.readyQueues.length > 0);
269
- await Promise.all([...this.connections.values()].map(({ actor }) => actor.flush()));
248
+ await Promise.all([...this.fanout.values()].map(({ actor }) => actor.flush()));
270
249
  }
271
250
  async drainReadyQueues() {
272
251
  while (this.readyQueues.length > 0) {
@@ -280,7 +259,7 @@ export class SessionEventWriter {
280
259
  try {
281
260
  // D9: exactly one complete record per raw write. The next lane is not
282
261
  // selected until this record has cleared stdout backpressure.
283
- const connection = queue.targetId ? this.connections.get(queue.targetId)?.connection : undefined;
262
+ const connection = queue.targetId ? this.fanout.get(queue.targetId)?.connection : undefined;
284
263
  const writeRaw = connection?.writeRaw ?? this.writeRaw;
285
264
  const waitForBackpressure = connection?.waitForBackpressure ?? this.waitForBackpressure;
286
265
  if (!connection && queue.targetId) {
@@ -311,18 +290,6 @@ export class SessionEventWriter {
311
290
  }
312
291
  }
313
292
  }
314
- rememberSnapshot(sessionId, value, line) {
315
- const event = value.assistantMessageEvent;
316
- const record = { line, rendered: value[RENDERED_COMPONENT_RECORD] === true };
317
- if (value.type === "message_start" || (value.type === "message_update" && event?.type === "text_start")) {
318
- this.sessionSnapshots.set(sessionId, [record]);
319
- }
320
- else if (this.sessionSnapshots.has(sessionId)) {
321
- this.sessionSnapshots.get(sessionId).push(record);
322
- }
323
- if (value.type === "message_end")
324
- this.sessionSnapshots.delete(sessionId);
325
- }
326
293
  connectionQueue(targetId) {
327
294
  const key = `connection:${targetId}`;
328
295
  let queue = this.queues.get(key);
@@ -367,12 +334,7 @@ export class SessionEventWriter {
367
334
  this.markReady(queue);
368
335
  }
369
336
  demoteAndMerge(queue, node) {
370
- const event = node.value.assistantMessageEvent;
371
- node.value = {
372
- ...node.value,
373
- message: null,
374
- assistantMessageEvent: { ...event, partial: null },
375
- };
337
+ node.value = demoteToDeltaOnly(node.value);
376
338
  const current = compactDelta(node.value);
377
339
  const preceding = node.previous;
378
340
  const previous = preceding ? compactDelta(preceding.value) : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"session-event-writer.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-event-writer.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { serializeJsonLine } from \"./jsonl.ts\";\nimport { SocketEventSinkActor } from \"./socket-event-fanout.ts\";\n\ntype RawWriter = (chunk: string) => void;\ntype BackpressureWaiter = () => Promise<void>;\ntype FlushScheduler = (flush: () => Promise<void>) => void;\ntype RpcRecord = Record<string, unknown>;\ntype CompactDeltaType = \"text_delta\" | \"thinking_delta\" | \"toolcall_delta\";\n\ntype QueueNode = {\n\tvalue: RpcRecord;\n\tkey?: string;\n\tprevious?: QueueNode;\n\tnext?: QueueNode;\n\tresolve?: () => void;\n\treject?: (cause: unknown) => void;\n};\n\ntype RecordQueue = {\n\tsessionId?: string;\n\ttargetId?: string;\n\thead?: QueueNode;\n\ttail?: QueueNode;\n\tlatestByKey: Map<string, QueueNode>;\n\tready: boolean;\n};\n\nconst MESSAGE_KEY = \"message\";\nconst COMPACT_DELTA_TYPES = new Set<CompactDeltaType>([\"text_delta\", \"thinking_delta\", \"toolcall_delta\"]);\n\nfunction compactDelta(value: RpcRecord): { type: CompactDeltaType; contentIndex: number; delta: string } | undefined {\n\tif (value.type !== \"message_update\" || !Object.hasOwn(value, \"message\")) return undefined;\n\tconst event = value.assistantMessageEvent;\n\tif (typeof event !== \"object\" || event === null) return undefined;\n\tconst typedEvent = event as Record<string, unknown>;\n\tif (\n\t\ttypeof typedEvent.type !== \"string\" ||\n\t\t!COMPACT_DELTA_TYPES.has(typedEvent.type as CompactDeltaType) ||\n\t\ttypeof typedEvent.contentIndex !== \"number\" ||\n\t\ttypeof typedEvent.delta !== \"string\"\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\ttype: typedEvent.type as CompactDeltaType,\n\t\tcontentIndex: typedEvent.contentIndex,\n\t\tdelta: typedEvent.delta,\n\t};\n}\n\nfunction toolUpdateKey(value: RpcRecord): string | undefined {\n\treturn value.type === \"tool_execution_update\" && typeof value.toolCallId === \"string\"\n\t\t? `tool:${value.toolCallId}`\n\t\t: undefined;\n}\n\n/**\n * Process-wide stdout scheduler for multi-session RPC mode.\n *\n * Each queue contains complete structured JSONL records for one routing handle.\n * Draining takes one record per queue in round-robin order and waits for stdout\n * backpressure before selecting the next one. A record is deliberately written\n * by itself: coalescing records from different sessions would obscure the\n * scheduling boundary and violate D9.\n */\nexport interface SessionEventWriterConnection {\n\treadonly writeRaw: RawWriter;\n\treadonly waitForBackpressure: BackpressureWaiter;\n}\n\nexport const RENDERED_COMPONENT_RECORD = \"__senpiRenderedComponent\";\n\nexport class SessionEventWriter {\n\tprivate readonly queues = new Map<string, RecordQueue>();\n\tprivate readonly connections = new Map<\n\t\tstring,\n\t\t{ connection: SessionEventWriterConnection; actor: SocketEventSinkActor }\n\t>();\n\tprivate readonly sessionSnapshots = new Map<string, Array<{ line: string; rendered: boolean }>>();\n\tprivate readonly connectionContext = new AsyncLocalStorage<string>();\n\tprivate readonly connectionCapabilities = new Map<string, Set<string>>();\n\tprivate readonly connectionSessions = new Map<string, Set<string>>();\n\tprivate readonly registeredCapabilityConnections = new Set<string>();\n\tprivate readonly controlQueue: RecordQueue = { latestByKey: new Map(), ready: false };\n\tprivate readonly readyQueues: RecordQueue[] = [];\n\tprivate readonly sealedSessions = new Set<string>();\n\tprivate readonly writeRaw: RawWriter;\n\tprivate readonly waitForBackpressure?: BackpressureWaiter;\n\tprivate readonly scheduleFlush: FlushScheduler;\n\tprivate flushScheduled = false;\n\tprivate drainPromise?: Promise<void>;\n\tprivate inFlight?: { queue: RecordQueue; node: QueueNode };\n\tprivate failure?: unknown;\n\n\tconstructor(writeRaw: RawWriter, scheduleFlush?: FlushScheduler);\n\tconstructor(writeRaw: RawWriter, waitForBackpressure: BackpressureWaiter, scheduleFlush?: FlushScheduler);\n\tconstructor(\n\t\twriteRaw: RawWriter,\n\t\twaitOrSchedule?: BackpressureWaiter | FlushScheduler,\n\t\tscheduleFlush?: FlushScheduler,\n\t) {\n\t\tthis.writeRaw = writeRaw;\n\t\tif (waitOrSchedule && scheduleFlush === undefined && waitOrSchedule.length > 0) {\n\t\t\tthis.scheduleFlush = waitOrSchedule as FlushScheduler;\n\t\t} else {\n\t\t\tthis.waitForBackpressure = waitOrSchedule as BackpressureWaiter | undefined;\n\t\t\tthis.scheduleFlush = scheduleFlush ?? ((flush) => queueMicrotask(() => void flush()));\n\t\t}\n\t}\n\n\tget bufferedRecordCount(): number {\n\t\tlet count = this.inFlight ? 1 : 0;\n\t\tfor (const queue of this.allQueues()) {\n\t\t\tfor (let node = queue.head; node; node = node.next) count++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tget bufferedByteLength(): number {\n\t\tlet bytes = this.inFlight ? Buffer.byteLength(serializeJsonLine(this.inFlight.node.value)) : 0;\n\t\tfor (const queue of this.allQueues()) {\n\t\t\tfor (let node = queue.head; node; node = node.next) {\n\t\t\t\tbytes += Buffer.byteLength(serializeJsonLine(node.value));\n\t\t\t}\n\t\t}\n\t\treturn bytes;\n\t}\n\n\tregisterConnection(id: string, connection: SessionEventWriterConnection): void {\n\t\tconst actor = new SocketEventSinkActor(connection, () => {\n\t\t\tif (this.connections.get(id)?.actor === actor) {\n\t\t\t\tthis.connections.delete(id);\n\t\t\t\tthis.connectionCapabilities.delete(id);\n\t\t\t\tthis.connectionSessions.delete(id);\n\t\t\t\tthis.registeredCapabilityConnections.delete(id);\n\t\t\t}\n\t\t});\n\t\tthis.connections.set(id, { connection, actor });\n\t\tthis.connectionCapabilities.set(id, new Set());\n\t\tthis.connectionSessions.set(id, new Set());\n\t\tfor (const snapshot of this.sessionSnapshots.values())\n\t\t\tfor (const record of snapshot) if (!record.rendered) actor.enqueue(record.line);\n\t}\n\n\tunregisterConnection(id: string): void {\n\t\tconst registered = this.connections.get(id);\n\t\tif (!registered) return;\n\t\tregistered.actor.close();\n\t\tthis.connections.delete(id);\n\t\tthis.connectionCapabilities.delete(id);\n\t\tthis.connectionSessions.delete(id);\n\t\tthis.registeredCapabilityConnections.delete(id);\n\t}\n\n\tattachConnectionToSession(id: string, sessionId: string): void {\n\t\tif (!this.connections.has(id)) return;\n\t\tconst sessions = this.connectionSessions.get(id) ?? new Set<string>();\n\t\tsessions.add(sessionId);\n\t\tthis.connectionSessions.set(id, sessions);\n\t\tif (this.connectionCapabilities.get(id)?.has(\"rendered_components\"))\n\t\t\tfor (const record of this.sessionSnapshots.get(sessionId) ?? [])\n\t\t\t\tif (record.rendered) this.connections.get(id)!.actor.enqueue(record.line);\n\t}\n\n\tdetachConnectionFromSession(id: string, sessionId: string): void {\n\t\tthis.connectionSessions.get(id)?.delete(sessionId);\n\t}\n\n\tsetConnectionCapabilities(id: string, capabilities: readonly string[]): void {\n\t\tconst registered = this.connections.get(id);\n\t\tif (!registered) return;\n\t\tconst wasCapable = this.connectionCapabilities.get(id)?.has(\"rendered_components\") ?? false;\n\t\tthis.connectionCapabilities.set(id, new Set(capabilities));\n\t\tthis.registeredCapabilityConnections.add(id);\n\t\tif (!wasCapable && capabilities.includes(\"rendered_components\"))\n\t\t\tfor (const sessionId of this.connectionSessions.get(id) ?? [])\n\t\t\t\tfor (const record of this.sessionSnapshots.get(sessionId) ?? [])\n\t\t\t\t\tif (record.rendered) registered.actor.enqueue(record.line);\n\t}\n\n\tclearConnectionCapabilities(id: string): void {\n\t\tif (this.connections.has(id)) {\n\t\t\tthis.connectionCapabilities.set(id, new Set());\n\t\t\tthis.registeredCapabilityConnections.delete(id);\n\t\t}\n\t}\n\n\thasRegisteredConnectionCapabilities(id: string): boolean {\n\t\treturn this.registeredCapabilityConnections.has(id);\n\t}\n\n\tgetConnectionCapabilities(id: string): readonly string[] | undefined {\n\t\tif (!this.registeredCapabilityConnections.has(id)) return undefined;\n\t\treturn [...(this.connectionCapabilities.get(id) ?? [])];\n\t}\n\n\thasCapableConnection(sessionId: string): boolean {\n\t\tfor (const [id, capabilities] of this.connectionCapabilities)\n\t\t\tif (capabilities.has(\"rendered_components\") && this.connectionSessions.get(id)?.has(sessionId)) return true;\n\t\treturn false;\n\t}\n\n\t/** Execute a connection's command with its response destination in context. */\n\twithConnection<T>(id: string, task: () => T): T {\n\t\treturn this.connectionContext.run(id, task);\n\t}\n\n\t/** Connection id of the command currently being dispatched, when one owns it. */\n\tcurrentConnection(): string | undefined {\n\t\treturn this.connectionContext.getStore();\n\t}\n\n\t/** Queue a session record. Lifecycle/events are broadcast; responses/UI are targeted. */\n\tenqueue(sessionId: string, value: object): boolean {\n\t\tif (this.sealedSessions.has(sessionId)) return false;\n\t\tconst targetId = this.connectionContext.getStore();\n\t\tconst record = value as RpcRecord;\n\t\tconst isTargeted =\n\t\t\trecord.type === \"response\" ||\n\t\t\trecord.type === \"bash_execution_update\" ||\n\t\t\t(record.type === \"extension_ui_request\" &&\n\t\t\t\t[\"select\", \"confirm\", \"input\", \"editor\"].includes(String(record.method)));\n\t\tconst tagged = { ...value, sessionId } as RpcRecord;\n\t\tconst { [RENDERED_COMPONENT_RECORD]: _rendered, ...wireTagged } = tagged;\n\t\tconst line = serializeJsonLine(wireTagged);\n\t\tthis.rememberSnapshot(sessionId, tagged, line);\n\t\tconst targets = isTargeted\n\t\t\t? [targetId]\n\t\t\t: record[RENDERED_COMPONENT_RECORD] && this.connections.size > 0\n\t\t\t\t? [...this.connections.keys()].filter(\n\t\t\t\t\t\t(id) =>\n\t\t\t\t\t\t\tthis.connectionCapabilities.get(id)?.has(\"rendered_components\") &&\n\t\t\t\t\t\t\tthis.connectionSessions.get(id)?.has(sessionId),\n\t\t\t\t\t)\n\t\t\t\t: this.connections.size > 0\n\t\t\t\t\t? [...this.connections.keys()]\n\t\t\t\t\t: [undefined];\n\t\tfor (const target of targets) {\n\t\t\tif (target !== undefined && !this.connections.has(target)) continue;\n\t\t\tconst registered = target === undefined ? undefined : this.connections.get(target);\n\t\t\tif (registered)\n\t\t\t\tregistered.actor.enqueue(line, compactDelta(tagged) && tagged.message !== null ? MESSAGE_KEY : undefined);\n\t\t\telse this.appendSessionRecord(sessionId, wireTagged, target);\n\t\t}\n\t\tthis.requestFlush();\n\t\treturn true;\n\t}\n\n\t/** Queue one untagged host-control response for the current connection. */\n\tenqueueControl(value: object): Promise<void> {\n\t\tif (this.failure !== undefined) return Promise.reject(this.failure);\n\t\tconst targetId = this.connectionContext.getStore();\n\t\tconst registered = targetId === undefined ? undefined : this.connections.get(targetId);\n\t\tif (registered) {\n\t\t\tregistered.actor.enqueue(serializeJsonLine(value));\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\tconst queue = targetId === undefined ? this.controlQueue : this.connectionQueue(targetId);\n\t\tconst completion = new Promise<void>((resolve, reject) => {\n\t\t\tthis.append(queue, { ...value }, undefined, resolve, reject);\n\t\t});\n\t\tthis.markReady(queue);\n\t\tthis.requestFlush();\n\t\treturn completion;\n\t}\n\n\t/**\n\t * Prevent subsequent records for a session and append its terminal response.\n\t * Existing records retain FIFO order; this response is therefore that\n\t * session's final stdout record.\n\t */\n\tcloseSession(sessionId: string, response: object): void {\n\t\tif (this.sealedSessions.has(sessionId)) return;\n\t\tthis.sealedSessions.add(sessionId);\n\t\tconst targetId = this.connectionContext.getStore();\n\t\tconst lifecycle = { type: \"session_closed\", sessionId };\n\t\tfor (const connectionId of this.connections.keys()) {\n\t\t\tthis.connections.get(connectionId)!.actor.enqueue(serializeJsonLine(lifecycle));\n\t\t}\n\t\tconst taggedResponse = { ...response, sessionId };\n\t\tconst registered = targetId === undefined ? undefined : this.connections.get(targetId);\n\t\tif (registered) registered.actor.enqueue(serializeJsonLine(taggedResponse));\n\t\telse this.appendSessionRecord(sessionId, taggedResponse, targetId);\n\t\tthis.requestFlush();\n\t}\n\n\t/**\n\t * Drops per-session bookkeeping for a handle whose runtime is fully disposed.\n\t * Routing handles are unique per process epoch, so nothing can legitimately\n\t * emit under this id again; without this every host-closed session would\n\t * leave a permanent sealed-handle (and snapshot) entry behind.\n\t */\n\tforgetSession(sessionId: string): void {\n\t\tthis.sealedSessions.delete(sessionId);\n\t\tthis.sessionSnapshots.delete(sessionId);\n\t}\n\n\t/** Drain every retained lane and the current in-flight record. */\n\tflush(): Promise<void> {\n\t\tif (this.failure !== undefined) return Promise.reject(this.failure);\n\t\tthis.flushScheduled = false;\n\t\tif (this.drainPromise) return this.drainPromise;\n\t\tif (this.readyQueues.length === 0)\n\t\t\treturn Promise.all([...this.connections.values()].map(({ actor }) => actor.flush())).then(() => undefined);\n\t\tlet resolveDrain!: () => void;\n\t\tlet rejectDrain!: (cause: unknown) => void;\n\t\tconst drain = new Promise<void>((resolve, reject) => {\n\t\t\tresolveDrain = resolve;\n\t\t\trejectDrain = reject;\n\t\t});\n\t\tthis.drainPromise = drain;\n\t\tvoid this.drainUntilEmpty().then(resolveDrain, rejectDrain);\n\t\tvoid drain.then(\n\t\t\t() => {\n\t\t\t\tif (this.drainPromise === drain) this.drainPromise = undefined;\n\t\t\t\tif (this.readyQueues.length > 0) this.requestFlush();\n\t\t\t},\n\t\t\t(cause) => {\n\t\t\t\tif (this.drainPromise === drain) this.drainPromise = undefined;\n\t\t\t\tthis.fail(cause);\n\t\t\t},\n\t\t);\n\t\treturn drain;\n\t}\n\n\tprivate async drainUntilEmpty(): Promise<void> {\n\t\tdo {\n\t\t\tawait this.drainReadyQueues();\n\t\t} while (this.readyQueues.length > 0);\n\t\tawait Promise.all([...this.connections.values()].map(({ actor }) => actor.flush()));\n\t}\n\n\tprivate async drainReadyQueues(): Promise<void> {\n\t\twhile (this.readyQueues.length > 0) {\n\t\t\tconst queue = this.readyQueues.shift()!;\n\t\t\tqueue.ready = false;\n\t\t\tconst node = queue.head;\n\t\t\tif (!node) continue;\n\n\t\t\tthis.unlink(queue, node);\n\t\t\tthis.inFlight = { queue, node };\n\t\t\ttry {\n\t\t\t\t// D9: exactly one complete record per raw write. The next lane is not\n\t\t\t\t// selected until this record has cleared stdout backpressure.\n\t\t\t\tconst connection = queue.targetId ? this.connections.get(queue.targetId)?.connection : undefined;\n\t\t\t\tconst writeRaw = connection?.writeRaw ?? this.writeRaw;\n\t\t\t\tconst waitForBackpressure = connection?.waitForBackpressure ?? this.waitForBackpressure;\n\t\t\t\tif (!connection && queue.targetId) {\n\t\t\t\t\tnode.resolve?.();\n\t\t\t\t} else {\n\t\t\t\t\twriteRaw(serializeJsonLine(node.value));\n\t\t\t\t\tif (waitForBackpressure) await waitForBackpressure();\n\t\t\t\t\tnode.resolve?.();\n\t\t\t\t}\n\t\t\t} catch (cause) {\n\t\t\t\tnode.reject?.(cause);\n\t\t\t\tthrow cause;\n\t\t\t} finally {\n\t\t\t\tthis.inFlight = undefined;\n\t\t\t}\n\n\t\t\tif (queue.head) {\n\t\t\t\tthis.markReady(queue);\n\t\t\t} else if (queue.sessionId || queue.targetId) {\n\t\t\t\tfor (const [key, candidate] of this.queues) {\n\t\t\t\t\tif (candidate === queue) this.queues.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate rememberSnapshot(sessionId: string, value: RpcRecord, line: string): void {\n\t\tconst event = value.assistantMessageEvent as Record<string, unknown> | undefined;\n\t\tconst record = { line, rendered: value[RENDERED_COMPONENT_RECORD] === true };\n\t\tif (value.type === \"message_start\" || (value.type === \"message_update\" && event?.type === \"text_start\")) {\n\t\t\tthis.sessionSnapshots.set(sessionId, [record]);\n\t\t} else if (this.sessionSnapshots.has(sessionId)) {\n\t\t\tthis.sessionSnapshots.get(sessionId)!.push(record);\n\t\t}\n\t\tif (value.type === \"message_end\") this.sessionSnapshots.delete(sessionId);\n\t}\n\n\tprivate connectionQueue(targetId: string): RecordQueue {\n\t\tconst key = `connection:${targetId}`;\n\t\tlet queue = this.queues.get(key);\n\t\tif (!queue) {\n\t\t\tqueue = { targetId, latestByKey: new Map(), ready: false };\n\t\t\tthis.queues.set(key, queue);\n\t\t}\n\t\treturn queue;\n\t}\n\n\tprivate appendSessionRecord(sessionId: string, value: RpcRecord, targetId?: string): void {\n\t\tconst key = `${targetId ?? \"default\"}:${sessionId}`;\n\t\tlet queue = this.queues.get(key);\n\t\tif (!queue) {\n\t\t\tqueue = { sessionId, targetId, latestByKey: new Map(), ready: false };\n\t\t\tthis.queues.set(key, queue);\n\t\t}\n\n\t\tconst delta = compactDelta(value);\n\t\tif (delta) {\n\t\t\tconst previousFull = queue.latestByKey.get(MESSAGE_KEY);\n\t\t\tif (previousFull) this.demoteAndMerge(queue, previousFull);\n\t\t\tconst node = this.append(queue, value, MESSAGE_KEY);\n\t\t\tqueue.latestByKey.set(MESSAGE_KEY, node);\n\t\t\tthis.markReady(queue);\n\t\t\treturn;\n\t\t}\n\n\t\tconst toolKey = toolUpdateKey(value);\n\t\tif (toolKey) {\n\t\t\tconst previous = queue.latestByKey.get(toolKey);\n\t\t\tif (previous) this.unlink(queue, previous);\n\t\t\tconst node = this.append(queue, value, toolKey);\n\t\t\tqueue.latestByKey.set(toolKey, node);\n\t\t\tthis.markReady(queue);\n\t\t\treturn;\n\t\t}\n\n\t\t// All non-compactable records are ordering barriers. In particular this\n\t\t// includes delta-only/full non-delta message updates, protocol responses,\n\t\t// extension UI requests, errors, retries, lifecycle, and unknown records.\n\t\tqueue.latestByKey.clear();\n\t\tthis.append(queue, value);\n\t\tthis.markReady(queue);\n\t}\n\n\tprivate demoteAndMerge(queue: RecordQueue, node: QueueNode): void {\n\t\tconst event = node.value.assistantMessageEvent as Record<string, unknown>;\n\t\tnode.value = {\n\t\t\t...node.value,\n\t\t\tmessage: null,\n\t\t\tassistantMessageEvent: { ...event, partial: null },\n\t\t};\n\t\tconst current = compactDelta(node.value);\n\t\tconst preceding = node.previous;\n\t\tconst previous = preceding ? compactDelta(preceding.value) : undefined;\n\t\tif (\n\t\t\tpreceding &&\n\t\t\tprevious &&\n\t\t\tcurrent &&\n\t\t\tpreceding.value.message === null &&\n\t\t\tprevious.type === current.type &&\n\t\t\tprevious.contentIndex === current.contentIndex\n\t\t) {\n\t\t\tconst precedingEvent = preceding.value.assistantMessageEvent as Record<string, unknown>;\n\t\t\tpreceding.value = {\n\t\t\t\t...preceding.value,\n\t\t\t\tassistantMessageEvent: { ...precedingEvent, delta: previous.delta + current.delta },\n\t\t\t};\n\t\t\tthis.unlink(queue, node);\n\t\t}\n\t}\n\n\tprivate append(\n\t\tqueue: RecordQueue,\n\t\tvalue: RpcRecord,\n\t\tkey?: string,\n\t\tresolve?: () => void,\n\t\treject?: (cause: unknown) => void,\n\t): QueueNode {\n\t\tconst node: QueueNode = { value, key, previous: queue.tail, resolve, reject };\n\t\tif (queue.tail) queue.tail.next = node;\n\t\telse queue.head = node;\n\t\tqueue.tail = node;\n\t\treturn node;\n\t}\n\n\tprivate unlink(queue: RecordQueue, node: QueueNode): void {\n\t\tif (node.previous) node.previous.next = node.next;\n\t\telse queue.head = node.next;\n\t\tif (node.next) node.next.previous = node.previous;\n\t\telse queue.tail = node.previous;\n\t\tif (node.key && queue.latestByKey.get(node.key) === node) queue.latestByKey.delete(node.key);\n\t\tnode.previous = undefined;\n\t\tnode.next = undefined;\n\t}\n\n\tprivate markReady(queue: RecordQueue): void {\n\t\tif (queue.ready || this.inFlight?.queue === queue || !queue.head) return;\n\t\tqueue.ready = true;\n\t\tthis.readyQueues.push(queue);\n\t}\n\n\tprivate requestFlush(): void {\n\t\tif (this.failure !== undefined || this.flushScheduled || this.drainPromise) return;\n\t\tthis.flushScheduled = true;\n\t\tthis.scheduleFlush(() => this.flush());\n\t}\n\n\tprivate fail(cause: unknown): void {\n\t\tif (this.failure !== undefined) return;\n\t\tthis.failure = cause;\n\t\tfor (const queue of this.allQueues()) {\n\t\t\tfor (let node = queue.head; node; node = node.next) node.reject?.(cause);\n\t\t}\n\t}\n\n\tprivate *allQueues(): Iterable<RecordQueue> {\n\t\tyield* this.queues.values();\n\t\tyield this.controlQueue;\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-event-writer.js","sourceRoot":"","sources":["../../../src/modes/rpc/session-event-writer.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { MEDIA_PLACEHOLDERS_CAPABILITY } from \"./custom-capability.ts\";\nimport { serializeJsonLine } from \"./jsonl.ts\";\nimport { omitInlineMedia } from \"./media-placeholders.ts\";\nimport {\n\tRENDERED_COMPONENT_RECORD,\n\tSessionEventFanout,\n\ttype SessionEventWriterConnection,\n} from \"./session-event-fanout.ts\";\n\nexport { RENDERED_COMPONENT_RECORD, type SessionEventWriterConnection } from \"./session-event-fanout.ts\";\n\ntype RawWriter = (chunk: string) => void;\ntype BackpressureWaiter = () => Promise<void>;\ntype FlushScheduler = (flush: () => Promise<void>) => void;\ntype RpcRecord = Record<string, unknown>;\ntype CompactDeltaType = \"text_delta\" | \"thinking_delta\" | \"toolcall_delta\";\n\ntype QueueNode = {\n\tvalue: RpcRecord;\n\tkey?: string;\n\tprevious?: QueueNode;\n\tnext?: QueueNode;\n\tresolve?: () => void;\n\treject?: (cause: unknown) => void;\n};\n\ntype RecordQueue = {\n\tsessionId?: string;\n\ttargetId?: string;\n\thead?: QueueNode;\n\ttail?: QueueNode;\n\tlatestByKey: Map<string, QueueNode>;\n\tready: boolean;\n};\n\nconst MESSAGE_KEY = \"message\";\nconst COMPACT_DELTA_TYPES = new Set<CompactDeltaType>([\"text_delta\", \"thinking_delta\", \"toolcall_delta\"]);\n\nfunction compactDelta(value: RpcRecord): { type: CompactDeltaType; contentIndex: number; delta: string } | undefined {\n\tif (value.type !== \"message_update\" || !Object.hasOwn(value, \"message\")) return undefined;\n\tconst event = value.assistantMessageEvent;\n\tif (typeof event !== \"object\" || event === null) return undefined;\n\tconst typedEvent = event as Record<string, unknown>;\n\tif (\n\t\ttypeof typedEvent.type !== \"string\" ||\n\t\t!COMPACT_DELTA_TYPES.has(typedEvent.type as CompactDeltaType) ||\n\t\ttypeof typedEvent.contentIndex !== \"number\" ||\n\t\ttypeof typedEvent.delta !== \"string\"\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\ttype: typedEvent.type as CompactDeltaType,\n\t\tcontentIndex: typedEvent.contentIndex,\n\t\tdelta: typedEvent.delta,\n\t};\n}\n\n/** The delta-only form of a compact message_update: cumulative snapshot fields blanked, delta kept. */\nfunction demoteToDeltaOnly(value: RpcRecord): RpcRecord {\n\tconst event = value.assistantMessageEvent as Record<string, unknown>;\n\treturn { ...value, message: null, assistantMessageEvent: { ...event, partial: null } };\n}\n\nfunction toolUpdateKey(value: RpcRecord): string | undefined {\n\treturn value.type === \"tool_execution_update\" && typeof value.toolCallId === \"string\"\n\t\t? `tool:${value.toolCallId}`\n\t\t: undefined;\n}\n\n/**\n * Process-wide stdout scheduler for multi-session RPC mode.\n *\n * Each queue contains complete structured JSONL records for one routing handle.\n * Draining takes one record per queue in round-robin order and waits for stdout\n * backpressure before selecting the next one. A record is deliberately written\n * by itself: coalescing records from different sessions would obscure the\n * scheduling boundary and violate D9.\n */\nexport class SessionEventWriter {\n\tprivate readonly queues = new Map<string, RecordQueue>();\n\tprivate readonly fanout = new SessionEventFanout();\n\tprivate readonly connectionContext = new AsyncLocalStorage<string>();\n\tprivate readonly controlQueue: RecordQueue = { latestByKey: new Map(), ready: false };\n\tprivate readonly readyQueues: RecordQueue[] = [];\n\tprivate readonly sealedSessions = new Set<string>();\n\tprivate readonly writeRaw: RawWriter;\n\tprivate readonly waitForBackpressure?: BackpressureWaiter;\n\tprivate readonly scheduleFlush: FlushScheduler;\n\tprivate flushScheduled = false;\n\tprivate drainPromise?: Promise<void>;\n\tprivate inFlight?: { queue: RecordQueue; node: QueueNode };\n\tprivate failure?: unknown;\n\n\tconstructor(writeRaw: RawWriter, scheduleFlush?: FlushScheduler);\n\tconstructor(writeRaw: RawWriter, waitForBackpressure: BackpressureWaiter, scheduleFlush?: FlushScheduler);\n\tconstructor(\n\t\twriteRaw: RawWriter,\n\t\twaitOrSchedule?: BackpressureWaiter | FlushScheduler,\n\t\tscheduleFlush?: FlushScheduler,\n\t) {\n\t\tthis.writeRaw = writeRaw;\n\t\tif (waitOrSchedule && scheduleFlush === undefined && waitOrSchedule.length > 0) {\n\t\t\tthis.scheduleFlush = waitOrSchedule as FlushScheduler;\n\t\t} else {\n\t\t\tthis.waitForBackpressure = waitOrSchedule as BackpressureWaiter | undefined;\n\t\t\tthis.scheduleFlush = scheduleFlush ?? ((flush) => queueMicrotask(() => void flush()));\n\t\t}\n\t}\n\n\tget bufferedRecordCount(): number {\n\t\tlet count = this.inFlight ? 1 : 0;\n\t\tfor (const queue of this.allQueues()) {\n\t\t\tfor (let node = queue.head; node; node = node.next) count++;\n\t\t}\n\t\treturn count;\n\t}\n\n\tget bufferedByteLength(): number {\n\t\tlet bytes = this.inFlight ? Buffer.byteLength(serializeJsonLine(this.inFlight.node.value)) : 0;\n\t\tfor (const queue of this.allQueues()) {\n\t\t\tfor (let node = queue.head; node; node = node.next) {\n\t\t\t\tbytes += Buffer.byteLength(serializeJsonLine(node.value));\n\t\t\t}\n\t\t}\n\t\treturn bytes;\n\t}\n\n\tregisterConnection(\n\t\tid: string,\n\t\tconnection: SessionEventWriterConnection,\n\t\toptions: { readonly maxQueueBytes?: number } = {},\n\t): void {\n\t\tthis.fanout.registerConnection(id, connection, options);\n\t}\n\n\tunregisterConnection(id: string): void {\n\t\tthis.fanout.unregisterConnection(id);\n\t}\n\n\tattachConnectionToSession(id: string, sessionId: string): void {\n\t\tthis.fanout.attachConnectionToSession(id, sessionId);\n\t}\n\n\tdetachConnectionFromSession(id: string, sessionId: string): void {\n\t\tthis.fanout.detachConnectionFromSession(id, sessionId);\n\t}\n\n\tsetConnectionCapabilities(id: string, capabilities: readonly string[]): void {\n\t\tthis.fanout.setConnectionCapabilities(id, capabilities);\n\t}\n\n\tclearConnectionCapabilities(id: string): void {\n\t\tthis.fanout.clearConnectionCapabilities(id);\n\t}\n\n\thasRegisteredConnectionCapabilities(id: string): boolean {\n\t\treturn this.fanout.hasRegisteredConnectionCapabilities(id);\n\t}\n\n\tgetConnectionCapabilities(id: string): readonly string[] | undefined {\n\t\treturn this.fanout.getConnectionCapabilities(id);\n\t}\n\n\thasCapableConnection(sessionId: string): boolean {\n\t\treturn this.fanout.hasCapableConnection(sessionId);\n\t}\n\n\t/** Execute a connection's command with its response destination in context. */\n\twithConnection<T>(id: string, task: () => T): T {\n\t\treturn this.connectionContext.run(id, task);\n\t}\n\n\t/** Connection id of the command currently being dispatched, when one owns it. */\n\tcurrentConnection(): string | undefined {\n\t\treturn this.connectionContext.getStore();\n\t}\n\n\t/** Queue a session record. Content events target connections attached to the session. */\n\tenqueue(sessionId: string, value: object): boolean {\n\t\tif (this.sealedSessions.has(sessionId)) return false;\n\t\tconst targetId = this.connectionContext.getStore();\n\t\tconst record = value as RpcRecord;\n\t\tconst isTargeted =\n\t\t\trecord.type === \"response\" ||\n\t\t\trecord.type === \"bash_execution_update\" ||\n\t\t\t(record.type === \"extension_ui_request\" &&\n\t\t\t\t[\"select\", \"confirm\", \"input\", \"editor\"].includes(String(record.method)));\n\t\tconst tagged = { ...value, sessionId } as RpcRecord;\n\t\tconst { [RENDERED_COMPONENT_RECORD]: _rendered, ...wireTagged } = tagged;\n\t\tconst line = serializeJsonLine(wireTagged);\n\t\tconst targets = this.fanout.targets(\n\t\t\tsessionId,\n\t\t\ttargetId,\n\t\t\tisTargeted,\n\t\t\trecord[RENDERED_COMPONENT_RECORD] === true,\n\t\t\trecord.type,\n\t\t);\n\t\t// A record is only walked and re-serialized when a target asked for placeholders;\n\t\t// otherwise this is byte-for-byte today's path, with serializeJsonLine called once.\n\t\tconst hasPlaceholderTarget = targets.some((target) =>\n\t\t\tthis.fanout.connectionHas(target, MEDIA_PLACEHOLDERS_CAPABILITY),\n\t\t);\n\t\tconst redacted = hasPlaceholderTarget ? omitInlineMedia(wireTagged) : wireTagged;\n\t\tconst placeholderLine = redacted === wireTagged ? undefined : serializeJsonLine(redacted);\n\t\tif (!isTargeted) this.fanout.rememberSnapshot(sessionId, tagged, line, placeholderLine, wireTagged);\n\t\tfor (const target of targets) {\n\t\t\tif (target !== undefined && !this.fanout.get(target)) continue;\n\t\t\tconst registered = target === undefined ? undefined : this.fanout.get(target);\n\t\t\tconst wants =\n\t\t\t\tplaceholderLine !== undefined && this.fanout.connectionHas(target, MEDIA_PLACEHOLDERS_CAPABILITY);\n\t\t\tif (registered) {\n\t\t\t\tconst keyed = compactDelta(tagged) !== undefined && tagged.message !== null;\n\t\t\t\tregistered.actor.enqueue(\n\t\t\t\t\twants ? placeholderLine : line,\n\t\t\t\t\tkeyed ? MESSAGE_KEY : undefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\tkeyed ? serializeJsonLine(demoteToDeltaOnly(wireTagged)) : undefined,\n\t\t\t\t);\n\t\t\t} else this.appendSessionRecord(sessionId, wants ? (redacted as RpcRecord) : wireTagged, target);\n\t\t}\n\t\tthis.requestFlush();\n\t\treturn true;\n\t}\n\n\t/** Queue one untagged host-control response for the current connection. */\n\tenqueueControl(value: object): Promise<void> {\n\t\tif (this.failure !== undefined) return Promise.reject(this.failure);\n\t\tconst targetId = this.connectionContext.getStore();\n\t\tconst registered = targetId === undefined ? undefined : this.fanout.get(targetId);\n\t\tif (registered) {\n\t\t\tregistered.actor.enqueue(serializeJsonLine(value));\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\tconst queue = targetId === undefined ? this.controlQueue : this.connectionQueue(targetId);\n\t\tconst completion = new Promise<void>((resolve, reject) => {\n\t\t\tthis.append(queue, { ...value }, undefined, resolve, reject);\n\t\t});\n\t\tthis.markReady(queue);\n\t\tthis.requestFlush();\n\t\treturn completion;\n\t}\n\n\t/**\n\t * Prevent subsequent records for a session and append its terminal response.\n\t * Existing records retain FIFO order; this response is therefore that\n\t * session's final stdout record.\n\t */\n\tcloseSession(sessionId: string, response: object): void {\n\t\tif (this.sealedSessions.has(sessionId)) return;\n\t\tthis.sealedSessions.add(sessionId);\n\t\tconst targetId = this.connectionContext.getStore();\n\t\tconst lifecycle = { type: \"session_closed\", sessionId };\n\t\tif (this.fanout.isEmpty()) this.appendSessionRecord(sessionId, lifecycle);\n\t\telse this.fanout.broadcast(serializeJsonLine(lifecycle));\n\t\tconst taggedResponse = { ...response, sessionId };\n\t\tconst registered = targetId === undefined ? undefined : this.fanout.get(targetId);\n\t\tif (registered) registered.actor.enqueue(serializeJsonLine(taggedResponse));\n\t\telse this.appendSessionRecord(sessionId, taggedResponse, targetId);\n\t\tthis.requestFlush();\n\t}\n\n\t/** Queue a successful response for a joined close after the terminal lifecycle record. */\n\tenqueueClosedResponse(sessionId: string, response: object): void {\n\t\tconst targetId = this.connectionContext.getStore();\n\t\tconst taggedResponse = { ...response, sessionId };\n\t\tconst registered = targetId === undefined ? undefined : this.fanout.get(targetId);\n\t\tif (registered) registered.actor.enqueue(serializeJsonLine(taggedResponse));\n\t\telse this.appendSessionRecord(sessionId, taggedResponse, targetId);\n\t\tthis.requestFlush();\n\t}\n\n\t/**\n\t * Drops per-session bookkeeping for a handle whose runtime is fully disposed.\n\t * Routing handles are unique per process epoch, so nothing can legitimately\n\t * emit under this id again; without this every host-closed session would\n\t * leave a permanent sealed-handle (and snapshot) entry behind.\n\t */\n\tforgetSession(sessionId: string): void {\n\t\tthis.sealedSessions.delete(sessionId);\n\t\tthis.fanout.forgetSession(sessionId);\n\t}\n\n\t/** Drain every retained lane and the current in-flight record. */\n\tflush(): Promise<void> {\n\t\tif (this.failure !== undefined) return Promise.reject(this.failure);\n\t\tthis.flushScheduled = false;\n\t\tif (this.drainPromise) return this.drainPromise;\n\t\tif (this.readyQueues.length === 0)\n\t\t\treturn Promise.all([...this.fanout.values()].map(({ actor }) => actor.flush())).then(() => undefined);\n\t\tlet resolveDrain!: () => void;\n\t\tlet rejectDrain!: (cause: unknown) => void;\n\t\tconst drain = new Promise<void>((resolve, reject) => {\n\t\t\tresolveDrain = resolve;\n\t\t\trejectDrain = reject;\n\t\t});\n\t\tthis.drainPromise = drain;\n\t\tvoid this.drainUntilEmpty().then(resolveDrain, rejectDrain);\n\t\tvoid drain.then(\n\t\t\t() => {\n\t\t\t\tif (this.drainPromise === drain) this.drainPromise = undefined;\n\t\t\t\tif (this.readyQueues.length > 0) this.requestFlush();\n\t\t\t},\n\t\t\t(cause) => {\n\t\t\t\tif (this.drainPromise === drain) this.drainPromise = undefined;\n\t\t\t\tthis.fail(cause);\n\t\t\t},\n\t\t);\n\t\treturn drain;\n\t}\n\n\tprivate async drainUntilEmpty(): Promise<void> {\n\t\tdo {\n\t\t\tawait this.drainReadyQueues();\n\t\t} while (this.readyQueues.length > 0);\n\t\tawait Promise.all([...this.fanout.values()].map(({ actor }) => actor.flush()));\n\t}\n\n\tprivate async drainReadyQueues(): Promise<void> {\n\t\twhile (this.readyQueues.length > 0) {\n\t\t\tconst queue = this.readyQueues.shift()!;\n\t\t\tqueue.ready = false;\n\t\t\tconst node = queue.head;\n\t\t\tif (!node) continue;\n\n\t\t\tthis.unlink(queue, node);\n\t\t\tthis.inFlight = { queue, node };\n\t\t\ttry {\n\t\t\t\t// D9: exactly one complete record per raw write. The next lane is not\n\t\t\t\t// selected until this record has cleared stdout backpressure.\n\t\t\t\tconst connection = queue.targetId ? this.fanout.get(queue.targetId)?.connection : undefined;\n\t\t\t\tconst writeRaw = connection?.writeRaw ?? this.writeRaw;\n\t\t\t\tconst waitForBackpressure = connection?.waitForBackpressure ?? this.waitForBackpressure;\n\t\t\t\tif (!connection && queue.targetId) {\n\t\t\t\t\tnode.resolve?.();\n\t\t\t\t} else {\n\t\t\t\t\twriteRaw(serializeJsonLine(node.value));\n\t\t\t\t\tif (waitForBackpressure) await waitForBackpressure();\n\t\t\t\t\tnode.resolve?.();\n\t\t\t\t}\n\t\t\t} catch (cause) {\n\t\t\t\tnode.reject?.(cause);\n\t\t\t\tthrow cause;\n\t\t\t} finally {\n\t\t\t\tthis.inFlight = undefined;\n\t\t\t}\n\n\t\t\tif (queue.head) {\n\t\t\t\tthis.markReady(queue);\n\t\t\t} else if (queue.sessionId || queue.targetId) {\n\t\t\t\tfor (const [key, candidate] of this.queues) {\n\t\t\t\t\tif (candidate === queue) this.queues.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate connectionQueue(targetId: string): RecordQueue {\n\t\tconst key = `connection:${targetId}`;\n\t\tlet queue = this.queues.get(key);\n\t\tif (!queue) {\n\t\t\tqueue = { targetId, latestByKey: new Map(), ready: false };\n\t\t\tthis.queues.set(key, queue);\n\t\t}\n\t\treturn queue;\n\t}\n\n\tprivate appendSessionRecord(sessionId: string, value: RpcRecord, targetId?: string): void {\n\t\tconst key = `${targetId ?? \"default\"}:${sessionId}`;\n\t\tlet queue = this.queues.get(key);\n\t\tif (!queue) {\n\t\t\tqueue = { sessionId, targetId, latestByKey: new Map(), ready: false };\n\t\t\tthis.queues.set(key, queue);\n\t\t}\n\n\t\tconst delta = compactDelta(value);\n\t\tif (delta) {\n\t\t\tconst previousFull = queue.latestByKey.get(MESSAGE_KEY);\n\t\t\tif (previousFull) this.demoteAndMerge(queue, previousFull);\n\t\t\tconst node = this.append(queue, value, MESSAGE_KEY);\n\t\t\tqueue.latestByKey.set(MESSAGE_KEY, node);\n\t\t\tthis.markReady(queue);\n\t\t\treturn;\n\t\t}\n\n\t\tconst toolKey = toolUpdateKey(value);\n\t\tif (toolKey) {\n\t\t\tconst previous = queue.latestByKey.get(toolKey);\n\t\t\tif (previous) this.unlink(queue, previous);\n\t\t\tconst node = this.append(queue, value, toolKey);\n\t\t\tqueue.latestByKey.set(toolKey, node);\n\t\t\tthis.markReady(queue);\n\t\t\treturn;\n\t\t}\n\n\t\t// All non-compactable records are ordering barriers. In particular this\n\t\t// includes delta-only/full non-delta message updates, protocol responses,\n\t\t// extension UI requests, errors, retries, lifecycle, and unknown records.\n\t\tqueue.latestByKey.clear();\n\t\tthis.append(queue, value);\n\t\tthis.markReady(queue);\n\t}\n\n\tprivate demoteAndMerge(queue: RecordQueue, node: QueueNode): void {\n\t\tnode.value = demoteToDeltaOnly(node.value);\n\t\tconst current = compactDelta(node.value);\n\t\tconst preceding = node.previous;\n\t\tconst previous = preceding ? compactDelta(preceding.value) : undefined;\n\t\tif (\n\t\t\tpreceding &&\n\t\t\tprevious &&\n\t\t\tcurrent &&\n\t\t\tpreceding.value.message === null &&\n\t\t\tprevious.type === current.type &&\n\t\t\tprevious.contentIndex === current.contentIndex\n\t\t) {\n\t\t\tconst precedingEvent = preceding.value.assistantMessageEvent as Record<string, unknown>;\n\t\t\tpreceding.value = {\n\t\t\t\t...preceding.value,\n\t\t\t\tassistantMessageEvent: { ...precedingEvent, delta: previous.delta + current.delta },\n\t\t\t};\n\t\t\tthis.unlink(queue, node);\n\t\t}\n\t}\n\n\tprivate append(\n\t\tqueue: RecordQueue,\n\t\tvalue: RpcRecord,\n\t\tkey?: string,\n\t\tresolve?: () => void,\n\t\treject?: (cause: unknown) => void,\n\t): QueueNode {\n\t\tconst node: QueueNode = { value, key, previous: queue.tail, resolve, reject };\n\t\tif (queue.tail) queue.tail.next = node;\n\t\telse queue.head = node;\n\t\tqueue.tail = node;\n\t\treturn node;\n\t}\n\n\tprivate unlink(queue: RecordQueue, node: QueueNode): void {\n\t\tif (node.previous) node.previous.next = node.next;\n\t\telse queue.head = node.next;\n\t\tif (node.next) node.next.previous = node.previous;\n\t\telse queue.tail = node.previous;\n\t\tif (node.key && queue.latestByKey.get(node.key) === node) queue.latestByKey.delete(node.key);\n\t\tnode.previous = undefined;\n\t\tnode.next = undefined;\n\t}\n\n\tprivate markReady(queue: RecordQueue): void {\n\t\tif (queue.ready || this.inFlight?.queue === queue || !queue.head) return;\n\t\tqueue.ready = true;\n\t\tthis.readyQueues.push(queue);\n\t}\n\n\tprivate requestFlush(): void {\n\t\tif (this.failure !== undefined || this.flushScheduled || this.drainPromise) return;\n\t\tthis.flushScheduled = true;\n\t\tthis.scheduleFlush(() => this.flush());\n\t}\n\n\tprivate fail(cause: unknown): void {\n\t\tif (this.failure !== undefined) return;\n\t\tthis.failure = cause;\n\t\tfor (const queue of this.allQueues()) {\n\t\t\tfor (let node = queue.head; node; node = node.next) node.reject?.(cause);\n\t\t}\n\t}\n\n\tprivate *allQueues(): Iterable<RecordQueue> {\n\t\tyield* this.queues.values();\n\t\tyield this.controlQueue;\n\t}\n}\n"]}
@@ -26,6 +26,9 @@ export interface RpcSessionEntry {
26
26
  /** Timestamp of the last routed command / observed activity; drives idle eviction. */
27
27
  lastCommandAt: number;
28
28
  lifecycleMutex: Promise<void>;
29
+ closeCompletion?: Promise<void>;
30
+ closeResolve?: () => void;
31
+ closeStarted?: boolean;
29
32
  }
30
33
  export declare class RpcSessionRegistryError extends Error {
31
34
  readonly code: "unknown_session" | "session_closing" | "session_path_in_use" | "invalid_path" | "open_failed" | "too_many_sessions";
@@ -38,6 +41,8 @@ export interface RpcSessionRegistryOptions {
38
41
  now?: () => number;
39
42
  /** Cap on concurrently opening/open sessions; attach-on-open is exempt. */
40
43
  maxSessions?: number;
44
+ /** Maximum time to wait for graceful runtime teardown before forced release. */
45
+ closeGraceMs?: number;
41
46
  }
42
47
  export interface OpenRpcSession {
43
48
  sessionId: string;
@@ -50,9 +55,11 @@ export interface OpenRpcSession {
50
55
  export declare class RpcSessionRegistry {
51
56
  private readonly entries;
52
57
  private readonly reservations;
58
+ private readonly teardownHost;
53
59
  private nextHandle;
54
60
  private readonly options;
55
61
  private readonly now;
62
+ readonly closeGraceMs: number;
56
63
  constructor(options: RpcSessionRegistryOptions);
57
64
  /** Number of live entries, including ones still opening or closing. */
58
65
  get size(): number;
@@ -65,14 +72,8 @@ export declare class RpcSessionRegistry {
65
72
  */
66
73
  peek(handle: string): RpcSessionEntry | undefined;
67
74
  getForCommand(handle: string, command: string): RpcSessionEntry;
68
- /**
69
- * Starts a close synchronously. Call this before disposing any session-owned
70
- * binding so a concurrent command cannot reach a half-disposed handler.
71
- * Each call releases one attachment; the entry transitions to "closing" only
72
- * when the last attachment closes, so callers must check the returned state
73
- * and skip finalization while other attachments remain.
74
- */
75
- beginClose(handle: string): RpcSessionEntry;
75
+ /** Starts a close synchronously and returns the live entry for routing decisions. */
76
+ beginClose(handle: string, onRole?: (finalizer: boolean) => void): RpcSessionEntry;
76
77
  close(handle: string): Promise<void>;
77
78
  /** Completes a close previously made visible by beginClose(). */
78
79
  closeMarked(handle: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"session-registry.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/session-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-registry.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/session-registry.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { basename, dirname, isAbsolute, resolve } from "node:path";
3
3
  import { ProviderScope, runWithProviderScope } from "@earendil-works/pi-ai/node/provider-scope";
4
4
  import { AgentSessionRuntime, createAgentSessionRuntime, } from "../../core/agent-session-runtime.js";
5
5
  import { SessionManager } from "../../core/session-manager.js";
6
+ import { beginSessionClose, closeMarkedSession, closeSession } from "./session-teardown.js";
6
7
  export class RpcSessionRegistryError extends Error {
7
8
  constructor(code, reason) {
8
9
  super(code === "open_failed" && reason ? `${code}: ${reason}` : code);
@@ -30,6 +31,14 @@ export class RpcSessionRegistry {
30
31
  this.nextHandle = 0;
31
32
  this.options = options;
32
33
  this.now = options.now ?? Date.now;
34
+ this.closeGraceMs = options.closeGraceMs ?? 10_000;
35
+ this.teardownHost = {
36
+ closeGraceMs: this.closeGraceMs,
37
+ get: (handle) => this.entries.get(handle),
38
+ delete: (handle) => this.entries.delete(handle),
39
+ releaseReservation: (key) => this.reservations.delete(key),
40
+ sync: () => this.syncRuntimeMetadata(),
41
+ };
33
42
  }
34
43
  /** Number of live entries, including ones still opening or closing. */
35
44
  get size() {
@@ -178,53 +187,16 @@ export class RpcSessionRegistry {
178
187
  entry.lastCommandAt = this.now();
179
188
  return entry;
180
189
  }
181
- /**
182
- * Starts a close synchronously. Call this before disposing any session-owned
183
- * binding so a concurrent command cannot reach a half-disposed handler.
184
- * Each call releases one attachment; the entry transitions to "closing" only
185
- * when the last attachment closes, so callers must check the returned state
186
- * and skip finalization while other attachments remain.
187
- */
188
- beginClose(handle) {
189
- const entry = this.entries.get(handle);
190
- if (entry?.state !== "open")
191
- throw new RpcSessionRegistryError("unknown_session");
192
- entry.attachments -= 1;
193
- if (entry.attachments > 0)
194
- return entry;
195
- entry.state = "closing";
196
- return entry;
190
+ /** Starts a close synchronously and returns the live entry for routing decisions. */
191
+ beginClose(handle, onRole) {
192
+ return beginSessionClose(this.teardownHost, handle, onRole);
197
193
  }
198
194
  async close(handle) {
199
- const entry = this.beginClose(handle);
200
- // Other attachments may still own the live session; only the last close finalizes.
201
- if (entry.state !== "closing")
202
- return;
203
- return this.closeMarked(handle);
195
+ return closeSession(this.teardownHost, handle);
204
196
  }
205
197
  /** Completes a close previously made visible by beginClose(). */
206
198
  async closeMarked(handle) {
207
- this.syncRuntimeMetadata();
208
- const entry = this.entries.get(handle);
209
- if (entry?.state !== "closing")
210
- throw new RpcSessionRegistryError("unknown_session");
211
- const previousLifecycle = entry.lifecycleMutex;
212
- entry.lifecycleMutex = (async () => {
213
- await previousLifecycle;
214
- try {
215
- await entry.runtime?.session.abort();
216
- await entry.runtime?.session.waitForIdle();
217
- await entry.runtime?.dispose();
218
- await entry.scope.close?.();
219
- }
220
- finally {
221
- entry.state = "closed";
222
- this.entries.delete(handle);
223
- if (entry.reservationKey)
224
- this.reservations.delete(entry.reservationKey);
225
- }
226
- })();
227
- return entry.lifecycleMutex;
199
+ return closeMarkedSession(this.teardownHost, handle);
228
200
  }
229
201
  list() {
230
202
  this.syncRuntimeMetadata();