@maudecode/talaria-web 1.17.2 → 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 (623) hide show
  1. package/_release.json +8 -8
  2. package/dist/api/auth-raw.d.ts +1 -1
  3. package/dist/api/auth-raw.js +20 -20
  4. package/dist/api/auth-raw.js.map +1 -1
  5. package/dist/api/automation-raw.d.ts +7 -1
  6. package/dist/api/automation-raw.js +74 -27
  7. package/dist/api/automation-raw.js.map +1 -1
  8. package/dist/api/automation-router.d.ts +128 -23
  9. package/dist/api/automation-router.js +29 -13
  10. package/dist/api/automation-router.js.map +1 -1
  11. package/dist/api/chat-router.d.ts +1845 -40
  12. package/dist/api/chat-router.js +196 -114
  13. package/dist/api/chat-router.js.map +1 -1
  14. package/dist/api/git-router.d.ts +37 -3
  15. package/dist/api/git-router.js +47 -48
  16. package/dist/api/git-router.js.map +1 -1
  17. package/dist/api/raw-routes.d.ts +9 -1
  18. package/dist/api/raw-routes.js +286 -73
  19. package/dist/api/raw-routes.js.map +1 -1
  20. package/dist/api/router.d.ts +16 -6
  21. package/dist/api/router.js +28 -26
  22. package/dist/api/router.js.map +1 -1
  23. package/dist/api/session-visibility.d.ts +4 -4
  24. package/dist/api/session-visibility.js +26 -16
  25. package/dist/api/session-visibility.js.map +1 -1
  26. package/dist/api/sessions-router.d.ts +3312 -131
  27. package/dist/api/sessions-router.js +287 -157
  28. package/dist/api/sessions-router.js.map +1 -1
  29. package/dist/api/settings-router.d.ts +457 -8
  30. package/dist/api/settings-router.js +54 -33
  31. package/dist/api/settings-router.js.map +1 -1
  32. package/dist/api/sse-routes.d.ts +7 -2
  33. package/dist/api/sse-routes.js +109 -62
  34. package/dist/api/sse-routes.js.map +1 -1
  35. package/dist/api/tools-raw.d.ts +5 -0
  36. package/dist/api/tools-raw.js +63 -55
  37. package/dist/api/tools-raw.js.map +1 -1
  38. package/dist/api/tools-router.d.ts +998 -85
  39. package/dist/api/tools-router.js +447 -61
  40. package/dist/api/tools-router.js.map +1 -1
  41. package/dist/api/transcribe-stream.d.ts +16 -0
  42. package/dist/api/transcribe-stream.js +172 -0
  43. package/dist/api/transcribe-stream.js.map +1 -0
  44. package/dist/app.d.ts +4 -1
  45. package/dist/app.js +98 -59
  46. package/dist/app.js.map +1 -1
  47. package/dist/auth/gate.js +15 -11
  48. package/dist/auth/gate.js.map +1 -1
  49. package/dist/auth/oidc.d.ts +5 -2
  50. package/dist/auth/oidc.js +8 -7
  51. package/dist/auth/oidc.js.map +1 -1
  52. package/dist/auth/passkeys.d.ts +15 -14
  53. package/dist/auth/passkeys.js +89 -91
  54. package/dist/auth/passkeys.js.map +1 -1
  55. package/dist/auth/store.d.ts +17 -7
  56. package/dist/auth/store.js +93 -52
  57. package/dist/auth/store.js.map +1 -1
  58. package/dist/bin/talaria-web.js +12 -81
  59. package/dist/bin/talaria-web.js.map +1 -1
  60. package/dist/cli/ctl.js +2 -1
  61. package/dist/cli/ctl.js.map +1 -1
  62. package/dist/cli/dotenv.d.ts +5 -0
  63. package/dist/cli/dotenv.js +15 -2
  64. package/dist/cli/dotenv.js.map +1 -1
  65. package/dist/cli/launcher.js +5 -5
  66. package/dist/cli/launcher.js.map +1 -1
  67. package/dist/cli/main.d.ts +1 -0
  68. package/dist/cli/main.js +85 -0
  69. package/dist/cli/main.js.map +1 -0
  70. package/dist/cli/supervise.d.ts +2 -0
  71. package/dist/cli/supervise.js +67 -4
  72. package/dist/cli/supervise.js.map +1 -1
  73. package/dist/config/agent-config.d.ts +34 -11
  74. package/dist/config/agent-config.js +116 -60
  75. package/dist/config/agent-config.js.map +1 -1
  76. package/dist/config.d.ts +4 -0
  77. package/dist/config.js +19 -6
  78. package/dist/config.js.map +1 -1
  79. package/dist/fs/atomic.d.ts +1 -0
  80. package/dist/fs/atomic.js +4 -1
  81. package/dist/fs/atomic.js.map +1 -1
  82. package/dist/fs/stat.d.ts +1 -0
  83. package/dist/fs/stat.js +11 -0
  84. package/dist/fs/stat.js.map +1 -0
  85. package/dist/http/context.d.ts +31 -12
  86. package/dist/http/context.js +60 -24
  87. package/dist/http/context.js.map +1 -1
  88. package/dist/http/csp.d.ts +2 -1
  89. package/dist/http/csp.js +3 -2
  90. package/dist/http/csp.js.map +1 -1
  91. package/dist/onboarding.d.ts +2 -2
  92. package/dist/onboarding.js +10 -8
  93. package/dist/onboarding.js.map +1 -1
  94. package/dist/profiles/profiles.d.ts +20 -4
  95. package/dist/profiles/profiles.js +115 -30
  96. package/dist/profiles/profiles.js.map +1 -1
  97. package/dist/projects.d.ts +15 -6
  98. package/dist/projects.js +55 -47
  99. package/dist/projects.js.map +1 -1
  100. package/dist/providers/catalog.d.ts +84 -14
  101. package/dist/providers/catalog.js +474 -151
  102. package/dist/providers/catalog.js.map +1 -1
  103. package/dist/providers/env-file.d.ts +10 -3
  104. package/dist/providers/env-file.js +24 -75
  105. package/dist/providers/env-file.js.map +1 -1
  106. package/dist/providers/runtime-env.d.ts +4 -2
  107. package/dist/providers/runtime-env.js +9 -6
  108. package/dist/providers/runtime-env.js.map +1 -1
  109. package/dist/providers/tables.d.ts +3 -1
  110. package/dist/providers/tables.js +4 -2
  111. package/dist/providers/tables.js.map +1 -1
  112. package/dist/raster-image.d.ts +7 -0
  113. package/dist/raster-image.js +267 -0
  114. package/dist/raster-image.js.map +1 -0
  115. package/dist/redact.js +342 -46
  116. package/dist/redact.js.map +1 -1
  117. package/dist/release.d.ts +7 -0
  118. package/dist/release.js +14 -0
  119. package/dist/release.js.map +1 -1
  120. package/dist/runtime.d.ts +5 -1
  121. package/dist/runtime.js +305 -96
  122. package/dist/runtime.js.map +1 -1
  123. package/dist/server.js +15 -0
  124. package/dist/server.js.map +1 -1
  125. package/dist/sessions/anchor.d.ts +9 -3
  126. package/dist/sessions/anchor.js +28 -36
  127. package/dist/sessions/anchor.js.map +1 -1
  128. package/dist/sessions/background-events.d.ts +2 -0
  129. package/dist/sessions/background-events.js +10 -0
  130. package/dist/sessions/background-events.js.map +1 -0
  131. package/dist/sessions/background-tasks.d.ts +26 -27
  132. package/dist/sessions/background-tasks.js +89 -97
  133. package/dist/sessions/background-tasks.js.map +1 -1
  134. package/dist/sessions/background-updates.d.ts +15 -8
  135. package/dist/sessions/background-updates.js +101 -25
  136. package/dist/sessions/background-updates.js.map +1 -1
  137. package/dist/sessions/cli-sessions.d.ts +27 -6
  138. package/dist/sessions/cli-sessions.js +152 -42
  139. package/dist/sessions/cli-sessions.js.map +1 -1
  140. package/dist/sessions/completions.d.ts +77 -9
  141. package/dist/sessions/completions.js +482 -45
  142. package/dist/sessions/completions.js.map +1 -1
  143. package/dist/sessions/compress.d.ts +8 -0
  144. package/dist/sessions/compress.js +2 -2
  145. package/dist/sessions/compress.js.map +1 -1
  146. package/dist/sessions/drafts.d.ts +14 -10
  147. package/dist/sessions/drafts.js +38 -43
  148. package/dist/sessions/drafts.js.map +1 -1
  149. package/dist/sessions/export.d.ts +5 -0
  150. package/dist/sessions/export.js +30 -0
  151. package/dist/sessions/export.js.map +1 -1
  152. package/dist/sessions/gateway-sessions.d.ts +46 -0
  153. package/dist/sessions/gateway-sessions.js +378 -0
  154. package/dist/sessions/gateway-sessions.js.map +1 -0
  155. package/dist/sessions/gateway-watcher.d.ts +7 -3
  156. package/dist/sessions/gateway-watcher.js +31 -19
  157. package/dist/sessions/gateway-watcher.js.map +1 -1
  158. package/dist/sessions/goals.d.ts +31 -0
  159. package/dist/sessions/goals.js +75 -0
  160. package/dist/sessions/goals.js.map +1 -0
  161. package/dist/sessions/handoff.d.ts +32 -0
  162. package/dist/sessions/handoff.js +114 -0
  163. package/dist/sessions/handoff.js.map +1 -0
  164. package/dist/sessions/journal.d.ts +5 -79
  165. package/dist/sessions/journal.js +15 -606
  166. package/dist/sessions/journal.js.map +1 -1
  167. package/dist/sessions/list.d.ts +31 -16
  168. package/dist/sessions/list.js +139 -129
  169. package/dist/sessions/list.js.map +1 -1
  170. package/dist/sessions/merge.d.ts +69 -13
  171. package/dist/sessions/merge.js +265 -64
  172. package/dist/sessions/merge.js.map +1 -1
  173. package/dist/sessions/notices.d.ts +22 -0
  174. package/dist/sessions/notices.js +72 -0
  175. package/dist/sessions/notices.js.map +1 -0
  176. package/dist/sessions/pending.d.ts +10 -4
  177. package/dist/sessions/pending.js +83 -7
  178. package/dist/sessions/pending.js.map +1 -1
  179. package/dist/sessions/prefix-index.d.ts +82 -0
  180. package/dist/sessions/prefix-index.js +232 -0
  181. package/dist/sessions/prefix-index.js.map +1 -0
  182. package/dist/sessions/recovery.d.ts +19 -0
  183. package/dist/sessions/recovery.js +322 -0
  184. package/dist/sessions/recovery.js.map +1 -0
  185. package/dist/sessions/relay.d.ts +38 -19
  186. package/dist/sessions/relay.js +302 -79
  187. package/dist/sessions/relay.js.map +1 -1
  188. package/dist/sessions/service.d.ts +260 -55
  189. package/dist/sessions/service.js +1448 -462
  190. package/dist/sessions/service.js.map +1 -1
  191. package/dist/sessions/session.d.ts +24 -2
  192. package/dist/sessions/session.js +69 -7
  193. package/dist/sessions/session.js.map +1 -1
  194. package/dist/sessions/shares.d.ts +7 -6
  195. package/dist/sessions/shares.js +22 -45
  196. package/dist/sessions/shares.js.map +1 -1
  197. package/dist/sessions/source-kind.js +1 -0
  198. package/dist/sessions/source-kind.js.map +1 -1
  199. package/dist/sessions/state-db-identity.d.ts +18 -0
  200. package/dist/sessions/state-db-identity.js +67 -0
  201. package/dist/sessions/state-db-identity.js.map +1 -0
  202. package/dist/sessions/state-db-worker.d.ts +1 -0
  203. package/dist/sessions/state-db-worker.js +35 -0
  204. package/dist/sessions/state-db-worker.js.map +1 -0
  205. package/dist/sessions/state-db.d.ts +113 -7
  206. package/dist/sessions/state-db.js +861 -44
  207. package/dist/sessions/state-db.js.map +1 -1
  208. package/dist/sessions/storage/backend.d.ts +162 -0
  209. package/dist/sessions/storage/backend.js +19 -0
  210. package/dist/sessions/storage/backend.js.map +1 -0
  211. package/dist/sessions/storage/conformance.d.ts +20 -0
  212. package/dist/sessions/storage/conformance.js +237 -0
  213. package/dist/sessions/storage/conformance.js.map +1 -0
  214. package/dist/sessions/storage/document.d.ts +16 -0
  215. package/dist/sessions/storage/document.js +44 -0
  216. package/dist/sessions/storage/document.js.map +1 -0
  217. package/dist/sessions/storage/json-documents.d.ts +23 -0
  218. package/dist/sessions/storage/json-documents.js +233 -0
  219. package/dist/sessions/storage/json-documents.js.map +1 -0
  220. package/dist/sessions/storage/json-files.d.ts +12 -0
  221. package/dist/sessions/storage/json-files.js +124 -0
  222. package/dist/sessions/storage/json-files.js.map +1 -0
  223. package/dist/sessions/storage/json-installation.d.ts +3 -0
  224. package/dist/sessions/storage/json-installation.js +31 -0
  225. package/dist/sessions/storage/json-installation.js.map +1 -0
  226. package/dist/sessions/storage/json-journal.d.ts +114 -0
  227. package/dist/sessions/storage/json-journal.js +686 -0
  228. package/dist/sessions/storage/json-journal.js.map +1 -0
  229. package/dist/sessions/storage/json-recovery.d.ts +4 -0
  230. package/dist/sessions/storage/json-recovery.js +195 -0
  231. package/dist/sessions/storage/json-recovery.js.map +1 -0
  232. package/dist/sessions/storage/json.d.ts +68 -0
  233. package/dist/sessions/storage/json.js +258 -0
  234. package/dist/sessions/storage/json.js.map +1 -0
  235. package/dist/sessions/storage/row.d.ts +6 -0
  236. package/dist/sessions/storage/row.js +49 -0
  237. package/dist/sessions/storage/row.js.map +1 -0
  238. package/dist/sessions/storage/search-text.d.ts +4 -0
  239. package/dist/sessions/storage/search-text.js +16 -0
  240. package/dist/sessions/storage/search-text.js.map +1 -0
  241. package/dist/sessions/store.d.ts +65 -68
  242. package/dist/sessions/store.js +305 -602
  243. package/dist/sessions/store.js.map +1 -1
  244. package/dist/sessions/streams.d.ts +4 -0
  245. package/dist/sessions/streams.js +9 -1
  246. package/dist/sessions/streams.js.map +1 -1
  247. package/dist/sessions/titles.d.ts +2 -0
  248. package/dist/sessions/titles.js +5 -1
  249. package/dist/sessions/titles.js.map +1 -1
  250. package/dist/sessions/todo.d.ts +5 -0
  251. package/dist/sessions/todo.js +28 -21
  252. package/dist/sessions/todo.js.map +1 -1
  253. package/dist/sessions/tool-display.d.ts +5 -4
  254. package/dist/sessions/tool-display.js +30 -50
  255. package/dist/sessions/tool-display.js.map +1 -1
  256. package/dist/sessions/turn-context.d.ts +11 -2
  257. package/dist/sessions/turn-context.js +18 -11
  258. package/dist/sessions/turn-context.js.map +1 -1
  259. package/dist/sessions/turn.d.ts +122 -17
  260. package/dist/sessions/turn.js +939 -358
  261. package/dist/sessions/turn.js.map +1 -1
  262. package/dist/sessions/wakeup-pause.d.ts +54 -0
  263. package/dist/sessions/wakeup-pause.js +163 -0
  264. package/dist/sessions/wakeup-pause.js.map +1 -0
  265. package/dist/sessions/window.js +13 -12
  266. package/dist/sessions/window.js.map +1 -1
  267. package/dist/settings.d.ts +19 -7
  268. package/dist/settings.js +178 -184
  269. package/dist/settings.js.map +1 -1
  270. package/dist/sidecar/client.d.ts +17 -3
  271. package/dist/sidecar/client.js +78 -8
  272. package/dist/sidecar/client.js.map +1 -1
  273. package/dist/sidecar/discover.d.ts +2 -1
  274. package/dist/sidecar/discover.js +93 -10
  275. package/dist/sidecar/discover.js.map +1 -1
  276. package/dist/sidecar/env.d.ts +4 -0
  277. package/dist/sidecar/env.js +3 -0
  278. package/dist/sidecar/env.js.map +1 -0
  279. package/dist/sidecar/fake.d.ts +2 -2
  280. package/dist/sidecar/fake.js +19 -2
  281. package/dist/sidecar/fake.js.map +1 -1
  282. package/dist/startup.d.ts +13 -5
  283. package/dist/startup.js +48 -0
  284. package/dist/startup.js.map +1 -1
  285. package/dist/test/env-file.d.ts +5 -0
  286. package/dist/test/env-file.js +88 -0
  287. package/dist/test/env-file.js.map +1 -0
  288. package/dist/test/harness.d.ts +1 -0
  289. package/dist/test/harness.js +1 -1
  290. package/dist/test/harness.js.map +1 -1
  291. package/dist/test/passkeys.d.ts +22 -0
  292. package/dist/test/passkeys.js +62 -0
  293. package/dist/test/passkeys.js.map +1 -0
  294. package/dist/test/storage.d.ts +15 -0
  295. package/dist/test/storage.js +26 -0
  296. package/dist/test/storage.js.map +1 -0
  297. package/dist/test/ts-worker-hooks.d.ts +1 -0
  298. package/dist/test/ts-worker-hooks.js +24 -0
  299. package/dist/test/ts-worker-hooks.js.map +1 -0
  300. package/dist/text/diff.d.ts +9 -14
  301. package/dist/text/diff.js +74 -108
  302. package/dist/text/diff.js.map +1 -1
  303. package/dist/tools/commands.d.ts +6 -1
  304. package/dist/tools/commands.js +8 -2
  305. package/dist/tools/commands.js.map +1 -1
  306. package/dist/tools/connectors.d.ts +33 -0
  307. package/dist/tools/connectors.js +121 -0
  308. package/dist/tools/connectors.js.map +1 -0
  309. package/dist/tools/crons.d.ts +38 -1
  310. package/dist/tools/crons.js +122 -18
  311. package/dist/tools/crons.js.map +1 -1
  312. package/dist/tools/dashboard-plugins.d.ts +53 -0
  313. package/dist/tools/dashboard-plugins.js +188 -0
  314. package/dist/tools/dashboard-plugins.js.map +1 -0
  315. package/dist/tools/extensions.d.ts +18 -5
  316. package/dist/tools/extensions.js +344 -266
  317. package/dist/tools/extensions.js.map +1 -1
  318. package/dist/tools/gateway-restart.d.ts +62 -0
  319. package/dist/tools/gateway-restart.js +142 -0
  320. package/dist/tools/gateway-restart.js.map +1 -0
  321. package/dist/tools/health.d.ts +44 -0
  322. package/dist/tools/health.js +201 -46
  323. package/dist/tools/health.js.map +1 -1
  324. package/dist/tools/hygiene.d.ts +4 -3
  325. package/dist/tools/hygiene.js +23 -9
  326. package/dist/tools/hygiene.js.map +1 -1
  327. package/dist/tools/kanban.d.ts +4 -2
  328. package/dist/tools/kanban.js +28 -19
  329. package/dist/tools/kanban.js.map +1 -1
  330. package/dist/tools/mcp.d.ts +13 -0
  331. package/dist/tools/mcp.js +88 -0
  332. package/dist/tools/mcp.js.map +1 -1
  333. package/dist/tools/memory-masks.d.ts +5 -0
  334. package/dist/tools/memory-masks.js +256 -0
  335. package/dist/tools/memory-masks.js.map +1 -0
  336. package/dist/tools/memory.d.ts +29 -3
  337. package/dist/tools/memory.js +69 -27
  338. package/dist/tools/memory.js.map +1 -1
  339. package/dist/tools/plugin-settings.d.ts +15 -0
  340. package/dist/tools/plugin-settings.js +90 -0
  341. package/dist/tools/plugin-settings.js.map +1 -0
  342. package/dist/tools/project-os.d.ts +11 -0
  343. package/dist/tools/project-os.js +267 -0
  344. package/dist/tools/project-os.js.map +1 -0
  345. package/dist/tools/skills.d.ts +14 -5
  346. package/dist/tools/skills.js +49 -16
  347. package/dist/tools/skills.js.map +1 -1
  348. package/dist/tools/update-notifications.d.ts +34 -15
  349. package/dist/tools/update-notifications.js +141 -57
  350. package/dist/tools/update-notifications.js.map +1 -1
  351. package/dist/tools/update-rollback.d.ts +11 -0
  352. package/dist/tools/update-rollback.js +28 -0
  353. package/dist/tools/update-rollback.js.map +1 -0
  354. package/dist/tools/updates.d.ts +110 -32
  355. package/dist/tools/updates.js +1112 -294
  356. package/dist/tools/updates.js.map +1 -1
  357. package/dist/tools/wiki.d.ts +68 -0
  358. package/dist/tools/wiki.js +413 -0
  359. package/dist/tools/wiki.js.map +1 -0
  360. package/dist/util.d.ts +2 -0
  361. package/dist/util.js +5 -0
  362. package/dist/util.js.map +1 -1
  363. package/dist/workspace/escape.d.ts +61 -0
  364. package/dist/workspace/escape.js +149 -0
  365. package/dist/workspace/escape.js.map +1 -0
  366. package/dist/workspace/extract.d.ts +22 -0
  367. package/dist/workspace/extract.js +308 -0
  368. package/dist/workspace/extract.js.map +1 -0
  369. package/dist/workspace/fs.d.ts +12 -0
  370. package/dist/workspace/fs.js +92 -23
  371. package/dist/workspace/fs.js.map +1 -1
  372. package/dist/workspace/git.d.ts +34 -1
  373. package/dist/workspace/git.js +328 -35
  374. package/dist/workspace/git.js.map +1 -1
  375. package/dist/workspace/media.d.ts +16 -13
  376. package/dist/workspace/media.js +43 -61
  377. package/dist/workspace/media.js.map +1 -1
  378. package/dist/workspace/rollback.d.ts +36 -22
  379. package/dist/workspace/rollback.js +178 -272
  380. package/dist/workspace/rollback.js.map +1 -1
  381. package/dist/workspace/unzip.js +4 -1
  382. package/dist/workspace/unzip.js.map +1 -1
  383. package/dist/workspace/upload.d.ts +7 -4
  384. package/dist/workspace/upload.js +5 -2
  385. package/dist/workspace/upload.js.map +1 -1
  386. package/dist/workspace/workspaces.d.ts +15 -19
  387. package/dist/workspace/workspaces.js +55 -127
  388. package/dist/workspace/workspaces.js.map +1 -1
  389. package/dist/workspace/worktrees.d.ts +2 -1
  390. package/dist/workspace/worktrees.js +179 -42
  391. package/dist/workspace/worktrees.js.map +1 -1
  392. package/package.json +7 -3
  393. package/sidecar/agent_dependency.json +4 -4
  394. package/sidecar/agent_support.json +26 -0
  395. package/sidecar/scripts/record-fixtures.py +12 -3
  396. package/sidecar/scripts/replay_sidecar.py +32 -0
  397. package/sidecar/scripts/suite_runner.py +302 -0
  398. package/sidecar/scripts/test.sh +12 -4
  399. package/sidecar/talaria_sidecar/__init__.py +6 -1
  400. package/sidecar/talaria_sidecar/__main__.py +4 -2
  401. package/sidecar/talaria_sidecar/agent_mutation.py +975 -0
  402. package/sidecar/talaria_sidecar/agent_services.py +1053 -0
  403. package/sidecar/talaria_sidecar/dependency_sync.py +85 -0
  404. package/sidecar/talaria_sidecar/home.py +56 -3
  405. package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
  406. package/sidecar/talaria_sidecar/methods/aux.py +166 -24
  407. package/sidecar/talaria_sidecar/methods/chat.py +852 -135
  408. package/sidecar/talaria_sidecar/methods/checkpoints.py +89 -0
  409. package/sidecar/talaria_sidecar/methods/commands.py +294 -4
  410. package/sidecar/talaria_sidecar/methods/config.py +123 -4
  411. package/sidecar/talaria_sidecar/methods/connectors.py +343 -0
  412. package/sidecar/talaria_sidecar/methods/cron.py +395 -36
  413. package/sidecar/talaria_sidecar/methods/cron_execution.py +284 -0
  414. package/sidecar/talaria_sidecar/methods/gateway.py +212 -55
  415. package/sidecar/talaria_sidecar/methods/gateway_sessions.py +234 -0
  416. package/sidecar/talaria_sidecar/methods/goals.py +81 -41
  417. package/sidecar/talaria_sidecar/methods/kanban.py +108 -34
  418. package/sidecar/talaria_sidecar/methods/mcp.py +1 -1
  419. package/sidecar/talaria_sidecar/methods/memory.py +84 -0
  420. package/sidecar/talaria_sidecar/methods/oauth.py +5 -2
  421. package/sidecar/talaria_sidecar/methods/process.py +218 -15
  422. package/sidecar/talaria_sidecar/methods/profiles.py +121 -13
  423. package/sidecar/talaria_sidecar/methods/providers.py +217 -28
  424. package/sidecar/talaria_sidecar/methods/runtime.py +69 -1
  425. package/sidecar/talaria_sidecar/methods/skills.py +67 -4
  426. package/sidecar/talaria_sidecar/methods/state_db.py +316 -75
  427. package/sidecar/talaria_sidecar/methods/stt.py +159 -78
  428. package/sidecar/talaria_sidecar/methods/text.py +14 -1
  429. package/sidecar/talaria_sidecar/methods/toolsets.py +49 -0
  430. package/sidecar/talaria_sidecar/methods/usage.py +113 -14
  431. package/sidecar/talaria_sidecar/methods/worktree.py +26 -19
  432. package/sidecar/talaria_sidecar/methods/write_approval.py +181 -0
  433. package/sidecar/talaria_sidecar/rpc.py +45 -4
  434. package/sidecar/talaria_sidecar/runtime.py +98 -13
  435. package/sidecar/talaria_sidecar/speed.py +35 -0
  436. package/static/dist/FILES.txt +126 -126
  437. package/static/dist/assets/AppShell-cey33v9s.js +8 -0
  438. package/static/dist/assets/ChatPage-i8wnugr7.js +18 -0
  439. package/static/dist/assets/ConnectTargets-hg19553x.js +1 -0
  440. package/static/dist/assets/ExtensionRoute-cly4apm5.js +1 -0
  441. package/static/dist/assets/Field-j8uqoigz.js +9 -0
  442. package/static/dist/assets/HubRoute-e4bgz41j.js +2 -0
  443. package/static/dist/assets/Markdown-lahuichm.js +598 -0
  444. package/static/dist/assets/RightPanel-lbo4i0fn.js +1 -0
  445. package/static/dist/assets/Select-gqatm2e0.js +1 -0
  446. package/static/dist/assets/SessionListPanel-mfqayfjh.js +1 -0
  447. package/static/dist/assets/SettingsLayout-b8980u7k.js +1 -0
  448. package/static/dist/assets/States-e7dkgtxf.js +1 -0
  449. package/static/dist/assets/Toaster-bfqqy786.js +1 -0
  450. package/static/dist/assets/_app-n1n6pfx1.js +1 -0
  451. package/static/dist/assets/{_app.ext._extensionId-opyh9y0v.js → _app.ext._extensionId-buxjxav3.js} +1 -1
  452. package/static/dist/assets/_app.index-jt8zwiu2.js +1 -0
  453. package/static/dist/assets/_app.insights-cv76ml71.js +1 -0
  454. package/static/dist/assets/_app.kanban-h6ts53j7.js +1 -0
  455. package/static/dist/assets/_app.logs-dm873z90.js +1 -0
  456. package/static/dist/assets/_app.memory-glk5y6m8.js +1 -0
  457. package/static/dist/assets/_app.profiles-ka6zpstq.js +1 -0
  458. package/static/dist/assets/{_app.session._sessionId-bfd4h3id.js → _app.session._sessionId-g2vzghvc.js} +1 -1
  459. package/static/dist/assets/_app.settings-hgjdhzcd.js +1 -0
  460. package/static/dist/assets/_app.settings._section-jf2kmhae.js +3 -0
  461. package/static/dist/assets/_app.skills-cii852yq.js +1 -0
  462. package/static/dist/assets/_app.tasks-fp9q7atm.js +1 -0
  463. package/static/dist/assets/_app.todos-dw94qzue.js +1 -0
  464. package/static/dist/assets/_app.workspaces-inyygzze.js +1 -0
  465. package/static/dist/assets/{abnfDiagram-VCTEODGH-b2x1lqot.js → abnfDiagram-VCTEODGH-gjayq3ra.js} +1 -1
  466. package/static/dist/assets/architecture-7GRP2DOG-lp56972r.js +1 -0
  467. package/static/dist/assets/{architectureDiagram-5GKGNRK7-h38o5l7b.js → architectureDiagram-5GKGNRK7-nwb3xovn.js} +1 -1
  468. package/static/dist/assets/archive-b1j004vn.js +1 -0
  469. package/static/dist/assets/back-g74gkozu.js +1 -0
  470. package/static/dist/assets/{blockDiagram-I7D4REHJ-bqquxv2u.js → blockDiagram-I7D4REHJ-joedghi3.js} +1 -1
  471. package/static/dist/assets/{c4Diagram-7LVT6UL2-f3fb8w6z.js → c4Diagram-7LVT6UL2-hyrjrohe.js} +1 -1
  472. package/static/dist/assets/channel-es95o4y8.js +1 -0
  473. package/static/dist/assets/{chunk-4HAMMTFA-bzfyyzp3.js → chunk-4HAMMTFA-koouqbut.js} +1 -1
  474. package/static/dist/assets/{chunk-75Z2AOVW-ly99rfx5.js → chunk-75Z2AOVW-bl4bhdnt.js} +1 -1
  475. package/static/dist/assets/{chunk-DU6HZSFF-bg6ecfqf.js → chunk-DU6HZSFF-gpedttsp.js} +3 -3
  476. package/static/dist/assets/{chunk-F27PBJKO-e8k7mmqw.js → chunk-F27PBJKO-d8xxi0zi.js} +1 -1
  477. package/static/dist/assets/{chunk-GMAD6QVW-cmalnoaj.js → chunk-GMAD6QVW-jro0hl73.js} +1 -1
  478. package/static/dist/assets/{chunk-GVQU2GXP-gmif5o01.js → chunk-GVQU2GXP-djn6gbyu.js} +1 -1
  479. package/static/dist/assets/{chunk-IMKFNOWR-f1nwwh6u.js → chunk-IMKFNOWR-vw4p5p7o.js} +1 -1
  480. package/static/dist/assets/{chunk-L3NEJ4N5-oktfh5v7.js → chunk-L3NEJ4N5-n1hj77q8.js} +1 -1
  481. package/static/dist/assets/{chunk-OSK3NFVY-b1sdx96z.js → chunk-OSK3NFVY-oy0gwn2n.js} +1 -1
  482. package/static/dist/assets/{chunk-P2QGCYS3-fhu4nzxt.js → chunk-P2QGCYS3-onf1hz6c.js} +1 -1
  483. package/static/dist/assets/{chunk-POPQ4Y6H-em31rnef.js → chunk-POPQ4Y6H-m8sqn7cs.js} +1 -1
  484. package/static/dist/assets/{chunk-PWAF6VOD-bxhhyftw.js → chunk-PWAF6VOD-ek4smc8x.js} +1 -1
  485. package/static/dist/assets/{chunk-SHT3W25Y-fmrvwcav.js → chunk-SHT3W25Y-g9gfvefo.js} +3 -3
  486. package/static/dist/assets/{chunk-SVP7TREG-lymukl2j.js → chunk-SVP7TREG-f9nfv2cu.js} +1 -1
  487. package/static/dist/assets/{chunk-TICWLB2K-lmza6k23.js → chunk-TICWLB2K-bnk3m1mq.js} +1 -1
  488. package/static/dist/assets/classDiagram-ZZMXUADV-kmihoqxh.js +1 -0
  489. package/static/dist/assets/classDiagram-v2-VYDZK3BY-kmihoqxh.js +1 -0
  490. package/static/dist/assets/copied-bli9tbcx.js +1 -0
  491. package/static/dist/assets/{copy-fw5b1pc6.js → copy-jamtd1pf.js} +1 -1
  492. package/static/dist/assets/{cynefin-OW5HDTMX-czlhbyhs.js → cynefin-OW5HDTMX-f8xfdd3f.js} +1 -1
  493. package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-gq7mvswb.js → cynefinDiagram-5FMLGOSQ-n9lb99h9.js} +1 -1
  494. package/static/dist/assets/{dagre-GXQ25YYZ-cqdbf7dr.js → dagre-GXQ25YYZ-dgailddi.js} +4 -4
  495. package/static/dist/assets/{diagram-S7CK7UJ4-o6arxa58.js → diagram-S7CK7UJ4-m6aeoe7c.js} +1 -1
  496. package/static/dist/assets/{diagram-UQ7AKVKN-nhnd68tz.js → diagram-UQ7AKVKN-jall3j0x.js} +1 -1
  497. package/static/dist/assets/{diagram-VSXAHHWV-dk2sclzn.js → diagram-VSXAHHWV-hbawi7hn.js} +1 -1
  498. package/static/dist/assets/{diagram-VX7I27RA-n3k5nyx3.js → diagram-VX7I27RA-hendl2tt.js} +1 -1
  499. package/static/dist/assets/{diagram-Z3DM3KII-m6q9cwdh.js → diagram-Z3DM3KII-igwc35p3.js} +1 -1
  500. package/static/dist/assets/{ebnfDiagram-PWID7BFC-lsa5641p.js → ebnfDiagram-PWID7BFC-c64knz08.js} +1 -1
  501. package/static/dist/assets/{erDiagram-RLTQ6QDP-fo2ckbe6.js → erDiagram-RLTQ6QDP-brdu9lcm.js} +1 -1
  502. package/static/dist/assets/eventmodeling-NTZA5JFV-njk1j8wl.js +1 -0
  503. package/static/dist/assets/flowDiagram-HODETNUW-nma6f0ga.js +1 -0
  504. package/static/dist/assets/folder-plus-lvt9kudb.js +1 -0
  505. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-nzqz6x9g.js → ganttDiagram-EL5Y4UJY-ma6jxj5i.js} +1 -1
  506. package/static/dist/assets/{gitGraph-4MIJSDKK-gukvcxe6.js → gitGraph-4MIJSDKK-naa9w6xa.js} +1 -1
  507. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-lqhdp8f0.js → gitGraphDiagram-WWUBYQGX-hzltvsod.js} +1 -1
  508. package/static/dist/assets/{highlighted-body-KPVGNVTW-igw6cp39.js → highlighted-body-KPVGNVTW-ghoavj8d.js} +1 -1
  509. package/static/dist/assets/host-hzm8n85n.js +1 -0
  510. package/static/dist/assets/index-drdcaqeq.css +2 -0
  511. package/static/dist/assets/index-jzm844he.js +11 -0
  512. package/static/dist/assets/{info-A6RAGUB7-gvu7a93l.js → info-A6RAGUB7-mn2ut5ko.js} +1 -1
  513. package/static/dist/assets/{infoDiagram-27XIBGKW-m8t8g6w1.js → infoDiagram-27XIBGKW-h6kuqvsb.js} +1 -1
  514. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-l07vkbgj.js → ishikawaDiagram-5VMMS53U-e7bnwq7h.js} +1 -1
  515. package/static/dist/assets/{journeyDiagram-3NMN7TZE-hybkgj8l.js → journeyDiagram-3NMN7TZE-etd1bi6p.js} +1 -1
  516. package/static/dist/assets/{kanban-definition-UXKFOSKX-by13uvtn.js → kanban-definition-UXKFOSKX-emb1g9dz.js} +4 -4
  517. package/static/dist/assets/lazyRouteComponent-o816ytzl.js +1 -0
  518. package/static/dist/assets/{line-osxq6fq7.js → line-h0ojzsvs.js} +1 -1
  519. package/static/dist/assets/link-k01ryaf9.js +1 -0
  520. package/static/dist/assets/login-bsae49ew.js +1 -0
  521. package/static/dist/assets/mermaid-HWGCJPDP-ihl34s74.js +1 -0
  522. package/static/dist/assets/{mermaid-parser.core-i91oxmou.js → mermaid-parser.core-bnre27u8.js} +3 -3
  523. package/static/dist/assets/{mindmap-definition-YA3MSWOX-m82mx8ww.js → mindmap-definition-YA3MSWOX-o1vathns.js} +1 -1
  524. package/static/dist/assets/onboarding-c65tysya.js +1 -0
  525. package/static/dist/assets/onboarding_model_label-gpn28uix.js +1 -0
  526. package/static/dist/assets/{packet-AYTQ26CC-nbtgge2o.js → packet-AYTQ26CC-hatq7m2e.js} +1 -1
  527. package/static/dist/assets/pcmTap.worklet-74EKjWAZ.js +1 -0
  528. package/static/dist/assets/{pegDiagram-XKGWAZYB-f1zxzga1.js → pegDiagram-XKGWAZYB-gwisz8jv.js} +1 -1
  529. package/static/dist/assets/{pie-WAS4IAKB-of8vuhxs.js → pie-WAS4IAKB-fpftf0mk.js} +1 -1
  530. package/static/dist/assets/{pieDiagram-E7YTZNPT-o7y8ftio.js → pieDiagram-E7YTZNPT-khm1o9a6.js} +1 -1
  531. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-iqiwia1t.js → quadrantDiagram-AXDQQJYC-owqc4uqn.js} +1 -1
  532. package/static/dist/assets/{radar-RG4KPBEZ-delnsy2v.js → radar-RG4KPBEZ-cntfwjpq.js} +1 -1
  533. package/static/dist/assets/{railroad-74A4TZTK-nspnyq9u.js → railroad-74A4TZTK-a7t5eibp.js} +1 -1
  534. package/static/dist/assets/railroad-abnf-HS5TGJTU-ol8cdktf.js +1 -0
  535. package/static/dist/assets/railroad-ebnf-LZEXJU2U-i8vzd429.js +1 -0
  536. package/static/dist/assets/railroad-peg-WCYAUIDC-nw3ulewz.js +1 -0
  537. package/static/dist/assets/{railroadDiagram-O6MQD6OU-z41tqx5z.js → railroadDiagram-O6MQD6OU-etuh0qa0.js} +1 -1
  538. package/static/dist/assets/{refresh-cw-nt1dtsx4.js → refresh-cw-mqbkv2a3.js} +1 -1
  539. package/static/dist/assets/refresh-l29ljp76.js +1 -0
  540. package/static/dist/assets/{requirementDiagram-BXWQKSXE-bdvif194.js → requirementDiagram-BXWQKSXE-oq2ulk22.js} +1 -1
  541. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-h73e0rol.js → sankeyDiagram-P5KCCOFB-iqc02emv.js} +1 -1
  542. package/static/dist/assets/saved-ndd4t2xb.js +1 -0
  543. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-iv95mb1z.js → sequenceDiagram-WJ2MYXX4-i0v116q0.js} +2 -2
  544. package/static/dist/assets/settings_section_extensions_title-jhfo6o8z.js +1 -0
  545. package/static/dist/assets/share._token-c1ri0hy1.js +2 -0
  546. package/static/dist/assets/sliders-horizontal-j3jjt9tv.js +1 -0
  547. package/static/dist/assets/{stateDiagram-D77RDMKH-k417ixmf.js → stateDiagram-D77RDMKH-dnpt1ato.js} +1 -1
  548. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-bxjacpk6.js +1 -0
  549. package/static/dist/assets/{swimlanes-42K2YHIH-esola70w.js → swimlanes-42K2YHIH-loqbdazb.js} +1 -1
  550. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-id62p9hz.js +8 -0
  551. package/static/dist/assets/{timeline-definition-24CTP7MA-getrz2y8.js → timeline-definition-24CTP7MA-ol2hnvma.js} +1 -1
  552. package/static/dist/assets/toast-i3h34v6o.js +64 -0
  553. package/static/dist/assets/{treeView-Q6P3EWNA-hc7ap1q7.js → treeView-Q6P3EWNA-idrj6iox.js} +1 -1
  554. package/static/dist/assets/{treemap-WGGIJYW6-b7k1syy5.js → treemap-WGGIJYW6-lzr49vv5.js} +1 -1
  555. package/static/dist/assets/untitled-oaoya4qj.js +1 -0
  556. package/static/dist/assets/useForm-nfaxgmsk.js +1 -0
  557. package/static/dist/assets/{useParams-lhg566ew.js → useParams-gjc70qru.js} +1 -1
  558. package/static/dist/assets/{useSearch-lbrh6ejn.js → useSearch-e6ae539u.js} +1 -1
  559. package/static/dist/assets/{vennDiagram-4TSXK5OY-n6pcy5qb.js → vennDiagram-4TSXK5OY-bvwr9o2z.js} +1 -1
  560. package/static/dist/assets/{wardley-WFR3VGLG-lpa18vz1.js → wardley-WFR3VGLG-31ui8tma.js} +1 -1
  561. package/static/dist/assets/{wardleyDiagram-VM6X3IG4-kpclwwg7.js → wardleyDiagram-VM6X3IG4-k5wqtx4b.js} +1 -1
  562. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-paa2n8y0.js → xychartDiagram-S5SC5T6Z-aqbgvujg.js} +1 -1
  563. package/static/dist/index.html +1 -1
  564. package/static/dist/sw.js +1 -1
  565. package/static/dist/assets/AppShell-fb2td9zi.js +0 -1
  566. package/static/dist/assets/ChatPage-cj96kiy9.js +0 -25
  567. package/static/dist/assets/Dialog-kxcg7ard.js +0 -1
  568. package/static/dist/assets/ExtensionRoute-jf7h0754.js +0 -1
  569. package/static/dist/assets/HubRoute-gmanpd5y.js +0 -2
  570. package/static/dist/assets/Markdown-mdwlvj3w.js +0 -598
  571. package/static/dist/assets/RightPanel-ftvrjlcp.js +0 -1
  572. package/static/dist/assets/Select-bilaypej.js +0 -1
  573. package/static/dist/assets/SessionListPanel-og8n36qs.js +0 -1
  574. package/static/dist/assets/SettingsLayout-jonjefmj.js +0 -1
  575. package/static/dist/assets/States-nmejrwrm.js +0 -1
  576. package/static/dist/assets/Toaster-nnl8zkt9.js +0 -1
  577. package/static/dist/assets/_app-gdidzd94.js +0 -1
  578. package/static/dist/assets/_app.index-hbarzbjx.js +0 -1
  579. package/static/dist/assets/_app.insights-luywlarz.js +0 -1
  580. package/static/dist/assets/_app.kanban-kincnbr8.js +0 -1
  581. package/static/dist/assets/_app.logs-oi2gr3gs.js +0 -1
  582. package/static/dist/assets/_app.memory-b6jfivt6.js +0 -1
  583. package/static/dist/assets/_app.profiles-lpvixmqp.js +0 -1
  584. package/static/dist/assets/_app.settings-vowx3iq0.js +0 -1
  585. package/static/dist/assets/_app.settings._section-cnntg1tu.js +0 -3
  586. package/static/dist/assets/_app.skills-fb57lpau.js +0 -1
  587. package/static/dist/assets/_app.tasks-eszpx1q7.js +0 -2
  588. package/static/dist/assets/_app.todos-nr05ac6w.js +0 -1
  589. package/static/dist/assets/_app.workspaces-d2luomu6.js +0 -1
  590. package/static/dist/assets/architecture-7GRP2DOG-hd0o7bde.js +0 -1
  591. package/static/dist/assets/back-bemaer09.js +0 -1
  592. package/static/dist/assets/cancel-drd0g6d9.js +0 -1
  593. package/static/dist/assets/channel-cpdgf867.js +0 -1
  594. package/static/dist/assets/classDiagram-ZZMXUADV-ko09sguk.js +0 -1
  595. package/static/dist/assets/classDiagram-v2-VYDZK3BY-ko09sguk.js +0 -1
  596. package/static/dist/assets/copied-ima3pysb.js +0 -1
  597. package/static/dist/assets/endpoints-d33siokx.js +0 -64
  598. package/static/dist/assets/eventmodeling-NTZA5JFV-emctlo64.js +0 -1
  599. package/static/dist/assets/flowDiagram-HODETNUW-bfi3moqa.js +0 -1
  600. package/static/dist/assets/index-cxq58xb1.js +0 -11
  601. package/static/dist/assets/index-hgtx08n5.css +0 -2
  602. package/static/dist/assets/lazyRouteComponent-af0lvgjx.js +0 -1
  603. package/static/dist/assets/link-jyxicdhg.js +0 -1
  604. package/static/dist/assets/login-ec21t39x.js +0 -1
  605. package/static/dist/assets/mermaid-HWGCJPDP-gfl8z3ep.js +0 -1
  606. package/static/dist/assets/onboarding-btnltvyz.js +0 -1
  607. package/static/dist/assets/onboarding_model_label-dp7xffoh.js +0 -1
  608. package/static/dist/assets/railroad-abnf-HS5TGJTU-nst1qxyn.js +0 -1
  609. package/static/dist/assets/railroad-ebnf-LZEXJU2U-ci37x8qy.js +0 -1
  610. package/static/dist/assets/railroad-peg-WCYAUIDC-aimkk07z.js +0 -1
  611. package/static/dist/assets/refresh-b4uams1i.js +0 -1
  612. package/static/dist/assets/saved-kg52csy7.js +0 -1
  613. package/static/dist/assets/settings_section_extensions_title-ej0iapxe.js +0 -1
  614. package/static/dist/assets/share._token-f97e94r0.js +0 -2
  615. package/static/dist/assets/sliders-horizontal-fj18it47.js +0 -1
  616. package/static/dist/assets/sse-fwpqtzbg.js +0 -1
  617. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hwn4apct.js +0 -1
  618. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-d1h97oyg.js +0 -8
  619. package/static/dist/assets/todoStore-eginf9h4.js +0 -1
  620. package/static/dist/assets/tts-lxdxnmjd.js +0 -1
  621. package/static/dist/assets/untitled-ovpfthg4.js +0 -1
  622. package/static/dist/assets/useForm-bcblv1rx.js +0 -1
  623. package/static/dist/assets/useLocale-fi5jb8ma.js +0 -1
