@maudecode/talaria-web 1.19.0 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (616) hide show
  1. package/_release.json +8 -8
  2. package/dist/api/automation-raw.js +61 -6
  3. package/dist/api/automation-raw.js.map +1 -1
  4. package/dist/api/automation-router.d.ts +309 -2
  5. package/dist/api/automation-router.js +28 -2
  6. package/dist/api/automation-router.js.map +1 -1
  7. package/dist/api/chat-router.d.ts +646 -24
  8. package/dist/api/chat-router.js +54 -167
  9. package/dist/api/chat-router.js.map +1 -1
  10. package/dist/api/git-router.d.ts +54 -0
  11. package/dist/api/git-router.js +18 -5
  12. package/dist/api/git-router.js.map +1 -1
  13. package/dist/api/raw-routes.js +13 -1
  14. package/dist/api/raw-routes.js.map +1 -1
  15. package/dist/api/router.d.ts +3 -3
  16. package/dist/api/session-visibility.js +2 -2
  17. package/dist/api/session-visibility.js.map +1 -1
  18. package/dist/api/sessions-router.d.ts +1868 -79
  19. package/dist/api/sessions-router.js +72 -43
  20. package/dist/api/sessions-router.js.map +1 -1
  21. package/dist/api/settings-router.d.ts +34 -13
  22. package/dist/api/settings-router.js +54 -17
  23. package/dist/api/settings-router.js.map +1 -1
  24. package/dist/api/sse-routes.js +45 -21
  25. package/dist/api/sse-routes.js.map +1 -1
  26. package/dist/api/tools-router.d.ts +773 -39
  27. package/dist/api/tools-router.js +167 -45
  28. package/dist/api/tools-router.js.map +1 -1
  29. package/dist/app.js +15 -11
  30. package/dist/app.js.map +1 -1
  31. package/dist/auth/crypto.d.ts +3 -0
  32. package/dist/auth/crypto.js +18 -0
  33. package/dist/auth/crypto.js.map +1 -1
  34. package/dist/auth/gate.js +5 -1
  35. package/dist/auth/gate.js.map +1 -1
  36. package/dist/cli/ctl.js +6 -1
  37. package/dist/cli/ctl.js.map +1 -1
  38. package/dist/cli/main.js +23 -18
  39. package/dist/cli/main.js.map +1 -1
  40. package/dist/cli/supervise.d.ts +22 -0
  41. package/dist/cli/supervise.js +80 -2
  42. package/dist/cli/supervise.js.map +1 -1
  43. package/dist/config/agent-config.d.ts +3 -0
  44. package/dist/config/agent-config.js +36 -9
  45. package/dist/config/agent-config.js.map +1 -1
  46. package/dist/fs/atomic.d.ts +3 -0
  47. package/dist/fs/atomic.js +19 -5
  48. package/dist/fs/atomic.js.map +1 -1
  49. package/dist/fs/stat.d.ts +6 -0
  50. package/dist/fs/stat.js +18 -2
  51. package/dist/fs/stat.js.map +1 -1
  52. package/dist/http/context.d.ts +16 -0
  53. package/dist/http/context.js +48 -5
  54. package/dist/http/context.js.map +1 -1
  55. package/dist/profiles/profiles.d.ts +2 -0
  56. package/dist/profiles/profiles.js +1 -0
  57. package/dist/profiles/profiles.js.map +1 -1
  58. package/dist/providers/catalog.d.ts +11 -6
  59. package/dist/providers/catalog.js +76 -24
  60. package/dist/providers/catalog.js.map +1 -1
  61. package/dist/redact.d.ts +2 -0
  62. package/dist/redact.js +55 -16
  63. package/dist/redact.js.map +1 -1
  64. package/dist/release.js +5 -3
  65. package/dist/release.js.map +1 -1
  66. package/dist/runtime.js +118 -26
  67. package/dist/runtime.js.map +1 -1
  68. package/dist/server.js +25 -21
  69. package/dist/server.js.map +1 -1
  70. package/dist/sessions/admission.d.ts +21 -0
  71. package/dist/sessions/admission.js +176 -0
  72. package/dist/sessions/admission.js.map +1 -0
  73. package/dist/sessions/anchor.d.ts +4 -1
  74. package/dist/sessions/anchor.js +9 -5
  75. package/dist/sessions/anchor.js.map +1 -1
  76. package/dist/sessions/background-tasks.d.ts +41 -3
  77. package/dist/sessions/background-tasks.js +110 -10
  78. package/dist/sessions/background-tasks.js.map +1 -1
  79. package/dist/sessions/cli-sessions.d.ts +9 -2
  80. package/dist/sessions/cli-sessions.js +38 -57
  81. package/dist/sessions/cli-sessions.js.map +1 -1
  82. package/dist/sessions/completions.d.ts +8 -0
  83. package/dist/sessions/completions.js +55 -25
  84. package/dist/sessions/completions.js.map +1 -1
  85. package/dist/sessions/events.d.ts +3 -0
  86. package/dist/sessions/events.js +4 -0
  87. package/dist/sessions/events.js.map +1 -1
  88. package/dist/sessions/export.d.ts +2 -0
  89. package/dist/sessions/export.js +6 -2
  90. package/dist/sessions/export.js.map +1 -1
  91. package/dist/sessions/gateway-sessions.d.ts +92 -4
  92. package/dist/sessions/gateway-sessions.js +762 -93
  93. package/dist/sessions/gateway-sessions.js.map +1 -1
  94. package/dist/sessions/gateway-watcher.d.ts +10 -11
  95. package/dist/sessions/gateway-watcher.js +25 -21
  96. package/dist/sessions/gateway-watcher.js.map +1 -1
  97. package/dist/sessions/list.d.ts +9 -2
  98. package/dist/sessions/list.js +38 -26
  99. package/dist/sessions/list.js.map +1 -1
  100. package/dist/sessions/merge.d.ts +12 -5
  101. package/dist/sessions/merge.js +65 -18
  102. package/dist/sessions/merge.js.map +1 -1
  103. package/dist/sessions/prefix-index.d.ts +15 -4
  104. package/dist/sessions/prefix-index.js +35 -13
  105. package/dist/sessions/prefix-index.js.map +1 -1
  106. package/dist/sessions/prompt-queues.d.ts +36 -0
  107. package/dist/sessions/prompt-queues.js +318 -0
  108. package/dist/sessions/prompt-queues.js.map +1 -0
  109. package/dist/sessions/recovery.d.ts +1 -1
  110. package/dist/sessions/recovery.js +4 -3
  111. package/dist/sessions/recovery.js.map +1 -1
  112. package/dist/sessions/relay.d.ts +12 -1
  113. package/dist/sessions/relay.js +75 -17
  114. package/dist/sessions/relay.js.map +1 -1
  115. package/dist/sessions/service.d.ts +132 -37
  116. package/dist/sessions/service.js +688 -160
  117. package/dist/sessions/service.js.map +1 -1
  118. package/dist/sessions/session.d.ts +2 -0
  119. package/dist/sessions/session.js +5 -0
  120. package/dist/sessions/session.js.map +1 -1
  121. package/dist/sessions/state-db-worker.js +22 -5
  122. package/dist/sessions/state-db-worker.js.map +1 -1
  123. package/dist/sessions/state-db.d.ts +106 -15
  124. package/dist/sessions/state-db.js +651 -236
  125. package/dist/sessions/state-db.js.map +1 -1
  126. package/dist/sessions/state-saved.d.ts +1 -1
  127. package/dist/sessions/state-saved.js +35 -11
  128. package/dist/sessions/state-saved.js.map +1 -1
  129. package/dist/sessions/storage/backend.d.ts +10 -1
  130. package/dist/sessions/storage/backend.js.map +1 -1
  131. package/dist/sessions/storage/conformance.js +1 -1
  132. package/dist/sessions/storage/conformance.js.map +1 -1
  133. package/dist/sessions/storage/json-documents.d.ts +2 -0
  134. package/dist/sessions/storage/json-documents.js +71 -26
  135. package/dist/sessions/storage/json-documents.js.map +1 -1
  136. package/dist/sessions/storage/json-files.d.ts +13 -2
  137. package/dist/sessions/storage/json-files.js +126 -6
  138. package/dist/sessions/storage/json-files.js.map +1 -1
  139. package/dist/sessions/storage/json-journal.d.ts +6 -7
  140. package/dist/sessions/storage/json-journal.js +143 -73
  141. package/dist/sessions/storage/json-journal.js.map +1 -1
  142. package/dist/sessions/storage/json.d.ts +15 -1
  143. package/dist/sessions/storage/json.js +125 -33
  144. package/dist/sessions/storage/json.js.map +1 -1
  145. package/dist/sessions/store.d.ts +6 -1
  146. package/dist/sessions/store.js +68 -27
  147. package/dist/sessions/store.js.map +1 -1
  148. package/dist/sessions/streams.d.ts +10 -7
  149. package/dist/sessions/streams.js +49 -14
  150. package/dist/sessions/streams.js.map +1 -1
  151. package/dist/sessions/tool-display.d.ts +11 -2
  152. package/dist/sessions/tool-display.js +45 -4
  153. package/dist/sessions/tool-display.js.map +1 -1
  154. package/dist/sessions/turn-context.js +6 -2
  155. package/dist/sessions/turn-context.js.map +1 -1
  156. package/dist/sessions/turn.d.ts +27 -6
  157. package/dist/sessions/turn.js +186 -89
  158. package/dist/sessions/turn.js.map +1 -1
  159. package/dist/sidecar/client.d.ts +24 -1
  160. package/dist/sidecar/client.js +118 -38
  161. package/dist/sidecar/client.js.map +1 -1
  162. package/dist/sidecar/fake.d.ts +6 -2
  163. package/dist/sidecar/fake.js +15 -2
  164. package/dist/sidecar/fake.js.map +1 -1
  165. package/dist/spa.d.ts +9 -4
  166. package/dist/spa.js +36 -12
  167. package/dist/spa.js.map +1 -1
  168. package/dist/startup-timing.d.ts +66 -0
  169. package/dist/startup-timing.js +129 -0
  170. package/dist/startup-timing.js.map +1 -0
  171. package/dist/test/fs-handles.d.ts +11 -0
  172. package/dist/test/fs-handles.js +31 -0
  173. package/dist/test/fs-handles.js.map +1 -0
  174. package/dist/tools/connectors.d.ts +1 -1
  175. package/dist/tools/connectors.js +2 -2
  176. package/dist/tools/connectors.js.map +1 -1
  177. package/dist/tools/crons.d.ts +8 -4
  178. package/dist/tools/crons.js +25 -18
  179. package/dist/tools/crons.js.map +1 -1
  180. package/dist/tools/dashboard-plugins.d.ts +29 -0
  181. package/dist/tools/dashboard-plugins.js +132 -0
  182. package/dist/tools/dashboard-plugins.js.map +1 -1
  183. package/dist/tools/gateway-restart.d.ts +25 -5
  184. package/dist/tools/gateway-restart.js +103 -23
  185. package/dist/tools/gateway-restart.js.map +1 -1
  186. package/dist/tools/health.d.ts +13 -1
  187. package/dist/tools/health.js +80 -22
  188. package/dist/tools/health.js.map +1 -1
  189. package/dist/tools/insights.d.ts +1 -1
  190. package/dist/tools/insights.js +2 -2
  191. package/dist/tools/insights.js.map +1 -1
  192. package/dist/tools/kanban.d.ts +10 -1
  193. package/dist/tools/kanban.js +73 -1
  194. package/dist/tools/kanban.js.map +1 -1
  195. package/dist/tools/mcp-health.js +74 -24
  196. package/dist/tools/mcp-health.js.map +1 -1
  197. package/dist/tools/mcp.d.ts +3 -1
  198. package/dist/tools/mcp.js +92 -1
  199. package/dist/tools/mcp.js.map +1 -1
  200. package/dist/tools/memory.d.ts +28 -0
  201. package/dist/tools/memory.js +120 -14
  202. package/dist/tools/memory.js.map +1 -1
  203. package/dist/tools/plugin-oauth.d.ts +14 -0
  204. package/dist/tools/plugin-oauth.js +53 -0
  205. package/dist/tools/plugin-oauth.js.map +1 -0
  206. package/dist/tools/prune-advice.d.ts +50 -0
  207. package/dist/tools/prune-advice.js +114 -0
  208. package/dist/tools/prune-advice.js.map +1 -0
  209. package/dist/tools/skills.d.ts +5 -2
  210. package/dist/tools/skills.js +9 -6
  211. package/dist/tools/skills.js.map +1 -1
  212. package/dist/tools/update-notifications.d.ts +77 -9
  213. package/dist/tools/update-notifications.js +390 -46
  214. package/dist/tools/update-notifications.js.map +1 -1
  215. package/dist/tools/updates.d.ts +29 -3
  216. package/dist/tools/updates.js +166 -34
  217. package/dist/tools/updates.js.map +1 -1
  218. package/dist/workspace/managed-buffers.d.ts +58 -0
  219. package/dist/workspace/managed-buffers.js +76 -0
  220. package/dist/workspace/managed-buffers.js.map +1 -0
  221. package/dist/workspace/media.js +69 -20
  222. package/dist/workspace/media.js.map +1 -1
  223. package/dist/workspace/preview.js +4 -14
  224. package/dist/workspace/preview.js.map +1 -1
  225. package/dist/workspace/rollback.d.ts +6 -2
  226. package/dist/workspace/rollback.js +18 -8
  227. package/dist/workspace/rollback.js.map +1 -1
  228. package/package.json +3 -3
  229. package/sidecar/agent_dependency.json +4 -4
  230. package/sidecar/agent_support.json +30 -15
  231. package/sidecar/scripts/suite_runner.py +183 -27
  232. package/sidecar/scripts/test.sh +5 -7
  233. package/sidecar/talaria_sidecar/__init__.py +1 -1
  234. package/sidecar/talaria_sidecar/__main__.py +10 -3
  235. package/sidecar/talaria_sidecar/agent_mutation.py +246 -32
  236. package/sidecar/talaria_sidecar/agent_services.py +157 -34
  237. package/sidecar/talaria_sidecar/context_detail.py +59 -0
  238. package/sidecar/talaria_sidecar/home.py +97 -20
  239. package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
  240. package/sidecar/talaria_sidecar/methods/aux.py +80 -18
  241. package/sidecar/talaria_sidecar/methods/chat.py +571 -106
  242. package/sidecar/talaria_sidecar/methods/checkpoints.py +29 -4
  243. package/sidecar/talaria_sidecar/methods/commands.py +277 -16
  244. package/sidecar/talaria_sidecar/methods/config.py +73 -3
  245. package/sidecar/talaria_sidecar/methods/connectors.py +45 -13
  246. package/sidecar/talaria_sidecar/methods/cron.py +8 -2
  247. package/sidecar/talaria_sidecar/methods/dashboard_plugins.py +301 -0
  248. package/sidecar/talaria_sidecar/methods/gateway.py +24 -4
  249. package/sidecar/talaria_sidecar/methods/gateway_sessions.py +304 -30
  250. package/sidecar/talaria_sidecar/methods/kanban.py +50 -3
  251. package/sidecar/talaria_sidecar/methods/managed_buffers.py +110 -0
  252. package/sidecar/talaria_sidecar/methods/mcp.py +55 -0
  253. package/sidecar/talaria_sidecar/methods/oauth.py +139 -11
  254. package/sidecar/talaria_sidecar/methods/outbound_drafts.py +165 -0
  255. package/sidecar/talaria_sidecar/methods/plugin_catalog.py +198 -0
  256. package/sidecar/talaria_sidecar/methods/plugin_oauth.py +234 -0
  257. package/sidecar/talaria_sidecar/methods/process.py +70 -6
  258. package/sidecar/talaria_sidecar/methods/profiles.py +4 -3
  259. package/sidecar/talaria_sidecar/methods/runtime.py +2 -0
  260. package/sidecar/talaria_sidecar/methods/skills.py +22 -7
  261. package/sidecar/talaria_sidecar/methods/state_db.py +128 -42
  262. package/sidecar/talaria_sidecar/methods/toolsets.py +4 -2
  263. package/sidecar/talaria_sidecar/methods/worktree.py +121 -2
  264. package/sidecar/talaria_sidecar/rpc.py +25 -3
  265. package/sidecar/talaria_sidecar/runtime.py +42 -3
  266. package/sidecar/talaria_sidecar/speed.py +13 -1
  267. package/sidecar/talaria_sidecar/startup_timing.py +119 -0
  268. package/static/dist/FILES.txt +240 -213
  269. package/static/dist/THIRD_PARTY_LICENSES.md +6 -22
  270. package/static/dist/assets/AppShell-c5989995.js +8 -0
  271. package/static/dist/assets/Button-nuaikybd.js +1 -0
  272. package/static/dist/assets/ChatPage-bfg4khph.js +6 -0
  273. package/static/dist/assets/ConnectTargets-k5wo9yo8.js +1 -0
  274. package/static/dist/assets/Dialog-o8vo2aws.js +1 -0
  275. package/static/dist/assets/ExtensionRoute-l1yjrso4.js +1 -0
  276. package/static/dist/assets/Field-j7o8cfps.js +1 -0
  277. package/static/dist/assets/HubRoute-efnwe4xz.js +2 -0
  278. package/static/dist/assets/LinkCheckContext-ix6zqqkk.js +1 -0
  279. package/static/dist/assets/Markdown-clqf5m22.js +2 -0
  280. package/static/dist/assets/MarkdownRenderer-ccgqrza3.js +302 -0
  281. package/static/dist/assets/MarkdownRenderer-i9o6nr38.css +1 -0
  282. package/static/dist/assets/OAuthSignIn-h7bjaqp6.js +1 -0
  283. package/static/dist/assets/ResourceSwitch-oai2zqaj.js +1 -0
  284. package/static/dist/assets/RightPanel-ho161a45.js +1 -0
  285. package/static/dist/assets/Select-d1g5a8bm.js +1 -0
  286. package/static/dist/assets/SessionListPanel-i7kaokhi.js +1 -0
  287. package/static/dist/assets/SettingsLayout-lnecm87w.js +1 -0
  288. package/static/dist/assets/States-easntmry.js +1 -0
  289. package/static/dist/assets/TerminalPanel-lxhwd4jl.js +16 -0
  290. package/static/dist/assets/Toaster-l4sciy8t.js +1 -0
  291. package/static/dist/assets/_app-mqexqbg8.js +1 -0
  292. package/static/dist/assets/_app.ext._extensionId-n797jp72.js +1 -0
  293. package/static/dist/assets/_app.index-ne43mdw2.js +1 -0
  294. package/static/dist/assets/_app.insights-fqonovb4.js +1 -0
  295. package/static/dist/assets/_app.kanban-kysliv19.js +1 -0
  296. package/static/dist/assets/_app.logs-febut82r.js +1 -0
  297. package/static/dist/assets/_app.memory-ha86oj1c.js +1 -0
  298. package/static/dist/assets/_app.profiles-cnu3gxxq.js +1 -0
  299. package/static/dist/assets/_app.session._sessionId-ifzjpcgn.js +1 -0
  300. package/static/dist/assets/_app.settings-nmakdiaf.js +1 -0
  301. package/static/dist/assets/_app.settings._section-djglnjmi.js +3 -0
  302. package/static/dist/assets/_app.skills-f3wad8yo.js +1 -0
  303. package/static/dist/assets/_app.tasks-l10py1c0.js +1 -0
  304. package/static/dist/assets/_app.todos-bml1m3r1.js +1 -0
  305. package/static/dist/assets/_app.workspaces-f3d066lx.js +1 -0
  306. package/static/dist/assets/abnfDiagram-VCTEODGH-i53jc4yp.js +1 -0
  307. package/static/dist/assets/{angular-html-nu6l31w3.js → angular-html-l28bd5fo.js} +1 -1
  308. package/static/dist/assets/{angular-ts-fbx4f8mm.js → angular-ts-ffzx1vj0.js} +1 -1
  309. package/static/dist/assets/{apl-bx2xr7dh.js → apl-b7h7mmy4.js} +1 -1
  310. package/static/dist/assets/{arc-7popfhbk.js → arc-fk1b21lm.js} +1 -1
  311. package/static/dist/assets/architecture-7GRP2DOG-e3bv5m6f.js +1 -0
  312. package/static/dist/assets/architectureDiagram-5GKGNRK7-pakekxu2.js +36 -0
  313. package/static/dist/assets/archive-ihqi7z2x.js +1 -0
  314. package/static/dist/assets/{astro-g77i97cb.js → astro-k117fy0t.js} +1 -1
  315. package/static/dist/assets/back-gu3nu279.js +1 -0
  316. package/static/dist/assets/{blade-boo0u92y.js → blade-npefsmn8.js} +1 -1
  317. package/static/dist/assets/{blockDiagram-I7D4REHJ-joedghi3.js → blockDiagram-I7D4REHJ-bc6bo1n6.js} +4 -4
  318. package/static/dist/assets/{c-cat0w3sc.js → c-2umg6kbn.js} +1 -1
  319. package/static/dist/assets/{c4Diagram-7LVT6UL2-hyrjrohe.js → c4Diagram-7LVT6UL2-btvwk2qx.js} +1 -1
  320. package/static/dist/assets/channel-jn4f8443.js +1 -0
  321. package/static/dist/assets/{chunk-4HAMMTFA-koouqbut.js → chunk-4HAMMTFA-dlwab11c.js} +20 -20
  322. package/static/dist/assets/{chunk-75Z2AOVW-bl4bhdnt.js → chunk-75Z2AOVW-dp5gh7i8.js} +1 -1
  323. package/static/dist/assets/chunk-DU6HZSFF-bi06zl1c.js +128 -0
  324. package/static/dist/assets/{chunk-F27PBJKO-d8xxi0zi.js → chunk-F27PBJKO-kvv1rnlh.js} +1 -1
  325. package/static/dist/assets/{chunk-FOHPRMQF-opuflp73.js → chunk-FOHPRMQF-ipewusgj.js} +8 -8
  326. package/static/dist/assets/{chunk-GMAD6QVW-jro0hl73.js → chunk-GMAD6QVW-ji0rx9by.js} +6 -6
  327. package/static/dist/assets/{chunk-GVQU2GXP-djn6gbyu.js → chunk-GVQU2GXP-nmz0j82p.js} +1 -1
  328. package/static/dist/assets/{chunk-IMKFNOWR-vw4p5p7o.js → chunk-IMKFNOWR-kmi1qx88.js} +5 -5
  329. package/static/dist/assets/{chunk-L3NEJ4N5-n1hj77q8.js → chunk-L3NEJ4N5-xhb7mebj.js} +1 -1
  330. package/static/dist/assets/chunk-OSK3NFVY-5a9sgscq.js +10 -0
  331. package/static/dist/assets/{chunk-P2QGCYS3-onf1hz6c.js → chunk-P2QGCYS3-dfezp4vu.js} +1 -1
  332. package/static/dist/assets/{chunk-POPQ4Y6H-m8sqn7cs.js → chunk-POPQ4Y6H-gd2vq3c0.js} +1 -1
  333. package/static/dist/assets/{chunk-PWAF6VOD-ek4smc8x.js → chunk-PWAF6VOD-wvw2nksf.js} +1 -1
  334. package/static/dist/assets/{chunk-SHT3W25Y-g9gfvefo.js → chunk-SHT3W25Y-f58q97px.js} +13 -13
  335. package/static/dist/assets/{chunk-SVP7TREG-f9nfv2cu.js → chunk-SVP7TREG-abgwpyz9.js} +4 -4
  336. package/static/dist/assets/{chunk-TICWLB2K-bnk3m1mq.js → chunk-TICWLB2K-h4sbs8ds.js} +6 -6
  337. package/static/dist/assets/{chunk-XXDRQBXY-n40pf9vy.js → chunk-XXDRQBXY-jkmnqu65.js} +1 -1
  338. package/static/dist/assets/classDiagram-ZZMXUADV-dzrw66se.js +1 -0
  339. package/static/dist/assets/classDiagram-v2-VYDZK3BY-dzrw66se.js +1 -0
  340. package/static/dist/assets/{cobol-go622aep.js → cobol-ssf9hkh7.js} +1 -1
  341. package/static/dist/assets/{coffee-jwo1xjhq.js → coffee-lsi9fwae.js} +1 -1
  342. package/static/dist/assets/completionAudio-ce86msbu.js +1 -0
  343. package/static/dist/assets/copied-bz3gkazh.js +1 -0
  344. package/static/dist/assets/copy-m9h56qa8.js +1 -0
  345. package/static/dist/assets/cose-bilkent-JH36ORCC-layy2r27.js +1 -0
  346. package/static/dist/assets/{cpp-nre7j0kq.js → cpp-lfrh4y55.js} +1 -1
  347. package/static/dist/assets/{crystal-lviso2je.js → crystal-efh4pte7.js} +1 -1
  348. package/static/dist/assets/{css-ywz9j4hb.js → css-i82qdo89.js} +1 -1
  349. package/static/dist/assets/cynefin-OW5HDTMX-g081vffs.js +1 -0
  350. package/static/dist/assets/cynefinDiagram-5FMLGOSQ-odxvjesk.js +62 -0
  351. package/static/dist/assets/cytoscape.esm-fjn2algp.js +321 -0
  352. package/static/dist/assets/dagre-GXQ25YYZ-cpdwzjs4.js +4 -0
  353. package/static/dist/assets/dagre-o5jmjz46.js +1 -0
  354. package/static/dist/assets/{diagram-S7CK7UJ4-m6aeoe7c.js → diagram-S7CK7UJ4-clv5mxvu.js} +4 -4
  355. package/static/dist/assets/diagram-UQ7AKVKN-m2ia1mbf.js +41 -0
  356. package/static/dist/assets/{diagram-VSXAHHWV-hbawi7hn.js → diagram-VSXAHHWV-ea6zv636.js} +1 -1
  357. package/static/dist/assets/diagram-VX7I27RA-oqlef685.js +24 -0
  358. package/static/dist/assets/diagram-Z3DM3KII-kjubcbwu.js +24 -0
  359. package/static/dist/assets/dist-carq1azj.js +44 -0
  360. package/static/dist/assets/dist-crc46di9.js +7 -0
  361. package/static/dist/assets/{dist-c4c2m3kv.js → dist-nb670eu6.js} +1 -1
  362. package/static/dist/assets/ebnfDiagram-PWID7BFC-fg0zri3e.js +1 -0
  363. package/static/dist/assets/{edge-dvv35byi.js → edge-lrob635n.js} +1 -1
  364. package/static/dist/assets/{elixir-i2f1ki1g.js → elixir-kdpxeq93.js} +1 -1
  365. package/static/dist/assets/{elm-cpepyjm4.js → elm-c8irj9uh.js} +1 -1
  366. package/static/dist/assets/erDiagram-RLTQ6QDP-eb7pmk3x.js +99 -0
  367. package/static/dist/assets/{erb-idlyfheg.js → erb-flwsv146.js} +1 -1
  368. package/static/dist/assets/eventmodeling-NTZA5JFV-gvi1fxhn.js +1 -0
  369. package/static/dist/assets/flowDiagram-HODETNUW-abekab15.js +1 -0
  370. package/static/dist/assets/folder-plus-ksaons88.js +1 -0
  371. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-ma6jxj5i.js → ganttDiagram-EL5Y4UJY-jmisowrc.js} +1 -1
  372. package/static/dist/assets/{git-rebase-d9lpfpbn.js → git-rebase-bli19aoq.js} +1 -1
  373. package/static/dist/assets/gitGraph-4MIJSDKK-m7kt3u6e.js +1 -0
  374. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-hzltvsod.js → gitGraphDiagram-WWUBYQGX-nq7vfzh2.js} +1 -1
  375. package/static/dist/assets/{glimmer-js-39i0urfb.js → glimmer-js-d4icg38p.js} +1 -1
  376. package/static/dist/assets/{glimmer-ts-gdtd6n73.js → glimmer-ts-bk75772u.js} +1 -1
  377. package/static/dist/assets/{glsl-o1djm5pp.js → glsl-lqormp2b.js} +1 -1
  378. package/static/dist/assets/{graphql-kj6rz55t.js → graphql-hw6s5qzd.js} +1 -1
  379. package/static/dist/assets/{hack-pe1qqr2i.js → hack-ozrv6l4d.js} +1 -1
  380. package/static/dist/assets/{haml-cknnbcqs.js → haml-gytfosdt.js} +1 -1
  381. package/static/dist/assets/{handlebars-hwq64orh.js → handlebars-b6g7jffd.js} +1 -1
  382. package/static/dist/assets/highlighted-body-KPVGNVTW-gcu017ay.js +1 -0
  383. package/static/dist/assets/host-ipp4e84c.js +1 -0
  384. package/static/dist/assets/{html-derivative-h2i2pyjc.js → html-derivative-f1tqcroo.js} +1 -1
  385. package/static/dist/assets/{html-ha05xtvt.js → html-on6oj6yj.js} +1 -1
  386. package/static/dist/assets/{http-cf94zu27.js → http-odhufsl7.js} +1 -1
  387. package/static/dist/assets/{hurl-lslax568.js → hurl-mu680336.js} +1 -1
  388. package/static/dist/assets/index-d6vbxlra.js +13 -0
  389. package/static/dist/assets/index-ey6qo0zx.css +2 -0
  390. package/static/dist/assets/info-A6RAGUB7-idazwfqe.js +1 -0
  391. package/static/dist/assets/infoDiagram-27XIBGKW-bb9jh8gl.js +2 -0
  392. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-e7bnwq7h.js → ishikawaDiagram-5VMMS53U-nqc132rv.js} +6 -6
  393. package/static/dist/assets/{java-ndjf2o89.js → java-nxbe8uju.js} +1 -1
  394. package/static/dist/assets/{javascript-coftlwy3.js → javascript-lz3kxcyz.js} +1 -1
  395. package/static/dist/assets/{jinja-etei9wy7.js → jinja-l5pk84gt.js} +1 -1
  396. package/static/dist/assets/{jison-hyekgft1.js → jison-jdutdwyy.js} +1 -1
  397. package/static/dist/assets/{journeyDiagram-3NMN7TZE-etd1bi6p.js → journeyDiagram-3NMN7TZE-fpvnhy44.js} +1 -1
  398. package/static/dist/assets/{json-lok0yaho.js → json-dnge4ssf.js} +1 -1
  399. package/static/dist/assets/{jsx-b64w0nbx.js → jsx-c3lwhkep.js} +1 -1
  400. package/static/dist/assets/{jsx-runtime-eu92a5pu.js → jsx-runtime-o40ukmjl.js} +1 -1
  401. package/static/dist/assets/{julia-jxxzz2yn.js → julia-hwd4rrcb.js} +1 -1
  402. package/static/dist/assets/{just-mc29iw9t.js → just-nka3oxdx.js} +1 -1
  403. package/static/dist/assets/{kanban-definition-UXKFOSKX-emb1g9dz.js → kanban-definition-UXKFOSKX-ndzqm6fu.js} +28 -28
  404. package/static/dist/assets/katex-cbdd1ohw.css +1 -0
  405. package/static/dist/assets/katex-pbij2oo6.js +257 -0
  406. package/static/dist/assets/{latex-pafa03ft.js → latex-iqmr7e40.js} +1 -1
  407. package/static/dist/assets/lazyRouteComponent-javud235.js +1 -0
  408. package/static/dist/assets/{line-h0ojzsvs.js → line-g625e7cj.js} +1 -1
  409. package/static/dist/assets/linear-jlwrvvy6.js +1 -0
  410. package/static/dist/assets/link-gfdaho08.js +2 -0
  411. package/static/dist/assets/{liquid-hz5c2pov.js → liquid-okmk9tbp.js} +1 -1
  412. package/static/dist/assets/locale-cs-n41hptse.js +5 -0
  413. package/static/dist/assets/locale-de-k7ht47ew.js +5 -0
  414. package/static/dist/assets/locale-es-ih078lco.js +5 -0
  415. package/static/dist/assets/locale-fr-ojabnf41.js +5 -0
  416. package/static/dist/assets/locale-it-kb96jufy.js +5 -0
  417. package/static/dist/assets/locale-ja-jpsp3xs1.js +7 -0
  418. package/static/dist/assets/locale-ko-cpzuy0n7.js +5 -0
  419. package/static/dist/assets/locale-pl-dbap4leu.js +5 -0
  420. package/static/dist/assets/locale-pt-nci7w72x.js +5 -0
  421. package/static/dist/assets/locale-ru-soghe4cs.js +7 -0
  422. package/static/dist/assets/locale-tr-ks00mu68.js +5 -0
  423. package/static/dist/assets/locale-vi-ij7twfm6.js +5 -0
  424. package/static/dist/assets/locale-zh-Hant-feakwr7a.js +5 -0
  425. package/static/dist/assets/locale-zh-ren0vjyv.js +7 -0
  426. package/static/dist/assets/login-iv6yq4xf.js +1 -0
  427. package/static/dist/assets/{lua-leyf8mlb.js → lua-krx4xj5h.js} +1 -1
  428. package/static/dist/assets/{marko-cn1fzpdv.js → marko-gbvpfehz.js} +1 -1
  429. package/static/dist/assets/{mdc-huhy88df.js → mdc-c21zlyi5.js} +1 -1
  430. package/static/dist/assets/mermaid-HWGCJPDP-cwj5cl6k.js +1 -0
  431. package/static/dist/assets/mermaid-parser.core-plzkuzov.js +7 -0
  432. package/static/dist/assets/micromark-factory-space-fnmnpi6s.js +1 -0
  433. package/static/dist/assets/{mindmap-definition-YA3MSWOX-o1vathns.js → mindmap-definition-YA3MSWOX-ojrgs569.js} +28 -28
  434. package/static/dist/assets/{nginx-e7lvhsmn.js → nginx-f3d68ed4.js} +1 -1
  435. package/static/dist/assets/{nim-dun5d8mk.js → nim-dw0jcy70.js} +1 -1
  436. package/static/dist/assets/onboarding-ff4emacu.js +1 -0
  437. package/static/dist/assets/packet-AYTQ26CC-gyaf9s8h.js +1 -0
  438. package/static/dist/assets/pegDiagram-XKGWAZYB-bf6xj8mq.js +1 -0
  439. package/static/dist/assets/{perl-bj3oqtet.js → perl-3c0r45c8.js} +1 -1
  440. package/static/dist/assets/{php-buzp12r0.js → php-rznhidvp.js} +1 -1
  441. package/static/dist/assets/pie-WAS4IAKB-f5ymzelo.js +1 -0
  442. package/static/dist/assets/pieDiagram-E7YTZNPT-d0qjl3zi.js +39 -0
  443. package/static/dist/assets/{pug-mjad7he9.js → pug-f2le4f3y.js} +1 -1
  444. package/static/dist/assets/{qml-d1gdp10s.js → qml-e2wbq9cr.js} +1 -1
  445. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-owqc4uqn.js → quadrantDiagram-AXDQQJYC-oqy1mras.js} +1 -1
  446. package/static/dist/assets/queryKeys-x8fjxhut.js +9 -0
  447. package/static/dist/assets/{r-o3r9c7ao.js → r-epfzuw6q.js} +1 -1
  448. package/static/dist/assets/radar-RG4KPBEZ-b6jcjvda.js +1 -0
  449. package/static/dist/assets/railroad-74A4TZTK-e3a6lk5k.js +1 -0
  450. package/static/dist/assets/railroad-abnf-HS5TGJTU-ff5hocrx.js +1 -0
  451. package/static/dist/assets/railroad-ebnf-LZEXJU2U-exkhyw4n.js +1 -0
  452. package/static/dist/assets/railroad-peg-WCYAUIDC-jefk9b7c.js +1 -0
  453. package/static/dist/assets/railroadDiagram-O6MQD6OU-e4amks1i.js +1 -0
  454. package/static/dist/assets/{razor-ilc585yr.js → razor-pea1u1d0.js} +1 -1
  455. package/static/dist/assets/refresh-cw-lfp4u1oh.js +1 -0
  456. package/static/dist/assets/{regexp-mpjtcvwm.js → regexp-hzte0a5x.js} +1 -1
  457. package/static/dist/assets/registry-g7w3353u.js +1 -0
  458. package/static/dist/assets/requirementDiagram-BXWQKSXE-c77k1e2y.js +84 -0
  459. package/static/dist/assets/rolldown-runtime-bnnw9q4a.js +1 -0
  460. package/static/dist/assets/{rst-jrkwjdyi.js → rst-m6tugj5o.js} +1 -1
  461. package/static/dist/assets/{ruby-n4tjcbpz.js → ruby-l19vq3w1.js} +1 -1
  462. package/static/dist/assets/runtime-nlxpnegr.js +1 -0
  463. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-iqc02emv.js → sankeyDiagram-P5KCCOFB-oa1cc52s.js} +1 -1
  464. package/static/dist/assets/{sas-hjo6y93k.js → sas-ktdxo397.js} +1 -1
  465. package/static/dist/assets/{scss-ncidjv48.js → scss-kn3oxfwf.js} +1 -1
  466. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-i0v116q0.js → sequenceDiagram-WJ2MYXX4-j20gqt22.js} +11 -11
  467. package/static/dist/assets/settings_section_extensions_title-fadc7o65.js +1 -0
  468. package/static/dist/assets/share._token-kmfoflw6.js +2 -0
  469. package/static/dist/assets/{shellscript-m8whjpqd.js → shellscript-l100jtrg.js} +1 -1
  470. package/static/dist/assets/{shellsession-i5bj6syz.js → shellsession-m5qukwow.js} +1 -1
  471. package/static/dist/assets/sizeCapture-INFHLROL-dk1io13w.js +1 -0
  472. package/static/dist/assets/sliders-horizontal-g5jkzd9k.js +1 -0
  473. package/static/dist/assets/{soy-hhh36ysq.js → soy-mexlscur.js} +1 -1
  474. package/static/dist/assets/{sql-j21bzcl6.js → sql-o0ho5suh.js} +1 -1
  475. package/static/dist/assets/src-h89s0hs4.js +1 -0
  476. package/static/dist/assets/{stata-bbu2onh1.js → stata-be9ck1q3.js} +1 -1
  477. package/static/dist/assets/stateDiagram-D77RDMKH-co2ghkdp.js +1 -0
  478. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-faw1opgh.js +1 -0
  479. package/static/dist/assets/{surrealql-l5vczuco.js → surrealql-gk1xkkyy.js} +1 -1
  480. package/static/dist/assets/{svelte-idn422g6.js → svelte-k6ecjilf.js} +1 -1
  481. package/static/dist/assets/swimlanes-42K2YHIH-m30cktqe.js +1 -0
  482. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-hfil433g.js +8 -0
  483. package/static/dist/assets/{templ-e22qou3c.js → templ-gf3bftk6.js} +1 -1
  484. package/static/dist/assets/{tex-deqpc5ee.js → tex-d21fqv1z.js} +1 -1
  485. package/static/dist/assets/{timeline-definition-24CTP7MA-ol2hnvma.js → timeline-definition-24CTP7MA-liuep6fl.js} +8 -8
  486. package/static/dist/assets/toast-zmb35u3r.js +56 -0
  487. package/static/dist/assets/treeView-Q6P3EWNA-np5d2jv2.js +1 -0
  488. package/static/dist/assets/treemap-WGGIJYW6-cmpltxh1.js +1 -0
  489. package/static/dist/assets/{ts-tags-ctnibc27.js → ts-tags-n0g61gr6.js} +1 -1
  490. package/static/dist/assets/{tsx-i163n32g.js → tsx-cvv7wv6q.js} +1 -1
  491. package/static/dist/assets/{twig-x0fi7wm8.js → twig-n1f67204.js} +1 -1
  492. package/static/dist/assets/{typescript-g18c34xz.js → typescript-og7o55cx.js} +1 -1
  493. package/static/dist/assets/untitled-mj86r4gz.js +1 -0
  494. package/static/dist/assets/useDebounced-g8r0ggve.js +1 -0
  495. package/static/dist/assets/useForm-f1udzsjf.js +1 -0
  496. package/static/dist/assets/{useParams-gjc70qru.js → useParams-ierevvts.js} +1 -1
  497. package/static/dist/assets/{useSearch-e6ae539u.js → useSearch-i7nr9ypl.js} +1 -1
  498. package/static/dist/assets/vennDiagram-4TSXK5OY-b2g42qrg.js +34 -0
  499. package/static/dist/assets/{vue-mwu5l1bb.js → vue-ej4xpwqw.js} +1 -1
  500. package/static/dist/assets/{vue-html-nskj3du0.js → vue-html-d48xsjuo.js} +1 -1
  501. package/static/dist/assets/{vue-vine-cqe77smq.js → vue-vine-pev88ip6.js} +1 -1
  502. package/static/dist/assets/wardley-WFR3VGLG-lb0eqbff.js +1 -0
  503. package/static/dist/assets/wardleyDiagram-VM6X3IG4-ermwaqha.js +78 -0
  504. package/static/dist/assets/with-selector-nu1b5z0v.js +1 -0
  505. package/static/dist/assets/{xml-gau7gvrv.js → xml-ifxp6gqb.js} +1 -1
  506. package/static/dist/assets/{xsl-ew09zq8b.js → xsl-fug2cckc.js} +1 -1
  507. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-aqbgvujg.js → xychartDiagram-S5SC5T6Z-dll0jldk.js} +6 -6
  508. package/static/dist/assets/{yaml-ofnrxtvf.js → yaml-fjmafnlo.js} +1 -1
  509. package/static/dist/extension-sdk.js +1 -1
  510. package/static/dist/index.html +1 -1
  511. package/static/dist/sw.js +180 -136
  512. package/static/dist/assets/AppShell-cey33v9s.js +0 -8
  513. package/static/dist/assets/ChatPage-i8wnugr7.js +0 -18
  514. package/static/dist/assets/ConnectTargets-hg19553x.js +0 -1
  515. package/static/dist/assets/ExtensionRoute-cly4apm5.js +0 -1
  516. package/static/dist/assets/Field-j8uqoigz.js +0 -9
  517. package/static/dist/assets/HubRoute-e4bgz41j.js +0 -2
  518. package/static/dist/assets/Markdown-lahuichm.js +0 -598
  519. package/static/dist/assets/Markdown-lwviulmg.css +0 -1
  520. package/static/dist/assets/RightPanel-lbo4i0fn.js +0 -1
  521. package/static/dist/assets/Select-gqatm2e0.js +0 -1
  522. package/static/dist/assets/SessionListPanel-mfqayfjh.js +0 -1
  523. package/static/dist/assets/SettingsLayout-b8980u7k.js +0 -1
  524. package/static/dist/assets/States-e7dkgtxf.js +0 -1
  525. package/static/dist/assets/Toaster-bfqqy786.js +0 -1
  526. package/static/dist/assets/_app-n1n6pfx1.js +0 -1
  527. package/static/dist/assets/_app.ext._extensionId-buxjxav3.js +0 -1
  528. package/static/dist/assets/_app.index-jt8zwiu2.js +0 -1
  529. package/static/dist/assets/_app.insights-cv76ml71.js +0 -1
  530. package/static/dist/assets/_app.kanban-h6ts53j7.js +0 -1
  531. package/static/dist/assets/_app.logs-dm873z90.js +0 -1
  532. package/static/dist/assets/_app.memory-glk5y6m8.js +0 -1
  533. package/static/dist/assets/_app.profiles-ka6zpstq.js +0 -1
  534. package/static/dist/assets/_app.session._sessionId-g2vzghvc.js +0 -1
  535. package/static/dist/assets/_app.settings-hgjdhzcd.js +0 -1
  536. package/static/dist/assets/_app.settings._section-jf2kmhae.js +0 -3
  537. package/static/dist/assets/_app.skills-cii852yq.js +0 -1
  538. package/static/dist/assets/_app.tasks-fp9q7atm.js +0 -1
  539. package/static/dist/assets/_app.todos-dw94qzue.js +0 -1
  540. package/static/dist/assets/_app.workspaces-inyygzze.js +0 -1
  541. package/static/dist/assets/abnfDiagram-VCTEODGH-gjayq3ra.js +0 -1
  542. package/static/dist/assets/architecture-7GRP2DOG-lp56972r.js +0 -1
  543. package/static/dist/assets/architectureDiagram-5GKGNRK7-nwb3xovn.js +0 -36
  544. package/static/dist/assets/archive-b1j004vn.js +0 -1
  545. package/static/dist/assets/back-g74gkozu.js +0 -1
  546. package/static/dist/assets/channel-es95o4y8.js +0 -1
  547. package/static/dist/assets/chunk-DU6HZSFF-gpedttsp.js +0 -128
  548. package/static/dist/assets/chunk-OSK3NFVY-oy0gwn2n.js +0 -10
  549. package/static/dist/assets/classDiagram-ZZMXUADV-kmihoqxh.js +0 -1
  550. package/static/dist/assets/classDiagram-v2-VYDZK3BY-kmihoqxh.js +0 -1
  551. package/static/dist/assets/copied-bli9tbcx.js +0 -1
  552. package/static/dist/assets/copy-jamtd1pf.js +0 -1
  553. package/static/dist/assets/cose-bilkent-JH36ORCC-eclcy6ja.js +0 -1
  554. package/static/dist/assets/cynefin-OW5HDTMX-f8xfdd3f.js +0 -1
  555. package/static/dist/assets/cynefinDiagram-5FMLGOSQ-n9lb99h9.js +0 -62
  556. package/static/dist/assets/cytoscape.esm-bqu53u12.js +0 -321
  557. package/static/dist/assets/dagre-GXQ25YYZ-dgailddi.js +0 -4
  558. package/static/dist/assets/dagre-lkoknbjn.js +0 -1
  559. package/static/dist/assets/diagram-UQ7AKVKN-jall3j0x.js +0 -41
  560. package/static/dist/assets/diagram-VX7I27RA-hendl2tt.js +0 -24
  561. package/static/dist/assets/diagram-Z3DM3KII-igwc35p3.js +0 -24
  562. package/static/dist/assets/ebnfDiagram-PWID7BFC-c64knz08.js +0 -1
  563. package/static/dist/assets/erDiagram-RLTQ6QDP-brdu9lcm.js +0 -99
  564. package/static/dist/assets/eventmodeling-NTZA5JFV-njk1j8wl.js +0 -1
  565. package/static/dist/assets/flowDiagram-HODETNUW-nma6f0ga.js +0 -1
  566. package/static/dist/assets/folder-plus-lvt9kudb.js +0 -1
  567. package/static/dist/assets/gitGraph-4MIJSDKK-naa9w6xa.js +0 -1
  568. package/static/dist/assets/highlighted-body-KPVGNVTW-ghoavj8d.js +0 -1
  569. package/static/dist/assets/host-hzm8n85n.js +0 -1
  570. package/static/dist/assets/index-drdcaqeq.css +0 -2
  571. package/static/dist/assets/index-jzm844he.js +0 -11
  572. package/static/dist/assets/info-A6RAGUB7-mn2ut5ko.js +0 -1
  573. package/static/dist/assets/infoDiagram-27XIBGKW-h6kuqvsb.js +0 -2
  574. package/static/dist/assets/lazyRouteComponent-o816ytzl.js +0 -1
  575. package/static/dist/assets/linear-becwlnhk.js +0 -1
  576. package/static/dist/assets/link-k01ryaf9.js +0 -1
  577. package/static/dist/assets/login-bsae49ew.js +0 -1
  578. package/static/dist/assets/mermaid-HWGCJPDP-ihl34s74.js +0 -1
  579. package/static/dist/assets/mermaid-parser.core-bnre27u8.js +0 -7
  580. package/static/dist/assets/not-found-ccnnac39.js +0 -1
  581. package/static/dist/assets/onboarding-c65tysya.js +0 -1
  582. package/static/dist/assets/onboarding_model_label-gpn28uix.js +0 -1
  583. package/static/dist/assets/packet-AYTQ26CC-hatq7m2e.js +0 -1
  584. package/static/dist/assets/pegDiagram-XKGWAZYB-gwisz8jv.js +0 -1
  585. package/static/dist/assets/pie-WAS4IAKB-fpftf0mk.js +0 -1
  586. package/static/dist/assets/pieDiagram-E7YTZNPT-khm1o9a6.js +0 -39
  587. package/static/dist/assets/radar-RG4KPBEZ-cntfwjpq.js +0 -1
  588. package/static/dist/assets/railroad-74A4TZTK-a7t5eibp.js +0 -1
  589. package/static/dist/assets/railroad-abnf-HS5TGJTU-ol8cdktf.js +0 -1
  590. package/static/dist/assets/railroad-ebnf-LZEXJU2U-i8vzd429.js +0 -1
  591. package/static/dist/assets/railroad-peg-WCYAUIDC-nw3ulewz.js +0 -1
  592. package/static/dist/assets/railroadDiagram-O6MQD6OU-etuh0qa0.js +0 -1
  593. package/static/dist/assets/refresh-cw-mqbkv2a3.js +0 -1
  594. package/static/dist/assets/refresh-l29ljp76.js +0 -1
  595. package/static/dist/assets/requirementDiagram-BXWQKSXE-oq2ulk22.js +0 -84
  596. package/static/dist/assets/rolldown-runtime-b9miacsj.js +0 -1
  597. package/static/dist/assets/root-mbklpuv4.js +0 -1
  598. package/static/dist/assets/saved-ndd4t2xb.js +0 -1
  599. package/static/dist/assets/settings_section_extensions_title-jhfo6o8z.js +0 -1
  600. package/static/dist/assets/share._token-c1ri0hy1.js +0 -2
  601. package/static/dist/assets/sizeCapture-INFHLROL-g612l48j.js +0 -1
  602. package/static/dist/assets/sliders-horizontal-j3jjt9tv.js +0 -1
  603. package/static/dist/assets/src-hjyib4mu.js +0 -1
  604. package/static/dist/assets/stateDiagram-D77RDMKH-dnpt1ato.js +0 -1
  605. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-bxjacpk6.js +0 -1
  606. package/static/dist/assets/swimlanes-42K2YHIH-loqbdazb.js +0 -1
  607. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-id62p9hz.js +0 -8
  608. package/static/dist/assets/toast-i3h34v6o.js +0 -64
  609. package/static/dist/assets/treeView-Q6P3EWNA-idrj6iox.js +0 -1
  610. package/static/dist/assets/treemap-WGGIJYW6-lzr49vv5.js +0 -1
  611. package/static/dist/assets/untitled-oaoya4qj.js +0 -1
  612. package/static/dist/assets/useForm-nfaxgmsk.js +0 -1
  613. package/static/dist/assets/vennDiagram-4TSXK5OY-bvwr9o2z.js +0 -34
  614. package/static/dist/assets/wardley-WFR3VGLG-31ui8tma.js +0 -1
  615. package/static/dist/assets/wardleyDiagram-VM6X3IG4-k5wqtx4b.js +0 -78
  616. /package/static/dist/assets/{ChatPage-gmu5c7lf.css → TerminalPanel-gmu5c7lf.css} +0 -0
