@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
@@ -10,54 +10,12 @@ import { createHash } from 'node:crypto';
10
10
  import { redactText } from '../redact.js';
11
11
  import { CONTEXT_USAGE_FIELDS, Session, contextUsage, sharePath, stripSidebarHeavyMetadata } from './session.js';
12
12
  import { existsSync, readFileSync, statSync } from 'node:fs';
13
- import { isCliSessionRow as isStateDbCliRow, isCliSessionRowVisible, normalizeAgentSessionSource } from './state-db.js';
13
+ import { AGENT_STORAGE_OK, CANONICAL_READ_ONLY_REASON, OWNERSHIP_UNAVAILABLE_REASON, isCliSessionRow as isStateDbCliRow, isCliSessionRowVisible, normalizeAgentSessionSource } from './state-db.js';
14
14
  import { MESSAGING_SOURCES, sourceKind } from './source-kind.js';
15
- import { SessionRowSchema } from '@maudecode/talaria-web-contracts';
15
+ import {} from '@maudecode/talaria-web-contracts';
16
16
  const num = (v) => { const n = Number(v ?? 0); return Number.isFinite(n) && n > 0 ? n : 0; };
17
- const malformedFiles = new WeakMap();
18
- /** Read-only projection; never let a corrupt identity acquire a generated ID. */
19
- export function sanitizeSessionRow(value, store, file) {
20
- const row = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
21
- file ??= `${str(row.session_id)}.json`;
22
- const mismatchedFile = file.endsWith('.json') && file !== '_index.json' && row.session_id !== file.slice(0, -5);
23
- if (!SessionRowSchema.shape.session_id.safeParse(row.session_id).success || mismatchedFile) {
24
- const logged = malformedFiles.get(store) ?? new Set();
25
- if (!logged.has(file)) {
26
- store.deps.log(`[webui] WARNING: skipping session row with invalid session_id in ${JSON.stringify(file)}`);
27
- logged.add(file);
28
- malformedFiles.set(store, logged);
29
- }
30
- return null;
31
- }
32
- const result = { ...row, title: row.title ?? '' };
33
- for (const [key, schema] of Object.entries(SessionRowSchema.shape)) {
34
- const value = result[key];
35
- if (value === undefined || schema.safeParse(value).success)
36
- continue;
37
- const coerced = typeof value === 'string' && value.trim() !== ''
38
- ? value.trim() === 'true' ? true : value.trim() === 'false' ? false : Number(value)
39
- : typeof value === 'number' || typeof value === 'boolean' ? String(value) : undefined;
40
- const boolean = value === 0 || value === 1 ? value === 1 : coerced === 0 || coerced === 1 ? coerced === 1 : undefined;
41
- if (coerced !== undefined && schema.safeParse(coerced).success)
42
- result[key] = coerced;
43
- else if (boolean !== undefined && schema.safeParse(boolean).success)
44
- result[key] = boolean;
45
- else if (key === 'title')
46
- result[key] = '';
47
- // Invalid persisted permissions must not turn a locked session into an editable one.
48
- else if (key === 'read_only')
49
- result[key] = true;
50
- else
51
- Reflect.deleteProperty(result, key);
52
- }
53
- // These persisted flags affect list filtering before the wire flags are computed.
54
- for (const key of ['pre_compression_snapshot', 'default_hidden', 'has_pending_user_message']) {
55
- if (result[key] === 'true' || result[key] === 'false')
56
- result[key] = result[key] === 'true';
57
- }
58
- return result;
59
- }
60
- /** TAL-306: the row's `sort_ts`, the time it sorts and date-buckets by on every client. */
17
+ import { sanitizeSessionRow } from './storage/row.js';
18
+ export { sanitizeSessionRow } from './storage/row.js';
61
19
  export function sessionSortTimestamp(row) {
62
20
  return num(row.last_message_at) || num(row.updated_at) || num(row.created_at);
63
21
  }
@@ -205,7 +163,7 @@ function isEmptyUntitledDraft(row) {
205
163
  return str(row.title || 'Untitled') === 'Untitled' && Math.trunc(Number(row.message_count ?? 0)) === 0 && !row.active_stream_id && !row.has_pending_user_message && !row.worktree_path;
206
164
  }
