@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
@@ -239,7 +239,7 @@ def forget_profile_mcp_tools(home) -> None:
239
239
  _MCP_DISCOVERED_HOMES.discard(os.path.realpath(home))
240
240
 
241
241
 
242
- def _reload_mcp() -> str:
242
+ def _reload_mcp(*, log_errors=True) -> str:
243
243
  with _RELOAD_MCP_LOCK:
244
244
  try:
245
245
  from agent.secret_scope import is_multiplex_active
@@ -274,7 +274,8 @@ def _reload_mcp() -> str:
274
274
  with _lock:
275
275
  tools = [name for name in tools if _mcp_tool_server_names.get(name) in connected]
276
276
  except Exception as exc: # noqa: BLE001
277
- log.warning("Failed to reload MCP servers", exc_info=True)
277
+ if log_errors:
278
+ log.warning("Failed to reload MCP servers", exc_info=True)
278
279
  raise RpcError("Failed to reload MCP servers", condition="mcp_reload_failed") from exc
279
280
  added, removed, reconnected = connected - old, old - connected, connected & old
280
281
  lines = ["Reloaded MCP servers from configuration."]
@@ -846,11 +847,12 @@ def register(registry) -> None:
846
847
  output = execute_agent_command(command, session_id, workspace)
847
848
  source = "agent"
848
849
  if output is None:
849
- from .chat import _turn_identity
850
+ from .chat import _turn_identity, command_choices
850
851
 
851
852
  # TAL-904: a chat's plugin command runs under that chat's session and workspace, as its turns do.
852
- with _turn_identity(session_id, workspace) if session_id else contextlib.nullcontext():
853
+ with command_choices(ctx, params), (_turn_identity(session_id, workspace) if session_id else contextlib.nullcontext()):
853
854
  output = execute_plugin_command(command, session_id)
855
+ ctx.check_cancelled()
854
856
  source = "plugin"
855
857
  if output is None:
856
858
  raise RpcError(f"unknown command {parse_slash_command(command)[0]!r}", condition="command_not_found")
@@ -133,9 +133,8 @@ def _split_config_aliases(text: str, desired: dict) -> str:
133
133
  return output.getvalue()
134
134
 
135
135
 
136
- def write_config(path: Path, config: dict, *, profile_home: Path | None = None) -> dict:
137
- if not isinstance(config, dict):
138
- raise InvalidParams("config must be an object")
136
+ def assert_config_writable(profile_home: Path | None = None) -> None:
137
+ """Verify the owning profile policy before any config publication; uncertainty refuses."""
139
138
  try:
140
139
  managed = importlib.import_module("hermes_constants").get_managed_system(profile_home)
141
140
  except Exception as exc: # noqa: BLE001
@@ -144,6 +143,12 @@ def write_config(path: Path, config: dict, *, profile_home: Path | None = None)
144
143
  if managed is not None:
145
144
  raise RpcError("config.yaml is package-managed. Update the declarative configuration instead.",
146
145
  condition="config_write_refused")
146
+
147
+
148
+ def write_config(path: Path, config: dict, *, profile_home: Path | None = None) -> dict:
149
+ if not isinstance(config, dict):
150
+ raise InvalidParams("config must be an object")
151
+ assert_config_writable(profile_home)
147
152
  target = _write_target(path)
148
153
  target.parent.mkdir(parents=True, exist_ok=True)
149
154
  try:
@@ -8,10 +8,13 @@ registers its session operation here through ``remember_chat_operation``. Every
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
+ import contextvars
12
+ import hashlib
11
13
  import inspect
12
14
  import json
13
15
  import logging
14
16
  import threading
17
+ import uuid
15
18
  from collections import OrderedDict
16
19
  from pathlib import Path
17
20
  from types import SimpleNamespace
@@ -130,11 +133,46 @@ def accounts() -> dict:
130
133
  client = _portal()
131
134
  if not _authenticated(client):
132
135
  return {"accounts": []}