@@ -0,0 +1,110 @@
1
+ """Fixed devkit REST adapter through the existing admitted Agent plugin host."""
2
+ import base64
3
+ import json
4
+ import re
5
+
6
+ from .. import home as homes
7
+ from ..errors import InvalidParams, RpcError
8
+ from . import dashboard_plugins as host
9
+
10
+ MAX_BYTES = 256 * 1024
11
+ _NAME = re.compile(r'[A-Za-z0-9][A-Za-z0-9._-]{0,127}')
12
+ _DIR = re.compile(r'[A-Za-z0-9_-]{1,96}')
13
+
14
+
15
+ def _text_size(value):
16
+ try:
17
+ return len(value.encode('utf-8')) if isinstance(value, str) else -1
18
+ except UnicodeError:
19
+ return -1
20
+
21
+
22
+ def _bad():
23
+ raise RpcError('Managed buffer response is invalid or too large', condition='buffer_invalid')
24
+
25
+
26
+ def _json(ctx, plugin, home, method, path, content=None):
27
+ # Recheck admission for each native call, including the PUT after inventory.
28
+ current = host._named(home, 'devkit', require_panel=False)
29
+ if current is None or current['_dir'] != plugin['_dir'] or current.get('_api_file') != plugin.get('_api_file'):
30
+ raise RpcError('Managed buffer backend changed or was disabled', condition='buffer_unavailable')
31
+ body = b'' if content is None else json.dumps({'content': content}, ensure_ascii=False).encode()
32
+ result = host._request(ctx, plugin, dict(profile_home=str(home), authenticated=True, method=method, path=path, query='',
33
+ headers={'content-type': 'application/json'}, body=base64.b64encode(body).decode()), require_panel=False)
34
+ if result['status'] != 200:
35
+ # A PUT may have committed before an error or malformed acknowledgement. Never replay it here.
36
+ raise RpcError('Managed buffer unavailable' if method == 'GET' else 'Save outcome is unknown; reload before retrying',
37
+ condition='buffer_unavailable' if method == 'GET' else 'buffer_save_unconfirmed')
38
+ try:
39
+ value = json.loads(base64.b64decode(result['body']))
40
+ except (ValueError, UnicodeDecodeError):
41
+ _bad()
42
+ if not isinstance(value, dict):
43
+ _bad()
44
+ return value
45
+
46
+
47
+ def run(ctx, params):
48
+ action, sid = params.get('action'), params.get('session_id')
49
+ if action not in ('list', 'read', 'save') or not isinstance(sid, str) or not 0 < len(sid) <= 200:
50
+ raise InvalidParams('Invalid managed buffer request')
51
+ name = params.get('name')
52
+ if action != 'list' and (not isinstance(name, str) or not _NAME.fullmatch(name)):
53
+ raise InvalidParams('Invalid managed buffer name')
54
+ content = params.get('content')
55
+ if action == 'save' and (not 0 <= _text_size(content) <= MAX_BYTES):
56
+ raise InvalidParams('Managed buffer content is too large or is not text')
57
+ home = homes.profile_home_param(params)
58
+ with homes.scoped_home(home, load_plugins=False):
59
+ plugin = host._named(home, 'devkit', require_panel=False) if host._supported() else None
60
+ result = {'supported': plugin is not None, 'buffers': [], 'write_semantics': 'unconditional'}
61
+ if plugin is None:
62
+ if action != 'list':
63
+ raise RpcError('Enable and approve the devkit backend in Plugins', condition='buffer_unavailable')
64
+ return result
65
+ rows = _json(ctx, plugin, home, 'GET', '/sessions').get('sessions')
66
+ if not isinstance(rows, list) or len(rows) > 2000 or any(not isinstance(r, dict) for r in rows):
67
+ _bad()
68
+ matches = [r for r in rows if r.get('session_id') == sid]
69
+ if len(matches) > 1:
70
+ _bad()
71
+ row = matches[0] if matches else None
72
+ if row is None:
73
+ if action != 'list':
74
+ raise RpcError('Managed buffer no longer exists', condition='buffer_unavailable')
75
+ return result
76
+ directory, buffers = row.get('dir'), row.get('buffers')
77
+ if not isinstance(directory, str) or not _DIR.fullmatch(directory) or not isinstance(buffers, list) or len(buffers) > 200:
78
+ _bad()
79
+ seen = set()
80
+ for buf in buffers:
81
+ if not isinstance(buf, dict):
82
+ _bad()
83
+ key, size = buf.get('name'), buf.get('bytes')
84
+ if not isinstance(key, str) or not _NAME.fullmatch(key) or key in seen or type(size) is not int or not 0 <= size <= MAX_BYTES:
85
+ _bad()
86
+ seen.add(key)
87
+ result['buffers'].append({'name': key, 'size': size, 'read_only': row.get('exists') is not True})
88
+ if action == 'list':
89
+ return result
90
+ selected = next((b for b in result['buffers'] if b['name'] == name), None)
91
+ if selected is None:
92
+ raise RpcError('Managed buffer no longer exists', condition='buffer_unavailable')
93
+ if action == 'save' and selected['read_only']:
94
+ raise RpcError('Managed session is deleted or cannot be verified', condition='buffer_read_only')
95
+ value = _json(ctx, plugin, home, 'PUT' if action == 'save' else 'GET', f'/sessions/{directory}/buffers/{name}', content if action == 'save' else None)
96
+ if action == 'read':
97
+ text = value.get('content')
98
+ if value.get('session_id') != sid or value.get('name') != name or not 0 <= _text_size(text) <= MAX_BYTES:
99
+ _bad()
100
+ result.update(content=text, size=_text_size(text), read_only=selected['read_only'])
101
+ else:
102
+ # Native PUT acknowledgements may omit session_id, but an explicit identity must match.
103
+ if value.get('session_id', sid) != sid or value.get('name') != name or type(value.get('bytes')) is not int or not 0 <= value['bytes'] <= MAX_BYTES:
104
+ raise RpcError('Save outcome is unknown; reload before retrying', condition='buffer_save_unconfirmed')
105
+ result.update(size=value['bytes'], read_only=False)
106
+ return result
107
+
108
+
109
+ def register(registry):
110
+ registry.method('plugins.buffers')(run)
@@ -6,6 +6,8 @@ Config edits and health probes live in the server; this namespace only reads
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ import hashlib
10
+ import json
9
11
  import logging
