@maudecode/talaria-web 1.18.0 → 1.19.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 (567) hide show
  1. package/_release.json +8 -8
  2. package/dist/api/auth-raw.js +16 -16
  3. package/dist/api/auth-raw.js.map +1 -1
  4. package/dist/api/automation-raw.d.ts +2 -2
  5. package/dist/api/automation-raw.js +32 -32
  6. package/dist/api/automation-raw.js.map +1 -1
  7. package/dist/api/automation-router.d.ts +102 -22
  8. package/dist/api/automation-router.js +15 -13
  9. package/dist/api/automation-router.js.map +1 -1
  10. package/dist/api/chat-router.d.ts +1205 -34
  11. package/dist/api/chat-router.js +158 -78
  12. package/dist/api/chat-router.js.map +1 -1
  13. package/dist/api/git-router.d.ts +2 -2
  14. package/dist/api/git-router.js +29 -29
  15. package/dist/api/git-router.js.map +1 -1
  16. package/dist/api/raw-routes.d.ts +3 -3
  17. package/dist/api/raw-routes.js +63 -61
  18. package/dist/api/raw-routes.js.map +1 -1
  19. package/dist/api/router.d.ts +6 -6
  20. package/dist/api/router.js +22 -22
  21. package/dist/api/router.js.map +1 -1
  22. package/dist/api/session-visibility.d.ts +4 -4
  23. package/dist/api/session-visibility.js +26 -16
  24. package/dist/api/session-visibility.js.map +1 -1
  25. package/dist/api/sessions-router.d.ts +1928 -124
  26. package/dist/api/sessions-router.js +177 -173
  27. package/dist/api/sessions-router.js.map +1 -1
  28. package/dist/api/settings-router.d.ts +427 -9
  29. package/dist/api/settings-router.js +48 -32
  30. package/dist/api/settings-router.js.map +1 -1
  31. package/dist/api/sse-routes.d.ts +2 -2
  32. package/dist/api/sse-routes.js +63 -63
  33. package/dist/api/sse-routes.js.map +1 -1
  34. package/dist/api/tools-raw.d.ts +5 -0
  35. package/dist/api/tools-raw.js +58 -33
  36. package/dist/api/tools-raw.js.map +1 -1
  37. package/dist/api/tools-router.d.ts +663 -91
  38. package/dist/api/tools-router.js +309 -52
  39. package/dist/api/tools-router.js.map +1 -1
  40. package/dist/api/transcribe-stream.d.ts +16 -0
  41. package/dist/api/transcribe-stream.js +172 -0
  42. package/dist/api/transcribe-stream.js.map +1 -0
  43. package/dist/app.d.ts +4 -1
  44. package/dist/app.js +66 -47
  45. package/dist/app.js.map +1 -1
  46. package/dist/auth/gate.js +10 -9
  47. package/dist/auth/gate.js.map +1 -1
  48. package/dist/auth/passkeys.d.ts +15 -14
  49. package/dist/auth/passkeys.js +89 -91
  50. package/dist/auth/passkeys.js.map +1 -1
  51. package/dist/auth/store.d.ts +17 -7
  52. package/dist/auth/store.js +93 -52
  53. package/dist/auth/store.js.map +1 -1
  54. package/dist/bin/talaria-web.js +12 -81
  55. package/dist/bin/talaria-web.js.map +1 -1
  56. package/dist/cli/ctl.js +2 -1
  57. package/dist/cli/ctl.js.map +1 -1
  58. package/dist/cli/dotenv.d.ts +5 -0
  59. package/dist/cli/dotenv.js +14 -2
  60. package/dist/cli/dotenv.js.map +1 -1
  61. package/dist/cli/launcher.js +5 -5
  62. package/dist/cli/launcher.js.map +1 -1
  63. package/dist/cli/main.d.ts +1 -0
  64. package/dist/cli/main.js +85 -0
  65. package/dist/cli/main.js.map +1 -0
  66. package/dist/cli/supervise.d.ts +2 -0
  67. package/dist/cli/supervise.js +67 -4
  68. package/dist/cli/supervise.js.map +1 -1
  69. package/dist/config/agent-config.d.ts +34 -11
  70. package/dist/config/agent-config.js +113 -58
  71. package/dist/config/agent-config.js.map +1 -1
  72. package/dist/config.d.ts +2 -0
  73. package/dist/config.js +14 -5
  74. package/dist/config.js.map +1 -1
  75. package/dist/fs/atomic.d.ts +1 -0
  76. package/dist/fs/atomic.js +4 -1
  77. package/dist/fs/atomic.js.map +1 -1
  78. package/dist/fs/stat.d.ts +1 -0
  79. package/dist/fs/stat.js +11 -0
  80. package/dist/fs/stat.js.map +1 -0
  81. package/dist/http/context.d.ts +14 -9
  82. package/dist/http/context.js +29 -20
  83. package/dist/http/context.js.map +1 -1
  84. package/dist/onboarding.d.ts +2 -2
  85. package/dist/onboarding.js +10 -8
  86. package/dist/onboarding.js.map +1 -1
  87. package/dist/profiles/profiles.d.ts +10 -4
  88. package/dist/profiles/profiles.js +77 -30
  89. package/dist/profiles/profiles.js.map +1 -1
  90. package/dist/projects.d.ts +15 -6
  91. package/dist/projects.js +55 -47
  92. package/dist/projects.js.map +1 -1
  93. package/dist/providers/catalog.d.ts +78 -12
  94. package/dist/providers/catalog.js +445 -141
  95. package/dist/providers/catalog.js.map +1 -1
  96. package/dist/providers/env-file.d.ts +10 -3
  97. package/dist/providers/env-file.js +24 -75
  98. package/dist/providers/env-file.js.map +1 -1
  99. package/dist/providers/runtime-env.d.ts +4 -2
  100. package/dist/providers/runtime-env.js +9 -6
  101. package/dist/providers/runtime-env.js.map +1 -1
  102. package/dist/providers/tables.d.ts +3 -1
  103. package/dist/providers/tables.js +4 -2
  104. package/dist/providers/tables.js.map +1 -1
  105. package/dist/redact.js +18 -9
  106. package/dist/redact.js.map +1 -1
  107. package/dist/release.d.ts +7 -0
  108. package/dist/release.js +14 -0
  109. package/dist/release.js.map +1 -1
  110. package/dist/runtime.d.ts +5 -1
  111. package/dist/runtime.js +233 -90
  112. package/dist/runtime.js.map +1 -1
  113. package/dist/server.js +10 -0
  114. package/dist/server.js.map +1 -1
  115. package/dist/sessions/anchor.d.ts +9 -3
  116. package/dist/sessions/anchor.js +28 -36
  117. package/dist/sessions/anchor.js.map +1 -1
  118. package/dist/sessions/background-events.d.ts +2 -0
  119. package/dist/sessions/background-events.js +10 -0
  120. package/dist/sessions/background-events.js.map +1 -0
  121. package/dist/sessions/background-tasks.d.ts +26 -20
  122. package/dist/sessions/background-tasks.js +88 -86
  123. package/dist/sessions/background-tasks.js.map +1 -1
  124. package/dist/sessions/background-updates.d.ts +15 -8
  125. package/dist/sessions/background-updates.js +101 -25
  126. package/dist/sessions/background-updates.js.map +1 -1
  127. package/dist/sessions/cli-sessions.d.ts +15 -5
  128. package/dist/sessions/cli-sessions.js +62 -43
  129. package/dist/sessions/cli-sessions.js.map +1 -1
  130. package/dist/sessions/completions.d.ts +30 -2
  131. package/dist/sessions/completions.js +294 -53
  132. package/dist/sessions/completions.js.map +1 -1
  133. package/dist/sessions/compress.d.ts +8 -0
  134. package/dist/sessions/compress.js +2 -2
  135. package/dist/sessions/compress.js.map +1 -1
  136. package/dist/sessions/drafts.d.ts +14 -10
  137. package/dist/sessions/drafts.js +38 -43
  138. package/dist/sessions/drafts.js.map +1 -1
  139. package/dist/sessions/gateway-sessions.d.ts +46 -0
  140. package/dist/sessions/gateway-sessions.js +378 -0
  141. package/dist/sessions/gateway-sessions.js.map +1 -0
  142. package/dist/sessions/goals.d.ts +31 -0
  143. package/dist/sessions/goals.js +75 -0
  144. package/dist/sessions/goals.js.map +1 -0
  145. package/dist/sessions/journal.d.ts +5 -79
  146. package/dist/sessions/journal.js +15 -606
  147. package/dist/sessions/journal.js.map +1 -1
  148. package/dist/sessions/list.d.ts +27 -18
  149. package/dist/sessions/list.js +133 -131
  150. package/dist/sessions/list.js.map +1 -1
  151. package/dist/sessions/merge.d.ts +68 -10
  152. package/dist/sessions/merge.js +259 -51
  153. package/dist/sessions/merge.js.map +1 -1
  154. package/dist/sessions/notices.d.ts +22 -0
  155. package/dist/sessions/notices.js +72 -0
  156. package/dist/sessions/notices.js.map +1 -0
  157. package/dist/sessions/pending.d.ts +10 -4
  158. package/dist/sessions/pending.js +83 -7
  159. package/dist/sessions/pending.js.map +1 -1
  160. package/dist/sessions/prefix-index.d.ts +82 -0
  161. package/dist/sessions/prefix-index.js +232 -0
  162. package/dist/sessions/prefix-index.js.map +1 -0
  163. package/dist/sessions/recovery.d.ts +4 -7
  164. package/dist/sessions/recovery.js +97 -281
  165. package/dist/sessions/recovery.js.map +1 -1
  166. package/dist/sessions/relay.d.ts +20 -20
  167. package/dist/sessions/relay.js +205 -127
  168. package/dist/sessions/relay.js.map +1 -1
  169. package/dist/sessions/service.d.ts +162 -59
  170. package/dist/sessions/service.js +1133 -521
  171. package/dist/sessions/service.js.map +1 -1
  172. package/dist/sessions/session.d.ts +18 -2
  173. package/dist/sessions/session.js +29 -5
  174. package/dist/sessions/session.js.map +1 -1
  175. package/dist/sessions/shares.d.ts +7 -6
  176. package/dist/sessions/shares.js +22 -45
  177. package/dist/sessions/shares.js.map +1 -1
  178. package/dist/sessions/source-kind.js +1 -0
  179. package/dist/sessions/source-kind.js.map +1 -1
  180. package/dist/sessions/state-db-identity.d.ts +18 -0
  181. package/dist/sessions/state-db-identity.js +67 -0
  182. package/dist/sessions/state-db-identity.js.map +1 -0
  183. package/dist/sessions/state-db-worker.js +3 -1
  184. package/dist/sessions/state-db-worker.js.map +1 -1
  185. package/dist/sessions/state-db.d.ts +53 -8
  186. package/dist/sessions/state-db.js +576 -50
  187. package/dist/sessions/state-db.js.map +1 -1
  188. package/dist/sessions/storage/backend.d.ts +162 -0
  189. package/dist/sessions/storage/backend.js +19 -0
  190. package/dist/sessions/storage/backend.js.map +1 -0
  191. package/dist/sessions/storage/conformance.d.ts +20 -0
  192. package/dist/sessions/storage/conformance.js +237 -0
  193. package/dist/sessions/storage/conformance.js.map +1 -0
  194. package/dist/sessions/storage/document.d.ts +16 -0
  195. package/dist/sessions/storage/document.js +44 -0
  196. package/dist/sessions/storage/document.js.map +1 -0
  197. package/dist/sessions/storage/json-documents.d.ts +23 -0
  198. package/dist/sessions/storage/json-documents.js +233 -0
  199. package/dist/sessions/storage/json-documents.js.map +1 -0
  200. package/dist/sessions/storage/json-files.d.ts +12 -0
  201. package/dist/sessions/storage/json-files.js +124 -0
  202. package/dist/sessions/storage/json-files.js.map +1 -0
  203. package/dist/sessions/storage/json-installation.d.ts +3 -0
  204. package/dist/sessions/storage/json-installation.js +31 -0
  205. package/dist/sessions/storage/json-installation.js.map +1 -0
  206. package/dist/sessions/storage/json-journal.d.ts +114 -0
  207. package/dist/sessions/storage/json-journal.js +686 -0
  208. package/dist/sessions/storage/json-journal.js.map +1 -0
  209. package/dist/sessions/storage/json-recovery.d.ts +4 -0
  210. package/dist/sessions/storage/json-recovery.js +195 -0
  211. package/dist/sessions/storage/json-recovery.js.map +1 -0
  212. package/dist/sessions/storage/json.d.ts +68 -0
  213. package/dist/sessions/storage/json.js +258 -0
  214. package/dist/sessions/storage/json.js.map +1 -0
  215. package/dist/sessions/storage/row.d.ts +6 -0
  216. package/dist/sessions/storage/row.js +49 -0
  217. package/dist/sessions/storage/row.js.map +1 -0
  218. package/dist/sessions/storage/search-text.d.ts +4 -0
  219. package/dist/sessions/storage/search-text.js +16 -0
  220. package/dist/sessions/storage/search-text.js.map +1 -0
  221. package/dist/sessions/store.d.ts +63 -73
  222. package/dist/sessions/store.js +305 -611
  223. package/dist/sessions/store.js.map +1 -1
  224. package/dist/sessions/streams.d.ts +4 -0
  225. package/dist/sessions/streams.js +9 -1
  226. package/dist/sessions/streams.js.map +1 -1
  227. package/dist/sessions/titles.js +1 -1
  228. package/dist/sessions/titles.js.map +1 -1
  229. package/dist/sessions/todo.d.ts +5 -0
  230. package/dist/sessions/todo.js +28 -21
  231. package/dist/sessions/todo.js.map +1 -1
  232. package/dist/sessions/tool-display.d.ts +5 -4
  233. package/dist/sessions/tool-display.js +22 -16
  234. package/dist/sessions/tool-display.js.map +1 -1
  235. package/dist/sessions/turn-context.d.ts +10 -1
  236. package/dist/sessions/turn-context.js +7 -4
  237. package/dist/sessions/turn-context.js.map +1 -1
  238. package/dist/sessions/turn.d.ts +87 -17
  239. package/dist/sessions/turn.js +795 -347
  240. package/dist/sessions/turn.js.map +1 -1
  241. package/dist/sessions/wakeup-pause.d.ts +8 -13
  242. package/dist/sessions/wakeup-pause.js +31 -49
  243. package/dist/sessions/wakeup-pause.js.map +1 -1
  244. package/dist/sessions/window.js +13 -12
  245. package/dist/sessions/window.js.map +1 -1
  246. package/dist/settings.d.ts +19 -7
  247. package/dist/settings.js +179 -183
  248. package/dist/settings.js.map +1 -1
  249. package/dist/sidecar/client.d.ts +17 -3
  250. package/dist/sidecar/client.js +78 -8
  251. package/dist/sidecar/client.js.map +1 -1
  252. package/dist/sidecar/discover.d.ts +2 -1
  253. package/dist/sidecar/discover.js +93 -10
  254. package/dist/sidecar/discover.js.map +1 -1
  255. package/dist/sidecar/env.d.ts +4 -0
  256. package/dist/sidecar/env.js +3 -0
  257. package/dist/sidecar/env.js.map +1 -0
  258. package/dist/sidecar/fake.js +19 -2
  259. package/dist/sidecar/fake.js.map +1 -1
  260. package/dist/test/env-file.d.ts +5 -0
  261. package/dist/test/env-file.js +88 -0
  262. package/dist/test/env-file.js.map +1 -0
  263. package/dist/test/harness.d.ts +1 -0
  264. package/dist/test/harness.js +1 -1
  265. package/dist/test/harness.js.map +1 -1
  266. package/dist/test/passkeys.d.ts +22 -0
  267. package/dist/test/passkeys.js +62 -0
  268. package/dist/test/passkeys.js.map +1 -0
  269. package/dist/test/storage.d.ts +15 -0
  270. package/dist/test/storage.js +26 -0
  271. package/dist/test/storage.js.map +1 -0
  272. package/dist/tools/commands.d.ts +6 -1
  273. package/dist/tools/commands.js +8 -2
  274. package/dist/tools/commands.js.map +1 -1
  275. package/dist/tools/connectors.d.ts +33 -0
  276. package/dist/tools/connectors.js +121 -0
  277. package/dist/tools/connectors.js.map +1 -0
  278. package/dist/tools/crons.d.ts +38 -1
  279. package/dist/tools/crons.js +82 -15
  280. package/dist/tools/crons.js.map +1 -1
  281. package/dist/tools/dashboard-plugins.d.ts +5 -5
  282. package/dist/tools/dashboard-plugins.js +14 -14
  283. package/dist/tools/dashboard-plugins.js.map +1 -1
  284. package/dist/tools/extensions.d.ts +5 -4
  285. package/dist/tools/extensions.js +213 -207
  286. package/dist/tools/extensions.js.map +1 -1
  287. package/dist/tools/gateway-restart.d.ts +62 -0
  288. package/dist/tools/gateway-restart.js +142 -0
  289. package/dist/tools/gateway-restart.js.map +1 -0
  290. package/dist/tools/health.d.ts +15 -3
  291. package/dist/tools/health.js +97 -34
  292. package/dist/tools/health.js.map +1 -1
  293. package/dist/tools/hygiene.d.ts +4 -3
  294. package/dist/tools/hygiene.js +23 -9
  295. package/dist/tools/hygiene.js.map +1 -1
  296. package/dist/tools/kanban.d.ts +4 -2
  297. package/dist/tools/kanban.js +28 -19
  298. package/dist/tools/kanban.js.map +1 -1
  299. package/dist/tools/memory-masks.d.ts +5 -0
  300. package/dist/tools/memory-masks.js +256 -0
  301. package/dist/tools/memory-masks.js.map +1 -0
  302. package/dist/tools/memory.d.ts +29 -3
  303. package/dist/tools/memory.js +69 -27
  304. package/dist/tools/memory.js.map +1 -1
  305. package/dist/tools/plugin-settings.d.ts +15 -0
  306. package/dist/tools/plugin-settings.js +90 -0
  307. package/dist/tools/plugin-settings.js.map +1 -0
  308. package/dist/tools/skills.d.ts +9 -4
  309. package/dist/tools/skills.js +44 -13
  310. package/dist/tools/skills.js.map +1 -1
  311. package/dist/tools/update-notifications.d.ts +34 -15
  312. package/dist/tools/update-notifications.js +141 -57
  313. package/dist/tools/update-notifications.js.map +1 -1
  314. package/dist/tools/update-rollback.d.ts +11 -0
  315. package/dist/tools/update-rollback.js +28 -0
  316. package/dist/tools/update-rollback.js.map +1 -0
  317. package/dist/tools/updates.d.ts +93 -33
  318. package/dist/tools/updates.js +1051 -345
  319. package/dist/tools/updates.js.map +1 -1
  320. package/dist/util.d.ts +2 -0
  321. package/dist/util.js +5 -0
  322. package/dist/util.js.map +1 -1
  323. package/dist/workspace/git.d.ts +16 -1
  324. package/dist/workspace/git.js +291 -11
  325. package/dist/workspace/git.js.map +1 -1
  326. package/dist/workspace/media.d.ts +12 -9
  327. package/dist/workspace/media.js +31 -20
  328. package/dist/workspace/media.js.map +1 -1
  329. package/dist/workspace/rollback.d.ts +2 -2
  330. package/dist/workspace/rollback.js +5 -5
  331. package/dist/workspace/rollback.js.map +1 -1
  332. package/dist/workspace/workspaces.d.ts +15 -19
  333. package/dist/workspace/workspaces.js +55 -127
  334. package/dist/workspace/workspaces.js.map +1 -1
  335. package/dist/workspace/worktrees.js +170 -32
  336. package/dist/workspace/worktrees.js.map +1 -1
  337. package/package.json +5 -3
  338. package/sidecar/agent_dependency.json +4 -4
  339. package/sidecar/agent_support.json +26 -0
  340. package/sidecar/scripts/record-fixtures.py +12 -3
  341. package/sidecar/scripts/replay_sidecar.py +8 -0
  342. package/sidecar/scripts/suite_runner.py +302 -0
  343. package/sidecar/scripts/test.sh +12 -4
  344. package/sidecar/talaria_sidecar/__init__.py +6 -1
  345. package/sidecar/talaria_sidecar/__main__.py +4 -2
  346. package/sidecar/talaria_sidecar/agent_mutation.py +975 -0
  347. package/sidecar/talaria_sidecar/agent_services.py +1053 -0
  348. package/sidecar/talaria_sidecar/dependency_sync.py +85 -0
  349. package/sidecar/talaria_sidecar/home.py +43 -1
  350. package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
  351. package/sidecar/talaria_sidecar/methods/aux.py +139 -31
  352. package/sidecar/talaria_sidecar/methods/chat.py +847 -134
  353. package/sidecar/talaria_sidecar/methods/commands.py +213 -4
  354. package/sidecar/talaria_sidecar/methods/config.py +123 -4
  355. package/sidecar/talaria_sidecar/methods/connectors.py +343 -0
  356. package/sidecar/talaria_sidecar/methods/cron.py +366 -34
  357. package/sidecar/talaria_sidecar/methods/cron_execution.py +284 -0
  358. package/sidecar/talaria_sidecar/methods/gateway.py +194 -54
  359. package/sidecar/talaria_sidecar/methods/gateway_sessions.py +234 -0
  360. package/sidecar/talaria_sidecar/methods/goals.py +81 -41
  361. package/sidecar/talaria_sidecar/methods/kanban.py +80 -27
  362. package/sidecar/talaria_sidecar/methods/memory.py +84 -0
  363. package/sidecar/talaria_sidecar/methods/oauth.py +5 -2
  364. package/sidecar/talaria_sidecar/methods/process.py +160 -11
  365. package/sidecar/talaria_sidecar/methods/profiles.py +44 -6
  366. package/sidecar/talaria_sidecar/methods/providers.py +196 -26
  367. package/sidecar/talaria_sidecar/methods/runtime.py +69 -1
  368. package/sidecar/talaria_sidecar/methods/skills.py +67 -4
  369. package/sidecar/talaria_sidecar/methods/state_db.py +277 -70
  370. package/sidecar/talaria_sidecar/methods/stt.py +159 -78
  371. package/sidecar/talaria_sidecar/methods/text.py +14 -1
  372. package/sidecar/talaria_sidecar/methods/toolsets.py +49 -0
  373. package/sidecar/talaria_sidecar/methods/usage.py +113 -14
  374. package/sidecar/talaria_sidecar/methods/worktree.py +26 -19
  375. package/sidecar/talaria_sidecar/methods/write_approval.py +181 -0
  376. package/sidecar/talaria_sidecar/rpc.py +45 -4
  377. package/sidecar/talaria_sidecar/runtime.py +81 -12
  378. package/sidecar/talaria_sidecar/speed.py +35 -0
  379. package/static/dist/FILES.txt +126 -127
  380. package/static/dist/assets/AppShell-cey33v9s.js +8 -0
  381. package/static/dist/assets/ChatPage-i8wnugr7.js +18 -0
  382. package/static/dist/assets/ConnectTargets-hg19553x.js +1 -0
  383. package/static/dist/assets/ExtensionRoute-cly4apm5.js +1 -0
  384. package/static/dist/assets/Field-j8uqoigz.js +9 -0
  385. package/static/dist/assets/HubRoute-e4bgz41j.js +2 -0
  386. package/static/dist/assets/Markdown-lahuichm.js +598 -0
  387. package/static/dist/assets/RightPanel-lbo4i0fn.js +1 -0
  388. package/static/dist/assets/Select-gqatm2e0.js +1 -0
  389. package/static/dist/assets/SessionListPanel-mfqayfjh.js +1 -0
  390. package/static/dist/assets/SettingsLayout-b8980u7k.js +1 -0
  391. package/static/dist/assets/States-e7dkgtxf.js +1 -0
  392. package/static/dist/assets/Toaster-bfqqy786.js +1 -0
  393. package/static/dist/assets/_app-n1n6pfx1.js +1 -0
  394. package/static/dist/assets/{_app.ext._extensionId-gfbzpoou.js → _app.ext._extensionId-buxjxav3.js} +1 -1
  395. package/static/dist/assets/_app.index-jt8zwiu2.js +1 -0
  396. package/static/dist/assets/_app.insights-cv76ml71.js +1 -0
  397. package/static/dist/assets/_app.kanban-h6ts53j7.js +1 -0
  398. package/static/dist/assets/_app.logs-dm873z90.js +1 -0
  399. package/static/dist/assets/_app.memory-glk5y6m8.js +1 -0
  400. package/static/dist/assets/_app.profiles-ka6zpstq.js +1 -0
  401. package/static/dist/assets/{_app.session._sessionId-fn1bhde6.js → _app.session._sessionId-g2vzghvc.js} +1 -1
  402. package/static/dist/assets/_app.settings-hgjdhzcd.js +1 -0
  403. package/static/dist/assets/_app.settings._section-jf2kmhae.js +3 -0
  404. package/static/dist/assets/_app.skills-cii852yq.js +1 -0
  405. package/static/dist/assets/_app.tasks-fp9q7atm.js +1 -0
  406. package/static/dist/assets/_app.todos-dw94qzue.js +1 -0
  407. package/static/dist/assets/_app.workspaces-inyygzze.js +1 -0
  408. package/static/dist/assets/{abnfDiagram-VCTEODGH-c8kdixke.js → abnfDiagram-VCTEODGH-gjayq3ra.js} +1 -1
  409. package/static/dist/assets/architecture-7GRP2DOG-lp56972r.js +1 -0
  410. package/static/dist/assets/{architectureDiagram-5GKGNRK7-cku06x1p.js → architectureDiagram-5GKGNRK7-nwb3xovn.js} +1 -1
  411. package/static/dist/assets/archive-b1j004vn.js +1 -0
  412. package/static/dist/assets/back-g74gkozu.js +1 -0
  413. package/static/dist/assets/{blockDiagram-I7D4REHJ-jzthp1wa.js → blockDiagram-I7D4REHJ-joedghi3.js} +1 -1
  414. package/static/dist/assets/{c4Diagram-7LVT6UL2-mwr67mt8.js → c4Diagram-7LVT6UL2-hyrjrohe.js} +1 -1
  415. package/static/dist/assets/channel-es95o4y8.js +1 -0
  416. package/static/dist/assets/{chunk-4HAMMTFA-gpq1y228.js → chunk-4HAMMTFA-koouqbut.js} +1 -1
  417. package/static/dist/assets/{chunk-75Z2AOVW-ktje58c4.js → chunk-75Z2AOVW-bl4bhdnt.js} +1 -1
  418. package/static/dist/assets/{chunk-DU6HZSFF-ofajdixh.js → chunk-DU6HZSFF-gpedttsp.js} +3 -3
  419. package/static/dist/assets/{chunk-F27PBJKO-cmev85ti.js → chunk-F27PBJKO-d8xxi0zi.js} +1 -1
  420. package/static/dist/assets/{chunk-GMAD6QVW-htjgt22y.js → chunk-GMAD6QVW-jro0hl73.js} +1 -1
  421. package/static/dist/assets/{chunk-GVQU2GXP-qndvoxl7.js → chunk-GVQU2GXP-djn6gbyu.js} +1 -1
  422. package/static/dist/assets/{chunk-IMKFNOWR-e5bkd5q6.js → chunk-IMKFNOWR-vw4p5p7o.js} +1 -1
  423. package/static/dist/assets/{chunk-L3NEJ4N5-mj1155r6.js → chunk-L3NEJ4N5-n1hj77q8.js} +1 -1
  424. package/static/dist/assets/{chunk-OSK3NFVY-e7gkikcw.js → chunk-OSK3NFVY-oy0gwn2n.js} +1 -1
  425. package/static/dist/assets/{chunk-P2QGCYS3-f7t54xfm.js → chunk-P2QGCYS3-onf1hz6c.js} +1 -1
  426. package/static/dist/assets/{chunk-POPQ4Y6H-i927v9oa.js → chunk-POPQ4Y6H-m8sqn7cs.js} +1 -1
  427. package/static/dist/assets/{chunk-PWAF6VOD-m84lmnyt.js → chunk-PWAF6VOD-ek4smc8x.js} +1 -1
  428. package/static/dist/assets/{chunk-SHT3W25Y-mi0tlcu9.js → chunk-SHT3W25Y-g9gfvefo.js} +3 -3
  429. package/static/dist/assets/{chunk-SVP7TREG-dnau702j.js → chunk-SVP7TREG-f9nfv2cu.js} +1 -1
  430. package/static/dist/assets/{chunk-TICWLB2K-edem1gkg.js → chunk-TICWLB2K-bnk3m1mq.js} +1 -1
  431. package/static/dist/assets/classDiagram-ZZMXUADV-kmihoqxh.js +1 -0
  432. package/static/dist/assets/classDiagram-v2-VYDZK3BY-kmihoqxh.js +1 -0
  433. package/static/dist/assets/copied-bli9tbcx.js +1 -0
  434. package/static/dist/assets/{copy-magtofyp.js → copy-jamtd1pf.js} +1 -1
  435. package/static/dist/assets/{cynefin-OW5HDTMX-siqlulkl.js → cynefin-OW5HDTMX-f8xfdd3f.js} +1 -1
  436. package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-i648tah9.js → cynefinDiagram-5FMLGOSQ-n9lb99h9.js} +1 -1
  437. package/static/dist/assets/{dagre-GXQ25YYZ-mwn6uc17.js → dagre-GXQ25YYZ-dgailddi.js} +4 -4
  438. package/static/dist/assets/{diagram-S7CK7UJ4-l8abxaes.js → diagram-S7CK7UJ4-m6aeoe7c.js} +1 -1
  439. package/static/dist/assets/{diagram-UQ7AKVKN-mekq7zgq.js → diagram-UQ7AKVKN-jall3j0x.js} +1 -1
  440. package/static/dist/assets/{diagram-VSXAHHWV-fnky6lvc.js → diagram-VSXAHHWV-hbawi7hn.js} +1 -1
  441. package/static/dist/assets/{diagram-VX7I27RA-xe6r5qfw.js → diagram-VX7I27RA-hendl2tt.js} +1 -1
  442. package/static/dist/assets/{diagram-Z3DM3KII-nq07dg7k.js → diagram-Z3DM3KII-igwc35p3.js} +1 -1
  443. package/static/dist/assets/{ebnfDiagram-PWID7BFC-c62ipm3g.js → ebnfDiagram-PWID7BFC-c64knz08.js} +1 -1
  444. package/static/dist/assets/{erDiagram-RLTQ6QDP-h39kmnzy.js → erDiagram-RLTQ6QDP-brdu9lcm.js} +1 -1
  445. package/static/dist/assets/eventmodeling-NTZA5JFV-njk1j8wl.js +1 -0
  446. package/static/dist/assets/flowDiagram-HODETNUW-nma6f0ga.js +1 -0
  447. package/static/dist/assets/folder-plus-lvt9kudb.js +1 -0
  448. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-ngbsyp37.js → ganttDiagram-EL5Y4UJY-ma6jxj5i.js} +1 -1
  449. package/static/dist/assets/{gitGraph-4MIJSDKK-fr2i7caa.js → gitGraph-4MIJSDKK-naa9w6xa.js} +1 -1
  450. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-eravdti4.js → gitGraphDiagram-WWUBYQGX-hzltvsod.js} +1 -1
  451. package/static/dist/assets/{highlighted-body-KPVGNVTW-jwpop9p8.js → highlighted-body-KPVGNVTW-ghoavj8d.js} +1 -1
  452. package/static/dist/assets/host-hzm8n85n.js +1 -0
  453. package/static/dist/assets/index-drdcaqeq.css +2 -0
  454. package/static/dist/assets/index-jzm844he.js +11 -0
  455. package/static/dist/assets/{info-A6RAGUB7-h11x0dxo.js → info-A6RAGUB7-mn2ut5ko.js} +1 -1
  456. package/static/dist/assets/{infoDiagram-27XIBGKW-dfh47dw9.js → infoDiagram-27XIBGKW-h6kuqvsb.js} +1 -1
  457. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-i6ypq351.js → ishikawaDiagram-5VMMS53U-e7bnwq7h.js} +1 -1
  458. package/static/dist/assets/{journeyDiagram-3NMN7TZE-lduf1z95.js → journeyDiagram-3NMN7TZE-etd1bi6p.js} +1 -1
  459. package/static/dist/assets/{kanban-definition-UXKFOSKX-e18bu4pg.js → kanban-definition-UXKFOSKX-emb1g9dz.js} +4 -4
  460. package/static/dist/assets/lazyRouteComponent-o816ytzl.js +1 -0
  461. package/static/dist/assets/{line-meizqsvn.js → line-h0ojzsvs.js} +1 -1
  462. package/static/dist/assets/link-k01ryaf9.js +1 -0
  463. package/static/dist/assets/login-bsae49ew.js +1 -0
  464. package/static/dist/assets/mermaid-HWGCJPDP-ihl34s74.js +1 -0
  465. package/static/dist/assets/{mermaid-parser.core-ntne45i9.js → mermaid-parser.core-bnre27u8.js} +3 -3
  466. package/static/dist/assets/{mindmap-definition-YA3MSWOX-27b26eok.js → mindmap-definition-YA3MSWOX-o1vathns.js} +1 -1
  467. package/static/dist/assets/onboarding-c65tysya.js +1 -0
  468. package/static/dist/assets/onboarding_model_label-gpn28uix.js +1 -0
  469. package/static/dist/assets/{packet-AYTQ26CC-l6jdka8p.js → packet-AYTQ26CC-hatq7m2e.js} +1 -1
  470. package/static/dist/assets/pcmTap.worklet-74EKjWAZ.js +1 -0
  471. package/static/dist/assets/{pegDiagram-XKGWAZYB-g1er3bxj.js → pegDiagram-XKGWAZYB-gwisz8jv.js} +1 -1
  472. package/static/dist/assets/{pie-WAS4IAKB-i0ylcrt9.js → pie-WAS4IAKB-fpftf0mk.js} +1 -1
  473. package/static/dist/assets/{pieDiagram-E7YTZNPT-fbz1e55z.js → pieDiagram-E7YTZNPT-khm1o9a6.js} +1 -1
  474. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-hhue7d8o.js → quadrantDiagram-AXDQQJYC-owqc4uqn.js} +1 -1
  475. package/static/dist/assets/{radar-RG4KPBEZ-f9b70aa4.js → radar-RG4KPBEZ-cntfwjpq.js} +1 -1
  476. package/static/dist/assets/{railroad-74A4TZTK-lgsuoeda.js → railroad-74A4TZTK-a7t5eibp.js} +1 -1
  477. package/static/dist/assets/railroad-abnf-HS5TGJTU-ol8cdktf.js +1 -0
  478. package/static/dist/assets/railroad-ebnf-LZEXJU2U-i8vzd429.js +1 -0
  479. package/static/dist/assets/railroad-peg-WCYAUIDC-nw3ulewz.js +1 -0
  480. package/static/dist/assets/{railroadDiagram-O6MQD6OU-eqpy9fnz.js → railroadDiagram-O6MQD6OU-etuh0qa0.js} +1 -1
  481. package/static/dist/assets/{refresh-cw-hlwb02qv.js → refresh-cw-mqbkv2a3.js} +1 -1
  482. package/static/dist/assets/refresh-l29ljp76.js +1 -0
  483. package/static/dist/assets/{requirementDiagram-BXWQKSXE-ogf6puhi.js → requirementDiagram-BXWQKSXE-oq2ulk22.js} +1 -1
  484. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-fqb8xcjf.js → sankeyDiagram-P5KCCOFB-iqc02emv.js} +1 -1
  485. package/static/dist/assets/saved-ndd4t2xb.js +1 -0
  486. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-dlcz6qjz.js → sequenceDiagram-WJ2MYXX4-i0v116q0.js} +2 -2
  487. package/static/dist/assets/settings_section_extensions_title-jhfo6o8z.js +1 -0
  488. package/static/dist/assets/share._token-c1ri0hy1.js +2 -0
  489. package/static/dist/assets/sliders-horizontal-j3jjt9tv.js +1 -0
  490. package/static/dist/assets/{stateDiagram-D77RDMKH-fyoznpcs.js → stateDiagram-D77RDMKH-dnpt1ato.js} +1 -1
  491. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-bxjacpk6.js +1 -0
  492. package/static/dist/assets/{swimlanes-42K2YHIH-oefldhfy.js → swimlanes-42K2YHIH-loqbdazb.js} +1 -1
  493. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-id62p9hz.js +8 -0
  494. package/static/dist/assets/{timeline-definition-24CTP7MA-b1vl2zil.js → timeline-definition-24CTP7MA-ol2hnvma.js} +1 -1
  495. package/static/dist/assets/toast-i3h34v6o.js +64 -0
  496. package/static/dist/assets/{treeView-Q6P3EWNA-f7hcci5o.js → treeView-Q6P3EWNA-idrj6iox.js} +1 -1
  497. package/static/dist/assets/{treemap-WGGIJYW6-nl85071a.js → treemap-WGGIJYW6-lzr49vv5.js} +1 -1
  498. package/static/dist/assets/untitled-oaoya4qj.js +1 -0
  499. package/static/dist/assets/useForm-nfaxgmsk.js +1 -0
  500. package/static/dist/assets/{useParams-b4dq6n4q.js → useParams-gjc70qru.js} +1 -1
  501. package/static/dist/assets/{useSearch-ipfmv3he.js → useSearch-e6ae539u.js} +1 -1
  502. package/static/dist/assets/{vennDiagram-4TSXK5OY-h5hzbk0n.js → vennDiagram-4TSXK5OY-bvwr9o2z.js} +1 -1
  503. package/static/dist/assets/{wardley-WFR3VGLG-jftvpm3e.js → wardley-WFR3VGLG-31ui8tma.js} +1 -1
  504. package/static/dist/assets/{wardleyDiagram-VM6X3IG4-hedh85ge.js → wardleyDiagram-VM6X3IG4-k5wqtx4b.js} +1 -1
  505. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-e49523ab.js → xychartDiagram-S5SC5T6Z-aqbgvujg.js} +1 -1
  506. package/static/dist/index.html +1 -1
  507. package/static/dist/sw.js +1 -1
  508. package/static/dist/assets/AppShell-g3bkgnvt.js +0 -1
  509. package/static/dist/assets/ChatPage-oo7bdan6.js +0 -25
  510. package/static/dist/assets/Dialog-g355qxhp.js +0 -1
  511. package/static/dist/assets/ExtensionRoute-i2y9fvjm.js +0 -1
  512. package/static/dist/assets/HubRoute-lmkrbw47.js +0 -2
  513. package/static/dist/assets/Markdown-j4kut4j2.js +0 -598
  514. package/static/dist/assets/RightPanel-ohlsdzfl.js +0 -1
  515. package/static/dist/assets/Select-kddq75qc.js +0 -1
  516. package/static/dist/assets/SessionListPanel-lu3oy0hw.js +0 -1
  517. package/static/dist/assets/SettingsLayout-o9bv4mgb.js +0 -1
  518. package/static/dist/assets/States-eq6fe29m.js +0 -1
  519. package/static/dist/assets/Toaster-pc247u9f.js +0 -1
  520. package/static/dist/assets/_app-f8n1i0m1.js +0 -1
  521. package/static/dist/assets/_app.index-bzzv80hk.js +0 -1
  522. package/static/dist/assets/_app.insights-dzixbryi.js +0 -1
  523. package/static/dist/assets/_app.kanban-c6hep2us.js +0 -1
  524. package/static/dist/assets/_app.logs-i69qds98.js +0 -1
  525. package/static/dist/assets/_app.memory-kl4vf0gd.js +0 -1
  526. package/static/dist/assets/_app.profiles-b8zinmyp.js +0 -1
  527. package/static/dist/assets/_app.settings-cg8plwmf.js +0 -1
  528. package/static/dist/assets/_app.settings._section-bkwbi9zn.js +0 -3
  529. package/static/dist/assets/_app.skills-cs47sbvs.js +0 -1
  530. package/static/dist/assets/_app.tasks-dwvk64tc.js +0 -1
  531. package/static/dist/assets/_app.todos-c8xjm8p3.js +0 -1
  532. package/static/dist/assets/_app.workspaces-ehvd1gds.js +0 -1
  533. package/static/dist/assets/architecture-7GRP2DOG-6crvnylg.js +0 -1
  534. package/static/dist/assets/back-h7aun7ew.js +0 -1
  535. package/static/dist/assets/cancel-fhi0vcnu.js +0 -1
  536. package/static/dist/assets/channel-b2zo73z1.js +0 -1
  537. package/static/dist/assets/classDiagram-ZZMXUADV-oe99st8x.js +0 -1
  538. package/static/dist/assets/classDiagram-v2-VYDZK3BY-oe99st8x.js +0 -1
  539. package/static/dist/assets/copied-hcplv46p.js +0 -1
  540. package/static/dist/assets/endpoints-klbxod4t.js +0 -64
  541. package/static/dist/assets/eventmodeling-NTZA5JFV-obfede4u.js +0 -1
  542. package/static/dist/assets/flowDiagram-HODETNUW-kdpsp1je.js +0 -1
  543. package/static/dist/assets/host-i828xuo7.js +0 -1
  544. package/static/dist/assets/index-eh8zilnv.css +0 -2
  545. package/static/dist/assets/index-r648f4o1.js +0 -11
  546. package/static/dist/assets/lazyRouteComponent-e1y4t2i9.js +0 -1
  547. package/static/dist/assets/link-oot2yn73.js +0 -1
  548. package/static/dist/assets/login-gu28l9ou.js +0 -1
  549. package/static/dist/assets/mermaid-HWGCJPDP-mtwrj8fn.js +0 -1
  550. package/static/dist/assets/onboarding-lkphzu1s.js +0 -1
  551. package/static/dist/assets/onboarding_model_label-ftpjdwqk.js +0 -1
  552. package/static/dist/assets/railroad-abnf-HS5TGJTU-nf9d6pdx.js +0 -1
  553. package/static/dist/assets/railroad-ebnf-LZEXJU2U-f7ummkt5.js +0 -1
  554. package/static/dist/assets/railroad-peg-WCYAUIDC-oczq5tqs.js +0 -1
  555. package/static/dist/assets/refresh-abtu93ke.js +0 -1
  556. package/static/dist/assets/saved-girnabkf.js +0 -1
  557. package/static/dist/assets/settings_section_extensions_title-h14cwk6f.js +0 -1
  558. package/static/dist/assets/share._token-kl0r7ido.js +0 -2
  559. package/static/dist/assets/sliders-horizontal-n1zm34qq.js +0 -1
  560. package/static/dist/assets/sse-iwku0sjo.js +0 -1
  561. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-ixhx8r46.js +0 -1
  562. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-h9ersk2e.js +0 -8
  563. package/static/dist/assets/todoStore-jjr5yr78.js +0 -1
  564. package/static/dist/assets/units-kgxzxfhi.js +0 -1
  565. package/static/dist/assets/untitled-cikfjntn.js +0 -1
  566. package/static/dist/assets/useForm-kqoqg0k9.js +0 -1
  567. package/static/dist/assets/useLocale-o59tbiea.js +0 -1
