@maudecode/talaria-web 1.18.0 → 1.20.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 (774) 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 +93 -38
  6. package/dist/api/automation-raw.js.map +1 -1
  7. package/dist/api/automation-router.d.ts +99 -17
  8. package/dist/api/automation-router.js +22 -14
  9. package/dist/api/automation-router.js.map +1 -1
  10. package/dist/api/chat-router.d.ts +1433 -37
  11. package/dist/api/chat-router.js +205 -90
  12. package/dist/api/chat-router.js.map +1 -1
  13. package/dist/api/git-router.d.ts +6 -2
  14. package/dist/api/git-router.js +30 -30
  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 +76 -62
  18. package/dist/api/raw-routes.js.map +1 -1
  19. package/dist/api/router.d.ts +5 -5
  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 +2635 -151
  26. package/dist/api/sessions-router.js +193 -177
  27. package/dist/api/sessions-router.js.map +1 -1
  28. package/dist/api/settings-router.d.ts +450 -11
  29. package/dist/api/settings-router.js +102 -49
  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 +102 -80
  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 +963 -109
  38. package/dist/api/tools-router.js +426 -72
  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 +80 -57
  45. package/dist/app.js.map +1 -1
  46. package/dist/auth/crypto.d.ts +3 -0
  47. package/dist/auth/crypto.js +18 -0
  48. package/dist/auth/crypto.js.map +1 -1
  49. package/dist/auth/gate.js +14 -9
  50. package/dist/auth/gate.js.map +1 -1
  51. package/dist/auth/passkeys.d.ts +15 -14
  52. package/dist/auth/passkeys.js +89 -91
  53. package/dist/auth/passkeys.js.map +1 -1
  54. package/dist/auth/store.d.ts +17 -7
  55. package/dist/auth/store.js +93 -52
  56. package/dist/auth/store.js.map +1 -1
  57. package/dist/bin/talaria-web.js +12 -81
  58. package/dist/bin/talaria-web.js.map +1 -1
  59. package/dist/cli/ctl.js +8 -2
  60. package/dist/cli/ctl.js.map +1 -1
  61. package/dist/cli/dotenv.d.ts +5 -0
  62. package/dist/cli/dotenv.js +14 -2
  63. package/dist/cli/dotenv.js.map +1 -1
  64. package/dist/cli/launcher.js +5 -5
  65. package/dist/cli/launcher.js.map +1 -1
  66. package/dist/cli/main.d.ts +1 -0
  67. package/dist/cli/main.js +90 -0
  68. package/dist/cli/main.js.map +1 -0
  69. package/dist/cli/supervise.d.ts +24 -0
  70. package/dist/cli/supervise.js +147 -6
  71. package/dist/cli/supervise.js.map +1 -1
  72. package/dist/config/agent-config.d.ts +37 -11
  73. package/dist/config/agent-config.js +146 -64
  74. package/dist/config/agent-config.js.map +1 -1
  75. package/dist/config.d.ts +2 -0
  76. package/dist/config.js +14 -5
  77. package/dist/config.js.map +1 -1
  78. package/dist/fs/atomic.d.ts +4 -0
  79. package/dist/fs/atomic.js +19 -2
  80. package/dist/fs/atomic.js.map +1 -1
  81. package/dist/fs/stat.d.ts +7 -0
  82. package/dist/fs/stat.js +27 -0
  83. package/dist/fs/stat.js.map +1 -0
  84. package/dist/http/context.d.ts +28 -9
  85. package/dist/http/context.js +77 -25
  86. package/dist/http/context.js.map +1 -1
  87. package/dist/onboarding.d.ts +2 -2
  88. package/dist/onboarding.js +10 -8
  89. package/dist/onboarding.js.map +1 -1
  90. package/dist/profiles/profiles.d.ts +12 -4
  91. package/dist/profiles/profiles.js +78 -30
  92. package/dist/profiles/profiles.js.map +1 -1
  93. package/dist/projects.d.ts +15 -6
  94. package/dist/projects.js +55 -47
  95. package/dist/projects.js.map +1 -1
  96. package/dist/providers/catalog.d.ts +85 -14
  97. package/dist/providers/catalog.js +502 -146
  98. package/dist/providers/catalog.js.map +1 -1
  99. package/dist/providers/env-file.d.ts +10 -3
  100. package/dist/providers/env-file.js +24 -75
  101. package/dist/providers/env-file.js.map +1 -1
  102. package/dist/providers/runtime-env.d.ts +4 -2
  103. package/dist/providers/runtime-env.js +9 -6
  104. package/dist/providers/runtime-env.js.map +1 -1
  105. package/dist/providers/tables.d.ts +3 -1
  106. package/dist/providers/tables.js +4 -2
  107. package/dist/providers/tables.js.map +1 -1
  108. package/dist/redact.js +56 -23
  109. package/dist/redact.js.map +1 -1
  110. package/dist/release.d.ts +7 -0
  111. package/dist/release.js +19 -3
  112. package/dist/release.js.map +1 -1
  113. package/dist/runtime.d.ts +5 -1
  114. package/dist/runtime.js +303 -96
  115. package/dist/runtime.js.map +1 -1
  116. package/dist/server.js +31 -18
  117. package/dist/server.js.map +1 -1
  118. package/dist/sessions/anchor.d.ts +11 -4
  119. package/dist/sessions/anchor.js +33 -37
  120. package/dist/sessions/anchor.js.map +1 -1
  121. package/dist/sessions/background-events.d.ts +2 -0
  122. package/dist/sessions/background-events.js +10 -0
  123. package/dist/sessions/background-events.js.map +1 -0
  124. package/dist/sessions/background-tasks.d.ts +49 -23
  125. package/dist/sessions/background-tasks.js +161 -89
  126. package/dist/sessions/background-tasks.js.map +1 -1
  127. package/dist/sessions/background-updates.d.ts +15 -8
  128. package/dist/sessions/background-updates.js +101 -25
  129. package/dist/sessions/background-updates.js.map +1 -1
  130. package/dist/sessions/cli-sessions.d.ts +23 -6
  131. package/dist/sessions/cli-sessions.js +84 -84
  132. package/dist/sessions/cli-sessions.js.map +1 -1
  133. package/dist/sessions/completions.d.ts +38 -2
  134. package/dist/sessions/completions.js +348 -77
  135. package/dist/sessions/completions.js.map +1 -1
  136. package/dist/sessions/compress.d.ts +8 -0
  137. package/dist/sessions/compress.js +2 -2
  138. package/dist/sessions/compress.js.map +1 -1
  139. package/dist/sessions/drafts.d.ts +14 -10
  140. package/dist/sessions/drafts.js +38 -43
  141. package/dist/sessions/drafts.js.map +1 -1
  142. package/dist/sessions/export.d.ts +2 -0
  143. package/dist/sessions/export.js +6 -2
  144. package/dist/sessions/export.js.map +1 -1
  145. package/dist/sessions/gateway-sessions.d.ts +86 -0
  146. package/dist/sessions/gateway-sessions.js +914 -0
  147. package/dist/sessions/gateway-sessions.js.map +1 -0
  148. package/dist/sessions/gateway-watcher.d.ts +10 -11
  149. package/dist/sessions/gateway-watcher.js +25 -21
  150. package/dist/sessions/gateway-watcher.js.map +1 -1
  151. package/dist/sessions/goals.d.ts +31 -0
  152. package/dist/sessions/goals.js +75 -0
  153. package/dist/sessions/goals.js.map +1 -0
  154. package/dist/sessions/journal.d.ts +5 -79
  155. package/dist/sessions/journal.js +15 -606
  156. package/dist/sessions/journal.js.map +1 -1
  157. package/dist/sessions/list.d.ts +34 -18
  158. package/dist/sessions/list.js +161 -147
  159. package/dist/sessions/list.js.map +1 -1
  160. package/dist/sessions/merge.d.ts +77 -13
  161. package/dist/sessions/merge.js +315 -65
  162. package/dist/sessions/merge.js.map +1 -1
  163. package/dist/sessions/notices.d.ts +22 -0
  164. package/dist/sessions/notices.js +72 -0
  165. package/dist/sessions/notices.js.map +1 -0
  166. package/dist/sessions/pending.d.ts +10 -4
  167. package/dist/sessions/pending.js +83 -7
  168. package/dist/sessions/pending.js.map +1 -1
  169. package/dist/sessions/prefix-index.d.ts +85 -0
  170. package/dist/sessions/prefix-index.js +243 -0
  171. package/dist/sessions/prefix-index.js.map +1 -0
  172. package/dist/sessions/recovery.d.ts +4 -7
  173. package/dist/sessions/recovery.js +100 -283
  174. package/dist/sessions/recovery.js.map +1 -1
  175. package/dist/sessions/relay.d.ts +20 -20
  176. package/dist/sessions/relay.js +205 -127
  177. package/dist/sessions/relay.js.map +1 -1
  178. package/dist/sessions/service.d.ts +251 -78
  179. package/dist/sessions/service.js +1510 -564
  180. package/dist/sessions/service.js.map +1 -1
  181. package/dist/sessions/session.d.ts +20 -2
  182. package/dist/sessions/session.js +33 -5
  183. package/dist/sessions/session.js.map +1 -1
  184. package/dist/sessions/shares.d.ts +7 -6
  185. package/dist/sessions/shares.js +22 -45
  186. package/dist/sessions/shares.js.map +1 -1
  187. package/dist/sessions/source-kind.js +1 -0
  188. package/dist/sessions/source-kind.js.map +1 -1
  189. package/dist/sessions/state-db-identity.d.ts +18 -0
  190. package/dist/sessions/state-db-identity.js +67 -0
  191. package/dist/sessions/state-db-identity.js.map +1 -0
  192. package/dist/sessions/state-db-worker.js +24 -5
  193. package/dist/sessions/state-db-worker.js.map +1 -1
  194. package/dist/sessions/state-db.d.ts +157 -21
  195. package/dist/sessions/state-db.js +1145 -204
  196. package/dist/sessions/state-db.js.map +1 -1
  197. package/dist/sessions/state-saved.d.ts +1 -1
  198. package/dist/sessions/state-saved.js +35 -11
  199. package/dist/sessions/state-saved.js.map +1 -1
  200. package/dist/sessions/storage/backend.d.ts +171 -0
  201. package/dist/sessions/storage/backend.js +19 -0
  202. package/dist/sessions/storage/backend.js.map +1 -0
  203. package/dist/sessions/storage/conformance.d.ts +20 -0
  204. package/dist/sessions/storage/conformance.js +237 -0
  205. package/dist/sessions/storage/conformance.js.map +1 -0
  206. package/dist/sessions/storage/document.d.ts +16 -0
  207. package/dist/sessions/storage/document.js +44 -0
  208. package/dist/sessions/storage/document.js.map +1 -0
  209. package/dist/sessions/storage/json-documents.d.ts +25 -0
  210. package/dist/sessions/storage/json-documents.js +277 -0
  211. package/dist/sessions/storage/json-documents.js.map +1 -0
  212. package/dist/sessions/storage/json-files.d.ts +23 -0
  213. package/dist/sessions/storage/json-files.js +244 -0
  214. package/dist/sessions/storage/json-files.js.map +1 -0
  215. package/dist/sessions/storage/json-installation.d.ts +3 -0
  216. package/dist/sessions/storage/json-installation.js +31 -0
  217. package/dist/sessions/storage/json-installation.js.map +1 -0
  218. package/dist/sessions/storage/json-journal.d.ts +113 -0
  219. package/dist/sessions/storage/json-journal.js +756 -0
  220. package/dist/sessions/storage/json-journal.js.map +1 -0
  221. package/dist/sessions/storage/json-recovery.d.ts +4 -0
  222. package/dist/sessions/storage/json-recovery.js +195 -0
  223. package/dist/sessions/storage/json-recovery.js.map +1 -0
  224. package/dist/sessions/storage/json.d.ts +82 -0
  225. package/dist/sessions/storage/json.js +350 -0
  226. package/dist/sessions/storage/json.js.map +1 -0
  227. package/dist/sessions/storage/row.d.ts +6 -0
  228. package/dist/sessions/storage/row.js +49 -0
  229. package/dist/sessions/storage/row.js.map +1 -0
  230. package/dist/sessions/storage/search-text.d.ts +4 -0
  231. package/dist/sessions/storage/search-text.js +16 -0
  232. package/dist/sessions/storage/search-text.js.map +1 -0
  233. package/dist/sessions/store.d.ts +67 -73
  234. package/dist/sessions/store.js +341 -607
  235. package/dist/sessions/store.js.map +1 -1
  236. package/dist/sessions/streams.d.ts +12 -7
  237. package/dist/sessions/streams.js +58 -15
  238. package/dist/sessions/streams.js.map +1 -1
  239. package/dist/sessions/titles.js +1 -1
  240. package/dist/sessions/titles.js.map +1 -1
  241. package/dist/sessions/todo.d.ts +5 -0
  242. package/dist/sessions/todo.js +28 -21
  243. package/dist/sessions/todo.js.map +1 -1
  244. package/dist/sessions/tool-display.d.ts +8 -5
  245. package/dist/sessions/tool-display.js +28 -16
  246. package/dist/sessions/tool-display.js.map +1 -1
  247. package/dist/sessions/turn-context.d.ts +10 -1
  248. package/dist/sessions/turn-context.js +13 -6
  249. package/dist/sessions/turn-context.js.map +1 -1
  250. package/dist/sessions/turn.d.ts +110 -22
  251. package/dist/sessions/turn.js +918 -380
  252. package/dist/sessions/turn.js.map +1 -1
  253. package/dist/sessions/wakeup-pause.d.ts +8 -13
  254. package/dist/sessions/wakeup-pause.js +31 -49
  255. package/dist/sessions/wakeup-pause.js.map +1 -1
  256. package/dist/sessions/window.js +13 -12
  257. package/dist/sessions/window.js.map +1 -1
  258. package/dist/settings.d.ts +19 -7
  259. package/dist/settings.js +179 -183
  260. package/dist/settings.js.map +1 -1
  261. package/dist/sidecar/client.d.ts +41 -4
  262. package/dist/sidecar/client.js +192 -42
  263. package/dist/sidecar/client.js.map +1 -1
  264. package/dist/sidecar/discover.d.ts +2 -1
  265. package/dist/sidecar/discover.js +93 -10
  266. package/dist/sidecar/discover.js.map +1 -1
  267. package/dist/sidecar/env.d.ts +4 -0
  268. package/dist/sidecar/env.js +3 -0
  269. package/dist/sidecar/env.js.map +1 -0
  270. package/dist/sidecar/fake.d.ts +6 -2
  271. package/dist/sidecar/fake.js +34 -4
  272. package/dist/sidecar/fake.js.map +1 -1
  273. package/dist/spa.d.ts +9 -4
  274. package/dist/spa.js +36 -12
  275. package/dist/spa.js.map +1 -1
  276. package/dist/startup-timing.d.ts +66 -0
  277. package/dist/startup-timing.js +129 -0
  278. package/dist/startup-timing.js.map +1 -0
  279. package/dist/test/env-file.d.ts +5 -0
  280. package/dist/test/env-file.js +88 -0
  281. package/dist/test/env-file.js.map +1 -0
  282. package/dist/test/fs-handles.d.ts +11 -0
  283. package/dist/test/fs-handles.js +31 -0
  284. package/dist/test/fs-handles.js.map +1 -0
  285. package/dist/test/harness.d.ts +1 -0
  286. package/dist/test/harness.js +1 -1
  287. package/dist/test/harness.js.map +1 -1
  288. package/dist/test/passkeys.d.ts +22 -0
  289. package/dist/test/passkeys.js +62 -0
  290. package/dist/test/passkeys.js.map +1 -0
  291. package/dist/test/storage.d.ts +15 -0
  292. package/dist/test/storage.js +26 -0
  293. package/dist/test/storage.js.map +1 -0
  294. package/dist/tools/commands.d.ts +6 -1
  295. package/dist/tools/commands.js +8 -2
  296. package/dist/tools/commands.js.map +1 -1
  297. package/dist/tools/connectors.d.ts +33 -0
  298. package/dist/tools/connectors.js +121 -0
  299. package/dist/tools/connectors.js.map +1 -0
  300. package/dist/tools/crons.d.ts +46 -5
  301. package/dist/tools/crons.js +100 -26
  302. package/dist/tools/crons.js.map +1 -1
  303. package/dist/tools/dashboard-plugins.d.ts +34 -5
  304. package/dist/tools/dashboard-plugins.js +146 -14
  305. package/dist/tools/dashboard-plugins.js.map +1 -1
  306. package/dist/tools/extensions.d.ts +5 -4
  307. package/dist/tools/extensions.js +213 -207
  308. package/dist/tools/extensions.js.map +1 -1
  309. package/dist/tools/gateway-restart.d.ts +82 -0
  310. package/dist/tools/gateway-restart.js +222 -0
  311. package/dist/tools/gateway-restart.js.map +1 -0
  312. package/dist/tools/health.d.ts +28 -4
  313. package/dist/tools/health.js +171 -50
  314. package/dist/tools/health.js.map +1 -1
  315. package/dist/tools/hygiene.d.ts +4 -3
  316. package/dist/tools/hygiene.js +23 -9
  317. package/dist/tools/hygiene.js.map +1 -1
  318. package/dist/tools/insights.d.ts +1 -1
  319. package/dist/tools/insights.js +2 -2
  320. package/dist/tools/insights.js.map +1 -1
  321. package/dist/tools/kanban.d.ts +4 -2
  322. package/dist/tools/kanban.js +28 -19
  323. package/dist/tools/kanban.js.map +1 -1
  324. package/dist/tools/mcp-health.js +74 -24
  325. package/dist/tools/mcp-health.js.map +1 -1
  326. package/dist/tools/mcp.js +19 -1
  327. package/dist/tools/mcp.js.map +1 -1
  328. package/dist/tools/memory-masks.d.ts +5 -0
  329. package/dist/tools/memory-masks.js +256 -0
  330. package/dist/tools/memory-masks.js.map +1 -0
  331. package/dist/tools/memory.d.ts +29 -3
  332. package/dist/tools/memory.js +69 -27
  333. package/dist/tools/memory.js.map +1 -1
  334. package/dist/tools/plugin-oauth.d.ts +14 -0
  335. package/dist/tools/plugin-oauth.js +53 -0
  336. package/dist/tools/plugin-oauth.js.map +1 -0
  337. package/dist/tools/plugin-settings.d.ts +15 -0
  338. package/dist/tools/plugin-settings.js +90 -0
  339. package/dist/tools/plugin-settings.js.map +1 -0
  340. package/dist/tools/prune-advice.d.ts +50 -0
  341. package/dist/tools/prune-advice.js +114 -0
  342. package/dist/tools/prune-advice.js.map +1 -0
  343. package/dist/tools/skills.d.ts +13 -5
  344. package/dist/tools/skills.js +53 -19
  345. package/dist/tools/skills.js.map +1 -1
  346. package/dist/tools/update-notifications.d.ts +102 -17
  347. package/dist/tools/update-notifications.js +400 -82
  348. package/dist/tools/update-notifications.js.map +1 -1
  349. package/dist/tools/update-rollback.d.ts +11 -0
  350. package/dist/tools/update-rollback.js +28 -0
  351. package/dist/tools/update-rollback.js.map +1 -0
  352. package/dist/tools/updates.d.ts +100 -33
  353. package/dist/tools/updates.js +1085 -345
  354. package/dist/tools/updates.js.map +1 -1
  355. package/dist/util.d.ts +2 -0
  356. package/dist/util.js +5 -0
  357. package/dist/util.js.map +1 -1
  358. package/dist/workspace/git.d.ts +16 -1
  359. package/dist/workspace/git.js +291 -11
  360. package/dist/workspace/git.js.map +1 -1
  361. package/dist/workspace/media.d.ts +12 -9
  362. package/dist/workspace/media.js +98 -38
  363. package/dist/workspace/media.js.map +1 -1
  364. package/dist/workspace/preview.js +4 -14
  365. package/dist/workspace/preview.js.map +1 -1
  366. package/dist/workspace/rollback.d.ts +8 -4
  367. package/dist/workspace/rollback.js +22 -12
  368. package/dist/workspace/rollback.js.map +1 -1
  369. package/dist/workspace/workspaces.d.ts +15 -19
  370. package/dist/workspace/workspaces.js +55 -127
  371. package/dist/workspace/workspaces.js.map +1 -1
  372. package/dist/workspace/worktrees.js +170 -32
  373. package/dist/workspace/worktrees.js.map +1 -1
  374. package/package.json +6 -4
  375. package/sidecar/agent_dependency.json +4 -4
  376. package/sidecar/agent_support.json +29 -0
  377. package/sidecar/scripts/record-fixtures.py +12 -3
  378. package/sidecar/scripts/replay_sidecar.py +8 -0
  379. package/sidecar/scripts/suite_runner.py +458 -0
  380. package/sidecar/scripts/test.sh +11 -5
  381. package/sidecar/talaria_sidecar/__init__.py +6 -1
  382. package/sidecar/talaria_sidecar/__main__.py +13 -4
  383. package/sidecar/talaria_sidecar/agent_mutation.py +1111 -0
  384. package/sidecar/talaria_sidecar/agent_services.py +1116 -0
  385. package/sidecar/talaria_sidecar/context_detail.py +59 -0
  386. package/sidecar/talaria_sidecar/dependency_sync.py +85 -0
  387. package/sidecar/talaria_sidecar/home.py +133 -14
  388. package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
  389. package/sidecar/talaria_sidecar/methods/aux.py +211 -41
  390. package/sidecar/talaria_sidecar/methods/chat.py +1378 -200
  391. package/sidecar/talaria_sidecar/methods/checkpoints.py +29 -4
  392. package/sidecar/talaria_sidecar/methods/commands.py +483 -13
  393. package/sidecar/talaria_sidecar/methods/config.py +195 -6
  394. package/sidecar/talaria_sidecar/methods/connectors.py +375 -0
  395. package/sidecar/talaria_sidecar/methods/cron.py +374 -36
  396. package/sidecar/talaria_sidecar/methods/cron_execution.py +284 -0
  397. package/sidecar/talaria_sidecar/methods/dashboard_plugins.py +301 -0
  398. package/sidecar/talaria_sidecar/methods/gateway.py +215 -55
  399. package/sidecar/talaria_sidecar/methods/gateway_sessions.py +418 -0
  400. package/sidecar/talaria_sidecar/methods/goals.py +81 -41
  401. package/sidecar/talaria_sidecar/methods/kanban.py +82 -30
  402. package/sidecar/talaria_sidecar/methods/memory.py +84 -0
  403. package/sidecar/talaria_sidecar/methods/oauth.py +144 -13
  404. package/sidecar/talaria_sidecar/methods/plugin_catalog.py +198 -0
  405. package/sidecar/talaria_sidecar/methods/plugin_oauth.py +234 -0
  406. package/sidecar/talaria_sidecar/methods/process.py +229 -16
  407. package/sidecar/talaria_sidecar/methods/profiles.py +48 -9
  408. package/sidecar/talaria_sidecar/methods/providers.py +196 -26
  409. package/sidecar/talaria_sidecar/methods/runtime.py +71 -1
  410. package/sidecar/talaria_sidecar/methods/skills.py +83 -5
  411. package/sidecar/talaria_sidecar/methods/state_db.py +405 -112
  412. package/sidecar/talaria_sidecar/methods/stt.py +159 -78
  413. package/sidecar/talaria_sidecar/methods/text.py +14 -1
  414. package/sidecar/talaria_sidecar/methods/toolsets.py +51 -0
  415. package/sidecar/talaria_sidecar/methods/usage.py +113 -14
  416. package/sidecar/talaria_sidecar/methods/worktree.py +145 -19
  417. package/sidecar/talaria_sidecar/methods/write_approval.py +181 -0
  418. package/sidecar/talaria_sidecar/rpc.py +70 -7
  419. package/sidecar/talaria_sidecar/runtime.py +122 -14
  420. package/sidecar/talaria_sidecar/speed.py +47 -0
  421. package/sidecar/talaria_sidecar/startup_timing.py +119 -0
  422. package/static/dist/FILES.txt +242 -215
  423. package/static/dist/THIRD_PARTY_LICENSES.md +6 -22
  424. package/static/dist/assets/AppShell-3isgvoro.js +8 -0
  425. package/static/dist/assets/Button-f4n6dapf.js +1 -0
  426. package/static/dist/assets/ChatPage-k7b6xfax.js +4 -0
  427. package/static/dist/assets/ConnectTargets-juqvt5lm.js +1 -0
  428. package/static/dist/assets/Dialog-hta5utr3.js +1 -0
  429. package/static/dist/assets/ExtensionRoute-zrhjn0wm.js +1 -0
  430. package/static/dist/assets/Field-b6ez48oz.js +1 -0
  431. package/static/dist/assets/HubRoute-iwvso2tz.js +2 -0
  432. package/static/dist/assets/LinkCheckContext-ix6zqqkk.js +1 -0
  433. package/static/dist/assets/Markdown-jdeth7zq.js +2 -0
  434. package/static/dist/assets/MarkdownRenderer-fbswsgld.js +302 -0
  435. package/static/dist/assets/MarkdownRenderer-i9o6nr38.css +1 -0
  436. package/static/dist/assets/OAuthSignIn-bpd8hom3.js +1 -0
  437. package/static/dist/assets/ResourceSwitch-odi6dy2o.js +1 -0
  438. package/static/dist/assets/RightPanel-eu6enlo6.js +1 -0
  439. package/static/dist/assets/Select-kr07928w.js +1 -0
  440. package/static/dist/assets/SessionListPanel-etb2i54l.js +1 -0
  441. package/static/dist/assets/SettingsLayout-eu3xxp23.js +1 -0
  442. package/static/dist/assets/States-icab19yg.js +1 -0
  443. package/static/dist/assets/TerminalPanel-hngmsr8b.js +16 -0
  444. package/static/dist/assets/Toaster-nb2uzjw1.js +1 -0
  445. package/static/dist/assets/_app-ga1moszl.js +1 -0
  446. package/static/dist/assets/_app.ext._extensionId-na62087t.js +1 -0
  447. package/static/dist/assets/_app.index-jypgdqoi.js +1 -0
  448. package/static/dist/assets/_app.insights-kabejdtm.js +1 -0
  449. package/static/dist/assets/_app.kanban-m19kfcmx.js +1 -0
  450. package/static/dist/assets/_app.logs-iw4m96sz.js +1 -0
  451. package/static/dist/assets/_app.memory-jq5frwcg.js +1 -0
  452. package/static/dist/assets/_app.profiles-kwa3m7rp.js +1 -0
  453. package/static/dist/assets/_app.session._sessionId-o5lyeipj.js +1 -0
  454. package/static/dist/assets/_app.settings-ckl8hdll.js +1 -0
  455. package/static/dist/assets/_app.settings._section-dtdjk98a.js +3 -0
  456. package/static/dist/assets/_app.skills-n016rihd.js +1 -0
  457. package/static/dist/assets/_app.tasks-n8zuqsqe.js +1 -0
  458. package/static/dist/assets/_app.todos-btew5v2s.js +1 -0
  459. package/static/dist/assets/_app.workspaces-lnfk95ch.js +1 -0
  460. package/static/dist/assets/abnfDiagram-VCTEODGH-dttheegb.js +1 -0
  461. package/static/dist/assets/{angular-html-nu6l31w3.js → angular-html-l28bd5fo.js} +1 -1
  462. package/static/dist/assets/{angular-ts-fbx4f8mm.js → angular-ts-ffzx1vj0.js} +1 -1
  463. package/static/dist/assets/{apl-bx2xr7dh.js → apl-b7h7mmy4.js} +1 -1
  464. package/static/dist/assets/{arc-7popfhbk.js → arc-fk1b21lm.js} +1 -1
  465. package/static/dist/assets/architecture-7GRP2DOG-ic435919.js +1 -0
  466. package/static/dist/assets/architectureDiagram-5GKGNRK7-8r3glgiq.js +36 -0
  467. package/static/dist/assets/archive-il7c6053.js +1 -0
  468. package/static/dist/assets/{astro-g77i97cb.js → astro-k117fy0t.js} +1 -1
  469. package/static/dist/assets/back-gu3nu279.js +1 -0
  470. package/static/dist/assets/{blade-boo0u92y.js → blade-npefsmn8.js} +1 -1
  471. package/static/dist/assets/{blockDiagram-I7D4REHJ-jzthp1wa.js → blockDiagram-I7D4REHJ-jenyos6c.js} +4 -4
  472. package/static/dist/assets/{c-cat0w3sc.js → c-2umg6kbn.js} +1 -1
  473. package/static/dist/assets/{c4Diagram-7LVT6UL2-mwr67mt8.js → c4Diagram-7LVT6UL2-nzlx7yc4.js} +1 -1
  474. package/static/dist/assets/cancel-bsnfo36u.js +1 -0
  475. package/static/dist/assets/channel-dsbtk01y.js +1 -0
  476. package/static/dist/assets/{chunk-4HAMMTFA-gpq1y228.js → chunk-4HAMMTFA-g0cru63b.js} +20 -20
  477. package/static/dist/assets/{chunk-75Z2AOVW-ktje58c4.js → chunk-75Z2AOVW-7rkswkjw.js} +1 -1
  478. package/static/dist/assets/chunk-DU6HZSFF-fn73jzdo.js +128 -0
  479. package/static/dist/assets/{chunk-F27PBJKO-cmev85ti.js → chunk-F27PBJKO-oey8e72m.js} +1 -1
  480. package/static/dist/assets/{chunk-FOHPRMQF-opuflp73.js → chunk-FOHPRMQF-ipewusgj.js} +8 -8
  481. package/static/dist/assets/{chunk-GMAD6QVW-htjgt22y.js → chunk-GMAD6QVW-l2a32wiy.js} +6 -6
  482. package/static/dist/assets/{chunk-GVQU2GXP-qndvoxl7.js → chunk-GVQU2GXP-o9dwzh8h.js} +1 -1
  483. package/static/dist/assets/{chunk-IMKFNOWR-e5bkd5q6.js → chunk-IMKFNOWR-eblwj20b.js} +5 -5
  484. package/static/dist/assets/{chunk-L3NEJ4N5-mj1155r6.js → chunk-L3NEJ4N5-o2mufspb.js} +1 -1
  485. package/static/dist/assets/chunk-OSK3NFVY-ijp9pw29.js +10 -0
  486. package/static/dist/assets/{chunk-P2QGCYS3-f7t54xfm.js → chunk-P2QGCYS3-hs9hqwl4.js} +1 -1
  487. package/static/dist/assets/{chunk-POPQ4Y6H-i927v9oa.js → chunk-POPQ4Y6H-bp9rsqez.js} +1 -1
  488. package/static/dist/assets/{chunk-PWAF6VOD-m84lmnyt.js → chunk-PWAF6VOD-brkprov6.js} +1 -1
  489. package/static/dist/assets/{chunk-SHT3W25Y-mi0tlcu9.js → chunk-SHT3W25Y-gmpv0pxz.js} +13 -13
  490. package/static/dist/assets/{chunk-SVP7TREG-dnau702j.js → chunk-SVP7TREG-oldm08fu.js} +4 -4
  491. package/static/dist/assets/{chunk-TICWLB2K-edem1gkg.js → chunk-TICWLB2K-ooqilfv7.js} +6 -6
  492. package/static/dist/assets/{chunk-XXDRQBXY-n40pf9vy.js → chunk-XXDRQBXY-jkmnqu65.js} +1 -1
  493. package/static/dist/assets/classDiagram-ZZMXUADV-fvgcv24g.js +1 -0
  494. package/static/dist/assets/classDiagram-v2-VYDZK3BY-fvgcv24g.js +1 -0
  495. package/static/dist/assets/{cobol-go622aep.js → cobol-ssf9hkh7.js} +1 -1
  496. package/static/dist/assets/{coffee-jwo1xjhq.js → coffee-lsi9fwae.js} +1 -1
  497. package/static/dist/assets/copied-bz3gkazh.js +1 -0
  498. package/static/dist/assets/copy-jo006coq.js +1 -0
  499. package/static/dist/assets/cose-bilkent-JH36ORCC-layy2r27.js +1 -0
  500. package/static/dist/assets/{cpp-nre7j0kq.js → cpp-lfrh4y55.js} +1 -1
  501. package/static/dist/assets/{crystal-lviso2je.js → crystal-efh4pte7.js} +1 -1
  502. package/static/dist/assets/{css-ywz9j4hb.js → css-i82qdo89.js} +1 -1
  503. package/static/dist/assets/cynefin-OW5HDTMX-d47op7qs.js +1 -0
  504. package/static/dist/assets/cynefinDiagram-5FMLGOSQ-doa7594y.js +62 -0
  505. package/static/dist/assets/cytoscape.esm-fjn2algp.js +321 -0
  506. package/static/dist/assets/dagre-GXQ25YYZ-os768dp4.js +4 -0
  507. package/static/dist/assets/dagre-o5jmjz46.js +1 -0
  508. package/static/dist/assets/{diagram-S7CK7UJ4-l8abxaes.js → diagram-S7CK7UJ4-fyi81nxd.js} +4 -4
  509. package/static/dist/assets/diagram-UQ7AKVKN-j3exggaq.js +41 -0
  510. package/static/dist/assets/{diagram-VSXAHHWV-fnky6lvc.js → diagram-VSXAHHWV-omo1en2l.js} +1 -1
  511. package/static/dist/assets/diagram-VX7I27RA-oro2cyu0.js +24 -0
  512. package/static/dist/assets/diagram-Z3DM3KII-byt9vdb7.js +24 -0
  513. package/static/dist/assets/dist-crc46di9.js +7 -0
  514. package/static/dist/assets/dist-etpoyscq.js +44 -0
  515. package/static/dist/assets/{dist-c4c2m3kv.js → dist-nb670eu6.js} +1 -1
  516. package/static/dist/assets/ebnfDiagram-PWID7BFC-ee3haugh.js +1 -0
  517. package/static/dist/assets/{edge-dvv35byi.js → edge-lrob635n.js} +1 -1
  518. package/static/dist/assets/{elixir-i2f1ki1g.js → elixir-kdpxeq93.js} +1 -1
  519. package/static/dist/assets/{elm-cpepyjm4.js → elm-c8irj9uh.js} +1 -1
  520. package/static/dist/assets/erDiagram-RLTQ6QDP-d1e93yff.js +99 -0
  521. package/static/dist/assets/{erb-idlyfheg.js → erb-flwsv146.js} +1 -1
  522. package/static/dist/assets/eventmodeling-NTZA5JFV-i1ihb40c.js +1 -0
  523. package/static/dist/assets/flowDiagram-HODETNUW-jahfpiod.js +1 -0
  524. package/static/dist/assets/folder-plus-ivoglq98.js +1 -0
  525. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-ngbsyp37.js → ganttDiagram-EL5Y4UJY-m7g0jud4.js} +1 -1
  526. package/static/dist/assets/{git-rebase-d9lpfpbn.js → git-rebase-bli19aoq.js} +1 -1
  527. package/static/dist/assets/gitGraph-4MIJSDKK-hzdj07yy.js +1 -0
  528. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-eravdti4.js → gitGraphDiagram-WWUBYQGX-dm9agbna.js} +1 -1
  529. package/static/dist/assets/{glimmer-js-39i0urfb.js → glimmer-js-d4icg38p.js} +1 -1
  530. package/static/dist/assets/{glimmer-ts-gdtd6n73.js → glimmer-ts-bk75772u.js} +1 -1
  531. package/static/dist/assets/{glsl-o1djm5pp.js → glsl-lqormp2b.js} +1 -1
  532. package/static/dist/assets/{graphql-kj6rz55t.js → graphql-hw6s5qzd.js} +1 -1
  533. package/static/dist/assets/{hack-pe1qqr2i.js → hack-ozrv6l4d.js} +1 -1
  534. package/static/dist/assets/{haml-cknnbcqs.js → haml-gytfosdt.js} +1 -1
  535. package/static/dist/assets/{handlebars-hwq64orh.js → handlebars-b6g7jffd.js} +1 -1
  536. package/static/dist/assets/highlighted-body-KPVGNVTW-mmgz2czu.js +1 -0
  537. package/static/dist/assets/host-fr6lni1p.js +1 -0
  538. package/static/dist/assets/{html-derivative-h2i2pyjc.js → html-derivative-f1tqcroo.js} +1 -1
  539. package/static/dist/assets/{html-ha05xtvt.js → html-on6oj6yj.js} +1 -1
  540. package/static/dist/assets/{http-cf94zu27.js → http-odhufsl7.js} +1 -1
  541. package/static/dist/assets/{hurl-lslax568.js → hurl-mu680336.js} +1 -1
  542. package/static/dist/assets/index-73649w7o.js +10 -0
  543. package/static/dist/assets/index-lhf1fsdf.css +2 -0
  544. package/static/dist/assets/info-A6RAGUB7-lll1dqmm.js +1 -0
  545. package/static/dist/assets/infoDiagram-27XIBGKW-k7esc639.js +2 -0
  546. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-i6ypq351.js → ishikawaDiagram-5VMMS53U-lgr6k9wo.js} +6 -6
  547. package/static/dist/assets/{java-ndjf2o89.js → java-nxbe8uju.js} +1 -1
  548. package/static/dist/assets/{javascript-coftlwy3.js → javascript-lz3kxcyz.js} +1 -1
  549. package/static/dist/assets/{jinja-etei9wy7.js → jinja-l5pk84gt.js} +1 -1
  550. package/static/dist/assets/{jison-hyekgft1.js → jison-jdutdwyy.js} +1 -1
  551. package/static/dist/assets/{journeyDiagram-3NMN7TZE-lduf1z95.js → journeyDiagram-3NMN7TZE-ndmbxuqk.js} +1 -1
  552. package/static/dist/assets/{json-lok0yaho.js → json-dnge4ssf.js} +1 -1
  553. package/static/dist/assets/{jsx-b64w0nbx.js → jsx-c3lwhkep.js} +1 -1
  554. package/static/dist/assets/{jsx-runtime-eu92a5pu.js → jsx-runtime-o40ukmjl.js} +1 -1
  555. package/static/dist/assets/{julia-jxxzz2yn.js → julia-hwd4rrcb.js} +1 -1
  556. package/static/dist/assets/{just-mc29iw9t.js → just-nka3oxdx.js} +1 -1
  557. package/static/dist/assets/{kanban-definition-UXKFOSKX-e18bu4pg.js → kanban-definition-UXKFOSKX-mjxym0jp.js} +28 -28
  558. package/static/dist/assets/katex-cbdd1ohw.css +1 -0
  559. package/static/dist/assets/katex-pbij2oo6.js +257 -0
  560. package/static/dist/assets/{latex-pafa03ft.js → latex-iqmr7e40.js} +1 -1
  561. package/static/dist/assets/lazyRouteComponent-cwb6l7xh.js +1 -0
  562. package/static/dist/assets/{line-meizqsvn.js → line-mtr5k6il.js} +1 -1
  563. package/static/dist/assets/linear-jlwrvvy6.js +1 -0
  564. package/static/dist/assets/link-iadw4ghw.js +2 -0
  565. package/static/dist/assets/{liquid-hz5c2pov.js → liquid-okmk9tbp.js} +1 -1
  566. package/static/dist/assets/locale-cs-n41hptse.js +5 -0
  567. package/static/dist/assets/locale-de-k7ht47ew.js +5 -0
  568. package/static/dist/assets/locale-es-ih078lco.js +5 -0
  569. package/static/dist/assets/locale-fr-ojabnf41.js +5 -0
  570. package/static/dist/assets/locale-it-kb96jufy.js +5 -0
  571. package/static/dist/assets/locale-ja-jpsp3xs1.js +7 -0
  572. package/static/dist/assets/locale-ko-cpzuy0n7.js +5 -0
  573. package/static/dist/assets/locale-pl-dbap4leu.js +5 -0
  574. package/static/dist/assets/locale-pt-nci7w72x.js +5 -0
  575. package/static/dist/assets/locale-ru-soghe4cs.js +7 -0
  576. package/static/dist/assets/locale-tr-ks00mu68.js +5 -0
  577. package/static/dist/assets/locale-vi-ij7twfm6.js +5 -0
  578. package/static/dist/assets/locale-zh-Hant-feakwr7a.js +5 -0
  579. package/static/dist/assets/locale-zh-ren0vjyv.js +7 -0
  580. package/static/dist/assets/login-lkhtzfcl.js +1 -0
  581. package/static/dist/assets/{lua-leyf8mlb.js → lua-krx4xj5h.js} +1 -1
  582. package/static/dist/assets/{marko-cn1fzpdv.js → marko-gbvpfehz.js} +1 -1
  583. package/static/dist/assets/{mdc-huhy88df.js → mdc-c21zlyi5.js} +1 -1
  584. package/static/dist/assets/mermaid-HWGCJPDP-jx0q5dm2.js +1 -0
  585. package/static/dist/assets/mermaid-parser.core-k91vdnvi.js +7 -0
  586. package/static/dist/assets/micromark-factory-space-fnmnpi6s.js +1 -0
  587. package/static/dist/assets/{mindmap-definition-YA3MSWOX-27b26eok.js → mindmap-definition-YA3MSWOX-ehztfea4.js} +28 -28
  588. package/static/dist/assets/{nginx-e7lvhsmn.js → nginx-f3d68ed4.js} +1 -1
  589. package/static/dist/assets/{nim-dun5d8mk.js → nim-dw0jcy70.js} +1 -1
  590. package/static/dist/assets/onboarding-f67z0a2r.js +1 -0
  591. package/static/dist/assets/packet-AYTQ26CC-ok2xrblz.js +1 -0
  592. package/static/dist/assets/pcmTap.worklet-74EKjWAZ.js +1 -0
  593. package/static/dist/assets/pegDiagram-XKGWAZYB-ec3rpj0m.js +1 -0
  594. package/static/dist/assets/{perl-bj3oqtet.js → perl-3c0r45c8.js} +1 -1
  595. package/static/dist/assets/{php-buzp12r0.js → php-rznhidvp.js} +1 -1
  596. package/static/dist/assets/pie-WAS4IAKB-iwkir23u.js +1 -0
  597. package/static/dist/assets/pieDiagram-E7YTZNPT-fcpqpekh.js +39 -0
  598. package/static/dist/assets/{pug-mjad7he9.js → pug-f2le4f3y.js} +1 -1
  599. package/static/dist/assets/{qml-d1gdp10s.js → qml-e2wbq9cr.js} +1 -1
  600. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-hhue7d8o.js → quadrantDiagram-AXDQQJYC-lqsync43.js} +1 -1
  601. package/static/dist/assets/queryKeys-ed4n2egc.js +9 -0
  602. package/static/dist/assets/{r-o3r9c7ao.js → r-epfzuw6q.js} +1 -1
  603. package/static/dist/assets/radar-RG4KPBEZ-hje4jbk6.js +1 -0
  604. package/static/dist/assets/railroad-74A4TZTK-gll9n6qi.js +1 -0
  605. package/static/dist/assets/railroad-abnf-HS5TGJTU-o6h6lpn4.js +1 -0
  606. package/static/dist/assets/railroad-ebnf-LZEXJU2U-juaefj6o.js +1 -0
  607. package/static/dist/assets/railroad-peg-WCYAUIDC-cgfhvpah.js +1 -0
  608. package/static/dist/assets/railroadDiagram-O6MQD6OU-lp3w7awf.js +1 -0
  609. package/static/dist/assets/{razor-ilc585yr.js → razor-pea1u1d0.js} +1 -1
  610. package/static/dist/assets/refresh-cw-iccm7a4e.js +1 -0
  611. package/static/dist/assets/refresh-i9ya9dvl.js +1 -0
  612. package/static/dist/assets/{regexp-mpjtcvwm.js → regexp-hzte0a5x.js} +1 -1
  613. package/static/dist/assets/registry-g7w3353u.js +1 -0
  614. package/static/dist/assets/requirementDiagram-BXWQKSXE-ha8eibcf.js +84 -0
  615. package/static/dist/assets/rolldown-runtime-bnnw9q4a.js +1 -0
  616. package/static/dist/assets/{rst-jrkwjdyi.js → rst-m6tugj5o.js} +1 -1
  617. package/static/dist/assets/{ruby-n4tjcbpz.js → ruby-l19vq3w1.js} +1 -1
  618. package/static/dist/assets/runtime-nlxpnegr.js +1 -0
  619. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-fqb8xcjf.js → sankeyDiagram-P5KCCOFB-oxf31pr9.js} +1 -1
  620. package/static/dist/assets/{sas-hjo6y93k.js → sas-ktdxo397.js} +1 -1
  621. package/static/dist/assets/{scss-ncidjv48.js → scss-kn3oxfwf.js} +1 -1
  622. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-dlcz6qjz.js → sequenceDiagram-WJ2MYXX4-jiq8lhyo.js} +11 -11
  623. package/static/dist/assets/settings_section_extensions_title-fadc7o65.js +1 -0
  624. package/static/dist/assets/share._token-o76ki0ly.js +2 -0
  625. package/static/dist/assets/{shellscript-m8whjpqd.js → shellscript-l100jtrg.js} +1 -1
  626. package/static/dist/assets/{shellsession-i5bj6syz.js → shellsession-m5qukwow.js} +1 -1
  627. package/static/dist/assets/sizeCapture-INFHLROL-dk1io13w.js +1 -0
  628. package/static/dist/assets/sliders-horizontal-ddcs88av.js +1 -0
  629. package/static/dist/assets/{soy-hhh36ysq.js → soy-mexlscur.js} +1 -1
  630. package/static/dist/assets/{sql-j21bzcl6.js → sql-o0ho5suh.js} +1 -1
  631. package/static/dist/assets/src-h89s0hs4.js +1 -0
  632. package/static/dist/assets/{stata-bbu2onh1.js → stata-be9ck1q3.js} +1 -1
  633. package/static/dist/assets/stateDiagram-D77RDMKH-f3fslnon.js +1 -0
  634. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hlt6yphw.js +1 -0
  635. package/static/dist/assets/{surrealql-l5vczuco.js → surrealql-gk1xkkyy.js} +1 -1
  636. package/static/dist/assets/{svelte-idn422g6.js → svelte-k6ecjilf.js} +1 -1
  637. package/static/dist/assets/swimlanes-42K2YHIH-k1hmk7jf.js +1 -0
  638. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-hd5t9tnt.js +8 -0
  639. package/static/dist/assets/{templ-e22qou3c.js → templ-gf3bftk6.js} +1 -1
  640. package/static/dist/assets/{tex-deqpc5ee.js → tex-d21fqv1z.js} +1 -1
  641. package/static/dist/assets/{timeline-definition-24CTP7MA-b1vl2zil.js → timeline-definition-24CTP7MA-n3ncfy9r.js} +8 -8
  642. package/static/dist/assets/toast-liparz2j.js +56 -0
  643. package/static/dist/assets/treeView-Q6P3EWNA-l3y2pejt.js +1 -0
  644. package/static/dist/assets/treemap-WGGIJYW6-jown9axh.js +1 -0
  645. package/static/dist/assets/{ts-tags-ctnibc27.js → ts-tags-n0g61gr6.js} +1 -1
  646. package/static/dist/assets/{tsx-i163n32g.js → tsx-cvv7wv6q.js} +1 -1
  647. package/static/dist/assets/{twig-x0fi7wm8.js → twig-n1f67204.js} +1 -1
  648. package/static/dist/assets/{typescript-g18c34xz.js → typescript-og7o55cx.js} +1 -1
  649. package/static/dist/assets/untitled-mj86r4gz.js +1 -0
  650. package/static/dist/assets/useDebounced-g8r0ggve.js +1 -0
  651. package/static/dist/assets/useForm-o4uu74mx.js +1 -0
  652. package/static/dist/assets/{useParams-b4dq6n4q.js → useParams-ftsveu84.js} +1 -1
  653. package/static/dist/assets/{useSearch-ipfmv3he.js → useSearch-crqueqga.js} +1 -1
  654. package/static/dist/assets/vennDiagram-4TSXK5OY-dh59uq1c.js +34 -0
  655. package/static/dist/assets/{vue-mwu5l1bb.js → vue-ej4xpwqw.js} +1 -1
  656. package/static/dist/assets/{vue-html-nskj3du0.js → vue-html-d48xsjuo.js} +1 -1
  657. package/static/dist/assets/{vue-vine-cqe77smq.js → vue-vine-pev88ip6.js} +1 -1
  658. package/static/dist/assets/wardley-WFR3VGLG-e6d74b0j.js +1 -0
  659. package/static/dist/assets/wardleyDiagram-VM6X3IG4-hnofh78f.js +78 -0
  660. package/static/dist/assets/with-selector-nu1b5z0v.js +1 -0
  661. package/static/dist/assets/{xml-gau7gvrv.js → xml-ifxp6gqb.js} +1 -1
  662. package/static/dist/assets/{xsl-ew09zq8b.js → xsl-fug2cckc.js} +1 -1
  663. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-e49523ab.js → xychartDiagram-S5SC5T6Z-bpymjelb.js} +6 -6
  664. package/static/dist/assets/{yaml-ofnrxtvf.js → yaml-fjmafnlo.js} +1 -1
  665. package/static/dist/extension-sdk.js +1 -1
  666. package/static/dist/index.html +1 -1
  667. package/static/dist/sw.js +180 -136
  668. package/static/dist/assets/AppShell-g3bkgnvt.js +0 -1
  669. package/static/dist/assets/ChatPage-oo7bdan6.js +0 -25
  670. package/static/dist/assets/Dialog-g355qxhp.js +0 -1
  671. package/static/dist/assets/ExtensionRoute-i2y9fvjm.js +0 -1
  672. package/static/dist/assets/HubRoute-lmkrbw47.js +0 -2
  673. package/static/dist/assets/Markdown-j4kut4j2.js +0 -598
  674. package/static/dist/assets/Markdown-lwviulmg.css +0 -1
  675. package/static/dist/assets/RightPanel-ohlsdzfl.js +0 -1
  676. package/static/dist/assets/Select-kddq75qc.js +0 -1
  677. package/static/dist/assets/SessionListPanel-lu3oy0hw.js +0 -1
  678. package/static/dist/assets/SettingsLayout-o9bv4mgb.js +0 -1
  679. package/static/dist/assets/States-eq6fe29m.js +0 -1
  680. package/static/dist/assets/Toaster-pc247u9f.js +0 -1
  681. package/static/dist/assets/_app-f8n1i0m1.js +0 -1
  682. package/static/dist/assets/_app.ext._extensionId-gfbzpoou.js +0 -1
  683. package/static/dist/assets/_app.index-bzzv80hk.js +0 -1
  684. package/static/dist/assets/_app.insights-dzixbryi.js +0 -1
  685. package/static/dist/assets/_app.kanban-c6hep2us.js +0 -1
  686. package/static/dist/assets/_app.logs-i69qds98.js +0 -1
  687. package/static/dist/assets/_app.memory-kl4vf0gd.js +0 -1
  688. package/static/dist/assets/_app.profiles-b8zinmyp.js +0 -1
  689. package/static/dist/assets/_app.session._sessionId-fn1bhde6.js +0 -1
  690. package/static/dist/assets/_app.settings-cg8plwmf.js +0 -1
  691. package/static/dist/assets/_app.settings._section-bkwbi9zn.js +0 -3
  692. package/static/dist/assets/_app.skills-cs47sbvs.js +0 -1
  693. package/static/dist/assets/_app.tasks-dwvk64tc.js +0 -1
  694. package/static/dist/assets/_app.todos-c8xjm8p3.js +0 -1
  695. package/static/dist/assets/_app.workspaces-ehvd1gds.js +0 -1
  696. package/static/dist/assets/abnfDiagram-VCTEODGH-c8kdixke.js +0 -1
  697. package/static/dist/assets/architecture-7GRP2DOG-6crvnylg.js +0 -1
  698. package/static/dist/assets/architectureDiagram-5GKGNRK7-cku06x1p.js +0 -36
  699. package/static/dist/assets/back-h7aun7ew.js +0 -1
  700. package/static/dist/assets/cancel-fhi0vcnu.js +0 -1
  701. package/static/dist/assets/channel-b2zo73z1.js +0 -1
  702. package/static/dist/assets/chunk-DU6HZSFF-ofajdixh.js +0 -128
  703. package/static/dist/assets/chunk-OSK3NFVY-e7gkikcw.js +0 -10
  704. package/static/dist/assets/classDiagram-ZZMXUADV-oe99st8x.js +0 -1
  705. package/static/dist/assets/classDiagram-v2-VYDZK3BY-oe99st8x.js +0 -1
  706. package/static/dist/assets/copied-hcplv46p.js +0 -1
  707. package/static/dist/assets/copy-magtofyp.js +0 -1
  708. package/static/dist/assets/cose-bilkent-JH36ORCC-eclcy6ja.js +0 -1
  709. package/static/dist/assets/cynefin-OW5HDTMX-siqlulkl.js +0 -1
  710. package/static/dist/assets/cynefinDiagram-5FMLGOSQ-i648tah9.js +0 -62
  711. package/static/dist/assets/cytoscape.esm-bqu53u12.js +0 -321
  712. package/static/dist/assets/dagre-GXQ25YYZ-mwn6uc17.js +0 -4
  713. package/static/dist/assets/dagre-lkoknbjn.js +0 -1
  714. package/static/dist/assets/diagram-UQ7AKVKN-mekq7zgq.js +0 -41
  715. package/static/dist/assets/diagram-VX7I27RA-xe6r5qfw.js +0 -24
  716. package/static/dist/assets/diagram-Z3DM3KII-nq07dg7k.js +0 -24
  717. package/static/dist/assets/ebnfDiagram-PWID7BFC-c62ipm3g.js +0 -1
  718. package/static/dist/assets/endpoints-klbxod4t.js +0 -64
  719. package/static/dist/assets/erDiagram-RLTQ6QDP-h39kmnzy.js +0 -99
  720. package/static/dist/assets/eventmodeling-NTZA5JFV-obfede4u.js +0 -1
  721. package/static/dist/assets/flowDiagram-HODETNUW-kdpsp1je.js +0 -1
  722. package/static/dist/assets/gitGraph-4MIJSDKK-fr2i7caa.js +0 -1
  723. package/static/dist/assets/highlighted-body-KPVGNVTW-jwpop9p8.js +0 -1
  724. package/static/dist/assets/host-i828xuo7.js +0 -1
  725. package/static/dist/assets/index-eh8zilnv.css +0 -2
  726. package/static/dist/assets/index-r648f4o1.js +0 -11
  727. package/static/dist/assets/info-A6RAGUB7-h11x0dxo.js +0 -1
  728. package/static/dist/assets/infoDiagram-27XIBGKW-dfh47dw9.js +0 -2
  729. package/static/dist/assets/lazyRouteComponent-e1y4t2i9.js +0 -1
  730. package/static/dist/assets/linear-becwlnhk.js +0 -1
  731. package/static/dist/assets/link-oot2yn73.js +0 -1
  732. package/static/dist/assets/login-gu28l9ou.js +0 -1
  733. package/static/dist/assets/mermaid-HWGCJPDP-mtwrj8fn.js +0 -1
  734. package/static/dist/assets/mermaid-parser.core-ntne45i9.js +0 -7
  735. package/static/dist/assets/not-found-ccnnac39.js +0 -1
  736. package/static/dist/assets/onboarding-lkphzu1s.js +0 -1
  737. package/static/dist/assets/onboarding_model_label-ftpjdwqk.js +0 -1
  738. package/static/dist/assets/packet-AYTQ26CC-l6jdka8p.js +0 -1
  739. package/static/dist/assets/pegDiagram-XKGWAZYB-g1er3bxj.js +0 -1
  740. package/static/dist/assets/pie-WAS4IAKB-i0ylcrt9.js +0 -1
  741. package/static/dist/assets/pieDiagram-E7YTZNPT-fbz1e55z.js +0 -39
  742. package/static/dist/assets/radar-RG4KPBEZ-f9b70aa4.js +0 -1
  743. package/static/dist/assets/railroad-74A4TZTK-lgsuoeda.js +0 -1
  744. package/static/dist/assets/railroad-abnf-HS5TGJTU-nf9d6pdx.js +0 -1
  745. package/static/dist/assets/railroad-ebnf-LZEXJU2U-f7ummkt5.js +0 -1
  746. package/static/dist/assets/railroad-peg-WCYAUIDC-oczq5tqs.js +0 -1
  747. package/static/dist/assets/railroadDiagram-O6MQD6OU-eqpy9fnz.js +0 -1
  748. package/static/dist/assets/refresh-abtu93ke.js +0 -1
  749. package/static/dist/assets/refresh-cw-hlwb02qv.js +0 -1
  750. package/static/dist/assets/requirementDiagram-BXWQKSXE-ogf6puhi.js +0 -84
  751. package/static/dist/assets/rolldown-runtime-b9miacsj.js +0 -1
  752. package/static/dist/assets/root-mbklpuv4.js +0 -1
  753. package/static/dist/assets/saved-girnabkf.js +0 -1
  754. package/static/dist/assets/settings_section_extensions_title-h14cwk6f.js +0 -1
  755. package/static/dist/assets/share._token-kl0r7ido.js +0 -2
  756. package/static/dist/assets/sizeCapture-INFHLROL-g612l48j.js +0 -1
  757. package/static/dist/assets/sliders-horizontal-n1zm34qq.js +0 -1
  758. package/static/dist/assets/src-hjyib4mu.js +0 -1
  759. package/static/dist/assets/sse-iwku0sjo.js +0 -1
  760. package/static/dist/assets/stateDiagram-D77RDMKH-fyoznpcs.js +0 -1
  761. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-ixhx8r46.js +0 -1
  762. package/static/dist/assets/swimlanes-42K2YHIH-oefldhfy.js +0 -1
  763. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-h9ersk2e.js +0 -8
  764. package/static/dist/assets/todoStore-jjr5yr78.js +0 -1
  765. package/static/dist/assets/treeView-Q6P3EWNA-f7hcci5o.js +0 -1
  766. package/static/dist/assets/treemap-WGGIJYW6-nl85071a.js +0 -1
  767. package/static/dist/assets/units-kgxzxfhi.js +0 -1
  768. package/static/dist/assets/untitled-cikfjntn.js +0 -1
  769. package/static/dist/assets/useForm-kqoqg0k9.js +0 -1
  770. package/static/dist/assets/useLocale-o59tbiea.js +0 -1
  771. package/static/dist/assets/vennDiagram-4TSXK5OY-h5hzbk0n.js +0 -34
  772. package/static/dist/assets/wardley-WFR3VGLG-jftvpm3e.js +0 -1
  773. package/static/dist/assets/wardleyDiagram-VM6X3IG4-hedh85ge.js +0 -78
  774. /package/static/dist/assets/{ChatPage-gmu5c7lf.css → TerminalPanel-gmu5c7lf.css} +0 -0