10
12
 
11
13
  from ..home import profile_home_param, scoped_home
@@ -48,7 +50,60 @@ def registry_tools() -> list[dict]:
48
50
  return out
49
51
 
50
52
 
53
+ def cost_policies(servers: dict) -> dict:
54
+ """Read declarations using the native parser; inspect cached packages without discovering or connecting."""
55
+ try:
56
+ from tools.mcp_tool_costs import CONFIG_KEYS, _parse_cost, config_cost_policy
57
+ from hermes_cli.plugins import get_plugin_manager
58
+
59
+ portable = get_plugin_manager().get_portable_mcp_servers()
60
+ except (ImportError, AttributeError):
61
+ return {"supported": False, "policies": []}
62
+ rows = []
63
+ for name in sorted(servers.keys() | portable.keys()):
64
+ native, package = servers.get(name), portable.get(name, {})
65
+ if not isinstance(package, dict):
66
+ package = {}
67
+ editable = isinstance(native, dict) and ("command" in native or "url" in native)
68
+ own = {k: native[k] for k in CONFIG_KEYS if isinstance(native, dict) and k in native}
69
+ # The native loader rejects a malformed package before it can donate inherited keys.
70
+ if native is not None:
71
+ try:
72
+ config_cost_policy(name, package)
73
+ except (ValueError, TypeError):
74
+ package = {}
75
+ inherited = {k: package[k] for k in CONFIG_KEYS if k in package}
76
+ effective = {**inherited, **own}
77
+ sources = {k: "native" if k in own else "package" if k in inherited else "default" for k in CONFIG_KEYS}
78
+ row = {"name": name, "source": "native_override" if native is not None and package else "native" if native is not None else "package",
79
+ "valid": True, "can_edit": editable, "error": None,
80
+ "package_revision": hashlib.sha256(json.dumps(inherited, sort_keys=True, default=str).encode()).hexdigest(),
81
+ "overrides": {"tool_costs": None, "spend_limit": None, "cost_unit": None},
82
+ "tool_costs": [], "spend_limit": 0, "cost_unit": "credits", "budget_enabled": False, "field_sources": sources}
83
+ try:
84
+ # Validate the native entry separately as the Agent does before package inheritance.
85
+ config_cost_policy(name, own)
86
+ policy = config_cost_policy(name, effective)
87
+ costs = effective.get("tool_costs") or {}
88
+ row["tool_costs"] = [{"name": tool, "low": cost.low, "high": cost.high, "note": cost.note}
89
+ for tool, value in costs.items() for cost in [_parse_cost(value, "declared cost")]]
90
+ row["spend_limit"] = effective.get("spend_limit") or 0
91
+ row["cost_unit"] = (effective.get("cost_unit") or "credits").strip()
92
+ row["budget_enabled"] = policy is not None and policy.limit > 0
93
+ row["overrides"] = {k: own.get(k) for k in CONFIG_KEYS}
94
+ except (ValueError, TypeError):
95
+ # Native errors may quote arbitrary config values, including mistakenly pasted credentials.
96
+ row.update(valid=False, error="Invalid declared cost policy. Check tool estimates, limit and unit.")
97
+ rows.append(row)
98
+ return {"supported": True, "policies": rows}
99
+
100
+
51
101
  def register(registry_) -> None:
