@maudecode/talaria-web 1.20.0 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/_release.json +8 -8
  2. package/dist/api/automation-router.d.ts +319 -14
  3. package/dist/api/automation-router.js +21 -1
  4. package/dist/api/automation-router.js.map +1 -1
  5. package/dist/api/chat-router.d.ts +615 -69
  6. package/dist/api/chat-router.js +22 -170
  7. package/dist/api/chat-router.js.map +1 -1
  8. package/dist/api/git-router.d.ts +50 -0
  9. package/dist/api/git-router.js +17 -4
  10. package/dist/api/git-router.js.map +1 -1
  11. package/dist/api/groups-router.d.ts +764 -0
  12. package/dist/api/groups-router.js +79 -0
  13. package/dist/api/groups-router.js.map +1 -0
  14. package/dist/api/raw-routes.js +3 -1
  15. package/dist/api/raw-routes.js.map +1 -1
  16. package/dist/api/router.d.ts +1 -1
  17. package/dist/api/sessions-router.d.ts +1675 -167
  18. package/dist/api/sessions-router.js +67 -53
  19. package/dist/api/sessions-router.js.map +1 -1
  20. package/dist/api/settings-router.d.ts +911 -1
  21. package/dist/api/settings-router.js +53 -2
  22. package/dist/api/settings-router.js.map +1 -1
  23. package/dist/api/sse-routes.d.ts +1 -1
  24. package/dist/api/sse-routes.js +15 -5
  25. package/dist/api/sse-routes.js.map +1 -1
  26. package/dist/api/tools-raw.js +27 -136
  27. package/dist/api/tools-raw.js.map +1 -1
  28. package/dist/api/tools-router.d.ts +588 -51
  29. package/dist/api/tools-router.js +98 -16
  30. package/dist/api/tools-router.js.map +1 -1
  31. package/dist/app.js +5 -1
  32. package/dist/app.js.map +1 -1
  33. package/dist/auth/gate.js +5 -1
  34. package/dist/auth/gate.js.map +1 -1
  35. package/dist/config/agent-config.d.ts +6 -1
  36. package/dist/config/agent-config.js +75 -3
  37. package/dist/config/agent-config.js.map +1 -1
  38. package/dist/feedback.d.ts +18 -0
  39. package/dist/feedback.js +145 -0
  40. package/dist/feedback.js.map +1 -0
  41. package/dist/fs/stat.d.ts +2 -0
  42. package/dist/fs/stat.js +4 -0
  43. package/dist/fs/stat.js.map +1 -1
  44. package/dist/http/context.d.ts +9 -0
  45. package/dist/http/context.js +0 -6
  46. package/dist/http/context.js.map +1 -1
  47. package/dist/http/pinned.js +19 -8
  48. package/dist/http/pinned.js.map +1 -1
  49. package/dist/providers/catalog.d.ts +9 -1
  50. package/dist/providers/catalog.js +86 -6
  51. package/dist/providers/catalog.js.map +1 -1
  52. package/dist/redact.d.ts +2 -0
  53. package/dist/redact.js +26 -5
  54. package/dist/redact.js.map +1 -1
  55. package/dist/runtime.js +62 -11
  56. package/dist/runtime.js.map +1 -1
  57. package/dist/server.js +2 -0
  58. package/dist/server.js.map +1 -1
  59. package/dist/sessions/admission.d.ts +21 -0
  60. package/dist/sessions/admission.js +176 -0
  61. package/dist/sessions/admission.js.map +1 -0
  62. package/dist/sessions/anchor.d.ts +5 -2
  63. package/dist/sessions/anchor.js +14 -13
  64. package/dist/sessions/anchor.js.map +1 -1
  65. package/dist/sessions/background-tasks.d.ts +19 -1
  66. package/dist/sessions/background-tasks.js +36 -6
  67. package/dist/sessions/background-tasks.js.map +1 -1
  68. package/dist/sessions/cli-sessions.js +11 -6
  69. package/dist/sessions/cli-sessions.js.map +1 -1
  70. package/dist/sessions/compress.d.ts +10 -9
  71. package/dist/sessions/compress.js +31 -20
  72. package/dist/sessions/compress.js.map +1 -1
  73. package/dist/sessions/events.d.ts +3 -0
  74. package/dist/sessions/events.js +4 -0
  75. package/dist/sessions/events.js.map +1 -1
  76. package/dist/sessions/gateway-sessions.d.ts +61 -2
  77. package/dist/sessions/gateway-sessions.js +223 -35
  78. package/dist/sessions/gateway-sessions.js.map +1 -1
  79. package/dist/sessions/gateway-watcher.js +8 -4
  80. package/dist/sessions/gateway-watcher.js.map +1 -1
  81. package/dist/sessions/groups.d.ts +60 -0
  82. package/dist/sessions/groups.js +339 -0
  83. package/dist/sessions/groups.js.map +1 -0
  84. package/dist/sessions/list.d.ts +7 -2
  85. package/dist/sessions/list.js +13 -4
  86. package/dist/sessions/list.js.map +1 -1
  87. package/dist/sessions/merge.d.ts +15 -5
  88. package/dist/sessions/merge.js +49 -15
  89. package/dist/sessions/merge.js.map +1 -1
  90. package/dist/sessions/pending.d.ts +1 -1
  91. package/dist/sessions/pending.js +15 -6
  92. package/dist/sessions/pending.js.map +1 -1
  93. package/dist/sessions/prefix-index.d.ts +9 -14
  94. package/dist/sessions/prefix-index.js +14 -52
  95. package/dist/sessions/prefix-index.js.map +1 -1
  96. package/dist/sessions/prompt-queues.d.ts +36 -0
  97. package/dist/sessions/prompt-queues.js +318 -0
  98. package/dist/sessions/prompt-queues.js.map +1 -0
  99. package/dist/sessions/reasoning-display.d.ts +2 -0
  100. package/dist/sessions/reasoning-display.js +31 -0
  101. package/dist/sessions/reasoning-display.js.map +1 -0
  102. package/dist/sessions/relay.d.ts +16 -2
  103. package/dist/sessions/relay.js +119 -24
  104. package/dist/sessions/relay.js.map +1 -1
  105. package/dist/sessions/service.d.ts +33 -3
  106. package/dist/sessions/service.js +304 -70
  107. package/dist/sessions/service.js.map +1 -1
  108. package/dist/sessions/session.d.ts +6 -0
  109. package/dist/sessions/session.js +14 -0
  110. package/dist/sessions/session.js.map +1 -1
  111. package/dist/sessions/shares.d.ts +1 -1
  112. package/dist/sessions/shares.js +13 -4
  113. package/dist/sessions/shares.js.map +1 -1
  114. package/dist/sessions/state-db.d.ts +2 -1
  115. package/dist/sessions/state-db.js +7 -3
  116. package/dist/sessions/state-db.js.map +1 -1
  117. package/dist/sessions/storage/json-documents.js +3 -0
  118. package/dist/sessions/storage/json-documents.js.map +1 -1
  119. package/dist/sessions/store.d.ts +2 -0
  120. package/dist/sessions/store.js +11 -3
  121. package/dist/sessions/store.js.map +1 -1
  122. package/dist/sessions/streams.d.ts +4 -0
  123. package/dist/sessions/streams.js +12 -0
  124. package/dist/sessions/streams.js.map +1 -1
  125. package/dist/sessions/todo.js +10 -1
  126. package/dist/sessions/todo.js.map +1 -1
  127. package/dist/sessions/tool-display.d.ts +8 -1
  128. package/dist/sessions/tool-display.js +39 -4
  129. package/dist/sessions/tool-display.js.map +1 -1
  130. package/dist/sessions/turn.d.ts +4 -1
  131. package/dist/sessions/turn.js +53 -22
  132. package/dist/sessions/turn.js.map +1 -1
  133. package/dist/settings.js +2 -1
  134. package/dist/settings.js.map +1 -1
  135. package/dist/spa.js +1 -1
  136. package/dist/spa.js.map +1 -1
  137. package/dist/test/group-fixture.d.ts +66 -0
  138. package/dist/test/group-fixture.js +89 -0
  139. package/dist/test/group-fixture.js.map +1 -0
  140. package/dist/test/harness.d.ts +3 -0
  141. package/dist/test/harness.js +3 -0
  142. package/dist/test/harness.js.map +1 -1
  143. package/dist/tools/connectors.d.ts +9 -1
  144. package/dist/tools/connectors.js +48 -0
  145. package/dist/tools/connectors.js.map +1 -1
  146. package/dist/tools/kanban.d.ts +10 -1
  147. package/dist/tools/kanban.js +73 -1
  148. package/dist/tools/kanban.js.map +1 -1
  149. package/dist/tools/mcp.d.ts +3 -1
  150. package/dist/tools/mcp.js +73 -0
  151. package/dist/tools/mcp.js.map +1 -1
  152. package/dist/tools/memory.d.ts +28 -0
  153. package/dist/tools/memory.js +120 -14
  154. package/dist/tools/memory.js.map +1 -1
  155. package/dist/tools/skills.d.ts +6 -0
  156. package/dist/tools/skills.js +17 -0
  157. package/dist/tools/skills.js.map +1 -1
  158. package/dist/tools/update-notifications.d.ts +12 -10
  159. package/dist/tools/update-notifications.js +124 -14
  160. package/dist/tools/update-notifications.js.map +1 -1
  161. package/dist/tools/updates.d.ts +38 -12
  162. package/dist/tools/updates.js +180 -44
  163. package/dist/tools/updates.js.map +1 -1
  164. package/dist/workspace/fs.d.ts +2 -0
  165. package/dist/workspace/fs.js +63 -1
  166. package/dist/workspace/fs.js.map +1 -1
  167. package/dist/workspace/managed-buffers.d.ts +58 -0
  168. package/dist/workspace/managed-buffers.js +76 -0
  169. package/dist/workspace/managed-buffers.js.map +1 -0
  170. package/dist/workspace/rollback.js +1 -1
  171. package/dist/workspace/rollback.js.map +1 -1
  172. package/dist/workspace/upload.d.ts +1 -1
  173. package/dist/workspace/upload.js +52 -37
  174. package/dist/workspace/upload.js.map +1 -1
  175. package/dist/workspace/workspaces.d.ts +5 -1
  176. package/dist/workspace/workspaces.js +32 -6
  177. package/dist/workspace/workspaces.js.map +1 -1
  178. package/package.json +2 -2
  179. package/sidecar/agent_dependency.json +4 -4
  180. package/sidecar/agent_importer.json +8 -0
  181. package/sidecar/agent_support.json +20 -8
  182. package/sidecar/scripts/agent_importer_contract.py +19 -0
  183. package/sidecar/scripts/test.sh +3 -1
  184. package/sidecar/talaria_sidecar/__init__.py +1 -1
  185. package/sidecar/talaria_sidecar/agent_mutation.py +87 -9
  186. package/sidecar/talaria_sidecar/agent_services.py +83 -23
  187. package/sidecar/talaria_sidecar/home.py +12 -5
  188. package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
  189. package/sidecar/talaria_sidecar/methods/agent_imports.py +346 -0
  190. package/sidecar/talaria_sidecar/methods/chat.py +141 -58
  191. package/sidecar/talaria_sidecar/methods/commands.py +6 -4
  192. package/sidecar/talaria_sidecar/methods/config.py +8 -3
  193. package/sidecar/talaria_sidecar/methods/connectors.py +138 -4
  194. package/sidecar/talaria_sidecar/methods/dashboard_plugins.py +25 -4
  195. package/sidecar/talaria_sidecar/methods/delegation.py +126 -0
  196. package/sidecar/talaria_sidecar/methods/gateway.py +5 -0
  197. package/sidecar/talaria_sidecar/methods/gateway_sessions.py +142 -23
  198. package/sidecar/talaria_sidecar/methods/groups.py +120 -0
  199. package/sidecar/talaria_sidecar/methods/kanban.py +48 -0
  200. package/sidecar/talaria_sidecar/methods/managed_buffers.py +110 -0
  201. package/sidecar/talaria_sidecar/methods/mcp.py +55 -0
  202. package/sidecar/talaria_sidecar/methods/memory.py +27 -3
  203. package/sidecar/talaria_sidecar/methods/nous_account.py +130 -0
  204. package/sidecar/talaria_sidecar/methods/oauth.py +25 -4
  205. package/sidecar/talaria_sidecar/methods/outbound_drafts.py +147 -0
  206. package/sidecar/talaria_sidecar/methods/plugin_catalog.py +73 -2
  207. package/sidecar/talaria_sidecar/methods/providers.py +51 -1
  208. package/sidecar/talaria_sidecar/methods/skill_revisions.py +177 -0
  209. package/sidecar/talaria_sidecar/methods/skills.py +10 -0
  210. package/sidecar/talaria_sidecar/methods/tts.py +67 -0
  211. package/sidecar/talaria_sidecar/rpc.py +11 -2
  212. package/static/dist/FILES.txt +155 -144
  213. package/static/dist/THIRD_PARTY_LICENSES.md +1 -1
  214. package/static/dist/assets/AppShell-hvysbd9x.js +8 -0
  215. package/static/dist/assets/Button-dlsibkzq.js +1 -0
  216. package/static/dist/assets/ChatPage-jikwrwfd.js +2 -0
  217. package/static/dist/assets/Composer-mnke8ss2.js +5 -0
  218. package/static/dist/assets/ConnectTargets-ejplzo4q.js +1 -0
  219. package/static/dist/assets/Dialog-rksfyyq5.js +1 -0
  220. package/static/dist/assets/{ExtensionRoute-zrhjn0wm.js → ExtensionRoute-igk5h0rj.js} +1 -1
  221. package/static/dist/assets/HubRoute-eooassx4.js +2 -0
  222. package/static/dist/assets/Markdown-m5pzgvtx.js +2 -0
  223. package/static/dist/assets/{MarkdownRenderer-fbswsgld.js → MarkdownRenderer-74ysuomr.js} +18 -18
  224. package/static/dist/assets/OAuthSignIn-i4flsuq2.js +1 -0
  225. package/static/dist/assets/QueueCard-msz9wd1m.js +1 -0
  226. package/static/dist/assets/ResourceSwitch-b70zg4xd.js +1 -0
  227. package/static/dist/assets/RightPanel-f5v61m8j.js +1 -0
  228. package/static/dist/assets/Select-f3l897pt.js +1 -0
  229. package/static/dist/assets/SessionListPanel-brnzacw9.js +1 -0
  230. package/static/dist/assets/SettingsLayout-f4akmrt2.js +1 -0
  231. package/static/dist/assets/States-msohx3c0.js +1 -0
  232. package/static/dist/assets/TerminalPanel-bnu5xawo.js +16 -0
  233. package/static/dist/assets/Toaster-d6col3ch.js +1 -0
  234. package/static/dist/assets/_app-lrjgufcy.js +1 -0
  235. package/static/dist/assets/{_app.ext._extensionId-na62087t.js → _app.ext._extensionId-k3xitxr1.js} +1 -1
  236. package/static/dist/assets/_app.groups-bt4wdwnd.js +1 -0
  237. package/static/dist/assets/{_app.index-jypgdqoi.js → _app.index-n3otiki0.js} +1 -1
  238. package/static/dist/assets/{_app.insights-kabejdtm.js → _app.insights-b0mzlh6m.js} +1 -1
  239. package/static/dist/assets/{_app.kanban-m19kfcmx.js → _app.kanban-d923g7j5.js} +1 -1
  240. package/static/dist/assets/{_app.logs-iw4m96sz.js → _app.logs-donegue1.js} +1 -1
  241. package/static/dist/assets/{_app.memory-jq5frwcg.js → _app.memory-hdnled08.js} +1 -1
  242. package/static/dist/assets/{_app.profiles-kwa3m7rp.js → _app.profiles-fumot3jk.js} +1 -1
  243. package/static/dist/assets/{_app.session._sessionId-o5lyeipj.js → _app.session._sessionId-crmdl2ux.js} +1 -1
  244. package/static/dist/assets/{_app.settings-ckl8hdll.js → _app.settings-jui8iesz.js} +1 -1
  245. package/static/dist/assets/_app.settings._section-do84hsqw.js +3 -0
  246. package/static/dist/assets/{_app.skills-n016rihd.js → _app.skills-heqcn21m.js} +1 -1
  247. package/static/dist/assets/_app.tasks-jiudtutt.js +1 -0
  248. package/static/dist/assets/{_app.todos-btew5v2s.js → _app.todos-bl6kk2zq.js} +1 -1
  249. package/static/dist/assets/{_app.workspaces-lnfk95ch.js → _app.workspaces-frvh3o7w.js} +1 -1
  250. package/static/dist/assets/_delete-qnxuo87s.js +1 -0
  251. package/static/dist/assets/{abnfDiagram-VCTEODGH-dttheegb.js → abnfDiagram-VCTEODGH-dppg3yfx.js} +1 -1
  252. package/static/dist/assets/{architecture-7GRP2DOG-ic435919.js → architecture-7GRP2DOG-gbajejh3.js} +1 -1
  253. package/static/dist/assets/{architectureDiagram-5GKGNRK7-8r3glgiq.js → architectureDiagram-5GKGNRK7-bzrxyais.js} +1 -1
  254. package/static/dist/assets/archive-yhdyz231.js +1 -0
  255. package/static/dist/assets/autoReadClaim-nlyv8tu9.js +1 -0
  256. package/static/dist/assets/{blockDiagram-I7D4REHJ-jenyos6c.js → blockDiagram-I7D4REHJ-gmk9koab.js} +1 -1
  257. package/static/dist/assets/{c4Diagram-7LVT6UL2-nzlx7yc4.js → c4Diagram-7LVT6UL2-bfqiqqcz.js} +1 -1
  258. package/static/dist/assets/channel-grt3rob4.js +1 -0
  259. package/static/dist/assets/{chunk-4HAMMTFA-g0cru63b.js → chunk-4HAMMTFA-i9s6h4wv.js} +1 -1
  260. package/static/dist/assets/{chunk-75Z2AOVW-7rkswkjw.js → chunk-75Z2AOVW-gnt6pnso.js} +1 -1
  261. package/static/dist/assets/{chunk-DU6HZSFF-fn73jzdo.js → chunk-DU6HZSFF-gq439wot.js} +3 -3
  262. package/static/dist/assets/{chunk-F27PBJKO-oey8e72m.js → chunk-F27PBJKO-wvx90pbt.js} +1 -1
  263. package/static/dist/assets/{chunk-GMAD6QVW-l2a32wiy.js → chunk-GMAD6QVW-mc2gu30k.js} +1 -1
  264. package/static/dist/assets/{chunk-GVQU2GXP-o9dwzh8h.js → chunk-GVQU2GXP-f8fxa2ym.js} +1 -1
  265. package/static/dist/assets/{chunk-IMKFNOWR-eblwj20b.js → chunk-IMKFNOWR-lnsl31hj.js} +1 -1
  266. package/static/dist/assets/{chunk-L3NEJ4N5-o2mufspb.js → chunk-L3NEJ4N5-kbfdidwu.js} +1 -1
  267. package/static/dist/assets/{chunk-OSK3NFVY-ijp9pw29.js → chunk-OSK3NFVY-dvxsduj6.js} +1 -1
  268. package/static/dist/assets/{chunk-P2QGCYS3-hs9hqwl4.js → chunk-P2QGCYS3-ivo3i1wf.js} +1 -1
  269. package/static/dist/assets/{chunk-POPQ4Y6H-bp9rsqez.js → chunk-POPQ4Y6H-i0gfu0hx.js} +1 -1
  270. package/static/dist/assets/{chunk-PWAF6VOD-brkprov6.js → chunk-PWAF6VOD-jb0fdyb0.js} +1 -1
  271. package/static/dist/assets/{chunk-SHT3W25Y-gmpv0pxz.js → chunk-SHT3W25Y-b7ou2xsp.js} +1 -1
  272. package/static/dist/assets/{chunk-SVP7TREG-oldm08fu.js → chunk-SVP7TREG-e2v7me5v.js} +1 -1
  273. package/static/dist/assets/{chunk-TICWLB2K-ooqilfv7.js → chunk-TICWLB2K-e5zlai62.js} +1 -1
  274. package/static/dist/assets/classDiagram-ZZMXUADV-nnsp49jr.js +1 -0
  275. package/static/dist/assets/classDiagram-v2-VYDZK3BY-nnsp49jr.js +1 -0
  276. package/static/dist/assets/completionAudio-c5at041z.js +1 -0
  277. package/static/dist/assets/{copy-jo006coq.js → copy-jj3oiw13.js} +1 -1
  278. package/static/dist/assets/{cynefin-OW5HDTMX-d47op7qs.js → cynefin-OW5HDTMX-n5n1ck70.js} +1 -1
  279. package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-doa7594y.js → cynefinDiagram-5FMLGOSQ-b33npu4f.js} +1 -1
  280. package/static/dist/assets/{dagre-GXQ25YYZ-os768dp4.js → dagre-GXQ25YYZ-miwvae07.js} +1 -1
  281. package/static/dist/assets/{diagram-S7CK7UJ4-fyi81nxd.js → diagram-S7CK7UJ4-j8fphsp4.js} +1 -1
  282. package/static/dist/assets/{diagram-UQ7AKVKN-j3exggaq.js → diagram-UQ7AKVKN-5cixo166.js} +1 -1
  283. package/static/dist/assets/{diagram-VSXAHHWV-omo1en2l.js → diagram-VSXAHHWV-ii3bf92m.js} +1 -1
  284. package/static/dist/assets/{diagram-VX7I27RA-oro2cyu0.js → diagram-VX7I27RA-b3cfgx81.js} +1 -1
  285. package/static/dist/assets/{diagram-Z3DM3KII-byt9vdb7.js → diagram-Z3DM3KII-bey9lqr8.js} +1 -1
  286. package/static/dist/assets/{dist-etpoyscq.js → dist-cb8um5dh.js} +4 -4
  287. package/static/dist/assets/{dist-crc46di9.js → dist-kpg5ccm9.js} +1 -1
  288. package/static/dist/assets/{ebnfDiagram-PWID7BFC-ee3haugh.js → ebnfDiagram-PWID7BFC-2m4wrnqc.js} +1 -1
  289. package/static/dist/assets/{erDiagram-RLTQ6QDP-d1e93yff.js → erDiagram-RLTQ6QDP-kak5te0n.js} +1 -1
  290. package/static/dist/assets/{eventmodeling-NTZA5JFV-i1ihb40c.js → eventmodeling-NTZA5JFV-ojcc486t.js} +1 -1
  291. package/static/dist/assets/flowDiagram-HODETNUW-kxr9sicu.js +1 -0
  292. package/static/dist/assets/folder-plus-fk6j7tlv.js +1 -0
  293. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-m7g0jud4.js → ganttDiagram-EL5Y4UJY-k6nfmhrh.js} +1 -1
  294. package/static/dist/assets/getPseudoElementBounds-mwj3vqni.js +1 -0
  295. package/static/dist/assets/{gitGraph-4MIJSDKK-hzdj07yy.js → gitGraph-4MIJSDKK-bxq1lbhy.js} +1 -1
  296. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-dm9agbna.js → gitGraphDiagram-WWUBYQGX-ehvoankt.js} +1 -1
  297. package/static/dist/assets/group_discussions-fk5hry4l.js +1 -0
  298. package/static/dist/assets/{highlighted-body-KPVGNVTW-mmgz2czu.js → highlighted-body-KPVGNVTW-nr4nfdq7.js} +1 -1
  299. package/static/dist/assets/{host-fr6lni1p.js → host-dhgqiozp.js} +1 -1
  300. package/static/dist/assets/index-hx7z4wdj.js +13 -0
  301. package/static/dist/assets/index-o8ebuc5x.css +2 -0
  302. package/static/dist/assets/{info-A6RAGUB7-lll1dqmm.js → info-A6RAGUB7-dtsj0ybw.js} +1 -1
  303. package/static/dist/assets/{infoDiagram-27XIBGKW-k7esc639.js → infoDiagram-27XIBGKW-jena90ao.js} +1 -1
  304. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-lgr6k9wo.js → ishikawaDiagram-5VMMS53U-kia6bn5u.js} +1 -1
  305. package/static/dist/assets/{journeyDiagram-3NMN7TZE-ndmbxuqk.js → journeyDiagram-3NMN7TZE-ipsa6icb.js} +1 -1
  306. package/static/dist/assets/{kanban-definition-UXKFOSKX-mjxym0jp.js → kanban-definition-UXKFOSKX-moxx59kp.js} +1 -1
  307. package/static/dist/assets/katex-ic33v820.js +257 -0
  308. package/static/dist/assets/katex-qcv7xo0t.css +1 -0
  309. package/static/dist/assets/{lazyRouteComponent-cwb6l7xh.js → lazyRouteComponent-i74ujrfk.js} +1 -1
  310. package/static/dist/assets/{line-mtr5k6il.js → line-lgrkg9no.js} +1 -1
  311. package/static/dist/assets/link-2-fp49mwl2.js +1 -0
  312. package/static/dist/assets/{link-iadw4ghw.js → link-es18mse1.js} +2 -2
  313. package/static/dist/assets/{locale-cs-n41hptse.js → locale-cs-brltdkcp.js} +1 -1
  314. package/static/dist/assets/{locale-de-k7ht47ew.js → locale-de-h6e9oq6v.js} +1 -1
  315. package/static/dist/assets/{locale-es-ih078lco.js → locale-es-oklmh80f.js} +1 -1
  316. package/static/dist/assets/{locale-fr-ojabnf41.js → locale-fr-b17ozoi2.js} +1 -1
  317. package/static/dist/assets/{locale-it-kb96jufy.js → locale-it-whe01eef.js} +1 -1
  318. package/static/dist/assets/{locale-ja-jpsp3xs1.js → locale-ja-g1s0rtpc.js} +1 -1
  319. package/static/dist/assets/{locale-pl-dbap4leu.js → locale-pl-d9p3lqcb.js} +1 -1
  320. package/static/dist/assets/{locale-pt-nci7w72x.js → locale-pt-l75on74f.js} +1 -1
  321. package/static/dist/assets/{locale-ru-soghe4cs.js → locale-ru-wl3mbsaw.js} +1 -1
  322. package/static/dist/assets/{locale-tr-ks00mu68.js → locale-tr-cz87itrq.js} +1 -1
  323. package/static/dist/assets/{locale-vi-ij7twfm6.js → locale-vi-elqj1y4k.js} +1 -1
  324. package/static/dist/assets/{locale-zh-Hant-feakwr7a.js → locale-zh-Hant-hf8gqm7d.js} +1 -1
  325. package/static/dist/assets/{locale-zh-ren0vjyv.js → locale-zh-cdckwb0u.js} +1 -1
  326. package/static/dist/assets/login-o6gfl4gy.js +1 -0
  327. package/static/dist/assets/mermaid-HWGCJPDP-n2kbzsao.js +1 -0
  328. package/static/dist/assets/{mermaid-parser.core-k91vdnvi.js → mermaid-parser.core-fflovwf2.js} +3 -3
  329. package/static/dist/assets/{mindmap-definition-YA3MSWOX-ehztfea4.js → mindmap-definition-YA3MSWOX-ic8l9whi.js} +1 -1
  330. package/static/dist/assets/onboarding-bxm7gdrr.js +1 -0
  331. package/static/dist/assets/{packet-AYTQ26CC-ok2xrblz.js → packet-AYTQ26CC-ntci3088.js} +1 -1
  332. package/static/dist/assets/{pegDiagram-XKGWAZYB-ec3rpj0m.js → pegDiagram-XKGWAZYB-e3btz04w.js} +1 -1
  333. package/static/dist/assets/{pie-WAS4IAKB-iwkir23u.js → pie-WAS4IAKB-o2dc7l36.js} +1 -1
  334. package/static/dist/assets/{pieDiagram-E7YTZNPT-fcpqpekh.js → pieDiagram-E7YTZNPT-gro55rrw.js} +1 -1
  335. package/static/dist/assets/presence-lq6m12ga.js +1 -0
  336. package/static/dist/assets/prompt_queue_cancelled-cebcuagu.js +1 -0
  337. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-lqsync43.js → quadrantDiagram-AXDQQJYC-fxulmd7d.js} +1 -1
  338. package/static/dist/assets/queryKeys-cnvn6pea.js +9 -0
  339. package/static/dist/assets/{radar-RG4KPBEZ-hje4jbk6.js → radar-RG4KPBEZ-9pcospra.js} +1 -1
  340. package/static/dist/assets/{railroad-74A4TZTK-gll9n6qi.js → railroad-74A4TZTK-nzdga12j.js} +1 -1
  341. package/static/dist/assets/{railroad-abnf-HS5TGJTU-o6h6lpn4.js → railroad-abnf-HS5TGJTU-ep3ytel0.js} +1 -1
  342. package/static/dist/assets/{railroad-ebnf-LZEXJU2U-juaefj6o.js → railroad-ebnf-LZEXJU2U-iw7uc1wy.js} +1 -1
  343. package/static/dist/assets/{railroad-peg-WCYAUIDC-cgfhvpah.js → railroad-peg-WCYAUIDC-fo3b3gme.js} +1 -1
  344. package/static/dist/assets/{railroadDiagram-O6MQD6OU-lp3w7awf.js → railroadDiagram-O6MQD6OU-lxpxf8f0.js} +1 -1
  345. package/static/dist/assets/{refresh-cw-iccm7a4e.js → refresh-cw-d14h79x5.js} +1 -1
  346. package/static/dist/assets/rename-ccd52yws.js +1 -0
  347. package/static/dist/assets/{requirementDiagram-BXWQKSXE-ha8eibcf.js → requirementDiagram-BXWQKSXE-lrozucd2.js} +1 -1
  348. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-oxf31pr9.js → sankeyDiagram-P5KCCOFB-iusxy9mq.js} +1 -1
  349. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-jiq8lhyo.js → sequenceDiagram-WJ2MYXX4-o987q8ti.js} +1 -1
  350. package/static/dist/assets/{share._token-o76ki0ly.js → share._token-bfw7f9m5.js} +1 -1
  351. package/static/dist/assets/sliders-horizontal-l65hoa3x.js +1 -0
  352. package/static/dist/assets/{stateDiagram-D77RDMKH-f3fslnon.js → stateDiagram-D77RDMKH-hh23v7y5.js} +1 -1
  353. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-jukr0d8h.js +1 -0
  354. package/static/dist/assets/{swimlanes-42K2YHIH-k1hmk7jf.js → swimlanes-42K2YHIH-gj2t3rm8.js} +1 -1
  355. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-ik9m9j2m.js +8 -0
  356. package/static/dist/assets/{timeline-definition-24CTP7MA-n3ncfy9r.js → timeline-definition-24CTP7MA-84s2w2sr.js} +1 -1
  357. package/static/dist/assets/toast-gqqcvxiy.js +56 -0
  358. package/static/dist/assets/{treeView-Q6P3EWNA-l3y2pejt.js → treeView-Q6P3EWNA-cmuj50l7.js} +1 -1
  359. package/static/dist/assets/{treemap-WGGIJYW6-jown9axh.js → treemap-WGGIJYW6-dpjlg0xc.js} +1 -1
  360. package/static/dist/assets/tts-jw84jlqy.js +1 -0
  361. package/static/dist/assets/{useForm-o4uu74mx.js → useForm-lxzhiqao.js} +1 -1
  362. package/static/dist/assets/{useParams-ftsveu84.js → useParams-dt6gkoq7.js} +1 -1
  363. package/static/dist/assets/{useSearch-crqueqga.js → useSearch-o8t49csk.js} +1 -1
  364. package/static/dist/assets/useTranscript-gx9umcc2.js +1 -0
  365. package/static/dist/assets/{vennDiagram-4TSXK5OY-dh59uq1c.js → vennDiagram-4TSXK5OY-g9g5o8vy.js} +1 -1
  366. package/static/dist/assets/{wardley-WFR3VGLG-e6d74b0j.js → wardley-WFR3VGLG-ij35obrl.js} +1 -1
  367. package/static/dist/assets/{wardleyDiagram-VM6X3IG4-hnofh78f.js → wardleyDiagram-VM6X3IG4-f9my7q7w.js} +1 -1
  368. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-bpymjelb.js → xychartDiagram-S5SC5T6Z-olqx1s1p.js} +1 -1
  369. package/static/dist/index.html +1 -1
  370. package/static/dist/sw.js +1 -1
  371. package/static/dist/assets/AppShell-3isgvoro.js +0 -8
  372. package/static/dist/assets/Button-f4n6dapf.js +0 -1
  373. package/static/dist/assets/ChatPage-k7b6xfax.js +0 -4
  374. package/static/dist/assets/ConnectTargets-juqvt5lm.js +0 -1
  375. package/static/dist/assets/Dialog-hta5utr3.js +0 -1
  376. package/static/dist/assets/Field-b6ez48oz.js +0 -1
  377. package/static/dist/assets/HubRoute-iwvso2tz.js +0 -2
  378. package/static/dist/assets/Markdown-jdeth7zq.js +0 -2
  379. package/static/dist/assets/OAuthSignIn-bpd8hom3.js +0 -1
  380. package/static/dist/assets/ResourceSwitch-odi6dy2o.js +0 -1
  381. package/static/dist/assets/RightPanel-eu6enlo6.js +0 -1
  382. package/static/dist/assets/Select-kr07928w.js +0 -1
  383. package/static/dist/assets/SessionListPanel-etb2i54l.js +0 -1
  384. package/static/dist/assets/SettingsLayout-eu3xxp23.js +0 -1
  385. package/static/dist/assets/States-icab19yg.js +0 -1
  386. package/static/dist/assets/TerminalPanel-hngmsr8b.js +0 -16
  387. package/static/dist/assets/Toaster-nb2uzjw1.js +0 -1
  388. package/static/dist/assets/_app-ga1moszl.js +0 -1
  389. package/static/dist/assets/_app.settings._section-dtdjk98a.js +0 -3
  390. package/static/dist/assets/_app.tasks-n8zuqsqe.js +0 -1
  391. package/static/dist/assets/archive-il7c6053.js +0 -1
  392. package/static/dist/assets/cancel-bsnfo36u.js +0 -1
  393. package/static/dist/assets/channel-dsbtk01y.js +0 -1
  394. package/static/dist/assets/classDiagram-ZZMXUADV-fvgcv24g.js +0 -1
  395. package/static/dist/assets/classDiagram-v2-VYDZK3BY-fvgcv24g.js +0 -1
  396. package/static/dist/assets/flowDiagram-HODETNUW-jahfpiod.js +0 -1
  397. package/static/dist/assets/folder-plus-ivoglq98.js +0 -1
  398. package/static/dist/assets/index-73649w7o.js +0 -10
  399. package/static/dist/assets/index-lhf1fsdf.css +0 -2
  400. package/static/dist/assets/katex-cbdd1ohw.css +0 -1
  401. package/static/dist/assets/katex-pbij2oo6.js +0 -257
  402. package/static/dist/assets/login-lkhtzfcl.js +0 -1
  403. package/static/dist/assets/mermaid-HWGCJPDP-jx0q5dm2.js +0 -1
  404. package/static/dist/assets/onboarding-f67z0a2r.js +0 -1
  405. package/static/dist/assets/queryKeys-ed4n2egc.js +0 -9
  406. package/static/dist/assets/refresh-i9ya9dvl.js +0 -1
  407. package/static/dist/assets/sliders-horizontal-ddcs88av.js +0 -1
  408. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hlt6yphw.js +0 -1
  409. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-hd5t9tnt.js +0 -8
  410. package/static/dist/assets/toast-liparz2j.js +0 -56