@@ -7,17 +7,20 @@ server; the sidecar receives typed params.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
+ import functools
10
11
  import json
11
12
  import secrets
12
13
  import time
13
14
  from dataclasses import asdict, is_dataclass
14
- from typing import Any
15
+ from typing import Any, NamedTuple
15
16
 
16
17
  from ..errors import InvalidParams, RpcError
17
18
  from ..home import profile_home_param, scoped_home
18
19
  from ..rpc import CallContext
19
20
 
20
- BOARD_COLUMNS = ["triage", "todo", "ready", "running", "blocked", "done"]
21
+ # Agent 2026.9.24 predates ``kanban_workflow``; its ``VALID_STATUSES`` set holds these columns, in this board order.
22
+ # Delete with that release's entry in ``agent_support.json``.
23
+ _LEGACY_COLUMNS = ("triage", "todo", "scheduled", "ready", "running", "blocked", "review", "done")
21
24
 
22
25
 
23
26
  class NotFound(RpcError):
@@ -38,6 +41,27 @@ def _kb():
38
41
  return kb
39
42
 
40
43
 
44
+ class _Workflow(NamedTuple):
45
+ columns: tuple[tuple[str, str], ...] # (key, label) in board order
46
+ manual: dict | None # src -> [dst]; None on an Agent without a move table
47
+
48
+
49
+ @functools.cache
50
+ def _workflow() -> _Workflow:
51
+ """The Agent's board columns and manual move table from ``kanban_workflow.DEFAULT_WORKFLOW`` (Agent 0.21.6+, TAL-796)."""
52
+ try:
53
+ from hermes_cli.kanban_workflow import DEFAULT_WORKFLOW
54
+ except ImportError:
55
+ statuses = getattr(_kb(), "VALID_STATUSES", _LEGACY_COLUMNS)
56
+ return _Workflow(tuple((key, key.title()) for key in _LEGACY_COLUMNS if key in statuses), None)
57
+ workflow = DEFAULT_WORKFLOW.to_dict()
58
+ return _Workflow(tuple((c["key"], c["label"]) for c in workflow["columns"]), workflow["manual"])
59
+
60
+
61
+ def _columns() -> list[str]:
62
+ return [key for key, _ in _workflow().columns]
63
+
64
+
41
65
  def _board(params: dict):