@@ -5,7 +5,8 @@ import { resolvePathLikePython } from '../workspace/paths.js';
5
5
  import { createHash } from 'node:crypto';
6
6
  import { closeSync, existsSync, fstatSync, lstatSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
7
7
  import { dirname, join, relative, resolve, sep } from 'node:path';
8
- import { atomicWriteText } from '../fs/atomic.js';
8
+ import { InvalidDocument } from '../sessions/storage/backend.js';
9
+ import { readDocument } from '../sessions/storage/document.js';
9
10
  import { readZip } from '../workspace/unzip.js';
10
11
  import { isDict } from '../config/agent-config.js';
11
12
  import { str } from '../util.js';
@@ -339,8 +340,7 @@ export class ExtensionService {
339
340
  this.deps = deps;
340
341
  }
341
342
  get defaultRoot() { return join(this.deps.stateDir, 'extensions'); }
342
- get stateFile() { return join(this.deps.stateDir, 'extension-overrides.json'); }
343
- get installFile() { return join(this.deps.stateDir, 'extension-install-manifest.json'); }
343
+ revisions = new Map();
344
344
  root() {
345
345
  const raw = (this.deps.env.HERMES_WEBUI_EXTENSION_DIR ?? '').trim();
346
346
  if (raw) {
@@ -365,22 +365,25 @@ export class ExtensionService {
365
365
  return null;
366
366
  }
367
367
  }
368
- loadState(d) {
368
+ async loadState(d) {
369
369
  const empty = { version: 1, disabled_extensions: [], sidecar_proxy_consents: {} };
370
370
  const src = 'extension_state';
371
371
  let parsed;
372
372
  try {
373
- if (!existsSync(this.stateFile) || !statSync(this.stateFile).isFile())
373
+ const record = await readDocument(this.deps.documents, 'extensions', 'overrides', { replaceInvalid: true, maxBytes: MAX_STATE_BYTES });
374
+ this.revisions.set('overrides', record?.revision ?? null);
375
+ if (!record)
374
376
  return empty;
375
- const raw = readFileSync(this.stateFile);
376
- if (raw.length > MAX_STATE_BYTES) {
377
+ if (Buffer.byteLength(JSON.stringify(record.value)) > MAX_STATE_BYTES) {
377
378
  warn(d, 'extension_state_oversized', src);
378
379
  return empty;
379
380
  }
380
- parsed = JSON.parse(raw.toString('utf8'));
381
+ parsed = record.value;
381
382
  }
382
- catch {
383
- warn(d, 'extension_state_unreadable', src);
383
+ catch (error) {
384
+ if (error instanceof InvalidDocument && error.reason === 'too-large')
385
+ this.revisions.set('overrides', error.revision);
386
+ warn(d, error instanceof InvalidDocument && error.reason === 'too-large' ? 'extension_state_oversized' : 'extension_state_unreadable', src);
384
387
  return empty;
385
388
  }
386
389
  if (!isDict(parsed)) {
@@ -440,19 +443,17 @@ export class ExtensionService {
440
443
  warn(d, 'extension_state_invalid_entries', src);
441
444
  return { version: 1, disabled_extensions: disabled, sidecar_proxy_consents: consents };
442
445
  }
443
- writeState(state) {
444
- mkdirSync(this.deps.stateDir, { recursive: true });
445
- atomicWriteText(this.stateFile, JSON.stringify({ version: 1, disabled_extensions: [...new Set(state.disabled_extensions.filter(validId))].sort(), sidecar_proxy_consents: state.sidecar_proxy_consents }, null, 2));
446
+ async writeState(state) {
447
+ this.revisions.set('overrides', await this.deps.documents.put('extensions', 'overrides', { version: 1, disabled_extensions: [...new Set(state.disabled_extensions.filter(validId))].sort(), sidecar_proxy_consents: state.sidecar_proxy_consents }, this.revisions.get('overrides') ?? null));
446
448
  }
447
- loadInstallManifest() {
449
+ async loadInstallManifest() {
448
450
  const empty = { version: 1, installed: {} };
449
451
  try {
450
- if (!existsSync(this.installFile))
452
+ const record = await readDocument(this.deps.documents, 'extensions', 'install-manifest', { replaceInvalid: true, maxBytes: MAX_INSTALL_MANIFEST_BYTES });
453
+ this.revisions.set('install-manifest', record?.revision ?? null);
454
+ if (!record || Buffer.byteLength(JSON.stringify(record.value)) > MAX_INSTALL_MANIFEST_BYTES)
451
455
  return empty;
452
- const raw = readFileSync(this.installFile);
453
- if (raw.length > MAX_INSTALL_MANIFEST_BYTES)
454
- return empty;
455
- const parsed = JSON.parse(raw.toString('utf8'));
456
+ const parsed = record.value;
456
457
  if (!isDict(parsed) || !isDict(parsed.installed))
457
458
  return empty;
458
459
  const installed = {};
@@ -465,13 +466,14 @@ export class ExtensionService {
465
466
  }
466
467
  return { version: 1, installed };
467
468
  }
468
- catch {
469
+ catch (error) {
470
+ if (error instanceof InvalidDocument && error.reason === 'too-large')
471
+ this.revisions.set('install-manifest', error.revision);
469
472
  return empty;
470
473
  }
471
474
  }
472
- writeInstallManifest(manifest) {
473
- mkdirSync(this.deps.stateDir, { recursive: true });
474
- atomicWriteText(this.installFile, JSON.stringify(manifest, null, 2));
475
+ async writeInstallManifest(manifest) {
476
+ this.revisions.set('install-manifest', await this.deps.documents.put('extensions', 'install-manifest', manifest, this.revisions.get('install-manifest') ?? null));
475
477
  }
476
478
  manifestPath(root) {
477
479
  const raw = (this.deps.env.HERMES_WEBUI_EXTENSION_MANIFEST ?? '').trim();
@@ -492,8 +494,8 @@ export class ExtensionService {
492
494
  return [null, 'invalid_path'];
493
495
  return [manifest, 'configured'];
494
496
  }
495
- galleryManifest(root, d) {
496
- const installed = this.loadInstallManifest().installed;
497
+ async galleryManifest(root, d) {
498
+ const installed = (await this.loadInstallManifest()).installed;
497
499
  const entries = [];
498
500
  for (const id of Object.keys(installed).sort()) {
499
501
  if (!validId(id))
@@ -550,14 +552,14 @@ export class ExtensionService {
550
552
  }
551
553
  return entries.length ? { extensions: entries } : null;
552
554
  }
553
- loadManifest(root, d) {
555
+ async loadManifest(root, d) {
554
556
  const [file, pathStatus] = this.manifestPath(root);
555
557
  const status = { configured: pathStatus !== 'not_configured', loaded: false, status: pathStatus, _asset_base: '', entry_count: 0, script_count: 0, stylesheet_count: 0, sidecar_count: 0 };
556
558
  if (!file) {
557
559
  if (pathStatus === 'invalid_path')
558
560
  warn(d, 'manifest_invalid_path', 'manifest');
559
561
  else if (pathStatus === 'not_configured') {
560
- const gallery = this.galleryManifest(root, d);
562
+ const gallery = (await this.galleryManifest(root, d));
561
563
  if (gallery)
562
564
  return [gallery, { ...status, loaded: true, status: 'gallery_installed' }];
563
565
  }
@@ -739,7 +741,7 @@ export class ExtensionService {
739
741
  const d = { warnings: [] };
740
742
  const envDir = (this.deps.env.HERMES_WEBUI_EXTENSION_DIR ?? '').trim();
741
743
  const root = this.root();
742
- const state = this.loadState(d);
744
+ const state = (await this.loadState(d));
743
745
  const disabled = new Set(state.disabled_extensions);
744
746
  const manifestConfigured = Boolean((this.deps.env.HERMES_WEBUI_EXTENSION_MANIFEST ?? '').trim());
745
747
  if (envDir && !root)
@@ -747,7 +749,7 @@ export class ExtensionService {
747
749
  if (!root) {
748
750
  return { manifest: null, assetBase: '', sidecarsById: new Map(), status: { enabled: false, extension_dir_configured: true, extension_dir_valid: false, script_urls: [], stylesheet_urls: [], sidecars: [], counts: { script_urls: 0, stylesheet_urls: 0, sidecars: 0, manifest_extensions: 0, user_disabled: 0 }, manifest: { configured: manifestConfigured, loaded: false, status: manifestConfigured ? 'extension_disabled' : 'not_configured', entry_count: 0, script_count: 0, stylesheet_count: 0, sidecar_count: 0 }, extensions: [], warnings: d.warnings } };
749
751
  }
750
- const [manifest, status] = this.loadManifest(root, d);
752
+ const [manifest, status] = (await this.loadManifest(root, d));
751
753
  const consentIds = new Set(Object.keys(state.sidecar_proxy_consents));
752
754
  const ext = manifest !== null ? this.extensionState(manifest, disabled, d, consentIds) : { extensions: [], knownIds: new Set(), manifestDisabled: new Set() };
753
755
  const urls = manifest !== null ? await this.manifestUrls(manifest, status, disabled, state, d) : { scripts: [], stylesheets: [], sidecars: [], sidecarsById: new Map() };
@@ -757,12 +759,12 @@ export class ExtensionService {
757
759
  return { manifest, assetBase: str(status._asset_base), sidecarsById: urls.sidecarsById, status: {
758
760
  enabled: true, extension_dir_configured: true, extension_dir_valid: true, script_urls: scriptUrls, stylesheet_urls: stylesheetUrls, sidecars: urls.sidecars,
759
761
  counts: { script_urls: scriptUrls.length, stylesheet_urls: stylesheetUrls.length, sidecars: urls.sidecars.length, manifest_extensions: ext.extensions.length, user_disabled: [...disabled].filter((id) => ext.knownIds.has(id)).length },
760
- manifest: publicStatus, extensions: ext.extensions, gallery_installed: this.loadInstallManifest().installed, warnings: d.warnings,
762
+ manifest: publicStatus, extensions: ext.extensions, gallery_installed: (await this.loadInstallManifest()).installed, warnings: d.warnings,
761
763
  } };
762
764
  }
763
- loaded(root, d) {
764
- const state = this.loadState(d);
765
- const [manifest, status] = this.loadManifest(root, d);
765
+ async loaded(root, d) {
766
+ const state = (await this.loadState(d));
767
+ const [manifest, status] = (await this.loadManifest(root, d));
766
768
  if (manifest === null || status.loaded !== true)
767
769
  throw new ExtensionError('Extension manifest is not loaded', 409);
768
770
  return { manifest, state, disabled: new Set(state.disabled_extensions) };
@@ -777,14 +779,14 @@ export class ExtensionService {
777
779
  throw new ExtensionError('Invalid extension id', 400);
778
780
  if (typeof enabled !== 'boolean')
779
781
  throw new ExtensionError('enabled must be a boolean', 400);
780
- return this.mutateState(async () => this.setEnabledLocked(idRaw.trim(), enabled));
782
+ return this.mutateState(async () => (await this.setEnabledLocked(idRaw.trim(), enabled)));
781
783
  }
782
784
  async setEnabledLocked(id, enabled) {
783
785
  const root = this.root();
784
786
  if (!root)
785
787
  throw new ExtensionError('Extensions are not configured', 404);
786
788
  const d = { warnings: [] };
787
- const { manifest, state, disabled } = this.loaded(root, d);
789
+ const { manifest, state, disabled } = (await this.loaded(root, d));
788
790
  const ext = this.extensionState(manifest, disabled, d, new Set(Object.keys(state.sidecar_proxy_consents)));
789
791
  if (!ext.knownIds.has(id))
790
792
  throw new ExtensionError('Extension not found', 404);
@@ -794,7 +796,7 @@ export class ExtensionService {
794
796
  disabled.delete(id);
795
797
  else
796
798
  disabled.add(id);
797
- this.writeState({ disabled_extensions: [...disabled], sidecar_proxy_consents: Object.fromEntries(Object.entries(state.sidecar_proxy_consents).filter(([k]) => ext.knownIds.has(k))) });
799
+ await this.writeState({ disabled_extensions: [...disabled], sidecar_proxy_consents: Object.fromEntries(Object.entries(state.sidecar_proxy_consents).filter(([k]) => ext.knownIds.has(k))) });
798
800
  return this.status();
799
801
  }
800
802
  setConsent(idRaw, approved) {
@@ -802,14 +804,14 @@ export class ExtensionService {
802
804
  throw new ExtensionError('Invalid extension id', 400);
803
805
  if (typeof approved !== 'boolean')
804
806
  throw new ExtensionError('approved must be a boolean', 400);
805
- return this.mutateState(() => this.setConsentLocked(idRaw.trim(), approved));
807
+ return this.mutateState(async () => (await this.setConsentLocked(idRaw.trim(), approved)));
806
808
  }
807
809
  async setConsentLocked(id, approved) {
808
810
  const root = this.root();
809
811
  if (!root)
810
812
  throw new ExtensionError('Extensions are not configured', 404);
811
813
  const d = { warnings: [] };
812
- const { manifest, state, disabled } = this.loaded(root, d);
814
+ const { manifest, state, disabled } = (await this.loaded(root, d));
813
815
  const consents = { ...state.sidecar_proxy_consents };
814
816
  const ext = this.extensionState(manifest, disabled, d, new Set(Object.keys(consents)));
815
817
  if (!ext.knownIds.has(id))
@@ -827,7 +829,7 @@ export class ExtensionService {
827
829
  }
828
830
  else
829
831
  Reflect.deleteProperty(consents, id);
830
- this.writeState({ disabled_extensions: [...disabled], sidecar_proxy_consents: Object.fromEntries(Object.entries(consents).filter(([k]) => ext.knownIds.has(k))) });
832
+ await this.writeState({ disabled_extensions: [...disabled], sidecar_proxy_consents: Object.fromEntries(Object.entries(consents).filter(([k]) => ext.knownIds.has(k))) });
831
833
  return this.status();
832
834
  }
833
835
  /** Python `resolve_extension_sidecar_proxy_target` (legacy proxy auth only). */
@@ -842,7 +844,7 @@ export class ExtensionService {
842
844
  throw new ExtensionError('Extensions are not configured', 404);
843
845
  const id = idRaw.trim();
844
846
  const d = { warnings: [] };
845
- const { manifest, state, disabled } = this.loaded(root, d);
847
+ const { manifest, state, disabled } = (await this.loaded(root, d));
846
848
  const ext = this.extensionState(manifest, disabled, d, new Set(Object.keys(state.sidecar_proxy_consents)));
847
849
  if (!ext.knownIds.has(id))
848
850
  throw new ExtensionError('Extension not found', 404);
@@ -908,191 +910,195 @@ export class ExtensionService {
908
910
  }
909
911
  }
910
912
  async install(idRaw, downloadUrl, sha256) {
911
- if (!validId(idRaw))
912
- throw new ExtensionError('Invalid extension id');
913
- const id = idRaw.trim();
914
- if (typeof downloadUrl !== 'string' || !downloadUrl.startsWith('https://'))
915
- throw new ExtensionError('Invalid download URL');
916
- let host = '';
917
- try {
918
- host = new URL(downloadUrl).hostname;
919
- }
920
- catch {
921
- host = '';
922
- }
923
- if (!ALLOWED_DOWNLOAD_HOSTS.has(host))
924
- throw new ExtensionError('Invalid download URL');
925
- if (typeof sha256 !== 'string' || !/^[0-9a-f]{64}$/.test(sha256))
926
- throw new ExtensionError('Invalid sha256');
927
- const root = this.writableRoot();
928
- if (!root)
929
- throw new ExtensionError('Extensions not configured', 404);
930
- let raw;
931
- try {
932
- const res = await this.galleryFetch(downloadUrl, 30_000);
933
- if (!res.ok)
934
- throw new Error(`download ${String(res.status)}`);
935
- const capped = await readCapped(res, MAX_ZIP_BYTES);
936
- if (!capped)
937
- throw new ExtensionError('Download too large');
938
- raw = capped;
939
- }
940
- catch (error) {
941
- throw new ExtensionError(error instanceof ExtensionError ? error.message : 'Download failed', error instanceof ExtensionError ? error.status : 502);
942
- }
943
- if (createHash('sha256').update(raw).digest('hex') !== sha256)
944
- throw new ExtensionError('SHA-256 mismatch');
945
- let entries;
946
- try {
947
- entries = readZip(raw);
948
- }
949
- catch {
950
- throw new ExtensionError('Invalid zip archive');
951
- }
952
- const files = entries.filter((e) => e.name && !e.isDir);
953
- if (files.reduce((acc, e) => acc + e.size, 0) > MAX_ZIP_BYTES * 10)
954
- throw new ExtensionError('Archive uncompressed size exceeds limit');
955
- if (files.length > 1024)
956
- throw new ExtensionError('Archive contains too many files');
957
- const prefix = files.every((e) => e.name.startsWith(`${id}/`)) ? `${id}/` : '';
958
- const stripped = (name) => (prefix && name.startsWith(prefix) ? name.slice(prefix.length) : name);
959
- const anchor = resolvePathLikePython(root);
960
- const extDir = resolve(anchor, id);
961
- for (const e of files) {
962
- const decoded = fullyUnquote(stripped(e.name));
963
- if (!decoded || !isSafeArchiveMember(decoded))
964
- throw new ExtensionError('Unsafe archive member');
965
- const target = resolve(extDir, decoded);
966
- if (!target.startsWith(anchor + sep) || !target.startsWith(extDir + sep))
967
- throw new ExtensionError('Zip-slip detected');
968
- }
969
- let version = 'unknown';
970
- for (const vfile of ['extension.json', 'manifest.json']) {
971
- const entry = entries.find((e) => e.name === prefix + vfile);
972
- if (!entry)
973
- continue;
913
+ return await this.mutateState(async () => {
914
+ if (!validId(idRaw))
915
+ throw new ExtensionError('Invalid extension id');
916
+ const id = idRaw.trim();
917
+ if (typeof downloadUrl !== 'string' || !downloadUrl.startsWith('https://'))
918
+ throw new ExtensionError('Invalid download URL');
919
+ let host = '';
974
920
  try {
975
- const m = JSON.parse(entry.read().toString('utf8'));
976
- if (isDict(m) && typeof m.version === 'string') {
977
- version = m.version;
978
- break;
979
- }
921
+ host = new URL(downloadUrl).hostname;
980
922
  }
981
- catch { /* ignore */ }
982
- }
983
- try {
984
- if (lstatSync(extDir).isSymbolicLink())
985
- throw new ExtensionError('Extension directory is a symlink', 400);
986
- }
987
- catch (error) {
988
- if (error instanceof ExtensionError)
989
- throw error;
990
- }
991
- try {
992
- makeAnchoredDir(anchor, extDir);
993
- }
994
- catch {
995
- throw new ExtensionError('Extension directory is a symlink', 400);
996
- }
997
- const written = [];
998
- const rollback = () => {
999
- for (const p of written) {
1000
- try {
1001
- unlinkAnchored(anchor, p);
1002
- }
1003
- catch { /* gone */ }
923
+ catch {
924
+ host = '';
1004
925
  }
926
+ if (!ALLOWED_DOWNLOAD_HOSTS.has(host))
927
+ throw new ExtensionError('Invalid download URL');
928
+ if (typeof sha256 !== 'string' || !/^[0-9a-f]{64}$/.test(sha256))
929
+ throw new ExtensionError('Invalid sha256');
930
+ const root = this.writableRoot();
931
+ if (!root)
932
+ throw new ExtensionError('Extensions not configured', 404);
933
+ let raw;
1005
934
  try {
1006
- rmdirAnchored(anchor, extDir);
935
+ const res = await this.galleryFetch(downloadUrl, 30_000);
936
+ if (!res.ok)
937
+ throw new Error(`download ${String(res.status)}`);
938
+ const capped = await readCapped(res, MAX_ZIP_BYTES);
939
+ if (!capped)
940
+ throw new ExtensionError('Download too large');
941
+ raw = capped;
1007
942
  }
1008
- catch { /* not empty, or gone */ }
1009
- };
1010
- try {
1011
- // Every destination is created or truncated through the anchored walk from the extension root, so a symlink
1012
- // already inside the extension (or a parent swapped mid-extraction) can never redirect a write outside it.
943
+ catch (error) {
944
+ throw new ExtensionError(error instanceof ExtensionError ? error.message : 'Download failed', error instanceof ExtensionError ? error.status : 502);
945
+ }
946
+ if (createHash('sha256').update(raw).digest('hex') !== sha256)
947
+ throw new ExtensionError('SHA-256 mismatch');
948
+ let entries;
949
+ try {
950
+ entries = readZip(raw);
951
+ }
952
+ catch {
953
+ throw new ExtensionError('Invalid zip archive');
954
+ }
955
+ const files = entries.filter((e) => e.name && !e.isDir);
956
+ if (files.reduce((acc, e) => acc + e.size, 0) > MAX_ZIP_BYTES * 10)
957
+ throw new ExtensionError('Archive uncompressed size exceeds limit');
958
+ if (files.length > 1024)
959
+ throw new ExtensionError('Archive contains too many files');
960
+ const prefix = files.every((e) => e.name.startsWith(`${id}/`)) ? `${id}/` : '';
961
+ const stripped = (name) => (prefix && name.startsWith(prefix) ? name.slice(prefix.length) : name);
962
+ const anchor = resolvePathLikePython(root);
963
+ const extDir = resolve(anchor, id);
1013
964
  for (const e of files) {
1014
- const dest = resolve(extDir, fullyUnquote(stripped(e.name)));
1015
- let fd;
965
+ const decoded = fullyUnquote(stripped(e.name));
966
+ if (!decoded || !isSafeArchiveMember(decoded))
967
+ throw new ExtensionError('Unsafe archive member');
968
+ const target = resolve(extDir, decoded);
969
+ if (!target.startsWith(anchor + sep) || !target.startsWith(extDir + sep))
970
+ throw new ExtensionError('Zip-slip detected');
971
+ }
972
+ let version = 'unknown';
973
+ for (const vfile of ['extension.json', 'manifest.json']) {
974
+ const entry = entries.find((e) => e.name === prefix + vfile);
975
+ if (!entry)
976
+ continue;
1016
977
  try {
1017
- fd = openAnchoredCreateFd(anchor, dest);
978
+ const m = JSON.parse(entry.read().toString('utf8'));
979
+ if (isDict(m) && typeof m.version === 'string') {
980
+ version = m.version;
981
+ break;
982
+ }
1018
983
  }
1019
- catch (error) {
1020
- if (!(error instanceof FileExistsError))
1021
- throw error;
1022
- fd = openAnchoredWriteFd(anchor, dest);
984
+ catch { /* ignore */ }
985
+ }
986
+ try {
987
+ if (lstatSync(extDir).isSymbolicLink())
988
+ throw new ExtensionError('Extension directory is a symlink', 400);
989
+ }
990
+ catch (error) {
991
+ if (error instanceof ExtensionError)
992
+ throw error;
993
+ }
994
+ try {
995
+ makeAnchoredDir(anchor, extDir);
996
+ }
997
+ catch {
998
+ throw new ExtensionError('Extension directory is a symlink', 400);
999
+ }
1000
+ const written = [];
1001
+ const rollback = () => {
1002
+ for (const p of written) {
1003
+ try {
1004
+ unlinkAnchored(anchor, p);
1005
+ }
1006
+ catch { /* gone */ }
1023
1007
  }
1024
1008
  try {
1025
- writeFileSync(fd, e.read());
1009
+ rmdirAnchored(anchor, extDir);
1026
1010
  }
1027
- finally {
1028
- closeSync(fd);
1011
+ catch { /* not empty, or gone */ }
1012
+ };
1013
+ try {
1014
+ // Every destination is created or truncated through the anchored walk from the extension root, so a symlink
1015
+ // already inside the extension (or a parent swapped mid-extraction) can never redirect a write outside it.
1016
+ for (const e of files) {
1017
+ const dest = resolve(extDir, fullyUnquote(stripped(e.name)));
1018
+ let fd;
1019
+ try {
1020
+ fd = openAnchoredCreateFd(anchor, dest);
1021
+ }
1022
+ catch (error) {
1023
+ if (!(error instanceof FileExistsError))
1024
+ throw error;
1025
+ fd = openAnchoredWriteFd(anchor, dest);
1026
+ }
1027
+ try {
1028
+ writeFileSync(fd, e.read());
1029
+ }
1030
+ finally {
1031
+ closeSync(fd);
1032
+ }
1033
+ written.push(dest);
1029
1034
  }
1030
- written.push(dest);
1031
1035
  }
1032
- }
1033
- catch {
1034
- rollback();
1035
- throw new ExtensionError('Extraction failed', 500);
1036
- }
1037
- try {
1038
- const manifest = this.loadInstallManifest();
1039
- const record = { version, files: written.map((p) => relative(extDir, p).split(sep).join('/')), installed_at: new Date().toISOString() };
1040
- const next = { version: 1, installed: { ...manifest.installed, [id]: record } };
1041
- if (Buffer.byteLength(JSON.stringify(next, null, 2)) > MAX_INSTALL_MANIFEST_BYTES)
1042
- throw new ExtensionError('Install manifest would exceed size limit');
1043
- this.writeInstallManifest(next);
1044
- }
1045
- catch (error) {
1046
- rollback();
1047
- throw error instanceof ExtensionError ? error : new ExtensionError('Failed to record install', 500);
1048
- }
1049
- return { installed: true, id, version };
1050
- }
1051
- uninstall(idRaw) {
1052
- if (!validId(idRaw))
1053
- throw new ExtensionError('Invalid extension id');
1054
- const id = idRaw.trim();
1055
- const root = this.root();
1056
- if (!root)
1057
- throw new ExtensionError('Extensions not configured', 404);
1058
- const manifest = this.loadInstallManifest();
1059
- const entry = manifest.installed[id];
1060
- if (!entry)
1061
- throw new ExtensionError('Extension not installed', 404);
1062
- const anchor = resolvePathLikePython(root);
1063
- const extDir = resolve(anchor, id);
1064
- for (const rel of entry.files) {
1065
- if (!isSafeArchiveMember(rel))
1066
- continue;
1067
- const target = resolve(extDir, rel);
1068
- if (!target.startsWith(extDir + sep))
1069
- continue;
1070
- try {
1071
- unlinkAnchored(anchor, target);
1036
+ catch {
1037
+ rollback();
1038
+ throw new ExtensionError('Extraction failed', 500);
1072
1039
  }
1073
- catch { /* gone */ }
1074
- }
1075
- // Prune now-empty directories, enumerating and removing each through the anchored walk so a directory replaced by
1076
- // a symlink is skipped rather than followed into its target.
1077
- const prune = (dir) => {
1078
- let subdirs;
1079
1040
  try {
1080
- subdirs = withAnchoredDir(anchor, dir, (child) => readdirSync(child('.'), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name));
1041
+ const manifest = (await this.loadInstallManifest());
1042
+ const record = { version, files: written.map((p) => relative(extDir, p).split(sep).join('/')), installed_at: new Date().toISOString() };
1043
+ const next = { version: 1, installed: { ...manifest.installed, [id]: record } };
1044
+ if (Buffer.byteLength(JSON.stringify(next, null, 2)) > MAX_INSTALL_MANIFEST_BYTES)
1045
+ throw new ExtensionError('Install manifest would exceed size limit');
1046
+ await this.writeInstallManifest(next);
1081
1047
  }
1082
- catch {
1083
- return;
1048
+ catch (error) {
1049
+ rollback();
1050
+ throw error instanceof ExtensionError ? error : new ExtensionError('Failed to record install', 500);
1084
1051
  }
1085
- for (const name of subdirs)
1086
- prune(join(dir, name));
1087
- try {
1088
- rmdirAnchored(anchor, dir);
1052
+ return { installed: true, id, version };
1053
+ });
1054
+ }
1055
+ async uninstall(idRaw) {
1056
+ return await this.mutateState(async () => {
1057
+ if (!validId(idRaw))
1058
+ throw new ExtensionError('Invalid extension id');
1059
+ const id = idRaw.trim();
1060
+ const root = this.root();
1061
+ if (!root)
1062
+ throw new ExtensionError('Extensions not configured', 404);
1063
+ const manifest = (await this.loadInstallManifest());
1064
+ const entry = manifest.installed[id];
1065
+ if (!entry)
1066
+ throw new ExtensionError('Extension not installed', 404);
1067
+ const anchor = resolvePathLikePython(root);
1068
+ const extDir = resolve(anchor, id);
1069
+ for (const rel of entry.files) {
1070
+ if (!isSafeArchiveMember(rel))
1071
+ continue;
1072
+ const target = resolve(extDir, rel);
1073
+ if (!target.startsWith(extDir + sep))
1074
+ continue;
1075
+ try {
1076
+ unlinkAnchored(anchor, target);
1077
+ }
1078
+ catch { /* gone */ }
1089
1079
  }
1090
- catch { /* not empty, or gone */ }
1091
- };
1092
- prune(extDir);
1093
- Reflect.deleteProperty(manifest.installed, id);
1094
- this.writeInstallManifest(manifest);
1095
- return { uninstalled: true, id };
1080
+ // Prune now-empty directories, enumerating and removing each through the anchored walk so a directory replaced by
1081
+ // a symlink is skipped rather than followed into its target.
1082
+ const prune = (dir) => {
1083
+ let subdirs;
1084
+ try {
1085
+ subdirs = withAnchoredDir(anchor, dir, (child) => readdirSync(child('.'), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name));
1086
+ }
1087
+ catch {
1088
+ return;
1089
+ }
1090
+ for (const name of subdirs)
1091
+ prune(join(dir, name));
1092
+ try {
1093
+ rmdirAnchored(anchor, dir);
1094
+ }
1095
+ catch { /* not empty, or gone */ }
1096
+ };
1097
+ prune(extDir);
1098
+ Reflect.deleteProperty(manifest.installed, id);
1099
+ await this.writeInstallManifest(manifest);
1100
+ return { uninstalled: true, id };
1101
+ });
1096
1102
  }
1097
1103
  /** Python `serve_extension_static`: bytes, MIME, sandbox CSP for HTML; null means 404. */
1098
1104
  staticFile(rel) {