@@ -164,12 +164,15 @@ def snapshot(entry, *, records=None, expected=None):
164
164
  from gateway.status import get_process_start_time, _pid_exists
165
165
  service, pid = entry.get('service_pid', entry['pid']), entry['pid']
166
166
  anchors = {service, pid}
167
- observed = dict(expected or {})
167
+ observed = {**entry.get('departed_processes', {}), **(expected or {})}
168
168
  seen_parents = {int(p): proof['parent'] for p, proof in observed.items() if 'parent' in proof}
169
- departed = set()
169
+ departed = set(map(int, entry.get('departed_processes', {})))
170
170
 
171
171
  def exited(p):
172
- if _pid_exists(p) is False:
172
+ live = _pid_exists(p)
173
+ if live is None:
174
+ raise RuntimeError(f'{_name(entry)} process {p} liveness is unreadable; source was not changed.')
175
+ if live is False:
173
176
  if p in anchors:
174
177
  raise RuntimeError(f'{_name(entry)} anchor process {p} disappeared during discovery; source was not changed.')
175
178
  departed.add(p)
@@ -179,7 +182,7 @@ def snapshot(entry, *, records=None, expected=None):
179
182
  def inventory():
180
183
  parents = _process_table()
181
184
  if service not in _ancestors(pid, parents):