42
66
  raw = params.get("board")
43
67
  if raw is None or (isinstance(raw, str) and raw.strip() == ""):
@@ -49,9 +73,16 @@ def _board(params: dict):
49
73
  raise InvalidParams(f"invalid board slug: {raw!r}") from exc
50
74
  if not normed:
51
75
  return None
52
- default_slug = getattr(kb, "DEFAULT_BOARD", "default")
53
- if normed != default_slug and not kb.board_exists(normed):
54
- raise NotFound(f"board {normed!r} does not exist")
76
+ if normed == getattr(kb, "DEFAULT_BOARD", "default"):
77
+ return normed
78
+ return _live_board(kb, normed, normed)
79
+
80
+
81
+ def _live_board(kb, normed: str, shown, *, archived_ok: bool = False) -> str:
82
+ """``normed`` when it names a live board. Agent 0.21.6 leaves an ``archived`` ``board.json`` tombstone at an
83
+ archived board's slug, so ``board_exists`` alone would let a stale link reach it (TAL-795)."""
84
+ if not kb.board_exists(normed) or (not archived_ok and kb.read_board_metadata(normed).get("archived")):
85
+ raise NotFound(f"board {shown!r} does not exist")
55
86
  return normed
56
87
 
57
88
 
@@ -66,8 +97,6 @@ def _connect_module():
66
97
 