@@ -95,7 +95,8 @@ def sync_session_usage(home: Path, session_id: str, *, input_tokens=0, output_to
95
95
  _close(db)
96
96
 
97
97
 
98
- def sync_session_title(home: Path, session_id: str, title: str) -> bool:
98
+ def sync_session_title(home: Path, session_id: str, title: str, *, manual: bool = False) -> bool:
99
+ """A manual (user-requested) title lands with ``user`` provenance; an auto title is ``llm`` and never replaces a user name."""
99
100
  if not title:
100
101
  return False
101
102
  db = _session_db(home)
@@ -104,15 +105,38 @@ def sync_session_title(home: Path, session_id: str, title: str) -> bool:
104
105
  try:
105
106
  db.ensure_session(session_id=session_id, source="webui")
106
107
  source = getattr(db, "TITLE_SOURCE_LLM", "llm")
108
+
109
+ def write(value: str) -> None:
110
+ if manual:
111
+ db.set_session_title(session_id, value)
112
+ else:
113
+ db.set_auto_title(session_id, value, source=source)
114
+
107
115
  try:
108
- db.set_auto_title(session_id, title, source=source)
116
+ write(title)
109
117
  except ValueError:
110
118
  alt = db.get_next_title_in_lineage(title)
111
119
  if alt and alt != title:
112
- db.set_auto_title(session_id, alt, source=source)
120
+ write(alt)
121
+ return True
122
+ except Exception: # noqa: BLE001
123
+ log.debug("Failed to sync session title", exc_info=True)
124
+ return False
125
+ finally:
126
+ _close(db)
127
+
128
+
129
+ def append_message(home: Path, session_id: str, *, role: str, content: str, tool_name=None, timestamp=None) -> bool:
130
+ """TAL-258 (predecessor ``_persist_handoff_summary_to_state_db``): one row through ``SessionDB.append_message``,
131
+ which also bumps the session's ``message_count``. False without a state.db or when the write fails."""
132
+ db = _session_db(home)
133
+ if not db:
134
+ return False
135
+ try:
136
+ db.append_message(session_id, role, content=content, tool_name=tool_name or None, timestamp=timestamp)
113
137
  return True
114
138
  except Exception: # noqa: BLE001
115
- log.debug("Failed to sync auto title", exc_info=True)
139
+ log.warning("Failed to append a %s row to state.db for %s", role, session_id, exc_info=True)
116
140
  return False
117
141
  finally:
118
142
  _close(db)
@@ -157,12 +181,15 @@ def _is_safe_session_id(sid) -> bool:
157
181
  return isinstance(sid, str) and bool(_SAFE_SESSION_ID.match(sid))
158
182
 
159
183
 
160
- def _clean_artifacts(sessions_dir: Path, removed_id: str) -> bool:
184
+ def _clean_artifacts(sessions_dir: Path, removed_id: str, *, keep_legacy: bool) -> bool:
161
185
  if not _is_safe_session_id(removed_id):
162
186
  return False
163
187
  ok = True
164
- for suffix in (".json", ".jsonl"):
165
- artifact = sessions_dir / f"{removed_id}{suffix}"
188
+ # ``session_<id>.json`` is the legacy snapshot older Agents wrote; it can carry plaintext secrets. It is kept while a
189
+ # live session's id is ``session_<id>``, because then it is that session's own transcript.
190
+ names = [f"{removed_id}.json", f"{removed_id}.jsonl"] + ([] if keep_legacy else [f"session_{removed_id}.json"])
191
+ for name in names:
192
+ artifact = sessions_dir / name
166
193
  if artifact.exists():
167
194
  try:
168
195
  artifact.unlink(missing_ok=True)
@@ -195,13 +222,13 @@ def _process_manifests(conn, sessions_dir: Path, *, alive_query) -> bool:
195
222
  mp.unlink(missing_ok=True)
196
223
  continue
197
224
  try:
198
- alive = alive_query(conn, pending_ids)
225
+ alive = alive_query(conn, pending_ids + [f"session_{i}" for i in pending_ids])
199
226
  except Exception: # noqa: BLE001 - fail closed, retry later
200
227
  complete = False
201
228
  continue
202
229
  still_pending = []
203
230
  for removed_id in pending_ids:
204
- if removed_id in alive or not _clean_artifacts(sessions_dir, removed_id):
231
+ if removed_id in alive or not _clean_artifacts(sessions_dir, removed_id, keep_legacy=f"session_{removed_id}" in alive):
205
232
  still_pending.append(removed_id)
206
233
  if still_pending:
207
234
  tmp = mp.with_suffix(".tmp")
@@ -264,19 +291,169 @@ def _timestamp_value(value):
264
291
  return numeric if math.isfinite(numeric) else None
265
292
 
266
293
 
267
- def _delete_locked(sid: str, home: Path) -> bool:
294
+ def _is_continuation(parent: dict, child: dict) -> bool:
295
+ """The server's ``isContinuationSession``: ``child`` resumes ``parent`` after a compression or CLI close."""
296
+ lower = lambda v: str(v or "").strip().lower() # noqa: E731
297
+ if lower(child.get("session_source")) == "fork":
298
+ return False
299
+ if child.get("source") == "tool" or any(child.get(k) is not None for k in ("branched_from", "delegate_from", "reset_from")):
300
+ return False
301
+ if lower(parent.get("source")) and lower(child.get("source")) and lower(parent.get("source")) != lower(child.get("source")):
302
+ return False
303
+ if parent.get("end_reason") not in ("compression", "cli_close"):
304
+ return False
305
+ if parent.get("ended_at") is None:
306
+ return True
307
+ try:
308
+ started, ended = float(child.get("started_at") or 0), float(parent["ended_at"])
309
+ except (TypeError, ValueError):
310
+ return False
311
+ return math.isfinite(started) and math.isfinite(ended) and started + 1.0 >= ended
312
+
313
+
314
+ # The Agent's ``_CHAIN_CAP`` and the server's ``COMPRESSION_CHAIN_CAP``: the most hops a compression-chain walk takes.
315
+ _COMPRESSION_CHAIN_CAP = 1000
316
+
317
+
318
+ def _compression_lineage(records: list[dict], sid: str) -> list[str]:
319
+ """The server's ``stateDbCompressionLineage``: ``sid`` then each single continuation, up to ``_COMPRESSION_CHAIN_CAP``
320
+ hops, root first."""
321
+ by_id = {r["id"]: r for r in records}
322
+ children: dict[str, list[dict]] = {}
323
+ for r in records:
324
+ children.setdefault(r["parent_id"], []).append(r)
325
+ lineage, current = [sid], by_id.get(sid)
326
+ for _ in range(_COMPRESSION_CHAIN_CAP):
327
+ if current is None:
328
+ break
329
+ nxt = [r for r in children.get(current["id"], []) if _is_continuation(current, r)]
330
+ if len(nxt) != 1 or nxt[0]["id"] in lineage:
331
+ break
332
+ current = nxt[0]
333
+ lineage.append(current["id"])
334
+ return lineage
335
+
336
+
337
+ class _ActiveWriteGuard(Exception):
338
+ """Another Agent process holds a live turn lease or compression lock on a row the delete would remove."""
339
+
340
+
341
+ def _delete_locked(sid: str, home: Path, include_lineage: bool) -> dict:
268
342
  stale_complete = _process_stale_manifests(home)
269
343
  db_path = home / "state.db"
270
344
  if not db_path.exists():
271
- return False
345
+ return {"ok": False}
346
+ agent_db = _session_db(home)
347
+ if agent_db is None:
348
+ return {"ok": False}
349
+ try:
350
+ guarded = _write_guard_check(agent_db)
351
+ if guarded is None: # fail closed: without the Agent's guard, a live writer's rows cannot be told apart
352
+ log.warning("Agent has no session write-guard check; state.db rows are kept")
353
+ return {"ok": False}
354
+ try:
355
+ from hermes_state_mutation_retirement import delete_in_transaction
356
+ except ModuleNotFoundError as exc:
357
+ if exc.name != "hermes_state_mutation_retirement":
358
+ raise
359
+ result = _delete_rows(sid, include_lineage, home, db_path, guarded)
360
+ else:
361
+ result = _delete_runtime_rows(sid, home, agent_db, guarded, delete_in_transaction)
362
+ return {**result, "ok": result["ok"] and stale_complete}
363
+ finally:
364
+ _close(agent_db)
365
+
366
+
367
+ def _write_guard_check(agent_db):
368
+ """The Agent's own user-delete guard, ``(conn, ids) -> bool``: true when a live turn lease or compression lock protects
369
+ any id; expired or dead-holder guards are reclaimed. ``_guarded_ids`` from v0.21.6, the per-row check before it."""
370
+ guarded_ids = getattr(agent_db, "_guarded_ids", None)
371
+ if guarded_ids is not None:
372
+ return lambda conn, ids: bool(guarded_ids(conn, ids))
373
+ rejects = getattr(agent_db, "_write_guards_reject", None)
374
+ if rejects is not None:
375
+ return lambda conn, ids: any(rejects(conn, i, allow_closed_compression_parent=True) for i in ids)
376
+ return None
377
+
378
+
379
+ def _write_cleanup_manifest(home: Path, removed_ids: list[str]) -> None:
380
+ sessions_dir = home / "sessions"
381
+ sessions_dir.mkdir(parents=True, exist_ok=True)
382
+ base = f".cleanup_manifest_{uuid.uuid4().hex}"
383
+ manifest, tmp = sessions_dir / f"{base}.json", sessions_dir / f"{base}.tmp"
384
+ try:
385
+ tmp.write_text(json.dumps(sorted(removed_ids)), encoding="utf-8")
386
+ tmp.rename(manifest)
387
+ except OSError:
388
+ tmp.unlink(missing_ok=True)
389
+ raise
390
+
391
+
392
+ def _delete_runtime_rows(requested: str, home: Path, agent_db, guarded, delete_in_transaction) -> dict:
393
+ """Extend the legacy delete with the Agent's canonical target/retirement transaction.
394
+
395
+ Compression and receipt-backed reset segments are one conversation, even when the caller names its tip.
396
+ The Agent owns delegate/fork boundaries, live-ledger refusals, receipt compaction and tombstones.
397
+ """
398
+ from hermes_state_mutation_guards import delete_targets
399
+ from hermes_state_runtime import RuntimeStoreError
400
+ from hermes_state_media import collect_retired_media
401
+
402
+ def write(conn):
403
+ # The Agent's owner lookup falls back to the physical id on an unreadable receipt; refuse before that loses its owner.
404
+ row = conn.execute("SELECT chat_id FROM sessions WHERE id=?", (requested,)).fetchone()
405
+ owner = row[0] if row else None
406
+ saved = conn.execute("SELECT value FROM state_meta WHERE key=?", ("gateway.local_policy.v1:" + owner,)).fetchone() if owner else None
407
+ if saved is not None:
408
+ from hermes_state_local_lineage import validate_local_lineage
409
+ raw = saved[0]
410
+ if len(raw) > 1_000_000:
411
+ raise ValueError("local receipt exceeds read budget")
412
+ receipt = json.loads(raw)
413
+ ids = receipt.get("lineage", [owner])
414
+ if (receipt.get("session_id") != owner or not isinstance(ids, list) or not ids
415
+ or len(ids) > _COMPRESSION_CHAIN_CAP or not all(isinstance(sid, str) and sid for sid in ids)):
416
+ raise ValueError("invalid local receipt")
417
+ validate_local_lineage(conn, receipt)
418
+ members = conn.execute("SELECT id,chat_id,user_id,session_key,source,model_config FROM sessions WHERE id IN (SELECT value FROM json_each(?))",
419
+ (json.dumps(ids),)).fetchall()
420
+ if len(members) != len(ids) or any(tuple(member)[1:4] != (owner, receipt["principal_id"], receipt["route"]) for member in members):
421
+ raise ValueError("local receipt owner mismatch")
422
+ for member in members:
423
+ config = json.loads(member[5] or '{}')
424
+ if member[0] != owner and (member[4] == 'tool' or any(config.get(key) is not None for key in ('_branched_from', '_delegate_from'))):
425
+ raise ValueError("explicit child is not a local continuation")
426
+ # Preserve the older user-delete guard over the complete canonical set, including closed ancestors.
427
+ if guarded(conn, delete_targets(conn, requested)):
428
+ raise _ActiveWriteGuard
429
+ try:
430
+ _, result = delete_in_transaction(agent_db, conn, requested, {})
431
+ except RuntimeStoreError as exc:
432
+ if exc.reason in ("session_busy", "unknown_execution"):
433
+ raise _ActiveWriteGuard from exc
434
+ raise
435
+ # Publish cleanup intent before the database commit; a failed manifest rolls back retirement too.
436
+ _write_cleanup_manifest(home, result["deleted_ids"])
437
+ return result["deleted_ids"]
438
+
439
+ deleted_ids = agent_db._execute_write(write)
440
+ try:
441
+ collect_retired_media(agent_db)
442
+ except Exception: # noqa: BLE001 - retirement committed; retain its targets for caller cleanup and manifest retry
443
+ log.warning("Failed to collect retired session media", exc_info=True)
444
+ return {"ok": False, "deleted_ids": deleted_ids}
445
+ return {"ok": _process_stale_manifests(home), "deleted_ids": deleted_ids}
446
+
447
+
448
+ def _delete_rows(requested: str, include_lineage: bool, home: Path, db_path: Path, guarded) -> dict:
272
449
  with closing(sqlite3.connect(str(db_path))) as conn:
273
450
  conn.row_factory = sqlite3.Row
274
451
  conn.execute("PRAGMA foreign_keys = ON")
275
452
  conn.execute("BEGIN IMMEDIATE")
276
453
  columns = {row[1] for row in conn.execute("PRAGMA table_info(sessions)").fetchall()}
277
454
  if not {"id", "parent_session_id"}.issubset(columns):
278
- return False
279
- selected = ["id", "parent_session_id"] + [c if c in columns else f"NULL AS {c}" for c in ("model_config", "source", "end_reason", "started_at", "ended_at")]
455
+ return {"ok": False}
456
+ selected = ["id", "parent_session_id"] + [c if c in columns else f"NULL AS {c}" for c in ("model_config", "source", "session_source", "end_reason", "started_at", "ended_at", "chat_id")]
280
457
  rows = conn.execute(f"SELECT {', '.join(selected)} FROM sessions").fetchall()
281
458
  records = []
282
459
  for row in rows:
@@ -292,7 +469,8 @@ def _delete_locked(sid: str, home: Path) -> bool:
292
469
  model_config, known = parsed, True
293
470
  records.append({
294
471
  "id": row["id"], "parent_id": row["parent_session_id"], "delegate_from": model_config.get("_delegate_from"),
295
- "branched_from": model_config.get("_branched_from"), "model_config_known": known, "source": row["source"],
472
+ "branched_from": model_config.get("_branched_from"), "model_config_known": known, "source": row["source"], "session_source": row["session_source"],
473
+ "reset_from": model_config.get("_reset_from"), "chat_id": row["chat_id"],
296
474
  "end_reason": row["end_reason"], "started_at": row["started_at"], "ended_at": row["ended_at"],
297
475
  })
298
476
  by_id = {r["id"]: r for r in records}
@@ -315,82 +493,135 @@ def _delete_locked(sid: str, home: Path) -> bool:
315
493
  return by_id.get(record["delegate_from"]) or {}
316
494
  return by_id.get(record["parent_id"]) or {}
317
495
 
318
- preserved = {r["id"] for r in records if r["id"] != sid and must_preserve(r, lineage_parent(r))}
319
- while True:
320
- descendants = {r["id"] for r in records if r["id"] != sid and r["parent_id"] in preserved}
321
- new_ids = descendants - preserved
322
- if not new_ids:
323
- break
324
- preserved.update(new_ids)
325
- found, frontier = {sid}, {sid}
326
- while frontier:
327
- next_frontier = set()
328
- for record in records:
329
- row_id = record["id"]
330
- if row_id in found or row_id in preserved:
331
- continue
332
- parent_id, delegate_from = record["parent_id"], record["delegate_from"]
333
- if delegate_from not in frontier and parent_id not in frontier:
334
- continue
335
- if must_preserve(record, lineage_parent(record)):
336
- continue
337
- if delegate_from is not None:
338
- if delegate_from in frontier:
496
+ def delegates_of(sid: str) -> list[str]:
497
+ preserved = {r["id"] for r in records if r["id"] != sid and must_preserve(r, lineage_parent(r))}
498
+ while True:
499
+ descendants = {r["id"] for r in records if r["id"] != sid and r["parent_id"] in preserved}
500
+ new_ids = descendants - preserved
501
+ if not new_ids:
502
+ break
503
+ preserved.update(new_ids)
504
+ found, frontier = {sid}, {sid}
505
+ while frontier:
506
+ next_frontier = set()
507
+ for record in records:
508
+ row_id = record["id"]
509
+ if row_id in found or row_id in preserved:
510
+ continue
511
+ parent_id, delegate_from = record["parent_id"], record["delegate_from"]
512
+ if delegate_from not in frontier and parent_id not in frontier:
513
+ continue
514
+ if must_preserve(record, lineage_parent(record)):
515
+ continue
516
+ if delegate_from is not None:
517
+ if delegate_from in frontier:
518
+ next_frontier.add(row_id)
519
+ continue
520
+ if record["source"] != "subagent":
521
+ continue
522
+ if parent_id in frontier and record["model_config_known"]:
339
523
  next_frontier.add(row_id)
340
- continue
341
- if record["source"] != "subagent":
342
- continue
343
- if parent_id in frontier and record["model_config_known"]:
344
- next_frontier.add(row_id)
345
- found.update(next_frontier)
346
- frontier = next_frontier
347
- delegate_ids = sorted(found - {sid})
348
- all_removed = [sid, *delegate_ids]
524
+ found.update(next_frontier)
525
+ frontier = next_frontier
526
+ return sorted(found - {sid})
527
+
528
+ # TAL-792: the compression continuations are resolved here, in the delete transaction, so one that a compression
529
+ # finished after the caller looked is guarded and removed too; one transaction removes them all, tip first.
530
+ sids = _compression_lineage(records, requested) if include_lineage else [requested]
531
+ plan = [(sid, delegates_of(sid)) for sid in reversed(sids)]
532
+ all_removed = list(dict.fromkeys(i for sid, delegate_ids in plan for i in (sid, *delegate_ids)))
533
+ if _has_retained_runtime_history(conn, records, all_removed):
534
+ return {"ok": False, "refused": "runtime_history_unsupported"}
535
+ # The Agent's own user-delete guard, checked over every row before any is removed. A live writer's turn lease or
536
+ # compression lock refuses the whole delete; expired or dead-holder guards are reclaimed.
537
+ if guarded(conn, all_removed):
538
+ raise _ActiveWriteGuard
349
539
  placeholders = ",".join("?" * len(all_removed))
350
- for child_id in delegate_ids:
351
- conn.execute("DELETE FROM messages WHERE session_id = ?", (child_id,))
352
- for child_id in delegate_ids:
353
- conn.execute("UPDATE sessions SET parent_session_id = NULL WHERE parent_session_id = ?", (child_id,))
354
- for child_id in delegate_ids:
355
- conn.execute("DELETE FROM sessions WHERE id = ?", (child_id,))
356
- conn.execute("UPDATE sessions SET parent_session_id = NULL WHERE parent_session_id = ?", (sid,))
357
- conn.execute("DELETE FROM messages WHERE session_id = ?", (sid,))
358
- conn.execute("DELETE FROM sessions WHERE id = ?", (sid,))
540
+ for sid, delegate_ids in plan:
541
+ for child_id in delegate_ids:
542
+ conn.execute("DELETE FROM messages WHERE session_id = ?", (child_id,))
543
+ for child_id in delegate_ids:
544
+ conn.execute("UPDATE sessions SET parent_session_id = NULL WHERE parent_session_id = ?", (child_id,))
545
+ for child_id in delegate_ids:
546
+ conn.execute("DELETE FROM sessions WHERE id = ?", (child_id,))
547
+ conn.execute("UPDATE sessions SET parent_session_id = NULL WHERE parent_session_id = ?", (sid,))
548
+ conn.execute("DELETE FROM messages WHERE session_id = ?", (sid,))
549
+ conn.execute("DELETE FROM sessions WHERE id = ?", (sid,))
359
550
  tables = {row[0] for row in conn.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall()}
360
551
  for table in ("compression_locks", "session_model_usage", "telegram_dm_topic_bindings"):
361
552
  if table in tables:
362
553
  conn.execute(f"DELETE FROM {table} WHERE session_id IN ({placeholders})", all_removed)
363
- sessions_dir = home / "sessions"
364
- sessions_dir.mkdir(parents=True, exist_ok=True)
365
- base = f".cleanup_manifest_{uuid.uuid4().hex}"
366
- manifest, tmp = sessions_dir / f"{base}.json", sessions_dir / f"{base}.tmp"
367
554
  try:
368
- tmp.write_text(json.dumps(sorted(str(i) for i in all_removed)), encoding="utf-8")
369
- tmp.rename(manifest)
555
+ _write_cleanup_manifest(home, all_removed)
370
556
  except OSError:
371
557
  log.warning("Failed to write cleanup manifest", exc_info=True)
372
- tmp.unlink(missing_ok=True)
373
558
  conn.rollback()
374
- return False
559
+ return {"ok": False}
375
560
  conn.commit()
376
-
377
- def alive_after_commit(c, ids):
378
- try:
379
- return _alive_set(c, ids)
380
- except Exception: # noqa: BLE001 - fail closed: treat as alive
381
- return set(ids)
382
-
383
- cleanup_complete = _process_manifests(conn, sessions_dir, alive_query=alive_after_commit)
384
- return stale_complete and cleanup_complete
561
+ return {"ok": _process_stale_manifests(home), "deleted_ids": all_removed}
562
+
563
+
564
+ def _has_retained_runtime_history(conn, records: list[dict], removed_ids: list[str]) -> bool:
565
+ """Read-only downgrade fence, never a replacement for the Agent's retirement/receipt validator."""
566
+ targets = set(removed_ids)
567
+ by_id = {r["id"]: r for r in records}
568
+ # Inspect the logical family, including compressed delegates the legacy plan would detach.
569
+ # This only refuses deletion; the installed Agent remains the sole canonical retirement implementation.
570
+ while True:
571
+ connected = set()
572
+ for child in records:
573
+ parent = by_id.get(child["parent_id"])
574
+ if parent and (child['id'] in targets or parent['id'] in targets):
575
+ # Only markers actually copied from this parent are known to be inherited.
576
+ edge = {**child, **{k: None for k in ('branched_from', 'delegate_from', 'reset_from') if child[k] == parent[k]}}
577
+ if _is_continuation(parent, edge):
578
+ connected.update((parent['id'], child['id']))
579
+ if child['branched_from'] is None and child['reset_from'] is None and (child['delegate_from'] in targets
580
+ or (child['delegate_from'] is None and child['source'] == 'subagent' and child['parent_id'] in targets
581
+ and child['model_config_known'])):
582
+ connected.add(child['id'])
583
+ if connected.issubset(targets):
584
+ break
585
+ targets.update(connected)
586
+ tables = {r[0] for r in conn.execute("SELECT name FROM sqlite_master WHERE type='table'")}
587
+ placeholders = ','.join('?' for _ in targets)
588
+ for table, column in (("session_admissions", "target_session_id"), ("worker_executions", "session_id")):
589
+ if table in tables and conn.execute(f"SELECT 1 FROM {table} WHERE {column} IN ({placeholders}) LIMIT 1", tuple(targets)).fetchone():
590
+ return True
591
+ if 'state_meta' not in tables:
592
+ return False
593
+ # The key and stored chat owner still identify a reset receipt when its JSON is unreadable.
594
+ owners = targets | {r["chat_id"] for r in records if r["id"] in targets and isinstance(r["chat_id"], str)}
595
+ for key, raw in conn.execute("SELECT key,value FROM state_meta WHERE key GLOB 'gateway.*'"):
596
+ if key.startswith('gateway.local_policy.v1:') and key.removeprefix('gateway.local_policy.v1:') in owners:
597
+ return True
598
+ if key.startswith('gateway.retired_session.v1.') and key.removeprefix('gateway.retired_session.v1.') in targets:
599
+ return True
600
+ try:
601
+ receipt = json.loads(raw)
602
+ except (TypeError, ValueError):
603
+ continue
604
+ if not isinstance(receipt, dict):
605
+ continue
606
+ lineage = receipt.get('lineage')
607
+ entry = receipt.get('entry')
608
+ ids = [receipt.get('session_id'), receipt.get('target_session_id'),
609
+ entry.get('session_id') if isinstance(entry, dict) else None,
610
+ *(lineage if isinstance(lineage, list) else [])]
611
+ if any(isinstance(sid, str) and sid in targets for sid in ids):
612
+ return True
613
+ return False
385
614
 
386
615
 
387
- def delete_cli_session(home: Path, sid: str) -> bool:
616
+ def delete_cli_session(home: Path, sid: str, include_lineage: bool = False) -> dict:
388
617
  try:
389
618
  with _thread_lock(home), _process_lock(home):
390
- return _delete_locked(sid, home)
619
+ return _delete_locked(sid, home, include_lineage)
620
+ except _ActiveWriteGuard: # the uncommitted transaction rolls back on close: nothing is removed
621
+ return {"ok": False, "refused": "active_turn"}
391
622
  except Exception: # noqa: BLE001
392
623
  log.warning("Failed to delete CLI session %s from state.db", sid, exc_info=True)
393
- return False
624
+ return {"ok": False}
394
625
 
395
626
 
396
627
  def register(registry) -> None:
@@ -408,11 +639,21 @@ def register(registry) -> None:
408
639
 
409
640
  @registry.method("state_db.sync_title")
410
641
  def title(ctx: CallContext, params: dict) -> dict:
411
- return {"ok": sync_session_title(profile_home_param(params), _session_id(params), str(params.get("title") or ""))}
642
+ return {"ok": sync_session_title(profile_home_param(params), _session_id(params), str(params.get("title") or ""), manual=params.get("manual") is True)}
643
+
644
+ @registry.method("state_db.append_message")
645
+ def append(ctx: CallContext, params: dict) -> dict:
646
+ role = str(params.get("role") or "").strip()
647
+ if not role:
648
+ raise InvalidParams("role is required")
649
+ content = params.get("content")
650
+ if not isinstance(content, str):
651
+ raise InvalidParams("content must be a string")
652
+ return {"ok": append_message(profile_home_param(params), _session_id(params), role=role, content=content, tool_name=params.get("tool_name"), timestamp=params.get("timestamp"))}
412
653
 
413
654
  @registry.method("state_db.delete_cli_session")
414
655
  def delete(ctx: CallContext, params: dict) -> dict:
415
656
  sid = _session_id(params)
416
657
  if not _is_safe_session_id(sid):
417
658
  raise InvalidParams("unsafe session_id")
418
- return {"ok": delete_cli_session(profile_home_param(params).resolve(), sid)}
659
+ return delete_cli_session(profile_home_param(params).resolve(), sid, params.get("include_compression_lineage") is True)