182
- raise RuntimeError(f'{_name(entry)} does not own backend/gateway PID {pid}.')
185
+ raise RuntimeError(f'{_name(entry)} identity/ancestry changed: does not own backend/gateway PID {pid}.')
183
186
  if service in _ancestors(os.getpid(), parents):
184
187
  raise RuntimeError(f'{_name(entry)} owns the updater or an ancestor; source was not changed.')
185
188
  for p, parent in seen_parents.items():
@@ -188,6 +191,10 @@ def snapshot(entry, *, records=None, expected=None):
188
191
  continue
189
192
  raise RuntimeError(f'{_name(entry)} process {p} identity/ancestry changed during discovery; source was not changed.')
190
193
  descendants = _descendants(service, parents)
194
+ # Successor retries cannot discard a live writer from a previously observed tree.
195
+ for p in seen_parents.keys() - descendants - departed:
196
+ if not exited(p):
197
+ raise RuntimeError(f'{_name(entry)} process {p} remains live outside the attested tree; recovery remains owed.')
191
198
  seen_parents.update({p: parents[p] for p in descendants})
192
199
  # Zombies may remain in ps. Recheck departed PIDs at every inventory so
193
200
  # neither a recycled PID nor unknown liveness can be silently excluded.
@@ -205,6 +212,8 @@ def snapshot(entry, *, records=None, expected=None):
205
212
  if exited(p):