102
+ @registry_.method("mcp.cost_policies")
103
+ def policies(ctx: CallContext, params: dict) -> dict:
104
+ with scoped_home(profile_home_param(params), load_plugins=False):
105
+ return cost_policies(params.get("servers") or {})
106
+
52
107
  @registry_.method("mcp.status")
53
108
  def status_(ctx: CallContext, params: dict) -> dict:
54
109
  with scoped_home(profile_home_param(params)):
@@ -1,4 +1,5 @@
1
- """``oauth.*``: the Agent's device-code sign-ins for Nous Portal, OpenAI Codex, xAI and MiniMax (TAL-398).
1
+ """``oauth.*``: the Agent's device-code sign-ins for Nous Portal, OpenAI Codex, xAI and MiniMax (TAL-398), and the
2
+ browser sign-in of a plugin-declared OAuth client (``plugin:<key>:<id>``, TAL-1276, in ``plugin_oauth``).
2
3
 
3
4
  ``oauth.start`` asks the provider for a code and answers what the user has to see; a daemon thread then waits for the
4
5
  approval and saves the credential with the Agent's own auth-store helpers under the flow's profile home, the steps its
@@ -9,9 +10,12 @@ Flows live in this process only.
9
10
 
10
11
  from __future__ import annotations
11
12
 