136
+ rows = client.list_accounts()
137
+ try:
138
+ from hermes_cli.free_tier_offer import note_connected_apps_seen
139
+ note_connected_apps_seen([{"connected": row.get("active") is True and not row.get("disabled")} for row in rows])
140
+ except ImportError:
141
+ pass # older Agents have no connector offer
142
+ except Exception:
143
+ log.warning("connector sighting unavailable")
133
144
  return {"accounts": [{
134
145
  "connection_id": row["connectionId"], "connector": row["connector"], "status": row["status"],
135
146
  "status_reason": row.get("statusReason"), "label": row["label"], "alias": row.get("alias"),
136
147
  "active": bool(row["active"]), "disabled": bool(row.get("disabled")), "created_at": row["createdAt"],
137
- } for row in client.list_accounts()]}
148
+ } for row in rows]}
149
+
150
+
151
+ def sign_in_offer(home: Path, claim_guest: str | None = None) -> dict:
152
+ """Native policy and CAS only. The server owns retention of the delivered page result."""
153
+ result = {"available": False, "guest_id": None, "eligible": False, "due_in": None, "claimed": False}
154
+ try:
155
+ from hermes_cli import anon_auth, free_tier_offer as native
156
+ if not all(callable(getattr(native, name, None)) for name in ("_eligible", "offer_due_in", "claim_offer")):
157
+ return result
158
+
159
+ def identity():
160
+ state = anon_auth.current_nous_state()
161
+ token = state.get("anon_token") if anon_auth.is_guest_state(state) else None
162
+ return hashlib.sha256(f"{home.resolve()}\0{token}".encode()).hexdigest() if isinstance(token, str) and token else None
163
+
164
+ guest = identity()
165
+ result["guest_id"] = guest
166
+ eligible = bool(native._eligible(native.CONNECTOR))
167
+ due = native.offer_due_in(native.CONNECTOR)
168
+ claimed = bool(guest and guest == claim_guest and native.claim_offer(native.CONNECTOR)) if claim_guest else False
169
+ if identity() != guest:
170
+ return {**result, "guest_id": None}
171
+ return {"available": True, "guest_id": guest, "eligible": eligible, "due_in": due, "claimed": claimed}
172
+ except ImportError:
173
+ return result
174
+ except Exception:
175
+ return result # retain a proven identity, never raw auth or native error details
138
176
 
139
177
 
140
178
  def remove(connection_id: str) -> dict:
@@ -201,6 +239,14 @@ def _operation(home: Path, op_id: str):
201
239
  operation = _OPS.get((str(home), op_id))
202
240
  if operation is None:
203
241
  raise RpcError("No connection operation with that id.", condition="operation_not_found")
242
+ account_id = getattr(operation, "_talaria_nous_account_id", None)
243
+ if account_id:
244
+ from . import nous_account
245
+ current = nous_account.read(home)
246
+ if not current or current["account_id"] != account_id:
247
+ from tools.connectors.contract import SettleReason
248
+ operation.settle(SettleReason.interrupt)
249
+ raise RpcError("No connection operation for the current account.", condition="operation_not_found")
204
250
  return operation
205
251
 
206
252
 
@@ -226,8 +272,62 @@ def operation_view(operation) -> dict:
226
272
  }
227
273
 
228
274
 
