@maudecode/talaria-web 1.21.0 → 1.23.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/_release.json +4 -4
  2. package/dist/api/automation-router.d.ts +14 -14
  3. package/dist/api/chat-router.d.ts +225 -68
  4. package/dist/api/groups-router.d.ts +764 -0
  5. package/dist/api/groups-router.js +79 -0
  6. package/dist/api/groups-router.js.map +1 -0
  7. package/dist/api/raw-routes.d.ts +1 -1
  8. package/dist/api/raw-routes.js +15 -3
  9. package/dist/api/raw-routes.js.map +1 -1
  10. package/dist/api/router.d.ts +41 -0
  11. package/dist/api/router.js +2 -0
  12. package/dist/api/router.js.map +1 -1
  13. package/dist/api/sessions-router.d.ts +590 -160
  14. package/dist/api/sessions-router.js +14 -14
  15. package/dist/api/sessions-router.js.map +1 -1
  16. package/dist/api/settings-router.d.ts +948 -1
  17. package/dist/api/settings-router.js +54 -2
  18. package/dist/api/settings-router.js.map +1 -1
  19. package/dist/api/sse-routes.d.ts +1 -1
  20. package/dist/api/sse-routes.js +11 -3
  21. package/dist/api/sse-routes.js.map +1 -1
  22. package/dist/api/tools-raw.js +27 -136
  23. package/dist/api/tools-raw.js.map +1 -1
  24. package/dist/api/tools-router.d.ts +109 -24
  25. package/dist/api/tools-router.js +69 -9
  26. package/dist/api/tools-router.js.map +1 -1
  27. package/dist/app.js +5 -1
  28. package/dist/app.js.map +1 -1
  29. package/dist/auth/gate.js +5 -1
  30. package/dist/auth/gate.js.map +1 -1
  31. package/dist/cli/ctl.d.ts +5 -2
  32. package/dist/cli/ctl.js +90 -42
  33. package/dist/cli/ctl.js.map +1 -1
  34. package/dist/config/agent-config.d.ts +6 -1
  35. package/dist/config/agent-config.js +75 -3
  36. package/dist/config/agent-config.js.map +1 -1
  37. package/dist/feedback.d.ts +21 -0
  38. package/dist/feedback.js +328 -0
  39. package/dist/feedback.js.map +1 -0
  40. package/dist/fs/stat.d.ts +2 -0
  41. package/dist/fs/stat.js +4 -0
  42. package/dist/fs/stat.js.map +1 -1
  43. package/dist/http/context.d.ts +10 -1
  44. package/dist/http/context.js +0 -6
  45. package/dist/http/context.js.map +1 -1
  46. package/dist/http/pinned.js +19 -8
  47. package/dist/http/pinned.js.map +1 -1
  48. package/dist/providers/catalog.d.ts +10 -2
  49. package/dist/providers/catalog.js +113 -15
  50. package/dist/providers/catalog.js.map +1 -1
  51. package/dist/redact.js +9 -3
  52. package/dist/redact.js.map +1 -1
  53. package/dist/release.d.ts +14 -1
  54. package/dist/release.js +40 -2
  55. package/dist/release.js.map +1 -1
  56. package/dist/runtime.js +29 -5
  57. package/dist/runtime.js.map +1 -1
  58. package/dist/server.js +1 -0
  59. package/dist/server.js.map +1 -1
  60. package/dist/sessions/anchor.d.ts +3 -2
  61. package/dist/sessions/anchor.js +11 -10
  62. package/dist/sessions/anchor.js.map +1 -1
  63. package/dist/sessions/cli-sessions.js +11 -6
  64. package/dist/sessions/cli-sessions.js.map +1 -1
  65. package/dist/sessions/compress.d.ts +10 -9
  66. package/dist/sessions/compress.js +31 -20
  67. package/dist/sessions/compress.js.map +1 -1
  68. package/dist/sessions/gateway-sessions.d.ts +11 -0
  69. package/dist/sessions/gateway-sessions.js +79 -24
  70. package/dist/sessions/gateway-sessions.js.map +1 -1
  71. package/dist/sessions/gateway-watcher.js +8 -4
  72. package/dist/sessions/gateway-watcher.js.map +1 -1
  73. package/dist/sessions/groups.d.ts +60 -0
  74. package/dist/sessions/groups.js +339 -0
  75. package/dist/sessions/groups.js.map +1 -0
  76. package/dist/sessions/list.d.ts +8 -3
  77. package/dist/sessions/list.js +17 -6
  78. package/dist/sessions/list.js.map +1 -1
  79. package/dist/sessions/merge.d.ts +14 -5
  80. package/dist/sessions/merge.js +42 -13
  81. package/dist/sessions/merge.js.map +1 -1
  82. package/dist/sessions/pending.d.ts +1 -1
  83. package/dist/sessions/pending.js +15 -6
  84. package/dist/sessions/pending.js.map +1 -1
  85. package/dist/sessions/prefix-index.d.ts +1 -14
  86. package/dist/sessions/prefix-index.js +1 -50
  87. package/dist/sessions/prefix-index.js.map +1 -1
  88. package/dist/sessions/reasoning-display.d.ts +2 -0
  89. package/dist/sessions/reasoning-display.js +31 -0
  90. package/dist/sessions/reasoning-display.js.map +1 -0
  91. package/dist/sessions/relay.d.ts +34 -2
  92. package/dist/sessions/relay.js +84 -7
  93. package/dist/sessions/relay.js.map +1 -1
  94. package/dist/sessions/service.d.ts +7 -2
  95. package/dist/sessions/service.js +106 -64
  96. package/dist/sessions/service.js.map +1 -1
  97. package/dist/sessions/session.d.ts +6 -0
  98. package/dist/sessions/session.js +13 -0
  99. package/dist/sessions/session.js.map +1 -1
  100. package/dist/sessions/shares.d.ts +3 -1
  101. package/dist/sessions/shares.js +33 -11
  102. package/dist/sessions/shares.js.map +1 -1
  103. package/dist/sessions/source-kind.js +2 -0
  104. package/dist/sessions/source-kind.js.map +1 -1
  105. package/dist/sessions/state-db.d.ts +2 -1
  106. package/dist/sessions/state-db.js +12 -5
  107. package/dist/sessions/state-db.js.map +1 -1
  108. package/dist/sessions/storage/json-documents.js +2 -0
  109. package/dist/sessions/storage/json-documents.js.map +1 -1
  110. package/dist/sessions/store.d.ts +1 -0
  111. package/dist/sessions/store.js +10 -3
  112. package/dist/sessions/store.js.map +1 -1
  113. package/dist/sessions/streams.d.ts +7 -2
  114. package/dist/sessions/streams.js +16 -6
  115. package/dist/sessions/streams.js.map +1 -1
  116. package/dist/sessions/titles.d.ts +2 -0
  117. package/dist/sessions/titles.js +11 -0
  118. package/dist/sessions/titles.js.map +1 -1
  119. package/dist/sessions/todo.js +10 -1
  120. package/dist/sessions/todo.js.map +1 -1
  121. package/dist/sessions/turn.js +50 -21
  122. package/dist/sessions/turn.js.map +1 -1
  123. package/dist/settings.js +6 -1
  124. package/dist/settings.js.map +1 -1
  125. package/dist/sidecar/client.d.ts +3 -0
  126. package/dist/sidecar/client.js +2 -1
  127. package/dist/sidecar/client.js.map +1 -1
  128. package/dist/sidecar/discover.js +3 -2
  129. package/dist/sidecar/discover.js.map +1 -1
  130. package/dist/spa.js +1 -1
  131. package/dist/spa.js.map +1 -1
  132. package/dist/test/group-fixture.d.ts +66 -0
  133. package/dist/test/group-fixture.js +89 -0
  134. package/dist/test/group-fixture.js.map +1 -0
  135. package/dist/test/harness.d.ts +3 -0
  136. package/dist/test/harness.js +3 -0
  137. package/dist/test/harness.js.map +1 -1
  138. package/dist/tools/connectors.d.ts +9 -1
  139. package/dist/tools/connectors.js +48 -0
  140. package/dist/tools/connectors.js.map +1 -1
  141. package/dist/tools/gateway-restart.d.ts +1 -1
  142. package/dist/tools/insights.d.ts +3 -0
  143. package/dist/tools/insights.js +6 -7
  144. package/dist/tools/insights.js.map +1 -1
  145. package/dist/tools/skills.d.ts +6 -0
  146. package/dist/tools/skills.js +17 -0
  147. package/dist/tools/skills.js.map +1 -1
  148. package/dist/tools/update-notifications.d.ts +2 -0
  149. package/dist/tools/update-notifications.js +7 -3
  150. package/dist/tools/update-notifications.js.map +1 -1
  151. package/dist/tools/updates.d.ts +26 -9
  152. package/dist/tools/updates.js +144 -47
  153. package/dist/tools/updates.js.map +1 -1
  154. package/dist/workspace/fs.d.ts +2 -0
  155. package/dist/workspace/fs.js +63 -1
  156. package/dist/workspace/fs.js.map +1 -1
  157. package/dist/workspace/media-refs.js +10 -3
  158. package/dist/workspace/media-refs.js.map +1 -1
  159. package/dist/workspace/upload.d.ts +1 -1
  160. package/dist/workspace/upload.js +52 -37
  161. package/dist/workspace/upload.js.map +1 -1
  162. package/dist/workspace/workspaces.d.ts +5 -1
  163. package/dist/workspace/workspaces.js +32 -6
  164. package/dist/workspace/workspaces.js.map +1 -1
  165. package/package.json +4 -3
  166. package/sidecar/agent_importer.json +8 -0
  167. package/sidecar/scripts/agent_importer_contract.py +19 -0
  168. package/sidecar/scripts/suite_runner.py +55 -8
  169. package/sidecar/scripts/test.sh +3 -1
  170. package/sidecar/talaria_sidecar/__init__.py +1 -1
  171. package/sidecar/talaria_sidecar/home.py +12 -5
  172. package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
  173. package/sidecar/talaria_sidecar/methods/agent_imports.py +346 -0
  174. package/sidecar/talaria_sidecar/methods/chat.py +141 -58
  175. package/sidecar/talaria_sidecar/methods/commands.py +6 -4
  176. package/sidecar/talaria_sidecar/methods/config.py +8 -3
  177. package/sidecar/talaria_sidecar/methods/connectors.py +138 -4
  178. package/sidecar/talaria_sidecar/methods/dashboard_plugins.py +21 -0
  179. package/sidecar/talaria_sidecar/methods/delegation.py +126 -0
  180. package/sidecar/talaria_sidecar/methods/gateway.py +5 -0
  181. package/sidecar/talaria_sidecar/methods/gateway_sessions.py +35 -6
  182. package/sidecar/talaria_sidecar/methods/groups.py +120 -0
  183. package/sidecar/talaria_sidecar/methods/memory.py +27 -3
  184. package/sidecar/talaria_sidecar/methods/nous_account.py +130 -0
  185. package/sidecar/talaria_sidecar/methods/oauth.py +25 -4
  186. package/sidecar/talaria_sidecar/methods/outbound_drafts.py +1 -19
  187. package/sidecar/talaria_sidecar/methods/plugin_catalog.py +73 -2
  188. package/sidecar/talaria_sidecar/methods/providers.py +51 -1
  189. package/sidecar/talaria_sidecar/methods/skill_revisions.py +177 -0
  190. package/sidecar/talaria_sidecar/methods/skills.py +10 -0
  191. package/sidecar/talaria_sidecar/methods/tts.py +67 -0
  192. package/sidecar/talaria_sidecar/rpc.py +11 -2
  193. package/static/dist/FILES.txt +154 -143
  194. package/static/dist/THIRD_PARTY_LICENSES.md +1 -1
  195. package/static/dist/assets/AppShell-jwd95ofg.js +8 -0
  196. package/static/dist/assets/{Button-nuaikybd.js → Button-nrcj7shj.js} +1 -1
  197. package/static/dist/assets/ChatPage-fmgk8xpk.js +2 -0
  198. package/static/dist/assets/Composer-oya4ggu7.js +5 -0
  199. package/static/dist/assets/ConnectTargets-rg90uiui.js +1 -0
  200. package/static/dist/assets/Dialog-gk0uatl8.js +1 -0
  201. package/static/dist/assets/ExtensionRoute-ji4xce9l.js +1 -0
  202. package/static/dist/assets/HubRoute-2pgy4aa2.js +2 -0
  203. package/static/dist/assets/Markdown-d6br42ts.js +2 -0
  204. package/static/dist/assets/{MarkdownRenderer-ccgqrza3.js → MarkdownRenderer-k8rmb83g.js} +6 -6
  205. package/static/dist/assets/OAuthSignIn-pbls9ljk.js +1 -0
  206. package/static/dist/assets/QueueCard-liib58ru.js +1 -0
  207. package/static/dist/assets/ResourceSwitch-gtdv2jgs.js +1 -0
  208. package/static/dist/assets/RightPanel-b89e4kx3.js +1 -0
  209. package/static/dist/assets/Select-l6qybenp.js +1 -0
  210. package/static/dist/assets/SessionListPanel-l4vy95j8.js +1 -0
  211. package/static/dist/assets/SettingsLayout-chw7pl2m.js +1 -0
  212. package/static/dist/assets/TerminalPanel-qrd0gkx7.js +16 -0
  213. package/static/dist/assets/Toaster-ihzgaq9z.js +1 -0
  214. package/static/dist/assets/_app-cn1au4zq.js +1 -0
  215. package/static/dist/assets/{_app.ext._extensionId-n797jp72.js → _app.ext._extensionId-m4npkrr0.js} +1 -1
  216. package/static/dist/assets/_app.groups-c8ycbp5n.js +1 -0
  217. package/static/dist/assets/{_app.index-ne43mdw2.js → _app.index-f1fckz3h.js} +1 -1
  218. package/static/dist/assets/{_app.insights-fqonovb4.js → _app.insights-ezivk7ad.js} +1 -1
  219. package/static/dist/assets/{_app.kanban-kysliv19.js → _app.kanban-zbkeov0f.js} +1 -1
  220. package/static/dist/assets/{_app.logs-febut82r.js → _app.logs-dqam5zyz.js} +1 -1
  221. package/static/dist/assets/{_app.memory-ha86oj1c.js → _app.memory-gzxkm3a0.js} +1 -1
  222. package/static/dist/assets/{_app.profiles-cnu3gxxq.js → _app.profiles-j28l31hl.js} +1 -1
  223. package/static/dist/assets/{_app.session._sessionId-ifzjpcgn.js → _app.session._sessionId-55egsufs.js} +1 -1
  224. package/static/dist/assets/{_app.settings-nmakdiaf.js → _app.settings-f5ltpieb.js} +1 -1
  225. package/static/dist/assets/_app.settings._section-dda0vfot.js +3 -0
  226. package/static/dist/assets/{_app.skills-f3wad8yo.js → _app.skills-kuc81hq0.js} +1 -1
  227. package/static/dist/assets/_app.tasks-gyy6vj5l.js +1 -0
  228. package/static/dist/assets/{_app.todos-bml1m3r1.js → _app.todos-d0xoy68t.js} +1 -1
  229. package/static/dist/assets/{_app.workspaces-f3d066lx.js → _app.workspaces-pawp2gxk.js} +1 -1
  230. package/static/dist/assets/_delete-qnxuo87s.js +1 -0
  231. package/static/dist/assets/{abnfDiagram-VCTEODGH-i53jc4yp.js → abnfDiagram-VCTEODGH-mhav7n5a.js} +1 -1
  232. package/static/dist/assets/{architecture-7GRP2DOG-e3bv5m6f.js → architecture-7GRP2DOG-ozbanukt.js} +1 -1
  233. package/static/dist/assets/{architectureDiagram-5GKGNRK7-pakekxu2.js → architectureDiagram-5GKGNRK7-febtor5m.js} +1 -1
  234. package/static/dist/assets/archive-gyk9c34a.js +1 -0
  235. package/static/dist/assets/autoReadClaim-nlyv8tu9.js +1 -0
  236. package/static/dist/assets/{blockDiagram-I7D4REHJ-bc6bo1n6.js → blockDiagram-I7D4REHJ-ocais2jf.js} +1 -1
  237. package/static/dist/assets/{c4Diagram-7LVT6UL2-btvwk2qx.js → c4Diagram-7LVT6UL2-cgpfjx5f.js} +1 -1
  238. package/static/dist/assets/channel-els5ri1f.js +1 -0
  239. package/static/dist/assets/{chunk-4HAMMTFA-dlwab11c.js → chunk-4HAMMTFA-hvqdiiow.js} +1 -1
  240. package/static/dist/assets/{chunk-75Z2AOVW-dp5gh7i8.js → chunk-75Z2AOVW-hxbulvtb.js} +1 -1
  241. package/static/dist/assets/{chunk-DU6HZSFF-bi06zl1c.js → chunk-DU6HZSFF-kkp6a7gp.js} +3 -3
  242. package/static/dist/assets/{chunk-F27PBJKO-kvv1rnlh.js → chunk-F27PBJKO-ljz0gssc.js} +1 -1
  243. package/static/dist/assets/{chunk-GMAD6QVW-ji0rx9by.js → chunk-GMAD6QVW-bo0enyxn.js} +1 -1
  244. package/static/dist/assets/{chunk-GVQU2GXP-nmz0j82p.js → chunk-GVQU2GXP-cnq7l2v6.js} +1 -1
  245. package/static/dist/assets/{chunk-IMKFNOWR-kmi1qx88.js → chunk-IMKFNOWR-gjnkrfu6.js} +1 -1
  246. package/static/dist/assets/{chunk-L3NEJ4N5-xhb7mebj.js → chunk-L3NEJ4N5-gjfp71qi.js} +1 -1
  247. package/static/dist/assets/{chunk-OSK3NFVY-5a9sgscq.js → chunk-OSK3NFVY-ieq5r94b.js} +1 -1
  248. package/static/dist/assets/{chunk-P2QGCYS3-dfezp4vu.js → chunk-P2QGCYS3-hdefjk56.js} +1 -1
  249. package/static/dist/assets/{chunk-POPQ4Y6H-gd2vq3c0.js → chunk-POPQ4Y6H-mcbt8wpr.js} +1 -1
  250. package/static/dist/assets/{chunk-PWAF6VOD-wvw2nksf.js → chunk-PWAF6VOD-mx2drja9.js} +1 -1
  251. package/static/dist/assets/{chunk-SHT3W25Y-f58q97px.js → chunk-SHT3W25Y-j7dd9i66.js} +1 -1
  252. package/static/dist/assets/{chunk-SVP7TREG-abgwpyz9.js → chunk-SVP7TREG-jcnt3lxt.js} +1 -1
  253. package/static/dist/assets/{chunk-TICWLB2K-h4sbs8ds.js → chunk-TICWLB2K-lrwv5hx9.js} +1 -1
  254. package/static/dist/assets/classDiagram-ZZMXUADV-krpt9pdd.js +1 -0
  255. package/static/dist/assets/classDiagram-v2-VYDZK3BY-krpt9pdd.js +1 -0
  256. package/static/dist/assets/completionAudio-fhxf0h9j.js +1 -0
  257. package/static/dist/assets/{copy-m9h56qa8.js → copy-gyzrqmyr.js} +1 -1
  258. package/static/dist/assets/{cynefin-OW5HDTMX-g081vffs.js → cynefin-OW5HDTMX-heq36srt.js} +1 -1
  259. package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-odxvjesk.js → cynefinDiagram-5FMLGOSQ-crrmq338.js} +1 -1
  260. package/static/dist/assets/{dagre-GXQ25YYZ-cpdwzjs4.js → dagre-GXQ25YYZ-m7fpnt6k.js} +1 -1
  261. package/static/dist/assets/{diagram-S7CK7UJ4-clv5mxvu.js → diagram-S7CK7UJ4-ebm1ebv6.js} +1 -1
  262. package/static/dist/assets/{diagram-UQ7AKVKN-m2ia1mbf.js → diagram-UQ7AKVKN-hc0ypsp1.js} +1 -1
  263. package/static/dist/assets/{diagram-VSXAHHWV-ea6zv636.js → diagram-VSXAHHWV-mu8q5n4b.js} +1 -1
  264. package/static/dist/assets/{diagram-VX7I27RA-oqlef685.js → diagram-VX7I27RA-i488wdlb.js} +1 -1
  265. package/static/dist/assets/{diagram-Z3DM3KII-kjubcbwu.js → diagram-Z3DM3KII-gz3nwvq9.js} +1 -1
  266. package/static/dist/assets/{dist-carq1azj.js → dist-ge7hom9n.js} +4 -4
  267. package/static/dist/assets/{dist-crc46di9.js → dist-kpg5ccm9.js} +1 -1
  268. package/static/dist/assets/{ebnfDiagram-PWID7BFC-fg0zri3e.js → ebnfDiagram-PWID7BFC-lwskecx4.js} +1 -1
  269. package/static/dist/assets/{erDiagram-RLTQ6QDP-eb7pmk3x.js → erDiagram-RLTQ6QDP-c0bysigr.js} +1 -1
  270. package/static/dist/assets/{eventmodeling-NTZA5JFV-gvi1fxhn.js → eventmodeling-NTZA5JFV-k19e509j.js} +1 -1
  271. package/static/dist/assets/feedbackVideo.worker-JBVT3sDD.js +480 -0
  272. package/static/dist/assets/flowDiagram-HODETNUW-n4m8e6kq.js +1 -0
  273. package/static/dist/assets/folder-plus-m1ywe0cv.js +1 -0
  274. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-jmisowrc.js → ganttDiagram-EL5Y4UJY-mz1p8yzt.js} +1 -1
  275. package/static/dist/assets/getPseudoElementBounds-ci0x9gki.js +1 -0
  276. package/static/dist/assets/{gitGraph-4MIJSDKK-m7kt3u6e.js → gitGraph-4MIJSDKK-h0uskiog.js} +1 -1
  277. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-nq7vfzh2.js → gitGraphDiagram-WWUBYQGX-e4d9um1j.js} +1 -1
  278. package/static/dist/assets/group_discussions-fk5hry4l.js +1 -0
  279. package/static/dist/assets/{highlighted-body-KPVGNVTW-gcu017ay.js → highlighted-body-KPVGNVTW-d47n6oqu.js} +1 -1
  280. package/static/dist/assets/{host-ipp4e84c.js → host-f7eudvft.js} +1 -1
  281. package/static/dist/assets/index-lab8g9gs.css +2 -0
  282. package/static/dist/assets/index-n5rg2q2r.js +13 -0
  283. package/static/dist/assets/{info-A6RAGUB7-idazwfqe.js → info-A6RAGUB7-k04of9c6.js} +1 -1
  284. package/static/dist/assets/{infoDiagram-27XIBGKW-bb9jh8gl.js → infoDiagram-27XIBGKW-l98n1tgz.js} +1 -1
  285. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-nqc132rv.js → ishikawaDiagram-5VMMS53U-gkznu2d6.js} +1 -1
  286. package/static/dist/assets/{journeyDiagram-3NMN7TZE-fpvnhy44.js → journeyDiagram-3NMN7TZE-mt23qvx1.js} +1 -1
  287. package/static/dist/assets/{kanban-definition-UXKFOSKX-ndzqm6fu.js → kanban-definition-UXKFOSKX-ab93l7y5.js} +1 -1
  288. package/static/dist/assets/katex-ic33v820.js +257 -0
  289. package/static/dist/assets/katex-qcv7xo0t.css +1 -0
  290. package/static/dist/assets/{lazyRouteComponent-javud235.js → lazyRouteComponent-dt9efiqk.js} +1 -1
  291. package/static/dist/assets/{line-g625e7cj.js → line-dkm9r3as.js} +1 -1
  292. package/static/dist/assets/link-2-ozyjqwhh.js +1 -0
  293. package/static/dist/assets/{link-gfdaho08.js → link-dip3g6zs.js} +1 -1
  294. package/static/dist/assets/{locale-cs-n41hptse.js → locale-cs-brltdkcp.js} +1 -1
  295. package/static/dist/assets/{locale-de-k7ht47ew.js → locale-de-h6e9oq6v.js} +1 -1
  296. package/static/dist/assets/{locale-es-ih078lco.js → locale-es-oklmh80f.js} +1 -1
  297. package/static/dist/assets/{locale-fr-ojabnf41.js → locale-fr-b17ozoi2.js} +1 -1
  298. package/static/dist/assets/{locale-it-kb96jufy.js → locale-it-whe01eef.js} +1 -1
  299. package/static/dist/assets/{locale-ja-jpsp3xs1.js → locale-ja-g1s0rtpc.js} +1 -1
  300. package/static/dist/assets/{locale-pl-dbap4leu.js → locale-pl-d9p3lqcb.js} +1 -1
  301. package/static/dist/assets/{locale-pt-nci7w72x.js → locale-pt-l75on74f.js} +1 -1
  302. package/static/dist/assets/{locale-ru-soghe4cs.js → locale-ru-wl3mbsaw.js} +1 -1
  303. package/static/dist/assets/{locale-tr-ks00mu68.js → locale-tr-cz87itrq.js} +1 -1
  304. package/static/dist/assets/{locale-vi-ij7twfm6.js → locale-vi-elqj1y4k.js} +1 -1
  305. package/static/dist/assets/{locale-zh-Hant-feakwr7a.js → locale-zh-Hant-hf8gqm7d.js} +1 -1
  306. package/static/dist/assets/{locale-zh-ren0vjyv.js → locale-zh-cdckwb0u.js} +1 -1
  307. package/static/dist/assets/login-go5xfzkx.js +1 -0
  308. package/static/dist/assets/mermaid-HWGCJPDP-o7wh7c74.js +1 -0
  309. package/static/dist/assets/{mermaid-parser.core-plzkuzov.js → mermaid-parser.core-c4ywstu7.js} +3 -3
  310. package/static/dist/assets/{mindmap-definition-YA3MSWOX-ojrgs569.js → mindmap-definition-YA3MSWOX-mnvkgz5u.js} +1 -1
  311. package/static/dist/assets/onboarding-hbbpvp6w.js +1 -0
  312. package/static/dist/assets/{packet-AYTQ26CC-gyaf9s8h.js → packet-AYTQ26CC-dfm2ygox.js} +1 -1
  313. package/static/dist/assets/{pegDiagram-XKGWAZYB-bf6xj8mq.js → pegDiagram-XKGWAZYB-kfbyls4v.js} +1 -1
  314. package/static/dist/assets/{pie-WAS4IAKB-f5ymzelo.js → pie-WAS4IAKB-jniw7r2b.js} +1 -1
  315. package/static/dist/assets/{pieDiagram-E7YTZNPT-d0qjl3zi.js → pieDiagram-E7YTZNPT-cir9nlg4.js} +1 -1
  316. package/static/dist/assets/presence-ivo54s19.js +1 -0
  317. package/static/dist/assets/prompt_queue_cancelled-cebcuagu.js +1 -0
  318. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-oqy1mras.js → quadrantDiagram-AXDQQJYC-2nnb2u4m.js} +1 -1
  319. package/static/dist/assets/queryKeys-mbi6o5vh.js +9 -0
  320. package/static/dist/assets/{radar-RG4KPBEZ-b6jcjvda.js → radar-RG4KPBEZ-jfvtqhq2.js} +1 -1
  321. package/static/dist/assets/{railroad-74A4TZTK-e3a6lk5k.js → railroad-74A4TZTK-hnm0ikx7.js} +1 -1
  322. package/static/dist/assets/{railroad-abnf-HS5TGJTU-ff5hocrx.js → railroad-abnf-HS5TGJTU-hcfz5gyc.js} +1 -1
  323. package/static/dist/assets/{railroad-ebnf-LZEXJU2U-exkhyw4n.js → railroad-ebnf-LZEXJU2U-ocbvmcwo.js} +1 -1
  324. package/static/dist/assets/{railroad-peg-WCYAUIDC-jefk9b7c.js → railroad-peg-WCYAUIDC-kkbzgo8d.js} +1 -1
  325. package/static/dist/assets/{railroadDiagram-O6MQD6OU-e4amks1i.js → railroadDiagram-O6MQD6OU-ox5v7853.js} +1 -1
  326. package/static/dist/assets/rename-ccd52yws.js +1 -0
  327. package/static/dist/assets/{requirementDiagram-BXWQKSXE-c77k1e2y.js → requirementDiagram-BXWQKSXE-e1iq54h4.js} +1 -1
  328. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-oa1cc52s.js → sankeyDiagram-P5KCCOFB-mmza9r2u.js} +1 -1
  329. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-j20gqt22.js → sequenceDiagram-WJ2MYXX4-dioic69h.js} +1 -1
  330. package/static/dist/assets/{share._token-kmfoflw6.js → share._token-i51g4ccy.js} +1 -1
  331. package/static/dist/assets/sliders-horizontal-nj1dipq4.js +1 -0
  332. package/static/dist/assets/{stateDiagram-D77RDMKH-co2ghkdp.js → stateDiagram-D77RDMKH-do5wvqjw.js} +1 -1
  333. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-f0sedx52.js +1 -0
  334. package/static/dist/assets/{swimlanes-42K2YHIH-m30cktqe.js → swimlanes-42K2YHIH-mhjzgtgl.js} +1 -1
  335. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-n0x444kc.js +8 -0
  336. package/static/dist/assets/{timeline-definition-24CTP7MA-liuep6fl.js → timeline-definition-24CTP7MA-i5820ppg.js} +1 -1
  337. package/static/dist/assets/toast-esv4ma70.js +56 -0
  338. package/static/dist/assets/{treeView-Q6P3EWNA-np5d2jv2.js → treeView-Q6P3EWNA-btp8feob.js} +1 -1
  339. package/static/dist/assets/{treemap-WGGIJYW6-cmpltxh1.js → treemap-WGGIJYW6-lv71dt7p.js} +1 -1
  340. package/static/dist/assets/tts-bq7ax6xp.js +1 -0
  341. package/static/dist/assets/{useForm-f1udzsjf.js → useForm-d5wxx0l0.js} +1 -1
  342. package/static/dist/assets/{useParams-ierevvts.js → useParams-gk1u0y6m.js} +1 -1
  343. package/static/dist/assets/{useSearch-i7nr9ypl.js → useSearch-nsrme1pf.js} +1 -1
  344. package/static/dist/assets/useTranscript-m9ve9mml.js +1 -0
  345. package/static/dist/assets/{vennDiagram-4TSXK5OY-b2g42qrg.js → vennDiagram-4TSXK5OY-bffv7e11.js} +1 -1
  346. package/static/dist/assets/{wardley-WFR3VGLG-lb0eqbff.js → wardley-WFR3VGLG-f1m16ivx.js} +1 -1
  347. package/static/dist/assets/{wardleyDiagram-VM6X3IG4-ermwaqha.js → wardleyDiagram-VM6X3IG4-ous4pq48.js} +1 -1
  348. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-dll0jldk.js → xychartDiagram-S5SC5T6Z-jxgbp4as.js} +1 -1
  349. package/static/dist/index.html +1 -1
  350. package/static/dist/sw.js +1 -1
  351. package/static/dist/assets/AppShell-c5989995.js +0 -8
  352. package/static/dist/assets/ChatPage-bfg4khph.js +0 -6
  353. package/static/dist/assets/ConnectTargets-k5wo9yo8.js +0 -1
  354. package/static/dist/assets/Dialog-o8vo2aws.js +0 -1
  355. package/static/dist/assets/ExtensionRoute-l1yjrso4.js +0 -1
  356. package/static/dist/assets/Field-j7o8cfps.js +0 -1
  357. package/static/dist/assets/HubRoute-efnwe4xz.js +0 -2
  358. package/static/dist/assets/Markdown-clqf5m22.js +0 -2
  359. package/static/dist/assets/OAuthSignIn-h7bjaqp6.js +0 -1
  360. package/static/dist/assets/ResourceSwitch-oai2zqaj.js +0 -1
  361. package/static/dist/assets/RightPanel-ho161a45.js +0 -1
  362. package/static/dist/assets/Select-d1g5a8bm.js +0 -1
  363. package/static/dist/assets/SessionListPanel-i7kaokhi.js +0 -1
  364. package/static/dist/assets/SettingsLayout-lnecm87w.js +0 -1
  365. package/static/dist/assets/States-easntmry.js +0 -1
  366. package/static/dist/assets/TerminalPanel-lxhwd4jl.js +0 -16
  367. package/static/dist/assets/Toaster-l4sciy8t.js +0 -1
  368. package/static/dist/assets/_app-mqexqbg8.js +0 -1
  369. package/static/dist/assets/_app.settings._section-djglnjmi.js +0 -3
  370. package/static/dist/assets/_app.tasks-l10py1c0.js +0 -1
  371. package/static/dist/assets/archive-ihqi7z2x.js +0 -1
  372. package/static/dist/assets/channel-jn4f8443.js +0 -1
  373. package/static/dist/assets/classDiagram-ZZMXUADV-dzrw66se.js +0 -1
  374. package/static/dist/assets/classDiagram-v2-VYDZK3BY-dzrw66se.js +0 -1
  375. package/static/dist/assets/completionAudio-ce86msbu.js +0 -1
  376. package/static/dist/assets/flowDiagram-HODETNUW-abekab15.js +0 -1
  377. package/static/dist/assets/folder-plus-ksaons88.js +0 -1
  378. package/static/dist/assets/index-d6vbxlra.js +0 -13
  379. package/static/dist/assets/index-ey6qo0zx.css +0 -2
  380. package/static/dist/assets/katex-cbdd1ohw.css +0 -1
  381. package/static/dist/assets/katex-pbij2oo6.js +0 -257
  382. package/static/dist/assets/login-iv6yq4xf.js +0 -1
  383. package/static/dist/assets/mermaid-HWGCJPDP-cwj5cl6k.js +0 -1
  384. package/static/dist/assets/onboarding-ff4emacu.js +0 -1
  385. package/static/dist/assets/queryKeys-x8fjxhut.js +0 -9
  386. package/static/dist/assets/refresh-cw-lfp4u1oh.js +0 -1
  387. package/static/dist/assets/sliders-horizontal-g5jkzd9k.js +0 -1
  388. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-faw1opgh.js +0 -1
  389. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-hfil433g.js +0 -8
  390. package/static/dist/assets/toast-zmb35u3r.js +0 -56
