@maudecode/talaria-web 1.15.0 → 1.17.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 (386) hide show
  1. package/_release.json +4 -4
  2. package/dist/api/automation-raw.js +6 -3
  3. package/dist/api/automation-raw.js.map +1 -1
  4. package/dist/api/automation-router.d.ts +158 -16
  5. package/dist/api/automation-router.js +12 -6
  6. package/dist/api/automation-router.js.map +1 -1
  7. package/dist/api/chat-router.d.ts +193 -6
  8. package/dist/api/chat-router.js +39 -16
  9. package/dist/api/chat-router.js.map +1 -1
  10. package/dist/api/git-router.d.ts +12 -1
  11. package/dist/api/git-router.js +60 -38
  12. package/dist/api/git-router.js.map +1 -1
  13. package/dist/api/raw-routes.d.ts +6 -0
  14. package/dist/api/raw-routes.js +35 -58
  15. package/dist/api/raw-routes.js.map +1 -1
  16. package/dist/api/router.d.ts +4 -2
  17. package/dist/api/router.js +8 -8
  18. package/dist/api/router.js.map +1 -1
  19. package/dist/api/sessions-router.d.ts +974 -42
  20. package/dist/api/sessions-router.js +87 -25
  21. package/dist/api/sessions-router.js.map +1 -1
  22. package/dist/api/settings-router.d.ts +254 -11
  23. package/dist/api/settings-router.js +68 -18
  24. package/dist/api/settings-router.js.map +1 -1
  25. package/dist/api/sse-routes.d.ts +11 -3
  26. package/dist/api/sse-routes.js +145 -65
  27. package/dist/api/sse-routes.js.map +1 -1
  28. package/dist/api/tools-raw.js +6 -2
  29. package/dist/api/tools-raw.js.map +1 -1
  30. package/dist/api/tools-router.d.ts +86 -9
  31. package/dist/api/tools-router.js +19 -15
  32. package/dist/api/tools-router.js.map +1 -1
  33. package/dist/app.d.ts +0 -8397
  34. package/dist/app.js +7 -2
  35. package/dist/app.js.map +1 -1
  36. package/dist/auth/gate.js +11 -4
  37. package/dist/auth/gate.js.map +1 -1
  38. package/dist/auth/oidc.d.ts +6 -2
  39. package/dist/auth/oidc.js +16 -11
  40. package/dist/auth/oidc.js.map +1 -1
  41. package/dist/auth/store.d.ts +14 -2
  42. package/dist/auth/store.js +26 -1
  43. package/dist/auth/store.js.map +1 -1
  44. package/dist/cli/dotenv.d.ts +1 -1
  45. package/dist/cli/dotenv.js +36 -3
  46. package/dist/cli/dotenv.js.map +1 -1
  47. package/dist/config/agent-config.d.ts +2 -0
  48. package/dist/config/agent-config.js +9 -0
  49. package/dist/config/agent-config.js.map +1 -1
  50. package/dist/http/addresses.d.ts +6 -0
  51. package/dist/http/addresses.js +26 -0
  52. package/dist/http/addresses.js.map +1 -1
  53. package/dist/http/context.d.ts +6 -3
  54. package/dist/http/context.js +10 -4
  55. package/dist/http/context.js.map +1 -1
  56. package/dist/links.d.ts +26 -0
  57. package/dist/links.js +60 -0
  58. package/dist/links.js.map +1 -0
  59. package/dist/onboarding.js +30 -7
  60. package/dist/onboarding.js.map +1 -1
  61. package/dist/profiles/profiles.js +1 -1
  62. package/dist/profiles/profiles.js.map +1 -1
  63. package/dist/providers/catalog.d.ts +167 -5
  64. package/dist/providers/catalog.js +662 -135
  65. package/dist/providers/catalog.js.map +1 -1
  66. package/dist/providers/tables.d.ts +3 -1
  67. package/dist/providers/tables.js +9 -4
  68. package/dist/providers/tables.js.map +1 -1
  69. package/dist/redact.d.ts +1 -0
  70. package/dist/redact.js +518 -15
  71. package/dist/redact.js.map +1 -1
  72. package/dist/runtime.js +79 -37
  73. package/dist/runtime.js.map +1 -1
  74. package/dist/sessions/anchor.d.ts +24 -3
  75. package/dist/sessions/anchor.js +94 -44
  76. package/dist/sessions/anchor.js.map +1 -1
  77. package/dist/sessions/background-tasks.d.ts +4 -1
  78. package/dist/sessions/background-tasks.js +7 -4
  79. package/dist/sessions/background-tasks.js.map +1 -1
  80. package/dist/sessions/claude-code.d.ts +19 -0
  81. package/dist/sessions/claude-code.js +250 -0
  82. package/dist/sessions/claude-code.js.map +1 -0
  83. package/dist/sessions/completions.d.ts +13 -1
  84. package/dist/sessions/completions.js +64 -12
  85. package/dist/sessions/completions.js.map +1 -1
  86. package/dist/sessions/compress.d.ts +14 -1
  87. package/dist/sessions/compress.js +52 -11
  88. package/dist/sessions/compress.js.map +1 -1
  89. package/dist/sessions/journal.d.ts +8 -0
  90. package/dist/sessions/journal.js +44 -10
  91. package/dist/sessions/journal.js.map +1 -1
  92. package/dist/sessions/list.d.ts +13 -5
  93. package/dist/sessions/list.js +56 -26
  94. package/dist/sessions/list.js.map +1 -1
  95. package/dist/sessions/merge.d.ts +122 -9
  96. package/dist/sessions/merge.js +544 -33
  97. package/dist/sessions/merge.js.map +1 -1
  98. package/dist/sessions/pending.d.ts +5 -0
  99. package/dist/sessions/pending.js +30 -10
  100. package/dist/sessions/pending.js.map +1 -1
  101. package/dist/sessions/service.d.ts +100 -4
  102. package/dist/sessions/service.js +567 -102
  103. package/dist/sessions/service.js.map +1 -1
  104. package/dist/sessions/session.d.ts +16 -1
  105. package/dist/sessions/session.js +29 -2
  106. package/dist/sessions/session.js.map +1 -1
  107. package/dist/sessions/shares.js +11 -2
  108. package/dist/sessions/shares.js.map +1 -1
  109. package/dist/sessions/state-db.d.ts +26 -4
  110. package/dist/sessions/state-db.js +126 -8
  111. package/dist/sessions/state-db.js.map +1 -1
  112. package/dist/sessions/store.js +6 -1
  113. package/dist/sessions/store.js.map +1 -1
  114. package/dist/sessions/streams.d.ts +10 -0
  115. package/dist/sessions/streams.js +14 -3
  116. package/dist/sessions/streams.js.map +1 -1
  117. package/dist/sessions/todo.d.ts +6 -1
  118. package/dist/sessions/todo.js +11 -4
  119. package/dist/sessions/todo.js.map +1 -1
  120. package/dist/sessions/tool-display.d.ts +12 -1
  121. package/dist/sessions/tool-display.js +76 -1
  122. package/dist/sessions/tool-display.js.map +1 -1
  123. package/dist/sessions/turn.d.ts +49 -10
  124. package/dist/sessions/turn.js +459 -185
  125. package/dist/sessions/turn.js.map +1 -1
  126. package/dist/settings.d.ts +20 -2
  127. package/dist/settings.js +49 -2
  128. package/dist/settings.js.map +1 -1
  129. package/dist/sidecar/fake.d.ts +2 -2
  130. package/dist/sidecar/fake.js +7 -2
  131. package/dist/sidecar/fake.js.map +1 -1
  132. package/dist/spa.js +2 -1
  133. package/dist/spa.js.map +1 -1
  134. package/dist/test/harness.js +2 -0
  135. package/dist/test/harness.js.map +1 -1
  136. package/dist/tools/commands.d.ts +15 -0
  137. package/dist/tools/commands.js +52 -0
  138. package/dist/tools/commands.js.map +1 -0
  139. package/dist/tools/crons.d.ts +4 -1
  140. package/dist/tools/crons.js +58 -11
  141. package/dist/tools/crons.js.map +1 -1
  142. package/dist/tools/insights.d.ts +8 -2
  143. package/dist/tools/insights.js +18 -2
  144. package/dist/tools/insights.js.map +1 -1
  145. package/dist/tools/kanban.d.ts +41 -1
  146. package/dist/tools/kanban.js +113 -2
  147. package/dist/tools/kanban.js.map +1 -1
  148. package/dist/tools/mcp.d.ts +2 -1
  149. package/dist/tools/mcp.js +16 -6
  150. package/dist/tools/mcp.js.map +1 -1
  151. package/dist/tools/terminal.d.ts +1 -0
  152. package/dist/tools/terminal.js +1 -1
  153. package/dist/tools/terminal.js.map +1 -1
  154. package/dist/tools/update-notifications.d.ts +1 -1
  155. package/dist/tools/update-notifications.js +1 -1
  156. package/dist/tools/update-notifications.js.map +1 -1
  157. package/dist/tools/updates.d.ts +15 -3
  158. package/dist/tools/updates.js +207 -41
  159. package/dist/tools/updates.js.map +1 -1
  160. package/dist/workspace/fs.d.ts +7 -3
  161. package/dist/workspace/fs.js +5 -1
  162. package/dist/workspace/fs.js.map +1 -1
  163. package/dist/workspace/git.d.ts +57 -10
  164. package/dist/workspace/git.js +302 -195
  165. package/dist/workspace/git.js.map +1 -1
  166. package/dist/workspace/media-refs.d.ts +13 -0
  167. package/dist/workspace/media-refs.js +165 -0
  168. package/dist/workspace/media-refs.js.map +1 -0
  169. package/dist/workspace/media.d.ts +19 -0
  170. package/dist/workspace/media.js +63 -2
  171. package/dist/workspace/media.js.map +1 -1
  172. package/dist/workspace/preview.d.ts +28 -0
  173. package/dist/workspace/preview.js +110 -0
  174. package/dist/workspace/preview.js.map +1 -0
  175. package/dist/workspace/rollback.d.ts +5 -4
  176. package/dist/workspace/rollback.js +12 -9
  177. package/dist/workspace/rollback.js.map +1 -1
  178. package/dist/workspace/upload.d.ts +2 -0
  179. package/dist/workspace/upload.js +4 -1
  180. package/dist/workspace/upload.js.map +1 -1
  181. package/dist/workspace/workspaces.d.ts +7 -1
  182. package/dist/workspace/workspaces.js +30 -21
  183. package/dist/workspace/workspaces.js.map +1 -1
  184. package/dist/workspace/worktrees.d.ts +2 -4
  185. package/dist/workspace/worktrees.js +28 -33
  186. package/dist/workspace/worktrees.js.map +1 -1
  187. package/package.json +4 -2
  188. package/sidecar/scripts/replay_sidecar.py +4 -2
  189. package/sidecar/talaria_sidecar/__init__.py +1 -1
  190. package/sidecar/talaria_sidecar/__main__.py +7 -1
  191. package/sidecar/talaria_sidecar/home.py +98 -2
  192. package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
  193. package/sidecar/talaria_sidecar/methods/aux.py +19 -3
  194. package/sidecar/talaria_sidecar/methods/chat.py +551 -61
  195. package/sidecar/talaria_sidecar/methods/commands.py +61 -33
  196. package/sidecar/talaria_sidecar/methods/config.py +14 -10
  197. package/sidecar/talaria_sidecar/methods/cron.py +10 -6
  198. package/sidecar/talaria_sidecar/methods/kanban.py +115 -15
  199. package/sidecar/talaria_sidecar/methods/oauth.py +439 -0
  200. package/sidecar/talaria_sidecar/methods/process.py +60 -1
  201. package/sidecar/talaria_sidecar/methods/profiles.py +12 -5
  202. package/sidecar/talaria_sidecar/methods/providers.py +161 -1
  203. package/sidecar/talaria_sidecar/methods/runtime.py +5 -0
  204. package/sidecar/talaria_sidecar/methods/text.py +18 -21
  205. package/sidecar/talaria_sidecar/methods/usage.py +264 -5
  206. package/static/dist/FILES.txt +126 -121
  207. package/static/dist/assets/AppShell-fb2td9zi.js +1 -0
  208. package/static/dist/assets/ChatPage-cj96kiy9.js +25 -0
  209. package/static/dist/assets/Dialog-kxcg7ard.js +1 -0
  210. package/static/dist/assets/ExtensionRoute-jf7h0754.js +1 -0
  211. package/static/dist/assets/HubRoute-gmanpd5y.js +2 -0
  212. package/static/dist/assets/{Markdown-dy8t4dy7.js → Markdown-mdwlvj3w.js} +125 -125
  213. package/static/dist/assets/RightPanel-ftvrjlcp.js +1 -0
  214. package/static/dist/assets/Select-bilaypej.js +1 -0
  215. package/static/dist/assets/SessionListPanel-og8n36qs.js +1 -0
  216. package/static/dist/assets/SettingsLayout-jonjefmj.js +1 -0
  217. package/static/dist/assets/States-nmejrwrm.js +1 -0
  218. package/static/dist/assets/Toaster-nnl8zkt9.js +1 -0
  219. package/static/dist/assets/_app-gdidzd94.js +1 -0
  220. package/static/dist/assets/_app.ext._extensionId-opyh9y0v.js +1 -0
  221. package/static/dist/assets/_app.index-hbarzbjx.js +1 -0
  222. package/static/dist/assets/_app.insights-luywlarz.js +1 -0
  223. package/static/dist/assets/_app.kanban-kincnbr8.js +1 -0
  224. package/static/dist/assets/_app.logs-oi2gr3gs.js +1 -0
  225. package/static/dist/assets/_app.memory-b6jfivt6.js +1 -0
  226. package/static/dist/assets/_app.profiles-lpvixmqp.js +1 -0
  227. package/static/dist/assets/{_app.session._sessionId-gyoh5ylx.js → _app.session._sessionId-bfd4h3id.js} +1 -1
  228. package/static/dist/assets/_app.settings-vowx3iq0.js +1 -0
  229. package/static/dist/assets/_app.settings._section-cnntg1tu.js +3 -0
  230. package/static/dist/assets/_app.skills-fb57lpau.js +1 -0
  231. package/static/dist/assets/_app.tasks-eszpx1q7.js +2 -0
  232. package/static/dist/assets/_app.todos-nr05ac6w.js +1 -0
  233. package/static/dist/assets/_app.workspaces-d2luomu6.js +1 -0
  234. package/static/dist/assets/{abnfDiagram-VCTEODGH-cjqletra.js → abnfDiagram-VCTEODGH-b2x1lqot.js} +1 -1
  235. package/static/dist/assets/architecture-7GRP2DOG-hd0o7bde.js +1 -0
  236. package/static/dist/assets/architectureDiagram-5GKGNRK7-h38o5l7b.js +36 -0
  237. package/static/dist/assets/{back-e4m6nsnm.js → back-bemaer09.js} +1 -1
  238. package/static/dist/assets/{blockDiagram-I7D4REHJ-b195z021.js → blockDiagram-I7D4REHJ-bqquxv2u.js} +1 -1
  239. package/static/dist/assets/{c4Diagram-7LVT6UL2-olu212k1.js → c4Diagram-7LVT6UL2-f3fb8w6z.js} +1 -1
  240. package/static/dist/assets/cancel-drd0g6d9.js +1 -0
  241. package/static/dist/assets/channel-cpdgf867.js +1 -0
  242. package/static/dist/assets/{chunk-4HAMMTFA-b8o1nufs.js → chunk-4HAMMTFA-bzfyyzp3.js} +1 -1
  243. package/static/dist/assets/{chunk-75Z2AOVW-l1seddto.js → chunk-75Z2AOVW-ly99rfx5.js} +1 -1
  244. package/static/dist/assets/{chunk-DU6HZSFF-lo5zg15v.js → chunk-DU6HZSFF-bg6ecfqf.js} +3 -3
  245. package/static/dist/assets/{chunk-F27PBJKO-dsdzrp16.js → chunk-F27PBJKO-e8k7mmqw.js} +1 -1
  246. package/static/dist/assets/{chunk-GMAD6QVW-f3fxqq8b.js → chunk-GMAD6QVW-cmalnoaj.js} +1 -1
  247. package/static/dist/assets/{chunk-GVQU2GXP-h8egxtf6.js → chunk-GVQU2GXP-gmif5o01.js} +1 -1
  248. package/static/dist/assets/{chunk-IMKFNOWR-iolwd8s0.js → chunk-IMKFNOWR-f1nwwh6u.js} +1 -1
  249. package/static/dist/assets/{chunk-L3NEJ4N5-b88bbtwi.js → chunk-L3NEJ4N5-oktfh5v7.js} +1 -1
  250. package/static/dist/assets/{chunk-OSK3NFVY-e3e7nr6s.js → chunk-OSK3NFVY-b1sdx96z.js} +1 -1
  251. package/static/dist/assets/{chunk-P2QGCYS3-mdc46rt1.js → chunk-P2QGCYS3-fhu4nzxt.js} +1 -1
  252. package/static/dist/assets/{chunk-POPQ4Y6H-kqlllrrm.js → chunk-POPQ4Y6H-em31rnef.js} +1 -1
  253. package/static/dist/assets/{chunk-PWAF6VOD-he585k2x.js → chunk-PWAF6VOD-bxhhyftw.js} +1 -1
  254. package/static/dist/assets/{chunk-SHT3W25Y-gh94y9a4.js → chunk-SHT3W25Y-fmrvwcav.js} +3 -3
  255. package/static/dist/assets/{chunk-SVP7TREG-euxp9y7e.js → chunk-SVP7TREG-lymukl2j.js} +1 -1
  256. package/static/dist/assets/{chunk-TICWLB2K-c8cxes1q.js → chunk-TICWLB2K-lmza6k23.js} +1 -1
  257. package/static/dist/assets/classDiagram-ZZMXUADV-ko09sguk.js +1 -0
  258. package/static/dist/assets/classDiagram-v2-VYDZK3BY-ko09sguk.js +1 -0
  259. package/static/dist/assets/{copied-kq0u3ht7.js → copied-ima3pysb.js} +1 -1
  260. package/static/dist/assets/copy-fw5b1pc6.js +1 -0
  261. package/static/dist/assets/{cynefin-OW5HDTMX-lxd44ux4.js → cynefin-OW5HDTMX-czlhbyhs.js} +1 -1
  262. package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-njpiwat8.js → cynefinDiagram-5FMLGOSQ-gq7mvswb.js} +1 -1
  263. package/static/dist/assets/{dagre-GXQ25YYZ-nvgy6yju.js → dagre-GXQ25YYZ-cqdbf7dr.js} +4 -4
  264. package/static/dist/assets/{diagram-S7CK7UJ4-g98nyv72.js → diagram-S7CK7UJ4-o6arxa58.js} +3 -3
  265. package/static/dist/assets/{diagram-UQ7AKVKN-ovgm6lvv.js → diagram-UQ7AKVKN-nhnd68tz.js} +1 -1
  266. package/static/dist/assets/{diagram-VSXAHHWV-pb2bn2e4.js → diagram-VSXAHHWV-dk2sclzn.js} +1 -1
  267. package/static/dist/assets/{diagram-VX7I27RA-6j4mvfqo.js → diagram-VX7I27RA-n3k5nyx3.js} +1 -1
  268. package/static/dist/assets/{diagram-Z3DM3KII-dqmb982r.js → diagram-Z3DM3KII-m6q9cwdh.js} +1 -1
  269. package/static/dist/assets/{ebnfDiagram-PWID7BFC-ozbpzb6d.js → ebnfDiagram-PWID7BFC-lsa5641p.js} +1 -1
  270. package/static/dist/assets/endpoints-d33siokx.js +64 -0
  271. package/static/dist/assets/{erDiagram-RLTQ6QDP-hl7m8vua.js → erDiagram-RLTQ6QDP-fo2ckbe6.js} +1 -1
  272. package/static/dist/assets/eventmodeling-NTZA5JFV-emctlo64.js +1 -0
  273. package/static/dist/assets/flowDiagram-HODETNUW-bfi3moqa.js +1 -0
  274. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-ompixqmh.js → ganttDiagram-EL5Y4UJY-nzqz6x9g.js} +1 -1
  275. package/static/dist/assets/{gitGraph-4MIJSDKK-b6vxwp9q.js → gitGraph-4MIJSDKK-gukvcxe6.js} +1 -1
  276. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-k98f57on.js → gitGraphDiagram-WWUBYQGX-lqhdp8f0.js} +1 -1
  277. package/static/dist/assets/{highlighted-body-KPVGNVTW-cd3ff6ge.js → highlighted-body-KPVGNVTW-igw6cp39.js} +1 -1
  278. package/static/dist/assets/index-cxq58xb1.js +11 -0
  279. package/static/dist/assets/index-hgtx08n5.css +2 -0
  280. package/static/dist/assets/{info-A6RAGUB7-hjcwjami.js → info-A6RAGUB7-gvu7a93l.js} +1 -1
  281. package/static/dist/assets/infoDiagram-27XIBGKW-m8t8g6w1.js +2 -0
  282. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-bxak4mwu.js → ishikawaDiagram-5VMMS53U-l07vkbgj.js} +1 -1
  283. package/static/dist/assets/{journeyDiagram-3NMN7TZE-khmihclr.js → journeyDiagram-3NMN7TZE-hybkgj8l.js} +1 -1
  284. package/static/dist/assets/{kanban-definition-UXKFOSKX-h1r32wdx.js → kanban-definition-UXKFOSKX-by13uvtn.js} +1 -1
  285. package/static/dist/assets/{lazyRouteComponent-b2eg0fws.js → lazyRouteComponent-af0lvgjx.js} +1 -1
  286. package/static/dist/assets/{line-friyjof3.js → line-osxq6fq7.js} +1 -1
  287. package/static/dist/assets/link-jyxicdhg.js +1 -0
  288. package/static/dist/assets/login-ec21t39x.js +1 -0
  289. package/static/dist/assets/mermaid-HWGCJPDP-gfl8z3ep.js +1 -0
  290. package/static/dist/assets/{mermaid-parser.core-f1gvpwrt.js → mermaid-parser.core-i91oxmou.js} +3 -3
  291. package/static/dist/assets/{mindmap-definition-YA3MSWOX-mt2oxwue.js → mindmap-definition-YA3MSWOX-m82mx8ww.js} +1 -1
  292. package/static/dist/assets/onboarding-btnltvyz.js +1 -0
  293. package/static/dist/assets/onboarding_model_label-dp7xffoh.js +1 -0
  294. package/static/dist/assets/{packet-AYTQ26CC-jik4ixlf.js → packet-AYTQ26CC-nbtgge2o.js} +1 -1
  295. package/static/dist/assets/{pegDiagram-XKGWAZYB-erxlv6cc.js → pegDiagram-XKGWAZYB-f1zxzga1.js} +1 -1
  296. package/static/dist/assets/{pie-WAS4IAKB-mnkoldfl.js → pie-WAS4IAKB-of8vuhxs.js} +1 -1
  297. package/static/dist/assets/{pieDiagram-E7YTZNPT-i7lwrada.js → pieDiagram-E7YTZNPT-o7y8ftio.js} +3 -3
  298. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-fr8ejdoy.js → quadrantDiagram-AXDQQJYC-iqiwia1t.js} +1 -1
  299. package/static/dist/assets/{radar-RG4KPBEZ-otarjte2.js → radar-RG4KPBEZ-delnsy2v.js} +1 -1
  300. package/static/dist/assets/{railroad-74A4TZTK-lw362oto.js → railroad-74A4TZTK-nspnyq9u.js} +1 -1
  301. package/static/dist/assets/railroad-abnf-HS5TGJTU-nst1qxyn.js +1 -0
  302. package/static/dist/assets/railroad-ebnf-LZEXJU2U-ci37x8qy.js +1 -0
  303. package/static/dist/assets/railroad-peg-WCYAUIDC-aimkk07z.js +1 -0
  304. package/static/dist/assets/{railroadDiagram-O6MQD6OU-esyn75pw.js → railroadDiagram-O6MQD6OU-z41tqx5z.js} +1 -1
  305. package/static/dist/assets/refresh-b4uams1i.js +1 -0
  306. package/static/dist/assets/refresh-cw-nt1dtsx4.js +1 -0
  307. package/static/dist/assets/{requirementDiagram-BXWQKSXE-cyhi5u29.js → requirementDiagram-BXWQKSXE-bdvif194.js} +1 -1
  308. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-jljpbo0h.js → sankeyDiagram-P5KCCOFB-h73e0rol.js} +1 -1
  309. package/static/dist/assets/{saved-do49si3v.js → saved-kg52csy7.js} +1 -1
  310. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-fz0dhlu7.js → sequenceDiagram-WJ2MYXX4-iv95mb1z.js} +1 -1
  311. package/static/dist/assets/{settings_section_extensions_title-b7lojn0o.js → settings_section_extensions_title-ej0iapxe.js} +1 -1
  312. package/static/dist/assets/share._token-f97e94r0.js +2 -0
  313. package/static/dist/assets/sliders-horizontal-fj18it47.js +1 -0
  314. package/static/dist/assets/sse-fwpqtzbg.js +1 -0
  315. package/static/dist/assets/{stateDiagram-D77RDMKH-kdnithdx.js → stateDiagram-D77RDMKH-k417ixmf.js} +1 -1
  316. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hwn4apct.js +1 -0
  317. package/static/dist/assets/{swimlanes-42K2YHIH-esd6gmz3.js → swimlanes-42K2YHIH-esola70w.js} +1 -1
  318. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-d1h97oyg.js +8 -0
  319. package/static/dist/assets/{timeline-definition-24CTP7MA-g0qygccv.js → timeline-definition-24CTP7MA-getrz2y8.js} +1 -1
  320. package/static/dist/assets/todoStore-eginf9h4.js +1 -0
  321. package/static/dist/assets/{treeView-Q6P3EWNA-ndchzkuu.js → treeView-Q6P3EWNA-hc7ap1q7.js} +1 -1
  322. package/static/dist/assets/{treemap-WGGIJYW6-hwjxj0zz.js → treemap-WGGIJYW6-b7k1syy5.js} +1 -1
  323. package/static/dist/assets/tts-lxdxnmjd.js +1 -0
  324. package/static/dist/assets/{untitled-mbr6tuhu.js → untitled-ovpfthg4.js} +1 -1
  325. package/static/dist/assets/useForm-bcblv1rx.js +1 -0
  326. package/static/dist/assets/useLocale-fi5jb8ma.js +1 -0
  327. package/static/dist/assets/{useParams-lo9u33d1.js → useParams-lhg566ew.js} +1 -1
  328. package/static/dist/assets/{useSearch-lq1mr090.js → useSearch-lbrh6ejn.js} +1 -1
  329. package/static/dist/assets/{vennDiagram-4TSXK5OY-gubovd1r.js → vennDiagram-4TSXK5OY-n6pcy5qb.js} +1 -1
  330. package/static/dist/assets/{wardley-WFR3VGLG-ir3om65j.js → wardley-WFR3VGLG-lpa18vz1.js} +1 -1
  331. package/static/dist/assets/{wardleyDiagram-VM6X3IG4-ce0or1ie.js → wardleyDiagram-VM6X3IG4-kpclwwg7.js} +2 -2
  332. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-dexylcjg.js → xychartDiagram-S5SC5T6Z-paa2n8y0.js} +1 -1
  333. package/static/dist/index.html +1 -1
  334. package/static/dist/sw.js +2 -2
  335. package/static/dist/assets/AppShell-orat1s43.js +0 -1
  336. package/static/dist/assets/ChatPage-ojhka3hy.js +0 -22
  337. package/static/dist/assets/HubRoute-gxgw1t33.js +0 -2
  338. package/static/dist/assets/RightPanel-c66ani1s.js +0 -1
  339. package/static/dist/assets/Select-fswf66up.js +0 -1
  340. package/static/dist/assets/SessionListPanel-goh5mtt8.js +0 -1
  341. package/static/dist/assets/SettingsLayout-n5d4wq4m.js +0 -1
  342. package/static/dist/assets/States-kxyu50at.js +0 -1
  343. package/static/dist/assets/Toaster-6zmbcqgg.js +0 -1
  344. package/static/dist/assets/_app-fowyruiu.js +0 -1
  345. package/static/dist/assets/_app.ext._extensionId-nvjyrwhy.js +0 -1
  346. package/static/dist/assets/_app.index-c9zv4y7w.js +0 -1
  347. package/static/dist/assets/_app.insights-jf12nofo.js +0 -1
  348. package/static/dist/assets/_app.kanban-lri5a4yu.js +0 -1
  349. package/static/dist/assets/_app.logs-md1p0zqo.js +0 -1
  350. package/static/dist/assets/_app.memory-bzvf2e28.js +0 -1
  351. package/static/dist/assets/_app.profiles-jpg7zmbn.js +0 -1
  352. package/static/dist/assets/_app.settings-mpuwlx4j.js +0 -1
  353. package/static/dist/assets/_app.settings._section-knz8rwoj.js +0 -1
  354. package/static/dist/assets/_app.skills-fwu1dkir.js +0 -1
  355. package/static/dist/assets/_app.tasks-h9gphtl3.js +0 -2
  356. package/static/dist/assets/_app.todos-hd1dnvrh.js +0 -1
  357. package/static/dist/assets/_app.workspaces-l8toyn5f.js +0 -1
  358. package/static/dist/assets/architecture-7GRP2DOG-cavnusaw.js +0 -1
  359. package/static/dist/assets/architectureDiagram-5GKGNRK7-k5a7v36n.js +0 -36
  360. package/static/dist/assets/channel-gozy3dp3.js +0 -1
  361. package/static/dist/assets/classDiagram-ZZMXUADV-n0vs2f2q.js +0 -1
  362. package/static/dist/assets/classDiagram-v2-VYDZK3BY-n0vs2f2q.js +0 -1
  363. package/static/dist/assets/endpoints-k8agnro8.js +0 -9
  364. package/static/dist/assets/eventmodeling-NTZA5JFV-j1y2ekec.js +0 -1
  365. package/static/dist/assets/flowDiagram-HODETNUW-g2cvcbm5.js +0 -1
  366. package/static/dist/assets/index-nfy0ezs6.css +0 -2
  367. package/static/dist/assets/index-nqed3oum.js +0 -11
  368. package/static/dist/assets/infoDiagram-27XIBGKW-fm06rj36.js +0 -2
  369. package/static/dist/assets/link-m90ahx3n.js +0 -1
  370. package/static/dist/assets/login-bw7m2fzo.js +0 -1
  371. package/static/dist/assets/matchContext-f8oy3lo7.js +0 -1
  372. package/static/dist/assets/mermaid-HWGCJPDP-njwcl62n.js +0 -1
  373. package/static/dist/assets/onboarding-ret37j1e.js +0 -1
  374. package/static/dist/assets/railroad-abnf-HS5TGJTU-m741owar.js +0 -1
  375. package/static/dist/assets/railroad-ebnf-LZEXJU2U-noa4fbia.js +0 -1
  376. package/static/dist/assets/railroad-peg-WCYAUIDC-o4bpw4nb.js +0 -1
  377. package/static/dist/assets/refresh-cw-k66keho6.js +0 -1
  378. package/static/dist/assets/search-j5ki6a9o.js +0 -1
  379. package/static/dist/assets/share._token-kg8w647b.js +0 -2
  380. package/static/dist/assets/sliders-horizontal-c4wya4dy.js +0 -1
  381. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-k2wg2645.js +0 -1
  382. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-n5kvjtgr.js +0 -8
  383. package/static/dist/assets/tabBuild-bjmyvmn5.js +0 -56
  384. package/static/dist/assets/todoStore-kjk5l0sy.js +0 -1
  385. package/static/dist/assets/useForm-ocxu460f.js +0 -1
  386. package/static/dist/assets/useLocale-fzy5jhg6.js +0 -1