13
+ import contextlib
14
+ import inspect
12
15
  import logging
13
16
  import os
14
17
  import secrets
18
+ import ssl
15
19
  import threading
16
20
  import time
17
21
  from dataclasses import dataclass, field
@@ -22,6 +26,7 @@ from typing import Any, Callable
22
26
  from ..errors import InvalidParams, RpcError
23
27
  from ..home import profile_home_param, scoped_home
24
28
  from ..rpc import CallContext
29
+ from . import plugin_oauth
25
30
 
26
31
  log = logging.getLogger("talaria_sidecar.oauth")
27
32
 
@@ -31,6 +36,8 @@ _CODEX_EXPIRES_IN = 15 * 60 # OpenAI's device-code lifetime, as the Agent dashb
31
36
  _ENDED_TTL = 10 * 60
32
37
  # A pending flow past its code's expiry by this much ends expired even if its provider call has not returned yet.
33
38
  _EXPIRY_GRACE = 60
39
+ # How long a start waits for the flows it replaces to close their loopback listeners.
40
+ _RELEASE_WAIT = 5.0
34
41
 
35
42
  _DENIED = "Sign-in was declined."
36
43
  _EXPIRED = "The sign-in code expired before it was approved."
@@ -55,6 +62,17 @@ class Flow:
55
62
  cancelled: threading.Event = field(default_factory=threading.Event)
