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