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
@@ -1,5 +1,5 @@
1
- import { a as DaemonResourcesConfig, b as DaemonServicesConfig } from './config-services-DcO2GRgh.js';
2
- import { j as UserRole } from './user-BfVWBmXA.js';
1
+ import { a as DaemonResourcesConfig, b as DaemonServicesConfig } from './config-services-DhM7_yWn.js';
2
+ import { t as UserRole } from './user-DP-XZMIM.js';
3
3
  import { l as WorktreePermissionLevel } from './repo-84E0A2gV.js';
4
4
 
5
5
  /**
@@ -268,6 +268,22 @@ interface AgorExecutionSettings {
268
268
  mcp_token_expiration_ms?: number;
269
269
  /** Sync web passwords to Unix user passwords (default: true). When enabled, passwords are synced on user creation/update. */
270
270
  sync_unix_passwords?: boolean;
271
+ /**
272
+ * When true (default), the daemon writes the initial user-message row inside
273
+ * `POST /sessions/:id/prompt`, immediately after the task is created. This
274
+ * guarantees the chat transcript reflects what the user typed even if the
275
+ * executor crashes during startup ("never lose a prompt").
276
+ *
277
+ * Set to false to revert to the legacy behavior where the executor is the
278
+ * sole writer of the user-message row. The legacy behavior is racy: any
279
+ * crash before the executor connects back via Feathers leaves the prompt
280
+ * visible only on `tasks.full_prompt`, not in the chat transcript.
281
+ *
282
+ * Kill switch only — intended for emergency rollback. The executor's
283
+ * `createUserMessage` path always honors a "skip if user-message row already
284
+ * exists for this task" guard, so toggling this flag is safe at runtime.
285
+ */
286
+ daemon_writes_user_message?: boolean;
271
287
  /** Permission request timeout in ms (default: 600000 = 10 minutes). When a permission request is not resolved within this time, the agent is notified and can continue. */
272
288
  permission_timeout_ms?: number;
273
289
  /**
@@ -87,6 +87,7 @@ __export(config_manager_exports, {
87
87
  getWorktreesDir: () => getWorktreesDir,
88
88
  getWorktreesDirAsync: () => getWorktreesDirAsync,
89
89
  initConfig: () => initConfig,
90
+ isConfigCredentialKey: () => isConfigCredentialKey,
90
91
  isUnixImpersonationEnabled: () => isUnixImpersonationEnabled,
91
92
  isWorktreeRbacEnabled: () => isWorktreeRbacEnabled,
92
93
  loadConfig: () => loadConfig,
@@ -353,6 +354,9 @@ function loadConfigSync() {
353
354
  );
354
355
  }
355
356
  }
357
+ function isConfigCredentialKey(key) {
358
+ return CONFIG_CREDENTIAL_KEYS.has(key);
359
+ }
356
360
  function getCredential(key) {
357
361
  try {
358
362
  const config = loadConfigSync();
@@ -448,7 +452,7 @@ async function getReposDirAsync() {
448
452
  async function getWorktreesDirAsync() {
449
453
  return import_node_path.default.join(await getDataHomeAsync(), "worktrees");
450
454
  }
451
- var import_node_fs2, import_promises, import_node_os, import_node_path, import_js_yaml2, PublicBaseUrlNotConfiguredError;
455
+ var import_node_fs2, import_promises, import_node_os, import_node_path, import_js_yaml2, PublicBaseUrlNotConfiguredError, CONFIG_CREDENTIAL_KEYS;
452
456
  var init_config_manager = __esm({
453
457
  "src/config/config-manager.ts"() {
454
458
  "use strict";
@@ -466,6 +470,13 @@ var init_config_manager = __esm({
466
470
  this.name = "PublicBaseUrlNotConfiguredError";
467
471
  }
468
472
  };
473
+ CONFIG_CREDENTIAL_KEYS = /* @__PURE__ */ new Set([
474
+ "ANTHROPIC_API_KEY",
475
+ "ANTHROPIC_AUTH_TOKEN",
476
+ "ANTHROPIC_BASE_URL",
477
+ "OPENAI_API_KEY",
478
+ "GEMINI_API_KEY"
479
+ ]);
469
480
  }
470
481
  });
471
482
 
@@ -865,6 +876,21 @@ var init_ui = __esm({
865
876
  });
866
877
 