67
98
 
68
99
  def _conn(board=None):
69
- kb = _kb()
70
- kb.init_db(board=board)
71
100
  module = _connect_module()
72
101
  closing = getattr(module, "connect_closing", None)
73
102
  return closing(board=board) if closing is not None else module.connect(board=board)
@@ -197,6 +226,8 @@ def _task_dict(task, conn):
197
226
  # stored or supplied evidence, and refuses to release a live worker's claim.
198
227
  data["claim_live"] = data.get("status") == "running" and _claim_live(conn, data.get("id"))
199
228
  data["has_completion_evidence"] = bool(str(data.get("result") or "").strip())
229
+ manual = _workflow().manual
230
+ data["agent_move_targets"] = None if manual is None else list(manual.get(data.get("status"), []))
200
231
  try:
201
232
  age = _kb().task_age(task)
202
233
  except Exception: # noqa: BLE001
@@ -237,8 +268,13 @@ def _comment_counts(conn):
237
268
 
238
269
  def _validate_status(status: str) -> str:
239
270
  value = str(status or "").strip().lower()
240
- if value not in set(BOARD_COLUMNS) | {"archived"}:
271
+ if value not in {*_columns(), "archived"}:
241
272
  raise InvalidParams(f"invalid status: {value}")
273
+ if value == "running":
274
+ raise InvalidParams("Cannot set status to 'running' directly; use the dispatcher/claim path")
275
+ if value in ("scheduled", "review"):
276
+ # The Agent reaches these through verbs with extra input (a wake time, a reviewer), which Talaria does not offer.
277
+ raise InvalidParams(f"Cannot set status to {value!r} directly")
242
278
  return value