56
63
  # Serialises the cancel check with the credential save: a cancel cannot land between them.
57
64
  lock: threading.Lock = field(default_factory=threading.Lock)
65
+ # The credential is saved but the sign-in has not finished (a guest sign-in still settles the account): a cancel or
66
+ # an expiry can no longer undo it, and the flow stays pending until its own ending.
67
+ committed: bool = False
68
+ # A browser sign-in also finishes from the redirect address the user pastes (``oauth.submit_redirect``).
69
+ submit: Callable[[str], None] | None = None
70
+ # Set once a browser sign-in's loopback listener is closed, so a replacing start can bind the same fixed port.
71
+ closed: threading.Event | None = None
72
+
73
+ @property
74
+ def stoppable(self) -> bool:
75
+ return self.status == "pending" and not self.committed
58
76
 
59
77
  def end(self, status: str, error: str | None = None) -> None:
60
78
  self.status, self.error, self.ended_at = status, error, time.time()
@@ -107,9 +125,24 @@ def _now_z() -> str:
107
125
 
108
126
 
109
127
  def _client(timeout: float, **kwargs: Any) -> Any:
128
+ """Every flow's HTTP client, verifying TLS as the Agent's own sign-in does: the OS trust store, and (v0.22.3+) a
129
+ certifi bundle an install-environment rotation deleted under this process, re-derived process-wide."""
110
130
  import httpx
111
131
 
112
- return httpx.Client(timeout=httpx.Timeout(timeout), headers={"Accept": "application/json"}, **kwargs)
132
+ return httpx.Client(timeout=httpx.Timeout(timeout), headers={"Accept": "application/json"}, verify=_verify(), **kwargs)
133
+
134
+
135
+ def _verify() -> Any:
136
+ try:
137
+ from agent.ssl_verify import resolve_httpx_verify
138
+ except ImportError: # an Agent without it keeps httpx's default
139
+ return True
140
+ verify = resolve_httpx_verify()
141
+ # The resolver hands over the platform store alone when SSL_CERT_FILE/SSL_CERT_DIR is set; httpx's default trusted
142
+ # that bundle, so keep it, on top of the platform store the resolver installed (as ``platform_ssl_context`` does).
143
+ cafile, capath = os.environ.get("SSL_CERT_FILE", "").strip(), os.environ.get("SSL_CERT_DIR", "").strip()
144
+ cafile, capath = (cafile if os.path.isfile(cafile) else None), (capath if os.path.isdir(capath) else None)
145
+ return ssl.create_default_context(cafile=cafile, capath=capath) if cafile or capath else verify
113
146
 
114
147
 
115
148
  # ── providers: (begin, wait, save) over the Agent's own steps ──────────