206
213
  return None
207
214
  raise RuntimeError(f'{_name(entry)} process {p} birth identity is live or unreadable; source was not changed.')
215
+ if exited(p):
216
+ return None
208
217
  if any(proof.get(key) != value for key, value in observed.get(str(p), {}).items()):
209
218
  raise RuntimeError(f'{_name(entry)} process {p} identity/ancestry changed during discovery; source was not changed.')
210
219
  observed[str(p)] = proof
@@ -219,6 +228,8 @@ def snapshot(entry, *, records=None, expected=None):
219
228
  _, final = inventory()
220
229
  if live & departed or remaining != live or final != live:
221
230
  continue
231
+ if departed:
232
+ entry['departed_processes'] = {str(p): observed.get(str(p), {'parent': seen_parents[p]}) for p in departed}
222
233
  return proofs
223
234
  raise RuntimeError(f'{_name(entry)} process inventory kept changing after {SNAPSHOT_ATTEMPTS} samples; retry when descendants settle. Source was not changed and recovery remains owed.')
224
235
 
@@ -403,8 +414,23 @@ def _service_pid(entry):
403
414
 
404
415
  def verify_processes(entry, records, *, stopping=False, fenced=False):
405
416
  from gateway.status import get_process_start_time, _pid_exists
417
+ if not stopping:
418
+ # Reuse discovery's bounded proof without granting permission to lose an anchor.
419
+ candidate = dict(entry)
420
+ for boundary in range(2):
421
+ _, service_pid = _service_pid(entry)
422
+ if service_pid != entry['service_pid']:
423
+ raise RuntimeError(f'{_name(entry)} supervisor respawned during quiescence; source was not changed.')
424
+ if 'config_stamp' in entry and _config_stamp(entry) != entry['config_stamp']:
425
+ raise RuntimeError(f'{_name(entry)} service configuration changed; recovery remains owed.')
426
+ if boundary == 0:
427
+ candidate['processes'] = snapshot(candidate, records=records, expected=entry['processes'])
428
+ entry.update(processes=candidate['processes'])
429
+ if candidate.get('departed_processes'):
430
+ entry['departed_processes'] = candidate['departed_processes']
431
+ return True
406
432
  parents = _process_table()
