@maudecode/talaria-web 1.19.0 → 1.20.0

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 (591) hide show
  1. package/_release.json +8 -8
  2. package/dist/api/automation-raw.js +61 -6
  3. package/dist/api/automation-raw.js.map +1 -1
  4. package/dist/api/automation-router.d.ts +8 -6
  5. package/dist/api/automation-router.js +7 -1
  6. package/dist/api/automation-router.js.map +1 -1
  7. package/dist/api/chat-router.d.ts +258 -33
  8. package/dist/api/chat-router.js +60 -25
  9. package/dist/api/chat-router.js.map +1 -1
  10. package/dist/api/git-router.d.ts +4 -0
  11. package/dist/api/git-router.js +1 -1
  12. package/dist/api/git-router.js.map +1 -1
  13. package/dist/api/raw-routes.js +13 -1
  14. package/dist/api/raw-routes.js.map +1 -1
  15. package/dist/api/router.d.ts +2 -2
  16. package/dist/api/session-visibility.js +2 -2
  17. package/dist/api/session-visibility.js.map +1 -1
  18. package/dist/api/sessions-router.d.ts +787 -107
  19. package/dist/api/sessions-router.js +16 -4
  20. package/dist/api/sessions-router.js.map +1 -1
  21. package/dist/api/settings-router.d.ts +34 -13
  22. package/dist/api/settings-router.js +54 -17
  23. package/dist/api/settings-router.js.map +1 -1
  24. package/dist/api/sse-routes.js +41 -19
  25. package/dist/api/sse-routes.js.map +1 -1
  26. package/dist/api/tools-router.d.ts +314 -32
  27. package/dist/api/tools-router.js +135 -38
  28. package/dist/api/tools-router.js.map +1 -1
  29. package/dist/app.js +15 -11
  30. package/dist/app.js.map +1 -1
  31. package/dist/auth/crypto.d.ts +3 -0
  32. package/dist/auth/crypto.js +18 -0
  33. package/dist/auth/crypto.js.map +1 -1
  34. package/dist/auth/gate.js +5 -1
  35. package/dist/auth/gate.js.map +1 -1
  36. package/dist/cli/ctl.js +6 -1
  37. package/dist/cli/ctl.js.map +1 -1
  38. package/dist/cli/main.js +23 -18
  39. package/dist/cli/main.js.map +1 -1
  40. package/dist/cli/supervise.d.ts +22 -0
  41. package/dist/cli/supervise.js +80 -2
  42. package/dist/cli/supervise.js.map +1 -1
  43. package/dist/config/agent-config.d.ts +3 -0
  44. package/dist/config/agent-config.js +36 -9
  45. package/dist/config/agent-config.js.map +1 -1
  46. package/dist/fs/atomic.d.ts +3 -0
  47. package/dist/fs/atomic.js +19 -5
  48. package/dist/fs/atomic.js.map +1 -1
  49. package/dist/fs/stat.d.ts +6 -0
  50. package/dist/fs/stat.js +18 -2
  51. package/dist/fs/stat.js.map +1 -1
  52. package/dist/http/context.d.ts +14 -0
  53. package/dist/http/context.js +48 -5
  54. package/dist/http/context.js.map +1 -1
  55. package/dist/profiles/profiles.d.ts +2 -0
  56. package/dist/profiles/profiles.js +1 -0
  57. package/dist/profiles/profiles.js.map +1 -1
  58. package/dist/providers/catalog.d.ts +11 -6
  59. package/dist/providers/catalog.js +76 -24
  60. package/dist/providers/catalog.js.map +1 -1
  61. package/dist/redact.js +38 -14
  62. package/dist/redact.js.map +1 -1
  63. package/dist/release.js +5 -3
  64. package/dist/release.js.map +1 -1
  65. package/dist/runtime.js +85 -21
  66. package/dist/runtime.js.map +1 -1
  67. package/dist/server.js +24 -21
  68. package/dist/server.js.map +1 -1
  69. package/dist/sessions/anchor.d.ts +2 -1
  70. package/dist/sessions/anchor.js +5 -1
  71. package/dist/sessions/anchor.js.map +1 -1
  72. package/dist/sessions/background-tasks.d.ts +23 -3
  73. package/dist/sessions/background-tasks.js +74 -4
  74. package/dist/sessions/background-tasks.js.map +1 -1
  75. package/dist/sessions/cli-sessions.d.ts +9 -2
  76. package/dist/sessions/cli-sessions.js +38 -57
  77. package/dist/sessions/cli-sessions.js.map +1 -1
  78. package/dist/sessions/completions.d.ts +8 -0
  79. package/dist/sessions/completions.js +55 -25
  80. package/dist/sessions/completions.js.map +1 -1
  81. package/dist/sessions/export.d.ts +2 -0
  82. package/dist/sessions/export.js +6 -2
  83. package/dist/sessions/export.js.map +1 -1
  84. package/dist/sessions/gateway-sessions.d.ts +44 -4
  85. package/dist/sessions/gateway-sessions.js +626 -90
  86. package/dist/sessions/gateway-sessions.js.map +1 -1
  87. package/dist/sessions/gateway-watcher.d.ts +10 -11
  88. package/dist/sessions/gateway-watcher.js +25 -21
  89. package/dist/sessions/gateway-watcher.js.map +1 -1
  90. package/dist/sessions/list.d.ts +9 -2
  91. package/dist/sessions/list.js +38 -26
  92. package/dist/sessions/list.js.map +1 -1
  93. package/dist/sessions/merge.d.ts +11 -5
  94. package/dist/sessions/merge.js +59 -17
  95. package/dist/sessions/merge.js.map +1 -1
  96. package/dist/sessions/prefix-index.d.ts +7 -4
  97. package/dist/sessions/prefix-index.js +21 -10
  98. package/dist/sessions/prefix-index.js.map +1 -1
  99. package/dist/sessions/recovery.d.ts +1 -1
  100. package/dist/sessions/recovery.js +4 -3
  101. package/dist/sessions/recovery.js.map +1 -1
  102. package/dist/sessions/service.d.ts +107 -37
  103. package/dist/sessions/service.js +490 -156
  104. package/dist/sessions/service.js.map +1 -1
  105. package/dist/sessions/session.d.ts +2 -0
  106. package/dist/sessions/session.js +4 -0
  107. package/dist/sessions/session.js.map +1 -1
  108. package/dist/sessions/state-db-worker.js +22 -5
  109. package/dist/sessions/state-db-worker.js.map +1 -1
  110. package/dist/sessions/state-db.d.ts +106 -15
  111. package/dist/sessions/state-db.js +651 -236
  112. package/dist/sessions/state-db.js.map +1 -1
  113. package/dist/sessions/state-saved.d.ts +1 -1
  114. package/dist/sessions/state-saved.js +35 -11
  115. package/dist/sessions/state-saved.js.map +1 -1
  116. package/dist/sessions/storage/backend.d.ts +10 -1
  117. package/dist/sessions/storage/backend.js.map +1 -1
  118. package/dist/sessions/storage/conformance.js +1 -1
  119. package/dist/sessions/storage/conformance.js.map +1 -1
  120. package/dist/sessions/storage/json-documents.d.ts +2 -0
  121. package/dist/sessions/storage/json-documents.js +70 -26
  122. package/dist/sessions/storage/json-documents.js.map +1 -1
  123. package/dist/sessions/storage/json-files.d.ts +13 -2
  124. package/dist/sessions/storage/json-files.js +126 -6
  125. package/dist/sessions/storage/json-files.js.map +1 -1
  126. package/dist/sessions/storage/json-journal.d.ts +6 -7
  127. package/dist/sessions/storage/json-journal.js +143 -73
  128. package/dist/sessions/storage/json-journal.js.map +1 -1
  129. package/dist/sessions/storage/json.d.ts +15 -1
  130. package/dist/sessions/storage/json.js +125 -33
  131. package/dist/sessions/storage/json.js.map +1 -1
  132. package/dist/sessions/store.d.ts +5 -1
  133. package/dist/sessions/store.js +67 -27
  134. package/dist/sessions/store.js.map +1 -1
  135. package/dist/sessions/streams.d.ts +8 -7
  136. package/dist/sessions/streams.js +49 -14
  137. package/dist/sessions/streams.js.map +1 -1
  138. package/dist/sessions/tool-display.d.ts +3 -1
  139. package/dist/sessions/tool-display.js +6 -0
  140. package/dist/sessions/tool-display.js.map +1 -1
  141. package/dist/sessions/turn-context.js +6 -2
  142. package/dist/sessions/turn-context.js.map +1 -1
  143. package/dist/sessions/turn.d.ts +23 -5
  144. package/dist/sessions/turn.js +168 -78
  145. package/dist/sessions/turn.js.map +1 -1
  146. package/dist/sidecar/client.d.ts +24 -1
  147. package/dist/sidecar/client.js +118 -38
  148. package/dist/sidecar/client.js.map +1 -1
  149. package/dist/sidecar/fake.d.ts +6 -2
  150. package/dist/sidecar/fake.js +15 -2
  151. package/dist/sidecar/fake.js.map +1 -1
  152. package/dist/spa.d.ts +9 -4
  153. package/dist/spa.js +36 -12
  154. package/dist/spa.js.map +1 -1
  155. package/dist/startup-timing.d.ts +66 -0
  156. package/dist/startup-timing.js +129 -0
  157. package/dist/startup-timing.js.map +1 -0
  158. package/dist/test/fs-handles.d.ts +11 -0
  159. package/dist/test/fs-handles.js +31 -0
  160. package/dist/test/fs-handles.js.map +1 -0
  161. package/dist/tools/connectors.d.ts +1 -1
  162. package/dist/tools/connectors.js +2 -2
  163. package/dist/tools/connectors.js.map +1 -1
  164. package/dist/tools/crons.d.ts +8 -4
  165. package/dist/tools/crons.js +25 -18
  166. package/dist/tools/crons.js.map +1 -1
  167. package/dist/tools/dashboard-plugins.d.ts +29 -0
  168. package/dist/tools/dashboard-plugins.js +132 -0
  169. package/dist/tools/dashboard-plugins.js.map +1 -1
  170. package/dist/tools/gateway-restart.d.ts +25 -5
  171. package/dist/tools/gateway-restart.js +103 -23
  172. package/dist/tools/gateway-restart.js.map +1 -1
  173. package/dist/tools/health.d.ts +13 -1
  174. package/dist/tools/health.js +80 -22
  175. package/dist/tools/health.js.map +1 -1
  176. package/dist/tools/insights.d.ts +1 -1
  177. package/dist/tools/insights.js +2 -2
  178. package/dist/tools/insights.js.map +1 -1
  179. package/dist/tools/mcp-health.js +74 -24
  180. package/dist/tools/mcp-health.js.map +1 -1
  181. package/dist/tools/mcp.js +19 -1
  182. package/dist/tools/mcp.js.map +1 -1
  183. package/dist/tools/plugin-oauth.d.ts +14 -0
  184. package/dist/tools/plugin-oauth.js +53 -0
  185. package/dist/tools/plugin-oauth.js.map +1 -0
  186. package/dist/tools/prune-advice.d.ts +50 -0
  187. package/dist/tools/prune-advice.js +114 -0
  188. package/dist/tools/prune-advice.js.map +1 -0
  189. package/dist/tools/skills.d.ts +5 -2
  190. package/dist/tools/skills.js +9 -6
  191. package/dist/tools/skills.js.map +1 -1
  192. package/dist/tools/update-notifications.d.ts +73 -7
  193. package/dist/tools/update-notifications.js +277 -43
  194. package/dist/tools/update-notifications.js.map +1 -1
  195. package/dist/tools/updates.d.ts +8 -1
  196. package/dist/tools/updates.js +51 -17
  197. package/dist/tools/updates.js.map +1 -1
  198. package/dist/workspace/media.js +69 -20
  199. package/dist/workspace/media.js.map +1 -1
  200. package/dist/workspace/preview.js +4 -14
  201. package/dist/workspace/preview.js.map +1 -1
  202. package/dist/workspace/rollback.d.ts +6 -2
  203. package/dist/workspace/rollback.js +17 -7
  204. package/dist/workspace/rollback.js.map +1 -1
  205. package/package.json +3 -3
  206. package/sidecar/agent_dependency.json +4 -4
  207. package/sidecar/agent_support.json +17 -14
  208. package/sidecar/scripts/suite_runner.py +183 -27
  209. package/sidecar/scripts/test.sh +5 -7
  210. package/sidecar/talaria_sidecar/__init__.py +1 -1
  211. package/sidecar/talaria_sidecar/__main__.py +10 -3
  212. package/sidecar/talaria_sidecar/agent_mutation.py +159 -23
  213. package/sidecar/talaria_sidecar/agent_services.py +74 -11
  214. package/sidecar/talaria_sidecar/context_detail.py +59 -0
  215. package/sidecar/talaria_sidecar/home.py +97 -20
  216. package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
  217. package/sidecar/talaria_sidecar/methods/aux.py +80 -18
  218. package/sidecar/talaria_sidecar/methods/chat.py +571 -106
  219. package/sidecar/talaria_sidecar/methods/checkpoints.py +29 -4
  220. package/sidecar/talaria_sidecar/methods/commands.py +277 -16
  221. package/sidecar/talaria_sidecar/methods/config.py +73 -3
  222. package/sidecar/talaria_sidecar/methods/connectors.py +45 -13
  223. package/sidecar/talaria_sidecar/methods/cron.py +8 -2
  224. package/sidecar/talaria_sidecar/methods/dashboard_plugins.py +301 -0
  225. package/sidecar/talaria_sidecar/methods/gateway.py +24 -4
  226. package/sidecar/talaria_sidecar/methods/gateway_sessions.py +211 -27
  227. package/sidecar/talaria_sidecar/methods/kanban.py +2 -3
  228. package/sidecar/talaria_sidecar/methods/oauth.py +139 -11
  229. package/sidecar/talaria_sidecar/methods/plugin_catalog.py +198 -0
  230. package/sidecar/talaria_sidecar/methods/plugin_oauth.py +234 -0
  231. package/sidecar/talaria_sidecar/methods/process.py +70 -6
  232. package/sidecar/talaria_sidecar/methods/profiles.py +4 -3
  233. package/sidecar/talaria_sidecar/methods/runtime.py +2 -0
  234. package/sidecar/talaria_sidecar/methods/skills.py +22 -7
  235. package/sidecar/talaria_sidecar/methods/state_db.py +128 -42
  236. package/sidecar/talaria_sidecar/methods/toolsets.py +4 -2
  237. package/sidecar/talaria_sidecar/methods/worktree.py +121 -2
  238. package/sidecar/talaria_sidecar/rpc.py +25 -3
  239. package/sidecar/talaria_sidecar/runtime.py +42 -3
  240. package/sidecar/talaria_sidecar/speed.py +13 -1
  241. package/sidecar/talaria_sidecar/startup_timing.py +119 -0
  242. package/static/dist/FILES.txt +241 -213
  243. package/static/dist/THIRD_PARTY_LICENSES.md +6 -22
  244. package/static/dist/assets/AppShell-3isgvoro.js +8 -0
  245. package/static/dist/assets/Button-f4n6dapf.js +1 -0
  246. package/static/dist/assets/ChatPage-k7b6xfax.js +4 -0
  247. package/static/dist/assets/ConnectTargets-juqvt5lm.js +1 -0
  248. package/static/dist/assets/Dialog-hta5utr3.js +1 -0
  249. package/static/dist/assets/ExtensionRoute-zrhjn0wm.js +1 -0
  250. package/static/dist/assets/Field-b6ez48oz.js +1 -0
  251. package/static/dist/assets/HubRoute-iwvso2tz.js +2 -0
  252. package/static/dist/assets/LinkCheckContext-ix6zqqkk.js +1 -0
  253. package/static/dist/assets/Markdown-jdeth7zq.js +2 -0
  254. package/static/dist/assets/MarkdownRenderer-fbswsgld.js +302 -0
  255. package/static/dist/assets/MarkdownRenderer-i9o6nr38.css +1 -0
  256. package/static/dist/assets/OAuthSignIn-bpd8hom3.js +1 -0
  257. package/static/dist/assets/ResourceSwitch-odi6dy2o.js +1 -0
  258. package/static/dist/assets/RightPanel-eu6enlo6.js +1 -0
  259. package/static/dist/assets/Select-kr07928w.js +1 -0
  260. package/static/dist/assets/SessionListPanel-etb2i54l.js +1 -0
  261. package/static/dist/assets/SettingsLayout-eu3xxp23.js +1 -0
  262. package/static/dist/assets/States-icab19yg.js +1 -0
  263. package/static/dist/assets/TerminalPanel-hngmsr8b.js +16 -0
  264. package/static/dist/assets/Toaster-nb2uzjw1.js +1 -0
  265. package/static/dist/assets/_app-ga1moszl.js +1 -0
  266. package/static/dist/assets/_app.ext._extensionId-na62087t.js +1 -0
  267. package/static/dist/assets/_app.index-jypgdqoi.js +1 -0
  268. package/static/dist/assets/_app.insights-kabejdtm.js +1 -0
  269. package/static/dist/assets/_app.kanban-m19kfcmx.js +1 -0
  270. package/static/dist/assets/_app.logs-iw4m96sz.js +1 -0
  271. package/static/dist/assets/_app.memory-jq5frwcg.js +1 -0
  272. package/static/dist/assets/_app.profiles-kwa3m7rp.js +1 -0
  273. package/static/dist/assets/_app.session._sessionId-o5lyeipj.js +1 -0
  274. package/static/dist/assets/_app.settings-ckl8hdll.js +1 -0
  275. package/static/dist/assets/_app.settings._section-dtdjk98a.js +3 -0
  276. package/static/dist/assets/_app.skills-n016rihd.js +1 -0
  277. package/static/dist/assets/_app.tasks-n8zuqsqe.js +1 -0
  278. package/static/dist/assets/_app.todos-btew5v2s.js +1 -0
  279. package/static/dist/assets/_app.workspaces-lnfk95ch.js +1 -0
  280. package/static/dist/assets/abnfDiagram-VCTEODGH-dttheegb.js +1 -0
  281. package/static/dist/assets/{angular-html-nu6l31w3.js → angular-html-l28bd5fo.js} +1 -1
  282. package/static/dist/assets/{angular-ts-fbx4f8mm.js → angular-ts-ffzx1vj0.js} +1 -1
  283. package/static/dist/assets/{apl-bx2xr7dh.js → apl-b7h7mmy4.js} +1 -1
  284. package/static/dist/assets/{arc-7popfhbk.js → arc-fk1b21lm.js} +1 -1
  285. package/static/dist/assets/architecture-7GRP2DOG-ic435919.js +1 -0
  286. package/static/dist/assets/architectureDiagram-5GKGNRK7-8r3glgiq.js +36 -0
  287. package/static/dist/assets/archive-il7c6053.js +1 -0
  288. package/static/dist/assets/{astro-g77i97cb.js → astro-k117fy0t.js} +1 -1
  289. package/static/dist/assets/back-gu3nu279.js +1 -0
  290. package/static/dist/assets/{blade-boo0u92y.js → blade-npefsmn8.js} +1 -1
  291. package/static/dist/assets/{blockDiagram-I7D4REHJ-joedghi3.js → blockDiagram-I7D4REHJ-jenyos6c.js} +4 -4
  292. package/static/dist/assets/{c-cat0w3sc.js → c-2umg6kbn.js} +1 -1
  293. package/static/dist/assets/{c4Diagram-7LVT6UL2-hyrjrohe.js → c4Diagram-7LVT6UL2-nzlx7yc4.js} +1 -1
  294. package/static/dist/assets/cancel-bsnfo36u.js +1 -0
  295. package/static/dist/assets/channel-dsbtk01y.js +1 -0
  296. package/static/dist/assets/{chunk-4HAMMTFA-koouqbut.js → chunk-4HAMMTFA-g0cru63b.js} +20 -20
  297. package/static/dist/assets/{chunk-75Z2AOVW-bl4bhdnt.js → chunk-75Z2AOVW-7rkswkjw.js} +1 -1
  298. package/static/dist/assets/chunk-DU6HZSFF-fn73jzdo.js +128 -0
  299. package/static/dist/assets/{chunk-F27PBJKO-d8xxi0zi.js → chunk-F27PBJKO-oey8e72m.js} +1 -1
  300. package/static/dist/assets/{chunk-FOHPRMQF-opuflp73.js → chunk-FOHPRMQF-ipewusgj.js} +8 -8
  301. package/static/dist/assets/{chunk-GMAD6QVW-jro0hl73.js → chunk-GMAD6QVW-l2a32wiy.js} +6 -6
  302. package/static/dist/assets/{chunk-GVQU2GXP-djn6gbyu.js → chunk-GVQU2GXP-o9dwzh8h.js} +1 -1
  303. package/static/dist/assets/{chunk-IMKFNOWR-vw4p5p7o.js → chunk-IMKFNOWR-eblwj20b.js} +5 -5
  304. package/static/dist/assets/{chunk-L3NEJ4N5-n1hj77q8.js → chunk-L3NEJ4N5-o2mufspb.js} +1 -1
  305. package/static/dist/assets/chunk-OSK3NFVY-ijp9pw29.js +10 -0
  306. package/static/dist/assets/{chunk-P2QGCYS3-onf1hz6c.js → chunk-P2QGCYS3-hs9hqwl4.js} +1 -1
  307. package/static/dist/assets/{chunk-POPQ4Y6H-m8sqn7cs.js → chunk-POPQ4Y6H-bp9rsqez.js} +1 -1
  308. package/static/dist/assets/{chunk-PWAF6VOD-ek4smc8x.js → chunk-PWAF6VOD-brkprov6.js} +1 -1
  309. package/static/dist/assets/{chunk-SHT3W25Y-g9gfvefo.js → chunk-SHT3W25Y-gmpv0pxz.js} +13 -13
  310. package/static/dist/assets/{chunk-SVP7TREG-f9nfv2cu.js → chunk-SVP7TREG-oldm08fu.js} +4 -4
  311. package/static/dist/assets/{chunk-TICWLB2K-bnk3m1mq.js → chunk-TICWLB2K-ooqilfv7.js} +6 -6
  312. package/static/dist/assets/{chunk-XXDRQBXY-n40pf9vy.js → chunk-XXDRQBXY-jkmnqu65.js} +1 -1
  313. package/static/dist/assets/classDiagram-ZZMXUADV-fvgcv24g.js +1 -0
  314. package/static/dist/assets/classDiagram-v2-VYDZK3BY-fvgcv24g.js +1 -0
  315. package/static/dist/assets/{cobol-go622aep.js → cobol-ssf9hkh7.js} +1 -1
  316. package/static/dist/assets/{coffee-jwo1xjhq.js → coffee-lsi9fwae.js} +1 -1
  317. package/static/dist/assets/copied-bz3gkazh.js +1 -0
  318. package/static/dist/assets/copy-jo006coq.js +1 -0
  319. package/static/dist/assets/cose-bilkent-JH36ORCC-layy2r27.js +1 -0
  320. package/static/dist/assets/{cpp-nre7j0kq.js → cpp-lfrh4y55.js} +1 -1
  321. package/static/dist/assets/{crystal-lviso2je.js → crystal-efh4pte7.js} +1 -1
  322. package/static/dist/assets/{css-ywz9j4hb.js → css-i82qdo89.js} +1 -1
  323. package/static/dist/assets/cynefin-OW5HDTMX-d47op7qs.js +1 -0
  324. package/static/dist/assets/cynefinDiagram-5FMLGOSQ-doa7594y.js +62 -0
  325. package/static/dist/assets/cytoscape.esm-fjn2algp.js +321 -0
  326. package/static/dist/assets/dagre-GXQ25YYZ-os768dp4.js +4 -0
  327. package/static/dist/assets/dagre-o5jmjz46.js +1 -0
  328. package/static/dist/assets/{diagram-S7CK7UJ4-m6aeoe7c.js → diagram-S7CK7UJ4-fyi81nxd.js} +4 -4
  329. package/static/dist/assets/diagram-UQ7AKVKN-j3exggaq.js +41 -0
  330. package/static/dist/assets/{diagram-VSXAHHWV-hbawi7hn.js → diagram-VSXAHHWV-omo1en2l.js} +1 -1
  331. package/static/dist/assets/diagram-VX7I27RA-oro2cyu0.js +24 -0
  332. package/static/dist/assets/diagram-Z3DM3KII-byt9vdb7.js +24 -0
  333. package/static/dist/assets/dist-crc46di9.js +7 -0
  334. package/static/dist/assets/dist-etpoyscq.js +44 -0
  335. package/static/dist/assets/{dist-c4c2m3kv.js → dist-nb670eu6.js} +1 -1
  336. package/static/dist/assets/ebnfDiagram-PWID7BFC-ee3haugh.js +1 -0
  337. package/static/dist/assets/{edge-dvv35byi.js → edge-lrob635n.js} +1 -1
  338. package/static/dist/assets/{elixir-i2f1ki1g.js → elixir-kdpxeq93.js} +1 -1
  339. package/static/dist/assets/{elm-cpepyjm4.js → elm-c8irj9uh.js} +1 -1
  340. package/static/dist/assets/erDiagram-RLTQ6QDP-d1e93yff.js +99 -0
  341. package/static/dist/assets/{erb-idlyfheg.js → erb-flwsv146.js} +1 -1
  342. package/static/dist/assets/eventmodeling-NTZA5JFV-i1ihb40c.js +1 -0
  343. package/static/dist/assets/flowDiagram-HODETNUW-jahfpiod.js +1 -0
  344. package/static/dist/assets/folder-plus-ivoglq98.js +1 -0
  345. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-ma6jxj5i.js → ganttDiagram-EL5Y4UJY-m7g0jud4.js} +1 -1
  346. package/static/dist/assets/{git-rebase-d9lpfpbn.js → git-rebase-bli19aoq.js} +1 -1
  347. package/static/dist/assets/gitGraph-4MIJSDKK-hzdj07yy.js +1 -0
  348. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-hzltvsod.js → gitGraphDiagram-WWUBYQGX-dm9agbna.js} +1 -1
  349. package/static/dist/assets/{glimmer-js-39i0urfb.js → glimmer-js-d4icg38p.js} +1 -1
  350. package/static/dist/assets/{glimmer-ts-gdtd6n73.js → glimmer-ts-bk75772u.js} +1 -1
  351. package/static/dist/assets/{glsl-o1djm5pp.js → glsl-lqormp2b.js} +1 -1
  352. package/static/dist/assets/{graphql-kj6rz55t.js → graphql-hw6s5qzd.js} +1 -1
  353. package/static/dist/assets/{hack-pe1qqr2i.js → hack-ozrv6l4d.js} +1 -1
  354. package/static/dist/assets/{haml-cknnbcqs.js → haml-gytfosdt.js} +1 -1
  355. package/static/dist/assets/{handlebars-hwq64orh.js → handlebars-b6g7jffd.js} +1 -1
  356. package/static/dist/assets/highlighted-body-KPVGNVTW-mmgz2czu.js +1 -0
  357. package/static/dist/assets/host-fr6lni1p.js +1 -0
  358. package/static/dist/assets/{html-derivative-h2i2pyjc.js → html-derivative-f1tqcroo.js} +1 -1
  359. package/static/dist/assets/{html-ha05xtvt.js → html-on6oj6yj.js} +1 -1
  360. package/static/dist/assets/{http-cf94zu27.js → http-odhufsl7.js} +1 -1
  361. package/static/dist/assets/{hurl-lslax568.js → hurl-mu680336.js} +1 -1
  362. package/static/dist/assets/index-73649w7o.js +10 -0
  363. package/static/dist/assets/index-lhf1fsdf.css +2 -0
  364. package/static/dist/assets/info-A6RAGUB7-lll1dqmm.js +1 -0
  365. package/static/dist/assets/infoDiagram-27XIBGKW-k7esc639.js +2 -0
  366. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-e7bnwq7h.js → ishikawaDiagram-5VMMS53U-lgr6k9wo.js} +6 -6
  367. package/static/dist/assets/{java-ndjf2o89.js → java-nxbe8uju.js} +1 -1
  368. package/static/dist/assets/{javascript-coftlwy3.js → javascript-lz3kxcyz.js} +1 -1
  369. package/static/dist/assets/{jinja-etei9wy7.js → jinja-l5pk84gt.js} +1 -1
  370. package/static/dist/assets/{jison-hyekgft1.js → jison-jdutdwyy.js} +1 -1
  371. package/static/dist/assets/{journeyDiagram-3NMN7TZE-etd1bi6p.js → journeyDiagram-3NMN7TZE-ndmbxuqk.js} +1 -1
  372. package/static/dist/assets/{json-lok0yaho.js → json-dnge4ssf.js} +1 -1
  373. package/static/dist/assets/{jsx-b64w0nbx.js → jsx-c3lwhkep.js} +1 -1
  374. package/static/dist/assets/{jsx-runtime-eu92a5pu.js → jsx-runtime-o40ukmjl.js} +1 -1
  375. package/static/dist/assets/{julia-jxxzz2yn.js → julia-hwd4rrcb.js} +1 -1
  376. package/static/dist/assets/{just-mc29iw9t.js → just-nka3oxdx.js} +1 -1
  377. package/static/dist/assets/{kanban-definition-UXKFOSKX-emb1g9dz.js → kanban-definition-UXKFOSKX-mjxym0jp.js} +28 -28
  378. package/static/dist/assets/katex-cbdd1ohw.css +1 -0
  379. package/static/dist/assets/katex-pbij2oo6.js +257 -0
  380. package/static/dist/assets/{latex-pafa03ft.js → latex-iqmr7e40.js} +1 -1
  381. package/static/dist/assets/lazyRouteComponent-cwb6l7xh.js +1 -0
  382. package/static/dist/assets/{line-h0ojzsvs.js → line-mtr5k6il.js} +1 -1
  383. package/static/dist/assets/linear-jlwrvvy6.js +1 -0
  384. package/static/dist/assets/link-iadw4ghw.js +2 -0
  385. package/static/dist/assets/{liquid-hz5c2pov.js → liquid-okmk9tbp.js} +1 -1
  386. package/static/dist/assets/locale-cs-n41hptse.js +5 -0
  387. package/static/dist/assets/locale-de-k7ht47ew.js +5 -0
  388. package/static/dist/assets/locale-es-ih078lco.js +5 -0
  389. package/static/dist/assets/locale-fr-ojabnf41.js +5 -0
  390. package/static/dist/assets/locale-it-kb96jufy.js +5 -0
  391. package/static/dist/assets/locale-ja-jpsp3xs1.js +7 -0
  392. package/static/dist/assets/locale-ko-cpzuy0n7.js +5 -0
  393. package/static/dist/assets/locale-pl-dbap4leu.js +5 -0
  394. package/static/dist/assets/locale-pt-nci7w72x.js +5 -0
  395. package/static/dist/assets/locale-ru-soghe4cs.js +7 -0
  396. package/static/dist/assets/locale-tr-ks00mu68.js +5 -0
  397. package/static/dist/assets/locale-vi-ij7twfm6.js +5 -0
  398. package/static/dist/assets/locale-zh-Hant-feakwr7a.js +5 -0
  399. package/static/dist/assets/locale-zh-ren0vjyv.js +7 -0
  400. package/static/dist/assets/login-lkhtzfcl.js +1 -0
  401. package/static/dist/assets/{lua-leyf8mlb.js → lua-krx4xj5h.js} +1 -1
  402. package/static/dist/assets/{marko-cn1fzpdv.js → marko-gbvpfehz.js} +1 -1
  403. package/static/dist/assets/{mdc-huhy88df.js → mdc-c21zlyi5.js} +1 -1
  404. package/static/dist/assets/mermaid-HWGCJPDP-jx0q5dm2.js +1 -0
  405. package/static/dist/assets/mermaid-parser.core-k91vdnvi.js +7 -0
  406. package/static/dist/assets/micromark-factory-space-fnmnpi6s.js +1 -0
  407. package/static/dist/assets/{mindmap-definition-YA3MSWOX-o1vathns.js → mindmap-definition-YA3MSWOX-ehztfea4.js} +28 -28
  408. package/static/dist/assets/{nginx-e7lvhsmn.js → nginx-f3d68ed4.js} +1 -1
  409. package/static/dist/assets/{nim-dun5d8mk.js → nim-dw0jcy70.js} +1 -1
  410. package/static/dist/assets/onboarding-f67z0a2r.js +1 -0
  411. package/static/dist/assets/packet-AYTQ26CC-ok2xrblz.js +1 -0
  412. package/static/dist/assets/pegDiagram-XKGWAZYB-ec3rpj0m.js +1 -0
  413. package/static/dist/assets/{perl-bj3oqtet.js → perl-3c0r45c8.js} +1 -1
  414. package/static/dist/assets/{php-buzp12r0.js → php-rznhidvp.js} +1 -1
  415. package/static/dist/assets/pie-WAS4IAKB-iwkir23u.js +1 -0
  416. package/static/dist/assets/pieDiagram-E7YTZNPT-fcpqpekh.js +39 -0
  417. package/static/dist/assets/{pug-mjad7he9.js → pug-f2le4f3y.js} +1 -1
  418. package/static/dist/assets/{qml-d1gdp10s.js → qml-e2wbq9cr.js} +1 -1
  419. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-owqc4uqn.js → quadrantDiagram-AXDQQJYC-lqsync43.js} +1 -1
  420. package/static/dist/assets/queryKeys-ed4n2egc.js +9 -0
  421. package/static/dist/assets/{r-o3r9c7ao.js → r-epfzuw6q.js} +1 -1
  422. package/static/dist/assets/radar-RG4KPBEZ-hje4jbk6.js +1 -0
  423. package/static/dist/assets/railroad-74A4TZTK-gll9n6qi.js +1 -0
  424. package/static/dist/assets/railroad-abnf-HS5TGJTU-o6h6lpn4.js +1 -0
  425. package/static/dist/assets/railroad-ebnf-LZEXJU2U-juaefj6o.js +1 -0
  426. package/static/dist/assets/railroad-peg-WCYAUIDC-cgfhvpah.js +1 -0
  427. package/static/dist/assets/railroadDiagram-O6MQD6OU-lp3w7awf.js +1 -0
  428. package/static/dist/assets/{razor-ilc585yr.js → razor-pea1u1d0.js} +1 -1
  429. package/static/dist/assets/refresh-cw-iccm7a4e.js +1 -0
  430. package/static/dist/assets/refresh-i9ya9dvl.js +1 -0
  431. package/static/dist/assets/{regexp-mpjtcvwm.js → regexp-hzte0a5x.js} +1 -1
  432. package/static/dist/assets/registry-g7w3353u.js +1 -0
  433. package/static/dist/assets/requirementDiagram-BXWQKSXE-ha8eibcf.js +84 -0
  434. package/static/dist/assets/rolldown-runtime-bnnw9q4a.js +1 -0
  435. package/static/dist/assets/{rst-jrkwjdyi.js → rst-m6tugj5o.js} +1 -1
  436. package/static/dist/assets/{ruby-n4tjcbpz.js → ruby-l19vq3w1.js} +1 -1
  437. package/static/dist/assets/runtime-nlxpnegr.js +1 -0
  438. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-iqc02emv.js → sankeyDiagram-P5KCCOFB-oxf31pr9.js} +1 -1
  439. package/static/dist/assets/{sas-hjo6y93k.js → sas-ktdxo397.js} +1 -1
  440. package/static/dist/assets/{scss-ncidjv48.js → scss-kn3oxfwf.js} +1 -1
  441. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-i0v116q0.js → sequenceDiagram-WJ2MYXX4-jiq8lhyo.js} +11 -11
  442. package/static/dist/assets/settings_section_extensions_title-fadc7o65.js +1 -0
  443. package/static/dist/assets/share._token-o76ki0ly.js +2 -0
  444. package/static/dist/assets/{shellscript-m8whjpqd.js → shellscript-l100jtrg.js} +1 -1
  445. package/static/dist/assets/{shellsession-i5bj6syz.js → shellsession-m5qukwow.js} +1 -1
  446. package/static/dist/assets/sizeCapture-INFHLROL-dk1io13w.js +1 -0
  447. package/static/dist/assets/sliders-horizontal-ddcs88av.js +1 -0
  448. package/static/dist/assets/{soy-hhh36ysq.js → soy-mexlscur.js} +1 -1
  449. package/static/dist/assets/{sql-j21bzcl6.js → sql-o0ho5suh.js} +1 -1
  450. package/static/dist/assets/src-h89s0hs4.js +1 -0
  451. package/static/dist/assets/{stata-bbu2onh1.js → stata-be9ck1q3.js} +1 -1
  452. package/static/dist/assets/stateDiagram-D77RDMKH-f3fslnon.js +1 -0
  453. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hlt6yphw.js +1 -0
  454. package/static/dist/assets/{surrealql-l5vczuco.js → surrealql-gk1xkkyy.js} +1 -1
  455. package/static/dist/assets/{svelte-idn422g6.js → svelte-k6ecjilf.js} +1 -1
  456. package/static/dist/assets/swimlanes-42K2YHIH-k1hmk7jf.js +1 -0
  457. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-hd5t9tnt.js +8 -0
  458. package/static/dist/assets/{templ-e22qou3c.js → templ-gf3bftk6.js} +1 -1
  459. package/static/dist/assets/{tex-deqpc5ee.js → tex-d21fqv1z.js} +1 -1
  460. package/static/dist/assets/{timeline-definition-24CTP7MA-ol2hnvma.js → timeline-definition-24CTP7MA-n3ncfy9r.js} +8 -8
  461. package/static/dist/assets/toast-liparz2j.js +56 -0
  462. package/static/dist/assets/treeView-Q6P3EWNA-l3y2pejt.js +1 -0
  463. package/static/dist/assets/treemap-WGGIJYW6-jown9axh.js +1 -0
  464. package/static/dist/assets/{ts-tags-ctnibc27.js → ts-tags-n0g61gr6.js} +1 -1
  465. package/static/dist/assets/{tsx-i163n32g.js → tsx-cvv7wv6q.js} +1 -1
  466. package/static/dist/assets/{twig-x0fi7wm8.js → twig-n1f67204.js} +1 -1
  467. package/static/dist/assets/{typescript-g18c34xz.js → typescript-og7o55cx.js} +1 -1
  468. package/static/dist/assets/untitled-mj86r4gz.js +1 -0
  469. package/static/dist/assets/useDebounced-g8r0ggve.js +1 -0
  470. package/static/dist/assets/useForm-o4uu74mx.js +1 -0
  471. package/static/dist/assets/{useParams-gjc70qru.js → useParams-ftsveu84.js} +1 -1
  472. package/static/dist/assets/{useSearch-e6ae539u.js → useSearch-crqueqga.js} +1 -1
  473. package/static/dist/assets/vennDiagram-4TSXK5OY-dh59uq1c.js +34 -0
  474. package/static/dist/assets/{vue-mwu5l1bb.js → vue-ej4xpwqw.js} +1 -1
  475. package/static/dist/assets/{vue-html-nskj3du0.js → vue-html-d48xsjuo.js} +1 -1
  476. package/static/dist/assets/{vue-vine-cqe77smq.js → vue-vine-pev88ip6.js} +1 -1
  477. package/static/dist/assets/wardley-WFR3VGLG-e6d74b0j.js +1 -0
  478. package/static/dist/assets/wardleyDiagram-VM6X3IG4-hnofh78f.js +78 -0
  479. package/static/dist/assets/with-selector-nu1b5z0v.js +1 -0
  480. package/static/dist/assets/{xml-gau7gvrv.js → xml-ifxp6gqb.js} +1 -1
  481. package/static/dist/assets/{xsl-ew09zq8b.js → xsl-fug2cckc.js} +1 -1
  482. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-aqbgvujg.js → xychartDiagram-S5SC5T6Z-bpymjelb.js} +6 -6
  483. package/static/dist/assets/{yaml-ofnrxtvf.js → yaml-fjmafnlo.js} +1 -1
  484. package/static/dist/extension-sdk.js +1 -1
  485. package/static/dist/index.html +1 -1
  486. package/static/dist/sw.js +180 -136
  487. package/static/dist/assets/AppShell-cey33v9s.js +0 -8
  488. package/static/dist/assets/ChatPage-i8wnugr7.js +0 -18
  489. package/static/dist/assets/ConnectTargets-hg19553x.js +0 -1
  490. package/static/dist/assets/ExtensionRoute-cly4apm5.js +0 -1
  491. package/static/dist/assets/Field-j8uqoigz.js +0 -9
  492. package/static/dist/assets/HubRoute-e4bgz41j.js +0 -2
  493. package/static/dist/assets/Markdown-lahuichm.js +0 -598
  494. package/static/dist/assets/Markdown-lwviulmg.css +0 -1
  495. package/static/dist/assets/RightPanel-lbo4i0fn.js +0 -1
  496. package/static/dist/assets/Select-gqatm2e0.js +0 -1
  497. package/static/dist/assets/SessionListPanel-mfqayfjh.js +0 -1
  498. package/static/dist/assets/SettingsLayout-b8980u7k.js +0 -1
  499. package/static/dist/assets/States-e7dkgtxf.js +0 -1
  500. package/static/dist/assets/Toaster-bfqqy786.js +0 -1
  501. package/static/dist/assets/_app-n1n6pfx1.js +0 -1
  502. package/static/dist/assets/_app.ext._extensionId-buxjxav3.js +0 -1
  503. package/static/dist/assets/_app.index-jt8zwiu2.js +0 -1
  504. package/static/dist/assets/_app.insights-cv76ml71.js +0 -1
  505. package/static/dist/assets/_app.kanban-h6ts53j7.js +0 -1
  506. package/static/dist/assets/_app.logs-dm873z90.js +0 -1
  507. package/static/dist/assets/_app.memory-glk5y6m8.js +0 -1
  508. package/static/dist/assets/_app.profiles-ka6zpstq.js +0 -1
  509. package/static/dist/assets/_app.session._sessionId-g2vzghvc.js +0 -1
  510. package/static/dist/assets/_app.settings-hgjdhzcd.js +0 -1
  511. package/static/dist/assets/_app.settings._section-jf2kmhae.js +0 -3
  512. package/static/dist/assets/_app.skills-cii852yq.js +0 -1
  513. package/static/dist/assets/_app.tasks-fp9q7atm.js +0 -1
  514. package/static/dist/assets/_app.todos-dw94qzue.js +0 -1
  515. package/static/dist/assets/_app.workspaces-inyygzze.js +0 -1
  516. package/static/dist/assets/abnfDiagram-VCTEODGH-gjayq3ra.js +0 -1
  517. package/static/dist/assets/architecture-7GRP2DOG-lp56972r.js +0 -1
  518. package/static/dist/assets/architectureDiagram-5GKGNRK7-nwb3xovn.js +0 -36
  519. package/static/dist/assets/archive-b1j004vn.js +0 -1
  520. package/static/dist/assets/back-g74gkozu.js +0 -1
  521. package/static/dist/assets/channel-es95o4y8.js +0 -1
  522. package/static/dist/assets/chunk-DU6HZSFF-gpedttsp.js +0 -128
  523. package/static/dist/assets/chunk-OSK3NFVY-oy0gwn2n.js +0 -10
  524. package/static/dist/assets/classDiagram-ZZMXUADV-kmihoqxh.js +0 -1
  525. package/static/dist/assets/classDiagram-v2-VYDZK3BY-kmihoqxh.js +0 -1
  526. package/static/dist/assets/copied-bli9tbcx.js +0 -1
  527. package/static/dist/assets/copy-jamtd1pf.js +0 -1
  528. package/static/dist/assets/cose-bilkent-JH36ORCC-eclcy6ja.js +0 -1
  529. package/static/dist/assets/cynefin-OW5HDTMX-f8xfdd3f.js +0 -1
  530. package/static/dist/assets/cynefinDiagram-5FMLGOSQ-n9lb99h9.js +0 -62
  531. package/static/dist/assets/cytoscape.esm-bqu53u12.js +0 -321
  532. package/static/dist/assets/dagre-GXQ25YYZ-dgailddi.js +0 -4
  533. package/static/dist/assets/dagre-lkoknbjn.js +0 -1
  534. package/static/dist/assets/diagram-UQ7AKVKN-jall3j0x.js +0 -41
  535. package/static/dist/assets/diagram-VX7I27RA-hendl2tt.js +0 -24
  536. package/static/dist/assets/diagram-Z3DM3KII-igwc35p3.js +0 -24
  537. package/static/dist/assets/ebnfDiagram-PWID7BFC-c64knz08.js +0 -1
  538. package/static/dist/assets/erDiagram-RLTQ6QDP-brdu9lcm.js +0 -99
  539. package/static/dist/assets/eventmodeling-NTZA5JFV-njk1j8wl.js +0 -1
  540. package/static/dist/assets/flowDiagram-HODETNUW-nma6f0ga.js +0 -1
  541. package/static/dist/assets/folder-plus-lvt9kudb.js +0 -1
  542. package/static/dist/assets/gitGraph-4MIJSDKK-naa9w6xa.js +0 -1
  543. package/static/dist/assets/highlighted-body-KPVGNVTW-ghoavj8d.js +0 -1
  544. package/static/dist/assets/host-hzm8n85n.js +0 -1
  545. package/static/dist/assets/index-drdcaqeq.css +0 -2
  546. package/static/dist/assets/index-jzm844he.js +0 -11
  547. package/static/dist/assets/info-A6RAGUB7-mn2ut5ko.js +0 -1
  548. package/static/dist/assets/infoDiagram-27XIBGKW-h6kuqvsb.js +0 -2
  549. package/static/dist/assets/lazyRouteComponent-o816ytzl.js +0 -1
  550. package/static/dist/assets/linear-becwlnhk.js +0 -1
  551. package/static/dist/assets/link-k01ryaf9.js +0 -1
  552. package/static/dist/assets/login-bsae49ew.js +0 -1
  553. package/static/dist/assets/mermaid-HWGCJPDP-ihl34s74.js +0 -1
  554. package/static/dist/assets/mermaid-parser.core-bnre27u8.js +0 -7
  555. package/static/dist/assets/not-found-ccnnac39.js +0 -1
  556. package/static/dist/assets/onboarding-c65tysya.js +0 -1
  557. package/static/dist/assets/onboarding_model_label-gpn28uix.js +0 -1
  558. package/static/dist/assets/packet-AYTQ26CC-hatq7m2e.js +0 -1
  559. package/static/dist/assets/pegDiagram-XKGWAZYB-gwisz8jv.js +0 -1
  560. package/static/dist/assets/pie-WAS4IAKB-fpftf0mk.js +0 -1
  561. package/static/dist/assets/pieDiagram-E7YTZNPT-khm1o9a6.js +0 -39
  562. package/static/dist/assets/radar-RG4KPBEZ-cntfwjpq.js +0 -1
  563. package/static/dist/assets/railroad-74A4TZTK-a7t5eibp.js +0 -1
  564. package/static/dist/assets/railroad-abnf-HS5TGJTU-ol8cdktf.js +0 -1
  565. package/static/dist/assets/railroad-ebnf-LZEXJU2U-i8vzd429.js +0 -1
  566. package/static/dist/assets/railroad-peg-WCYAUIDC-nw3ulewz.js +0 -1
  567. package/static/dist/assets/railroadDiagram-O6MQD6OU-etuh0qa0.js +0 -1
  568. package/static/dist/assets/refresh-cw-mqbkv2a3.js +0 -1
  569. package/static/dist/assets/refresh-l29ljp76.js +0 -1
  570. package/static/dist/assets/requirementDiagram-BXWQKSXE-oq2ulk22.js +0 -84
  571. package/static/dist/assets/rolldown-runtime-b9miacsj.js +0 -1
  572. package/static/dist/assets/root-mbklpuv4.js +0 -1
  573. package/static/dist/assets/saved-ndd4t2xb.js +0 -1
  574. package/static/dist/assets/settings_section_extensions_title-jhfo6o8z.js +0 -1
  575. package/static/dist/assets/share._token-c1ri0hy1.js +0 -2
  576. package/static/dist/assets/sizeCapture-INFHLROL-g612l48j.js +0 -1
  577. package/static/dist/assets/sliders-horizontal-j3jjt9tv.js +0 -1
  578. package/static/dist/assets/src-hjyib4mu.js +0 -1
  579. package/static/dist/assets/stateDiagram-D77RDMKH-dnpt1ato.js +0 -1
  580. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-bxjacpk6.js +0 -1
  581. package/static/dist/assets/swimlanes-42K2YHIH-loqbdazb.js +0 -1
  582. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-id62p9hz.js +0 -8
  583. package/static/dist/assets/toast-i3h34v6o.js +0 -64
  584. package/static/dist/assets/treeView-Q6P3EWNA-idrj6iox.js +0 -1
  585. package/static/dist/assets/treemap-WGGIJYW6-lzr49vv5.js +0 -1
  586. package/static/dist/assets/untitled-oaoya4qj.js +0 -1
  587. package/static/dist/assets/useForm-nfaxgmsk.js +0 -1
  588. package/static/dist/assets/vennDiagram-4TSXK5OY-bvwr9o2z.js +0 -34
  589. package/static/dist/assets/wardley-WFR3VGLG-31ui8tma.js +0 -1
  590. package/static/dist/assets/wardleyDiagram-VM6X3IG4-k5wqtx4b.js +0 -78
  591. /package/static/dist/assets/{ChatPage-gmu5c7lf.css → TerminalPanel-gmu5c7lf.css} +0 -0