@@ -124,8 +157,9 @@ def _nous_begin() -> tuple[dict, dict]:
124
157
  # v0.22.0 replaced ``guest_enabled`` with ``guest_allowed``; 0.21.x releases only have the former.
125
158
  guest_gate = getattr(anon_auth, "guest_allowed", None) or getattr(anon_auth, "guest_enabled")
126
159
  if guest_gate() and anon_auth.has_guest():
127
- # The free tier's sign-in moves its connectors to the account (``anon_auth.run_sign_in``); a plain device-code
128
- # sign-in here would orphan them.
160
+ # The native sign-in owns the guest's connector handoff for its installed protocol.
161
+ if hasattr(anon_auth, "run_sign_in"):
162
+ return _nous_sign_in(anon_auth)
129
163
  hint = getattr(anon_auth, "UPGRADE_HINT", None) or "Sign in from Hermes with `hermes auth upgrade`."
130
164
  raise RpcError(f"This profile uses the Nous free tier. {hint}", condition="oauth_unsupported")
131
165
  pconfig = PROVIDER_REGISTRY["nous"]
@@ -136,7 +170,63 @@ def _nous_begin() -> tuple[dict, dict]:
136
170
  return display, {"portal": portal, "client_id": pconfig.client_id, "scope": pconfig.scope, "device_code": str(data["device_code"])}
137
171
 
138
172
 
173
+ def _nous_sign_in(anon_auth: Any) -> tuple[dict, dict]:
174
+ """Over a guest, the Agent's own sign-in (``anon_auth.run_sign_in``, as its dashboard runs it): it moves the guest's
175
+ connected apps to the account, then persists and settles the account itself. Its cancel check, persist guard and
176
+ home scope read the flow ``_nous_wait`` binds into the state; before that only ``start``'s first step runs, already
177
+ under the flow's home."""
178
+ state: dict = {}
179
+
180
+ def cancelled() -> bool:
181
+ flow = state.get("flow")
182
+ return flow is not None and flow.cancelled.is_set()
183
+
184
+ @contextlib.contextmanager
185
+ def persist_guard():
186
+ # As ``_run`` does for a plain save, the final cancel check and the save share the flow's lock; the flow ends
187
+ # approved only when the Agent has also settled the account, through ``_run``.
188
+ flow = state["flow"]
189
+ with flow.lock:
190
+ may_persist = flow.status == "pending"
191
+ yield may_persist
192
+ if may_persist:
193
+ flow.committed = True
194
+
195
+ def scope():
196
+ flow = state.get("flow")
197
+ return scoped_home(flow.home) if flow is not None else contextlib.nullcontext()
198
+
199
+ # Older Agents use promotion; v0.22.5 removed its option in favor of plain device login and native handoff.
200
+ options = {"cancel_wins_after_promotion": True} if "cancel_wins_after_promotion" in inspect.signature(anon_auth.run_sign_in).parameters else {}
201
+ sign_in = anon_auth.run_sign_in(cancelled=cancelled, persist_guard=persist_guard, scope=scope, **options)
202
+ first = next(sign_in)
203
+ if first.kind != "code":
204
+ sign_in.close()
205
+ raise RpcError(first.copy_terminal, condition="oauth_unsupported" if first.precondition else "oauth_failed")
206
+ state["sign_in"] = sign_in
207
+ return {"user_code": first.code, "verification_url": first.link, "expires_in": first.expires_in, "interval": first.interval}, state
208
+
209
+
210
+ class _SignInEnded(Exception):
211
+ """A guest sign-in that ended without an account; ``code`` lets ``_ending`` classify a decline and an expiry."""
212
+
213
+ def __init__(self, ended: Any):
214
+ super().__init__(ended.copy)
215
+ self.code = {"declined": "access_denied", "timed_out": "expired_token"}.get(ended.kind, ended.kind)
216
+
217
+
139
218
  def _nous_wait(flow: Flow, state: dict) -> dict:
219
+ sign_in = state.get("sign_in")
220
+ if sign_in is not None:
221
+ state["flow"] = flow
222
+ try:
223
+ for ended in sign_in: # the generator always ends on one terminal state
224
+ pass
225
+ finally:
226
+ sign_in.close()
227
+ if not ended.ok:
228
+ raise _SignInEnded(ended)
229
+ return {}
140
230
  from hermes_cli.auth import _poll_for_token
141
231
 
142
232
  with _client(15.0) as client:
@@ -145,6 +235,8 @@ def _nous_wait(flow: Flow, state: dict) -> dict:
145
235
 
146
236
 
147
237
  def _nous_save(flow: Flow, state: dict, token_data: dict) -> None:
238
+ if "sign_in" in state: # the guest sign-in persisted and settled the account itself
239
+ return
148
240
  from hermes_cli import anon_auth
149
241
  from hermes_cli.auth import persist_nous_credentials, refresh_nous_oauth_from_state
150
242
 
@@ -213,8 +305,10 @@ def _codex_save(flow: Flow, state: dict, tokens: dict) -> None:
213
305
  def _xai_begin() -> tuple[dict, dict]:
214
306
  from hermes_cli.auth import _xai_oauth_discovery, _xai_oauth_request_device_code
215
307
 
216
- discovery = _xai_oauth_discovery(20.0)
217
308
  with _client(20.0) as client:
309
+ # The Agent's discovery is a bare ``httpx.get``: building the client first gives it the platform store and a
310
+ # certifi re-derived after a rotation.
311
+ discovery = _xai_oauth_discovery(20.0)
218
312
  data = _xai_oauth_request_device_code(client)
219
313
  display = {"user_code": str(data["user_code"]), "verification_url": str(data.get("verification_uri_complete") or data["verification_uri"]),
220
314
  "expires_in": int(data["expires_in"]), "interval": int(data["interval"])}