243
279
 
244
280
 
@@ -327,19 +363,21 @@ def _patch_task(conn, task_id: str, body: dict) -> None:
327
363
  elif status == "archived":
328
364
  if not _fenced(conn, task_id, lambda: kb.archive_task(conn, task_id), confirm_running_exit=confirm, releases_claim=False):
329
365
  raise NotFound("task not found")
330
- elif status == "running":
331
- raise InvalidParams("Cannot set status to 'running' directly; use the dispatcher/claim path")
332
- elif status == "ready":
366
+ else:
333
367
  current = kb.get_task(conn, task_id)
334
368
  if not current:
335
369
  raise NotFound("task not found")
336
- if current.status == "blocked":
337
- if not kb.unblock_task(conn, task_id):
338
- raise NotFound("task not found")
339
- elif not _set_status_direct(conn, task_id, "ready", confirm_running_exit=confirm):
340
- raise NotFound("task not found")
341
- elif status in ("triage", "todo"):
342
- if not _set_status_direct(conn, task_id, status, confirm_running_exit=confirm):
370
+ # Like the Agent's dashboard: leaving review reopens it, and blocked/scheduled -> ready unblocks; both re-gate on
371
+ # parents. Triage is a direct write there too. The reopen lands in ready whatever the target, so todo is refused.
372
+ if current.status == "review" and status == "todo":
373
+ raise Conflict("A task in review reopens to ready")
374
+ if current.status == "review" and status == "ready":
375
+ ok = kb.reopen_review_task(conn, task_id)
376
+ elif status == "ready" and current.status in ("blocked", "scheduled"):
377
+ ok = kb.unblock_task(conn, task_id)
378
+ else:
379
+ ok = _set_status_direct(conn, task_id, status, confirm_running_exit=confirm)
380
+ if not ok:
343
381
  raise NotFound("task not found")