@@ -1,34 +1,237 @@
1
- /** One native-owner seam. Talaria observes its history and never settles it into a local Session. */
1
+ import { unavailableContextDetail } from '@maudecode/talaria-web-contracts';
2
2
  import { createHash, randomUUID } from 'node:crypto';
3
- import { GatewaySessionResultSchema } from '@maudecode/talaria-web-contracts';
4
- import { redactNestedMessageContainers, publicToolFrame } from '../redact.js';
3
+ import { OWNER_EXPORT_MAX_BYTES, SessionNoticeSchema, GatewayClarifyBatchSchema, GatewaySessionResultSchema } from '@maudecode/talaria-web-contracts';
4
+ import { redactNestedMessageContainers, publicToolFrame, redactString } from '../redact.js';
5
5
  import { str } from '../util.js';
6
6
  import { PendingPrompts } from './pending.js';
7
+ import { wrapExportHtml } from './export.js';
7
8
  import { clarifyReply } from './pending.js';
8
9
  import { HttpFailure } from './service.js';
10
+ import { SessionNotices } from './notices.js';
9
11
  import { SessionEventBus } from './events.js';
10
12
  import { messageWindowForDisplay, messagesForLimitedPayload } from './window.js';
11
13
  import { pendingUserRow } from './merge.js';
