agor-live 0.17.2 → 0.17.3

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 (316) hide show
  1. package/dist/cli/lib/banner.d.ts +1 -1
  2. package/dist/cli/lib/banner.js +1 -1
  3. package/dist/cli/lib/check-migrations.test.js +9627 -9112
  4. package/dist/cli/lib/daemon-manager.test.js +9632 -9117
  5. package/dist/cli/lib/help.js +1 -1
  6. package/dist/core/api/index.d.cts +3 -3
  7. package/dist/core/api/index.d.ts +3 -3
  8. package/dist/core/{board-comment-DIdOJrSF.d.cts → board-comment-CCFVVN7K.d.cts} +0 -2
  9. package/dist/core/{board-comment-3N-jSgsk.d.ts → board-comment-iT3DgZb4.d.ts} +0 -2
  10. package/dist/core/claude/index.cjs +29 -19
  11. package/dist/core/claude/index.d.cts +2 -2
  12. package/dist/core/claude/index.d.ts +2 -2
  13. package/dist/core/claude/index.js +32 -33
  14. package/dist/core/client/index.cjs +49 -0
  15. package/dist/core/client/index.d.cts +7 -7
  16. package/dist/core/client/index.d.ts +7 -7
  17. package/dist/core/client/index.js +46 -0
  18. package/dist/core/{client-B5PyIvNc.d.cts → client-CemqXk0v.d.cts} +116 -100
  19. package/dist/core/{client-C1CsRi19.d.ts → client-uYEOha6g.d.ts} +116 -100
  20. package/dist/core/config/browser.d.cts +3 -3
  21. package/dist/core/config/browser.d.ts +3 -3
  22. package/dist/core/config/index.cjs +84 -41
  23. package/dist/core/config/index.d.cts +59 -17
  24. package/dist/core/config/index.d.ts +59 -17
  25. package/dist/core/config/index.js +86 -55
  26. package/dist/core/{config-manager-TxxjFMRd.d.cts → config-manager-B8TP9Kz0.d.cts} +12 -3
  27. package/dist/core/{config-manager-DTrsj6G3.d.ts → config-manager-CDEB0FY4.d.ts} +12 -3
  28. package/dist/core/{config-services-YEZ4DwCD.d.cts → config-services-CXyQKEK5.d.cts} +1 -1
  29. package/dist/core/{config-services-DcO2GRgh.d.ts → config-services-DhM7_yWn.d.ts} +1 -1
  30. package/dist/core/db/index.cjs +235 -175
  31. package/dist/core/db/index.d.cts +190 -147
  32. package/dist/core/db/index.d.ts +190 -147
  33. package/dist/core/db/index.js +239 -190
  34. package/dist/core/db/session-guard.d.cts +4 -4
  35. package/dist/core/db/session-guard.d.ts +4 -4
  36. package/dist/core/drizzle/postgres/0028_queued_tasks.sql +8 -0
  37. package/dist/core/drizzle/postgres/0030_migrate_queued_messages.sql +24 -0
  38. package/dist/core/drizzle/postgres/0031_restructure_agentic_tool_config.sql +201 -0
  39. package/dist/core/drizzle/postgres/meta/_journal.json +21 -0
  40. package/dist/core/drizzle/sqlite/0039_queued_tasks.sql +13 -0
  41. package/dist/core/drizzle/sqlite/0040_migrate_queued_messages.sql +61 -0
  42. package/dist/core/drizzle/sqlite/0041_restructure_agentic_tool_config.sql +204 -0
  43. package/dist/core/drizzle/sqlite/meta/_journal.json +21 -0
  44. package/dist/core/gateway/index.d.cts +2 -2
  45. package/dist/core/gateway/index.d.ts +2 -2
  46. package/dist/core/{gateway-BnOlAelY.d.cts → gateway-BWq4j_Ll.d.cts} +1 -1
  47. package/dist/core/{gateway-B_4X-v07.d.ts → gateway-C3Jm_akw.d.ts} +1 -1
  48. package/dist/core/git/index.d.cts +4 -4
  49. package/dist/core/git/index.d.ts +4 -4
  50. package/dist/core/index.cjs +474 -201
  51. package/dist/core/index.d.cts +12 -10
  52. package/dist/core/index.d.ts +12 -10
  53. package/dist/core/index.js +473 -216
  54. package/dist/core/lib/feathers-validation.cjs +2 -1
  55. package/dist/core/lib/feathers-validation.d.cts +1 -1
  56. package/dist/core/lib/feathers-validation.d.ts +1 -1
  57. package/dist/core/lib/feathers-validation.js +2 -1
  58. package/dist/core/mcp/index.cjs +26 -16
  59. package/dist/core/mcp/index.js +26 -16
  60. package/dist/core/{message-DinITA7a.d.cts → message-CSWOsdcZ.d.cts} +1 -9
  61. package/dist/core/{message-CHUUP6OS.d.ts → message-DZa8g0s0.d.ts} +1 -9
  62. package/dist/core/models/index.d.cts +3 -73
  63. package/dist/core/models/index.d.ts +3 -73
  64. package/dist/core/package.json +5 -0
  65. package/dist/core/permissions/index.d.cts +1 -1
  66. package/dist/core/permissions/index.d.ts +1 -1
  67. package/dist/core/resolve-config-BcL-Hv8k.d.ts +74 -0
  68. package/dist/core/resolve-config-DTCxuSBx.d.cts +74 -0
  69. package/dist/core/seed/index.cjs +145 -98
  70. package/dist/core/seed/index.js +148 -112
  71. package/dist/core/{session-guard-C0LkDEN7.d.ts → session-guard-BFqVtBoS.d.ts} +1 -1
  72. package/dist/core/{session-guard-kvAx_8Fb.d.cts → session-guard-KHh0cnET.d.cts} +1 -1
  73. package/dist/core/sessions/index.cjs +184 -0
  74. package/dist/core/sessions/index.d.cts +79 -0
  75. package/dist/core/sessions/index.d.ts +79 -0
  76. package/dist/core/sessions/index.js +157 -0
  77. package/dist/core/{task-BLPFCORT.d.ts → task-BHV-YHg1.d.ts} +41 -3
  78. package/dist/core/{task-wht1RJEL.d.cts → task-C2Hy7H6u.d.cts} +41 -3
  79. package/dist/core/templates/session-context.d.cts +1 -1
  80. package/dist/core/templates/session-context.d.ts +1 -1
  81. package/dist/core/tools/mcp/oauth-mcp-transport.cjs +168 -66
  82. package/dist/core/tools/mcp/oauth-mcp-transport.d.cts +92 -16
  83. package/dist/core/tools/mcp/oauth-mcp-transport.d.ts +92 -16
  84. package/dist/core/tools/mcp/oauth-mcp-transport.js +165 -66
  85. package/dist/core/tools/mcp/oauth-refresh.cjs +43 -53
  86. package/dist/core/tools/mcp/oauth-refresh.d.cts +3 -3
  87. package/dist/core/tools/mcp/oauth-refresh.d.ts +3 -3
  88. package/dist/core/tools/mcp/oauth-refresh.js +58 -78
  89. package/dist/core/types/index.cjs +49 -0
  90. package/dist/core/types/index.d.cts +7 -7
  91. package/dist/core/types/index.d.ts +7 -7
  92. package/dist/core/types/index.js +46 -0
  93. package/dist/core/{types-DNqfdt1z.d.cts → types-D4Rl6ZKN.d.cts} +18 -2
  94. package/dist/core/{types-DqPMmTad.d.ts → types-n61iaXub.d.ts} +18 -2
  95. package/dist/core/unix/index.cjs +164 -110
  96. package/dist/core/unix/index.d.cts +7 -8
  97. package/dist/core/unix/index.d.ts +7 -8
  98. package/dist/core/unix/index.js +167 -124
  99. package/dist/core/{user-DkNdeFoz.d.cts → user-CpfkcV2C.d.cts} +139 -13
  100. package/dist/core/{user-BfVWBmXA.d.ts → user-DP-XZMIM.d.ts} +139 -13
  101. package/dist/core/utils/permission-mode-mapper.d.cts +0 -2
  102. package/dist/core/utils/permission-mode-mapper.d.ts +0 -2
  103. package/dist/daemon/index.js +2976 -2791
  104. package/dist/daemon/main.js +2976 -2791
  105. package/dist/daemon/mcp/server.js +177 -134
  106. package/dist/daemon/mcp/tools/analytics.js +19 -5
  107. package/dist/daemon/mcp/tools/artifacts.js +19 -5
  108. package/dist/daemon/mcp/tools/boards.js +19 -5
  109. package/dist/daemon/mcp/tools/card-types.js +19 -5
  110. package/dist/daemon/mcp/tools/cards.js +19 -5
  111. package/dist/daemon/mcp/tools/environment.js +19 -5
  112. package/dist/daemon/mcp/tools/mcp-servers.d.ts +29 -2
  113. package/dist/daemon/mcp/tools/mcp-servers.js +64 -54
  114. package/dist/daemon/mcp/tools/messages.js +19 -5
  115. package/dist/daemon/mcp/tools/repos.js +19 -5
  116. package/dist/daemon/mcp/tools/search.js +19 -5
  117. package/dist/daemon/mcp/tools/sessions.js +175 -53
  118. package/dist/daemon/mcp/tools/tasks.js +19 -5
  119. package/dist/daemon/mcp/tools/users.js +19 -5
  120. package/dist/daemon/mcp/tools/worktrees.js +37 -38
  121. package/dist/daemon/register-hooks.js +52 -1
  122. package/dist/daemon/register-routes.js +436 -424
  123. package/dist/daemon/register-services.js +255 -140
  124. package/dist/daemon/services/config.d.ts +7 -1
  125. package/dist/daemon/services/config.js +3 -2
  126. package/dist/daemon/services/gateway.js +28 -15
  127. package/dist/daemon/services/mcp-servers.d.ts +7 -2
  128. package/dist/daemon/services/repos.js +2 -0
  129. package/dist/daemon/services/sessions.d.ts +1 -1
  130. package/dist/daemon/services/sessions.js +8 -16
  131. package/dist/daemon/services/tasks.js +16 -10
  132. package/dist/daemon/services/terminals.js +2 -0
  133. package/dist/daemon/services/users.d.ts +27 -11
  134. package/dist/daemon/services/users.js +89 -43
  135. package/dist/daemon/services/worktree-owners.js +2 -0
  136. package/dist/daemon/services/worktrees.js +2 -0
  137. package/dist/daemon/setup/index.js +5 -2
  138. package/dist/daemon/setup/socketio.d.ts +10 -1
  139. package/dist/daemon/setup/socketio.js +7 -3
  140. package/dist/daemon/startup.js +13 -1
  141. package/dist/daemon/utils/apply-session-config-defaults.d.ts +54 -0
  142. package/dist/daemon/utils/apply-session-config-defaults.js +46 -0
  143. package/dist/daemon/utils/spawn-executor.js +2 -0
  144. package/dist/daemon/utils/worktree-authorization.d.ts +2 -4
  145. package/dist/executor/commands/zellij.d.ts.map +1 -1
  146. package/dist/executor/commands/zellij.js +2 -2
  147. package/dist/executor/handlers/sdk/base-executor.d.ts +4 -3
  148. package/dist/executor/handlers/sdk/base-executor.d.ts.map +1 -1
  149. package/dist/executor/handlers/sdk/base-executor.js +11 -5
  150. package/dist/executor/payload-types.d.ts +14 -14
  151. package/dist/executor/sdk-handlers/claude/claude-tool.d.ts.map +1 -1
  152. package/dist/executor/sdk-handlers/claude/claude-tool.js +9 -4
  153. package/dist/executor/sdk-handlers/claude/import/task-extractor.d.ts.map +1 -1
  154. package/dist/executor/sdk-handlers/claude/import/task-extractor.js +0 -5
  155. package/dist/executor/sdk-handlers/claude/message-builder.d.ts +23 -2
  156. package/dist/executor/sdk-handlers/claude/message-builder.d.ts.map +1 -1
  157. package/dist/executor/sdk-handlers/claude/message-builder.js +33 -2
  158. package/dist/executor/sdk-handlers/claude/permissions/permission-hooks.d.ts +9 -1
  159. package/dist/executor/sdk-handlers/claude/permissions/permission-hooks.d.ts.map +1 -1
  160. package/dist/executor/sdk-handlers/claude/permissions/permission-hooks.js +12 -0
  161. package/dist/executor/sdk-handlers/claude/query-builder.d.ts.map +1 -1
  162. package/dist/executor/sdk-handlers/claude/query-builder.js +11 -6
  163. package/dist/executor/sdk-handlers/codex/codex-tool.d.ts +0 -5
  164. package/dist/executor/sdk-handlers/codex/codex-tool.d.ts.map +1 -1
  165. package/dist/executor/sdk-handlers/codex/codex-tool.js +9 -24
  166. package/dist/executor/sdk-handlers/codex/prompt-service.d.ts +15 -2
  167. package/dist/executor/sdk-handlers/codex/prompt-service.d.ts.map +1 -1
  168. package/dist/executor/sdk-handlers/codex/prompt-service.js +39 -10
  169. package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts +0 -5
  170. package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts.map +1 -1
  171. package/dist/executor/sdk-handlers/copilot/copilot-tool.js +5 -22
  172. package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts +0 -5
  173. package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts.map +1 -1
  174. package/dist/executor/sdk-handlers/gemini/gemini-tool.js +9 -24
  175. package/dist/ui/assets/{CodeEditor.inner-CO-5PAnZ.js → CodeEditor.inner-CVLqZBtM.js} +1 -1
  176. package/dist/ui/assets/{CodeEditor.inner-CO-5PAnZ.js.gz → CodeEditor.inner-CVLqZBtM.js.gz} +0 -0
  177. package/dist/ui/assets/{_basePickBy-DfxojsEt.js → _basePickBy-CFq5ES2J.js} +1 -1
  178. package/dist/ui/assets/_basePickBy-CFq5ES2J.js.gz +0 -0
  179. package/dist/ui/assets/{_baseUniq-DWFPJOTC.js → _baseUniq-C4uKBvNt.js} +1 -1
  180. package/dist/ui/assets/_baseUniq-C4uKBvNt.js.gz +0 -0
  181. package/dist/ui/assets/{arc-vMZ_XGSI.js → arc-BnrcXDJJ.js} +1 -1
  182. package/dist/ui/assets/arc-BnrcXDJJ.js.gz +0 -0
  183. package/dist/ui/assets/{architectureDiagram-VXUJARFQ-DGpk_uOD.js → architectureDiagram-VXUJARFQ-DD9HD-WR.js} +1 -1
  184. package/dist/ui/assets/architectureDiagram-VXUJARFQ-DD9HD-WR.js.gz +0 -0
  185. package/dist/ui/assets/{base-80a1f760-BsVlOKqO.js → base-80a1f760-BK1VmxWU.js} +1 -1
  186. package/dist/ui/assets/{blockDiagram-VD42YOAC-BkRnxc94.js → blockDiagram-VD42YOAC-LBAckZZe.js} +1 -1
  187. package/dist/ui/assets/blockDiagram-VD42YOAC-LBAckZZe.js.gz +0 -0
  188. package/dist/ui/assets/{c4Diagram-YG6GDRKO-Dcf-anJy.js → c4Diagram-YG6GDRKO-yEdylcYP.js} +1 -1
  189. package/dist/ui/assets/{c4Diagram-YG6GDRKO-Dcf-anJy.js.gz → c4Diagram-YG6GDRKO-yEdylcYP.js.gz} +0 -0
  190. package/dist/ui/assets/channel-CMN-iY3Q.js +1 -0
  191. package/dist/ui/assets/{chunk-4BX2VUAB-C4oVWDo8.js → chunk-4BX2VUAB-IHtzKbmQ.js} +1 -1
  192. package/dist/ui/assets/{chunk-55IACEB6-CsBbTu57.js → chunk-55IACEB6-C4o5tv_F.js} +1 -1
  193. package/dist/ui/assets/{chunk-B4BG7PRW-DtkeCZab.js → chunk-B4BG7PRW-EPkzLvlB.js} +1 -1
  194. package/dist/ui/assets/chunk-B4BG7PRW-EPkzLvlB.js.gz +0 -0
  195. package/dist/ui/assets/{chunk-DI55MBZ5-BQ_asW-1.js → chunk-DI55MBZ5-CW-Bzkzj.js} +1 -1
  196. package/dist/ui/assets/chunk-DI55MBZ5-CW-Bzkzj.js.gz +0 -0
  197. package/dist/ui/assets/{chunk-FMBD7UC4-DAdcLNG-.js → chunk-FMBD7UC4-DvGU02Io.js} +1 -1
  198. package/dist/ui/assets/{chunk-QN33PNHL-Do2zad3m.js → chunk-QN33PNHL-C-PIlz9n.js} +1 -1
  199. package/dist/ui/assets/{chunk-QZHKN3VN-CyhMmSdC.js → chunk-QZHKN3VN-BhpJFm6h.js} +1 -1
  200. package/dist/ui/assets/{chunk-TZMSLE5B-DlPypnIq.js → chunk-TZMSLE5B-Biake8IU.js} +1 -1
  201. package/dist/ui/assets/chunk-TZMSLE5B-Biake8IU.js.gz +0 -0
  202. package/dist/ui/assets/classDiagram-2ON5EDUG-Bz1et8oA.js +1 -0
  203. package/dist/ui/assets/classDiagram-v2-WZHVMYZB-Bz1et8oA.js +1 -0
  204. package/dist/ui/assets/clone-Dxo5sEAf.js +1 -0
  205. package/dist/ui/assets/{consoleHook-59e792cb-DHYIclEd.js → consoleHook-59e792cb-BzEkHWE8.js} +1 -1
  206. package/dist/ui/assets/consoleHook-59e792cb-BzEkHWE8.js.gz +0 -0
  207. package/dist/ui/assets/{cose-bilkent-S5V4N54A-DotJH9qH.js → cose-bilkent-S5V4N54A-vAiVi74s.js} +1 -1
  208. package/dist/ui/assets/cose-bilkent-S5V4N54A-vAiVi74s.js.gz +0 -0
  209. package/dist/ui/assets/{dagre-6UL2VRFP-Btssr8QF.js → dagre-6UL2VRFP-C8w7TshD.js} +1 -1
  210. package/dist/ui/assets/dagre-6UL2VRFP-C8w7TshD.js.gz +0 -0
  211. package/dist/ui/assets/{diagram-PSM6KHXK-D5_Jkog3.js → diagram-PSM6KHXK-CvnjEmtQ.js} +1 -1
  212. package/dist/ui/assets/diagram-PSM6KHXK-CvnjEmtQ.js.gz +0 -0
  213. package/dist/ui/assets/{diagram-QEK2KX5R-DlPEVSL5.js → diagram-QEK2KX5R-D245unng.js} +1 -1
  214. package/dist/ui/assets/diagram-QEK2KX5R-D245unng.js.gz +0 -0
  215. package/dist/ui/assets/{diagram-S2PKOQOG-CjO1k8aG.js → diagram-S2PKOQOG-DgGUHL8Z.js} +1 -1
  216. package/dist/ui/assets/diagram-S2PKOQOG-DgGUHL8Z.js.gz +0 -0
  217. package/dist/ui/assets/{erDiagram-Q2GNP2WA-3cO02-K3.js → erDiagram-Q2GNP2WA-Cf5paK9b.js} +1 -1
  218. package/dist/ui/assets/erDiagram-Q2GNP2WA-Cf5paK9b.js.gz +0 -0
  219. package/dist/ui/assets/{flowDiagram-NV44I4VS-CajTpSxI.js → flowDiagram-NV44I4VS-BJpHmEXV.js} +1 -1
  220. package/dist/ui/assets/flowDiagram-NV44I4VS-BJpHmEXV.js.gz +0 -0
  221. package/dist/ui/assets/{ganttDiagram-LVOFAZNH-CnY_bV3o.js → ganttDiagram-LVOFAZNH-zOyTZcXC.js} +1 -1
  222. package/dist/ui/assets/{ganttDiagram-LVOFAZNH-CnY_bV3o.js.gz → ganttDiagram-LVOFAZNH-zOyTZcXC.js.gz} +0 -0
  223. package/dist/ui/assets/{gitGraphDiagram-NY62KEGX-CH16bg-j.js → gitGraphDiagram-NY62KEGX-B0uxwqMv.js} +1 -1
  224. package/dist/ui/assets/gitGraphDiagram-NY62KEGX-B0uxwqMv.js.gz +0 -0
  225. package/dist/ui/assets/{graph-IQoZvE3o.js → graph-NWXc73TO.js} +1 -1
  226. package/dist/ui/assets/graph-NWXc73TO.js.gz +0 -0
  227. package/dist/ui/assets/{index-599aeaf7-RUCkgwsg.js → index-599aeaf7-BKmNqoNF.js} +1 -1
  228. package/dist/ui/assets/index-599aeaf7-BKmNqoNF.js.gz +0 -0
  229. package/dist/ui/assets/{index-B3AvIgqP.js → index-BRYNiHLB.js} +345 -349
  230. package/dist/ui/assets/index-BRYNiHLB.js.gz +0 -0
  231. package/dist/ui/assets/{index-QV5-5yA2.js → index-BX6Xmhes.js} +1 -1
  232. package/dist/ui/assets/index-BX6Xmhes.js.gz +0 -0
  233. package/dist/ui/assets/{index-ChmRuj_T.js → index-W1hIq1uU.js} +1 -1
  234. package/dist/ui/assets/index-W1hIq1uU.js.gz +0 -0
  235. package/dist/ui/assets/{index-C-quzPWC.js → index-ctuok0zf.js} +1 -1
  236. package/dist/ui/assets/index-ctuok0zf.js.gz +0 -0
  237. package/dist/ui/assets/{infoDiagram-ER5ION4S-2e4gZVGT.js → infoDiagram-ER5ION4S-CquCuoTH.js} +1 -1
  238. package/dist/ui/assets/{journeyDiagram-XKPGCS4Q-B5bgV3GH.js → journeyDiagram-XKPGCS4Q-B_XkufZ8.js} +1 -1
  239. package/dist/ui/assets/journeyDiagram-XKPGCS4Q-B_XkufZ8.js.gz +0 -0
  240. package/dist/ui/assets/{kanban-definition-3W4ZIXB7-Bp-aWRSc.js → kanban-definition-3W4ZIXB7-C2Bo9HkB.js} +1 -1
  241. package/dist/ui/assets/kanban-definition-3W4ZIXB7-C2Bo9HkB.js.gz +0 -0
  242. package/dist/ui/assets/katex-C6wkUDai.css +1 -0
  243. package/dist/ui/assets/{katex-DGRguze2.css.gz → katex-C6wkUDai.css.gz} +0 -0
  244. package/dist/ui/assets/{layout-BH-2XJZq.js → layout-D9A7Uaku.js} +1 -1
  245. package/dist/ui/assets/layout-D9A7Uaku.js.gz +0 -0
  246. package/dist/ui/assets/{linear-DCYXhl_f.js → linear-BJUwJsxE.js} +1 -1
  247. package/dist/ui/assets/linear-BJUwJsxE.js.gz +0 -0
  248. package/dist/ui/assets/{mermaid.core-BAuL6kgQ.js → mermaid.core-DcOEcjcA.js} +5 -5
  249. package/dist/ui/assets/mermaid.core-DcOEcjcA.js.gz +0 -0
  250. package/dist/ui/assets/{mindmap-definition-VGOIOE7T-DpH5N-N0.js → mindmap-definition-VGOIOE7T-BFT1m7BG.js} +1 -1
  251. package/dist/ui/assets/mindmap-definition-VGOIOE7T-BFT1m7BG.js.gz +0 -0
  252. package/dist/ui/assets/{pieDiagram-ADFJNKIX-BB8fBxj1.js → pieDiagram-ADFJNKIX-BFaX1oBV.js} +1 -1
  253. package/dist/ui/assets/pieDiagram-ADFJNKIX-BFaX1oBV.js.gz +0 -0
  254. package/dist/ui/assets/{quadrantDiagram-AYHSOK5B-D6oZLdUD.js → quadrantDiagram-AYHSOK5B-DQps5392.js} +1 -1
  255. package/dist/ui/assets/quadrantDiagram-AYHSOK5B-DQps5392.js.gz +0 -0
  256. package/dist/ui/assets/{requirementDiagram-UZGBJVZJ-B4uGPp8w.js → requirementDiagram-UZGBJVZJ-3EZ5KWEi.js} +1 -1
  257. package/dist/ui/assets/requirementDiagram-UZGBJVZJ-3EZ5KWEi.js.gz +0 -0
  258. package/dist/ui/assets/{sankeyDiagram-TZEHDZUN-MXhIjhme.js → sankeyDiagram-TZEHDZUN-D0qcydqq.js} +1 -1
  259. package/dist/ui/assets/sankeyDiagram-TZEHDZUN-D0qcydqq.js.gz +0 -0
  260. package/dist/ui/assets/{sequenceDiagram-WL72ISMW-Cm53TYug.js → sequenceDiagram-WL72ISMW-BCR5gaaN.js} +1 -1
  261. package/dist/ui/assets/sequenceDiagram-WL72ISMW-BCR5gaaN.js.gz +0 -0
  262. package/dist/ui/assets/{stateDiagram-FKZM4ZOC-BVuxUkj5.js → stateDiagram-FKZM4ZOC-BvX4FLQ9.js} +1 -1
  263. package/dist/ui/assets/stateDiagram-FKZM4ZOC-BvX4FLQ9.js.gz +0 -0
  264. package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-CxLDvgTF.js +1 -0
  265. package/dist/ui/assets/{timeline-definition-IT6M3QCI-CMypNiEP.js → timeline-definition-IT6M3QCI-_AWp5LJn.js} +1 -1
  266. package/dist/ui/assets/timeline-definition-IT6M3QCI-_AWp5LJn.js.gz +0 -0
  267. package/dist/ui/assets/{treemap-KMMF4GRG-BEtnV3BT.js → treemap-KMMF4GRG-BZ9FBl5-.js} +1 -1
  268. package/dist/ui/assets/treemap-KMMF4GRG-BZ9FBl5-.js.gz +0 -0
  269. package/dist/ui/assets/{xychartDiagram-PRI3JC2R-BnioEYUM.js → xychartDiagram-PRI3JC2R-_wB7yuVd.js} +1 -1
  270. package/dist/ui/assets/xychartDiagram-PRI3JC2R-_wB7yuVd.js.gz +0 -0
  271. package/dist/ui/index.html +1 -1
  272. package/package.json +8 -8
  273. package/dist/ui/assets/_basePickBy-DfxojsEt.js.gz +0 -0
  274. package/dist/ui/assets/_baseUniq-DWFPJOTC.js.gz +0 -0
  275. package/dist/ui/assets/arc-vMZ_XGSI.js.gz +0 -0
  276. package/dist/ui/assets/architectureDiagram-VXUJARFQ-DGpk_uOD.js.gz +0 -0
  277. package/dist/ui/assets/blockDiagram-VD42YOAC-BkRnxc94.js.gz +0 -0
  278. package/dist/ui/assets/channel-B9aI4bYN.js +0 -1
  279. package/dist/ui/assets/chunk-B4BG7PRW-DtkeCZab.js.gz +0 -0
  280. package/dist/ui/assets/chunk-DI55MBZ5-BQ_asW-1.js.gz +0 -0
  281. package/dist/ui/assets/chunk-TZMSLE5B-DlPypnIq.js.gz +0 -0
  282. package/dist/ui/assets/classDiagram-2ON5EDUG-p-68WO4Z.js +0 -1
  283. package/dist/ui/assets/classDiagram-v2-WZHVMYZB-p-68WO4Z.js +0 -1
  284. package/dist/ui/assets/clone-DzK5ogfn.js +0 -1
  285. package/dist/ui/assets/consoleHook-59e792cb-DHYIclEd.js.gz +0 -0
  286. package/dist/ui/assets/cose-bilkent-S5V4N54A-DotJH9qH.js.gz +0 -0
  287. package/dist/ui/assets/dagre-6UL2VRFP-Btssr8QF.js.gz +0 -0
  288. package/dist/ui/assets/diagram-PSM6KHXK-D5_Jkog3.js.gz +0 -0
  289. package/dist/ui/assets/diagram-QEK2KX5R-DlPEVSL5.js.gz +0 -0
  290. package/dist/ui/assets/diagram-S2PKOQOG-CjO1k8aG.js.gz +0 -0
  291. package/dist/ui/assets/erDiagram-Q2GNP2WA-3cO02-K3.js.gz +0 -0
  292. package/dist/ui/assets/flowDiagram-NV44I4VS-CajTpSxI.js.gz +0 -0
  293. package/dist/ui/assets/gitGraphDiagram-NY62KEGX-CH16bg-j.js.gz +0 -0
  294. package/dist/ui/assets/graph-IQoZvE3o.js.gz +0 -0
  295. package/dist/ui/assets/index-599aeaf7-RUCkgwsg.js.gz +0 -0
  296. package/dist/ui/assets/index-B3AvIgqP.js.gz +0 -0
  297. package/dist/ui/assets/index-C-quzPWC.js.gz +0 -0
  298. package/dist/ui/assets/index-ChmRuj_T.js.gz +0 -0
  299. package/dist/ui/assets/index-QV5-5yA2.js.gz +0 -0
  300. package/dist/ui/assets/journeyDiagram-XKPGCS4Q-B5bgV3GH.js.gz +0 -0
  301. package/dist/ui/assets/kanban-definition-3W4ZIXB7-Bp-aWRSc.js.gz +0 -0
  302. package/dist/ui/assets/katex-DGRguze2.css +0 -1
  303. package/dist/ui/assets/layout-BH-2XJZq.js.gz +0 -0
  304. package/dist/ui/assets/linear-DCYXhl_f.js.gz +0 -0
  305. package/dist/ui/assets/mermaid.core-BAuL6kgQ.js.gz +0 -0
  306. package/dist/ui/assets/mindmap-definition-VGOIOE7T-DpH5N-N0.js.gz +0 -0
  307. package/dist/ui/assets/pieDiagram-ADFJNKIX-BB8fBxj1.js.gz +0 -0
  308. package/dist/ui/assets/quadrantDiagram-AYHSOK5B-D6oZLdUD.js.gz +0 -0
  309. package/dist/ui/assets/requirementDiagram-UZGBJVZJ-B4uGPp8w.js.gz +0 -0
  310. package/dist/ui/assets/sankeyDiagram-TZEHDZUN-MXhIjhme.js.gz +0 -0
  311. package/dist/ui/assets/sequenceDiagram-WL72ISMW-Cm53TYug.js.gz +0 -0
  312. package/dist/ui/assets/stateDiagram-FKZM4ZOC-BVuxUkj5.js.gz +0 -0
  313. package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-8Jeww6Dc.js +0 -1
  314. package/dist/ui/assets/timeline-definition-IT6M3QCI-CMypNiEP.js.gz +0 -0
  315. package/dist/ui/assets/treemap-KMMF4GRG-BEtnV3BT.js.gz +0 -0
  316. package/dist/ui/assets/xychartDiagram-PRI3JC2R-BnioEYUM.js.gz +0 -0