407
- departed = set()
433
+ departed = set(map(int, entry.get('departed_processes', {})))
408
434
  for pid, expected in entry['processes'].items():
409
435
  pid = int(pid)
410
436
  if _pid_exists(pid) is False:
@@ -442,7 +468,6 @@ def verify_processes(entry, records, *, stopping=False, fenced=False):
442
468
 
443
469
  def bind_processes(entry, records):
444
470
  if entry.get('processes'):
445
- entry['processes'] = snapshot(entry, records=records, expected=entry['processes'])
446
471
  verify_processes(entry, records)
447
472
 
448
473
 
@@ -713,8 +738,20 @@ class ServiceRecovery:
713
738
  or ('runtime_revision' in transaction and not re.fullmatch(r'[a-f0-9]{40}', str(transaction['runtime_revision'])))):
714
739
  raise RuntimeError('Service recovery transaction has an unknown identity or format; its evidence is retained.')
715
740
 
741
+ operation = self.state.get('update_operation')
742
+ if operation is not None and (
743
+ not isinstance(operation, dict)
744
+ or not re.fullmatch(r'[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}', str(operation.get('operation_id', '')))
745
+ or any(not re.fullmatch(r'[a-f0-9]{40}', str(operation.get(key, ''))) for key in ('baseline_revision', 'target_revision'))
746
+ or ('attempt_error' in operation and (not isinstance(operation['attempt_error'], str) or len(operation['attempt_error']) > 2000))
747
+ or ('source_moved' in operation and not isinstance(operation['source_moved'], bool))
748
+ or ('failed_stage' in operation and operation['failed_stage'] not in {'install', 'gateway_restart', 'agent_ready'})
749
+ or operation.get('stage') not in {'install', 'gateway_restart', 'agent_ready'}
750
+ or ('recovered_revision' in operation and not re.fullmatch(r'[a-f0-9]{40}', str(operation['recovered_revision'])))):
751
+ raise RuntimeError('Update operation correlation is malformed; its evidence is retained.')
752
+
716
753
  def save(self, token=None):