229
- def connect(home: Path, connector: str) -> dict:
275
+ def _reconnect(home: Path, connector: str, account_id: str) -> dict:
276
+ """Compose the existing native operation with an account-fenced, noncreating client.
277
+
278
+ Native account.find_or_start_operation always uses a creating, live-credential client
279
+ in its later thread. Its lifecycle primitives accept the client this result needs.
280
+ """
281
+ from tools.connectors import account, live, managed
282
+ from tools.connectors.gateway.client import ConnectorClient
283
+ from tools.connectors.operation import ConnectionOperation, Target
284
+ from tools.connectors.run import drive_operation
285
+ from tools.connectors.contract import SettleReason
286
+ from . import nous_account
287
+
288
+ with account._start_lock:
289
+ existing = live.find_target(connector, profile_home=str(home))
290
+ if existing is not None:
291
+ if getattr(existing, "_talaria_nous_account_id", None) != account_id:
292
+ raise RpcError("Finish the current app connection before reconnecting this result.", condition="operation_refused")
293
+ _remember(home, existing)
294
+ return operation_view(_operation(home, existing.op_id))
295
+ client = ConnectorClient(initiator="desktop_page", header_provider=lambda url: nous_account.connector_headers(home, account_id, url))
296
+ operation = ConnectionOperation([Target(connector, "connector", "connect")], session_key=f"account:{uuid.uuid4().hex}")
297
+ operation._talaria_nous_account_id = account_id
298
+ operation._talaria_nous_client = client
299
+ start = account.AccountOperationStart(operation=operation, started=True)
300
+ context = contextvars.copy_context()
301
+
302
+ def run():
303
+ try:
304
+ drive_operation(operation, managed.managed_kind(client, "connect", force=False),
305
+ connection_callback=lambda payload: start.done.set(),
306
+ tick_seconds=managed.WATCH_TICK_SECONDS, with_urls_in_result=False)
307
+ except Exception:
308
+ start.failed = True
309
+ operation.settle(SettleReason.interrupt)
310
+ finally:
311
+ live.close(operation)
312
+ start.done.set()
313
+
314
+ live.open(operation)
315
+ _remember(home, operation)
316
+ try:
317
+ threading.Thread(target=lambda: context.run(run), daemon=True, name="connector-account-operation").start()
318
+ except Exception:
319
+ live.close(operation)
320
+ operation.settle(SettleReason.interrupt)
321
+ raise
322
+ if account.wait_for_prepare(start) and start.failed:
323
+ raise RpcError("Connector request failed.", condition="connectors_failed")
324
+ return operation_view(_operation(home, operation.op_id))
325
+
326
+
327
+ def connect(home: Path, connector: str, *, account_id: str | None = None) -> dict:
230
328
  """Start (or rejoin) the account-owned connect for ``connector`` and wait for its authorization link."""
329
+ if account_id is not None:
330
+ return _reconnect(home, connector, account_id)
231
331
  from tools.connectors import account
232
332
  from tools.connectors.contract import TargetState
233
333
  from tools.connectors.run import reissue
@@ -236,8 +336,11 @@ def connect(home: Path, connector: str) -> dict:
236
336
  page = {"initiator": "desktop_page"} if "initiator" in inspect.signature(account.find_or_start_operation).parameters else {}
237
337
  start = account.find_or_start_operation([connector], action="connect", profile_home=str(home), **page)
238
338
  _remember(home, start.operation)
339
+ _operation(home, start.operation.op_id)
239
340
  if not start.started:
240
341
  target = start.operation.target(connector)
342
+ if target is not None and target.state in (TargetState.failed, TargetState.expired) and getattr(start.operation, "_talaria_nous_client", None) is not None:
343
+ return respond(home, start.operation.op_id, "retry", connector, {})
241
344
  if target is not None and target.state in (TargetState.failed, TargetState.expired) and reissue(start.operation, [connector], **page):
242
345
  raise RpcError("This connection cannot be started again.", condition="operation_refused")
243
346
  return operation_view(start.operation)
@@ -262,7 +365,14 @@ def respond(home: Path, op_id: str, action: str, target: str | None, env: dict)
262
365
  if action == "continue":
263
366
  apply_answer(operation, json.dumps({"settled_by": SettleReason.continue_.value}))
264
367
  elif action == "retry" and row.kind == "connector":
265
- if reissue(operation, [row.name]):
368
+ client = getattr(operation, "_talaria_nous_client", None)
369
+ if client is not None:
370
+ from tools.connectors.managed import mint
371
+ from tools.connectors.contract import Actor, TargetState
372
+ if row.state not in (TargetState.failed, TargetState.expired):
373
+ raise RpcError("This target cannot be run again.", condition="operation_refused")
374
+ mint(client, operation, [row.name], reinitiate=True, actor=Actor.user)
375
+ elif reissue(operation, [row.name]):
266
376
  raise RpcError("This target cannot be run again.", condition="operation_refused")