12
- import { CANONICAL_READ_ONLY_REASON } from './state-db.js';
14
+ import { ReasoningTitleTracker, reasoningEventPayload } from './reasoning-titles.js';
15
+ import { CANONICAL_READ_ONLY_REASON, WEB_DIAGNOSTIC_REQUEST_PREFIX } from './state-db.js';
16
+ import { toolProgress } from './tool-display.js';
13
17
  const ownerStreamPrefix = (home) => `owner-${createHash('sha256').update(home).digest('hex').slice(0, 16)}-`;
14
18
  const ownerStateId = (identity) => `owner-${createHash('sha256').update(identity).digest('hex')}`;
15
19
  /** The scope remains verifiable after a server restart, before a journal lookup or stream subscription. */
16
20
  export const gatewayStreamVisible = (stream, home) => !stream.startsWith('owner-') || stream.startsWith(ownerStreamPrefix(home));
21
+ /** The server's one classification of why an owner cannot start a diagnostic chat; clients word the code. */
22
+ function unavailableReason(result) {
23
+ if (result.state === 'stopped')
24
+ return 'gateway_stopped';
25
+ if (result.reason === 'served_profile_sessions_unavailable')
26
+ return 'served_profile';
27
+ if (result.state === 'incompatible')
28
+ return 'agent_unsupported';
29
+ return 'gateway_unavailable';
30
+ }
17
31
  /** A preview can be absent in a valid native receipt; only original nonblank text can become a retry draft. */