@@ -14,6 +14,7 @@ import { readCapped } from '../http/capped.js';
14
14
  import { execFile } from 'node:child_process';
15
15
  import { createHash } from 'node:crypto';
16
16
  import { copyFileSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from 'node:fs';
17
+ import { tmpdir } from 'node:os';
17
18
  import { delimiter, dirname, isAbsolute, join, resolve } from 'node:path';
18
19
  import { dict } from '../config/agent-config.js';
19
20
  import { validateReleaseInfo } from '../release.js';
@@ -178,8 +179,12 @@ export function githubJson(fetchImpl, env) {
178
179
  return JSON.parse(body.toString('utf8'));
179
180
  };
180
181
  }
181
- /** Python `published_web_release`: the newest completed `release-set-<sha>` whose Web component matches the channel's tag family. */
182
- export async function publishedWebRelease(channel, getJson, now = () => performance.now()) {
182
+ const completeManifest = (m, tag) => m?.schemaVersion === 1 && m.status === 'complete' && m.releaseSet === tag.slice('release-set-'.length);
183
+ /**
184
+ * Python `published_web_release`: the newest completed `release-set-<sha>` whose Web component matches the channel's tag family.
185
+ * `installed` (a bare `X.Y.Z`) also counts the completed releases an update skips, one manifest per older release set (TAL-624).
186
+ */
187
+ export async function publishedWebRelease(channel, getJson, now = () => performance.now(), installed) {
183
188
  const tagPattern = new RegExp(`^${channel === 'experimental' ? 'web-exp-v' : 'web-v'}${VERSION}$`);
184
189
  const deadline = now() + 15_000;
185
190
  const fetchJson = (path, asset = false) => {
@@ -204,10 +209,11 @@ export async function publishedWebRelease(channel, getJson, now = () => performa
204
209
  if (exhausted)
205
210
  throw new ReleaseUnavailable('Release history exceeds automatic lookup; update manually');
206
211
  published.sort((a, b) => (str(a.published_at) < str(b.published_at) ? 1 : str(a.published_at) > str(b.published_at) ? -1 : 0));
207
- for (const release of published) {
212
+ /** A release set's tag and manifest; null for other releases. */
213
+ const manifestOf = async (release) => {
208
214
  const tag = release.tag_name;
209
215
  if (typeof tag !== 'string' || !/^release-set-[a-f0-9]{40}$/.test(tag))
210
- continue;
216
+ return null;
211
217
  if (!Array.isArray(release.assets))
212
218
  throw new ReleaseUnavailable('Published release set has invalid assets');
213
219
  const assets = release.assets.filter((a) => Boolean(a) && typeof a === 'object' && a.name === 'release-set.json');
@@ -215,8 +221,36 @@ export async function publishedWebRelease(channel, getJson, now = () => performa
215
221
  if (assets.length !== 1 || typeof id !== 'number' || !Number.isInteger(id) || id < 1)
216
222
  throw new ReleaseUnavailable('Published release set lacks its immutable manifest');
217
223
  const manifest = await fetchJson(`/releases/assets/${String(id)}`, true);
218
- const m = manifest && typeof manifest === 'object' && !Array.isArray(manifest) ? manifest : null;
219
- if (m?.schemaVersion !== 1 || m.status !== 'complete' || m.releaseSet !== tag.slice('release-set-'.length))
224
+ return { tag, m: manifest && typeof manifest === 'object' && !Array.isArray(manifest) ? manifest : null };
225
+ };
226
+ /** Distinct completed channel versions above `installed` in the older release sets, plus `latest`. A Web tag without a completed set never counts; an unreadable set ends the count. */
227
+ const releasesSince = async (older, latest) => {
228
+ if (installed === undefined || compareVersions(latest, installed) <= 0)
229
+ return 1;
230
+ const versions = new Set([latest]);
231
+ try {
232
+ for (const release of older) {
233
+ const set = await manifestOf(release);
234
+ if (!set || !completeManifest(set.m, set.tag))
235
+ continue;
236
+ const webTag = dict(dict(set.m.components).web).tag;
237
+ if (typeof webTag !== 'string' || !tagPattern.test(webTag))
238
+ continue;
239
+ const version = webTag.split('-v').pop() ?? '';
240
+ if (compareVersions(version, installed) <= 0)
241
+ break;
242
+ versions.add(version);
243
+ }
244
+ }
245
+ catch { /* the newest release still counts */ }
246
+ return versions.size;
247
+ };
248
+ for (const [index, release] of published.entries()) {
249
+ const set = await manifestOf(release);
250
+ if (!set)
251
+ continue;
252
+ const { tag, m } = set;
253
+ if (!completeManifest(m, tag))
220
254
  throw new ReleaseUnavailable('Release set is incomplete or has inconsistent provenance');
221
255
  if (!m.components || typeof m.components !== 'object' || Array.isArray(m.components))
222
256
  throw new ReleaseUnavailable('Release set lacks component metadata');
@@ -256,6 +290,7 @@ export async function publishedWebRelease(channel, getJson, now = () => performa
256
290
  manifestReleaseSet: str(m.releaseSet),
257
291
  runtime: { tag: componentTag, version: component.version, sourceRevision: source, releaseSet: source, contracts: supported, compatibleAgent: agent },
258
292
  release_url: `${REPOSITORY_URL}/releases/tag/${tag}`,
293
+ releasesBehind: await releasesSince(published.slice(index + 1), str(component.version)),
259
294
  };
260
295
  }
261
296
  throw new ReleaseUnavailable('No completed Talaria Web release is available on this channel');
@@ -319,6 +354,11 @@ export function ghcrExperimental(fetchImpl) {
319
354
  }
320
355
  return { tag: `web-exp-v${version}`, version, sourceRevision, digest: layer.digest, size };
321
356
  },
357
+ builds: async () => {
358
+ const body = await json(await send(`${GHCR}/v2/${EXPERIMENTAL_REPOSITORY}/tags/list?n=1000`, { headers: { Authorization: `Bearer ${await token()}` }, signal: AbortSignal.timeout(5000) }), 'tag list');
359
+ const tags = Array.isArray(body.tags) ? body.tags : [];
360
+ return new Set(tags.flatMap((tag) => (typeof tag === 'string' && /^sha-[a-f0-9]{40}$/.test(tag) ? [tag.slice(4)] : [])));
361
+ },
322
362
  download: async (release) => {
323
363
  let res = await send(`${GHCR}/v2/${EXPERIMENTAL_REPOSITORY}/blobs/${release.digest}`, { headers: { Authorization: `Bearer ${await token()}` }, signal: AbortSignal.timeout(120_000) });
324
364
  if (res.status >= 300 && res.status < 400) {
@@ -412,8 +452,37 @@ function diskRelease(webRoot) {
412
452
  function npmInstallChannel(installed, id) {
413
453
  return str(diskRelease(installed.packageRoot)?.tag ?? id.release().tag).startsWith('web-exp-v') ? 'experimental' : 'stable';
414
454
  }
415
- /** An npm install on Experimental: behind when its source differs from the `experimental` tag, or when switching channels. */
416
- async function checkNpmExperimental(result, installed, id, registry) {
455
+ /**
456
+ * Published Experimental builds after `installed` up to `latest` (TAL-626): commits on `latest`'s history back to `installed`
457
+ * that carry a `sha-` build tag. Never below 1; 1 when the history or tag list cannot be read.
458
+ */
459
+ async function experimentalBuildsBehind(installed, latest, registry, getJson) {
460
+ if (!installed)
461
+ return 1;
462
+ let count = 0;
463
+ try {
464
+ const builds = await registry.builds();
465
+ for (let page = 1; page <= 5; page += 1) {
466
+ const commits = await getJson(`/commits?sha=${latest}&per_page=100&page=${String(page)}`, { asset: false });
467
+ if (!Array.isArray(commits))
468
+ break;
469
+ for (const commit of commits) {
470
+ const sha = dict(commit).sha;
471
+ if (sha === installed)
472
+ return Math.max(1, count);
473
+ if (typeof sha === 'string' && builds.has(sha))
474
+ count += 1;
475
+ }
476
+ if (commits.length < 100)
477
+ break;
478
+ }
479
+ }
480
+ catch { /* count what was read */ }
481
+ // ponytail: 500 commits back; an older install reports the builds within that window.
482
+ return Math.max(1, count);
483
+ }
484
+ /** An npm install on Experimental: behind by its missed builds when its source differs from the `experimental` tag, or when switching channels. */
485
+ async function checkNpmExperimental(result, installed, id, registry, getJson) {
417
486
  let release;
418
487
  try {
419
488
  release = await registry.release();
@@ -426,9 +495,9 @@ async function checkNpmExperimental(result, installed, id, registry) {
426
495
  const disk = diskRelease(installed.packageRoot);
427
496
  const current = str(disk?.sourceRevision ?? id.release().sourceRevision) || null;
428
497
  if (npmInstallChannel(installed, id) !== 'experimental')
429
- return { ...result, current_sha: current, behind: 1, channel_switch: true, message: `Switching to Experimental installs ${release.version}.` };
498
+ return { ...result, current_sha: current, behind: await experimentalBuildsBehind(current, release.sourceRevision, registry, getJson), channel_switch: true, message: `Switching to Experimental installs ${release.version}.` };
430
499
  if (disk?.sourceRevision !== release.sourceRevision)
431
- return { ...result, current_sha: current, behind: 1, message: `Experimental update ${release.version} is available.` };
500
+ return { ...result, current_sha: current, behind: await experimentalBuildsBehind(current, release.sourceRevision, registry, getJson), message: `Experimental update ${release.version} is available.` };
432
501
  const metadataRepair = !same(id.release(), disk);
433
502
  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.' } : {}) };
434
503
  }
@@ -440,10 +509,12 @@ export async function checkWebUpdate(webRoot, currentVersion, channel, git, getJ
440
509
  if (root !== null)
441
510
  return { ...result, manual_update: true, message: CONTRIBUTOR_CHECKOUT_MESSAGE };
442
511
  if (channel === 'experimental' && npmInstall && registry)
443
- return checkNpmExperimental(result, npmInstall, id, registry);
512
+ return checkNpmExperimental(result, npmInstall, id, registry, getJson);
513
+ const packaged = new RegExp(`^${channel === 'experimental' ? 'web-exp-v' : 'web-v'}${VERSION}$`).exec(currentVersion)?.slice(1, 4).join('.');
514
+ const installed = npmInstall?.version ?? packaged;
444
515
  let release;
445
516
  try {
446
- release = await publishedWebRelease(channel, getJson);
517
+ release = await publishedWebRelease(channel, getJson, undefined, installed && new RegExp(`^${VERSION}$`).test(installed) ? installed : undefined);
447
518
  }
448
519
  catch (error) {
449
520
  if (error instanceof ReleaseUnavailable)
@@ -461,7 +532,7 @@ export async function checkWebUpdate(webRoot, currentVersion, channel, git, getJ
461
532
  if (comparison > 0)
462
533
  return { ...result, current_sha: id.release().sourceRevision ?? null, behind: 0, no_git: true, install_kind: 'npm', manual_update: true, message: 'This npm installation is ahead of the selected Stable release.' };
463
534
  if (comparison < 0)
464
- return { ...result, current_sha: id.release().sourceRevision ?? null, behind: 1, no_git: true, install_kind: 'npm', npm: release.npm, manual_update: false, message: `Stable npm update ${release.version} is available.` };
535
+ return { ...result, current_sha: id.release().sourceRevision ?? null, behind: release.releasesBehind, no_git: true, install_kind: 'npm', npm: release.npm, manual_update: false, message: `Stable npm update ${release.version} is available.` };
465
536
  const installed = diskRelease(npmInstall.packageRoot);
466
537
  if (!same(installed, release.runtime))
467
538
  return { ...result, current_sha: id.release().sourceRevision ?? null, behind: null, no_git: true, install_kind: 'npm', manual_update: true, error: 'Installed npm release metadata does not match the completed release.' };
@@ -476,7 +547,7 @@ export async function checkWebUpdate(webRoot, currentVersion, channel, git, getJ
476
547
  const latest = release.version.split('.').map(Number);
477
548
  const cmp = installed.map((v, i) => Math.sign(v - (latest[i] ?? 0))).find((s) => s !== 0) ?? 0;
478
549
  if (cmp !== 0)
479
- behind = cmp < 0 ? 1 : 0;
550
+ behind = cmp < 0 ? release.releasesBehind : 0;
480
551
  }
481
552
  return { ...result, current_sha: current, behind, no_git: true, manual_update: true, message: 'Use the published Talaria Web image or authenticated monorepo installation; legacy checkouts require migration.' };
482
553
  }
@@ -709,6 +780,7 @@ export async function checkAgentUpdate(path, git, channel = DEFAULT_CHANNEL) {
709
780
  const message = fetched.out ? `fetch failed: ${sanitizeGitDiagnostic(fetched.out)}` : 'fetch failed';
710
781
  return { name: 'agent', channel, behind: null, error: message, stale_check: true, dirty: await isDirty(path, git) };
711
782
  }
783
+ await recoverInterruptedAutostash(path, git);
712
784
  try {
713
785
  return { ...await agentTarget(path, git, channel), dirty: await isDirty(path, git) };
714
786
  }
@@ -716,7 +788,7 @@ export async function checkAgentUpdate(path, git, channel = DEFAULT_CHANNEL) {
716
788
  return { name: 'agent', channel, behind: null, error: error.message };
717
789
  }
718
790
  }
719
- /** Fetch, confirm the immutable Agent target, stash, fast-forward, and pop. */
791
+ /** Fetch, confirm the immutable Agent target, stash, fast-forward, and restore the stash. */
720
792
  export async function applyAgentUpdate(path, git, channel = DEFAULT_CHANNEL, policy) {
721
793
  if (!path || !existsSync(join(path, '.git')))
722
794
  return { ok: false, message: 'Not a git repository' };
@@ -746,6 +818,7 @@ export async function applyAgentUpdate(path, git, channel = DEFAULT_CHANNEL, pol
746
818
  return warning;
747
819
  const ref = str(info.branch);
748
820
  const revision = str(info.latest_sha);
821
+ await recoverInterruptedAutostash(path, git);
749
822
  const status = await git(['status', '--porcelain', '--untracked-files=no'], path);
750
823
  if (!status.ok) {
751
824
  if (isGitLockError(status.out))
@@ -755,41 +828,101 @@ export async function applyAgentUpdate(path, git, channel = DEFAULT_CHANNEL, pol
755
828
  if (status.out.split('\n').some((line) => ['DD', 'AU', 'UD', 'UA', 'DU', 'AA', 'UU'].includes(line.slice(0, 2)))) {
756
829
  return { ok: false, message: `The local agent repo has unresolved merge conflicts. To reset to the latest remote version run: git -C ${path} checkout . && git -C ${path} pull --ff-only`, conflict: true };
757
830
  }
758
- let stashed = false;
831
+ let saved = null;
759
832
  if (status.out) {
760
- if (!(await git(['stash', 'push', '-m', 'hermes-update-autostash'], path)).ok)
761
- return { ok: false, message: 'Failed to stash local changes' };
762
- stashed = true;
833
+ const result = await saveLocalChanges(path, git);
834
+ if (typeof result === 'string')
835
+ return { ok: false, message: result };
836
+ saved = result;
763
837
  }
764
838
  // Merge the immutable commit that was checked/acknowledged, never re-fetch a moving ref here.
765
839
  const pulled = await git(['merge', '--ff-only', revision], path, 30_000);
766
840
  if (!pulled.ok) {
767
- let note = '';
768
- if (stashed)
769
- note = ` ${await restoreStash(path, git, pulled.out)}`;
841
+ const restored = saved ? await restoreLocalChanges(path, git, saved) : null;
842
+ const note = restored ? ` ${restored.note}` : '';
843
+ const conflict = restored && !restored.applied ? { stash_conflict: true } : {};
770
844
  if (isGitLockError(pulled.out))
771
- return { ok: false, message: `Pull failed due to a repository lock: ${pulled.out.trim()}.${note}`, lock_conflict: true };
772
- return { ok: false, message: `Pull failed: ${sanitizeGitDiagnostic(pulled.out)}.${note}` };
773
- }
774
- let message = `agent updated to ${ref}`;
775
- if (stashed) {
776
- const popped = await git(['stash', 'pop'], path);
777
- if (!popped.ok)
778
- message += '. Local changes remain in `git stash list`; resolve them manually.';
845
+ return { ok: false, message: `Pull failed due to a repository lock: ${pulled.out.trim()}.${note}`, lock_conflict: true, ...conflict };
846
+ return { ok: false, message: `Pull failed: ${sanitizeGitDiagnostic(pulled.out)}.${note}`, ...conflict };
779
847
  }
848
+ const restored = saved ? await restoreLocalChanges(path, git, saved) : null;
780
849
  const verified = await verifiedAgentIdentity(path, revision, git);
781
850
  if (!verified)
782
851
  return { ok: false, message: 'The Agent update completed, but the installed revision could not be verified.', target: 'agent' };
783
- return { ok: true, message, target: 'agent', ref, ...verified };
852
+ return { ok: true, message: `agent updated to ${ref}.${restored ? ` ${restored.note}` : ''}`, target: 'agent', ref, ...verified, ...(restored && !restored.applied ? { stash_conflict: true } : {}) };
784
853
  }
785
- async function restoreStash(path, git, pullOut) {
786
- if ((await git(['stash', 'pop'], path)).ok)
787
- return 'Local modifications were restored from the temporary stash.';
788
- if ((await git(['stash', 'apply'], path)).ok) {
789
- await git(['stash', 'drop'], path);
790
- return 'Local modifications were restored from the temporary stash.';
791
- }
792
- return `Your local modifications could not be restored automatically (stash pop failed after pull error: ${pullOut.trim().slice(0, 200) || 'no detail'}). They remain safely in \`git stash list\`; run \`git -C ${path} stash pop\` once the lock is cleared.`;
854
+ const AUTOSTASH_REFS = 'refs/talaria/autostash/';
855
+ /** An update holds its saved changes here only while it runs; one left behind marks an interrupted update. */
856
+ const PENDING_AUTOSTASH_REFS = `${AUTOSTASH_REFS}pending/`;
857
+ async function autostashPatch(path, git, sha) {
858
+ const dir = mkdtempSync(join(tmpdir(), 'talaria-autostash-'));
859
+ const saved = { sha, ref: `${PENDING_AUTOSTASH_REFS}${sha}`, dir, patch: join(dir, 'autostash.patch') };
860
+ if ((await git(['diff', '--binary', `--output=${saved.patch}`, `${sha}^1`, sha], path)).ok)
861
+ return saved;
862
+ rmSync(dir, { recursive: true, force: true });
863
+ return null;
864
+ }
865
+ /**
866
+ * Save tracked local changes as a stash commit under a private per-commit ref, never the shared stash reflog
867
+ * whose entries other processes can shift, then revert exactly those changes. `git apply` writes the whole patch
868
+ * or nothing, so an edit made meanwhile aborts the update instead of being lost. Returns an error message on failure.
869
+ */
870
+ async function saveLocalChanges(path, git) {
871
+ const created = await git(['stash', 'create', 'hermes-update-autostash'], path);
872
+ if (!created.ok || !SHA.test(created.out))
873
+ return 'Failed to stash local changes';
874
+ const sha = created.out;
875
+ if (!(await git(['update-ref', `${PENDING_AUTOSTASH_REFS}${sha}`, sha], path)).ok)
876
+ return 'Failed to stash local changes';
877
+ const saved = await autostashPatch(path, git, sha);
878
+ if (!saved || (lstatSync(saved.patch).size > 0 && !(await git(['apply', '-R', '--whitespace=nowarn', saved.patch], path)).ok)) {
879
+ if (saved)
880
+ rmSync(saved.dir, { recursive: true, force: true });
881
+ await git(['update-ref', '-d', `${PENDING_AUTOSTASH_REFS}${sha}`, sha], path);
882
+ return 'Local changes in the Agent checkout changed while the update was saving them, so nothing was modified. Try the update again.';
883
+ }
884
+ // Only the index returns to HEAD; the working tree is untouched and staged content stays in the saved commit.
885
+ await git(['reset', '-q'], path);
886
+ return saved;
887
+ }
888
+ /** Re-apply the saved changes atomically; on a conflict keep the commit under its own ref and leave the files as the update wrote them. */
889
+ async function restoreLocalChanges(path, git, saved) {
890
+ try {
891
+ if (lstatSync(saved.patch).size === 0 || (await git(['apply', '--whitespace=nowarn', saved.patch], path)).ok) {
892
+ await git(['update-ref', '-d', saved.ref, saved.sha], path);
893
+ return { applied: true, note: 'Local modifications were restored.' };
894
+ }
895
+ }
896
+ finally {
897
+ rmSync(saved.dir, { recursive: true, force: true });
898
+ }
899
+ const short = saved.sha.slice(0, 12);
900
+ // The kept ref owns the commit; the stash list entry is only a convenience others may drop.
901
+ const keptRef = `${AUTOSTASH_REFS}${saved.sha}`;
902
+ const kept = (await git(['update-ref', keptRef, saved.sha], path)).ok;
903
+ if (kept)
904
+ await git(['update-ref', '-d', saved.ref, saved.sha], path);
905
+ const ref = kept ? keptRef : saved.ref;
906
+ const listed = kept && (await git(['stash', 'store', '-m', 'hermes-update-autostash', saved.sha], path)).ok;
907
+ return { applied: false, note: `Your local modifications could not be re-applied cleanly and were saved as ${short} under ${ref}${listed ? ' and in the git stash' : ''}; Agent files were left as the update wrote them. To inspect: git -C ${path} stash show -p ${short}. To re-apply: git -C ${path} stash apply ${short}, then resolve conflicts. Once you are satisfied, run git -C ${path} update-ref -d ${ref}${listed ? ' and drop that stash entry' : ''}.` };
908
+ }
909
+ /** Finish an update the server stopped mid-way: its saved changes return to the tree, or are kept and listed in the git stash if they no longer apply. */
910
+ async function recoverInterruptedAutostash(path, git) {
911
+ const refs = await git(['for-each-ref', '--format=%(objectname)', PENDING_AUTOSTASH_REFS], path);
912
+ if (!refs.ok)
913
+ return;
914
+ for (const sha of refs.out.split('\n').filter((line) => SHA.test(line))) {
915
+ const saved = await autostashPatch(path, git, sha);
916
+ if (!saved)
917
+ continue;
918
+ // Stopped before the revert or after the restore: the changes are already in the tree.
919
+ if (lstatSync(saved.patch).size === 0 || (await git(['apply', '-R', '--check', saved.patch], path)).ok) {
920
+ rmSync(saved.dir, { recursive: true, force: true });
921
+ await git(['update-ref', '-d', saved.ref, sha], path);
922
+ }
923
+ else
924
+ await restoreLocalChanges(path, git, saved);
925
+ }
793
926
  }
794
927
  /** Python `apply_force_update` (agent branch): fetch, refuse a pure-ancestor rewind, `checkout . && clean -fd && reset --hard`. */
795
928
  export async function forceAgentUpdate(path, git, log, channel = DEFAULT_CHANNEL, policy) {
@@ -1014,8 +1147,8 @@ export class UpdateService {
1014
1147
  }
1015
1148
  if (cached.include_agent !== includeAgent) {
1016
1149
  cached.include_agent = includeAgent;
1017
- if (!includeAgent)
1018
- cached.agent = ignoredAgent();
1150
+ // A cached result from the other mode never answers this one: re-enabled Agent checks wait for the next check.
1151
+ cached.agent = includeAgent ? null : ignoredAgent();
1019
1152
  }
1020
1153
  cached.cached = true;
1021
1154
  return cached;
@@ -1343,6 +1476,39 @@ export class UpdateService {
1343
1476
  }
1344
1477
  }
1345
1478
  const ignoredAgent = () => ({ name: 'agent', behind: 0, ignored: true });
1479
+ /** TAL-559: one target's status and apply availability, decided here so clients only word them. */
1480
+ export function updateTargetView(name, info, off) {
1481
+ const behind = typeof info.behind === 'number' ? info.behind : null;
1482
+ // Web refuses dirty checkouts; Agent updates stash local changes and restore them, so only Web dirt blocks.
1483
+ const state = off || info.ignored === true ? 'off'
1484
+ : info.error ? 'check_failed'
1485
+ : info.dirty === true && name === 'webui' ? 'local_changes'
1486
+ : info.metadata_repair === true ? 'finish'
1487
+ : info.manual_update === true ? 'manual'
1488
+ : behind !== null && behind > 0 ? (info.release_based === true ? 'release_ready' : 'commits_behind')
1489
+ : behind === 0 ? 'up_to_date'
1490
+ : info.no_git === true && info.install_kind !== 'npm' ? 'manual'
1491
+ : 'unknown';
1492
+ const latest = typeof info.latest_version === 'string' ? info.latest_version : null;
1493
+ const current = typeof info.current_version === 'string' ? info.current_version : '';
1494
+ return {
1495
+ ...info, state,
1496
+ can_apply: ['release_ready', 'commits_behind', 'finish'].includes(state) && info.manual_update !== true && (info.no_git !== true || info.install_kind === 'npm'),
1497
+ // Stable Agent reports a bare 12-hex revision when its checkout sits on no release tag.
1498
+ installed_unverified: state === 'release_ready' && (!current || /^[0-9a-f]{12}$/.test(current)),
1499
+ manual_link: name === 'webui' && state !== 'off' && info.manual_update === true && Boolean(info.error || info.dirty || info.behind !== 0),
1500
+ target_version: state === 'finish' || state === 'release_ready' || (state === 'manual' && info.release_based === true && (behind ?? 0) > 0) ? latest : null,
1501
+ };
1502
+ }
1503
+ /** `/api/updates/check`: every present target carries its view; disabled checks report both targets off. */
1504
+ export function updatesCheckView(status) {
1505
+ const off = status.disabled === true;
1506
+ const view = (name) => {
1507
+ const info = status[name];
1508
+ return info && typeof info === 'object' ? updateTargetView(name, info, off) : off ? updateTargetView(name, {}, true) : null;
1509
+ };
1510
+ return { ...status, webui: view('webui'), agent: view('agent') };
1511
+ }
1346
1512
  /** Python `_wait_until_restart_safe`: poll until no chat work is active, bounded so a stuck run cannot jam the update forever. */
1347
1513
  export async function waitUntilRestartSafe(blockers, opts = {}) {
1348
1514
  const now = opts.now ?? (() => Date.now());