@@ -323,9 +417,16 @@ def _run(flow: Flow, wait: Callable[[Flow, dict], dict], save: Callable[[Flow, d
323
417
  log.info("oauth: %s sign-in ended %s (flow=%s)", flow.provider, flow.status, flow.flow_id[:6])
324
418
 
325
419
 
420
+ def _discard(state: dict) -> None:
421
+ """Releases a begun sign-in that is never published: a guest sign-in's generator holds its HTTP client."""
422
+ if "sign_in" in state:
423
+ state["sign_in"].close()
424
+ plugin_oauth.discard(state)
425
+
426
+
326
427
  def _cancel(flow: Flow) -> None:
327
428
  with flow.lock:
328
- if flow.status == "pending":
429
+ if flow.stoppable:
329
430
  flow.cancelled.set()
330
431
  flow.end("cancelled")
331
432
 
@@ -357,7 +458,7 @@ def _pending(home: Path, provider: str) -> list[Flow]:
357
458
 
358
459
 
359
460
  def start(home: Path, provider: str, *, providers: dict[str, Provider] | None = None) -> dict:
360
- steps = (providers or PROVIDERS).get(provider)
461
+ steps = (providers or PROVIDERS).get(provider) or plugin_oauth.steps(provider)
361
462
  if steps is None:
362
463
  raise InvalidParams(f"{provider} has no device-code sign-in")
363
464
  begin, wait, save = steps
@@ -369,6 +470,11 @@ def start(home: Path, provider: str, *, providers: dict[str, Provider] | None =
369
470
  # old code that lands while the provider answers can no longer save.
370
471
  for old in _pending(home, provider):
371
472
  _cancel(old)
473
+ # A cancelled browser sign-in closes its listener from its own thread; a fixed redirect port is free only after that.
474
+ with _FLOWS_LOCK:
475
+ listening = [f for f in _FLOWS.values() if f.provider == provider and f.closed is not None and not f.closed.is_set() and _same_home(f.home, home)]
476
+ for old in listening:
477
+ old.closed.wait(_RELEASE_WAIT)
372
478
  try:
373
479
  with scoped_home(home):
374
480
  display, state = begin()
@@ -379,11 +485,13 @@ def start(home: Path, provider: str, *, providers: dict[str, Provider] | None =
379
485
  raise RpcError(_first_line(exc), condition="oauth_failed") from exc
380
486
  if not str(display["verification_url"]).lower().startswith(("https://", "http://")):
381
487
  # The browser opens this link: anything but a web address is refused before a flow exists.
488
+ _discard(state)
382
489
  raise RpcError("The provider answered an invalid sign-in link.", condition="oauth_failed")
383
- flow = Flow(secrets.token_urlsafe(16), provider, home, time.time() + int(display["expires_in"]), max(1, int(display["interval"])))
490
+ flow = Flow(secrets.token_urlsafe(16), provider, home, time.time() + int(display["expires_in"]), max(1, int(display["interval"])), submit=state.get("submit"), closed=state.get("closed"))
384
491
  with _FLOWS_LOCK:
385
492
  if _GENERATIONS.get(key) != generation:
386
493
  # A newer start for this home and provider began while this one waited on the provider: it owns the sign-in.
494
+ _discard(state)
387
495
  raise RpcError("A newer sign-in for this provider replaced this one.", condition="oauth_superseded")
388
496
  superseded = [f for f in _FLOWS.values() if f.provider == provider and f.status == "pending" and _same_home(f.home, home)]
389
497
  _FLOWS[flow.flow_id] = flow
@@ -403,10 +511,10 @@ def _flow(home: Path, flow_id: str) -> Flow:
403
511
 
404
512
  def poll(home: Path, flow_id: str) -> dict:
405
513
  flow = _flow(home, flow_id)
406
- if flow.status == "pending" and time.time() > flow.expires_at + _EXPIRY_GRACE:
514
+ if flow.stoppable and time.time() > flow.expires_at + _EXPIRY_GRACE:
407
515
  # The provider call outlived its code: end it now, and a late approval can no longer save.
408
516
  with flow.lock:
409
- if flow.status == "pending":
517
+ if flow.stoppable:
410
518
  flow.cancelled.set()
411
519
  flow.end("expired", _EXPIRED)
412
520
  return flow.view()
@@ -418,6 +526,18 @@ def cancel(home: Path, flow_id: str) -> dict:
418
526
  return flow.view()
419
527
 
420
528
 
529
+ def submit_redirect(home: Path, flow_id: str, url: str) -> dict:
530
+ """Finish a browser sign-in with the address its redirect reached, when the browser runs on another machine."""
531
+ flow = _flow(home, flow_id)
532
+ if flow.submit is None:
533
+ raise InvalidParams("This sign-in takes no redirect address.")
534
+ with flow.lock:
535
+ if not flow.stoppable or time.time() >= flow.expires_at:
536
+ raise RpcError("This sign-in already ended.", condition="oauth_flow_ended")
537
+ flow.submit(url)
538
+ return flow.view()
539
+
540
+
421
541
  def _flow_id(params: dict) -> str:
422
542
  flow_id = str(params.get("flow_id") or "").strip()
423
543
  if not flow_id:
@@ -428,7 +548,8 @@ def _flow_id(params: dict) -> str:
428
548
  def register(reg) -> None:
429
549
  @reg.method("oauth.start")
430
550
  def start_(ctx: CallContext, params: dict) -> dict:
431
- provider = str(params.get("provider") or "").strip().lower()
551
+ provider = str(params.get("provider") or "").strip()
552
+ provider = provider if provider.startswith(plugin_oauth.PREFIX) else provider.lower()
432
553
  if not provider:
433
554
  raise InvalidParams("provider is required")
434
555
  return start(profile_home_param(params), provider)
@@ -440,3 +561,10 @@ def register(reg) -> None:
440
561
  @reg.method("oauth.cancel", requires_agent=False)
441
562
  def cancel_(ctx: CallContext, params: dict) -> dict:
442
563
  return cancel(profile_home_param(params), _flow_id(params))
564
+
565
+ @reg.method("oauth.submit_redirect", requires_agent=False)
566
+ def submit_(ctx: CallContext, params: dict) -> dict:
567
+ url = str(params.get("url") or "").strip()
568
+ if not url:
569
+ raise InvalidParams("url is required")
570
+ return submit_redirect(profile_home_param(params), _flow_id(params), url)
@@ -0,0 +1,165 @@
1
+ """Typed adapter for the reviewed Draft Cards store. Never imports producer code or sends."""
2
+ from __future__ import annotations
3
+
4
+ import hashlib
5
+ import hmac
6
+ import secrets
7
+ import json
8
+ from pathlib import Path
9
+ import re
10
+ import sqlite3
11
+ import time
12
+ from contextlib import closing
13
+
14
+ from .. import home as homes
15
+ from ..errors import InvalidParams, RpcError
16
+ from . import dashboard_plugins
17
+
18
+ _KEY = secrets.token_bytes(32)
19
+ _PIN = '6e6ca659ece59b0ce1c28b3b188393491ee5a415'
20
+ _SOURCES = {'__init__.py': '73388811ddc4f7cfc336c2a278dad9c0c032b0b15e4183ce8a157e61ce13695b',
21
+ 'plugin.yaml': 'e2a8a92847f4519f1636ec542ae2b1599050d9552fb9a61d9c6d6afaca83d6eb',
22
+ 'dashboard/manifest.json': '14e906a0e492669f0950e091f42d98ad607486dbea524b2a8e8691faa2139941',
23
+ 'dashboard/plugin_api.py': '98e38f618c23ec266f1e171a958ffcf048339ea3c7876d1faa2d0b8910839336',
24
+ 'store.py': '5815d4b106082b7f51d1b7e9d239fc655fa247a5e61ff7465e8c1865476eaaf6',
25
+ 'tools.py': '29271409488efc39206a048dc2852effc156d9ca5d91721632e1219840f14db1'}
26
+ _STATES = {'draft', 'approved', 'sent', 'saved', 'failed', 'discarded'}
27
+
28
+
29
+ def _producer(home):
30
+ """Native registration, explicit profile consent and reviewed source, without loading a plugin."""
31
+ try:
32
+ from hermes_cli import plugins_cmd as pc
33
+ metadata = pc._read_install_metadata()
34
+ for plugin in dashboard_plugins._plugins(home):
35
+ if plugin['name'] != 'draft-cards' or not plugin['enabled'] or plugin.get('source') != 'user':
36
+ continue
37
+ root, anchor = Path(plugin['_dir']).parent, Path(plugin['_asset_anchor'])
38
+ record = metadata.get(root.name, {})
39
+ catalog = record.get('catalog', {})
40
+ if catalog.get('name') != 'draft-cards' or catalog.get('sha') != _PIN or record.get('revision') != _PIN:
41
+ continue
42
+ if not all((body := dashboard_plugins._read(root, name, anchor=anchor)) is not None
43
+ and hashlib.sha256(body).hexdigest() == digest for name, digest in _SOURCES.items()):
44
+ continue
45
+ return _PIN
46
+ except (ImportError, AttributeError, OSError, ValueError, TypeError):
47
+ pass
48
+ return None
49
+
50
+
51
+ def _database(home):
52
+ """Only the producer's existing profile-local database; never creates storage on a read."""
53
+ path = Path(home) / 'plugin-data' / 'draft-cards' / 'drafts.db'
54
+ # No caller supplies a filesystem path, and no symlink may redirect native state.
55
+ for parent in [path, *path.parents]:
56
+ if parent.is_symlink():
57
+ raise OSError('Symlink in draft storage')
58
+ if not path.is_file():
59
+ raise OSError('Draft storage unavailable')
60
+ connection = sqlite3.connect(path.as_uri() + '?mode=rw', uri=True, timeout=5)
61
+ connection.row_factory = sqlite3.Row
62
+ return connection
63
+
64
+
65
+ def _fields(value):
66
+ if not isinstance(value, dict) or set(value) != {'from', 'to', 'cc', 'bcc', 'subject', 'body'}:
67
+ raise InvalidParams('Invalid draft fields')
68
+ for key, limit in [('from', 320), ('subject', 300), ('body', 20_000)]:
69
+ if not isinstance(value[key], str) or len(value[key]) > limit or '\x00' in value[key]:
70
+ raise InvalidParams('Invalid draft fields')
71
+ for key in ('to', 'cc', 'bcc'):
72
+ if not isinstance(value[key], list) or len(value[key]) > 50 or any(
73
+ not isinstance(item, str) or len(item) > 320 or re.search(r'[\r\n\x00]', item) for item in value[key]):
74
+ raise InvalidParams('Invalid draft recipients')
75
+ if not value['body'].strip():
76
+ raise InvalidParams('A draft body is required')
77
+ return value
78
+
79
+
80
+ def _snapshot(conn, home, params, producer):
81
+ row = conn.execute('SELECT * FROM drafts WHERE id = ?', (params['draft_id'],)).fetchone()
82
+ if row is None or not row['session_id'] or row['session_id'] != params['session_id']:
83
+ return None
84
+ versions = conn.execute('SELECT * FROM versions WHERE draft_id = ? ORDER BY v LIMIT 61', (params['draft_id'],)).fetchall()
85
+ if not versions or len(versions) > 60 or row['kind'] not in ('email', 'message') or row['status'] not in _STATES:
86
+ return None
87
+ matches = [v for v in versions if v['card'] == params['card']]
88
+ if not matches:
89
+ return None
90
+ selected, latest = matches[-1], versions[-1]
91
+ fields = _fields(json.loads(selected['fields']))
92
+ state = row['status'] if selected['v'] == latest['v'] else 'superseded'
93
+ if state == 'approved' and row['approved_version'] != latest['v']:
94
+ state = 'unavailable'
95
+ consumed = False
96
+ if conn.execute("SELECT 1 FROM sqlite_master WHERE type='table' AND name='talaria_outbound_approvals'").fetchone():
97
+ consumed = conn.execute('SELECT 1 FROM talaria_outbound_approvals WHERE draft_id = ? AND version = ?',
98
+ (row['id'], selected['v'])).fetchone() is not None
99
+ revision = hmac.new(_KEY, json.dumps([str(home), producer, dict(row), [dict(v) for v in versions], consumed],
100
+ sort_keys=True, separators=(',', ':')).encode(), hashlib.sha256).hexdigest()
101
+ editable = state in ('draft', 'failed', 'approved')
102
+ return {'producer': 'draft-cards', 'producer_revision': producer, 'draft_id': row['id'], 'card': selected['card'],
103
+ 'kind': row['kind'], 'platform': str(row['platform'])[:40], 'version': selected['v'], 'revision': revision,
104
+ 'fields': fields, 'state': state, 'can_edit': editable, 'can_approve': state in ('draft', 'failed') and not consumed,
105
+ 'masked': False}
106
+
107
+
108
+ def _conflict():
109
+ raise RpcError('The draft changed or this version was already approved. Review it again.', condition='outbound_draft_conflict')
110
+
111
+
112
+ def review(ctx, params):
113
+ ctx.check_cancelled()
114
+ action = params.get('action')
115
+ if (action not in ('read', 'edit', 'approve') or not isinstance(params.get('draft_id'), str)
116
+ or not re.fullmatch(r'd_[0-9a-f]{8}', params['draft_id']) or type(params.get('card')) is not int
117
+ or params['card'] < 1 or not isinstance(params.get('session_id'), str) or not params['session_id']):
118
+ raise InvalidParams('Invalid outbound draft reference')
119
+ home = homes.profile_home_param(params)
120
+ with homes.scoped_home(home, load_plugins=False):
121
+ producer = _producer(home)
122
+ if producer is None:
123
+ if action != 'read':
124
+ _conflict()
125
+ return {'draft': None}
126
+ try:
127
+ with closing(_database(home)) as conn, conn:
128
+ # The native tool writers share this database lock. Check and mutation have one snapshot.
129
+ conn.execute('BEGIN IMMEDIATE' if action != 'read' else 'BEGIN')
130
+ draft = _snapshot(conn, home, params, producer)
131
+ if action == 'read':
132
+ ctx.check_cancelled()
133
+ return {'draft': draft if _producer(home) == producer else None}
134
+ if (draft is None or params.get('version') != draft['version'] or params.get('revision') != draft['revision']
135
+ or not draft['can_' + action] or _producer(home) != producer):
136
+ _conflict()
137
+ now = time.time()
138
+ if action == 'edit':
139
+ fields = _fields(params.get('fields'))
140
+ if fields == draft['fields']:
141
+ return {'draft': draft}
142
+ if conn.execute('SELECT count(*) FROM versions WHERE draft_id = ?', (draft['draft_id'],)).fetchone()[0] >= 60:
143
+ _conflict()
144
+ conn.execute("INSERT INTO versions (draft_id,v,card,author,note,fields,created_at) VALUES (?,?,?,'user','Edited in Talaria',?,?)",
145
+ (draft['draft_id'], draft['version'] + 1, draft['card'], json.dumps(fields, ensure_ascii=False), now))
146
+ conn.execute("UPDATE drafts SET status='draft', approved_version=NULL, status_detail='', status_at=?, updated_at=? WHERE id=?",
147
+ (now, now, draft['draft_id']))
148
+ else:
149
+ # Additive native-store state: Stable producer readers ignore this per-version receipt.
150
+ conn.execute('CREATE TABLE IF NOT EXISTS talaria_outbound_approvals (draft_id TEXT NOT NULL, version INTEGER NOT NULL, revision TEXT NOT NULL, PRIMARY KEY(draft_id,version))')
151
+ conn.execute('INSERT INTO talaria_outbound_approvals VALUES (?,?,?)', (draft['draft_id'], draft['version'], draft['revision']))
152
+ conn.execute("UPDATE drafts SET status='approved', approved_version=?, status_detail='', status_at=?, updated_at=? WHERE id=?",
153
+ (draft['version'], now, now, draft['draft_id']))
154
+ ctx.check_cancelled()
155
+ if _producer(home) != producer:
156
+ _conflict()
157
+ return {'draft': _snapshot(conn, home, params, producer)}
158
+ except (OSError, sqlite3.Error, ValueError, KeyError, TypeError, InvalidParams) as exc:
159
+ if action != 'read':
160
+ raise RpcError('Draft outcome unconfirmed; read its state before trying again.', condition='outbound_draft_unconfirmed') from exc
161
+ return {'draft': None}
162
+
163
+
164
+ def register(registry):
165
+ registry.method('drafts.review')(review)