@@ -547,6 +547,8 @@ var init_task = __esm({
547
547
  "use strict";
548
548
  init_cjs_shims();
549
549
  TaskStatus = {
550
+ QUEUED: "queued",
551
+ // Task created but not yet running (waiting for executor to drain queue)
550
552
  CREATED: "created",
551
553
  RUNNING: "running",
552
554
  STOPPING: "stopping",
@@ -577,6 +579,21 @@ function normalizeRole(role) {
577
579
  if (role === "owner") return ROLES.SUPERADMIN;
578
580
  return role || ROLES.MEMBER;
579
581
  }
582
+ function toAgenticToolsStatus(stored) {
583
+ if (!stored) return void 0;
584
+ const out = {};
585
+ for (const [tool, fields] of Object.entries(stored)) {
586
+ if (!fields) continue;
587
+ const flags = {};
588
+ for (const [field, value] of Object.entries(fields)) {
589
+ if (value) flags[field] = true;
590
+ }
591
+ if (Object.keys(flags).length > 0) {
592
+ out[tool] = flags;
593
+ }
594
+ }
595
+ return Object.keys(out).length > 0 ? out : void 0;
596
+ }
580
597
  var ROLES, ROLE_RANK;
581
598
  var init_user = __esm({
582
599
  "src/types/user.ts"() {
@@ -770,6 +787,7 @@ var init_schema_postgres = __esm({
770
787
  completed_at: t.timestamp("completed_at"),
771
788
  status: (0, import_pg_core.text)("status", {
772
789
  enum: [
790
+ "queued",
773
791
  "created",
774
792
  "running",
775
793
  "stopping",
@@ -781,6 +799,8 @@ var init_schema_postgres = __esm({
781
799
  "stopped"
782
800
  ]
783
801
  }).notNull(),
802
+ // Queue position (lower drains first); only populated for status='queued'
803
+ queue_position: (0, import_pg_core.integer)("queue_position"),
784
804
  // User attribution
785
805
  created_by: (0, import_pg_core.varchar)("created_by", { length: 36 }).notNull().default("anonymous"),
786
806
  // MD5 of SDK session file at task completion (only populated when stateless_fs_mode is enabled)
@@ -790,7 +810,12 @@ var init_schema_postgres = __esm({
790
810
  (table) => ({
791
811
  sessionIdx: (0, import_pg_core.index)("tasks_session_idx").on(table.session_id),
792
812
  statusIdx: (0, import_pg_core.index)("tasks_status_idx").on(table.status),
793
- createdIdx: (0, import_pg_core.index)("tasks_created_idx").on(table.created_at)
813
+ createdIdx: (0, import_pg_core.index)("tasks_created_idx").on(table.created_at),
814
+ queueIdx: (0, import_pg_core.index)("tasks_queue_idx").on(table.session_id, table.status, table.queue_position),
815
+ // Partial unique index — defense-in-depth for `tasks.createPending` race
816
+ // serialization. Only QUEUED rows are constrained; CREATED/RUNNING/done
817
+ // rows have NULL queue_position and are unaffected.
818
+ queuedPositionUnique: (0, import_pg_core.uniqueIndex)("tasks_queued_position_unique").on(table.session_id, table.queue_position).where(import_drizzle_orm.sql`${table.status} = 'queued'`)
794
819
  })
795
820
  );
796
821
  serializedSessions = (0, import_pg_core.pgTable)(
@@ -850,11 +875,9 @@ var init_schema_postgres = __esm({
850
875
  // First 200 chars for list views
851
876
  // Parent tool use ID (for nested tool calls - e.g., Task tool spawning Read/Grep)
852
877
  parent_tool_use_id: (0, import_pg_core.text)("parent_tool_use_id"),
853
- // Message queueing fields
854
- status: (0, import_pg_core.text)("status", { enum: ["queued"] }),
855
- // 'queued' or null (normal message)
856
- queue_position: (0, import_pg_core.integer)("queue_position"),
857
- // Position in queue (1, 2, 3, ...)
878
+ // NOTE: queueing moved off `messages` and onto `tasks.status='queued'` as
879
+ // of migration sqlite/0040 (postgres/0030). The legacy `status` and
880
+ // `queue_position` columns are gone — see `tasks.queue_position` instead.
858
881
  // Full data (JSON blob)
859
882
  data: t.json("data").$type().notNull()
860
883
  },
@@ -862,8 +885,7 @@ var init_schema_postgres = __esm({
862
885
  // Indexes for efficient lookups
863
886
  sessionIdx: (0, import_pg_core.index)("messages_session_id_idx").on(table.session_id),
864
887
  taskIdx: (0, import_pg_core.index)("messages_task_id_idx").on(table.task_id),
865
- sessionIndexIdx: (0, import_pg_core.index)("messages_session_index_idx").on(table.session_id, table.index),
866
- queueIdx: (0, import_pg_core.index)("messages_queue_idx").on(table.session_id, table.status, table.queue_position)
888
+ sessionIndexIdx: (0, import_pg_core.index)("messages_session_index_idx").on(table.session_id, table.index)
867
889
  })
868
890
  );
869
891
  boards = (0, import_pg_core.pgTable)(
@@ -1500,6 +1522,7 @@ var init_schema_sqlite = __esm({
1500
1522
  completed_at: t2.timestamp("completed_at"),
1501
1523
  status: (0, import_sqlite_core.text)("status", {
1502
1524
  enum: [
1525
+ "queued",
1503
1526
  "created",
1504
1527
  "running",
1505
1528
  "stopping",
@@ -1511,6 +1534,8 @@ var init_schema_sqlite = __esm({
1511
1534
  "stopped"
1512
1535
  ]
1513
1536
  }).notNull(),
1537
+ // Queue position (lower drains first); only populated for status='queued'
1538
+ queue_position: (0, import_sqlite_core.integer)("queue_position"),
1514
1539
  // User attribution
1515
1540
  created_by: (0, import_sqlite_core.text)("created_by", { length: 36 }).notNull().default("anonymous"),
1516
1541
  // MD5 of SDK session file at task completion (only populated when stateless_fs_mode is enabled)
@@ -1520,7 +1545,12 @@ var init_schema_sqlite = __esm({
1520
1545
  (table) => ({
1521
1546
  sessionIdx: (0, import_sqlite_core.index)("tasks_session_idx").on(table.session_id),
1522
1547
  statusIdx: (0, import_sqlite_core.index)("tasks_status_idx").on(table.status),
1523
- createdIdx: (0, import_sqlite_core.index)("tasks_created_idx").on(table.created_at)
1548
+ createdIdx: (0, import_sqlite_core.index)("tasks_created_idx").on(table.created_at),
1549
+ queueIdx: (0, import_sqlite_core.index)("tasks_queue_idx").on(table.session_id, table.status, table.queue_position),
1550
+ // Partial unique index — defense-in-depth for `tasks.createPending` race
1551
+ // serialization. Only QUEUED rows are constrained; CREATED/RUNNING/done
1552
+ // rows have NULL queue_position and are unaffected.
1553
+ queuedPositionUnique: (0, import_sqlite_core.uniqueIndex)("tasks_queued_position_unique").on(table.session_id, table.queue_position).where(import_drizzle_orm2.sql`${table.status} = 'queued'`)
1524
1554
  })
1525
1555
  );
1526
1556
  serializedSessions2 = (0, import_sqlite_core.sqliteTable)(
@@ -1580,11 +1610,9 @@ var init_schema_sqlite = __esm({
1580
1610
  // First 200 chars for list views
1581
1611
  // Parent tool use ID (for nested tool calls - e.g., Task tool spawning Read/Grep)
1582
1612
  parent_tool_use_id: (0, import_sqlite_core.text)("parent_tool_use_id"),
1583
- // Message queueing fields
1584
- status: (0, import_sqlite_core.text)("status", { enum: ["queued"] }),
1585
- // 'queued' or null (normal message)
1586
- queue_position: (0, import_sqlite_core.integer)("queue_position"),
1587
- // Position in queue (1, 2, 3, ...)
1613
+ // NOTE: queueing moved off `messages` and onto `tasks.status='queued'` as
1614
+ // of migration sqlite/0040 (postgres/0030). The legacy `status` and
1615
+ // `queue_position` columns are gone — see `tasks.queue_position` instead.
1588
1616
  // Full data (JSON blob)
1589
1617
  data: t2.json("data").$type().notNull()
1590
1618
  },
@@ -1592,8 +1620,7 @@ var init_schema_sqlite = __esm({
1592
1620
  // Indexes for efficient lookups
1593
1621
  sessionIdx: (0, import_sqlite_core.index)("messages_session_id_idx").on(table.session_id),
1594
1622
  taskIdx: (0, import_sqlite_core.index)("messages_task_id_idx").on(table.task_id),
1595
- sessionIndexIdx: (0, import_sqlite_core.index)("messages_session_index_idx").on(table.session_id, table.index),
1596
- queueIdx: (0, import_sqlite_core.index)("messages_queue_idx").on(table.session_id, table.status, table.queue_position)
1623
+ sessionIndexIdx: (0, import_sqlite_core.index)("messages_session_index_idx").on(table.session_id, table.index)
1597
1624
  })
1598
1625
  );
1599
1626
  boards2 = (0, import_sqlite_core.sqliteTable)(
@@ -5573,8 +5600,6 @@ var MessagesRepository = class {
5573
5600
  content: row.data.content,
5574
5601
  tool_uses: row.data.tool_uses,
5575
5602
  parent_tool_use_id: row.parent_tool_use_id || void 0,
5576
- status: row.status,
5577
- queue_position: row.queue_position ?? void 0,
5578
5603
  metadata: row.data.metadata
5579
5604
  };
5580
5605
  }
@@ -5593,8 +5618,6 @@ var MessagesRepository = class {
5593
5618
  timestamp: new Date(message.timestamp),
5594
5619
  content_preview: message.content_preview,
5595
5620
  parent_tool_use_id: message.parent_tool_use_id || null,
5596
- status: message.status || null,
5597
- queue_position: message.queue_position ?? null,
5598
5621
  data: {
5599
5622
  content: message.content,
5600
5623
  tool_uses: message.tool_uses,
@@ -5693,68 +5716,6 @@ var MessagesRepository = class {
5693
5716
  async delete(messageId) {
5694
5717
  await deleteFrom(this.db, messages3).where((0, import_drizzle_orm13.eq)(messages3.message_id, messageId)).run();
5695
5718
  }
5696
- /**
5697
- * Create a queued message
5698
- * NOTE: Queued messages always store prompt as string content
5699
- * This ensures compatibility with prompt execution endpoint
5700
- *
5701
- * @param sessionId - Session to queue message for
5702
- * @param prompt - Message content (string)
5703
- * @param metadata - Optional metadata (e.g., is_agor_callback, source, child_session_id)
5704
- */
5705
- async createQueued(sessionId, prompt, metadata) {
5706
- if (!prompt || typeof prompt !== "string") {
5707
- throw new Error("Prompt must be a non-empty string");
5708
- }
5709
- const { generateId: generateId2 } = await Promise.resolve().then(() => (init_ids(), ids_exports));
5710
- const result = await select(this.db).from(messages3).where((0, import_drizzle_orm13.and)((0, import_drizzle_orm13.eq)(messages3.session_id, sessionId), (0, import_drizzle_orm13.eq)(messages3.status, "queued"))).all();
5711
- const maxPosition = result.reduce(
5712
- (max, row) => Math.max(max, row.queue_position || 0),
5713
- 0
5714
- );
5715
- const nextPosition = maxPosition + 1;
5716
- const messageType = metadata?.is_agor_callback ? "system" : "user";
5717
- const message = {
5718
- message_id: generateId2(),
5719
- session_id: sessionId,
5720
- type: messageType,
5721
- role: "user",
5722
- // Always 'user' for right-side positioning
5723
- index: -1,
5724
- // Not in conversation yet
5725
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
5726
- content_preview: prompt.substring(0, 200),
5727
- content: prompt,
5728
- // Always string for queued messages
5729
- status: "queued",
5730
- queue_position: nextPosition,
5731
- task_id: void 0,
5732
- metadata
5733
- // Include metadata (is_agor_callback, source, child_session_id, etc.)
5734
- };
5735
- return this.create(message);
5736
- }
5737
- /**
5738
- * Find queued messages for a session
5739
- */
5740
- async findQueued(sessionId) {
5741
- const { asc: asc2 } = await import("drizzle-orm");
5742
- const rows = await select(this.db).from(messages3).where((0, import_drizzle_orm13.and)((0, import_drizzle_orm13.eq)(messages3.session_id, sessionId), (0, import_drizzle_orm13.eq)(messages3.status, "queued"))).orderBy(asc2(messages3.queue_position)).all();
5743
- return rows.map((r) => this.rowToMessage(r));
5744
- }
5745
- /**
5746
- * Get next queued message
5747
- */
5748
- async getNextQueued(sessionId) {
5749
- const queued = await this.findQueued(sessionId);
5750
- return queued[0] || null;
5751
- }
5752
- /**
5753
- * Delete queued message (when processing or user cancels)
5754
- */
5755
- async deleteQueued(messageId) {
5756
- await this.delete(messageId);
5757
- }
5758
5719
  };
5759
5720
 
5760
5721
  // src/db/repositories/repos.ts
@@ -6917,14 +6878,7 @@ var SessionRepository = class {
6917
6878
  for (const sessionId of sessionIds) {
6918
6879
  const query = select(this.db, {
6919
6880
  data: messagesTable.data
6920
- }).from(messagesTable).where(
6921
- (0, import_drizzle_orm17.and)(
6922
- (0, import_drizzle_orm17.eq)(messagesTable.session_id, sessionId),
6923
- (0, import_drizzle_orm17.eq)(messagesTable.role, "assistant"),
6924
- (0, import_drizzle_orm17.isNull)(messagesTable.status)
6925
- // Exclude queued messages
6926
- )
6927
- );
6881
+ }).from(messagesTable).where((0, import_drizzle_orm17.and)((0, import_drizzle_orm17.eq)(messagesTable.session_id, sessionId), (0, import_drizzle_orm17.eq)(messagesTable.role, "assistant")));
6928
6882
  const lastMessage = await query.orderBy((0, import_drizzle_orm17.desc)(messagesTable.index)).limit(1).one();
6929
6883
  if (lastMessage) {
6930
6884
  const messageData = lastMessage.data;
@@ -7212,6 +7166,7 @@ var TaskRepository = class {
7212
7166
  task_id: row.task_id,
7213
7167
  session_id: row.session_id,
7214
7168
  status: row.status,
7169
+ queue_position: row.queue_position ?? void 0,
7215
7170
  created_at: new Date(row.created_at).toISOString(),
7216
7171
  completed_at: row.completed_at ? new Date(row.completed_at).toISOString() : void 0,
7217
7172
  created_by: row.created_by,
@@ -7239,11 +7194,11 @@ var TaskRepository = class {
7239
7194
  // Always use server timestamp, ignore client-provided value
7240
7195
  completed_at: task.completed_at ? new Date(task.completed_at) : void 0,
7241
7196
  status: task.status ?? TaskStatus.CREATED,
7197
+ queue_position: task.queue_position ?? null,
7242
7198
  created_by: task.created_by ?? "anonymous",
7243
7199
  session_md5: task.session_md5 ?? null,
7244
7200
  data: {
7245
- description: task.description ?? "",
7246
- full_prompt: task.full_prompt ?? task.description ?? "",
7201
+ full_prompt: task.full_prompt ?? "",
7247
7202
  message_range: task.message_range ?? {
7248
7203
  start_index: 0,
7249
7204
  end_index: 0,
@@ -7265,8 +7220,10 @@ var TaskRepository = class {
7265
7220
  computed_context_window: task.computed_context_window,
7266
7221
  // Cumulative context window (computed by tool.computeContextWindow())
7267
7222
  report: task.report,
7268
- permission_request: task.permission_request
7223
+ permission_request: task.permission_request,
7269
7224
  // Permission state for UI approval flow
7225
+ metadata: task.metadata
7226
+ // Generic metadata bag (e.g., is_agor_callback, source)
7270
7227
  }
7271
7228
  };
7272
7229
  }
@@ -7393,7 +7350,12 @@ var TaskRepository = class {
7393
7350
  }
7394
7351
  /**
7395
7352
  * Find orphaned tasks (running, stopping, awaiting permission, or awaiting input)
7396
- * These are tasks that were interrupted when daemon stopped
7353
+ * These are tasks that were interrupted when daemon stopped.
7354
+ *
7355
+ * NOTE: QUEUED tasks are intentionally NOT considered orphans — they were
7356
+ * never spawned, so they have no executor to recover. The startup queue
7357
+ * drainer (see register-routes.ts processNextQueuedTask) picks them up
7358
+ * once any session goes idle. See never-lose-prompt §C.
7397
7359
  */
7398
7360
  async findOrphaned() {
7399
7361
  try {
@@ -7445,6 +7407,7 @@ var TaskRepository = class {
7445
7407
  const insertData = this.taskToInsert(merged);
7446
7408
  await update(txAsDb(tx), tasks3).set({
7447
7409
  status: insertData.status,
7410
+ queue_position: insertData.queue_position,
7448
7411
  completed_at: insertData.completed_at,
7449
7412
  session_md5: insertData.session_md5,
7450
7413
  data: insertData.data
@@ -7479,6 +7442,92 @@ var TaskRepository = class {
7479
7442
  );
7480
7443
  }
7481
7444
  }
7445
+ /**
7446
+ * Create a pending task — either CREATED (will spawn immediately) or
7447
+ * QUEUED (will drain later) — owning the sentinel defaults that the
7448
+ * caller would otherwise have to assemble by hand.
7449
+ *
7450
+ * For QUEUED tasks, `queue_position = max(queue_position) + 1` is computed
7451
+ * inside a transaction so concurrent writers don't both observe the same
7452
+ * max and collide. (The schema also carries a partial unique index on
7453
+ * `(session_id, queue_position) WHERE status='queued'` as a belt-and-
7454
+ * suspenders against transaction-isolation surprises.)
7455
+ *
7456
+ * Sentinel contract: while a task carries `message_range.start_index = -1`
7457
+ * and `git_state.sha_at_start = ''`, it has not yet been pinned to real
7458
+ * conversation/git state. spawnTaskExecutor is the sole place that
7459
+ * overwrites these on the way to RUNNING.
7460
+ */
7461
+ async createPending(input) {
7462
+ const taskBase = {
7463
+ session_id: input.session_id,
7464
+ full_prompt: input.full_prompt,
7465
+ created_by: input.created_by,
7466
+ status: input.status,
7467
+ metadata: input.metadata,
7468
+ // Sentinels — overwritten by spawnTaskExecutor at the status → RUNNING
7469
+ // transition. While `start_index === -1` / `sha_at_start === ''`, the
7470
+ // task is intentionally unpinned.
7471
+ message_range: {
7472
+ start_index: -1,
7473
+ end_index: -1,
7474
+ start_timestamp: (/* @__PURE__ */ new Date()).toISOString()
7475
+ },
7476
+ git_state: {
7477
+ ref_at_start: "",
7478
+ sha_at_start: ""
7479
+ },
7480
+ tool_use_count: 0
7481
+ };
7482
+ if (input.status === TaskStatus.CREATED) {
7483
+ return this.create(taskBase);
7484
+ }
7485
+ return this.db.transaction(async (tx) => {
7486
+ const positionRow = await select(txAsDb(tx), {
7487
+ maxPos: import_drizzle_orm19.sql`max(${tasks3.queue_position})`
7488
+ }).from(tasks3).where(import_drizzle_orm19.sql`${tasks3.session_id} = ${input.session_id} AND ${tasks3.status} = 'queued'`).one();
7489
+ const nextPosition = (positionRow?.maxPos ?? 0) + 1;
7490
+ const insertData = this.taskToInsert({
7491
+ ...taskBase,
7492
+ queue_position: nextPosition
7493
+ });
7494
+ await insert(txAsDb(tx), tasks3).values(insertData).run();
7495
+ const row = await select(txAsDb(tx)).from(tasks3).where((0, import_drizzle_orm19.eq)(tasks3.task_id, insertData.task_id)).one();
7496
+ if (!row) {
7497
+ throw new RepositoryError("Failed to retrieve created queued task");
7498
+ }
7499
+ return this.rowToTask(row);
7500
+ });
7501
+ }
7502
+ /**
7503
+ * Find all QUEUED tasks for a session, ordered by queue_position ascending.
7504
+ */
7505
+ async findQueued(sessionId) {
7506
+ try {
7507
+ const rows = await select(this.db).from(tasks3).where(import_drizzle_orm19.sql`${tasks3.session_id} = ${sessionId} AND ${tasks3.status} = 'queued'`).orderBy(tasks3.queue_position).all();
7508
+ return rows.map((row) => this.rowToTask(row));
7509
+ } catch (error) {
7510
+ throw new RepositoryError(
7511
+ `Failed to find queued tasks: ${error instanceof Error ? error.message : String(error)}`,
7512
+ error
7513
+ );
7514
+ }
7515
+ }
7516
+ /**
7517
+ * Return the next QUEUED task to drain (lowest queue_position) for a session,
7518
+ * or null if none.
7519
+ */
7520
+ async getNextQueued(sessionId) {
7521
+ try {
7522
+ const row = await select(this.db).from(tasks3).where(import_drizzle_orm19.sql`${tasks3.session_id} = ${sessionId} AND ${tasks3.status} = 'queued'`).orderBy(tasks3.queue_position).limit(1).one();
7523
+ return row ? this.rowToTask(row) : null;
7524
+ } catch (error) {
7525
+ throw new RepositoryError(
7526
+ `Failed to get next queued task: ${error instanceof Error ? error.message : String(error)}`,
7527
+ error
7528
+ );
7529
+ }
7530
+ }
7482
7531
  /**
7483
7532
  * Count tasks for a session
7484
7533
  */
@@ -8047,6 +8096,7 @@ var UserMCPOAuthTokenRepository = class {
8047
8096
 
8048
8097
  // src/db/repositories/users.ts
8049
8098
  init_cjs_shims();
8099
+ init_types();
8050
8100
  var import_drizzle_orm23 = require("drizzle-orm");
8051
8101
 
8052
8102
  // src/config/env-vars.ts
@@ -8086,8 +8136,9 @@ var UsersRepository = class {
8086
8136
  this.db = db;
8087
8137
  }
8088
8138
  /**
8089
- * Convert database row to User type
8090
- * Note: Converts encrypted API keys (strings) to boolean flags for API exposure
8139
+ * Convert database row to User type.
8140
+ * Converts the encrypted `agentic_tools` blob to a boolean presence DTO so
8141
+ * decrypted credentials never leave this repository.
8091
8142
  */
8092
8143
  rowToUser(row) {
8093
8144
  return {
@@ -8103,13 +8154,8 @@ var UsersRepository = class {
8103
8154
  must_change_password: row.must_change_password,
8104
8155
  avatar: row.data.avatar,
8105
8156
  preferences: row.data.preferences,
8106
- // Convert encrypted keys to boolean flags (true = key exists, false/undefined = no key)
8107
- api_keys: row.data.api_keys ? {
8108
- ANTHROPIC_API_KEY: !!row.data.api_keys.ANTHROPIC_API_KEY,
8109
- OPENAI_API_KEY: !!row.data.api_keys.OPENAI_API_KEY,
8110
- GEMINI_API_KEY: !!row.data.api_keys.GEMINI_API_KEY,
8111
- COPILOT_GITHUB_TOKEN: !!row.data.api_keys.COPILOT_GITHUB_TOKEN
8112
- } : void 0,
8157
+ // Convert encrypted per-tool credential blobs into boolean presence flags.
8158
+ agentic_tools: toAgenticToolsStatus(row.data.agentic_tools),
8113
8159
  // Convert stored env vars to presence + scope metadata (never exposes secrets).
8114
8160
  // Handles both legacy string form and v0.5 object form via normalizeStoredEnvMap.
8115
8161
  // The schema stores `scope` as a generic string (no SQL CHECK constraint); the
@@ -8153,10 +8199,17 @@ var UsersRepository = class {
8153
8199
  data: {
8154
8200
  avatar: user.avatar,
8155
8201
  preferences: user.preferences,
8156
- // Use raw API keys if provided (for internal operations like setApiKey)
8157
- api_keys: user.api_keys_raw,
8158
- env_vars: void 0,
8159
- // Not implemented yet
8202
+ // Encrypted per-tool credentials. Only forwarded when caller passes the
8203
+ // raw shape (internal credential mutators); regular updates leave it undefined,
8204
+ // letting the merge in `update()` reuse the existing on-disk blob.
8205
+ // Cast: schema declares `opencode: Record<string, never>` (no fields by
8206
+ // contract); StoredAgenticTools widens that to string values for shape
8207
+ // uniformity. Runtime never writes opencode, so the cast is safe.
8208
+ agentic_tools: user.agentic_tools_raw,
8209
+ // Same pass-through as agentic_tools: env_vars are encrypted blobs
8210
+ // not represented on the public DTO. `update()` threads the raw value
8211
+ // from the existing row so a generic field update doesn't wipe them.
8212
+ env_vars: user.env_vars_raw,
8160
8213
  default_agentic_config: user.default_agentic_config
8161
8214
  }
8162
8215
  };
@@ -8268,7 +8321,14 @@ var UsersRepository = class {
8268
8321
  );
8269
8322
  }
8270
8323
  }
8324
+ const rawRow = await this.getRawRow(fullId);
8271
8325
  const merged = { ...current, ...updates };
8326
+ if (rawRow?.data.agentic_tools) {
8327
+ merged.agentic_tools_raw = rawRow.data.agentic_tools;
8328
+ }
8329
+ if (rawRow?.data.env_vars) {
8330
+ merged.env_vars_raw = rawRow.data.env_vars;
8331
+ }
8272
8332
  const insertData = this.userToInsert(merged);
8273
8333
  await update(this.db, users3).set({
8274
8334
  ...insertData,
@@ -8303,96 +8363,103 @@ var UsersRepository = class {
8303
8363
  }
8304
8364
  }
8305
8365
  /**
8306
- * Get decrypted API key for a user and service
8366
+ * Get the full decrypted credential bag for a single agentic tool.
8307
8367
  *
8308
- * @param userId - User ID
8309
- * @param service - Service name ('anthropic', 'openai', 'gemini')
8310
- * @returns Decrypted API key or null if not found
8368
+ * Returns `null` when the user has no stored config for that tool.
8369
+ * Fields that fail to decrypt are dropped from the returned object and
8370
+ * logged callers see "missing field" rather than a thrown error so a
8371
+ * single corrupt value doesn't poison an entire SDK spawn.
8311
8372
  */
8312
- async getApiKey(userId, service) {
8373
+ async getToolConfig(userId, tool) {
8313
8374
  const row = await this.getRawRow(userId);
8314
- if (!row || !row.data.api_keys) {
8315
- return null;
8316
- }
8317
- const keyMap = {
8318
- anthropic: "ANTHROPIC_API_KEY",
8319
- openai: "OPENAI_API_KEY",
8320
- gemini: "GEMINI_API_KEY",
8321
- copilot: "COPILOT_GITHUB_TOKEN"
8322
- };
8323
- const encryptedKey = row.data.api_keys[keyMap[service]];
8324
- if (!encryptedKey) {
8325
- return null;
8375
+ if (!row) return null;
8376
+ const stored = row.data.agentic_tools;
8377
+ const fields = stored?.[tool];
8378
+ if (!fields || Object.keys(fields).length === 0) return null;
8379
+ const out = {};
8380
+ for (const [field, encrypted] of Object.entries(fields)) {
8381
+ if (!encrypted) continue;
8382
+ try {
8383
+ out[field] = decryptApiKey(encrypted);
8384
+ } catch (error) {
8385
+ console.error(
8386
+ `[users] Failed to decrypt ${tool}.${field} for user ${userId.substring(0, 8)}: ${error.message}`
8387
+ );
8388
+ }
8326
8389
  }
8390
+ return Object.keys(out).length > 0 ? out : null;
8391
+ }
8392
+ /**
8393
+ * Get a single decrypted credential field for a tool.
8394
+ *
8395
+ * Returns `null` when the field is unset OR when decryption fails (logged).
8396
+ * Throws only on storage-layer errors, not on missing/corrupt values.
8397
+ */
8398
+ async getToolConfigField(userId, tool, field) {
8399
+ const row = await this.getRawRow(userId);
8400
+ if (!row) return null;
8401
+ const stored = row.data.agentic_tools;
8402
+ const encrypted = stored?.[tool]?.[field];
8403
+ if (!encrypted) return null;
8327
8404
  try {
8328
- return decryptApiKey(encryptedKey);
8405
+ return decryptApiKey(encrypted);
8329
8406
  } catch (error) {
8330
- throw new RepositoryError(`Failed to decrypt API key for service ${service}`, error);
8407
+ console.error(
8408
+ `[users] Failed to decrypt ${tool}.${field} for user ${userId.substring(0, 8)}: ${error.message}`
8409
+ );
8410
+ return null;
8331
8411
  }
8332
8412
  }
8333
8413
  /**
8334
- * Set encrypted API key for a user and service
8414
+ * Set (encrypt + persist) a single credential field for a tool.
8335
8415
  *
8336
- * @param userId - User ID
8337
- * @param service - Service name ('anthropic', 'openai', 'gemini')
8338
- * @param apiKey - Plaintext API key to encrypt and store
8416
+ * Field names are env-var-shaped (e.g. ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL)
8417
+ * and are stored encrypted regardless of whether the value is a secret —
8418
+ * keeping the on-disk shape uniform avoids decrypt-vs-plain branching at
8419
+ * read time. UI controls own the text-vs-password rendering distinction.
8339
8420
  */
8340
- async setApiKey(userId, service, apiKey) {
8421
+ async setToolConfigField(userId, tool, field, value) {
8341
8422
  const fullId = await this.resolveId(userId);
8342
8423
  const row = await this.getRawRow(fullId);
8343
8424
  if (!row) {
8344
8425
  throw new EntityNotFoundError("User", userId);
8345
8426
  }
8346
- const keyMap = {
8347
- anthropic: "ANTHROPIC_API_KEY",
8348
- openai: "OPENAI_API_KEY",
8349
- gemini: "GEMINI_API_KEY",
8350
- copilot: "COPILOT_GITHUB_TOKEN"
8351
- };
8352
- const encryptedKey = encryptApiKey(apiKey);
8353
- const updatedApiKeys = {
8354
- ...row.data.api_keys || {},
8355
- [keyMap[service]]: encryptedKey
8356
- };
8357
- const user = this.rowToUser(row);
8358
- const updateData = {
8359
- ...user,
8360
- api_keys_raw: updatedApiKeys
8427
+ const stored = row.data.agentic_tools ?? {};
8428
+ const next = {
8429
+ ...stored,
8430
+ [tool]: {
8431
+ ...stored[tool] ?? {},
8432
+ [field]: encryptApiKey(value)
8433
+ }
8361
8434
  };
8362
- const insertData = this.userToInsert(updateData);
8363
8435
  await update(this.db, users3).set({
8364
- ...insertData,
8436
+ data: { ...row.data, agentic_tools: next },
8365
8437
  updated_at: /* @__PURE__ */ new Date()
8366
8438
  }).where((0, import_drizzle_orm23.eq)(users3.user_id, fullId)).run();
8367
8439
  }
8368
8440
  /**
8369
- * Delete API key for a user and service
8441
+ * Delete a single credential field for a tool.
8370
8442
  *
8371
- * @param userId - User ID
8372
- * @param service - Service name ('anthropic', 'openai', 'gemini')
8443
+ * If the tool's bucket becomes empty after the delete, the bucket itself is
8444
+ * removed so `data.agentic_tools` doesn't accumulate empty objects.
8373
8445
  */
8374
- async deleteApiKey(userId, service) {
8446
+ async deleteToolConfigField(userId, tool, field) {
8375
8447
  const fullId = await this.resolveId(userId);
8376
8448
  const row = await this.getRawRow(fullId);
8377
8449
  if (!row) {
8378
8450
  throw new EntityNotFoundError("User", userId);
8379
8451
  }
8380
- const keyMap = {
8381
- anthropic: "ANTHROPIC_API_KEY",
8382
- openai: "OPENAI_API_KEY",
8383
- gemini: "GEMINI_API_KEY",
8384
- copilot: "COPILOT_GITHUB_TOKEN"
8385
- };
8386
- const updatedApiKeys = { ...row.data.api_keys || {} };
8387
- delete updatedApiKeys[keyMap[service]];
8388
- const user = this.rowToUser(row);
8389
- const updateData = {
8390
- ...user,
8391
- api_keys_raw: updatedApiKeys
8392
- };
8393
- const insertData = this.userToInsert(updateData);
8452
+ const stored = row.data.agentic_tools ?? {};
8453
+ const toolFields = { ...stored[tool] ?? {} };
8454
+ delete toolFields[field];
8455
+ const next = { ...stored };
8456
+ if (Object.keys(toolFields).length > 0) {
8457
+ next[tool] = toolFields;
8458
+ } else {
8459
+ delete next[tool];
8460
+ }
8394
8461
  await update(this.db, users3).set({
8395
- ...insertData,
8462
+ data: { ...row.data, agentic_tools: next },
8396
8463
  updated_at: /* @__PURE__ */ new Date()
8397
8464
  }).where((0, import_drizzle_orm23.eq)(users3.user_id, fullId)).run();
8398
8465
  }
@@ -8932,14 +8999,7 @@ var WorktreeRepository = class {
8932
8999
  for (const sessionId of sessionIds) {
8933
9000
  const query = select(this.db, {
8934
9001
  data: messagesTable.data
8935
- }).from(messagesTable).where(
8936
- (0, import_drizzle_orm24.and)(
8937
- (0, import_drizzle_orm24.eq)(messagesTable.session_id, sessionId),
8938
- (0, import_drizzle_orm24.eq)(messagesTable.role, "assistant"),
8939
- (0, import_drizzle_orm24.isNull)(messagesTable.status)
8940
- // Exclude queued messages
8941
- )
8942
- );
9002
+ }).from(messagesTable).where((0, import_drizzle_orm24.and)((0, import_drizzle_orm24.eq)(messagesTable.session_id, sessionId), (0, import_drizzle_orm24.eq)(messagesTable.role, "assistant")));
8943
9003
  const lastMessage = await query.orderBy((0, import_drizzle_orm24.desc)(messagesTable.index)).limit(1).one();
8944
9004
  if (lastMessage) {
8945
9005
  const messageData = lastMessage.data;