267
377
  else:
268
378
  status = "skipped" if action == "skip" else "approved"
@@ -288,6 +398,21 @@ def remember_chat_operation(home: Path, payload: dict) -> dict | None:
288
398
 
289
399
 
290
400
  def register(registry_) -> None:
401
+ @registry_.method("connectors.offer.status")
402
+ def offer_status_(ctx: CallContext, params: dict) -> dict:
403
+ home = profile_home_param(params)
404
+ with scoped_home(home):
405
+ return sign_in_offer(home)
406
+
407
+ @registry_.method("connectors.offer.claim")
408
+ def offer_claim_(ctx: CallContext, params: dict) -> dict:
409
+ guest = params.get("guest_id")
410
+ if not isinstance(guest, str) or not guest:
411
+ raise InvalidParams("guest_id is required")
412
+ home = profile_home_param(params)
413
+ with scoped_home(home):
414
+ return sign_in_offer(home, guest)
415
+
291
416
  def page(params: dict, read, *, creates_guest: bool = False):
292
417
  with scoped_home(profile_home_param(params)):
293
418
  _open(creates_guest=creates_guest)
@@ -346,7 +471,16 @@ def register(registry_) -> None:
346
471
  def connect_(ctx: CallContext, params: dict) -> dict:
347
472
  slug = _slug(params)
348
473
  home = profile_home_param(params)
349
- return page(params, lambda: connect(home, slug), creates_guest=True)
474
+ def begin():
475
+ if "nous_account_id" in params:
476
+ from . import nous_account
477
+ view = nous_account.read(home)
478
+ if not view or view["account_id"] != params["nous_account_id"] or slug not in view["reconnect"]:
479
+ raise RpcError("The signed-in account or reconnect result changed. Refresh before reconnecting.", condition="connectors_forbidden")
480
+ if not any(row["slug"] == slug for row in catalog()["connectors"]):
481
+ raise RpcError("This app is not available to reconnect.", condition="connectors_forbidden")
482
+ return connect(home, slug, account_id=params.get("nous_account_id"))
483
+ return page(params, begin, creates_guest="nous_account_id" not in params)
350
484
 
351
485
  def gated() -> None:
352
486
  # Reads and moves on an operation pass the availability gate too, without creating an identity.
@@ -190,15 +190,36 @@ def _plugins(home):
190
190
  return out
191
191
 
192
192
 
193
- def _named(home, name):
194
- return next((p for p in _plugins(home) if p['name'] == name and p['enabled'] and p['panel']), None)
193
+ def reviewed_producer(home, name, pin, sources):
194
+ """Verify a store adapter's native registration, profile consent and reviewed bytes without loading it."""
195
+ try:
196
+ from hermes_cli import plugins_cmd as pc
197
+ metadata = pc._read_install_metadata()
198
+ for plugin in _plugins(home):
199
+ if plugin['name'] != name or not plugin['enabled'] or plugin.get('source') != 'user':
200
+ continue
201
+ root, anchor = Path(plugin['_dir']).parent, Path(plugin['_asset_anchor'])
202
+ record = metadata.get(root.name, {})
203
+ catalog = record.get('catalog', {})
204
+ if catalog.get('name') != name or catalog.get('sha') != pin or record.get('revision') != pin:
205
+ continue
206
+ if all((body := _read(root, file, anchor=anchor)) is not None
207
+ and hashlib.sha256(body).hexdigest() == digest for file, digest in sources.items()):
208
+ return pin
209
+ except (ImportError, AttributeError, OSError, ValueError, TypeError):
210
+ pass
211
+ return None
212
+
213
+
214
+ def _named(home, name, *, require_panel=True):
215
+ return next((p for p in _plugins(home) if p['name'] == name and p['enabled'] and (p['panel'] if require_panel else p.get('_api_file'))), None)
195
216
 
196
217
 
197
218
  def _reply(status=404, body=b'', content_type='application/octet-stream'):