344
382
 
345
383
 
@@ -373,15 +411,15 @@ def _board_counts(slug):
373
411
  pass
374
412
 
375
413
 
376
- def _normalize_existing_slug(slug) -> str:
414
+ def _normalize_existing_slug(slug, *, archived_ok: bool = False) -> str:
377
415
  kb = _kb()
378
416
  try:
379
417
  normed = kb._normalize_board_slug(slug)
380
418
  except (ValueError, AttributeError) as exc:
381
419
  raise InvalidParams(f"invalid board slug: {slug!r}") from exc
382
- if not normed or not kb.board_exists(normed):
420
+ if not normed:
383
421
  raise NotFound(f"board {slug!r} does not exist")
384
- return normed
422
+ return _live_board(kb, normed, slug, archived_ok=archived_ok)
385
423
 
386
424
 
387
425
  def _current_board() -> str:
@@ -449,9 +487,9 @@ def board_payload(params: dict) -> dict:
449
487
  data["comment_count"] = comment_counts.get(task.id, 0)
450
488
  return data
451
489
 
452
- columns = [{"name": name, "tasks": [row(t) for t in tasks if t.status == name]} for name in BOARD_COLUMNS]
490
+ columns = [{"name": key, "label": label, "tasks": [row(t) for t in tasks if t.status == key]} for key, label in _workflow().columns]
453
491
  if include_archived:
454
- columns.append({"name": "archived", "tasks": [row(t) for t in tasks if t.status == "archived"]})
492
+ columns.append({"name": "archived", "label": "Archived", "tasks": [row(t) for t in tasks if t.status == "archived"]})
455
493
  return {
456
494
  "columns": columns,
457
495
  "tenants": sorted({t.tenant for t in tasks if getattr(t, "tenant", None)}),
@@ -472,6 +510,8 @@ def create_task_payload(params: dict) -> dict:
472
510
  priority = int(body.get("priority") or 0)
473
511
  except (TypeError, ValueError):
474
512
  raise InvalidParams("priority must be an integer")
513
+ # Checked before the insert, so a refused status leaves no task behind.
514
+ status = _validate_status(body.get("status")) if body.get("status") else None
475
515
  kb = _kb()
476
516
  with _conn(board=_board(params)) as conn:
477
517
  task_id = kb.create_task(
@@ -480,8 +520,8 @@ def create_task_payload(params: dict) -> dict:
480
520
  workspace_kind=body.get("workspace_kind") or "scratch", workspace_path=body.get("workspace_path") or None,
481
521
  idempotency_key=body.get("idempotency_key") or None, max_runtime_seconds=body.get("max_runtime_seconds") or None, skills=body.get("skills") or None,
482
522
  )
483
- if body.get("status"):
484
- _patch_task(conn, task_id, {"status": body.get("status")})
523
+ if status:
524
+ _patch_task(conn, task_id, {"status": status})
485
525
  return {"task": _task_dict(kb.get_task(conn, task_id), conn), "read_only": False}
486
526
 
487
527
 
@@ -534,11 +574,17 @@ def task_detail_payload(params: dict) -> dict:
534
574
  task = kb.get_task(conn, task_id)
535
575
  if not task:
536
576
  raise NotFound("task not found")
577
+ data = _task_dict(task, conn)
578
+ # ``started_at`` is the first-ever start; a retried task's run clock counts from its current run (TAL-809).
579
+ data["current_run_started_at"] = kb.current_run_started_ats(conn, [task_id]).get(task_id)
580
+ links = {"parents": kb.parent_ids(conn, task_id), "children": kb.child_ids(conn, task_id)}
581
+ linked = (kb.get_task(conn, link_id) for link_id in dict.fromkeys([*links["parents"], *links["children"]]))
537
582
  return {
538
- "task": _task_dict(task, conn),
583
+ "task": data,
539
584
  "comments": [_obj_dict(c) for c in kb.list_comments(conn, task_id)],
540
585
  "events": [_obj_dict(e) for e in kb.list_events(conn, task_id)],
541
- "links": {"parents": kb.parent_ids(conn, task_id), "children": kb.child_ids(conn, task_id)},
586
+ "links": links,
587
+ "link_tasks": [{"id": t.id, "title": t.title, "status": t.status} for t in linked if t],
542
588
  "runs": [_obj_dict(r) for r in kb.list_runs(conn, task_id)],
543
589
  "read_only": False,
544
590
  }
@@ -547,6 +593,7 @@ def task_detail_payload(params: dict) -> dict:
547
593
  def events_payload(params: dict) -> dict:
548
594
  since = _int(params, "since", 0, minimum=0)
549
595
  limit = _int(params, "limit", 200, minimum=1, maximum=200)
596
+ kb = _kb()
550
597
  with _conn(board=_board(params)) as conn:
551
598
  rows = conn.execute(
552
599
  "SELECT id, task_id, run_id, kind, payload, created_at FROM task_events WHERE id > ? ORDER BY id ASC LIMIT ?", (since, limit)
@@ -557,7 +604,7 @@ def events_payload(params: dict) -> dict:
557
604
  payload = json.loads(row["payload"]) if row["payload"] else None
558
605
  except Exception: # noqa: BLE001
559
606
  payload = None
560
- events.append({"id": row["id"], "task_id": row["task_id"], "run_id": row["run_id"], "kind": row["kind"], "payload": payload, "created_at": row["created_at"]})
607
+ events.append({"id": row["id"], "task_id": row["task_id"], "run_id": row["run_id"], "kind": row["kind"], "payload": payload, "created_at": kb._to_epoch(row["created_at"])})
561
608
  cursor = int(row["id"])
562
609
  latest = _latest_event_id(conn)
563
610
  if not events:
@@ -583,13 +630,17 @@ def config_payload(params: dict) -> dict:
583
630
  cfg = {}
584
631
  k = ((cfg.get("dashboard") or {}).get("kanban") or {})
585
632
  return {
586
- "columns": BOARD_COLUMNS, "assignees": assignees, "default_tenant": k.get("default_tenant") or "",
633
+ "columns": _columns(), "assignees": assignees, "default_tenant": k.get("default_tenant") or "",
587
634
  "lane_by_profile": bool(k.get("lane_by_profile", True)), "include_archived_by_default": bool(k.get("include_archived_by_default", False)),
588
635
  "render_markdown": bool(k.get("render_markdown", True)), "read_only": False,
589
636
  }
590
637
 
591
638
 
592
639
  def stats_payload(params: dict) -> dict:
640
+ return {**_stats(params), "column_order": _columns()}
641
+
642
+
643
+ def _stats(params: dict) -> dict:
593
644
  kb = _kb()
594
645
  with _conn(board=_board(params)) as conn:
595
646
  if hasattr(kb, "board_stats"):
@@ -761,7 +812,8 @@ def create_board_payload(params: dict) -> dict:
761
812
  def update_board_payload(params: dict) -> dict:
762
813
  kb = _kb()
763
814
  body = params.get("board_spec") or {}
764
- normed = _normalize_existing_slug(params.get("slug"))
815
+ # Metadata edits stay open on an archived board: clearing ``archived`` is how one archived in place comes back.
816
+ normed = _normalize_existing_slug(params.get("slug"), archived_ok=True)
765
817
  kwargs = {}
766
818
  if "default_workdir" in body:
767
819
  kwargs["default_workdir"] = str(body.get("default_workdir") or "")
@@ -0,0 +1,84 @@
1
+ """``memory.*``: the Agent's ``MemoryStore`` reading of a memory page save (TAL-886) and its compare-and-write (TAL-784)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import errno
6
+ import hashlib
7
+ import os
8
+ import stat
9
+ import threading
10
+ from pathlib import Path
11
+
12
+ from ..errors import InvalidParams, RpcError
13
+ from ..home import profile_home_param, scoped_home
14
+ from ..rpc import CallContext
15
+
16
+ # Agents without the per-file lock helper: this sidecar's saves still run one at a time.
17
+ _SAVE_LOCK = threading.Lock()
18
+
19
+
20
+ def check(target: str, content: str) -> dict:
21
+ """``content``'s char count as the Agent's memory tool parses it, and the profile's limit for ``target``."""
22
+ from hermes_cli.config import load_config
23
+ from tools.memory_tool_store import ENTRY_DELIMITER, MemoryStore
24
+
25
+ mem = (load_config() or {}).get("memory") or {}
26
+ store = MemoryStore(**{key: int(mem[key]) for key in ("memory_char_limit", "user_char_limit") if mem.get(key) is not None})
27
+ # The store keeps each entry once (first occurrence wins), as its load and write paths do.
28
+ entries = list(dict.fromkeys(MemoryStore._parse_entries(content)))
29
+ return {"count": len(ENTRY_DELIMITER.join(entries)), "limit": store._char_limit(target)}
30
+
31
+
32
+ def _digest(path: Path) -> str | None:
33
+ """SHA-256 hex of the regular file at ``path`` (of no bytes when there is none), never following a link; None otherwise."""
34
+ try:
35
+ fd = os.open(path, os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0) | getattr(os, "O_NONBLOCK", 0))
36
+ except FileNotFoundError:
37
+ return hashlib.sha256(b"").hexdigest()
38
+ except OSError as exc:
39
+ if exc.errno == errno.ELOOP:
40
+ return None
41
+ raise
42
+ with os.fdopen(fd, "rb") as handle:
43
+ if not stat.S_ISREG(os.fstat(handle.fileno()).st_mode):
44
+ return None
45
+ return hashlib.sha256(handle.read()).hexdigest()
46
+
47
+
48
+ def write(home: Path, section: str, base: str, content: str) -> dict:
49
+ """Replace ``section``'s file with ``content`` only while its bytes still hash to ``base``, the server's read.
50
+
51
+ Each file is checked and written under the Agent's own per-file lock (``<file>.lock``), so neither a memory tool
52
+ call nor a concurrent save can land between the two; an Agent without the lock helper gets this sidecar's lock.
53
+ """
54
+ from tools.memory_tool_store import MemoryStore
55
+ from utils import atomic_write_text
56
+
57
+ if section not in ("memory", "user", "soul"):
58
+ raise InvalidParams("section must be memory, user, or soul")
59
+ # The files the server read: SOUL.md in the profile home, MEMORY.md / USER.md in its memories folder.
60
+ path = home / "SOUL.md" if section == "soul" else home / "memories" / ("USER.md" if section == "user" else "MEMORY.md")
61
+ file_lock = getattr(MemoryStore, "_file_lock", None)
62
+ try:
63
+ with file_lock(path) if file_lock else _SAVE_LOCK:
64
+ if _digest(path) != base:
65
+ return {"written": False}
66
+ atomic_write_text(path, content, tmp_prefix=".mem_", preserve_mode=True)
67
+ except OSError as exc:
68
+ if exc.errno not in (errno.EACCES, errno.EPERM, errno.EROFS):
69
+ raise
70
+ raise RpcError(f"{path.name} is not writable: {exc.strerror}", condition="memory_not_writable") from exc
71
+ return {"written": True}
72
+
73
+
74
+ def register(registry) -> None:
75
+ @registry.method("memory.check")
76
+ def check_(ctx: CallContext, params: dict) -> dict:
77
+ with scoped_home(profile_home_param(params)):
78
+ return check(str(params["target"]), str(params["content"]))
79
+
80
+ @registry.method("memory.write")
81
+ def write_(ctx: CallContext, params: dict) -> dict:
82
+ home = profile_home_param(params)
83
+ with scoped_home(home):
84
+ return write(home, str(params["section"]), str(params["base"]), str(params["content"]))
@@ -1,4 +1,5 @@
1
- """``oauth.*``: the Agent's device-code sign-ins for Nous Portal, OpenAI Codex, xAI and MiniMax (TAL-398).
1
+ """``oauth.*``: the Agent's device-code sign-ins for Nous Portal, OpenAI Codex, xAI and MiniMax (TAL-398), and the
2
+ browser sign-in of a plugin-declared OAuth client (``plugin:<key>:<id>``, TAL-1276, in ``plugin_oauth``).
2
3
 
3
4
  ``oauth.start`` asks the provider for a code and answers what the user has to see; a daemon thread then waits for the
4
5
  approval and saves the credential with the Agent's own auth-store helpers under the flow's profile home, the steps its
@@ -9,9 +10,12 @@ Flows live in this process only.
9
10
 
10
11
  from __future__ import annotations
11
12
 
13
+ import contextlib
14
+ import inspect
12
15
  import logging
13
16
  import os
14
17
  import secrets
18
+ import ssl
15
19
  import threading
16
20
  import time
17
21
  from dataclasses import dataclass, field
@@ -22,6 +26,7 @@ from typing import Any, Callable
22
26
  from ..errors import InvalidParams, RpcError
23
27
  from ..home import profile_home_param, scoped_home
24
28
  from ..rpc import CallContext
29
+ from . import plugin_oauth
25
30
 
26
31
  log = logging.getLogger("talaria_sidecar.oauth")
27
32
 
@@ -31,6 +36,8 @@ _CODEX_EXPIRES_IN = 15 * 60 # OpenAI's device-code lifetime, as the Agent dashb
31
36
  _ENDED_TTL = 10 * 60
32
37
  # A pending flow past its code's expiry by this much ends expired even if its provider call has not returned yet.
33
38
  _EXPIRY_GRACE = 60
39
+ # How long a start waits for the flows it replaces to close their loopback listeners.
40
+ _RELEASE_WAIT = 5.0
34
41
 
35
42
  _DENIED = "Sign-in was declined."
36
43
  _EXPIRED = "The sign-in code expired before it was approved."
@@ -55,6 +62,17 @@ class Flow:
55
62
  cancelled: threading.Event = field(default_factory=threading.Event)
56
63
  # Serialises the cancel check with the credential save: a cancel cannot land between them.
57
64
  lock: threading.Lock = field(default_factory=threading.Lock)
65
+ # The credential is saved but the sign-in has not finished (a guest sign-in still settles the account): a cancel or
66
+ # an expiry can no longer undo it, and the flow stays pending until its own ending.
67
+ committed: bool = False
68
+ # A browser sign-in also finishes from the redirect address the user pastes (``oauth.submit_redirect``).
69
+ submit: Callable[[str], None] | None = None
70
+ # Set once a browser sign-in's loopback listener is closed, so a replacing start can bind the same fixed port.
71
+ closed: threading.Event | None = None
72
+
73
+ @property
74
+ def stoppable(self) -> bool:
75
+ return self.status == "pending" and not self.committed
58
76
 
59
77
  def end(self, status: str, error: str | None = None) -> None:
60
78
  self.status, self.error, self.ended_at = status, error, time.time()
@@ -107,9 +125,24 @@ def _now_z() -> str:
107
125
 
108
126
 
109
127
  def _client(timeout: float, **kwargs: Any) -> Any:
128
+ """Every flow's HTTP client, verifying TLS as the Agent's own sign-in does: the OS trust store, and (v0.22.3+) a
129
+ certifi bundle an install-environment rotation deleted under this process, re-derived process-wide."""
110
130
  import httpx
111
131
 
112
- return httpx.Client(timeout=httpx.Timeout(timeout), headers={"Accept": "application/json"}, **kwargs)
132
+ return httpx.Client(timeout=httpx.Timeout(timeout), headers={"Accept": "application/json"}, verify=_verify(), **kwargs)
133
+
134
+
135
+ def _verify() -> Any:
136
+ try:
137
+ from agent.ssl_verify import resolve_httpx_verify
138
+ except ImportError: # an Agent without it keeps httpx's default
139
+ return True
140
+ verify = resolve_httpx_verify()
141
+ # The resolver hands over the platform store alone when SSL_CERT_FILE/SSL_CERT_DIR is set; httpx's default trusted
142
+ # that bundle, so keep it, on top of the platform store the resolver installed (as ``platform_ssl_context`` does).
143
+ cafile, capath = os.environ.get("SSL_CERT_FILE", "").strip(), os.environ.get("SSL_CERT_DIR", "").strip()
144
+ cafile, capath = (cafile if os.path.isfile(cafile) else None), (capath if os.path.isdir(capath) else None)
145
+ return ssl.create_default_context(cafile=cafile, capath=capath) if cafile or capath else verify
113
146
 
114
147
 
115
148
  # ── providers: (begin, wait, save) over the Agent's own steps ──────────
@@ -121,10 +154,14 @@ def _nous_begin() -> tuple[dict, dict]:
121
154
  from hermes_cli import anon_auth
122
155
  from hermes_cli.auth import PROVIDER_REGISTRY, _request_device_code
123
156
 
124
- if anon_auth.guest_enabled() and anon_auth.has_guest():
125
- # The free tier's sign-in moves its connectors to the account (``anon_auth.run_sign_in``); a plain device-code
126
- # sign-in here would orphan them.
127
- raise RpcError("This profile uses the Nous free tier. Sign in from Hermes with `hermes portal`.", condition="oauth_unsupported")
157
+ # v0.22.0 replaced ``guest_enabled`` with ``guest_allowed``; 0.21.x releases only have the former.
158
+ guest_gate = getattr(anon_auth, "guest_allowed", None) or getattr(anon_auth, "guest_enabled")
159
+ if guest_gate() and anon_auth.has_guest():
160
+ # The native sign-in owns the guest's connector handoff for its installed protocol.
161
+ if hasattr(anon_auth, "run_sign_in"):
162
+ return _nous_sign_in(anon_auth)
163
+ hint = getattr(anon_auth, "UPGRADE_HINT", None) or "Sign in from Hermes with `hermes auth upgrade`."
164
+ raise RpcError(f"This profile uses the Nous free tier. {hint}", condition="oauth_unsupported")
128
165
  pconfig = PROVIDER_REGISTRY["nous"]
129
166
  portal = (os.getenv("HERMES_PORTAL_BASE_URL") or os.getenv("NOUS_PORTAL_BASE_URL") or pconfig.portal_base_url).rstrip("/")
130
167
  with _client(15.0) as client:
@@ -133,7 +170,63 @@ def _nous_begin() -> tuple[dict, dict]:
133
170
  return display, {"portal": portal, "client_id": pconfig.client_id, "scope": pconfig.scope, "device_code": str(data["device_code"])}
134
171
 
135
172
 
173
+ def _nous_sign_in(anon_auth: Any) -> tuple[dict, dict]:
174
+ """Over a guest, the Agent's own sign-in (``anon_auth.run_sign_in``, as its dashboard runs it): it moves the guest's
175
+ connected apps to the account, then persists and settles the account itself. Its cancel check, persist guard and
176
+ home scope read the flow ``_nous_wait`` binds into the state; before that only ``start``'s first step runs, already
177
+ under the flow's home."""
178
+ state: dict = {}
179
+
180
+ def cancelled() -> bool:
181
+ flow = state.get("flow")
182
+ return flow is not None and flow.cancelled.is_set()
183
+
184
+ @contextlib.contextmanager
185
+ def persist_guard():
186
+ # As ``_run`` does for a plain save, the final cancel check and the save share the flow's lock; the flow ends
187
+ # approved only when the Agent has also settled the account, through ``_run``.
188
+ flow = state["flow"]
189
+ with flow.lock:
190
+ may_persist = flow.status == "pending"
191
+ yield may_persist
192
+ if may_persist:
193
+ flow.committed = True
194
+
195
+ def scope():
196
+ flow = state.get("flow")
197
+ return scoped_home(flow.home) if flow is not None else contextlib.nullcontext()
198
+
199
+ # Older Agents use promotion; v0.22.5 removed its option in favor of plain device login and native handoff.
200
+ options = {"cancel_wins_after_promotion": True} if "cancel_wins_after_promotion" in inspect.signature(anon_auth.run_sign_in).parameters else {}
201
+ sign_in = anon_auth.run_sign_in(cancelled=cancelled, persist_guard=persist_guard, scope=scope, **options)
202
+ first = next(sign_in)
203
+ if first.kind != "code":
204
+ sign_in.close()
205
+ raise RpcError(first.copy_terminal, condition="oauth_unsupported" if first.precondition else "oauth_failed")
206
+ state["sign_in"] = sign_in
207
+ return {"user_code": first.code, "verification_url": first.link, "expires_in": first.expires_in, "interval": first.interval}, state
208
+
209
+
210
+ class _SignInEnded(Exception):
211
+ """A guest sign-in that ended without an account; ``code`` lets ``_ending`` classify a decline and an expiry."""
212
+
213
+ def __init__(self, ended: Any):
214
+ super().__init__(ended.copy)
215
+ self.code = {"declined": "access_denied", "timed_out": "expired_token"}.get(ended.kind, ended.kind)
216
+
217
+
136
218
  def _nous_wait(flow: Flow, state: dict) -> dict:
219
+ sign_in = state.get("sign_in")
220
+ if sign_in is not None:
221
+ state["flow"] = flow
222
+ try:
223
+ for ended in sign_in: # the generator always ends on one terminal state
224
+ pass
225
+ finally:
226
+ sign_in.close()
227
+ if not ended.ok:
228
+ raise _SignInEnded(ended)
229
+ return {}
137
230
  from hermes_cli.auth import _poll_for_token
138
231
 
139
232
  with _client(15.0) as client:
@@ -142,6 +235,8 @@ def _nous_wait(flow: Flow, state: dict) -> dict:
142
235
 
143
236
 
144
237
  def _nous_save(flow: Flow, state: dict, token_data: dict) -> None:
238
+ if "sign_in" in state: # the guest sign-in persisted and settled the account itself
239
+ return
145
240
  from hermes_cli import anon_auth
146
241
  from hermes_cli.auth import persist_nous_credentials, refresh_nous_oauth_from_state
147
242
 
@@ -210,8 +305,10 @@ def _codex_save(flow: Flow, state: dict, tokens: dict) -> None:
210
305
  def _xai_begin() -> tuple[dict, dict]:
211
306
  from hermes_cli.auth import _xai_oauth_discovery, _xai_oauth_request_device_code
212
307
 
213
- discovery = _xai_oauth_discovery(20.0)
214
308
  with _client(20.0) as client:
309
+ # The Agent's discovery is a bare ``httpx.get``: building the client first gives it the platform store and a
310
+ # certifi re-derived after a rotation.
311
+ discovery = _xai_oauth_discovery(20.0)
215
312
  data = _xai_oauth_request_device_code(client)
216
313
  display = {"user_code": str(data["user_code"]), "verification_url": str(data.get("verification_uri_complete") or data["verification_uri"]),
217
314
  "expires_in": int(data["expires_in"]), "interval": int(data["interval"])}
@@ -320,9 +417,16 @@ def _run(flow: Flow, wait: Callable[[Flow, dict], dict], save: Callable[[Flow, d
320
417
  log.info("oauth: %s sign-in ended %s (flow=%s)", flow.provider, flow.status, flow.flow_id[:6])
321
418
 
322
419
 
420
+ def _discard(state: dict) -> None:
421
+ """Releases a begun sign-in that is never published: a guest sign-in's generator holds its HTTP client."""
422
+ if "sign_in" in state:
423
+ state["sign_in"].close()
424
+ plugin_oauth.discard(state)
425
+
426
+
323
427
  def _cancel(flow: Flow) -> None:
324
428
  with flow.lock:
325
- if flow.status == "pending":
429
+ if flow.stoppable:
326
430
  flow.cancelled.set()
327
431
  flow.end("cancelled")
328
432
 
@@ -354,7 +458,7 @@ def _pending(home: Path, provider: str) -> list[Flow]:
354
458
 
355
459
 
356
460
  def start(home: Path, provider: str, *, providers: dict[str, Provider] | None = None) -> dict:
357
- steps = (providers or PROVIDERS).get(provider)
461
+ steps = (providers or PROVIDERS).get(provider) or plugin_oauth.steps(provider)
358
462
  if steps is None:
359
463
  raise InvalidParams(f"{provider} has no device-code sign-in")
360
464
  begin, wait, save = steps
@@ -366,6 +470,11 @@ def start(home: Path, provider: str, *, providers: dict[str, Provider] | None =
366
470
  # old code that lands while the provider answers can no longer save.
367
471
  for old in _pending(home, provider):
368
472
  _cancel(old)
473
+ # A cancelled browser sign-in closes its listener from its own thread; a fixed redirect port is free only after that.
474
+ with _FLOWS_LOCK:
475
+ listening = [f for f in _FLOWS.values() if f.provider == provider and f.closed is not None and not f.closed.is_set() and _same_home(f.home, home)]
476
+ for old in listening:
477
+ old.closed.wait(_RELEASE_WAIT)
369
478
  try:
370
479
  with scoped_home(home):
371
480
  display, state = begin()
@@ -376,11 +485,13 @@ def start(home: Path, provider: str, *, providers: dict[str, Provider] | None =
376
485
  raise RpcError(_first_line(exc), condition="oauth_failed") from exc
377
486
  if not str(display["verification_url"]).lower().startswith(("https://", "http://")):
378
487
  # The browser opens this link: anything but a web address is refused before a flow exists.
488
+ _discard(state)
379
489
  raise RpcError("The provider answered an invalid sign-in link.", condition="oauth_failed")
380
- flow = Flow(secrets.token_urlsafe(16), provider, home, time.time() + int(display["expires_in"]), max(1, int(display["interval"])))
490
+ flow = Flow(secrets.token_urlsafe(16), provider, home, time.time() + int(display["expires_in"]), max(1, int(display["interval"])), submit=state.get("submit"), closed=state.get("closed"))
381
491
  with _FLOWS_LOCK:
382
492
  if _GENERATIONS.get(key) != generation:
383
493
  # A newer start for this home and provider began while this one waited on the provider: it owns the sign-in.
494
+ _discard(state)
384
495
  raise RpcError("A newer sign-in for this provider replaced this one.", condition="oauth_superseded")
385
496
  superseded = [f for f in _FLOWS.values() if f.provider == provider and f.status == "pending" and _same_home(f.home, home)]
386
497
  _FLOWS[flow.flow_id] = flow
@@ -400,10 +511,10 @@ def _flow(home: Path, flow_id: str) -> Flow:
400
511
 
401
512
  def poll(home: Path, flow_id: str) -> dict:
402
513
  flow = _flow(home, flow_id)
403
- if flow.status == "pending" and time.time() > flow.expires_at + _EXPIRY_GRACE:
514
+ if flow.stoppable and time.time() > flow.expires_at + _EXPIRY_GRACE:
404
515
  # The provider call outlived its code: end it now, and a late approval can no longer save.
405
516
  with flow.lock:
406
- if flow.status == "pending":
517
+ if flow.stoppable:
407
518
  flow.cancelled.set()
408
519
  flow.end("expired", _EXPIRED)
409
520
  return flow.view()
@@ -415,6 +526,18 @@ def cancel(home: Path, flow_id: str) -> dict:
415
526
  return flow.view()
416
527
 
417
528
 
529
+ def submit_redirect(home: Path, flow_id: str, url: str) -> dict:
530
+ """Finish a browser sign-in with the address its redirect reached, when the browser runs on another machine."""
531
+ flow = _flow(home, flow_id)
532
+ if flow.submit is None:
533
+ raise InvalidParams("This sign-in takes no redirect address.")
534
+ with flow.lock:
535
+ if not flow.stoppable or time.time() >= flow.expires_at:
536
+ raise RpcError("This sign-in already ended.", condition="oauth_flow_ended")
537
+ flow.submit(url)
538
+ return flow.view()
539
+
540
+
418
541
  def _flow_id(params: dict) -> str:
419
542
  flow_id = str(params.get("flow_id") or "").strip()
420
543
  if not flow_id:
@@ -425,7 +548,8 @@ def _flow_id(params: dict) -> str:
425
548
  def register(reg) -> None:
426
549
  @reg.method("oauth.start")
427
550
  def start_(ctx: CallContext, params: dict) -> dict:
428
- provider = str(params.get("provider") or "").strip().lower()
551
+ provider = str(params.get("provider") or "").strip()
552
+ provider = provider if provider.startswith(plugin_oauth.PREFIX) else provider.lower()
429
553
  if not provider:
430
554
  raise InvalidParams("provider is required")
431
555
  return start(profile_home_param(params), provider)
@@ -437,3 +561,10 @@ def register(reg) -> None:
437
561
  @reg.method("oauth.cancel", requires_agent=False)
438
562
  def cancel_(ctx: CallContext, params: dict) -> dict:
439
563
  return cancel(profile_home_param(params), _flow_id(params))
564
+
565
+ @reg.method("oauth.submit_redirect", requires_agent=False)
566
+ def submit_(ctx: CallContext, params: dict) -> dict:
567
+ url = str(params.get("url") or "").strip()
568
+ if not url:
569
+ raise InvalidParams("url is required")
570
+ return submit_redirect(profile_home_param(params), _flow_id(params), url)