717
- if not self.state['entries'] and not self.state.get('sync_failed') and not self.state.get('transaction'):
754
+ if not self.state['entries'] and not self.state.get('sync_failed') and not self.state.get('transaction') and not self.state.get('update_operation'):
718
755
  if self.path.exists():
719
756
  self.path.unlink()
720
757
  self._sync_directory()
@@ -734,9 +771,9 @@ class ServiceRecovery:
734
771
  with contextlib.suppress(FileNotFoundError):
735
772
  os.unlink(temporary)
736
773
 
737
- def _sync_directory(self):
774
+ def _sync_directory(self, directory=None):
738
775
  if os.name != 'nt':
739
- fd = os.open(self.path.parent, os.O_RDONLY)
776
+ fd = os.open(directory if directory is not None else self.path.parent, os.O_RDONLY)
740
777
  try:
741
778
  os.fsync(fd)
742
779
  finally:
@@ -767,10 +804,17 @@ class ServiceRecovery:
767
804
  self.records.write(token)
768
805
  self.save(token)
769
806
 
807
+ def verify_processes(self, entry, **permissions):
808
+ owed = next(e for e in self.state['entries'] if _service_key(e) == _service_key(entry))
809
+ result = verify_processes(owed, self.records, **permissions)
810
+ self.save() # Updated custody must precede the next lifecycle effect.
811
+ return result
812
+
770
813
  def stop(self, entry, stopped):