198
219
  return {'status': status, 'body': base64.b64encode(body).decode('ascii'), 'content_type': content_type}
199
220
 
200
221
 
201
- def _request(ctx, plugin, params):
222
+ def _request(ctx, plugin, params, *, require_panel=True):
202
223
  ctx.check_cancelled()
203
224
  if params.get('authenticated') is not True:
204
225
  return _reply()
@@ -240,7 +261,7 @@ def _request(ctx, plugin, params):
240
261
  content_type = next((v for k, v in result.get('headers', []) if k.lower() == 'content-type'), 'application/octet-stream')
241
262
  if 'text/event-stream' in content_type.lower():
242
263
  return _reply(501, b'Agent plugin host supports buffered HTTP only', 'text/plain; charset=utf-8')
243
- if _named(homes.profile_home_param(params), plugin['name']) is None:
264
+ if _named(homes.profile_home_param(params), plugin['name'], require_panel=require_panel) is None:
244
265
  return _reply()
245
266
  raw = result.get('body', b'')
246
267
  if not isinstance(raw, bytes) or len(raw) > _MAX_API:
@@ -0,0 +1,126 @@
1
+ """Native delegation registry and route validation for the auxiliary settings owner."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import asdict
6
+
7
+ from ..errors import InvalidParams, RpcError
8
+ from ..home import profile_home_param, scoped_home
9
+
10
+
11
+ def registry(config: dict) -> dict:
12
+ section = config.get("delegation")
13
+ section = section if isinstance(section, dict) else {}
14
+ try:
15
+ from agent.delegation_backends import list_backends
16
+ from agent.delegation_registry import backend_status, configured_backend
17
+ except ImportError:
18
+ configured = section.get("backend") or "default"
19
+ return {"supported": False, "configured": configured, "effective": None, "available": False,
20
+ "blocked_reason": "Update Hermes Agent to configure delegation modes.", "fixed_model_active": configured == "default",
21
+ "backends": [{"name": configured, "label": configured, "description": "", "available": False, "reason": "Update Hermes Agent."}], "profiles": []}
22
+ from hermes_cli.plugins import discover_plugins
23
+ from hermes_cli.profiles import list_profile_names
24
+
25
+ discover_plugins()
26
+ configured = configured_backend(section)
27
+ provider, reason = backend_status(configured)
28
+ available = provider is not None and not reason
29
+ backends = [asdict(info) for info in list_backends()]
30
+ if not any(info["name"] == configured for info in backends):
31
+ backends.append({"name": configured, "label": configured, "description": "", "available": False, "reason": reason})
32
+ return {"supported": True, "configured": configured, "effective": configured if available else None,
33
+ "available": available, "blocked_reason": reason or None, "fixed_model_active": available and configured == "default",
34
+ "backends": backends, "profiles": list_profile_names()}
35
+
36
+
37
+ def clean_routes(backend: str, block: dict, current: dict) -> dict:
38
+ """Use native canonical keys and parsers, preserving credentials by original route identity."""
39
+ from agent.delegation_provider import ROUTE_KEYS
40
+ from agent.fast_mode import STATIC_TIERS, parse_exact_service_tier
41
+ from hermes_constants import parse_reasoning_effort
42
+ from hermes_cli.profiles import list_profile_names
43
+
44
+ field = "options" if backend == "model_map" else "profiles"
45
+ entries = block.get(field)
46
+ if not isinstance(entries, list):
47
+ raise InvalidParams(f"{field} must be a list")
48
+ stored = {row.get("name"): row for row in current.get(field, []) if isinstance(row, dict)}
49
+ known = set(list_profile_names()) if backend == "profile_routes" else set()
50
+ rows, names = [], []
51
+ for entry in entries:
52
+ if not isinstance(entry, dict):
53
+ raise InvalidParams("Each route must be an object")
54
+ name = str(entry.get("name") or "").strip()
55
+ if not name or name in names:
56
+ raise InvalidParams("Route names must be nonempty and unique")
57
+ names.append(name)
58
+ if backend == "profile_routes":
59
+ if name not in known:
60
+ raise InvalidParams(f"Profile {name!r} does not exist")
61
+ rows.append({"name": name, **({"description": entry["description"].strip()} if entry.get("description", "").strip() else {})})
62
+ continue
63
+ source = stored.get(entry.get("original_name") or name, {})
64
+ # Hidden canonical values survive both edits and renames.
65
+ row = {key: value for key, value in source.items() if key in ROUTE_KEYS}
66
+ row.update({key: value for key, value in entry.items() if key in ROUTE_KEYS or key in {"name", "description"}})
67
+ row["name"] = name
68
+ for key in ("description", "model", "provider", "base_url", "api_mode"):
69
+ if key in row:
70
+ row[key] = str(row[key] or "").strip()
71
+ if not row.get("description") or not row.get("model") or not (row.get("provider") or row.get("base_url")):
72
+ raise InvalidParams(f"Route {name!r} needs a description, model and provider or endpoint")
73
+ for key in ("reasoning_effort", "service_tier"):
74
+ if key in entry and not entry[key]:
75
+ row.pop(key, None)
76
+ effort = row.get("reasoning_effort")
77
+ if effort and parse_reasoning_effort(effort) is None:
78
+ raise InvalidParams("Unknown reasoning effort")
79
+ tier = row.get("service_tier")
80
+ if tier:
81
+ try:
82
+ parsed = parse_exact_service_tier(tier)
83
+ except ValueError:
84
+ raise InvalidParams("Unknown service tier") from None
85
+ if parsed is None or parsed and parsed not in STATIC_TIERS:
86
+ raise InvalidParams("Unknown service tier")
87
+ if entry.get("api_key_clear"):
88
+ row.pop("api_key", None)
89
+ elif not entry.get("api_key") and source.get("api_key"):
90
+ row["api_key"] = source["api_key"]
91
+ if "fallback_providers" in row and not isinstance(row["fallback_providers"], list):
92
+ raise InvalidParams("fallback_providers must be a list")
93
+ rows.append(row)
94
+ default = (block.get("default") or "").strip()
95
+ if default and default not in names:
96
+ raise InvalidParams("The default route must be in the list")
97
+ return {field: rows, **({"default": default} if default else {})}
98
+
99
+
100
+ def register(methods) -> None:
101
+ @methods.method("aux.delegation")
102
+ def describe(ctx, params):
103
+ with scoped_home(profile_home_param(params)):
104
+ return registry(params.get("config") or {})
105
+
106
+ @methods.method("aux.delegation_routes")
107
+ def validate(ctx, params):
108
+ with scoped_home(profile_home_param(params)):
109
+ return {"block": clean_routes(params["backend"], params["block"], params["current"])}
110
+
111
+ @methods.method("aux.delegation_backend")
112
+ def select(ctx, params):
113
+ from hermes_cli.config import get_config_path
114
+ from agent.delegation_backends import set_global_backend
115
+ from .config import config_path_param
116
+
117
+ with scoped_home(profile_home_param(params)):
118
+ if get_config_path().resolve() != config_path_param(params).resolve():
119
+ raise RpcError("Native delegation config path differs from the configured file", condition="config_write_refused")
120
+ try:
121
+ set_global_backend(params["backend"])
122
+ except PermissionError:
123
+ raise RpcError("config.yaml is package-managed. Update the declarative configuration instead.", condition="config_write_refused") from None
124
+ except ValueError as exc:
125
+ raise InvalidParams(str(exc)) from None
126
+ return {"ok": True}
@@ -243,6 +243,11 @@ def _run(action: str, home: Path, cli_profile: str | None, ctx: CallContext, *,
243
243
 
244
244
 
245
245
  def register(registry) -> None:
246
+ @registry.method("gateway.groups")
247
+ def groups_(ctx: CallContext, params: dict) -> dict:
248
+ from .groups import groups
249
+ return groups(ctx, params)
250
+
246
251
  @registry.method("gateway.session")
247
252
  def session_(ctx: CallContext, params: dict) -> dict:
248
253
  from .gateway_sessions import session