@@ -12,9 +12,10 @@
12
12
  */
13
13
  import { backupPersistedStores } from '../sessions/storage/json-installation.js';
14
14
  export { backupPersistedStores, CHANNEL_SWITCH_BACKUPS } from '../sessions/storage/json-installation.js';
15
- import { UpdatesSummarySchema } from '@maudecode/talaria-web-contracts';
15
+ import { UpdatesSummarySchema, WebUpdateChannelSchema } from '@maudecode/talaria-web-contracts';
16
16
  import { z } from 'zod';
17
17
  import { readCapped } from '../http/capped.js';
18
+ import { SidecarError } from '../sidecar/client.js';
18
19
  import { execFile } from 'node:child_process';
19
20
  import { createHash } from 'node:crypto';
20
21
  import { existsSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from 'node:fs';
@@ -41,6 +42,13 @@ const WEB_NPM_PACKAGE = '@maudecode/talaria-web';
41
42
  const GIT_LOCK_SIGNATURES = ["index.lock': file exists", ".lock': file exists", 'another git process seems to be running', 'unable to create .git/index.lock'];
42
43
  const NETWORK_FAILURES = ['could not resolve host', 'failed to connect', 'network is unreachable', 'no route to host', 'connection timed out', 'timed out after', 'connection reset by peer', 'remote end hung up unexpectedly', 'tls connection was non-properly terminated', 'ssl certificate problem'];
43
44
  export const normalizeChannel = (channel) => (channel === 'experimental' ? 'experimental' : 'stable');
45
+ export const WEB_UPDATE_CHANNELS = WebUpdateChannelSchema.options;
46
+ export const isWebChannel = (channel) => WebUpdateChannelSchema.safeParse(channel).success;
47
+ export const normalizeWebChannel = (channel) => (isWebChannel(channel) ? channel : 'stable');
48
+ /** TAL-1569: Nightly installs the same GHCR artifacts as Experimental, one daily `nightly` tag behind it. */
49
+ const webFamily = (channel) => (channel === 'stable' ? 'stable' : 'experimental');
50
+ /** A packaged `web-v` or `web-exp-v` version label of the channel's artifact family. */
51
+ const familyVersion = (channel, label) => new RegExp(`^${webFamily(channel) === 'experimental' ? 'web-exp-v' : 'web-v'}${VERSION}$`).exec(label);
44
52
  export const ONLY_STABLE_VERSIONS = 'Choosing a version is available only on the Stable channel.';
45
53
  /** TAL-946: the release an update installs: the listed `version` (a `ref`), else the newest listed release (none when nothing is listed). */
46
54
  function selectVersion(versions, version, name) {
@@ -130,7 +138,12 @@ export function sanitizeGitDiagnostic(output, limit = 300) {
130
138
  s = s.replace(/([?&](?:access_token|oauth_token|private_token|client_secret|app_secret|api[_-]?key|token|password|secret|auth|key)=)[^&\s'"]+/gi, '$1<redacted>').trim();
131
139
  return s.length > limit ? `${s.slice(0, limit).trimEnd()}…` : s;
132
140
  }
141
+ /** `runGit`'s marker when its own deadline killed git; libcurl's "Operation timed out after N milliseconds" stays a network failure. */
142
+ const GIT_DEADLINE = /^git .+ timed out after (\d+(?:\.\d+)?)s$/;
133
143
  function fetchFailureMessage(out, network) {
144
+ const deadline = GIT_DEADLINE.exec(out.trim());
145
+ if (deadline)
146
+ return `The update check timed out after ${deadline[1] ?? ''}s. Try again.`;
134
147
  const detail = sanitizeGitDiagnostic(out);
135
148
  if (!detail)
136
149
  return network;
@@ -405,9 +418,9 @@ export function ghcrExperimental(fetchImpl) {
405
418
  return body.token;
406
419
  };
407
420
  return {
408
- release: async () => {
421
+ release: async (channel) => {
409
422
  const auth = { Authorization: `Bearer ${await token()}` };
410
- const m = await json(await send(`${GHCR}/v2/${EXPERIMENTAL_REPOSITORY}/manifests/experimental`, { headers: { ...auth, Accept: 'application/vnd.oci.image.manifest.v1+json' }, signal: AbortSignal.timeout(5000) }), 'manifest');
423
+ const m = await json(await send(`${GHCR}/v2/${EXPERIMENTAL_REPOSITORY}/manifests/${channel}`, { headers: { ...auth, Accept: 'application/vnd.oci.image.manifest.v1+json' }, signal: AbortSignal.timeout(5000) }), 'manifest');
411
424
  const layers = Array.isArray(m.layers) ? m.layers.map(dict) : [];
412
425
  const layer = layers[0];
413
426
  if (m.artifactType !== EXPERIMENTAL_ARTIFACT_TYPE || layers.length !== 1 || layer?.mediaType !== EXPERIMENTAL_LAYER_TYPE)
@@ -552,23 +565,51 @@ async function experimentalBuildsBehind(installed, latest, registry, getJson) {
552
565
  // ponytail: 500 commits back; an older install reports the builds within that window.
553
566
  return Math.max(1, count);
554
567
  }
555
- /** An npm install on Experimental: behind by its missed builds when its source differs from the `experimental` tag, or when switching channels. */
556
- async function checkNpmExperimental(result, installed, id, registry, getJson) {
568
+ const CHANNEL_NAMES = { stable: 'Stable', nightly: 'Nightly', experimental: 'Experimental' };
569
+ const AHEAD_OF_NIGHTLY = 'This npm installation is ahead of the Nightly build; it updates once Nightly passes it.';
570
+ /**
571
+ * TAL-1569: whether a Nightly install (not a switch) holds a source newer than the `nightly` build. Nightly trails
572
+ * Experimental, so an install taken from Experimental is ahead of it and must not move back. Unorderable sources fail closed.
573
+ */
574
+ async function aheadOfNightly(channel, switching, installed, nightly, getJson) {
575
+ if (channel !== 'nightly' || switching || !installed || installed === nightly)
576
+ return false;
577
+ let status;
578
+ try {
579
+ status = dict(await getJson(`/compare/${nightly}...${installed}`, { asset: false })).status;
580
+ }
581
+ catch {
582
+ status = null;
583
+ }
584
+ if (status === 'ahead')
585
+ return true;
586
+ if (status === 'behind' || status === 'diverged')
587
+ return false;
588
+ throw new ReleaseUnavailable('Cannot order this installation against the Nightly build', true);
589
+ }
590
+ /** An npm install on Experimental or Nightly: behind by its missed builds when its source differs from the channel's tag, or when switching from Stable. */
591
+ async function checkNpmExperimental(result, installed, id, registry, getJson, channel) {
592
+ const name = CHANNEL_NAMES[channel];
557
593
  let release;
594
+ const disk = diskRelease(installed.packageRoot);
595
+ const current = str(disk?.sourceRevision ?? id.release().sourceRevision) || null;
596
+ const switching = npmInstallChannel(installed, id) === 'stable';
597
+ let ahead = false;
558
598
  try {
559
- release = await registry.release();
599
+ release = await registry.release(channel);
600
+ ahead = await aheadOfNightly(channel, switching, current, release.sourceRevision, getJson);
560
601
  }
561
602
  catch (error) {
562
- const unavailable = error instanceof ReleaseUnavailable ? error : new ReleaseUnavailable('The Experimental artifact is unavailable');
603
+ const unavailable = error instanceof ReleaseUnavailable ? error : new ReleaseUnavailable(`The ${name} artifact is unavailable`);
563
604
  return { ...result, install_kind: 'npm', manual_update: true, error: unavailable.message, ...(unavailable.transient ? { stale_check: true } : {}) };
564
605
  }
565
- Object.assign(result, { latest_version: release.tag, latest_sha: release.sourceRevision, branch: 'experimental', release_based: true, no_git: true, install_kind: 'npm', manual_update: false });
566
- const disk = diskRelease(installed.packageRoot);
567
- const current = str(disk?.sourceRevision ?? id.release().sourceRevision) || null;
568
- if (npmInstallChannel(installed, id) !== 'experimental')
569
- return { ...result, current_sha: current, behind: await experimentalBuildsBehind(current, release.sourceRevision, registry, getJson), channel_switch: true, message: `Switching to Experimental installs ${release.version}.` };
606
+ Object.assign(result, { latest_version: release.tag, latest_sha: release.sourceRevision, branch: channel, release_based: true, no_git: true, install_kind: 'npm', manual_update: false });
607
+ if (switching)
608
+ return { ...result, current_sha: current, behind: await experimentalBuildsBehind(current, release.sourceRevision, registry, getJson), channel_switch: true, message: `Switching to ${name} installs ${release.version}.` };
609
+ if (ahead)
610
+ return { ...result, current_sha: current, behind: 0, manual_update: true, message: AHEAD_OF_NIGHTLY };
570
611
  if (disk?.sourceRevision !== release.sourceRevision)
571
- return { ...result, current_sha: current, behind: await experimentalBuildsBehind(current, release.sourceRevision, registry, getJson), message: `Experimental update ${release.version} is available.` };
612
+ return { ...result, current_sha: current, behind: await experimentalBuildsBehind(current, release.sourceRevision, registry, getJson), message: `${name} update ${release.version} is available.` };
572
613
  const metadataRepair = !same(id.release(), disk);
573
614
  return { ...result, current_sha: release.sourceRevision, behind: 0, metadata_repair: metadataRepair, ...(metadataRepair ? { message: 'The npm package is current; finish the update to restart with that version.' } : {}) };
574
615
  }
@@ -579,13 +620,13 @@ export async function checkWebUpdate(webRoot, currentVersion, channel, git, getJ
579
620
  const result = { name: 'webui', channel, repo_url: REPOSITORY_URL, current_version: currentVersion, behind: null, no_git: root === null };
580
621
  if (root !== null)
581
622
  return { ...result, manual_update: true, message: CONTRIBUTOR_CHECKOUT_MESSAGE };
582
- if (channel === 'experimental' && npmInstall && registry)
583
- return checkNpmExperimental(result, npmInstall, id, registry, getJson);
584
- const packaged = new RegExp(`^${channel === 'experimental' ? 'web-exp-v' : 'web-v'}${VERSION}$`).exec(currentVersion)?.slice(1, 4).join('.');
623
+ if (channel !== 'stable' && npmInstall && registry)
624
+ return checkNpmExperimental(result, npmInstall, id, registry, getJson, channel);
625
+ const packaged = familyVersion(channel, currentVersion)?.slice(1, 4).join('.');
585
626
  const installed = npmInstall?.version ?? packaged;
586
627
  let release;
587
628
  try {
588
- release = await publishedWebRelease(channel, getJson, undefined, installed && new RegExp(`^${VERSION}$`).test(installed) ? installed : undefined);
629
+ release = await publishedWebRelease(webFamily(channel), getJson, undefined, installed && new RegExp(`^${VERSION}$`).test(installed) ? installed : undefined);
589
630
  }
590
631
  catch (error) {
591
632
  if (error instanceof ReleaseUnavailable)
@@ -611,7 +652,7 @@ export async function checkWebUpdate(webRoot, currentVersion, channel, git, getJ
611
652
  return { ...result, current_sha: release.sourceRevision, behind: 0, no_git: true, install_kind: 'npm', npm: release.npm, manual_update: false, metadata_repair: metadataRepair, ...(metadataRepair ? { message: 'The npm package is current; finish the update to restart with that version.' } : {}) };
612
653
  }
613
654
  const current = id.release().sourceRevision ?? null;
614
- const version = new RegExp(`^${channel === 'experimental' ? 'web-exp-v' : 'web-v'}${VERSION}$`).exec(currentVersion);
655
+ const version = familyVersion(channel, currentVersion);
615
656
  let behind = version && current === release.sourceRevision ? 0 : null;
616
657
  if (behind === null && version) {
617
658
  const installed = version.slice(1).map(Number);
@@ -628,7 +669,7 @@ async function applyNpmWebUpdate(webRoot, channel, getJson, id, npmRun, canApply
628
669
  if (!installed)
629
670
  return { ok: false, manual_update: true, message: 'Automatic npm updates require a direct global @maudecode/talaria-web installation.' };
630
671
  // Switching channels installs the selected channel's newest artifact regardless of version order (TAL-343).
631
- const switching = npmInstallChannel(installed, id) !== channel;
672
+ const switching = npmInstallChannel(installed, id) !== webFamily(channel);
632
673
  if (version !== undefined && (channel !== 'stable' || switching))
633
674
  return { ok: false, target: 'webui', channel, message: ONLY_STABLE_VERSIONS };
634
675
  const onDisk = diskRelease(installed.packageRoot);
@@ -663,18 +704,21 @@ async function applyNpmWebUpdate(webRoot, channel, getJson, id, npmRun, canApply
663
704
  }
664
705
  }
665
706
  else {
707
+ const name = CHANNEL_NAMES[channel];
666
708
  if (!packaged.registry)
667
- return { ok: false, manual_update: true, message: 'Packaged Experimental updates are unavailable in this installation.' };
709
+ return { ok: false, manual_update: true, message: `Packaged ${name} updates are unavailable in this installation.` };
668
710
  let release;
669
711
  try {
670
- release = await packaged.registry.release();
712
+ release = await packaged.registry.release(channel);
713
+ if (await aheadOfNightly(channel, switching, str(onDisk?.sourceRevision ?? id.release().sourceRevision) || null, release.sourceRevision, getJson))
714
+ return { ok: false, manual_update: true, target: 'webui', channel, message: AHEAD_OF_NIGHTLY };
671
715
  }
672
716
  catch (error) {
673
- return { ok: false, message: error instanceof ReleaseUnavailable ? error.message : 'The Experimental artifact is unavailable.' };
717
+ return { ok: false, message: error instanceof ReleaseUnavailable ? error.message : `The ${name} artifact is unavailable.` };
674
718
  }
675
719
  const identity = { tag: release.tag, version: release.version, sourceRevision: release.sourceRevision, releaseSet: release.sourceRevision };
676
720
  // validateReleaseInfo (in diskRelease) already applies Stable's contract and Agent-pin checks to the packaged files.
677
- target = { tag: release.tag, version: release.version, sourceRevision: release.sourceRevision, label: `Experimental ${release.version}`, matches: (r) => r !== null && same({ tag: r.tag, version: r.version, sourceRevision: r.sourceRevision, releaseSet: r.releaseSet }, identity), experimental: release };
721
+ target = { tag: release.tag, version: release.version, sourceRevision: release.sourceRevision, label: `${name} ${release.version}`, matches: (r) => r !== null && same({ tag: r.tag, version: r.version, sourceRevision: r.sourceRevision, releaseSet: r.releaseSet }, identity), experimental: release };
678
722
  }
679
723
  const priorRollback = readUpdateRollback(packaged.stateDir);
680
724
  if (packaged.skipFailedVersion && priorRollback?.failedVersion === target.version)
@@ -717,7 +761,7 @@ async function applyNpmWebUpdate(webRoot, channel, getJson, id, npmRun, canApply
717
761
  const bins = dict(metadata.bin);
718
762
  if (metadata.name !== WEB_NPM_PACKAGE || metadata.version !== target.version || !target.matches(diskRelease(candidate))
719
763
  || !['talaria-web', 'talaria-web-mcp'].every((name) => str(bins[name]).replace(/^\.\//, '') === `dist/bin/${name}.js` && existsSync(join(candidate, `dist/bin/${name}.js`)))) {
720
- return { ok: false, verification_failed: true, target: 'webui', channel, message: `The downloaded npm package does not match ${channel === 'stable' ? 'the completed release' : 'the Experimental artifact'}. The installed package was preserved.` };
764
+ return { ok: false, verification_failed: true, target: 'webui', channel, message: `The downloaded npm package does not match ${channel === 'stable' ? 'the completed release' : `the ${CHANNEL_NAMES[channel]} artifact`}. The installed package was preserved.` };
721
765
  }
722
766
  // npm can leave a dependency as an empty directory; swapping that in crash-loops the server (TAL-1010).
723
767
  const missing = Object.keys(dict(metadata.dependencies)).filter((name) => !existsSync(join(candidate, 'node_modules', name, 'package.json')));
@@ -1347,21 +1391,25 @@ function splitCategory(line) {
1347
1391
  return [['worth knowing', 'worth', 'note'].includes(label) ? 'worth' : 'notice', m[2] ?? ''];
1348
1392
  }
1349
1393
  const tagList = (notes) => notes.map((n) => n.tag).join(', ');
1350
- function fallbackBullets(details) {
1394
+ const updateCount = (n) => `${String(n)} update${n === 1 ? '' : 's'}`;
1395
+ /** `resolved` is false when the update range could not be read, so empty notes and commits mean unknown, not none. */
1396
+ function fallbackBullets(details, resolved = true) {
1351
1397
  const out = details.map((item) => {
1352
1398
  const label = str(item.label || item.name) || 'Hermes';
1399
+ if (!resolved)
1400
+ return `${label} has ${updateCount(item.behind)} available. The summary could not be generated; try again later.`;
1353
1401
  const notes = item.notes;
1354
1402
  if (notes.length)
1355
1403
  return `${label} ${tagList(notes)} ${notes.length === 1 ? 'is' : 'are'} available.`;
1356
1404
  const commits = item.commits;
1357
1405
  if (commits.length)
1358
- return `${label} has ${String(item.behind)} update(s), including updates: ${commits.slice(0, 3).join('; ')}.`;
1359
- return `${label} has ${String(item.behind)} update(s) available.`;
1406
+ return `${label} has ${updateCount(item.behind)}, including: ${commits.slice(0, 3).join('; ')}.`;
1407
+ return `This build has no ${label} changes.`;
1360
1408
  });
1361
1409
  return out.length ? out : ['Updates are available.'];
1362
1410
  }
1363
1411
  function worthKnowingBullets(details) {
1364
- const targets = details.filter((d) => d.behind).map((d) => `${str(d.label || d.name) || 'Hermes'} (${String(d.behind)} update${d.behind === 1 ? '' : 's'})`);
1412
+ const targets = details.filter((d) => d.behind).map((d) => `${str(d.label || d.name) || 'Hermes'} (${updateCount(d.behind)})`);
1365
1413
  return targets.length > 1 ? [`This summary combines updates from ${targets.join(' and ')}.`] : [];
1366
1414
  }
1367
1415
  const sectionsText = (sections) => sections.map((section) => [section.title, ...section.items.map((item) => `- ${item}`), ''].join('\n')).join('\n').trim();
@@ -1399,6 +1447,11 @@ function formatSections(text, details) {
1399
1447
  sections.push({ title: 'Worth knowing', items: worth });
1400
1448
  return [sections, sectionsText(sections)];
1401
1449
  }
1450
+ /** Deterministic copy when the model has nothing to summarize or cannot answer; never titled as model output. */
1451
+ function fallbackSections(details, resolved, deferred = false) {
1452
+ const sections = [{ title: 'About this update', items: deferred ? ['The summary will be ready when the Agent update finishes.'] : uniqueBullets(fallbackBullets(details, resolved)) }];
1453
+ return [sections, sectionsText(sections)];
1454
+ }
1402
1455
  const SUMMARY_SYSTEM = 'You write human-readable release summaries for Hermes users. Focus on what the user will notice in the product. Keep it simple, specific, and short. avoid technical jargon, implementation details, SHA names, branch names, and file paths unless necessary. Return only bullets. Do not include headings, markdown tables, intro paragraphs, or closing notes.';
1403
1456
  const SUMMARY_FORMAT = ['Prefix each bullet with `Notice:` for user-visible behavior changes or `Worth knowing:` for useful context.', 'Use Worth knowing only for helpful context that is not a duplicate of a Notice bullet.', 'Use everyday language and explain visible behavior changes, not code mechanics.', 'Return only prefixed bullets; the WebUI will add the fixed section headings separately.'];
1404
1457
  function summaryPrompt(details) {
@@ -1523,6 +1576,8 @@ export class UpdateService {
1523
1576
  applying = false;
1524
1577
  /** TAL-1525: a forced check owed once the current apply releases its lock. */
1525
1578
  refreshOwed = false;
1579
+ /** TAL-1632: the latest owed refresh check, which runs after the apply that owed it returns. */
1580
+ refreshing = Promise.resolve();
1526
1581
  /** TAL-1525: the Web package installed for the pending restart; this process still runs the old one. */
1527
1582
  installedWeb = null;
1528
1583
  autoTimer = null;
@@ -1535,6 +1590,10 @@ export class UpdateService {
1535
1590
  summaryQueues = new Map();
1536
1591
  summarizing = new Map();
1537
1592
  summaryFailures = new Set();
1593
+ /** TAL-1591: targets whose model call the sidecar refused while the Agent runtime was mid-update; non-empty means the runtime is known stale. */
1594
+ summaryDeferred = new Set();
1595
+ /** Counts runtime-current signals, so a refusal that was in flight across one is retried rather than deferred. */
1596
+ runtimeCurrentEpoch = 0;
1538
1597
  publishedTags = new Map();
1539
1598
  git;
1540
1599
  now;
@@ -1593,16 +1652,25 @@ export class UpdateService {
1593
1652
  this.summaryQueues.delete(target); }).catch(() => undefined);
1594
1653
  return next;
1595
1654
  }
1596
- preGenerateSummaries(status) {
1597
- for (const target of ['webui', 'agent']) {
1655
+ preGenerateSummaries(status, targets = ['webui', 'agent']) {
1656
+ for (const target of targets) {
1598
1657
  const info = dict(status[target]);
1599
1658
  if (updateTargetView(target, info, false).summary_available !== true)
1600
1659
  continue;
1601
1660
  const automatic = this.deps.llm && this.deps.checkEnabled?.() !== false && this.deps.summarizeAutomatically?.() !== false;
1602
- const work = automatic ? this.summarizeTarget(target, info) : this.queueSummary(target, () => this.refreshSummaryItems(target, info));
1661
+ const work = automatic ? this.summarizeTarget(target, info, false, true) : this.queueSummary(target, () => this.refreshSummaryItems(target, info));
1603
1662
  void work.catch(() => { this.logSummaryFailure(this.summaryKey(target, info), target); });
1604
1663
  }
1605
1664
  }
1665
+ /** TAL-1591: the Agent runtime is current again, so deferred summaries are generated once. */
1666
+ resumeDeferredSummaries() {
1667
+ this.runtimeCurrentEpoch += 1;
1668
+ if (!this.summaryDeferred.size)
1669
+ return;
1670
+ const targets = [...this.summaryDeferred];
1671
+ this.summaryDeferred.clear();
1672
+ this.preGenerateSummaries(this.cache, targets);
1673
+ }
1606
1674
  agentChannel() { return this.deps.agentChannel?.() ?? DEFAULT_CHANNEL; }
1607
1675
  /** TAL-930: the Agent's published Stable tag, one anonymous GitHub read per remote per cache TTL; an unreadable answer keeps the last verified tag. */
1608
1676
  publishedTag = async (repoUrl) => {
@@ -1762,7 +1830,15 @@ export class UpdateService {
1762
1830
  if (!this.refreshOwed)
1763
1831
  return;
1764
1832
  this.refreshOwed = false;
1765
- void this.check(true).catch((error) => { this.deps.log(`[updates] refresh after update failed: ${error.message}`); });
1833
+ this.refreshing = this.check(true).catch((error) => { this.deps.log(`[updates] refresh after update failed: ${error.message}`); });
1834
+ }
1835
+ /** Resolves once every owed refresh check has finished, so a caller can safely remove the checkouts it reads. */
1836
+ async settled() {
1837
+ let refreshing;
1838
+ do {
1839
+ refreshing = this.refreshing;
1840
+ await refreshing;
1841
+ } while (refreshing !== this.refreshing);
1766
1842
  }
1767
1843
  startAutoApply(intervalMs = AUTO_UPDATE_INTERVAL_MS) {
1768
1844
  if (this.autoStarted || this.autoRestartScheduled)
@@ -1772,6 +1848,8 @@ export class UpdateService {
1772
1848
  this.recoveryUnsubscribe = this.deps.onAgentReconnect?.((runtime) => {
1773
1849
  if (!this.autoStarted || lifecycle !== this.lifecycle)
1774
1850
  return;
1851
+ if (runtime.compatible && !runtime.stale)
1852
+ this.resumeDeferredSummaries();
1775
1853
  if (runtime.compatible && !runtime.stale && this.recovery.phase === 'blocked') {
1776
1854
  this.recoveryAttempt = 0;
1777
1855
  this.recovery = { ...this.recovery, phase: 'waiting', attempt: 0, retry_at: null };
@@ -1911,6 +1989,7 @@ export class UpdateService {
1911
1989
  throw new Error(result.detail || 'Agent recovery remains unverified.');
1912
1990
  await this.invalidate('agent');
1913
1991
  this.recovery = { phase: 'complete', attempt: this.recoveryAttempt, detail: 'Agent service and runtime recovery is verified.', retry_at: null, ...(result.operation ? { operation: result.operation } : {}), ...(result.revision ? { verified_revision: result.revision } : {}), ...(result.runtime_revision ? { runtime_revision: result.runtime_revision } : {}), ...(result.verified_version ? { verified_version: result.verified_version } : {}) };
1992
+ this.resumeDeferredSummaries();
1914
1993
  }
1915
1994
  catch (error) {
1916
1995
  if (!current())
@@ -2295,7 +2374,7 @@ export class UpdateService {
2295
2374
  const latest = str(info.latest_sha);
2296
2375
  if (!SHA.test(current) || !SHA.test(latest))
2297
2376
  throw new Error('Update range is unavailable');
2298
- const releaseNotes = info.release_based === true && (target === 'webui' ? info.channel !== 'experimental' && Array.isArray(info.release_notes) && info.release_notes.length > 0 : Boolean(this.deps.getPublicJson && githubRepo(str(info.repo_url))));
2377
+ const releaseNotes = info.release_based === true && (target === 'webui' ? info.channel === 'stable' && Array.isArray(info.release_notes) && info.release_notes.length > 0 : Boolean(this.deps.getPublicJson && githubRepo(str(info.repo_url))));
2299
2378
  const rangeKey = this.summaryKey(target, info);
2300
2379
  const identity = canon({ channel: info.channel, current_version: info.current_version, release_based: releaseNotes, repo: info.repo_url, path: target === 'agent' ? this.deps.agentDir() : this.deps.webRoot });
2301
2380
  const stored = this.pendingSummaries.get(target);
@@ -2334,7 +2413,7 @@ export class UpdateService {
2334
2413
  async summarize(target, checksOff = false) {
2335
2414
  return this.summarizeTarget(target, dict(this.cachedStatus()[target]), checksOff);
2336
2415
  }
2337
- async summarizeTarget(target, info, checksOff = false) {
2416
+ async summarizeTarget(target, info, checksOff = false, automatic = false) {
2338
2417
  const view = updateTargetView(target, info, checksOff);
2339
2418
  const range = { current_version: typeof info.current_version === 'string' ? info.current_version : null, target_version: view.target_version ?? null };
2340
2419
  if (view.summary_available !== true)
@@ -2343,7 +2422,7 @@ export class UpdateService {
2343
2422
  const pending = this.summarizing.get(key);
2344
2423
  if (pending)
2345
2424
  return pending;
2346
- const generating = this.queueSummary(target, () => this.generateSummary(target, info, range, key)).finally(() => { this.summarizing.delete(key); });
2425
+ const generating = this.queueSummary(target, () => this.generateSummary(target, info, range, key, automatic)).finally(() => { this.summarizing.delete(key); });
2347
2426
  this.summarizing.set(key, generating);
2348
2427
  return generating;
2349
2428
  }
@@ -2384,7 +2463,7 @@ export class UpdateService {
2384
2463
  }
2385
2464
  return sections;
2386
2465
  }
2387
- async generateSummary(target, info, range, key) {
2466
+ async generateSummary(target, info, range, key, automatic) {
2388
2467
  let entry;
2389
2468
  let complete = false;
2390
2469
  try {
@@ -2398,21 +2477,39 @@ export class UpdateService {
2398
2477
  const last = entry?.items.at(-1)?.id ?? null;
2399
2478
  const cached = Boolean(complete && entry?.summary_sections && entry.summarized_through === last);
2400
2479
  let sections = cached ? entry.summary_sections : null;
2480
+ // Pre-generation skips a known-stale runtime; an on-demand request asks again, and its answer proves the runtime current.
2481
+ let deferred = false;
2401
2482
  if (!sections && entry && this.deps.llm && entry.items.length) {
2402
2483
  const at = entry.summarized_through === null ? 0 : entry.items.findIndex((item) => item.id === entry.summarized_through) + 1;
2403
- try {
2404
- sections = await this.foldSummary(entry.summary_sections, entry.items.slice(at), detail, source);
2405
- if (complete && sections) {
2406
- entry.summary_sections = sections;
2407
- entry.summarized_through = last;
2408
- this.persistSummaries();
2484
+ if (automatic && this.summaryDeferred.size)
2485
+ deferred = true;
2486
+ else
2487
+ for (;;) {
2488
+ const epoch = this.runtimeCurrentEpoch;
2489
+ try {
2490
+ sections = await this.foldSummary(entry.summary_sections, entry.items.slice(at), detail, source);
2491
+ if (complete && sections) {
2492
+ entry.summary_sections = sections;
2493
+ entry.summarized_through = last;
2494
+ this.persistSummaries();
2495
+ }
2496
+ this.summaryDeferred.delete(target);
2497
+ this.resumeDeferredSummaries();
2498
+ }
2499
+ catch (error) {
2500
+ if (!(error instanceof SidecarError && error.condition === 'agent_runtime_stale'))
2501
+ this.logSummaryFailure(key, target);
2502
+ else if (epoch !== this.runtimeCurrentEpoch)
2503
+ continue;
2504
+ else
2505
+ deferred = true;
2506
+ }
2507
+ break;
2409
2508
  }
2410
- }
2411
- catch {
2412
- this.logSummaryFailure(key, target);
2413
- }
2509
+ if (deferred)
2510
+ this.summaryDeferred.add(target);
2414
2511
  }
2415
- const fallback = formatSections('', [detail]);
2512
+ const fallback = fallbackSections([detail], Boolean(entry), deferred);
2416
2513
  const summary = sections ? sectionsText(sections) : fallback[1];
2417
2514
  return { ok: true, target, ...range, summary, summary_sections: sections ?? fallback[0], generated_by: sections ? 'llm' : 'fallback', source, cached };
2418
2515
  }