771
814
  owed = next(e for e in self.state['entries'] if _service_key(e) == _service_key(entry))
772
- verify_processes(owed, self.records)
815
+ self.verify_processes(owed)
773
816
  backend_request(owed)
817
+ self.verify_processes(owed)
774
818
  permit = backend_request(owed, 'prepare')
775
819
  if permit.get('ok') is not True or permit.get('idle') is not True or not isinstance(permit.get('token'), str):
776
820
  if owed['phase'] == 'recorded':
@@ -783,7 +827,7 @@ class ServiceRecovery:
783
827
  except BaseException:
784
828
  backend_request(owed, 'cancel', permit['token'])
785
829
  raise
786
- verify_processes(owed, self.records)
830
+ self.verify_processes(owed)
787
831
  if backend_request(owed, 'commit', permit['token']).get('ok') is not True:
788
832
  raise RuntimeError(f'{_name(owed)} did not commit its backend retirement; recovery remains owed.')
789
833
  owed['backend_committed'] = True
@@ -794,14 +838,14 @@ class ServiceRecovery:
794
838
  # Disarm through the original manager before its KeepAlive can admit a successor.
795
839
  owed['backend_stop_requested'] = True
796
840
  self.save()
797
- verify_processes(owed, self.records, stopping=stopping)
841
+ self.verify_processes(owed, stopping=stopping)
798
842
  if _config_stamp(owed) != owed['config_stamp']:
799
843
  raise RuntimeError(f'{_name(owed)} service configuration changed before backend stop; recovery remains owed.')
800
844
  if stopped.is_set():
801
845
  raise RuntimeError(f'{_name(owed)} backend stop was cancelled; recovery remains owed.')
802
846
  self.pause._disarm(service_entry(owed))
803
847
  wait_stopped(owed, self.records, stopped)
804
- verify_processes(owed, self.records, stopping=True)
848
+ self.verify_processes(owed, stopping=True)
805
849
  owed['phase'] = 'stopped'
806
850
  self.save()
807
851
 
@@ -811,15 +855,15 @@ class ServiceRecovery:
811
855
  raise RuntimeError(f'{_name(entry)} legacy shutdown remains owed; no signal was replayed.')
812
856
  if _config_stamp(owed) != owed['config_stamp']:
813
857
  raise RuntimeError(f'{_name(entry)} configuration changed before legacy refresh.')
814
- verify_processes(owed, self.records)
858
+ self.verify_processes(owed)
815
859
  verify_listener(owed)
816
860
  owed.update(legacy_refresh=True, phase='refreshing')
817
861
  self.save() # Older readers reject this phase and retain debt; no reader replays its signal.
818
- verify_processes(owed, self.records)
862
+ self.verify_processes(owed)
819
863
  verify_listener(owed)
820
864
  if _config_stamp(owed) != owed['config_stamp']:
821
865
  raise RuntimeError(f'{_name(owed)} configuration changed before legacy refresh.')
822
- verify_processes(owed, self.records)
866
+ self.verify_processes(owed)
823
867
  try:
824
868
  if stopped.is_set():
825
869
  raise InterruptedError('Legacy refresh was cancelled before interruption.')
@@ -883,6 +927,8 @@ class ServiceRecovery:
883
927
  if (_config_stamp(candidate) != entry['config_stamp']
884
928
  or candidate.get('profile') != entry.get('profile')):
885
929
  raise RuntimeError(f'{_name(entry)} successor configuration/profile changed; recovery remains owed.')
930
+ if entry.get('departed_processes'):
931
+ candidate['departed_processes'] = entry['departed_processes']
886
932
  bind_processes(candidate, self.records)
887
933
  parents = {int(pid): p['parent'] for pid, p in candidate['processes'].items()}
888
934
  chain, pid = set(), candidate['pid']
@@ -894,7 +940,8 @@ class ServiceRecovery:
894
940
  if chain | _descendants(candidate['pid'], parents) != set(parents):
895
941
  raise RuntimeError(f'{_name(entry)} successor has unrelated descendants; recovery remains owed.')
896
942
  for pid, process in candidate['processes'].items():
897
- old = entry['processes'].get(pid) or entry.get('retired_processes', {}).get(pid)
943
+ old = (entry['processes'].get(pid) or entry.get('departed_processes', {}).get(pid)
944
+ or entry.get('retired_processes', {}).get(pid))
898
945
  if old is not None and old != process:
899
946
  raise RuntimeError(f'{_name(entry)} successor reused a recorded process identity; recovery remains owed.')
900
947
  return candidate
@@ -966,7 +1013,7 @@ class ServiceRecovery:
966
1013
  if pending:
967
1014
  stopped.wait(.05)
968
1015
  continue
969
- if not verify_processes(entry, self.records, stopping=True, fenced=True):
1016
+ if not self.verify_processes(entry, stopping=True, fenced=True):
970
1017
  stopped.wait(.05)
971
1018
  continue
972
1019
  if self._gateway_writers_live(entry) or _config_stamp(entry) != entry['config_stamp']:
@@ -989,7 +1036,7 @@ class ServiceRecovery:
989
1036
  entry.update(candidate, retired_processes=retired, phase='retiring',
990
1037
  drain_acknowledged=False, drain_acknowledged_at=None, settle_attempts=attempts)
991
1038
  self.save() # Successor custody precedes its cooperative lifecycle request.
992
- verify_processes(entry, self.records)
1039
+ self.verify_processes(entry)
993
1040
  if _config_stamp(entry) != entry['config_stamp']:
994
1041
  raise RuntimeError(f'{_name(entry)} service configuration changed; recovery remains owed.')
995
1042
  if not self.pause._ask_to_drain(entry):
@@ -1036,7 +1083,7 @@ class ServiceRecovery:
1036
1083
  raise RuntimeError(f'{_name(entry)} uncommitted retirement could not yet be cancelled; recovery remains owed.')