18
32
  function retryText(admission) {
19
33
  const text = admission.text;
20
34
  return typeof text === 'string' && text.trim() ? text : null;
21
35
  }
36
+ /** Steering belongs to the current turn; it must never replace that turn's transcript anchor. */
37
+ const runningAdmission = (snapshot) => snapshot.pending.find((p) => p.status === 'started' && !p.steering);
38
+ const sameExecution = (a, b) => a.authority_epoch === b.authority_epoch && a.replay_epoch === b.replay_epoch && a.execution_generation === b.execution_generation;
39
+ /** Native counters and the owner's compact turn-end usage share one existing Web usage shape. */
40
+ function ownerUsage(data) {
41
+ const fields = {
42
+ input_tokens: ['prompt_tokens', 'prompt', 'input_tokens', 'input'], output_tokens: ['completion_tokens', 'completion', 'output_tokens', 'output'],
43
+ cache_read_tokens: ['cache_read_tokens'], cache_write_tokens: ['cache_write_tokens'],
44
+ estimated_cost: ['estimated_cost_usd'], last_prompt_tokens: ['last_prompt_tokens', 'context_used'],
45
+ context_length: ['context_length', 'context_max'], cache_hit_percent: ['cache_hit_pct'], tps: ['tokens_per_s', 'avg_tps'],
46
+ };
47
+ const usage = {};
48
+ for (const [field, keys] of Object.entries(fields)) {
49
+ const value = keys.map((key) => data[key]).find((value) => typeof value === 'number' && Number.isFinite(value) && value >= 0);
50
+ if (value !== undefined)
51
+ usage[field] = value;
52
+ }
53
+ return usage;
54
+ }
55
+ /** Translate only owner-confirmed outcomes; an unknown receipt never means applied. */
56
+ function modelChange(receipt, selection = {}) {
57
+ const payload = receipt.payload && typeof receipt.payload === 'object' ? receipt.payload : selection;
58
+ const model = str(receipt.target_model) || str(payload.model) || str(receipt.model);
59
+ const provider = Object.hasOwn(receipt, 'target_provider') ? receipt.target_provider : payload.provider;
60
+ const target = { ...(model ? { model } : {}), ...(provider === null || typeof provider === 'string' ? { provider } : {}) };
61
+ if (receipt.operation !== 'model')
62
+ return { state: 'refused', message: 'The owner did not confirm the model change' };
63
+ if (receipt.status === 'deferred')
64
+ return { state: 'deferred', ...target };
65
+ if (receipt.status === 'confirmation_required' && typeof receipt.confirm === 'string' && receipt.confirm && model)
66
+ return { state: 'confirmation_required', message: str(receipt.confirm_message), confirm: receipt.confirm, ...target };
67
+ if (receipt.status === undefined && Number.isInteger(receipt.revision))
68
+ return { state: 'applied' };
69
+ return { state: 'refused', message: str(receipt.reason || receipt.message) || 'The owner did not confirm the model change' };
70
+ }
22
71
  export class GatewaySessions {
23
72
  deps;
24
73
  watches = new Map();
74
+ runWorkers = new Set();
75
+ observations = new Map();
76
+ noticeEpochs = new Map();
77
+ notices;
78
+ modelMutations = new Map();
79
+ modelChanges = new Map();
80
+ rememberModelChange(target, snapshot, change) {
81
+ this.modelChanges.set(target.key, { epoch: snapshot.authority_epoch, replay: snapshot.replay_epoch, change });
82
+ }
83
+ currentModelChange(target, snapshot) {
84
+ const saved = this.modelChanges.get(target.key);
85
+ if (!saved || !snapshot)
86
+ return undefined;
87
+ if (saved.epoch === snapshot.authority_epoch && saved.replay === snapshot.replay_epoch)
88
+ return saved.change;
89
+ this.modelChanges.delete(target.key);
90
+ return undefined;
91
+ }
25
92
  constructor(deps) {
26
93
  this.deps = deps;
94
+ this.notices = new SessionNotices(deps.now);
95
+ }
96
+ addNativeNotice(target, key, frame) {
97
+ const text = typeof frame.text === 'string' ? frame.text.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, '') : '';
98
+ this.notices.add(target.key, { ...frame, key, text, lapses_with_agent: true });
99
+ }
100
+ noticeState(target, snapshot, reset = false) {
101
+ const identity = ownerStateId(JSON.stringify([target.key, snapshot.authority_epoch, snapshot.replay_epoch]));
102
+ let state = this.noticeEpochs.get(target.key);
103
+ if (state?.identity !== identity || reset) {
104
+ this.notices.reset(target.key);
105
+ state = { identity, sequence: reset ? snapshot.last_sequence : 0 };
106
+ this.noticeEpochs.set(target.key, state);
107
+ }
108
+ const warning = typeof snapshot.info.config_warning === 'string' ? snapshot.info.config_warning : '';
109
+ if (warning.trim())
110
+ this.addNativeNotice(target, `${identity}:config-warning`, { text: warning, level: 'warn' });
111
+ return state;
112
+ }
113
+ nativeNotices(target, snapshot) {
114
+ const observed = this.observations.get(target.key)?.snapshot;
115
+ this.noticeState(target, observed && observed.authority_epoch >= snapshot.authority_epoch ? observed : snapshot);
116
+ // A detail row may already contain our projection. Read the direct layer itself so
117
+ // retained transport bases cannot duplicate warnings or resurrect cleared notices.
118
+ const direct = SessionNoticeSchema.array().safeParse(this.deps.service.deps.runtime.sessionNotices?.(target.sid) ?? []);
119
+ return [...(direct.success ? direct.data : []), ...this.notices.list(target.key)];
120
+ }
121
+ changed(target) {
122
+ this.deps.channels.emit(target.sid, 'session-updated', { session_id: target.sid, source: 'native_owner' }, target.profile);
123
+ }
124
+ /** One shared connection, acquired by viewers and run projections, with no local Agent admission. */
125
+ transport(target, base, snapshot) {
126
+ const prior = this.observations.get(target.key);
127
+ if (prior && !prior.controller.signal.aborted)
128
+ return prior;
129
+ const observation = { controller: new AbortController(), snapshot, replaying: true, completion: null, listeners: new Set(), leases: 0, ended: Promise.resolve({ state: 'unavailable', reason: 'owner_connection_lost', snapshot: null, receipt: null }) };
130
+ this.observations.set(target.key, observation);
131
+ this.noticeState(target, snapshot);
132
+ observation.ended = (async () => {
133
+ const showReasoning = await this.deps.showReasoning(target.home).catch(() => false);
134
+ const sidecar = this.deps.sidecar();
135
+ if (!sidecar || observation.controller.signal.aborted)
136
+ return { state: 'unavailable', reason: 'sidecar_unavailable', snapshot: null, receipt: null };
137
+ return sidecar.call('gateway.session', { profile_home: target.home, session_id: target.sid, action: 'watch', show_reasoning: showReasoning }, {
138
+ signal: observation.controller.signal, timeoutMs: 0,
139
+ onStream: (frame) => {
140
+ if (observation.controller.signal.aborted || this.observations.get(target.key) !== observation)
141
+ return;
142
+ if (frame.event === 'snapshot') {
143
+ const result = GatewaySessionResultSchema.parse(frame.data);
144
+ if (result.snapshot?.session_id !== target.sid)
145
+ return;
146
+ const completed = observation.completion?.data;
147
+ if (result.replay_gap || completed && (completed.authority_epoch !== result.snapshot.authority_epoch || completed.replay_epoch !== result.snapshot.replay_epoch))
148
+ observation.completion = null;
149
+ observation.snapshot = result.snapshot;
150
+ observation.replaying = frame.data.replaying === true;
151
+ this.noticeState(target, result.snapshot, result.replay_gap === true);
152
+ if ((result.snapshot.running || result.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started')) && !this.watches.has(target.key))
153
+ this.watch(target, base, result.snapshot);
154
+ this.changed(target);
155
+ }
156
+ else if (frame.event === 'replay_complete') {
157
+ observation.replaying = false;
158
+ }
159
+ else if (frame.event === 'event') {
160
+ const event = frame.data;
161
+ const data = (event.payload ?? {});
162
+ if (event.type === 'notification.show' || event.type === 'notification.clear') {
163
+ const snap = observation.snapshot;
164
+ const state = this.noticeState(target, snap);
165
+ if (event.session_id !== target.sid || event.replay_epoch !== snap.replay_epoch
166
+ || event.authority_epoch !== undefined && event.authority_epoch !== snap.authority_epoch
167
+ || !Number.isSafeInteger(event.seq) || Number(event.seq) <= state.sequence)
168
+ return;
169
+ state.sequence = Number(event.seq);
170
+ const key = typeof data.key === 'string' ? data.key : typeof data.id === 'string' ? data.id : '';
171
+ if (!key)
172
+ return;
173
+ const scopedKey = `${state.identity}:plugin:${ownerStateId(key)}`;
174
+ if (event.type === 'notification.clear')
175
+ this.notices.clear(target.key, scopedKey);
176
+ else
177
+ this.addNativeNotice(target, scopedKey, data);
178
+ this.changed(target);
179
+ }
180
+ else if (event.type === 'session.info') {
181
+ if (data.authority_epoch !== observation.snapshot.authority_epoch || Number(data.execution_generation) < observation.snapshot.execution_generation)
182
+ return;
183
+ observation.snapshot = { ...observation.snapshot, ...data };
184
+ if ((observation.snapshot.running || observation.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started')) && !this.watches.has(target.key))
185
+ this.watch(target, base, observation.snapshot);
186
+ this.changed(target);
187
+ }
188
+ else if (event.type === 'message.complete' && event.session_id === target.sid
189
+ && event.authority_epoch === observation.snapshot.authority_epoch && event.replay_epoch === observation.snapshot.replay_epoch
190
+ && Number.isSafeInteger(event.execution_generation) && Number(event.execution_generation) >= observation.snapshot.execution_generation) {
191
+ observation.completion = frame;
192
+ }
193
+ else if (event.type === 'session.updated')
194
+ this.changed(target);
195
+ }
196
+ for (const listener of observation.listeners)
197
+ listener(frame);
198
+ },
199
+ });
200
+ })().catch(() => ({ state: 'unavailable', reason: 'owner_connection_lost', snapshot: null, receipt: null })).finally(() => {
201
+ observation.controller.abort();
202
+ if (this.observations.get(target.key) === observation)
203
+ this.observations.delete(target.key);
204
+ this.changed(target);
205
+ });
206
+ return observation;
207
+ }
208
+ lease(observation) {
209
+ observation.leases++;
210
+ let held = true;
211
+ return () => { if (!held)
212
+ return; held = false; if (--observation.leases === 0)
213
+ observation.controller.abort(); };
214
+ }
215
+ /** Called only after the existing HTTP owner has authorized and claimed a viewer's stream slot. */
216
+ async observe(sid, profile, signal) {
217
+ const target = await this.target(sid, profile);
218
+ if (!target || signal.aborted)
219
+ return null;
220
+ const base = await this.deps.service.detail(sid, {});
221
+ const result = await this.call(target, { action: 'snapshot' }, signal);
222
+ if (signal.aborted)
223
+ return null;
224
+ if (!result.snapshot || result.state !== 'attached')
225
+ return { release: () => undefined, ended: Promise.resolve(result) };
226
+ const observation = this.transport(target, base, result.snapshot);
227
+ const release = this.lease(observation);
228
+ signal.addEventListener('abort', release, { once: true });
229
+ return { release: () => { signal.removeEventListener('abort', release); release(); }, ended: observation.ended };
27
230
  }
28
- target(sid, profile = this.deps.activeProfile()) {
231
+ async target(sid, profile = this.deps.activeProfile()) {
29
232
  if (sid.length === 0 || sid !== sid.trim())
30
233
  return null;
31
- const owner = this.deps.service.stateDbSources([sid], profile)?.get(sid);
234
+ const owner = (await this.deps.service.stateDbSources([sid], profile))?.get(sid);
32
235
  if (typeof owner !== 'object')
33
236
  return null;
34
237
  if (owner.reason)
@@ -36,40 +239,137 @@ export class GatewaySessions {
36
239
  const home = this.deps.profileHome(profile);
37
240
  return { sid, profile, home, key: JSON.stringify([home, sid]) };
38
241
  }
39
- isOwned(sid) { return this.target(sid) !== null; }
40
- async call(target, params) {
242
+ async contextDetail(sid, expectedKey) {
243
+ const profile = this.deps.activeProfile();
244
+ const target = await this.target(sid, profile);
245
+ if (!target)
246
+ return unavailableContextDetail();
247
+ const result = await this.call(target, { action: 'context_detail' });
248
+ return profile === this.deps.activeProfile() && result.state === 'attached' && this.contextDetailKey(target, result.snapshot) === expectedKey ? result.context_detail ?? unavailableContextDetail('unsupported') : unavailableContextDetail('changed');
249
+ }
250
+ async isOwned(sid) { return (await this.target(sid)) !== null; }
251
+ async export(sid, format) {
252
+ const target = await this.target(sid);
253
+ if (!target)
254
+ return null;
255
+ const redact = this.deps.redactEnabled();
256
+ const result = await this.call(target, { action: 'export', format, redact });
257
+ const value = result.export;
258
+ if (result.reason === 'export_too_large')
259
+ throw new HttpFailure(413, 'The owner transcript exceeds the export limit');
260
+ if (result.state !== 'attached' || value?.format !== format) {
261
+ throw new HttpFailure(409, 'The Agent owner cannot export this chat. Check that its gateway is running and supports transcript export.', { code: 'owner_export_unavailable' });
262
+ }
263
+ if (Buffer.byteLength(value.content, 'utf8') > OWNER_EXPORT_MAX_BYTES)
264
+ throw new HttpFailure(413, 'The owner transcript exceeds the export limit');
265
+ let content;
266
+ try {
267
+ // The owner redacts HTML's structured transcript before rendering. A shell/text redactor corrupts its markup.
268
+ content = format === 'html' ? wrapExportHtml(value.content) : format === 'json'
269
+ ? JSON.stringify(redactNestedMessageContainers(JSON.parse(value.content), redact), null, 2)
270
+ : redactString(value.content, redact);
271
+ }
272
+ catch {
273
+ throw new HttpFailure(409, 'The Agent owner returned an invalid transcript export', { code: 'owner_export_invalid' });
274
+ }
275
+ if (Buffer.byteLength(content, 'utf8') > OWNER_EXPORT_MAX_BYTES)
276
+ throw new HttpFailure(413, 'The owner transcript exceeds the export limit');
277
+ return { ...value, content };
278
+ }
279
+ async createCall(params) {
41
280
  const sidecar = this.deps.sidecar();
42
281
  if (!sidecar)
43
282
  return { state: 'unavailable', reason: 'sidecar_unavailable', snapshot: null, receipt: null };
44
283
  try {
45
- return await sidecar.call('gateway.session', { ...params, profile_home: target.home, session_id: target.sid }, { timeoutMs: params.action === 'mutate' ? 675_000 : 35_000 });
284
+ return await sidecar.call('gateway.create', params, { timeoutMs: 35_000 });
46
285
  }
47
286
  catch {
48
287
  return { state: 'unavailable', reason: 'owner_connection_lost', snapshot: null, receipt: null };
49
288
  }
50
289
  }
290
+ /** TAL-1040: normal always runs; the bypass modes need an owner that freezes them before any Agent import. */
291
+ async modes(profile) {
292
+ const result = await this.createCall({ profile_home: this.deps.profileHome(profile), probe: true });
293
+ const reason = result.state === 'attached' ? null : unavailableReason(result);
294
+ // Owner chats take no file attachments (`submit` refuses them), so a fresh chat in either bypass mode cannot attach.
295
+ return { modes: [{ mode: 'normal', available: true, reason: null, can_attach: true }, ...['ignore_config', 'safe'].map((mode) => ({ mode, available: reason === null, reason, can_attach: false }))] };
296
+ }
297
+ /**
298
+ * TAL-1040: the owner mints a diagnostic chat, freezes its bypass in the creation receipt and runs each turn in a fresh
299
+ * private worker. Talaria keeps no local Session and never falls back to an ordinary chat; no credential is sent.
300
+ */
301
+ async create(profile, creationId, params) {
302
+ // The client's creation id survives a lost response, so a retry recovers the owner's committed session, never a second one.
303
+ const result = await this.createCall({ ...params, profile_home: this.deps.profileHome(profile), request_id: WEB_DIAGNOSTIC_REQUEST_PREFIX + (creationId ?? randomUUID()) });
304
+ if (result.state !== 'attached' || !result.snapshot) {
305
+ throw new HttpFailure(409, 'The Agent cannot start a chat in this mode', { code: 'execution_mode_unavailable', reason: unavailableReason(result) });
306
+ }
307
+ return result.snapshot.session_id;
308
+ }
309
+ async call(target, params, signal) {
310
+ const sidecar = this.deps.sidecar();
311
+ if (!sidecar)
312
+ return { state: 'unavailable', reason: 'sidecar_unavailable', snapshot: null, receipt: null };
313
+ const before = this.modelChanges.get(target.key);
314
+ const modelMutation = params.action === 'mutate' && params.operation === 'model';
315
+ if (modelMutation)
316
+ this.modelMutations.set(target.key, (this.modelMutations.get(target.key) ?? 0) + 1);
317
+ try {
318
+ const result = await sidecar.call('gateway.session', { ...params, profile_home: target.home, session_id: target.sid }, { timeoutMs: params.action === 'mutate' ? 675_000 : 35_000, ...(signal ? { signal } : {}) });
319
+ if (params.action === 'mutate' && params.operation === 'model' && result.snapshot) {
320
+ const change = modelChange(result.receipt ?? {}, params.payload);
321
+ // The stream can resolve a deferred pick before its HTTP ACK returns. Keep the later observation.
322
+ if (change.state !== 'deferred' || this.modelChanges.get(target.key) === before
323
+ || !this.currentModelChange(target, result.snapshot))
324
+ this.rememberModelChange(target, result.snapshot, change);
325
+ }
326
+ const change = this.currentModelChange(target, result.snapshot);
327
+ return { ...result, ...(change ? { model_change: change } : {}) };
328
+ }
329
+ catch {
330
+ return { state: 'unavailable', reason: 'owner_connection_lost', snapshot: null, receipt: null };
331
+ }
332
+ finally {
333
+ if (modelMutation) {
334
+ const remaining = (this.modelMutations.get(target.key) ?? 1) - 1;
335
+ if (remaining)
336
+ this.modelMutations.set(target.key, remaining);
337
+ else {
338
+ this.modelMutations.delete(target.key);
339
+ this.watches.get(target.key)?.reconcile?.();
340
+ }
341
+ }
342
+ }
343
+ }
51
344
  attachment(result) {
52
345
  const snapshot = result.snapshot;
53
346
  const unknown = snapshot?.pending.some((p) => p.status === 'unknown') ?? false;
347
+ const restarting = result.restarting === true;
54
348
  const value = {
55
- state: result.state, reason: result.reason, can_submit: result.state === 'attached' && snapshot !== null && !unknown,
349
+ state: result.state, reason: result.reason, restarting, can_submit: result.state === 'attached' && snapshot !== null && !unknown && !restarting,
56
350
  can_interrupt: result.state === 'attached' && snapshot?.running === true, can_attach: false,
57
351
  revision: snapshot?.revision ?? null, execution_generation: snapshot?.execution_generation ?? null,
58
- active_admission: snapshot?.pending.find((p) => p.status === 'started') ?? null,
352
+ ...(result.model_change ? { model_change: result.model_change } : {}),
353
+ active_admission: snapshot ? runningAdmission(snapshot) ?? null : null,
59
354
  admissions: (snapshot?.pending ?? []).filter((p) => p.status === 'queued' || p.status === 'unknown').map((p) => ({ ...p,
60
- actions: p.status === 'queued' ? ['cancel']
355
+ actions: p.status === 'queued' ? ['cancel', ...(p.controls?.includes('steer') ? ['steer'] : []), ...(p.controls?.includes('replace') ? ['edit'] : [])]
61
356
  : p.execution_generation === null ? []
62
357
  : retryText(p) === null ? ['discard'] : ['retry', 'discard'],
63
358
  })),
64
359
  };
65
360
  return redactNestedMessageContainers(value, this.deps.redactEnabled());
66
361
  }
362
+ contextDetailKey(target, snapshot) {
363
+ return snapshot ? ownerStateId(JSON.stringify([target.key, snapshot.authority_epoch, snapshot.replay_epoch, snapshot.revision, snapshot.execution_generation, snapshot.info, snapshot.last_sequence])) : null;
364
+ }
67
365
  async view(base, result, stream, target, limit = 120, before = null, withMessages = true) {
68
366
  const snapshot = result.snapshot;
69
- const fields = { ...base, owner_attachment: this.attachment(result), composer_state_key: ownerStateId(target.key), active_stream_id: stream, is_streaming: Boolean(stream) };
367
+ const fields = { ...base, owner_attachment: this.attachment({ ...result, model_change: this.currentModelChange(target, snapshot) }), composer_state_key: ownerStateId(target.key), context_detail_key: this.contextDetailKey(target, snapshot), active_stream_id: stream, is_streaming: Boolean(stream) };
70
368
  if (snapshot) {
369
+ fields.notices = this.nativeNotices(target, snapshot);
370
+ const observed = this.watches.get(target.key)?.snapshot;
71
371
  const nativeRows = [...snapshot.messages];
72
- const active = stream ? snapshot.pending.find((p) => p.status === 'started') : null;
372
+ const active = stream ? runningAdmission(snapshot) : null;
73
373
  let start = active ? nativeRows.findIndex((m) => m.role === 'user' && m.message_id === active.admission_id) : -1;
74
374
  if (active && stream && start < 0) {
75
375
  start = nativeRows.length;
@@ -86,6 +386,8 @@ export class GatewaySessions {
86
386
  model_provider: provider, model_option_id: this.deps.service.deps.modelOptionFor?.(model, provider) ?? null,
87
387
  workspace: str(snapshot.info.cwd) || base.workspace, active_stream_id: stream, is_streaming: Boolean(stream), agent_running: snapshot.running,
88
388
  transcript_seq: stream ? { stream_id: stream, seq: 0 } : null,
389
+ tool_calls: withMessages && before === null && stream && snapshot.running && observed && sameExecution(snapshot, observed)
390
+ ? this.deps.service.deps.runtime.liveToolProgress?.(stream) ?? [] : [],
89
391
  });
90
392
  fields.workspace_name = (await this.deps.service.workspaceNames([fields]))(fields);
91
393
  }
@@ -95,7 +397,7 @@ export class GatewaySessions {
95
397
  // The wire's existing owner lock already classified ordinary sessions, including cached pages.
96
398
  if (base.read_only_reason !== CANONICAL_READ_ONLY_REASON)
97
399
  return base;
98
- const target = this.target(str(base.session_id), str(base.profile) || this.deps.activeProfile());
400
+ const target = await this.target(str(base.session_id), str(base.profile) || this.deps.activeProfile());
99
401
  if (!target)
100
402
  return base;
101
403
  const result = await this.call(target, { action: 'snapshot' });
@@ -109,8 +411,8 @@ export class GatewaySessions {
109
411
  return this.view(base, result, watch?.stream ?? null, target, limit, before, withMessages);
110
412
  }
111
413
  /** Called before the direct-chat admission path, including for an already materialized foreign session. */
112
- async submit(sid, body) {
113
- const target = this.target(sid);
414
+ async submit(sid, body, timing) {
415
+ const target = await this.target(sid);
114
416
  if (!target)
115
417
  return null;
116
418
  const text = str(body.message).trim();
@@ -118,7 +420,9 @@ export class GatewaySessions {
118
420
  throw new HttpFailure(400, 'message is required');
119
421
  // Native policy is frozen by its owner. Changing model/workspace travels through session.mutate,
120
422
  // never through a hidden per-turn override or the local Agent setup path.
423
+ const closeSnapshot = timing?.begin('owner_snapshot');
121
424
  const before = await this.call(target, { action: 'snapshot' });
425
+ closeSnapshot?.(before.state === 'unavailable' ? 'unknown' : before.state === 'attached' ? 'ok' : 'refused');
122
426
  if (!this.attachment(before).can_submit)
123
427
  throw new HttpFailure(before.state === 'attached' ? 409 : 403, 'The owning Agent is unavailable or needs an explicit recovery decision', { owner_attachment: this.attachment(before) });
124
428
  if (typeof body.submission_id !== 'string' || !body.submission_id || body.submission_id.length > 128)
@@ -126,17 +430,27 @@ export class GatewaySessions {
126
430
  if (Array.isArray(body.attachments) && body.attachments.length)
127
431
  throw new HttpFailure(400, 'File attachments are unavailable through this owner connection', { code: 'owner_attachments_unavailable' });
128
432
  // Resolve display state before admission; a failed post-ACK read must never turn accepted work into a refusal.
129
- const base = await this.deps.service.detail(sid, {});
433
+ const base = await (timing ? timing.measure('owner_detail', () => this.deps.service.detail(sid, {})) : this.deps.service.detail(sid, {}));
434
+ const closeSubmit = timing?.begin('owner_submit');
130
435
  const result = await this.call(target, { action: 'submit', request_id: body.submission_id, text });
131
- if (!result.receipt)
436
+ closeSubmit?.(result.receipt ? 'ok' : result.state === 'unavailable' ? 'unknown' : 'refused');
437
+ if (result.state === 'attached' && result.snapshot && result.receipt?.voice_stopped === true) {
438
+ const watch = this.watches.get(target.key);
439
+ return { ok: true, status: 'suppressed', reason: 'voice_stopped', session_id: sid,
440
+ owner_attachment: this.attachment(result), session: await this.view(base, result, watch?.stream ?? null, target) };
441
+ }
442
+ if (!result.receipt || !('admission_id' in result.receipt))
132
443
  throw new HttpFailure(409, 'The owner did not confirm this admission. Reconcile it before resending.', { owner_attachment: this.attachment(result), outcome_unknown: result.state === 'unavailable' });
133
444
  const snapshot = result.snapshot;
134
- const watch = snapshot && (snapshot.running || snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started')) ? this.watches.get(target.key) ?? this.watch(target, base, snapshot) : null;
445
+ // A fast refusal can settle before submit returns; its retained completion still belongs to this input.
446
+ const refused = result.receipt.status === 'terminal' && result.receipt.outcome === 'failed';
447
+ const watch = snapshot && (refused || snapshot.running || snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started'))
448
+ ? this.watches.get(target.key) ?? this.watch(target, base, snapshot, refused ? str(result.receipt.admission_id) : undefined) : null;
135
449
  this.deps.events.publish('owner_admission', { profile: target.profile, sessionId: sid });
136
450
  return { session_id: sid, ...(watch ? { stream_id: watch.stream, turn_id: watch.stream } : {}), owner_attachment: this.attachment(result), admission_id: result.receipt.admission_id, session: await this.view(base, result, watch?.stream ?? null, target) };
137
451
  }
138
452
  async action(sid, params) {
139
- const target = this.target(sid);
453
+ const target = await this.target(sid);
140
454
  if (!target)
141
455
  throw new HttpFailure(403, 'This session has no canonical owner');
142
456
  if (params.action === 'mutate' && params.operation === 'workspace') {
@@ -155,7 +469,7 @@ export class GatewaySessions {
155
469
  }
156
470
  /** The display preview is redacted; an explicit retry returns the original text for review, like direct-chat retry. */
157
471
  async retry(sid, admissionId, generation) {
158
- const target = this.target(sid);
472
+ const target = await this.target(sid);
159
473
  if (!target)
160
474
  throw new HttpFailure(403, 'This session has no canonical owner');
161
475
  const current = await this.call(target, { action: 'snapshot' });
@@ -168,7 +482,7 @@ export class GatewaySessions {
168
482
  await this.action(sid, { action: 'discard', admission_id: admissionId, execution_generation: generation });
169
483
  return text;
170
484
  }
171
- prompts(snapshot, sid) {
485
+ prompts(snapshot, sid, batch) {
172
486
  const pending = new PendingPrompts(new SessionEventBus(), this.deps.now);
173
487
  for (const prompt of snapshot?.prompts ?? []) {
174
488
  const data = { ...prompt, session_id: sid, request_id: prompt.prompt_id, timeout_seconds: 0, allowed_choices: prompt.choices, can_enable_yolo: false };
@@ -177,25 +491,56 @@ export class GatewaySessions {
177
491
  else if (prompt.kind === 'clarify')
178
492
  pending.submitClarify(sid, { ...data, clarify_id: prompt.prompt_id });
179
493
  }
494
+ // A fully locked batch waits only for the owner's withdrawal; nothing is left to ask.
495
+ if (batch?.remaining.length) {
496
+ const entry = pending.submitClarify(sid, { session_id: sid, clarify_id: batch.request_id, request_id: batch.request_id, timeout_seconds: 0, questions: batch.questions });
497
+ for (const step of entry.steps)
498
+ step.answered = !batch.remaining.includes(step.qid);
499
+ }
180
500
  return pending;
181
501
  }
502
+ /** The batch the target's live watch received; the owner asks it once, of the viewers attached when it parks. */
503
+ batch(target) { return this.watches.get(target.key)?.batch ?? null; }
504
+ /** Locks each answer; the owner settles the batch on the lock that leaves nothing open. */
505
+ async lockBatch(target, batch, answers) {
506
+ for (const [qid, answer] of Object.entries(answers)) {
507
+ const result = await this.call(target, { action: 'clarify_lock', request_id: batch.request_id, question_id: qid, answer: Array.isArray(answer) ? JSON.stringify(answer) : answer });
508
+ if (result.state === 'attached' && result.lock?.status === 'ok') {
509
+ batch.remaining = result.lock.remaining ?? [];
510
+ continue;
511
+ }
512
+ if (result.lock?.status === 'expired')
513
+ batch.remaining = [];
514
+ // An unconfirmed lock keeps the card and its answers for a retry; an ended batch or a refusal is stale.
515
+ throw new HttpFailure(result.state === 'unavailable' ? 503 : 409, 'The owning Agent did not accept this answer', { owner_attachment: this.attachment(result) });
516
+ }
517
+ }
182
518
  async pending(sid, kind) {
183
- const target = this.target(sid);
519
+ const target = await this.target(sid);
184
520
  if (!target)
185
521
  throw new HttpFailure(404, 'Session not found');
186
522
  const result = await this.call(target, { action: 'snapshot' });
187
- const pending = this.prompts(result.snapshot, sid);
523
+ const pending = this.prompts(result.snapshot, sid, this.batch(target));
188
524
  const envelope = kind === 'approval' ? pending.approvalPending(sid) : pending.clarifyPending(sid);
189
525
  return { pending: envelope.pending ? redactNestedMessageContainers(envelope.pending, this.deps.redactEnabled()) : null, pending_count: envelope.pending_count };
190
526
  }
191
527
  async respond(sid, kind, id, value) {
192
- const target = this.target(sid);
528
+ const target = await this.target(sid);
193
529
  if (!target)
194
530
  return false;
195
531
  const current = await this.call(target, { action: 'snapshot' });
196
- const pending = this.prompts(current.snapshot, sid);
532
+ const batch = this.batch(target);
533
+ const pending = this.prompts(current.snapshot, sid, batch);
197
534
  if (current.state !== 'attached')
198
535
  throw new HttpFailure(403, 'This canonical session is read-only while its owner is unavailable');
536
+ if (kind === 'clarify' && batch?.remaining.length && batch.request_id === id) {
537
+ const entry = pending.peekClarify(sid, id);
538
+ const reply = entry && value !== null ? clarifyReply(entry, value) : null;
539
+ if (reply === null)
540
+ throw new HttpFailure(400, 'Answer every question in the pending clarification');
541
+ await this.lockBatch(target, batch, JSON.parse(reply).answers);
542
+ return true;
543
+ }
199
544
  const prompt = current.snapshot?.prompts.find((p) => p.kind === kind && p.prompt_id === id);
200
545
  if (!prompt)
201
546
  throw new HttpFailure(409, 'The owner prompt is stale');
@@ -228,9 +573,30 @@ export class GatewaySessions {
228
573
  await this.action(sid, { action: 'interrupt', execution_generation: watch.snapshot.execution_generation });
229
574
  return true;
230
575
  }
231
- watch(target, base, snapshot) {
232
- const watch = { stream: `${ownerStreamPrefix(target.home)}${randomUUID()}`, controller: new AbortController(), snapshot };
576
+ watch(target, base, snapshot, admissionId) {
577
+ const watch = { stream: `${ownerStreamPrefix(target.home)}${randomUUID()}`, controller: new AbortController(), snapshot, batch: null, restarting: false };
233
578
  this.watches.set(target.key, watch);
579
+ const observation = this.transport(target, base, snapshot);
580
+ const release = this.lease(observation);
581
+ let activeAdmission = admissionId ?? runningAdmission(snapshot)?.admission_id ?? snapshot.pending.find((p) => !p.steering)?.admission_id;
582
+ let receive = null;
583
+ const buffered = [{ event: 'snapshot', seq: 0, data: { state: 'attached', reason: null, snapshot, receipt: null, replaying: true } }];
584
+ const completed = observation.completion?.data;
585
+ if (completed?.authority_epoch === snapshot.authority_epoch && completed.replay_epoch === snapshot.replay_epoch
586
+ && completed.execution_generation === snapshot.execution_generation && (completed.payload ?? {}).admission_id === activeAdmission)
587
+ buffered.push(observation.completion);
588
+ if (!observation.replaying)
589
+ buffered.push({ event: 'replay_complete', seq: 0, data: {} });
590
+ const listener = (frame) => {
591
+ if (receive)
592
+ receive(frame);
593
+ else if (buffered.length < 4096)
594
+ buffered.push(frame);
595
+ else
596
+ watch.controller.abort();
597
+ };
598
+ observation.listeners.add(listener);
599
+ watch.controller.signal.addEventListener('abort', () => { observation.listeners.delete(listener); release(); }, { once: true });
234
600
  const registry = this.deps.registry;
235
601
  const channel = registry.create(watch.stream, target.sid);
236
602
  registry.registerActiveRun({ stream_id: watch.stream, session_id: target.sid, phase: 'running', started_at: this.deps.now(), workspace: str(base.workspace), model: str(base.model) || null, provider: null, ephemeral: false, origin: 'user' });
@@ -238,38 +604,88 @@ export class GatewaySessions {
238
604
  let terminal = false;
239
605
  let streamError = null;
240
606
  let closeWriter = null;
241
- let activeAdmission = snapshot.pending.find((p) => p.status === 'started')?.admission_id ?? snapshot.pending[0]?.admission_id;
607
+ const enqueue = (work) => {
608
+ chain = chain.then(async () => { if (!terminal && !streamError)
609
+ await work(); })
610
+ .catch((error) => { streamError = error; watch.controller.abort(); });
611
+ };
242
612
  const worker = async () => {
243
613
  // Same persisted IDs can exist in separate homes. Native observation journals must not
244
614
  // join the sid-only direct-chat journal; the owner retains the canonical transcript.
245
615
  const journalSession = ownerStateId(target.key);
246
616
  const writer = await this.deps.journal.writer(journalSession, watch.stream);
247
617
  closeWriter = writer;
618
+ const showReasoning = await this.deps.showReasoning(target.home).catch(() => false);
619
+ let completion = null;
620
+ let replaying = true;
621
+ let usage = {};
622
+ let reasoning = '';
623
+ let titles = new ReasoningTitleTracker();
624
+ const calls = registry.liveToolCalls.get(watch.stream);
248
625
  const put = async (event, data) => {
249
626
  const safe = event === 'tool' || event === 'tool_complete' ? publicToolFrame(data, this.deps.redactEnabled()) : redactNestedMessageContainers(data, this.deps.redactEnabled());
627
+ // Progress is ephemeral, just like direct turns; a reload gets the channel's latest value after journal replay.
628
+ if (event === 'tool_progress') {
629
+ channel.put([event, safe, null, this.deps.redactEnabled()]);
630
+ return;
631
+ }
250
632
  const record = await writer.appendSseEvent(event, safe);
251
633
  channel.put([event, safe, record.event_id]);
252
634
  };
635
+ const clearTools = async () => {
636
+ for (const call of calls)
637
+ if (call.progress)
638
+ await put('tool_progress', { id: call.tid, progress: null });
639
+ calls.length = 0;
640
+ };
641
+ const resetProjection = async () => { await clearTools(); reasoning = ''; usage = {}; completion = null; titles = new ReasoningTitleTracker(); };
642
+ const meter = async (data) => {
643
+ usage = { ...usage, ...ownerUsage(data) };
644
+ if (['input_tokens', 'output_tokens', 'cache_read_tokens', 'cache_write_tokens'].every((key) => typeof usage[key] === 'number'))
645
+ await put('metering', { session_id: target.sid, usage: { ...usage, estimated_cost: usage.estimated_cost ?? null }, tps: usage.tps ?? null, tps_available: usage.tps !== undefined, estimated: false });
646
+ };
253
647
  const finish = async () => {
254
- if (terminal)
648
+ // A model pick resolves at the owner's next claim boundary, after the turn becomes idle.
649
+ if (terminal || replaying || this.modelMutations.has(target.key) || this.currentModelChange(target, watch.snapshot)?.state === 'deferred')
255
650
  return;
256
651
  terminal = true;
652
+ // A new claim may arrive while this turn's receipt is being read. Give it its own projection immediately.
653
+ if (this.watches.get(target.key) === watch)
654
+ this.watches.delete(target.key);
655
+ registry.retire(watch.stream);
656
+ await clearTools();
257
657
  const current = await this.call(target, { action: 'snapshot' });
258
- const receipt = activeAdmission ? (await this.call(target, { action: 'receipt', admission_id: activeAdmission })).receipt : null;
658
+ const rawReceipt = activeAdmission ? (await this.call(target, { action: 'receipt', admission_id: activeAdmission })).receipt : null;
659
+ const receipt = rawReceipt && 'admission_id' in rawReceipt ? rawReceipt : null;
259
660
  const cancelled = receipt?.outcome === 'interrupted' || receipt?.outcome === 'cancelled';
260
661
  const failed = current.state !== 'attached' || receipt?.status !== 'terminal' || receipt.outcome !== 'completed' && !cancelled;
662
+ const refusal = current.state === 'attached' && current.snapshot && sameExecution(current.snapshot, watch.snapshot)
663
+ && receipt?.status === 'terminal' && receipt.outcome === 'failed' && completion && completion.admission === activeAdmission
664
+ && receipt.authority_epoch === watch.snapshot.authority_epoch && receipt.execution_generation === watch.snapshot.execution_generation
665
+ ? { message: completion.message, type: completion.type, code: completion.code, retryable: completion.retryable } : null;
666
+ // A terminal frame for the previous generation must not overwrite the newer turn's state.
667
+ const session = current.snapshot && !sameExecution(current.snapshot, observation.snapshot)
668
+ ? undefined : { ...await this.view(base, current, null, target), ...usage };
261
669
  await put(cancelled ? 'cancel' : failed ? 'apperror' : 'done', { session_id: target.sid,
262
670
  terminal_state: cancelled ? 'cancelled' : failed ? 'error' : 'completed',
263
- ...(failed ? { message: 'The owning Agent could not complete this turn', type: current.reason ?? 'owner_turn_failed' } : {}),
264
- session: await this.view(base, current, null, target) });
671
+ ...(failed ? refusal ?? { message: 'The owning Agent could not complete this turn', type: current.reason ?? 'owner_turn_failed' } : {}),
672
+ ...(Object.keys(usage).length ? { usage } : {}),
673
+ ...(session ? { session } : {}) });
265
674
  await put('stream_end', { session_id: target.sid });
266
675
  watch.controller.abort();
267
676
  };
268
- let pending = this.prompts(snapshot, target.sid);
677
+ // Reconcile after the last in-flight mutation releases its fence, in the same order as owner frames.
678
+ watch.reconcile = () => {
679
+ enqueue(async () => {
680
+ if (!watch.snapshot.running && !watch.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started'))
681
+ await finish();
682
+ });
683
+ };
684
+ let pending = this.prompts(snapshot, target.sid, watch.batch);
269
685
  let ran = snapshot.running;
270
686
  const prompts = async (snap) => {
271
687
  watch.snapshot = snap;
272
- pending = this.prompts(snap, target.sid);
688
+ pending = this.prompts(snap, target.sid, watch.batch);
273
689
  const approval = pending.approvalPending(target.sid);
274
690
  if (approval.pending)
275
691
  await put('approval', { ...approval.pending, pending_count: approval.pending_count });
@@ -278,67 +694,177 @@ export class GatewaySessions {
278
694
  await put('clarify', clarify);
279
695
  };
280
696
  await prompts(snapshot);
281
- const sidecar = this.deps.sidecar();
282
- if (!sidecar)
283
- throw new Error('sidecar_unavailable');
284
697
  if (watch.controller.signal.aborted)
285
698
  return;
286
- const result = await sidecar.call('gateway.session', { profile_home: target.home, session_id: target.sid, action: 'watch' }, {
287
- signal: watch.controller.signal, timeoutMs: 0,
288
- onStream: (frame) => {
289
- chain = chain.then(async () => {
290
- if (terminal || streamError)
699
+ receive = (frame) => {
700
+ enqueue(async () => {
701
+ if (frame.event === 'replay_complete') {
702
+ replaying = false;
703
+ if (!watch.snapshot.running && !watch.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started'))
704
+ await finish();
705
+ return;
706
+ }
707
+ if (frame.event === 'restarting') {
708
+ // The owner entered a restart's after-turn wait after this watch attached: clients stop sending.
709
+ watch.restarting = true;
710
+ await put('session_snapshot', { session: await this.view(base, { state: 'attached', reason: null, snapshot: watch.snapshot, receipt: null, restarting: true }, watch.stream, target) });
711
+ return;
712
+ }
713
+ if (frame.event === 'clarify_batch') {
714
+ const batch = GatewayClarifyBatchSchema.parse(frame.data);
715
+ watch.batch = { ...batch, remaining: batch.questions.map((q) => q.qid) };
716
+ await prompts(watch.snapshot);
717
+ return;
718
+ }
719
+ if (frame.event === 'snapshot') {
720
+ const result = GatewaySessionResultSchema.parse(frame.data);
721
+ replaying = frame.data.replaying === true;
722
+ if (!result.snapshot)
291
723
  return;
292
- if (frame.event === 'snapshot') {
293
- const result = GatewaySessionResultSchema.parse(frame.data);
294
- if (!result.snapshot)
295
- return;
296
- await put('session_snapshot', { session: await this.view(base, result, watch.stream, target), replay_gap: result.replay_gap === true });
297
- await prompts(result.snapshot);
298
- if (!result.snapshot.running && !result.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started'))
299
- await finish();
724
+ if (result.replay_gap || !sameExecution(result.snapshot, watch.snapshot))
725
+ await resetProjection();
726
+ await put('session_snapshot', { session: await this.view(base, result, watch.stream, target), replay_gap: result.replay_gap === true });
727
+ await prompts(result.snapshot);
728
+ if (!result.snapshot.running && !result.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started'))
729
+ await finish();
730
+ return;
731
+ }
732
+ const event = frame.data;
733
+ const data = (event.payload ?? {});
734
+ const kind = str(event.type);
735
+ if (kind === 'notification.show' || kind === 'notification.clear') {
736
+ await put('notices', { session_id: target.sid, notices: this.nativeNotices(target, observation.snapshot) });
737
+ return;
738
+ }
739
+ if (kind === 'request.cancel') {
740
+ // The owner withdraws a settled, timed-out or interrupted batch from every viewer.
741
+ if (!watch.batch || watch.batch.request_id !== data.id)
742
+ return;
743
+ watch.batch = null;
744
+ await prompts(watch.snapshot);
745
+ if (!pending.clarifyHeadFrame(target.sid))
746
+ await put('clarify', { status: 'resolved', clarify_id: data.id });
747
+ return;
748
+ }
749
+ if (kind === 'session.updated') {
750
+ // Idle owner mutations carry no execution stamp. The sidecar scopes their subscription and replay.
751
+ if (event.session_id !== target.sid
752
+ || event.authority_epoch !== undefined && event.authority_epoch !== watch.snapshot.authority_epoch
753
+ || event.execution_generation !== undefined && event.execution_generation !== watch.snapshot.execution_generation)
754
+ return;
755
+ if (data.operation !== 'model')
756
+ return;
757
+ this.rememberModelChange(target, watch.snapshot, modelChange(data));
758
+ const current = await this.call(target, { action: 'snapshot' });
759
+ if (current.snapshot)
760
+ watch.snapshot = current.snapshot;
761
+ await put('session_snapshot', { session: await this.view(base, current, watch.stream, target) });
762
+ if (!watch.snapshot.running && !watch.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started'))
763
+ await finish();
764
+ return;
765
+ }
766
+ if (kind === 'session.info') {
767
+ if (data.authority_epoch !== watch.snapshot.authority_epoch)
768
+ return;
769
+ if (Number(data.execution_generation) < watch.snapshot.execution_generation)
300
770
  return;
771
+ const firstClaim = !ran && data.running === true;
772
+ if (Number(data.execution_generation) > watch.snapshot.execution_generation)
773
+ await resetProjection();
774
+ watch.snapshot = { ...watch.snapshot, ...data };
775
+ const claimed = runningAdmission(watch.snapshot);
776
+ if (firstClaim && claimed)
777
+ activeAdmission = claimed.admission_id;
778
+ ran ||= data.running === true;
779
+ if (firstClaim)
780
+ await put('session_snapshot', { session: await this.view(base, { state: 'attached', reason: null, snapshot: watch.snapshot, receipt: null, restarting: watch.restarting }, watch.stream, target) });
781
+ if (data.running === false && (ran || !watch.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started')))
782
+ await finish();
783
+ return;
784
+ }
785
+ if (event.authority_epoch !== watch.snapshot.authority_epoch || event.execution_generation !== watch.snapshot.execution_generation)
786
+ return;
787
+ if (kind === 'message.delta') {
788
+ const stable = titles.stableSnapshot(reasoning);
789
+ if (stable !== null)
790
+ await put('reasoning', { text: '', titles: stable });
791
+ await put('token', { text: str(data.text || data.delta || data.content) });
792
+ }
793
+ else if (kind === 'reasoning.delta' && showReasoning) {
794
+ reasoning += str(data.text);
795
+ await put('reasoning', titles.prepare(reasoningEventPayload(data.text, reasoning)));
796
+ }
797
+ else if (kind.startsWith('subagent.') && str(data.subagent_id)) {
798
+ // Reuse the delegate activity row; each child keeps one identity through progress and completion.
799
+ const complete = kind === 'subagent.complete';
800
+ const preview = kind === 'subagent.thinking' && !showReasoning ? '' : str(data.summary || data.tool_preview || data.text);
801
+ await put(complete ? 'tool_complete' : 'tool', { id: `owner-subagent-${str(data.subagent_id)}`, name: 'subagent_progress',
802
+ args: { task: str(data.goal) }, preview: preview || null,
803
+ ...(complete ? { is_error: data.status !== 'completed', duration: data.duration_seconds } : {}) });
804
+ }
805
+ else if (kind === 'session.usage')
806
+ await meter(data);
807
+ else if (kind === 'message.complete') {
808
+ if (event.session_id !== target.sid || event.replay_epoch !== undefined && event.replay_epoch !== watch.snapshot.replay_epoch)
809
+ return;
810
+ // Only this owner-defined refusal is public; never forward provider diagnostics or private descriptor fields.
811
+ const surface = data.error_surface;
812
+ if (activeAdmission && data.admission_id === activeAdmission && data.outcome === 'failed' && data.status === 'error'
813
+ && surface?.layer === 'gateway' && surface.code === 'cron_session_read_only' && surface.retryable === false
814
+ && typeof data.text === 'string' && data.text.trim()) {
815
+ completion = { admission: activeAdmission, message: data.text, type: 'cron_session_read_only', code: 'cron_session_read_only', retryable: false };
301
816
  }
302
- const event = frame.data;
303
- const data = (event.payload ?? {});
304
- const kind = str(event.type);
305
- if (kind === 'session.info') {
306
- if (data.authority_epoch !== watch.snapshot.authority_epoch)
817
+ if (data.usage && typeof data.usage === 'object')
818
+ await meter(data.usage);
819
+ }
820
+ else if (kind === 'tool.start' || kind === 'tool.progress' || kind === 'tool.complete') {
821
+ if (event.session_id !== target.sid || event.replay_epoch !== undefined && event.replay_epoch !== watch.snapshot.replay_epoch)
822
+ return;
823
+ const id = str(data.tool_id) || str(data.tool_call_id);
824
+ const call = calls.findLast((call) => call.tid === id);
825
+ if (kind === 'tool.start') {
826
+ if (id && call)
307
827
  return;
308
- if (Number(data.execution_generation) < watch.snapshot.execution_generation)
828
+ calls.push({ tid: id, name: data.name || data.tool_name, args: data.args ?? {}, done: false });
829
+ await put('tool', { ...data, id, name: data.name || data.tool_name });
830
+ }
831
+ else if (kind === 'tool.progress') {
832
+ if (!id || !call || call.done || !watch.snapshot.running)
309
833
  return;
310
- const firstClaim = !ran && data.running === true;
311
- watch.snapshot = { ...watch.snapshot, ...data };
312
- const claimed = watch.snapshot.pending.find((p) => p.status === 'started');
313
- if (firstClaim && claimed)
314
- activeAdmission = claimed.admission_id;
315
- ran ||= data.running === true;
316
- if (firstClaim)
317
- await put('session_snapshot', { session: await this.view(base, { state: 'attached', reason: null, snapshot: watch.snapshot, receipt: null }, watch.stream, target) });
318
- if (data.running === false && (ran || !watch.snapshot.pending.some((p) => p.status === 'queued' || p.status === 'started')))
319
- await finish();
320
- return;
834
+ call.progress = toolProgress({ ...data, message: typeof data.message === 'string' ? redactString(data.message, this.deps.redactEnabled()) : null });
835
+ await put('tool_progress', { id, progress: call.progress });
321
836
  }
322
- if (event.authority_epoch !== watch.snapshot.authority_epoch || event.execution_generation !== watch.snapshot.execution_generation)
323
- return;
324
- if (kind === 'message.delta')
325
- await put('token', { text: str(data.text || data.delta || data.content) });
326
- else if (kind === 'tool.start')
327
- await put('tool', { ...data, id: data.tool_id || data.tool_call_id, name: data.name || data.tool_name });
328
- else if (kind === 'tool.complete')
329
- await put('tool_complete', { ...data, id: data.tool_id || data.tool_call_id, name: data.name || data.tool_name });
330
- else if (kind === 'approval.request' || kind === 'clarify.request')
331
- await prompts({ ...watch.snapshot, prompts: [...watch.snapshot.prompts.filter((p) => p.prompt_id !== data.prompt_id), { ...data, kind: kind.split('.')[0] }] });
332
- else if (kind === 'approval.settled' || kind === 'clarify.settled') {
333
- await prompts({ ...watch.snapshot, prompts: watch.snapshot.prompts.filter((p) => p.prompt_id !== data.prompt_id) });
334
- if (kind === 'approval.settled' && !pending.approvalPending(target.sid).pending)
335
- await put('approval_cleared', { pending_count: 0 });
336
- if (kind === 'clarify.settled' && !pending.clarifyHeadFrame(target.sid))
337
- await put('clarify', { status: 'resolved', clarify_id: data.prompt_id });
837
+ else {
838
+ if (call?.done)
839
+ return;
840
+ if (call)
841
+ Object.assign(call, { done: true, progress: null });
842
+ await put('tool_complete', { ...data, id, name: data.name || data.tool_name, progress: null });
338
843
  }
339
- }).catch((error) => { streamError = error; watch.controller.abort(); });
340
- },
341
- });
844
+ }
845
+ else if (kind === 'approval.request' || kind === 'clarify.request')
846
+ await prompts({ ...watch.snapshot, prompts: [...watch.snapshot.prompts.filter((p) => p.prompt_id !== data.prompt_id), { ...data, kind: kind.split('.')[0] }] });
847
+ else if (kind === 'approval.settled' || kind === 'clarify.settled') {
848
+ await prompts({ ...watch.snapshot, prompts: watch.snapshot.prompts.filter((p) => p.prompt_id !== data.prompt_id) });
849
+ if (kind === 'approval.settled' && !pending.approvalPending(target.sid).pending)
850
+ await put('approval_cleared', { pending_count: 0 });
851
+ if (kind === 'clarify.settled' && !pending.clarifyHeadFrame(target.sid))
852
+ await put('clarify', { status: 'resolved', clarify_id: data.prompt_id });
853
+ }
854
+ });
855
+ };
856
+ for (const frame of buffered.splice(0))
857
+ receive(frame);
858
+ const result = await Promise.race([
859
+ observation.ended,
860
+ new Promise((resolve) => {
861
+ const stopped = () => { resolve({ state: 'attached', reason: null, snapshot: watch.snapshot, receipt: null }); };
862
+ if (watch.controller.signal.aborted)
863
+ stopped();
864
+ else
865
+ watch.controller.signal.addEventListener('abort', stopped, { once: true });
866
+ }),
867
+ ]);
342
868
  await chain;
343
869
  if (streamError)
344
870
  throw streamError instanceof Error ? streamError : new Error('Owner stream projection failed');
@@ -348,13 +874,15 @@ export class GatewaySessions {
348
874
  watch.controller.abort();
349
875
  }
350
876
  };
351
- watch.worker = worker().catch((error) => {
877
+ const running = worker().catch((error) => {
352
878
  // Closing the sidecar after a terminal snapshot is expected; every other exit is observable.
353
879
  if (!terminal)
354
880
  channel.put(['apperror', { message: 'The owning Agent connection ended', type: 'owner_unavailable', terminal_state: 'error' }, null]);
355
881
  this.deps.log(`[webui] owner observation ended: ${error instanceof Error ? error.name : 'error'}`);
356
882
  }).finally(async () => {
357
883
  watch.controller.abort();
884
+ observation.listeners.delete(listener);
885
+ release();
358
886
  try {
359
887
  await closeWriter?.close();
360
888
  }
@@ -364,15 +892,23 @@ export class GatewaySessions {
364
892
  if (this.watches.get(target.key) === watch)
365
893
  this.watches.delete(target.key);
366
894
  registry.retire(watch.stream);
895
+ this.changed(target);
367
896
  this.deps.events.publish('owner_changed', { profile: target.profile, sessionId: target.sid });
897
+ this.runWorkers.delete(running);
368
898
  });
899
+ this.runWorkers.add(running);
369
900
  return watch;
370
901
  }
371
902
  async close() {
903
+ const observations = [...this.observations.values()];
904
+ for (const observation of observations)
905
+ observation.controller.abort();
372
906
  const watches = [...this.watches.values()];
373
907
  for (const watch of watches)
374
908
  watch.controller.abort();
375
- await Promise.allSettled(watches.flatMap((watch) => watch.worker ? [watch.worker] : []));
909
+ await Promise.allSettled([...this.runWorkers]);
910
+ await Promise.allSettled(observations.map((observation) => observation.ended));
911
+ this.modelChanges.clear();
376
912
  }
377
913
  }
378
914
  //# sourceMappingURL=gateway-sessions.js.map