207
165
  /** Python `all_sessions` without the state.db lineage overlay. */
208
- export function allSessions(store, opts = {}) {
166
+ export async function allSessions(store, opts = {}) {
209
167
  const activeStreamIds = store.deps.activeStreamIds();
210
168
  const finish = (result) => {
211
169
  result = result.flatMap((row) => { const clean = sanitizeSessionRow(row, store); return clean ? [clean] : []; });
@@ -228,43 +186,43 @@ export function allSessions(store, opts = {}) {
228
186
  }
229
187
  return rows.sort(compareSessionRows);
230
188
  };
231
- const indexExists = (() => { try {
232
- return Boolean(store.readIndexEntries());
189
+ const indexExists = (await (async () => { try {
190
+ return Boolean((await store.readIndexEntries()));
233
191
  }
234
192
  catch {
235
193
  return false;
236
- } })();
194
+ } })());
237
195
  if (!indexExists) {
238
196
  try {
239
- store.writeIndex();
197
+ (await store.writeIndex());
240
198
  }
241
199
  catch { /* fall through to the scan */ }
242
200
  }
243
201
  try {
244
- let index = store.readIndexEntries().flatMap((row) => {
245
- const clean = sanitizeSessionRow(row, store, '_index.json');
202
+ let index = (await store.readIndexEntries()).flatMap((row) => {
203
+ const clean = sanitizeSessionRow(row, store, 'index');
246
204
  return clean ? [clean] : [];
247
205
  });
248
206
  const inMemory = new Set(store.sessions.keys());
249
- const persisted = store.persistedIds();
250
- if (!index.length && store.hasPersistedSessionFiles())
207
+ const persisted = (await store.persistedIds());
208
+ if (!index.length && (await store.hasPersistedSessionFiles()))
251
209
  throw new Error('empty session index while session files exist');
252
210
  index = index.filter((r) => inMemory.has(str(r.session_id)) || persisted.has(str(r.session_id)));
253
- if (!index.length && store.hasPersistedSessionFiles())
211
+ if (!index.length && (await store.hasPersistedSessionFiles()))
254
212
  throw new Error('session index has no live rows while session files exist');
255
213
  const backfilled = [];
256
- index = index.map((r) => {
214
+ index = await Promise.all(index.map(async (r) => {
257
215
  if ('last_message_at' in r)
258
216
  return r;
259
- const full = store.load(str(r.session_id));
217
+ const full = (await store.load(str(r.session_id)));
260
218
  if (!full)
261
219
  return r;
262
220
  backfilled.push(full);
263
221
  return full.compact({ sidebarMetadataOnly: opts.sidebarMetadataOnly ?? false });
264
- });
222
+ }));
265
223
  if (backfilled.length) {
266
224
  try {
267
- store.writeIndex(backfilled);
225
+ (await store.writeIndex(backfilled));
268
226
  }
269
227
  catch { /* ignore */ }
270
228
  }
@@ -276,7 +234,7 @@ export function allSessions(store, opts = {}) {
276
234
  const missing = [...persisted].filter((sid) => !indexMap.has(sid)).sort();
277
235
  const recovered = [];
278
236
  for (const sid of missing) {
279
- const sidecar = store.loadMetadataOnly(sid);
237
+ const sidecar = (await store.loadMetadataOnly(sid));
280
238
  if (!sidecar)
281
239
  continue;
282
240
  indexMap.set(sidecar.session_id, sidecar.compact({ includeRuntime: true, activeStreamIds, sidebarMetadataOnly: opts.sidebarMetadataOnly ?? false }));
@@ -284,12 +242,12 @@ export function allSessions(store, opts = {}) {
284
242
  }
285
243
  if (recovered.length) {
286
244
  try {
287
- store.writeIndex(recovered);
245
+ (await store.writeIndex(recovered));
288
246
  }
289
247
  catch { /* ignore */ }
290
248
  }
291
- const indexCounts = store.indexMessageCounts(index);
292
- const refreshed = refreshIndexRowsFromSidecarMetadata(store, [...indexMap.values()], indexCounts, activeStreamIds);
249
+ const indexCounts = (await store.indexMessageCounts(index));
250
+ const refreshed = (await refreshIndexRowsFromSidecarMetadata(store, [...indexMap.values()], indexCounts, activeStreamIds));
293
251
  let result = refreshed.filter((r) => r.session_id);
294
252
  result = result.filter((r) => !isEmptyUntitledDraft(r));
295
253
  return finish(result);
@@ -297,7 +255,7 @@ export function allSessions(store, opts = {}) {
297
255
  catch {
298
256
  /* fall back to the full scan */
299
257
  }
300
- const out = store.scanAll();
258
+ const out = (await store.scanAll());
301
259
  for (const s of store.sessions.values())
302
260
  if (!out.some((x) => x.session_id === s.session_id))
303
261
  out.push(s);
@@ -306,22 +264,14 @@ export function allSessions(store, opts = {}) {
306
264
  .map((s) => s.compact({ includeRuntime: true, activeStreamIds, sidebarMetadataOnly: opts.sidebarMetadataOnly ?? false }));
307
265
  return finish(rows);
308
266
  }
309
- function sidecarMtimeAfterIndexTimestamp(store, row) {
267
+ async function sidecarMtimeAfterIndexTimestamp(store, row) {
310
268
  const sid = str(row.session_id);
311
269
  if (!sid)
312
270
  return false;
313
- try {
314
- const mtime = statSyncMtime(store.pathFor(sid));
315
- return mtime > sessionSortTimestamp(row) + 0.001;
316
- }
317
- catch {
318
- return false;
319
- }
271
+ // A backend revision is opaque; refresh legacy rows whenever persisted data exists.
272
+ return await store.revision(sid) !== null;
320
273
  }
321
- function statSyncMtime(path) {
322
- return statSync(path).mtimeMs / 1000;
323
- }
324
- function rowMayNeedSidecarRefresh(store, row, staleSnapshotIds) {
274
+ async function rowMayNeedSidecarRefresh(store, row, staleSnapshotIds) {
325
275
  if (hasLiveState(row))
326
276
  return true;
327
277
  const sid = str(row.session_id);
@@ -332,15 +282,15 @@ function rowMayNeedSidecarRefresh(store, row, staleSnapshotIds) {
332
282
  return true;
333
283
  const lineageShaped = Boolean(row.parent_session_id || row._lineage_root_id || row._compression_segment_count);
334
284
  const needsMtime = Boolean(sid) && (looksLikeStaleZeroMessageRow(row) || (lineageShaped && (row.user_message_count === null || row.user_message_count === undefined)));
335
- return needsMtime && sidecarMtimeAfterIndexTimestamp(store, row);
285
+ return needsMtime && await sidecarMtimeAfterIndexTimestamp(store, row);
336
286
  }
337
- if (sid && looksLikeStaleZeroMessageRow(row) && str(row.session_source).trim().toLowerCase() !== 'fork' && sidecarMtimeAfterIndexTimestamp(store, row))
287
+ if (sid && looksLikeStaleZeroMessageRow(row) && str(row.session_source).trim().toLowerCase() !== 'fork' && await sidecarMtimeAfterIndexTimestamp(store, row))
338
288
  return true;
339
289
  if (row.message_count === null || row.message_count === undefined || row.last_message_at === null || row.last_message_at === undefined)
340
290
  return true;
341
291
  return Boolean(sid) && staleSnapshotIds.has(sid);
342
292
  }
343
- function staleSnapshotRefreshIds(store, rows) {
293
+ async function staleSnapshotRefreshIds(store, rows) {
344
294
  const byId = new Map(rows.filter((r) => r.session_id).map((r) => [str(r.session_id), r]));
345
295
  const groups = new Map();
346
296
  for (const row of rows) {
@@ -364,23 +314,23 @@ function staleSnapshotRefreshIds(store, rows) {
364
314
  continue;
365
315
  if (snapshot.user_message_count !== null && snapshot.user_message_count !== undefined && Math.trunc(Number(snapshot.message_count ?? 0)) > 0 && snapshot.last_message_at !== null && snapshot.last_message_at !== undefined)
366
316
  continue;
367
- if (sidecarMtimeAfterIndexTimestamp(store, snapshot))
317
+ if (await sidecarMtimeAfterIndexTimestamp(store, snapshot))
368
318
  ids.add(sid);
369
319
  }
370
320
  }
371
321
  return ids;
372
322
  }
373
323
  const REFRESH_KEYS = ['message_count', 'updated_at', 'last_message_at', 'title', 'workspace', 'model', 'model_provider', 'created_at', 'pinned', 'archived', 'project_id', 'profile', 'pre_compression_snapshot', 'parent_session_id', 'source_tag', 'raw_source', 'session_source', 'source_label', 'active_stream_id', 'has_pending_user_message', 'pending_user_message', 'pending_started_at'];
374
- function refreshIndexRowsFromSidecarMetadata(store, rows, indexCounts, activeStreamIds) {
375
- const stale = staleSnapshotRefreshIds(store, rows);
324
+ async function refreshIndexRowsFromSidecarMetadata(store, rows, indexCounts, activeStreamIds) {
325
+ const stale = await staleSnapshotRefreshIds(store, rows);
376
326
  const out = [];
377
327
  for (const row of rows) {
378
328
  const sid = str(row.session_id);
379
- if (!rowMayNeedSidecarRefresh(store, row, stale) || !sid) {
329
+ if (!await rowMayNeedSidecarRefresh(store, row, stale) || !sid) {
380
330
  out.push(row);
381
331
  continue;
382
332
  }
383
- const sidecar = store.loadMetadataOnly(sid, { indexMessageCounts: indexCounts });
333
+ const sidecar = (await store.loadMetadataOnly(sid, { indexMessageCounts: indexCounts }));
384
334
  if (!sidecar) {
385
335
  out.push(row);
386
336
  continue;
@@ -407,7 +357,7 @@ export const SIDEBAR_SESSION_RESPONSE_FIELDS = new Set([
407
357
  'is_cli_session', 'is_messaging_session', 'is_streaming', 'cron_running', 'active_stream_id', 'has_pending_user_message', 'pending_started_at', 'default_hidden',
408
358
  'worktree_path', 'worktree_branch', 'parent_session_id', 'parent_title', 'parent_source', 'relationship_type', 'pre_compression_snapshot', '_lineage_root_id',
409
359
  '_lineage_tip_id', '_compression_segment_count', '_lineage_collapsed_count', '_parent_lineage_root_id', '_parent_lineage_tip_id', '_cross_surface_child_session',
410
- 'match_type', 'match_preview', 'read_only', 'can_branch', 'can_pin', 'can_archive', 'can_delete', 'can_duplicate', 'gateway_routing', 'share_url',
360
+ 'match_type', 'match_preview', 'read_only', 'read_only_reason', 'can_branch', 'can_pin', 'can_archive', 'can_delete', 'can_duplicate', 'gateway_routing', 'share_url',
411
361
  ]);
412
362
  export function isCliSessionRow(row) {
413
363
  const lower = (v) => str(v).trim().toLowerCase();
@@ -503,15 +453,20 @@ export function isMessagingSessionRecord(row) {
503
453
  return true;
504
454
  return isKnownMessagingSource(first(row.raw_source, row.source_tag, row.source, row.source_label));
505
455
  }
506
- /** Python `_is_claimable_cli_source`: a denylist of foreign families that own their sessions. */
456
+ /**
457
+ * Python `_is_claimable_cli_source`: a denylist of foreign families that own their sessions. A `kanban` state.db owner
458
+ * (`stateDbSessionSources` folds in the lineage's `created_source`) refuses whatever the row's tag says (TAL-793).
459
+ */
507
460
  export function isClaimableCliSource(meta, stateDbSource) {
508
- if (meta.read_only)
461
+ if (typeof stateDbSource === 'object' || meta.read_only)
462
+ return false;
463
+ if (stateDbSource.trim().toLowerCase() === 'kanban')
509
464
  return false;
510
465
  const sessionSource = str(meta.session_source).trim().toLowerCase();
511
466
  if (['messaging', 'external_agent'].includes(sessionSource))
512
467
  return false;
513
468
  const tag = str(meta.source_tag || meta.raw_source).trim().toLowerCase();
514
- const refused = new Set(['claude_code', 'cron', 'external_agent', 'gateway', 'messaging', 'subagent', 'unknown']);
469
+ const refused = new Set(['claude_code', 'cron', 'external_agent', 'gateway', 'kanban', 'messaging', 'subagent', 'unknown']);
515
470
  if (tag && refused.has(tag))
516
471
  return false;
517
472
  if (isMessagingSessionRecord(meta))
@@ -523,26 +478,33 @@ export function isClaimableCliSource(meta, stateDbSource) {
523
478
  /**
524
479
  * TAL-358: marks read-only each WebUI sidecar row whose active-profile state.db owner (`sessions.source`) refuses
525
480
  * claiming, as a sidecar-less row from that owner is. A sidecar persisted as WebUI- or fork-born stays WebUI-owned
526
- * whatever state.db mirrors for its id. `stateDbSources` reads every candidate's owner in one batch, not per row; an
481
+ * for legacy source tags, but cannot override a canonical receipt or ledger. Owners are batched per profile; an
527
482
  * unreadable state.db (null) locks every candidate, since an unknown owner is not a released one.
528
483
  */
529
484
  export function withOwnerLocks(rows, stateDbSources) {
530
- const candidates = ownerLockCandidates(rows);
531
- if (!candidates.length)
532
- return rows;
533
- const owners = stateDbSources(candidates);
534
- const locked = new Set(candidates.filter((sid) => {
535
- if (!owners)
536
- return true;
537
- const source = str(owners.get(sid)).trim().toLowerCase();
538
- return Boolean(source) && !isClaimableCliSource({ source_tag: source, ...normalizeAgentSessionSource(source) }, source);
539
- }));
540
- return locked.size ? rows.map((r) => (locked.has(str(r.session_id)) ? { ...r, read_only: true } : r)) : rows;
541
- }
542
- /** The ids `withOwnerLocks` asks `stateDbSources` about: rows not already read-only and not WebUI- or fork-born. */
485
+ const byProfile = ownerLockCandidates(rows);
486
+ const ownersByProfile = new Map([...byProfile].map(([profile, ids]) => [profile, stateDbSources([...ids], profile)]));
487
+ return rows.map((r) => {
488
+ const owners = ownersByProfile.get(str(r.profile) || 'default');
489
+ const owner = owners?.get(str(r.session_id).trim());
490
+ if (typeof owner === 'object')
491
+ return { ...r, ...(owner.source ? { ...normalizeAgentSessionSource(owner.source), source_tag: owner.source } : {}), read_only: true, read_only_reason: owner.reason ?? CANONICAL_READ_ONLY_REASON };
492
+ const webui = ['source_tag', 'raw_source', 'session_source'].some((k) => ['webui', 'fork'].includes(str(r[k]).trim().toLowerCase()));
493
+ if (!owners || (!webui && owner && !isClaimableCliSource({ source_tag: owner, ...normalizeAgentSessionSource(owner) }, owner)))
494
+ return { ...r, read_only: true, ...(!owners ? { read_only_reason: OWNERSHIP_UNAVAILABLE_REASON } : {}) };
495
+ return r;
496
+ });
497
+ }
498
+ /** Every sidecar is checked in its own profile, including cached WebUI/fork tags. */
543
499
  export function ownerLockCandidates(rows) {
544
- const webuiOwned = (r) => ['source_tag', 'raw_source', 'session_source'].some((k) => ['webui', 'fork'].includes(str(r[k]).trim().toLowerCase()));
545
- return rows.filter((r) => !r.read_only && !webuiOwned(r)).map((r) => str(r.session_id));
500
+ const byProfile = new Map();
501
+ for (const row of rows) {
502
+ const profile = str(row.profile) || 'default';
503
+ const ids = byProfile.get(profile) ?? new Set();
504
+ ids.add(str(row.session_id).trim());
505
+ byProfile.set(profile, ids);
506
+ }
507
+ return byProfile;
546
508
  }
547
509
  /** Python `_session_is_subagent_view_only` on a row: a delegated child by any source marker. */
548
510
  export function isSubagentRow(row) {
@@ -577,15 +539,16 @@ export function withSessionWireFlags(row, activeStreamIds) {
577
539
  else
578
540
  r.read_only = Boolean(r.read_only);
579
541
  // The branch gate (`SessionService.branch`): never a subagent child, and a read-only source only when it is a cron run.
580
- r.can_branch = !subagent && (!r.read_only || str(r.source_tag || r.raw_source).trim().toLowerCase() === 'cron');
542
+ const ownerReadOnly = r.read_only && Boolean(r.read_only_reason);
543
+ r.can_branch = !ownerReadOnly && !subagent && (!r.read_only || str(r.source_tag || r.raw_source).trim().toLowerCase() === 'cron');
581
544
  // Pin and archive refuse only subagent children; duplicate also needs the WebUI sidecar it copies, so a sidecar-less
582
545
  // foreign row arrives with `can_duplicate: false`. Rename, move and delete follow `read_only` (the mutation gate).
583
546
  // A Claude Code import is a live view Web never stores (TAL-551), so it cannot be pinned or archived either.
584
- const stored = !subagent && kind !== 'claude_code';
547
+ const stored = !ownerReadOnly && !subagent && kind !== 'claude_code';
585
548
  r.can_pin = stored;
586
549
  r.can_archive = stored;
587
550
  r.can_delete = !r.read_only;
588
- r.can_duplicate = !subagent && r.can_duplicate !== false;
551
+ r.can_duplicate = !ownerReadOnly && !subagent && r.can_duplicate !== false;
589
552
  r.sort_ts = sessionSortTimestamp(r);
590
553
  return row;
591
554
  }
@@ -618,13 +581,53 @@ export function mergeCliSidebarMetadata(ui, meta) {
618
581
  function sessionSourceIsWebui(row) {
619
582
  return ['source_tag', 'raw_source', 'session_source', 'source'].some((k) => str(row[k]).trim().toLowerCase() === 'webui');
620
583
  }
621
- function sessionLineageIds(row) {
584
+ export function sessionLineageIds(row) {
622
585
  const ids = new Set();
623
586
  for (const key of ['session_id', '_lineage_root_id', '_lineage_tip_id'])
624
587
  if (row[key])
625
588
  ids.add(str(row[key]));
589
+ if (Array.isArray(row._lineage_ids))
590
+ for (const id of row._lineage_ids)
591
+ if (typeof id === 'string')
592
+ ids.add(id);
626
593
  return ids;
627
594
  }
595
+ /** The newest saved physical member owns UI metadata; listing and materialization use this same selection. */
596
+ export function latestLineageSidecar(ids, profile, lookup, profilesMatch) {
597
+ for (let i = ids.length - 1; i >= 0; i -= 1) {
598
+ const row = lookup(ids[i]);
599
+ if (row && profilesMatch(str(row.profile) || null, profile))
600
+ return row;
601
+ }
602
+ return undefined;
603
+ }
604
+ /** Receipt members are aliases of the current target. Keep UI metadata, never an old member's transcript counts. */
605
+ export function reconcileLocalSessionRows(rows, cli, profilesMatch) {
606
+ const byId = new Map(rows.map((row) => [str(row.session_id), row]));
607
+ const members = new Map();
608
+ const chosen = new Map();
609
+ for (const meta of cli) {
610
+ if (!Array.isArray(meta._lineage_ids))
611
+ continue;
612
+ const ids = meta._lineage_ids.filter((id) => typeof id === 'string');
613
+ for (const id of ids)
614
+ members.set(id, meta);
615
+ const row = latestLineageSidecar(ids, str(meta.profile) || null, (id) => byId.get(id), profilesMatch);
616
+ if (row)
617
+ chosen.set(str(meta.session_id), { row, meta });
618
+ }
619
+ const other = rows.filter((row) => { const meta = members.get(str(row.session_id)); return !meta || !profilesMatch(str(row.profile) || null, str(meta.profile) || null); });
620
+ for (const [target, { row, meta }] of chosen) {
621
+ const merged = mergeCliSidebarMetadata(row, meta);
622
+ if (str(row.session_id) !== target) {
623
+ merged.message_count = meta.message_count ?? 0;
624
+ merged.user_message_count = meta.user_message_count ?? 0;
625
+ merged.last_message_at = meta.last_message_at ?? meta.updated_at;
626
+ }
627
+ other.push({ ...merged, session_id: target });
628
+ }
629
+ return other;
630
+ }
628
631
  /** Python `_dedupe_cli_sidebar_sessions_for_api`: additive state rows, keeping project-hidden background rows addressable. */
629
632
  export function dedupeCliSidebarSessions(cli, represented, opts) {
630
633
  const sf = str(opts.sourceFilter).trim().toLowerCase();
@@ -715,6 +718,9 @@ export function capRecentCliSessions(rows, cap = CLI_VISIBLE_SESSION_CAP) {
715
718
  return true; seen += 1; return seen <= cap; });
716
719
  }
717
720
  function sessionHasServerVisibleMessages(row) {
721
+ // A validated local reset keeps its empty current target discoverable under the existing lineage identity.
722
+ if (row._lineage_root_id && row._lineage_tip_id)
723
+ return true;
718
724
  // A worktree chat owns a directory on disk from creation; its row is where the user removes it (TAL-605).
719
725
  if (sidebarMessageCount(row) > 0 || row.worktree_path)
720
726
  return true;
@@ -750,9 +756,9 @@ function hiddenArchivedReferences(visible, archived) {
750
756
  return references;
751
757
  }
752
758
  /** Python `_build_session_list_cache_payload`; of its orphaned-sidecar prunes only the imported one (#3238) applies. */
753
- export function buildSessionListPayload(store, params) {
754
- let webuiSessions = (params.webuiRows ?? allSessions(store, { sidebarMetadataOnly: true })).map((r) => ({ ...r, is_cli_session: isCliSessionRow(r) }));
755
- const orphans = params.pruneOrphanedImports?.(webuiSessions);
759
+ export async function buildSessionListPayload(store, params) {
760
+ let webuiSessions = (params.webuiRows ?? (await allSessions(store, { sidebarMetadataOnly: true }))).map((r) => ({ ...r, is_cli_session: isCliSessionRow(r) }));
761
+ const orphans = await params.pruneOrphanedImports?.(webuiSessions);
756
762
  if (orphans?.size)
757
763
  webuiSessions = webuiSessions.filter((r) => !orphans.has(str(r.session_id)));
758
764
  // Before the state.db overlay below replaces the sidecar's own source fields, which the WebUI-born exception reads.
@@ -761,6 +767,7 @@ export function buildSessionListPayload(store, params) {
761
767
  let dedupedCli = [];
762
768
  if (params.cliRows) {
763
769
  const cliRows = params.cliRows.flatMap((r) => { const clean = sanitizeSessionRow(r, store, 'state.db'); return clean ? [clean] : []; });
770
+ webuiSessions = reconcileLocalSessionRows(webuiSessions, cliRows, params.profilesMatch);
764
771
  const cliById = new Map(cliRows.map((r) => [str(r.session_id), r]));
765
772
  webuiSessions = webuiSessions.map((s) => {
766
773
  const meta = cliById.get(str(s.session_id));
@@ -786,9 +793,11 @@ export function buildSessionListPayload(store, params) {
786
793
  for (const s of webuiSessions)
787
794
  for (const id of sessionLineageIds(s))
788
795
  represented.add(id);
789
- dedupedCli = dedupeCliSidebarSessions(cliRows, represented, { showCli: params.showCliSessions, showCron: params.showCronSessions, showWebhook: params.showWebhookSessions, showKanban: params.showKanbanSessions, sourceFilter: params.sourceFilter ?? null, requestVisibilityOverrides: params.requestVisibilityOverrides })
790
- // A sidecar-less foreign row whose owner refuses claiming is read-only, as its detail and mutations are.
791
- .map((r) => ({ ...r, read_only: !isClaimableCliSource(r, str(r.source)), can_duplicate: false }));
796
+ dedupedCli = dedupeCliSidebarSessions(cliRows, represented, { showCli: params.showCliSessions, showCron: params.showCronSessions, showWebhook: params.showWebhookSessions, showKanban: params.showKanbanSessions, sourceFilter: params.sourceFilter ?? null, requestVisibilityOverrides: params.requestVisibilityOverrides });
797
+ const owners = params.stateDbSources ? params.stateDbSources(dedupedCli.map((r) => str(r.session_id))) : new Map();
798
+ // A sidecar-less foreign row whose owner refuses claiming is read-only, as its detail and mutations are; an
799
+ // unreadable owner read (null) locks every row, as it locks sidecars.
800
+ dedupedCli = withOwnerLocks(dedupedCli.map((r) => ({ ...r, read_only: !owners || !isClaimableCliSource(r, owners.get(str(r.session_id)) || str(r.source)), can_duplicate: false })), () => owners);
792
801
  }
793
802
  else {
794
803
  webuiSessions = webuiSessions.filter((r) => !isCliSessionForSettings(r));
@@ -807,8 +816,12 @@ export function buildSessionListPayload(store, params) {
807
816
  otherProfileCount = params.isolatedProfileMode ? 0 : merged.length - scoped.length;
808
817
  }
809
818
  const identity = params.gatewayIdentity ?? new Map();
810
- const isPreCompressionSnapshotId = (sid) => { if (!/^[a-z0-9_]+$/.test(sid))
811
- return false; return Boolean(store.loadMetadataOnly(sid)?.pre_compression_snapshot); };
819
+ const snapshots = new Set();
820
+ for (const parent of new Set(scoped.map((row) => str(row.parent_session_id)))) {
821
+ if (/^[a-z0-9_]+$/.test(parent) && (await store.loadMetadataOnly(parent))?.pre_compression_snapshot)
822
+ snapshots.add(parent);
823
+ }
824
+ const isPreCompressionSnapshotId = (sid) => snapshots.has(sid);
812
825
  const dedupeOpts = { showPrevious: params.showPreviousMessagingSessions, identity, isPreCompressionSnapshotId };
813
826
  let archivedScoped = keepLatestMessagingSessionPerSource([...scoped], dedupeOpts);
814
827
  let visibleScoped = keepLatestMessagingSessionPerSource(scoped.filter((r) => !r.archived), dedupeOpts);
@@ -853,6 +866,7 @@ export function buildSessionListPayload(store, params) {
853
866
  scheduled_sessions_truncated: params.showCronSessions && truncated.has('cron'),
854
867
  webhook_session_count: visibleFiltered.filter((r) => sourceKind(r) === 'webhook').length,
855
868
  webhook_sessions_truncated: params.showWebhookSessions && truncated.has('webhook'),
869
+ agent_storage: params.agentStorage ?? AGENT_STORAGE_OK,
856
870
  include_archived: params.includeArchived,
857
871
  archived_limit: params.archivedLimit,
858
872
  archived_offset: params.archivedOffset,
@@ -952,6 +966,7 @@ export function sessionListResponse(payload, overlay, redactEnabled, now, worksp
952
966
  scheduled_sessions_truncated: payload.scheduled_sessions_truncated,
953
967
  webhook_session_count: payload.webhook_session_count,
954
968
  webhook_sessions_truncated: payload.webhook_sessions_truncated,
969
+ agent_storage: payload.agent_storage,
955
970
  };
956
971
  if (payload.archived_limit !== null) {
957
972
  body.archived_limit = Math.trunc(payload.archived_limit) || 0;
@@ -962,20 +977,7 @@ export function sessionListResponse(payload, overlay, redactEnabled, now, worksp
962
977
  return { body, etag };
963
978
  }
964
979
  // ── search ────────────────────────────────────────────────────────────────
965
- export function sessionSearchMessageText(message) {
966
- const content = message && typeof message === 'object' ? message.content : '';
967
- if (Array.isArray(content))
968
- return content.filter((p) => Boolean(p) && typeof p === 'object' && p.type === 'text').map((p) => str(p.text)).join(' ');
969
- return str(content);
970
- }
971
- /** TAL-453: a query's distinct whitespace-separated terms, lowercased; a row matches when one field holds them all. */
972
- export function sessionSearchTerms(query) {
973
- return [...new Set(query.toLowerCase().split(/\s+/).filter(Boolean))];
974
- }
975
- export function sessionSearchMatches(text, terms) {
976
- const lower = text.toLowerCase();
977
- return terms.length > 0 && terms.every((term) => lower.includes(term));
978
- }
980
+ export { sessionSearchMessageText, sessionSearchTerms, sessionSearchMatches } from './storage/search-text.js';
979
981
  /** An excerpt of `text` centred on the earliest occurrence of any of `terms`. */
980
982
  export function sessionSearchPreview(text, terms, maxLen = 124) {
981
983
  const normalized = text.replace(/\s+/g, ' ').trim();