@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
@@ -66,8 +66,8 @@ function queryPositiveInt(value, fallback, maximum) {
66
66
  }
67
67
  const sanitizeError = sanitizePaths;
68
68
  /** Python `_guard_request_session_visibility` for a body/query session id. */
69
- function guardVisibility(ctx, sid) {
70
- if (!ctx.deps.sessions.sessionIdVisible(sid))
69
+ async function guardVisibility(ctx, sid) {
70
+ if (!(await ctx.deps.sessions.sessionIdVisible(sid)))
71
71
  throw new HttpError(404, 'Session not found');
72
72
  }
73
73
  /** Python `float(body["since"])` for the handoff dock: a unix time or numeric string; absent is null. */
@@ -80,13 +80,13 @@ function handoffSince(value) {
80
80
  return n;
81
81
  }
82
82
  /** The handoff dock's session id and `since`, validated in the predecessor's order. */
83
- function handoffInput(ctx, input) {
83
+ async function handoffInput(ctx, input) {
84
84
  requireFields(input, 'session_id');
85
85
  const sid = str(input.session_id).trim();
86
86
  if (!sid)
87
87
  throw new HttpError(400, 'session_id is required');
88
88
  const since = handoffSince(input.since);
89
- guardVisibility(ctx, sid);
89
+ await guardVisibility(ctx, sid);
90
90
  return { sid, since };
91
91
  }
92
92
  function allProfilesEnabled(ctx, value) {
@@ -95,8 +95,8 @@ function allProfilesEnabled(ctx, value) {
95
95
  /** Search inputs that select the sidebar rows rather than every stored session (TAL-308). */
96
96
  const SIDEBAR_SEARCH_KEYS = ['project_id', 'sidebar_source', 'include_archived', 'exclude_hidden', 'show_cli_sessions', 'show_claude_code_sessions', 'show_cron_sessions', 'show_webhook_sessions', 'show_kanban_sessions'];
97
97
  /** The `/api/sessions` row selection for a list or sidebar-search query (TAL-308 shares it). */
98
- function sidebarListParams(ctx, input) {
99
- const settings = ctx.deps.settings.load();
98
+ async function sidebarListParams(ctx, input) {
99
+ const settings = (await ctx.deps.settings.load());
100
100
  const overrideKeys = ['show_cli_sessions', 'show_claude_code_sessions', 'show_cron_sessions', 'show_webhook_sessions', 'show_kanban_sessions'];
101
101
  const sidebarSourceRaw = (input.sidebar_source ?? '').trim().toLowerCase();
102
102
  return {
@@ -119,7 +119,7 @@ function sidebarListParams(ctx, input) {
119
119
  export const sessionsRouter = os.router({
120
120
  sessions: {
121
121
  list: os.sessions.list.handler(({ input, context: { ctx } }) => run(async () => {
122
- const { body, etag } = await ctx.deps.sessions.list(sidebarListParams(ctx, input));
122
+ const { body, etag } = await ctx.deps.sessions.list((await sidebarListParams(ctx, input)));
123
123
  ctx.extraResponseHeaders = { etag };
124
124
  if (ifNoneMatchMatches(ctx.header('if-none-match') ?? '', etag))
125
125
  ctx.notModified = true;
@@ -132,19 +132,19 @@ export const sessionsRouter = os.router({
132
132
  const opts = { content: (input.content ?? '1') === '1', depth, allProfiles: allProfilesEnabled(ctx, input.all_profiles) };
133
133
  // TAL-308: any sidebar filter answers from the sidebar's own rows; without one the store-only search stays.
134
134
  if (SIDEBAR_SEARCH_KEYS.some((k) => input[k] !== undefined)) {
135
- return await ctx.deps.sessions.sidebarSearch(input.q ?? '', sidebarListParams(ctx, input), { ...opts, projectId: input.project_id?.trim() || null });
135
+ return await ctx.deps.sessions.sidebarSearch(input.q ?? '', (await sidebarListParams(ctx, input)), { ...opts, projectId: input.project_id?.trim() || null });
136
136
  }
137
- return ctx.deps.sessions.search(input.q ?? '', opts);
137
+ return await ctx.deps.sessions.search(input.q ?? '', opts);
138
138
  })),
139
- cleanup: os.sessions.cleanup.handler(({ context: { ctx } }) => run(() => ctx.deps.sessions.cleanup(false))),
140
- cleanupZeroMessage: os.sessions.cleanupZeroMessage.handler(({ context: { ctx } }) => run(() => ctx.deps.sessions.cleanup(true))),
139
+ cleanup: os.sessions.cleanup.handler(({ context: { ctx } }) => run(async () => (await ctx.deps.sessions.cleanup(false)))),
140
+ cleanupZeroMessage: os.sessions.cleanupZeroMessage.handler(({ context: { ctx } }) => run(async () => (await ctx.deps.sessions.cleanup(true)))),
141
141
  // TAL-627: each id runs the single-session route's own guards, lock and cleanup, one at a time; a failure becomes
142
142
  // that id's result and the rest still run.
143
143
  bulk: os.sessions.bulk.handler(async ({ input, context: { ctx } }) => {
144
144
  const results = [];
145
145
  for (const sid of input.session_ids) {
146
146
  try {
147
- guardVisibility(ctx, sid);
147
+ await guardVisibility(ctx, sid);
148
148
  if (input.action === 'delete') {
149
149
  const { state_db_cleanup_failed } = await ctx.deps.sessions.delete(sid);
150
150
  results.push({ session_id: sid, ok: true, state_db_cleanup_failed: Boolean(state_db_cleanup_failed) });
@@ -159,7 +159,8 @@ export const sessionsRouter = os.router({
159
159
  : error instanceof HttpFailure ? [error.status, error.message]
160
160
  : error instanceof SessionNotFound ? [404, 'Session not found']
161
161
  : [500, sanitizeError(error)];
162
- results.push({ session_id: sid, ok: false, status, error: message });
162
+ const refused = error instanceof HttpFailure ? error.extra.refused : undefined;
163
+ results.push({ session_id: sid, ok: false, status, error: message, ...(refused ? { refused } : {}) });
163
164
  }
164
165
  }
165
166
  return { results };
@@ -169,28 +170,29 @@ export const sessionsRouter = os.router({
169
170
  // No visibility guard here: `detail()` answers 409 `session_profile_mismatch` so the frontend can switch to the owning profile.
170
171
  get: os.session.get.handler(({ input, context: { ctx } }) => run(async () => {
171
172
  await ctx.deps.sessions.deps.warmModelOptions?.();
173
+ await ctx.deps.turns.loadGoal(input.session_id.trim());
172
174
  try {
173
- return { session: ctx.deps.sessions.detail(input.session_id, input) };
175
+ return { session: (await ctx.deps.sessions.detail(input.session_id, input)) };
174
176
  }
175
177
  catch (error) {
176
178
  // Runs left on the relay by a deletion that predates `clearRelayCompletions` clear when the id is next requested.
177
179
  const sid = input.session_id.trim();
178
- if (error instanceof HttpFailure && error.status === 404 && ctx.deps.sessionStore.wasDeleted(sid))
179
- ctx.deps.relay.clearDeleted(sid, ctx.deps.activeProfile());
180
+ if (error instanceof HttpFailure && error.status === 404 && (await ctx.deps.sessionStore.wasDeleted(sid)))
181
+ (await ctx.deps.relay.clearDeleted(sid, ctx.deps.activeProfile()));
180
182
  throw error;
181
183
  }
182
184
  })),
183
- status: os.session.status.handler(({ input, context: { ctx } }) => run(() => {
185
+ status: os.session.status.handler(({ input, context: { ctx } }) => run(async () => {
184
186
  if (!input.session_id)
185
187
  throw new HttpError(400, 'Missing session_id');
186
- guardVisibility(ctx, input.session_id);
187
- return ctx.deps.sessions.status(input.session_id);
188
+ await guardVisibility(ctx, input.session_id);
189
+ return (await ctx.deps.sessions.status(input.session_id));
188
190
  })),
189
- usage: os.session.usage.handler(({ input, context: { ctx } }) => run(() => {
191
+ usage: os.session.usage.handler(({ input, context: { ctx } }) => run(async () => {
190
192
  if (!input.session_id)
191
193
  throw new HttpError(400, 'Missing session_id');
192
- guardVisibility(ctx, input.session_id);
193
- return ctx.deps.sessions.usage(input.session_id);
194
+ await guardVisibility(ctx, input.session_id);
195
+ return (await ctx.deps.sessions.usage(input.session_id));
194
196
  })),
195
197
  new: os.session.new.handler(({ input, context: { ctx } }) => run(async () => {
196
198
  // Python: an invisible prev_session_id is ignored (the service drops it), never an error (#5420).
@@ -213,8 +215,8 @@ export const sessionsRouter = os.router({
213
215
  }
214
216
  if (requested) {
215
217
  try {
216
- let base = input.workspace ? ctx.deps.sessions.resolveNewSessionWorkspace(input, null, profile) : null;
217
- base ??= ctx.deps.workspaces.resolveTrusted(ctx.deps.workspaces.lastWorkspace(profile), profile);
218
+ let base = input.workspace ? (await ctx.deps.sessions.resolveNewSessionWorkspace(input, null, profile)) : null;
219
+ base ??= (await ctx.deps.workspaces.resolveTrusted((await ctx.deps.workspaces.lastWorkspace(profile)), profile));
218
220
  const repo = base;
219
221
  worktree = await ctx.deps.git.holdWrite(repo, () => ctx.deps.worktrees.create(repo));
220
222
  }
@@ -232,67 +234,69 @@ export const sessionsRouter = os.router({
232
234
  worktreeSkipped = error.message;
233
235
  }
234
236
  }
235
- const s = ctx.deps.sessions.create(input, { worktree });
236
- const payload = { session: ctx.deps.sessions.publicSession(s) };
237
+ const s = (await ctx.deps.sessions.create(input, { worktree }));
238
+ const payload = { session: (await ctx.deps.sessions.publicSession(s)) };
237
239
  if (worktreeSkipped)
238
240
  payload.worktree_skipped = worktreeSkipped;
239
241
  return payload;
240
242
  })),
241
243
  rename: os.session.rename.handler(({ input, context: { ctx } }) => run(async () => {
242
- guardVisibility(ctx, input.session_id);
244
+ await guardVisibility(ctx, input.session_id);
243
245
  if (!input.title)
244
246
  throw new HttpError(400, 'Missing required field(s): title');
245
- return ctx.deps.sessions.rename(input.session_id, input.title);
247
+ return (await ctx.deps.sessions.rename(input.session_id, input.title));
246
248
  })),
247
249
  delete: os.session.delete.handler(({ input, context: { ctx } }) => run(async () => {
248
- guardVisibility(ctx, input.session_id);
249
- return ctx.deps.sessions.delete(input.session_id);
250
+ await guardVisibility(ctx, input.session_id);
251
+ return (await ctx.deps.sessions.delete(input.session_id));
250
252
  })),
251
253
  pin: os.session.pin.handler(({ input, context: { ctx } }) => run(async () => {
252
- guardVisibility(ctx, input.session_id);
254
+ await guardVisibility(ctx, input.session_id);
253
255
  return ctx.deps.sessions.pin(input.session_id, input.pinned ?? true);
254
256
  })),
255
257
  archive: os.session.archive.handler(({ input, context: { ctx } }) => run(async () => {
256
- guardVisibility(ctx, input.session_id);
257
- return ctx.deps.sessions.archive(input.session_id, input.archived ?? true);
258
+ await guardVisibility(ctx, input.session_id);
259
+ return (await ctx.deps.sessions.archive(input.session_id, input.archived ?? true));
258
260
  })),
259
261
  move: os.session.move.handler(({ input, context: { ctx } }) => run(async () => {
260
- guardVisibility(ctx, input.session_id);
261
- return ctx.deps.sessions.move(input.session_id, input.project_id || null);
262
+ await guardVisibility(ctx, input.session_id);
263
+ return (await ctx.deps.sessions.move(input.session_id, input.project_id || null));
262
264
  })),
263
- duplicate: os.session.duplicate.handler(({ input, context: { ctx } }) => run(() => {
265
+ duplicate: os.session.duplicate.handler(({ input, context: { ctx } }) => run(async () => {
264
266
  if (!input.session_id)
265
267
  throw new HttpError(400, 'session_id is required');
266
- guardVisibility(ctx, input.session_id);
267
- return ctx.deps.sessions.duplicate(input.session_id);
268
+ await guardVisibility(ctx, input.session_id);
269
+ return (await ctx.deps.sessions.duplicate(input.session_id));
268
270
  })),
269
- branch: os.session.branch.handler(({ input, context: { ctx } }) => run(() => {
270
- guardVisibility(ctx, input.session_id);
271
- return ctx.deps.sessions.branch(input.session_id, input);
271
+ branch: os.session.branch.handler(({ input, context: { ctx } }) => run(async () => {
272
+ await guardVisibility(ctx, input.session_id);
273
+ return (await ctx.deps.sessions.branch(input.session_id, input));
272
274
  })),
273
275
  truncate: os.session.truncate.handler(({ input, context: { ctx } }) => run(async () => {
274
- guardVisibility(ctx, input.session_id);
275
- return ctx.deps.sessions.truncate(input.session_id, input.keep_count);
276
+ await guardVisibility(ctx, input.session_id);
277
+ // A body without `confirm_deep_truncate` is a released App's, which asked on the device before sending it.
278
+ const hold = input.confirm_deep_truncate === undefined ? null : { confirmToken: input.confirm_deep_truncate ? input.confirm_token ?? null : null };
279
+ return (await ctx.deps.sessions.truncate(input.session_id, input.keep_count, hold));
276
280
  })),
277
281
  clear: os.session.clear.handler(({ input, context: { ctx } }) => run(async () => {
278
- guardVisibility(ctx, input.session_id);
279
- return ctx.deps.sessions.clear(input.session_id);
282
+ await guardVisibility(ctx, input.session_id);
283
+ return (await ctx.deps.sessions.clear(input.session_id));
280
284
  })),
281
285
  retry: os.session.retry.handler(({ input, context: { ctx } }) => run(async () => {
282
- guardVisibility(ctx, input.session_id);
283
- return ctx.deps.sessions.retry(input.session_id);
286
+ await guardVisibility(ctx, input.session_id);
287
+ return (await ctx.deps.sessions.retry(input.session_id));
284
288
  })),
285
289
  undo: os.session.undo.handler(({ input, context: { ctx } }) => run(async () => {
286
- guardVisibility(ctx, input.session_id);
287
- return ctx.deps.sessions.undo(input.session_id);
290
+ await guardVisibility(ctx, input.session_id);
291
+ return (await ctx.deps.sessions.undo(input.session_id));
288
292
  })),
289
293
  update: os.session.update.handler(({ input, context: { ctx } }) => run(async () => {
290
- guardVisibility(ctx, input.session_id);
291
- return ctx.deps.sessions.update(input.session_id, input);
294
+ await guardVisibility(ctx, input.session_id);
295
+ return (await ctx.deps.sessions.update(input.session_id, input));
292
296
  })),
293
297
  toolsets: os.session.toolsets.handler(({ input, context: { ctx } }) => run(async () => {
294
- guardVisibility(ctx, input.session_id);
295
- return ctx.deps.sessions.setToolsets(input.session_id, input.toolsets);
298
+ await guardVisibility(ctx, input.session_id);
299
+ return (await ctx.deps.sessions.setToolsets(input.session_id, input.toolsets));
296
300
  })),
297
301
  yoloGet: os.session.yoloGet.handler(({ input, context: { ctx } }) => run(() => ctx.deps.sessions.yolo(input.session_id))),
298
302
  yoloSet: os.session.yoloSet.handler(({ input, context: { ctx } }) => run(async () => {
@@ -312,25 +316,25 @@ export const sessionsRouter = os.router({
312
316
  const released = await ctx.deps.turns.respondApproval(sid, 'once', '', true);
313
317
  return { ok: true, yolo_enabled: Boolean(released.yolo_enabled ?? ctx.deps.sessions.yolo(sid).yolo_enabled), ...(released.stale_cleared ? { stale_cleared: true } : {}) };
314
318
  })),
315
- import: os.session.import.handler(({ input, context: { ctx } }) => run(() => ctx.deps.sessions.import(input))),
319
+ import: os.session.import.handler(({ input, context: { ctx } }) => run(async () => (await ctx.deps.sessions.import(input)))),
316
320
  regenerateTitle: os.session.regenerateTitle.handler(({ input, context: { ctx } }) => run(async () => {
317
321
  const sid = input.session_id;
318
322
  let session;
319
323
  try {
320
- session = ctx.deps.sessionStore.get(sid);
324
+ session = (await ctx.deps.sessionStore.get(sid));
321
325
  }
322
326
  catch {
323
327
  throw new HttpError(404, 'Session not found');
324
328
  }
325
- if (ctx.deps.sessions.isReadOnly(session) || ctx.deps.sessions.isSubagentViewOnly(sid))
329
+ if ((await ctx.deps.sessions.isReadOnly(session)) || (await ctx.deps.sessions.isSubagentViewOnly(sid)))
326
330
  throw new HttpError(403, 'Read-only imported sessions cannot regenerate titles');
327
331
  const generated = await ctx.deps.turns.generateTitle(session, { preferLatest: Boolean(input.prefer_latest) });
328
332
  if (!generated.title)
329
333
  throw new HttpError(422, `Could not generate a better title (${generated.status || 'empty'})`);
330
334
  const current = await ctx.deps.sessions.persistGeneratedTitle(sid, generated.title, 'session_title_regenerate');
331
- return { session: ctx.deps.sessions.wireRow(current), title: current.title, status: generated.status, raw_preview: generated.rawPreview.slice(0, 240) };
335
+ return { session: (await ctx.deps.sessions.wireRow(current)), title: current.title, status: generated.status, raw_preview: generated.rawPreview.slice(0, 240) };
332
336
  })),
333
- recoveryAudit: os.session.recoveryAudit.handler(({ context: { ctx } }) => run(() => ctx.deps.sessions.recoveryAudit())),
337
+ recoveryAudit: os.session.recoveryAudit.handler(({ context: { ctx } }) => run(async () => (await ctx.deps.sessions.recoveryAudit()))),
334
338
  recoveryRepairSafe: os.session.recoveryRepairSafe.handler(({ context: { ctx } }) => run(async () => {
335
339
  const result = await ctx.deps.sessions.recoveryRepairSafe();
336
340
  if (!result.clean)
@@ -346,18 +350,18 @@ export const sessionsRouter = os.router({
346
350
  throw new HttpError(404, 'Session not found');
347
351
  return report;
348
352
  })),
349
- compressionRecoveryStart: os.session.compressionRecoveryStart.handler(({ input, context: { ctx } }) => run(() => {
353
+ compressionRecoveryStart: os.session.compressionRecoveryStart.handler(({ input, context: { ctx } }) => run(async () => {
350
354
  requireFields(input, 'session_id');
351
355
  const sid = str(input.session_id).trim();
352
356
  if (!sid)
353
357
  throw new HttpError(400, 'session_id is required');
354
- return ctx.deps.sessions.compressionRecoveryStart(sid);
358
+ return (await ctx.deps.sessions.compressionRecoveryStart(sid));
355
359
  })),
356
360
  // TAL-255: the iOS `/compress` route joins or starts the session's compression job and answers with its result.
357
361
  compress: os.session.compress.handler(({ input, context: { ctx } }) => run(async () => {
358
362
  requireFields(input, 'session_id');
359
363
  const sid = str(input.session_id).trim();
360
- guardVisibility(ctx, sid);
364
+ await guardVisibility(ctx, sid);
361
365
  const job = await ctx.deps.sessions.startCompression(sid, input.focus_topic || input.topic);
362
366
  await job.done;
363
367
  if (job.status === 'error')
@@ -367,56 +371,56 @@ export const sessionsRouter = os.router({
367
371
  compressStart: os.session.compressStart.handler(({ input, context: { ctx } }) => run(async () => {
368
372
  requireFields(input, 'session_id');
369
373
  const sid = str(input.session_id).trim();
370
- guardVisibility(ctx, sid);
374
+ await guardVisibility(ctx, sid);
371
375
  return compressionStatusPayload(await ctx.deps.sessions.startCompression(sid, input.focus_topic || input.topic));
372
376
  })),
373
377
  // TAL-258: the handoff dock. Rounds decides when to offer it; the summary is generated and appended to the transcript.
374
- conversationRounds: os.session.conversationRounds.handler(({ input, context: { ctx } }) => run(() => {
375
- const { sid, since } = handoffInput(ctx, input);
376
- return ctx.deps.sessions.conversationRounds(sid, since);
378
+ conversationRounds: os.session.conversationRounds.handler(({ input, context: { ctx } }) => run(async () => {
379
+ const { sid, since } = (await handoffInput(ctx, input));
380
+ return (await ctx.deps.sessions.conversationRounds(sid, since));
377
381
  })),
378
- handoffSummary: os.session.handoffSummary.handler(({ input, context: { ctx } }) => run(() => {
379
- const { sid, since } = handoffInput(ctx, input);
380
- return ctx.deps.sessions.handoffSummary(sid, since);
382
+ handoffSummary: os.session.handoffSummary.handler(({ input, context: { ctx } }) => run(async () => {
383
+ const { sid, since } = (await handoffInput(ctx, input));
384
+ return (await ctx.deps.sessions.handoffSummary(sid, since));
381
385
  })),
382
- compressStatus: os.session.compressStatus.handler(({ input, context: { ctx } }) => run(() => {
386
+ compressStatus: os.session.compressStatus.handler(({ input, context: { ctx } }) => run(async () => {
383
387
  const sid = input.session_id.trim();
384
388
  if (!sid)
385
389
  throw new HttpError(400, 'session_id is required');
386
- guardVisibility(ctx, sid);
387
- const job = ctx.deps.sessions.compressionJob(sid);
390
+ await guardVisibility(ctx, sid);
391
+ const job = (await ctx.deps.sessions.compressionJob(sid));
388
392
  return (job ? compressionStatusPayload(job) : { ok: true, status: 'idle', session_id: sid });
389
393
  })),
390
- draftGet: os.session.draftGet.handler(({ input, context: { ctx } }) => run(() => {
391
- guardVisibility(ctx, input.session_id);
392
- return ctx.deps.sessions.readDraft(input.session_id);
394
+ draftGet: os.session.draftGet.handler(({ input, context: { ctx } }) => run(async () => {
395
+ await guardVisibility(ctx, input.session_id);
396
+ return (await ctx.deps.sessions.readDraft(input.session_id));
393
397
  })),
394
398
  draftSave: os.session.draftSave.handler(({ input, context: { ctx } }) => run(async () => {
395
- guardVisibility(ctx, input.session_id);
396
- return ctx.deps.sessions.writeDraft(input);
399
+ await guardVisibility(ctx, input.session_id);
400
+ return (await ctx.deps.sessions.writeDraft(input));
397
401
  })),
398
- anchorSceneGet: os.session.anchorSceneGet.handler(({ input, context: { ctx } }) => run(() => {
399
- guardVisibility(ctx, input.session_id);
400
- return ctx.deps.sessions.readAnchorScene(input);
402
+ anchorSceneGet: os.session.anchorSceneGet.handler(({ input, context: { ctx } }) => run(async () => {
403
+ await guardVisibility(ctx, input.session_id);
404
+ return (await ctx.deps.sessions.readAnchorScene(input));
401
405
  })),
402
- toolResult: os.session.toolResult.handler(({ input, context: { ctx } }) => run(() => {
403
- guardVisibility(ctx, input.session_id);
404
- return ctx.deps.sessions.readToolResult(input);
406
+ toolResult: os.session.toolResult.handler(({ input, context: { ctx } }) => run(async () => {
407
+ await guardVisibility(ctx, input.session_id);
408
+ return (await ctx.deps.sessions.readToolResult(input));
405
409
  })),
406
410
  anchorSceneSave: os.session.anchorSceneSave.handler(({ input, context: { ctx } }) => run(async () => {
407
- guardVisibility(ctx, input.session_id);
408
- return ctx.deps.sessions.saveAnchorScene(input);
411
+ await guardVisibility(ctx, input.session_id);
412
+ return (await ctx.deps.sessions.saveAnchorScene(input));
409
413
  })),
410
414
  },
411
415
  projects: {
412
- list: os.projects.list.handler(({ input, context: { ctx } }) => run(() => {
416
+ list: os.projects.list.handler(({ input, context: { ctx } }) => run(async () => {
413
417
  const activeProfile = ctx.deps.activeProfile();
414
- const all = ctx.deps.projects.load();
418
+ const all = (await ctx.deps.projects.load());
415
419
  const allProfiles = allProfilesEnabled(ctx, input.all_profiles);
416
420
  const scoped = allProfiles ? all : all.filter((p) => ctx.deps.profilesMatch(p.profile ?? null, activeProfile));
417
421
  return { projects: scoped, all_profiles: allProfiles, active_profile: activeProfile, other_profile_count: allProfiles || ctx.deps.isolatedProfileMode() ? 0 : all.length - scoped.length };
418
422
  })),
419
- create: os.projects.create.handler(({ input, context: { ctx } }) => run(() => {
423
+ create: os.projects.create.handler(({ input, context: { ctx } }) => run(async () => {
420
424
  const name = input.name.trim().slice(0, 128);
421
425
  if (!name)
422
426
  throw new HttpError(400, 'name required');
@@ -426,43 +430,43 @@ export const sessionsRouter = os.router({
426
430
  const requested = (input.profile ?? '').trim();
427
431
  if (requested && requested !== 'default' && !/^[a-z0-9][a-z0-9_-]{0,63}$/.test(requested))
428
432
  throw new HttpError(400, 'invalid profile');
429
- const projects = ctx.deps.projects.load();
430
433
  const proj = { project_id: randomUUID().replace(/-/g, '').slice(0, 12), name, color, profile: requested || ctx.deps.activeProfile() || 'default', created_at: ctx.deps.auth.now() };
431
- projects.push(proj);
432
- ctx.deps.projects.save(projects);
434
+ await ctx.deps.projects.mutate((projects) => { projects.push(proj); });
433
435
  ctx.deps.events.publish('project_create', { profile: proj.profile });
434
436
  return { ok: true, project: proj };
435
437
  })),
436
- rename: os.projects.rename.handler(({ input, context: { ctx } }) => run(() => {
437
- const projects = ctx.deps.projects.load();
438
- const proj = projects.find((p) => p.project_id === input.project_id);
438
+ rename: os.projects.rename.handler(({ input, context: { ctx } }) => run(async () => {
439
439
  const activeProfile = ctx.deps.activeProfile();
440
- if (!proj || !ctx.deps.profilesMatch(proj.profile ?? null, activeProfile))
441
- throw new HttpError(404, 'Project not found');
442
- requireFields(input, 'project_id', 'name');
443
- proj.name = input.name.trim().slice(0, 128);
444
- if ('color' in input) {
445
- const color = input.color ?? null;
446
- if (color && !/^#[0-9a-fA-F]{3,8}$/.test(color))
447
- throw new HttpError(400, 'Invalid color format');
448
- proj.color = color;
449
- }
450
- ctx.deps.projects.save(projects);
440
+ const proj = await ctx.deps.projects.mutate((projects) => {
441
+ const proj = projects.find((p) => p.project_id === input.project_id);
442
+ if (!proj || !ctx.deps.profilesMatch(proj.profile ?? null, activeProfile))
443
+ throw new HttpError(404, 'Project not found');
444
+ requireFields(input, 'project_id', 'name');
445
+ proj.name = input.name.trim().slice(0, 128);
446
+ if ('color' in input) {
447
+ const color = input.color ?? null;
448
+ if (color && !/^#[0-9a-fA-F]{3,8}$/.test(color))
449
+ throw new HttpError(400, 'Invalid color format');
450
+ proj.color = color;
451
+ }
452
+ return proj;
453
+ });
451
454
  ctx.deps.events.publish('project_rename', { profile: activeProfile });
452
455
  return { ok: true, project: proj };
453
456
  })),
454
- delete: os.projects.delete.handler(({ input, context: { ctx } }) => run(() => {
455
- let projects = ctx.deps.projects.load();
456
- const proj = projects.find((p) => p.project_id === input.project_id);
457
+ delete: os.projects.delete.handler(({ input, context: { ctx } }) => run(async () => {
457
458
  const activeProfile = ctx.deps.activeProfile();
458
- if (!proj || !ctx.deps.profilesMatch(proj.profile ?? null, activeProfile))
459
- throw new HttpError(404, 'Project not found');
460
- projects = projects.filter((p) => p.project_id !== input.project_id);
461
- ctx.deps.projects.save(projects);
459
+ await ctx.deps.projects.mutate((projects) => {
460
+ const position = projects.findIndex((p) => p.project_id === input.project_id);
461
+ const proj = projects[position];
462
+ if (!proj || !ctx.deps.profilesMatch(proj.profile ?? null, activeProfile))
463
+ throw new HttpError(404, 'Project not found');
464
+ projects.splice(position, 1);
465
+ });
462
466
  const store = ctx.deps.sessionStore;
463
467
  const activeIds = ctx.deps.sessions.deps.runtime.activeStreamIds;
464
468
  try {
465
- for (const entry of store.readIndexEntries()) {
469
+ for (const entry of (await store.readIndexEntries())) {
466
470
  if (entry.project_id !== input.project_id)
467
471
  continue;
468
472
  const sid = str(entry.session_id);
@@ -474,9 +478,9 @@ export const sessionsRouter = os.router({
474
478
  continue;
475
479
  }
476
480
  }
477
- const s = store.get(sid);
481
+ const s = (await store.get(sid));
478
482
  s.project_id = null;
479
- store.save(s);
483
+ await store.save(s);
480
484
  }
481
485
  catch { /* one slow or failing session never aborts the request */ }
482
486
  }
@@ -501,36 +505,36 @@ export const sessionsRouter = os.router({
501
505
  const bound = str(session?.bound_profile).trim() || null;
502
506
  return relayCall(() => Promise.resolve(ctx.deps.relay.presence.update(input, ctx.deps.isRootProfile(bound ?? ctx.deps.activeProfile()) ? 'default' : (bound ?? ctx.deps.activeProfile()))));
503
507
  }),
504
- viewed: os.talaria.viewed.handler(({ input, context: { ctx } }) => run(() => {
505
- ctx.deps.relay.markViewed(input.session_id.trim());
508
+ viewed: os.talaria.viewed.handler(({ input, context: { ctx } }) => run(async () => {
509
+ await ctx.deps.relay.markViewed(input.session_id.trim());
506
510
  return { ok: true };
507
511
  })),
508
512
  },
509
513
  share: {
510
- create: os.share.create.handler(({ input, context: { ctx } }) => run(() => {
514
+ create: os.share.create.handler(({ input, context: { ctx } }) => run(async () => {
511
515
  const sid = input.session_id.trim();
512
516
  if (!sid)
513
517
  throw new HttpError(400, 'session_id is required');
514
- return ctx.deps.sessions.createShare(sid);
518
+ return (await ctx.deps.sessions.createShare(sid));
515
519
  })),
516
- revoke: os.share.revoke.handler(({ input, context: { ctx } }) => run(() => {
520
+ revoke: os.share.revoke.handler(({ input, context: { ctx } }) => run(async () => {
517
521
  const sid = input.session_id.trim();
518
522
  if (!sid)
519
523
  throw new HttpError(400, 'session_id is required');
520
- return ctx.deps.sessions.revokeShare(sid);
524
+ return (await ctx.deps.sessions.revokeShare(sid));
521
525
  })),
522
- read: os.share.read.handler(({ input, context: { ctx } }) => run(() => {
526
+ read: os.share.read.handler(({ input, context: { ctx } }) => run(async () => {
523
527
  ctx.extraResponseHeaders = { 'x-robots-tag': 'noindex, nofollow' };
524
- return ctx.deps.sessions.loadShare(input.token.trim());
528
+ return (await ctx.deps.sessions.loadShare(input.token.trim()));
525
529
  })),
526
530
  },
527
531
  workspaces: {
528
- list: os.workspaces.list.handler(({ context: { ctx } }) => run(() => {
532
+ list: os.workspaces.list.handler(({ context: { ctx } }) => run(async () => {
529
533
  const profile = ctx.deps.activeProfile();
530
- return { workspaces: ctx.deps.workspaces.load(profile), last: ctx.deps.workspaces.lastWorkspace(profile), terminal_remote_backend: ctx.deps.features().terminal_remote_backend };
534
+ return { workspaces: (await ctx.deps.workspaces.load(profile)), last: (await ctx.deps.workspaces.lastWorkspace(profile)), terminal_remote_backend: ctx.deps.features().terminal_remote_backend };
531
535
  })),
532
- suggest: os.workspaces.suggest.handler(({ input, context: { ctx } }) => run(() => ({ suggestions: ctx.deps.workspaces.suggest(input.prefix ?? '', 12, ctx.deps.activeProfile()), prefix: input.prefix ?? '' }))),
533
- add: os.workspaces.add.handler(({ input, context: { ctx } }) => run(() => {
536
+ suggest: os.workspaces.suggest.handler(({ input, context: { ctx } }) => run(async () => ({ suggestions: (await ctx.deps.workspaces.suggest(input.prefix ?? '', 12, ctx.deps.activeProfile())), prefix: input.prefix ?? '' }))),
537
+ add: os.workspaces.add.handler(({ input, context: { ctx } }) => run(async () => {
534
538
  const ws = ctx.deps.workspaces;
535
539
  const pathStr = stripSurroundingQuotes(input.path.trim());
536
540
  const name = (input.name ?? '').trim();
@@ -569,42 +573,42 @@ export const sessionsRouter = os.router({
569
573
  catch (error) {
570
574
  throw new HttpError(400, error.message);
571
575
  }
572
- const list = ws.load(profile);
576
+ const list = (await ws.load(profile));
573
577
  if (list.some((w) => w.path === p))
574
578
  throw new HttpError(400, 'Workspace already in list');
575
579
  list.push({ path: p, name: name || basename(p) });
576
- ws.save(list, profile);
580
+ await ws.save(list, profile);
577
581
  return { ok: true, workspaces: list };
578
582
  })),
579
- remove: os.workspaces.remove.handler(({ input, context: { ctx } }) => run(() => {
583
+ remove: os.workspaces.remove.handler(({ input, context: { ctx } }) => run(async () => {
580
584
  const pathStr = input.path.trim();
581
585
  if (!pathStr)
582
586
  throw new HttpError(400, 'path is required');
583
587
  const profile = ctx.deps.activeProfile();
584
- const list = ctx.deps.workspaces.load(profile).filter((w) => w.path !== pathStr);
585
- ctx.deps.workspaces.save(list, profile);
588
+ const list = (await ctx.deps.workspaces.load(profile)).filter((w) => w.path !== pathStr);
589
+ await ctx.deps.workspaces.save(list, profile);
586
590
  return { ok: true, workspaces: list };
587
591
  })),
588
- rename: os.workspaces.rename.handler(({ input, context: { ctx } }) => run(() => {
592
+ rename: os.workspaces.rename.handler(({ input, context: { ctx } }) => run(async () => {
589
593
  const pathStr = input.path.trim();
590
594
  const name = input.name.trim();
591
595
  if (!pathStr || !name)
592
596
  throw new HttpError(400, 'path and name are required');
593
597
  const profile = ctx.deps.activeProfile();
594
- const list = ctx.deps.workspaces.load(profile);
598
+ const list = (await ctx.deps.workspaces.load(profile));
595
599
  const entry = list.find((w) => w.path === pathStr);
596
600
  if (!entry)
597
601
  throw new HttpError(404, 'Workspace not found');
598
602
  entry.name = name;
599
- ctx.deps.workspaces.save(list, profile);
603
+ await ctx.deps.workspaces.save(list, profile);
600
604
  return { ok: true, workspaces: list };
601
605
  })),
602
- reorder: os.workspaces.reorder.handler(({ input, context: { ctx } }) => run(() => {
606
+ reorder: os.workspaces.reorder.handler(({ input, context: { ctx } }) => run(async () => {
603
607
  const paths = input.paths;
604
608
  if (!Array.isArray(paths) || !paths.length)
605
609
  throw new HttpError(400, 'paths is required and must be a list');
606
610
  const profile = ctx.deps.activeProfile();
607
- const list = ctx.deps.workspaces.load(profile);
611
+ const list = (await ctx.deps.workspaces.load(profile));
608
612
  const byPath = new Map(list.map((w) => [w.path, w]));
609
613
  const reordered = [];
610
614
  const seen = new Set();
@@ -619,18 +623,18 @@ export const sessionsRouter = os.router({
619
623
  for (const w of list)
620
624
  if (!seen.has(w.path))
621
625
  reordered.push(w);
622
- ctx.deps.workspaces.save(reordered, profile);
626
+ await ctx.deps.workspaces.save(reordered, profile);
623
627
  return { ok: true, workspaces: reordered };
624
628
  })),
625
629
  },
626
630
  files: {
627
- list: os.files.list.handler(({ input, context: { ctx } }) => run(() => {
631
+ list: os.files.list.handler(({ input, context: { ctx } }) => run(async () => {
628
632
  if (!input.session_id)
629
633
  throw new HttpError(400, 'session_id is required');
630
- guardVisibility(ctx, input.session_id);
634
+ await guardVisibility(ctx, input.session_id);
631
635
  // Python `_handle_list` resolved the workspace directly and answered 404 with the trust error; the POST file ops
632
636
  // keep `get_session_for_file_ops`' lenient fallback.
633
- const s = fileOpsSession(ctx, input.session_id, { strictWorkspace: true });
637
+ const s = (await fileOpsSession(ctx, input.session_id, { strictWorkspace: true }));
634
638
  const rel = input.path ?? '.';
635
639
  try {
636
640
  const entries = listDir(s.workspace, rel);
@@ -640,11 +644,11 @@ export const sessionsRouter = os.router({
640
644
  throw fileError(error, 404);
641
645
  }
642
646
  })),
643
- read: os.files.read.handler(({ input, context: { ctx } }) => run(() => {
647
+ read: os.files.read.handler(({ input, context: { ctx } }) => run(async () => {
644
648
  if (!input.session_id)
645
649
  throw new HttpError(400, 'session_id is required');
646
- guardVisibility(ctx, input.session_id);
647
- const s = fileOpsSession(ctx, input.session_id);
650
+ await guardVisibility(ctx, input.session_id);
651
+ const s = (await fileOpsSession(ctx, input.session_id));
648
652
  if (!input.path)
649
653
  throw new HttpError(400, 'path is required');
650
654
  try {
@@ -655,9 +659,9 @@ export const sessionsRouter = os.router({
655
659
  throw fileError(error, 404);
656
660
  }
657
661
  })),
658
- save: os.files.save.handler(({ input, context: { ctx } }) => run(() => {
662
+ save: os.files.save.handler(({ input, context: { ctx } }) => run(async () => {
659
663
  requireFields(input, 'session_id', 'path');
660
- const s = fileOpsSession(ctx, input.session_id);
664
+ const s = (await fileOpsSession(ctx, input.session_id));
661
665
  try {
662
666
  if (['.docx', '.xlsx', '.pptx'].includes(extname(input.path).toLowerCase()))
663
667
  throw new HttpError(400, 'Office documents cannot be saved from the Web UI');
@@ -684,9 +688,9 @@ export const sessionsRouter = os.router({
684
688
  throw fileError(error);
685
689
  }
686
690
  })),
687
- create: os.files.create.handler(({ input, context: { ctx } }) => run(() => {
691
+ create: os.files.create.handler(({ input, context: { ctx } }) => run(async () => {
688
692
  requireFields(input, 'session_id', 'path');
689
- const s = fileOpsSession(ctx, input.session_id);
693
+ const s = (await fileOpsSession(ctx, input.session_id));
690
694
  try {
691
695
  const root = s.workspace;
692
696
  assertWorkspaceFree(ctx, root);
@@ -709,9 +713,9 @@ export const sessionsRouter = os.router({
709
713
  throw fileError(error);
710
714
  }
711
715
  })),
712
- createDir: os.files.createDir.handler(({ input, context: { ctx } }) => run(() => {
716
+ createDir: os.files.createDir.handler(({ input, context: { ctx } }) => run(async () => {
713
717
  requireFields(input, 'session_id', 'path');
714
- const s = fileOpsSession(ctx, input.session_id);
718
+ const s = (await fileOpsSession(ctx, input.session_id));
715
719
  try {
716
720
  const root = s.workspace;
717
721
  assertWorkspaceFree(ctx, root);
@@ -725,9 +729,9 @@ export const sessionsRouter = os.router({
725
729
  throw fileError(error);
726
730
  }
727
731
  })),
728
- delete: os.files.delete.handler(({ input, context: { ctx } }) => run(() => {
732
+ delete: os.files.delete.handler(({ input, context: { ctx } }) => run(async () => {
729
733
  requireFields(input, 'session_id', 'path');
730
- const s = fileOpsSession(ctx, input.session_id);
734
+ const s = (await fileOpsSession(ctx, input.session_id));
731
735
  try {
732
736
  const root = s.workspace;
733
737
  assertWorkspaceFree(ctx, root);
@@ -749,9 +753,9 @@ export const sessionsRouter = os.router({
749
753
  throw fileError(error);
750
754
  }
751
755
  })),
752
- rename: os.files.rename.handler(({ input, context: { ctx } }) => run(() => {
756
+ rename: os.files.rename.handler(({ input, context: { ctx } }) => run(async () => {
753
757
  requireFields(input, 'session_id', 'path', 'new_name');
754
- const s = fileOpsSession(ctx, input.session_id);
758
+ const s = (await fileOpsSession(ctx, input.session_id));
755
759
  try {
756
760
  const root = s.workspace;
757
761
  assertWorkspaceFree(ctx, root);
@@ -776,10 +780,10 @@ export const sessionsRouter = os.router({
776
780
  throw fileError(error);
777
781
  }
778
782
  })),
779
- move: os.files.move.handler(({ input, context: { ctx } }) => run(() => {
783
+ move: os.files.move.handler(({ input, context: { ctx } }) => run(async () => {
780
784
  requireFields({ ...input, dest_dir: input.dest_dir ?? input.destination }, 'session_id', 'path', 'dest_dir');
781
785
  const destDirRaw = (input.dest_dir ?? input.destination ?? '.').trim() || '.';
782
- const s = fileOpsSession(ctx, input.session_id);
786
+ const s = (await fileOpsSession(ctx, input.session_id));
783
787
  try {
784
788
  const root = s.workspace;
785
789
  assertWorkspaceFree(ctx, root);
@@ -812,7 +816,7 @@ export const sessionsRouter = os.router({
812
816
  })),
813
817
  reveal: os.files.reveal.handler(({ input, context: { ctx } }) => run(async () => {
814
818
  requireFields(input, 'session_id', 'path');
815
- const s = fileOpsSession(ctx, input.session_id);
819
+ const s = (await fileOpsSession(ctx, input.session_id));
816
820
  try {
817
821
  const target = safeResolve(s.workspace, input.path);
818
822
  if (!existsSync(target))
@@ -831,9 +835,9 @@ export const sessionsRouter = os.router({
831
835
  throw fileError(error);
832
836
  }
833
837
  })),
834
- path: os.files.path.handler(({ input, context: { ctx } }) => run(() => {
838
+ path: os.files.path.handler(({ input, context: { ctx } }) => run(async () => {
835
839
  requireFields(input, 'session_id', 'path');
836
- const s = fileOpsSession(ctx, input.session_id);
840
+ const s = (await fileOpsSession(ctx, input.session_id));
837
841
  try {
838
842
  return { ok: true, path: safeResolve(s.workspace, input.path) };
839
843
  }
@@ -843,7 +847,7 @@ export const sessionsRouter = os.router({
843
847
  })),
844
848
  openVsCode: os.files.openVsCode.handler(({ input, context: { ctx } }) => run(async () => {
845
849
  requireFields(input, 'session_id', 'path');
846
- const s = fileOpsSession(ctx, input.session_id);
850
+ const s = (await fileOpsSession(ctx, input.session_id));
847
851
  try {
848
852
  const target = safeResolve(s.workspace, input.path);
849
853
  if (!existsSync(target))
@@ -859,7 +863,7 @@ export const sessionsRouter = os.router({
859
863
  throw fileError(error);
860
864
  }
861
865
  })),
862
- escapeAuthorize: os.files.escapeAuthorize.handler(({ input, context: { ctx } }) => run(() => {
866
+ escapeAuthorize: os.files.escapeAuthorize.handler(({ input, context: { ctx } }) => run(async () => {
863
867
  // A Referer alone is not a browser fetch: Python required `Origin`, which the global CSRF check has already matched.
864
868
  if (!ctx.header('origin'))
865
869
  throw new HttpError(403, 'browser origin required');
@@ -871,7 +875,7 @@ export const sessionsRouter = os.router({
871
875
  throw new HttpError(400, 'session_id is required');
872
876
  if (!rel)
873
877
  throw new HttpError(400, 'path is required');
874
- const s = fileOpsSession(ctx, sid);
878
+ const s = (await fileOpsSession(ctx, sid));
875
879
  try {
876
880
  return ctx.deps.escapeGrants.authorize(s.workspace, sid, s.profile, rel);
877
881
  }
@@ -879,8 +883,8 @@ export const sessionsRouter = os.router({
879
883
  throw fileError(error, 404);
880
884
  }
881
885
  })),
882
- escapeList: os.files.escapeList.handler(({ input, context: { ctx } }) => run(() => {
883
- const req = escapeRequest(ctx, input.session_id, input.token, input.path ?? '.');
886
+ escapeList: os.files.escapeList.handler(({ input, context: { ctx } }) => run(async () => {
887
+ const req = (await escapeRequest(ctx, input.session_id, input.token, input.path ?? '.'));
884
888
  try {
885
889
  const listing = ctx.deps.escapeGrants.list(req);
886
890
  return { ...listing, entries: serializeEntriesForBrowser(listing.entries) };
@@ -889,8 +893,8 @@ export const sessionsRouter = os.router({
889
893
  throw fileError(error, 404);
890
894
  }
891
895
  })),
892
- escapeRead: os.files.escapeRead.handler(({ input, context: { ctx } }) => run(() => {
893
- const req = escapeRequest(ctx, input.session_id, input.token, input.path ?? '');
896
+ escapeRead: os.files.escapeRead.handler(({ input, context: { ctx } }) => run(async () => {
897
+ const req = (await escapeRequest(ctx, input.session_id, input.token, input.path ?? ''));
894
898
  try {
895
899
  const file = ctx.deps.escapeGrants.read(req);
896
900
  // The frame loads the bytes through the same grant; the workspace preview grant would outlive and skip its re-checks.
@@ -903,12 +907,12 @@ export const sessionsRouter = os.router({
903
907
  },
904
908
  });
905
909
  /** The escape routes' shared front half: required ids, the session, and the grant re-check (403 when it fails). */
906
- export function escapeRequest(ctx, sid, token, rel) {
910
+ export async function escapeRequest(ctx, sid, token, rel) {
907
911
  if (!sid)
908
912
  throw new HttpError(400, 'session_id is required');
909
913
  if (!token)
910
914
  throw new HttpError(400, 'token is required');
911
- const s = fileOpsSession(ctx, sid);
915
+ const s = (await fileOpsSession(ctx, sid));
912
916
  try {
913
917
  return ctx.deps.escapeGrants.resolve(s.workspace, sid, s.profile, token, rel);
914
918
  }
@@ -947,10 +951,10 @@ export function fileError(error, notFoundStatus = 400) {
947
951
  * `state.db` but that has no `sessions/<sid>.json` (CLI, messaging) is served as an external view bound to the active
948
952
  * workspace, as the sidebar already lists it (issue #3280).
949
953
  */
950
- export function fileOpsSession(ctx, sid, opts = {}) {
954
+ export async function fileOpsSession(ctx, sid, opts = {}) {
951
955
  let session;
952
956
  try {
953
- session = ctx.deps.sessionStore.get(sid, { metadataOnly: true });
957
+ session = (await ctx.deps.sessionStore.get(sid, { metadataOnly: true }));
954
958
  }
955
959
  catch {
956
960
  const profile = ctx.deps.activeProfile();
@@ -958,7 +962,7 @@ export function fileOpsSession(ctx, sid, opts = {}) {
958
962
  throw new HttpError(404, 'Session not found');
959
963
  if (!ctx.deps.workspaces.profileSupportsLocalIo(profile))
960
964
  throw new HttpError(400, REMOTE_WORKSPACE_UNSUPPORTED_CODE, { message: REMOTE_WORKSPACE_UNSUPPORTED_MESSAGE });
961
- return { workspace: ctx.deps.workspaces.lastWorkspace(profile), profile, recovered: false, session: null };
965
+ return { workspace: (await ctx.deps.workspaces.lastWorkspace(profile)), profile, recovered: false, session: null };
962
966
  }
963
967
  if (!ctx.deps.profilesMatch(session.profile, ctx.deps.activeProfile()))
964
968
  throw new HttpError(404, 'Session not found');
@@ -968,7 +972,7 @@ export function fileOpsSession(ctx, sid, opts = {}) {
968
972
  let recovered = false;
969
973
  try {
970
974
  ;
971
- [workspace, recovered] = ctx.deps.workspaces.resolveImplicitWithRecovery(session.workspace, (p) => ctx.deps.workspaces.lastWorkspace(p), session.profile);
975
+ [workspace, recovered] = (await ctx.deps.workspaces.resolveImplicitWithRecovery(session.workspace, async (p) => (await ctx.deps.workspaces.lastWorkspace(p)), session.profile));
972
976
  }
973
977
  catch (error) {
974
978
  if (opts.strictWorkspace)
@@ -981,10 +985,10 @@ export function fileOpsSession(ctx, sid, opts = {}) {
981
985
  if (cached)
982
986
  cached.workspace = workspace;
983
987
  try {
984
- const full = ctx.deps.sessionStore.load(sid);
988
+ const full = (await ctx.deps.sessionStore.load(sid));
985
989
  if (full) {
986
990
  full.workspace = workspace;
987
- ctx.deps.sessionStore.save(full, { touchUpdatedAt: false });
991
+ (await ctx.deps.sessionStore.save(full, { touchUpdatedAt: false }));
988
992
  }
989
993
  }
990
994
  catch { /* recovery persistence is best effort */ }