867
878
  // src/types/user.ts
879
+ function toAgenticToolsStatus(stored) {
880
+ if (!stored) return void 0;
881
+ const out = {};
882
+ for (const [tool, fields] of Object.entries(stored)) {
883
+ if (!fields) continue;
884
+ const flags = {};
885
+ for (const [field, value] of Object.entries(fields)) {
886
+ if (value) flags[field] = true;
887
+ }
888
+ if (Object.keys(flags).length > 0) {
889
+ out[tool] = flags;
890
+ }
891
+ }
892
+ return Object.keys(out).length > 0 ? out : void 0;
893
+ }
868
894
  var ROLES, ROLE_RANK;
869
895
  var init_user = __esm({
870
896
  "src/types/user.ts"() {
@@ -1058,6 +1084,7 @@ var init_schema_postgres = __esm({
1058
1084
  completed_at: t.timestamp("completed_at"),
1059
1085
  status: (0, import_pg_core.text)("status", {
1060
1086
  enum: [
1087
+ "queued",
1061
1088
  "created",
1062
1089
  "running",
1063
1090
  "stopping",
@@ -1069,6 +1096,8 @@ var init_schema_postgres = __esm({
1069
1096
  "stopped"
1070
1097
  ]
1071
1098
  }).notNull(),
1099
+ // Queue position (lower drains first); only populated for status='queued'
1100
+ queue_position: (0, import_pg_core.integer)("queue_position"),
1072
1101
  // User attribution
1073
1102
  created_by: (0, import_pg_core.varchar)("created_by", { length: 36 }).notNull().default("anonymous"),
1074
1103
  // MD5 of SDK session file at task completion (only populated when stateless_fs_mode is enabled)
@@ -1078,7 +1107,12 @@ var init_schema_postgres = __esm({
1078
1107
  (table) => ({
1079
1108
  sessionIdx: (0, import_pg_core.index)("tasks_session_idx").on(table.session_id),
1080
1109
  statusIdx: (0, import_pg_core.index)("tasks_status_idx").on(table.status),
1081
- createdIdx: (0, import_pg_core.index)("tasks_created_idx").on(table.created_at)
1110
+ createdIdx: (0, import_pg_core.index)("tasks_created_idx").on(table.created_at),
1111
+ queueIdx: (0, import_pg_core.index)("tasks_queue_idx").on(table.session_id, table.status, table.queue_position),
1112
+ // Partial unique index — defense-in-depth for `tasks.createPending` race
1113
+ // serialization. Only QUEUED rows are constrained; CREATED/RUNNING/done
1114
+ // rows have NULL queue_position and are unaffected.
1115
+ queuedPositionUnique: (0, import_pg_core.uniqueIndex)("tasks_queued_position_unique").on(table.session_id, table.queue_position).where(import_drizzle_orm2.sql`${table.status} = 'queued'`)
1082
1116
  })
1083
1117
  );
1084
1118
  serializedSessions = (0, import_pg_core.pgTable)(
@@ -1138,11 +1172,9 @@ var init_schema_postgres = __esm({
1138
1172
  // First 200 chars for list views
1139
1173
  // Parent tool use ID (for nested tool calls - e.g., Task tool spawning Read/Grep)
1140
1174
  parent_tool_use_id: (0, import_pg_core.text)("parent_tool_use_id"),
1141
- // Message queueing fields
1142
- status: (0, import_pg_core.text)("status", { enum: ["queued"] }),
1143
- // 'queued' or null (normal message)
1144
- queue_position: (0, import_pg_core.integer)("queue_position"),
1145
- // Position in queue (1, 2, 3, ...)
1175
+ // NOTE: queueing moved off `messages` and onto `tasks.status='queued'` as
1176
+ // of migration sqlite/0040 (postgres/0030). The legacy `status` and
1177
+ // `queue_position` columns are gone — see `tasks.queue_position` instead.
1146
1178
  // Full data (JSON blob)
1147
1179
  data: t.json("data").$type().notNull()
1148
1180
  },
@@ -1150,8 +1182,7 @@ var init_schema_postgres = __esm({
1150
1182
  // Indexes for efficient lookups
1151
1183
  sessionIdx: (0, import_pg_core.index)("messages_session_id_idx").on(table.session_id),
1152
1184
  taskIdx: (0, import_pg_core.index)("messages_task_id_idx").on(table.task_id),
1153
- sessionIndexIdx: (0, import_pg_core.index)("messages_session_index_idx").on(table.session_id, table.index),
1154
- queueIdx: (0, import_pg_core.index)("messages_queue_idx").on(table.session_id, table.status, table.queue_position)
1185
+ sessionIndexIdx: (0, import_pg_core.index)("messages_session_index_idx").on(table.session_id, table.index)
1155
1186
  })
1156
1187
  );
1157
1188
  boards = (0, import_pg_core.pgTable)(
@@ -1788,6 +1819,7 @@ var init_schema_sqlite = __esm({
1788
1819
  completed_at: t2.timestamp("completed_at"),
1789
1820
  status: (0, import_sqlite_core.text)("status", {
1790
1821
  enum: [
1822
+ "queued",
1791
1823
  "created",
1792
1824
  "running",
1793
1825
  "stopping",
@@ -1799,6 +1831,8 @@ var init_schema_sqlite = __esm({
1799
1831
  "stopped"
1800
1832
  ]
1801
1833
  }).notNull(),
1834
+ // Queue position (lower drains first); only populated for status='queued'
1835
+ queue_position: (0, import_sqlite_core.integer)("queue_position"),
1802
1836
  // User attribution
1803
1837
  created_by: (0, import_sqlite_core.text)("created_by", { length: 36 }).notNull().default("anonymous"),
1804
1838
  // MD5 of SDK session file at task completion (only populated when stateless_fs_mode is enabled)
@@ -1808,7 +1842,12 @@ var init_schema_sqlite = __esm({
1808
1842
  (table) => ({
1809
1843
  sessionIdx: (0, import_sqlite_core.index)("tasks_session_idx").on(table.session_id),
1810
1844
  statusIdx: (0, import_sqlite_core.index)("tasks_status_idx").on(table.status),
1811
- createdIdx: (0, import_sqlite_core.index)("tasks_created_idx").on(table.created_at)
1845
+ createdIdx: (0, import_sqlite_core.index)("tasks_created_idx").on(table.created_at),
1846
+ queueIdx: (0, import_sqlite_core.index)("tasks_queue_idx").on(table.session_id, table.status, table.queue_position),
1847
+ // Partial unique index — defense-in-depth for `tasks.createPending` race
1848
+ // serialization. Only QUEUED rows are constrained; CREATED/RUNNING/done
1849
+ // rows have NULL queue_position and are unaffected.
1850
+ queuedPositionUnique: (0, import_sqlite_core.uniqueIndex)("tasks_queued_position_unique").on(table.session_id, table.queue_position).where(import_drizzle_orm3.sql`${table.status} = 'queued'`)
1812
1851
  })
1813
1852
  );
1814
1853
  serializedSessions2 = (0, import_sqlite_core.sqliteTable)(
@@ -1868,11 +1907,9 @@ var init_schema_sqlite = __esm({
1868
1907
  // First 200 chars for list views
1869
1908
  // Parent tool use ID (for nested tool calls - e.g., Task tool spawning Read/Grep)
1870
1909
  parent_tool_use_id: (0, import_sqlite_core.text)("parent_tool_use_id"),
1871
- // Message queueing fields
1872
- status: (0, import_sqlite_core.text)("status", { enum: ["queued"] }),
1873
- // 'queued' or null (normal message)
1874
- queue_position: (0, import_sqlite_core.integer)("queue_position"),
1875
- // Position in queue (1, 2, 3, ...)
1910
+ // NOTE: queueing moved off `messages` and onto `tasks.status='queued'` as
1911
+ // of migration sqlite/0040 (postgres/0030). The legacy `status` and
1912
+ // `queue_position` columns are gone — see `tasks.queue_position` instead.
1876
1913
  // Full data (JSON blob)
1877
1914
  data: t2.json("data").$type().notNull()
1878
1915
  },
@@ -1880,8 +1917,7 @@ var init_schema_sqlite = __esm({
1880
1917
  // Indexes for efficient lookups
1881
1918
  sessionIdx: (0, import_sqlite_core.index)("messages_session_id_idx").on(table.session_id),
1882
1919
  taskIdx: (0, import_sqlite_core.index)("messages_task_id_idx").on(table.task_id),
1883
- sessionIndexIdx: (0, import_sqlite_core.index)("messages_session_index_idx").on(table.session_id, table.index),
1884
- queueIdx: (0, import_sqlite_core.index)("messages_queue_idx").on(table.session_id, table.status, table.queue_position)
1920
+ sessionIndexIdx: (0, import_sqlite_core.index)("messages_session_index_idx").on(table.session_id, table.index)
1885
1921
  })
1886
1922
  );
1887
1923
  boards2 = (0, import_sqlite_core.sqliteTable)(
@@ -3511,6 +3547,7 @@ var ALLOWED_ENV_VARS = /* @__PURE__ */ new Set([
3511
3547
  "ANTHROPIC_BASE_URL",
3512
3548
  "ANTHROPIC_AUTH_TOKEN",
3513
3549
  "OPENAI_API_KEY",
3550
+ "OPENAI_BASE_URL",
3514
3551
  "GEMINI_API_KEY",
3515
3552
  "GOOGLE_API_KEY",
3516
3553
  // Vertex AI (Claude Code on GCP)
@@ -3539,7 +3576,7 @@ var ALLOWED_ENV_PREFIXES = [
3539
3576
  ];
3540
3577
  async function resolveUserEnvironment(userId, db, options = {}) {
3541
3578
  const env = {};
3542
- const { sessionId } = options;
3579
+ const { sessionId, tool } = options;
3543
3580
  try {
3544
3581
  const row = await select(db).from(users3).where((0, import_drizzle_orm5.eq)(users3.user_id, userId)).one();
3545
3582
  if (row) {
@@ -3573,16 +3610,22 @@ async function resolveUserEnvironment(userId, db, options = {}) {
3573
3610
  console.error(`Failed to decrypt env var ${key} for user ${userId}:`, err);
3574
3611
  }
3575
3612
  }
3576
- const encryptedApiKeys = data.api_keys;
3577
- if (encryptedApiKeys) {
3578
- for (const [key, encryptedValue] of Object.entries(encryptedApiKeys)) {
3579
- try {
3580
- const decryptedValue = decryptApiKey(encryptedValue);
3581
- if (decryptedValue && decryptedValue.trim() !== "") {
3582
- env[key] = decryptedValue;
3613
+ if (tool) {
3614
+ const toolFields = data.agentic_tools?.[tool];
3615
+ if (toolFields) {
3616
+ for (const [key, encryptedValue] of Object.entries(toolFields)) {
3617
+ if (!encryptedValue) continue;
3618
+ try {
3619
+ const decryptedValue = decryptApiKey(encryptedValue);
3620
+ if (decryptedValue && decryptedValue.trim() !== "") {
3621
+ env[key] = decryptedValue;
3622
+ }
3623
+ } catch (err) {
3624
+ console.error(
3625
+ `Failed to decrypt agentic_tools.${tool}.${key} for user ${userId}:`,
3626
+ err
3627
+ );
3583
3628
  }
3584
- } catch (err) {
3585
- console.error(`Failed to decrypt API key ${key} for user ${userId}:`, err);
3586
3629
  }
3587
3630
  }
3588
3631
  }
@@ -3617,7 +3660,7 @@ function buildAllowlistedEnv() {
3617
3660
  }
3618
3661
  return env;
3619
3662
  }
3620
- async function createUserProcessEnvironment(userId, db, additionalEnv, forImpersonation = false, gatewayEnv, sessionId) {
3663
+ async function createUserProcessEnvironment(userId, db, additionalEnv, forImpersonation = false, gatewayEnv, sessionId, tool) {
3621
3664
  const env = buildAllowlistedEnv();
3622
3665
  const USER_IDENTITY_VARS = ["HOME", "USER", "LOGNAME", "SHELL"];
3623
3666
  if (forImpersonation) {
@@ -3635,7 +3678,7 @@ async function createUserProcessEnvironment(userId, db, additionalEnv, forImpers
3635
3678
  }
3636
3679
  }
3637
3680
  if (userId && db) {
3638
- const userEnv = await resolveUserEnvironment(userId, db, { sessionId });
3681
+ const userEnv = await resolveUserEnvironment(userId, db, { sessionId, tool });
3639
3682
  for (const [key, value] of Object.entries(userEnv)) {
3640
3683
  if (value && value.trim() !== "") {
3641
3684
  env[key] = value;
@@ -4229,6 +4272,7 @@ init_schema();
4229
4272
 
4230
4273
  // src/db/repositories/users.ts
4231
4274
  init_cjs_shims();
4275
+ init_types();
4232
4276
  var import_drizzle_orm24 = require("drizzle-orm");
4233
4277
  init_ids();
4234
4278
  init_database_wrapper();
@@ -4238,8 +4282,9 @@ var UsersRepository = class {
4238
4282
  this.db = db;
4239
4283
  }
4240
4284
  /**
4241
- * Convert database row to User type
4242
- * Note: Converts encrypted API keys (strings) to boolean flags for API exposure
4285
+ * Convert database row to User type.
4286
+ * Converts the encrypted `agentic_tools` blob to a boolean presence DTO so
4287
+ * decrypted credentials never leave this repository.
4243
4288
  */
4244
4289
  rowToUser(row) {
4245
4290
  return {
@@ -4255,13 +4300,8 @@ var UsersRepository = class {
4255
4300
  must_change_password: row.must_change_password,
4256
4301
  avatar: row.data.avatar,
4257
4302
  preferences: row.data.preferences,
4258
- // Convert encrypted keys to boolean flags (true = key exists, false/undefined = no key)
4259
- api_keys: row.data.api_keys ? {
4260
- ANTHROPIC_API_KEY: !!row.data.api_keys.ANTHROPIC_API_KEY,
4261
- OPENAI_API_KEY: !!row.data.api_keys.OPENAI_API_KEY,
4262
- GEMINI_API_KEY: !!row.data.api_keys.GEMINI_API_KEY,
4263
- COPILOT_GITHUB_TOKEN: !!row.data.api_keys.COPILOT_GITHUB_TOKEN
4264
- } : void 0,
4303
+ // Convert encrypted per-tool credential blobs into boolean presence flags.
4304
+ agentic_tools: toAgenticToolsStatus(row.data.agentic_tools),
4265
4305
  // Convert stored env vars to presence + scope metadata (never exposes secrets).
4266
4306
  // Handles both legacy string form and v0.5 object form via normalizeStoredEnvMap.
4267
4307
  // The schema stores `scope` as a generic string (no SQL CHECK constraint); the
@@ -4305,10 +4345,17 @@ var UsersRepository = class {
4305
4345
  data: {
4306
4346
  avatar: user.avatar,
4307
4347
  preferences: user.preferences,
4308
- // Use raw API keys if provided (for internal operations like setApiKey)
4309
- api_keys: user.api_keys_raw,
4310
- env_vars: void 0,
4311
- // Not implemented yet
4348
+ // Encrypted per-tool credentials. Only forwarded when caller passes the
4349
+ // raw shape (internal credential mutators); regular updates leave it undefined,
4350
+ // letting the merge in `update()` reuse the existing on-disk blob.
4351
+ // Cast: schema declares `opencode: Record<string, never>` (no fields by
4352
+ // contract); StoredAgenticTools widens that to string values for shape
4353
+ // uniformity. Runtime never writes opencode, so the cast is safe.
4354
+ agentic_tools: user.agentic_tools_raw,
4355
+ // Same pass-through as agentic_tools: env_vars are encrypted blobs
4356
+ // not represented on the public DTO. `update()` threads the raw value
4357
+ // from the existing row so a generic field update doesn't wipe them.
4358
+ env_vars: user.env_vars_raw,
4312
4359
  default_agentic_config: user.default_agentic_config
4313
4360
  }
4314
4361
  };
@@ -4420,7 +4467,14 @@ var UsersRepository = class {
4420
4467
  );
4421
4468
  }
4422
4469
  }
4470
+ const rawRow = await this.getRawRow(fullId);
4423
4471
  const merged = { ...current, ...updates };
4472
+ if (rawRow?.data.agentic_tools) {
4473
+ merged.agentic_tools_raw = rawRow.data.agentic_tools;
4474
+ }
4475
+ if (rawRow?.data.env_vars) {
4476
+ merged.env_vars_raw = rawRow.data.env_vars;
4477
+ }
4424
4478
  const insertData = this.userToInsert(merged);
4425
4479
  await update(this.db, users3).set({
4426
4480
  ...insertData,
@@ -4455,96 +4509,103 @@ var UsersRepository = class {
4455
4509
  }
4456
4510
  }
4457
4511
  /**
4458
- * Get decrypted API key for a user and service
4512
+ * Get the full decrypted credential bag for a single agentic tool.
4459
4513
  *
4460
- * @param userId - User ID
4461
- * @param service - Service name ('anthropic', 'openai', 'gemini')
4462
- * @returns Decrypted API key or null if not found
4514
+ * Returns `null` when the user has no stored config for that tool.
4515
+ * Fields that fail to decrypt are dropped from the returned object and
4516
+ * logged callers see "missing field" rather than a thrown error so a
4517
+ * single corrupt value doesn't poison an entire SDK spawn.
4463
4518
  */
4464
- async getApiKey(userId, service) {
4519
+ async getToolConfig(userId, tool) {
4465
4520
  const row = await this.getRawRow(userId);
4466
- if (!row || !row.data.api_keys) {
4467
- return null;
4468
- }
4469
- const keyMap = {
4470
- anthropic: "ANTHROPIC_API_KEY",
4471
- openai: "OPENAI_API_KEY",
4472
- gemini: "GEMINI_API_KEY",
4473
- copilot: "COPILOT_GITHUB_TOKEN"
4474
- };
4475
- const encryptedKey = row.data.api_keys[keyMap[service]];
4476
- if (!encryptedKey) {
4477
- return null;
4521
+ if (!row) return null;
4522
+ const stored = row.data.agentic_tools;
4523
+ const fields = stored?.[tool];
4524
+ if (!fields || Object.keys(fields).length === 0) return null;
4525
+ const out = {};
4526
+ for (const [field, encrypted] of Object.entries(fields)) {
4527
+ if (!encrypted) continue;
4528
+ try {
4529
+ out[field] = decryptApiKey(encrypted);
4530
+ } catch (error) {
4531
+ console.error(
4532
+ `[users] Failed to decrypt ${tool}.${field} for user ${userId.substring(0, 8)}: ${error.message}`
4533
+ );
4534
+ }
4478
4535
  }
4536
+ return Object.keys(out).length > 0 ? out : null;
4537
+ }
4538
+ /**
4539
+ * Get a single decrypted credential field for a tool.
4540
+ *
4541
+ * Returns `null` when the field is unset OR when decryption fails (logged).
4542
+ * Throws only on storage-layer errors, not on missing/corrupt values.
4543
+ */
4544
+ async getToolConfigField(userId, tool, field) {
4545
+ const row = await this.getRawRow(userId);
4546
+ if (!row) return null;
4547
+ const stored = row.data.agentic_tools;
4548
+ const encrypted = stored?.[tool]?.[field];
4549
+ if (!encrypted) return null;
4479
4550
  try {
4480
- return decryptApiKey(encryptedKey);
4551
+ return decryptApiKey(encrypted);
4481
4552
  } catch (error) {
4482
- throw new RepositoryError(`Failed to decrypt API key for service ${service}`, error);
4553
+ console.error(
4554
+ `[users] Failed to decrypt ${tool}.${field} for user ${userId.substring(0, 8)}: ${error.message}`
4555
+ );
4556
+ return null;
4483
4557
  }
4484
4558
  }
4485
4559
  /**
4486
- * Set encrypted API key for a user and service
4560
+ * Set (encrypt + persist) a single credential field for a tool.
4487
4561
  *
4488
- * @param userId - User ID
4489
- * @param service - Service name ('anthropic', 'openai', 'gemini')
4490
- * @param apiKey - Plaintext API key to encrypt and store
4562
+ * Field names are env-var-shaped (e.g. ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL)
4563
+ * and are stored encrypted regardless of whether the value is a secret —
4564
+ * keeping the on-disk shape uniform avoids decrypt-vs-plain branching at
4565
+ * read time. UI controls own the text-vs-password rendering distinction.
4491
4566
  */
4492
- async setApiKey(userId, service, apiKey) {
4567
+ async setToolConfigField(userId, tool, field, value) {
4493
4568
  const fullId = await this.resolveId(userId);
4494
4569
  const row = await this.getRawRow(fullId);
4495
4570
  if (!row) {
4496
4571
  throw new EntityNotFoundError("User", userId);
4497
4572
  }
4498
- const keyMap = {
4499
- anthropic: "ANTHROPIC_API_KEY",
4500
- openai: "OPENAI_API_KEY",
4501
- gemini: "GEMINI_API_KEY",
4502
- copilot: "COPILOT_GITHUB_TOKEN"
4503
- };
4504
- const encryptedKey = encryptApiKey(apiKey);
4505
- const updatedApiKeys = {
4506
- ...row.data.api_keys || {},
4507
- [keyMap[service]]: encryptedKey
4508
- };
4509
- const user = this.rowToUser(row);
4510
- const updateData = {
4511
- ...user,
4512
- api_keys_raw: updatedApiKeys
4573
+ const stored = row.data.agentic_tools ?? {};
4574
+ const next = {
4575
+ ...stored,
4576
+ [tool]: {
4577
+ ...stored[tool] ?? {},
4578
+ [field]: encryptApiKey(value)
4579
+ }
4513
4580
  };
4514
- const insertData = this.userToInsert(updateData);
4515
4581
  await update(this.db, users3).set({
4516
- ...insertData,
4582
+ data: { ...row.data, agentic_tools: next },
4517
4583
  updated_at: /* @__PURE__ */ new Date()
4518
4584
  }).where((0, import_drizzle_orm24.eq)(users3.user_id, fullId)).run();
4519
4585
  }
4520
4586
  /**
4521
- * Delete API key for a user and service
4587
+ * Delete a single credential field for a tool.
4522
4588
  *
4523
- * @param userId - User ID
4524
- * @param service - Service name ('anthropic', 'openai', 'gemini')
4589
+ * If the tool's bucket becomes empty after the delete, the bucket itself is
4590
+ * removed so `data.agentic_tools` doesn't accumulate empty objects.
4525
4591
  */
4526
- async deleteApiKey(userId, service) {
4592
+ async deleteToolConfigField(userId, tool, field) {
4527
4593
  const fullId = await this.resolveId(userId);
4528
4594
  const row = await this.getRawRow(fullId);
4529
4595
  if (!row) {
4530
4596
  throw new EntityNotFoundError("User", userId);
4531
4597
  }
4532
- const keyMap = {
4533
- anthropic: "ANTHROPIC_API_KEY",
4534
- openai: "OPENAI_API_KEY",
4535
- gemini: "GEMINI_API_KEY",
4536
- copilot: "COPILOT_GITHUB_TOKEN"
4537
- };
4538
- const updatedApiKeys = { ...row.data.api_keys || {} };
4539
- delete updatedApiKeys[keyMap[service]];
4540
- const user = this.rowToUser(row);
4541
- const updateData = {
4542
- ...user,
4543
- api_keys_raw: updatedApiKeys
4544
- };
4545
- const insertData = this.userToInsert(updateData);
4598
+ const stored = row.data.agentic_tools ?? {};
4599
+ const toolFields = { ...stored[tool] ?? {} };
4600
+ delete toolFields[field];
4601
+ const next = { ...stored };
4602
+ if (Object.keys(toolFields).length > 0) {
4603
+ next[tool] = toolFields;
4604
+ } else {
4605
+ delete next[tool];
4606
+ }
4546
4607
  await update(this.db, users3).set({
4547
- ...insertData,
4608
+ data: { ...row.data, agentic_tools: next },
4548
4609
  updated_at: /* @__PURE__ */ new Date()
4549
4610
  }).where((0, import_drizzle_orm24.eq)(users3.user_id, fullId)).run();
4550
4611
  }
@@ -5084,14 +5145,7 @@ var WorktreeRepository = class {
5084
5145
  for (const sessionId of sessionIds) {
5085
5146
  const query = select(this.db, {
5086
5147
  data: messagesTable.data
5087
- }).from(messagesTable).where(
5088
- (0, import_drizzle_orm25.and)(
5089
- (0, import_drizzle_orm25.eq)(messagesTable.session_id, sessionId),
5090
- (0, import_drizzle_orm25.eq)(messagesTable.role, "assistant"),
5091
- (0, import_drizzle_orm25.isNull)(messagesTable.status)
5092
- // Exclude queued messages
5093
- )
5094
- );
5148
+ }).from(messagesTable).where((0, import_drizzle_orm25.and)((0, import_drizzle_orm25.eq)(messagesTable.session_id, sessionId), (0, import_drizzle_orm25.eq)(messagesTable.role, "assistant")));
5095
5149
  const lastMessage = await query.orderBy((0, import_drizzle_orm25.desc)(messagesTable.index)).limit(1).one();
5096
5150
  if (lastMessage) {
5097
5151
  const messageData = lastMessage.data;
@@ -1,21 +1,21 @@
1
1
  import { SpawnOptions, ChildProcess } from 'node:child_process';
2
- import { j as Database } from '../client-B5PyIvNc.cjs';
2
+ import { j as Database } from '../client-CemqXk0v.cjs';
3
3
  import { h as Worktree } from '../repo-Ckl-vaAk.cjs';
4
4
  import { R as RepoID, W as WorktreeID, e as UUID, f as UserID } from '../id-CoIbY_uc.cjs';
5
- import { U as UnixUserMode } from '../types-DNqfdt1z.cjs';
5
+ import { U as UnixUserMode } from '../types-D4Rl6ZKN.cjs';
6
6
  import 'drizzle-orm/libsql';
7
7
  import 'drizzle-orm/postgres-js';
8
8
  import 'drizzle-orm';
9
- import '../message-DinITA7a.cjs';
9
+ import '../message-CSWOsdcZ.cjs';
10
10
  import '../agentic-tool-BulhIUGb.cjs';
11
11
  import '../board-D7SnPqp-.cjs';
12
12
  import '../session-MNU4BQv4.cjs';
13
13
  import '../context-BpkCELpO.cjs';
14
- import '../task-wht1RJEL.cjs';
14
+ import '../task-C2Hy7H6u.cjs';
15
15
  import 'drizzle-orm/pg-core';
16
16
  import 'drizzle-orm/sqlite-core';
17
- import '../config-services-YEZ4DwCD.cjs';
18
- import '../user-DkNdeFoz.cjs';
17
+ import '../config-services-CXyQKEK5.cjs';
18
+ import '../user-CpfkcV2C.cjs';
19
19
 
20
20
  /**
21
21
  * Command Executor Interface
@@ -417,8 +417,7 @@ declare function spawnEnvironmentCommand(options: SpawnEnvironmentCommandOptions
417
417
  * These functions are designed to be called via `sudo agor admin` commands
418
418
  * to perform privileged operations safely.
419
419
  *
420
- * @see context/explorations/unix-user-modes.md
421
- * @see context/explorations/rbac.md
420
+ * @see context/guides/rbac-and-unix-isolation.md
422
421
  */
423
422
 
424
423
  /**
@@ -1,21 +1,21 @@
1
1
  import { SpawnOptions, ChildProcess } from 'node:child_process';
2
- import { j as Database } from '../client-C1CsRi19.js';
2
+ import { j as Database } from '../client-uYEOha6g.js';
3
3
  import { h as Worktree } from '../repo-84E0A2gV.js';
4
4
  import { R as RepoID, W as WorktreeID, e as UUID, f as UserID } from '../id-CoIbY_uc.js';
5
- import { U as UnixUserMode } from '../types-DqPMmTad.js';
5
+ import { U as UnixUserMode } from '../types-n61iaXub.js';
6
6
  import 'drizzle-orm/libsql';
7
7
  import 'drizzle-orm/postgres-js';
8
8
  import 'drizzle-orm';
9
- import '../message-CHUUP6OS.js';
9
+ import '../message-DZa8g0s0.js';
10
10
  import '../agentic-tool-cYqsU5i5.js';
11
11
  import '../board-D3YJ0_ih.js';
12
12
  import '../session-CAfhv1qL.js';
13
13
  import '../context-BpkCELpO.js';
14
- import '../task-BLPFCORT.js';
14
+ import '../task-BHV-YHg1.js';
15
15
  import 'drizzle-orm/pg-core';
16
16
  import 'drizzle-orm/sqlite-core';
17
- import '../config-services-DcO2GRgh.js';
18
- import '../user-BfVWBmXA.js';
17
+ import '../config-services-DhM7_yWn.js';
18
+ import '../user-DP-XZMIM.js';
19
19
 
20
20
  /**
21
21
  * Command Executor Interface
@@ -417,8 +417,7 @@ declare function spawnEnvironmentCommand(options: SpawnEnvironmentCommandOptions
417
417
  * These functions are designed to be called via `sudo agor admin` commands
418
418
  * to perform privileged operations safely.
419
419
  *
420
- * @see context/explorations/unix-user-modes.md
421
- * @see context/explorations/rbac.md
420
+ * @see context/guides/rbac-and-unix-isolation.md
422
421
  */
423
422
 
424
423
  /**