1037
1084
  self.stop(entry, threading.Event())
1038
1085
  elif any(self.records.identity_is_live({'pid': int(pid), 'ct': p['ct']}) for pid, p in entry['processes'].items()):
1039
- verify_processes(entry, self.records, stopping=True)
1086
+ self.verify_processes(entry, stopping=True)
1040
1087
  if any(self.records.identity_is_live({'pid': int(pid), 'ct': p['ct']}) for pid, p in entry['processes'].items() if int(pid) != entry['service_pid']):
1041
1088
  raise RuntimeError(f'{_name(entry)} still has live writer descendants; recovery remains owed.')
1042
1089
  self._stop_backend_supervisor(entry, threading.Event(), stopping=True)
@@ -1062,6 +1109,18 @@ class ServiceRecovery:
1062
1109
  raise RuntimeError(f'{_name(entry)} readiness is unverified at its original endpoint; recovery remains owed.')
1063
1110
  time.sleep(.1)
1064
1111
 
1112
+ def _verify_candidate(self, candidate, entry):
1113
+ # Readiness retries must retain both live observations and proved departures.
1114
+ candidate['config_stamp'] = entry['config_stamp']
1115
+ candidate['processes'] = {**candidate['processes'], **entry.get('readiness_processes', {})}
1116
+ candidate['departed_processes'] = {**entry.get('departed_processes', {}),
1117
+ **candidate.get('departed_processes', {})}
1118
+ bind_processes(candidate, self.records)
1119
+ entry['readiness_processes'] = candidate['processes']
1120
+ if candidate['departed_processes']:
1121
+ entry['departed_processes'] = candidate['departed_processes']
1122
+ self.save()
1123
+
1065
1124
  def _ready(self, entry, ledger):
1066
1125
  if _config_stamp(entry) != entry['config_stamp']:
1067
1126
  raise RuntimeError(f'{_name(entry)} service configuration changed; backend recovery remains owed.')
@@ -1075,8 +1134,9 @@ class ServiceRecovery:
1075
1134
  candidate = self._gateway_candidate(entry)
1076
1135
  if candidate is None:
1077
1136
  return False
1137
+ self._verify_candidate(candidate, entry)
1078
1138
  ready = _gateway_home_matches(entry['home'], (candidate['pid'], candidate['ct']), self.pause)
1079
- verify_processes(candidate, self.records)
1139
+ self._verify_candidate(candidate, entry)
1080
1140
  return ready
1081
1141
  if entry.get('legacy_refresh') and any(self.records.identity_is_live({'pid': int(pid), 'ct': p['ct']})
1082
1142
  for pid, p in entry['processes'].items()
@@ -1095,7 +1155,7 @@ class ServiceRecovery:
1095
1155
  if (candidate['profile'] != entry['profile'] or _service_key(candidate) != _service_key(entry)
1096
1156
  or _config_stamp(candidate) != entry['config_stamp']):
1097
1157
  return False
1098
- bind_processes(candidate, self.records)
1158
+ self._verify_candidate(candidate, entry)
1099
1159
  try:
1100
1160
  if entry.get('legacy_refresh'):
1101
1161
  verify_listener(candidate)
@@ -1106,7 +1166,7 @@ class ServiceRecovery:
1106
1166
  return False
1107
1167
  if backend_request(candidate, 'cancel', permit['token']).get('ok') is not True:
1108
1168
  return False
1109
- verify_processes(candidate, self.records)
1169
+ self._verify_candidate(candidate, entry)
1110
1170
  if self.identity._pid_alive_matches(row['pid'], row['create_time'], strict=True) is not True:
1111
1171
  return False
1112
1172
  except BackendLifecycleUnsupported:
@@ -310,8 +310,8 @@ def _recover_processes(home: Path) -> None:
310
310
 
311
311
 
312
312
  @contextlib.contextmanager
313
- def scoped_home(home: Path, *, load_plugins: bool = True):
314
- """Run the body with Hermes Agent resolving ``get_hermes_home()`` to ``home``."""
313
+ def scoped_home(home: Path, *, load_plugins: bool = True, recover_processes: bool = True, read_only: bool = False):
314
+ """Bind the home; read-only inspection skips credential hydration, terminal defaults and recovery."""
315
315
  home = Path(home).expanduser()
316
316
  stamp = _scope_stamp(home)
317
317
  try:
@@ -321,18 +321,25 @@ def scoped_home(home: Path, *, load_plugins: bool = True):
321
321
  if set_hermes_home_override is not None:
322
322
  token = set_hermes_home_override(home)
323
323
  try:
324
- with _secret_scope(home, stamp, load_plugins=load_plugins), _terminal_scope(home, stamp):
325
- _recover_processes(home)
324
+ if read_only:
326
325
  yield home
326
+ else:
327
+ with _secret_scope(home, stamp, load_plugins=load_plugins), _terminal_scope(home, stamp):
328
+ if recover_processes:
329
+ _recover_processes(home)
330
+ yield home
327
331
  finally:
328
332
  reset_hermes_home_override(token)
329
333
  return
334
+ if read_only:
335
+ raise RpcError("Read-only profile binding is unavailable", condition="agent_incompatible")
330
336
  with _ENV_LOCK:
331
337
  previous = os.environ.get("HERMES_HOME")
332
338
  os.environ["HERMES_HOME"] = str(home)
333
339
  try:
334
340
  with _secret_scope(home, stamp, load_plugins=load_plugins), _terminal_scope(home, stamp):
335
- _recover_processes(home)
341
+ if recover_processes:
342
+ _recover_processes(home)
336
343
  yield home
337
344
  finally:
338
345
  if previous is None:
@@ -29,9 +29,9 @@ class Registry:
29
29
 
30
30
  def build_methods(runtime: AgentRuntime) -> dict[str, Handler]:
31
31
  registry = Registry(runtime)
32
- from . import aux, chat, checkpoints, commands, config, connectors, cron, dashboard_plugins, gateway, goals, kanban, mcp, memory, oauth, plugin_oauth, process, profiles, providers, skills, state_db, stt, text, toolsets, usage, worktree, write_approval # noqa: WPS433
32
+ from . import agent_imports, aux, chat, checkpoints, commands, config, connectors, cron, dashboard_plugins, delegation, gateway, goals, kanban, mcp, managed_buffers, memory, oauth, outbound_drafts, plugin_oauth, process, profiles, providers, skills, state_db, stt, tts, text, toolsets, usage, worktree, write_approval # noqa: WPS433
33
33
  from . import runtime as runtime_methods
34
34
 
35
- for module in (runtime_methods, goals, commands, kanban, state_db, profiles, skills, mcp, stt, cron, providers, oauth, plugin_oauth, aux, text, process, usage, gateway, worktree, checkpoints, memory, chat, config, toolsets, write_approval, connectors, dashboard_plugins):
35
+ for module in (agent_imports, runtime_methods, goals, commands, kanban, state_db, profiles, skills, mcp, stt, tts, cron, providers, oauth, plugin_oauth, aux, delegation, text, process, usage, gateway, worktree, checkpoints, memory, chat, config, toolsets, write_approval, connectors, dashboard_plugins, outbound_drafts, managed_buffers):
36
36
  module.register(registry)
37
37
  return registry.methods