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,7 +1,7 @@
1
1
  import { AgorConfig } from '@agor/core/config';
2
2
  import { Database } from '@agor/core/db';
3
3
  import { Application } from '@agor/core/feathers';
4
- import { Params, TaskID } from '@agor/core/types';
4
+ import { Params, TaskID, AgenticToolName } from '@agor/core/types';
5
5
 
6
6
  /**
7
7
  * Config Service
@@ -37,6 +37,12 @@ declare class ConfigService {
37
37
  resolveApiKey(data: {
38
38
  taskId: TaskID;
39
39
  keyName: string;
40
+ /**
41
+ * Restrict the per-user lookup to this tool's credential bucket. Executors
42
+ * always pass this; absent it, the resolver falls back to a cross-tool
43
+ * sweep (legacy behavior preserved for non-SDK callers).
44
+ */
45
+ tool?: AgenticToolName;
40
46
  }): Promise<{
41
47
  apiKey: string | null;
42
48
  source: 'user' | 'config' | 'env' | 'native';
@@ -62,7 +62,7 @@ var ConfigService = class {
62
62
  * Called via: client.service('config').resolveApiKey({ taskId, keyName })
63
63
  */
64
64
  async resolveApiKey(data) {
65
- const { taskId, keyName } = data;
65
+ const { taskId, keyName, tool } = data;
66
66
  let userId;
67
67
  try {
68
68
  const tasksService = this.app?.service("tasks");
@@ -75,7 +75,8 @@ var ConfigService = class {
75
75
  }
76
76
  const result = await resolveApiKey(keyName, {
77
77
  userId,
78
- db: this.db
78
+ db: this.db,
79
+ tool
79
80
  });
80
81
  return {
81
82
  apiKey: result.apiKey ?? null,
@@ -12,8 +12,8 @@ import {
12
12
  hasConnector,
13
13
  parseGitHubThreadId
14
14
  } from "@agor/core/gateway";
15
- import { resolveModelConfig } from "@agor/core/models";
16
- import { getDefaultPermissionMode, SessionStatus } from "@agor/core/types";
15
+ import { resolveSessionDefaults } from "@agor/core/sessions";
16
+ import { SessionStatus } from "@agor/core/types";
17
17
  function hasListeningConfig(channel) {
18
18
  const config = channel.config;
19
19
  switch (channel.channel_type) {
@@ -333,9 +333,23 @@ var GatewayService = class {
333
333
  let mcpAuthWarning;
334
334
  const agenticConfig = channel.agentic_config;
335
335
  const agenticTool = agenticConfig?.agent ?? "claude-code";
336
- const userDefaults = user.default_agentic_config?.[agenticTool];
337
- const permissionMode = agenticConfig?.permissionMode ?? userDefaults?.permissionMode ?? getDefaultPermissionMode(agenticTool);
338
- const modelConfig = agenticConfig?.modelConfig ?? userDefaults?.modelConfig;
336
+ const {
337
+ permission_config: gatewayPermissionConfig,
338
+ model_config: gatewayModelConfig,
339
+ mcp_server_ids: gatewayMcpServerIds
340
+ } = resolveSessionDefaults({
341
+ agenticTool,
342
+ user,
343
+ overrides: {
344
+ permissionMode: agenticConfig?.permissionMode,
345
+ modelConfig: agenticConfig?.modelConfig,
346
+ codexSandboxMode: agenticConfig?.codexSandboxMode,
347
+ codexApprovalPolicy: agenticConfig?.codexApprovalPolicy,
348
+ codexNetworkAccess: agenticConfig?.codexNetworkAccess,
349
+ mcpServerIds: agenticConfig?.mcpServerIds
350
+ }
351
+ });
352
+ const permissionMode = gatewayPermissionConfig.mode;
339
353
  if (existingMapping) {
340
354
  sessionId = existingMapping.session_id;
341
355
  await this.threadMapRepo.updateLastMessage(existingMapping.id);
@@ -387,8 +401,8 @@ var GatewayService = class {
387
401
  unix_username: user.unix_username ?? null,
388
402
  status: SessionStatus.IDLE,
389
403
  agentic_tool: agenticTool,
390
- permission_config: { mode: permissionMode },
391
- model_config: resolveModelConfig(modelConfig),
404
+ permission_config: gatewayPermissionConfig,
405
+ model_config: gatewayModelConfig,
392
406
  tasks: [],
393
407
  // Denormalized gateway metadata (immutable snapshot at creation time)
394
408
  // Avoids N+1 lookups when rendering board cards
@@ -398,15 +412,14 @@ var GatewayService = class {
398
412
  });
399
413
  sessionId = session.session_id;
400
414
  created = true;
401
- const mcpServerIds = agenticConfig?.mcpServerIds;
402
- if (mcpServerIds && mcpServerIds.length > 0) {
415
+ if (gatewayMcpServerIds.length > 0) {
403
416
  await sessionsService.setMCPServers(
404
417
  session.session_id,
405
- mcpServerIds,
418
+ gatewayMcpServerIds,
406
419
  "gateway"
407
420
  );
408
421
  const unauthedMcpNames = [];
409
- for (const serverId of mcpServerIds) {
422
+ for (const serverId of gatewayMcpServerIds) {
410
423
  try {
411
424
  const server = await this.mcpServerRepo.findById(serverId);
412
425
  if (server?.auth?.type === "oauth") {
@@ -480,18 +493,18 @@ var GatewayService = class {
480
493
 
481
494
  ${promptText}`;
482
495
  }
483
- const response = await promptService.create(
496
+ const task = await promptService.create(
484
497
  { prompt: promptText, permissionMode, messageSource: "gateway" },
485
498
  { route: { id: sessionId }, user }
486
499
  );
487
- if (response.queued) {
500
+ if (task.status === "queued") {
488
501
  console.log(
489
- `[gateway] Message queued for session ${sessionId.substring(0, 8)} at position ${response.queue_position}`
502
+ `[gateway] Message queued for session ${sessionId.substring(0, 8)} at position ${task.queue_position}`
490
503
  );
491
504
  this.sendDebugMessage(
492
505
  channel,
493
506
  data.thread_id,
494
- `Session is busy, message queued at position ${response.queue_position}`
507
+ `Session is busy, message queued at position ${task.queue_position}`
495
508
  );
496
509
  } else {
497
510
  console.log(
@@ -1,5 +1,5 @@
1
1
  import { Database } from '@agor/core/db';
2
- import { QueryParams, MCPServer, CreateMCPServerInput, UpdateMCPServerInput, Paginated } from '@agor/core/types';
2
+ import { QueryParams, MCPServer, CreateMCPServerInput, UpdateMCPServerInput } from '@agor/core/types';
3
3
  import { DrizzleService } from '../adapters/drizzle.js';
4
4
 
5
5
  /**
@@ -28,7 +28,12 @@ declare class MCPServersService extends DrizzleService<MCPServer, CreateMCPServe
28
28
  /**
29
29
  * Override find to support filter params
30
30
  */
31
- find(params?: MCPServerParams): Promise<MCPServer[] | Paginated<MCPServer>>;
31
+ find(params?: MCPServerParams): Promise<MCPServer[] | {
32
+ total: number;
33
+ limit: number;
34
+ skip: number;
35
+ data: MCPServer[];
36
+ }>;
32
37
  /**
33
38
  * Custom method: Find by scope
34
39
  */
@@ -343,7 +343,9 @@ function spawnExecutorLocal(payload, options) {
343
343
  ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY,
344
344
  ANTHROPIC_AUTH_TOKEN: env.ANTHROPIC_AUTH_TOKEN,
345
345
  ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL,
346
+ CLAUDE_CODE_OAUTH_TOKEN: env.CLAUDE_CODE_OAUTH_TOKEN,
346
347
  OPENAI_API_KEY: env.OPENAI_API_KEY,
348
+ OPENAI_BASE_URL: env.OPENAI_BASE_URL,
347
349
  GEMINI_API_KEY: env.GEMINI_API_KEY,
348
350
  GOOGLE_API_KEY: env.GOOGLE_API_KEY
349
351
  }).filter(([_, v]) => v !== void 0)
@@ -135,7 +135,7 @@ declare class SessionsService extends DrizzleService<Session, Partial<Session>,
135
135
  /**
136
136
  * Custom method: Trigger queue processing
137
137
  *
138
- * Processes the next queued message for an idle session.
138
+ * Drains the next queued task for an idle session.
139
139
  * Used by callback system to trigger immediate queue processing.
140
140
  *
141
141
  * NOTE: The actual implementation is provided by index.ts via setQueueProcessor
@@ -8,6 +8,7 @@ import {
8
8
  } from "@agor/core/db";
9
9
  import { Forbidden as Forbidden2 } from "@agor/core/feathers";
10
10
  import { resolveModelConfig } from "@agor/core/models";
11
+ import { resolveSessionDefaults } from "@agor/core/sessions";
11
12
  import { ROLES as ROLES2, SessionStatus } from "@agor/core/types";
12
13
 
13
14
  // src/adapters/drizzle.ts
@@ -517,25 +518,16 @@ var SessionsService = class extends DrizzleService {
517
518
  if (userId && this.app) {
518
519
  try {
519
520
  const user = await this.app.service("users").get(userId, params);
520
- const toolDefaults = user?.default_agentic_config?.[targetTool];
521
- if (toolDefaults) {
522
- permissionConfig = {
523
- mode: toolDefaults.permissionMode,
524
- ...targetTool === "codex" && toolDefaults.codexSandboxMode && toolDefaults.codexApprovalPolicy ? {
525
- codex: {
526
- sandboxMode: toolDefaults.codexSandboxMode,
527
- approvalPolicy: toolDefaults.codexApprovalPolicy,
528
- networkAccess: toolDefaults.codexNetworkAccess
529
- }
530
- } : {}
531
- };
532
- modelConfig = resolveModelConfig(toolDefaults.modelConfig) ?? modelConfig;
533
- }
521
+ const userResolved = resolveSessionDefaults({ agenticTool: targetTool, user });
522
+ permissionConfig = userResolved.permission_config;
523
+ modelConfig = userResolved.model_config ?? modelConfig;
534
524
  } catch (error) {
535
525
  console.warn(
536
- "Could not fetch user preferences for spawned session, using parent settings:",
526
+ "Could not fetch user preferences for spawned session, using system defaults:",
537
527
  error
538
528
  );
529
+ const sysResolved = resolveSessionDefaults({ agenticTool: targetTool });
530
+ permissionConfig = sysResolved.permission_config;
539
531
  }
540
532
  }
541
533
  }
@@ -656,7 +648,7 @@ ${data.extraInstructions}`;
656
648
  /**
657
649
  * Custom method: Trigger queue processing
658
650
  *
659
- * Processes the next queued message for an idle session.
651
+ * Drains the next queued task for an idle session.
660
652
  * Used by callback system to trigger immediate queue processing.
661
653
  *
662
654
  * NOTE: The actual implementation is provided by index.ts via setQueueProcessor
@@ -465,7 +465,7 @@ var TasksService = class extends DrizzleService {
465
465
  promptText = typeof firstUser.content === "string" ? firstUser.content : Array.isArray(firstUser.content) ? firstUser.content.filter((b) => b.type === "text").map((b) => b.text || "").join("\n\n") : "";
466
466
  }
467
467
  if (!promptText) {
468
- promptText = task.description || btwSession.title || "(no prompt)";
468
+ promptText = task.full_prompt?.substring(0, 120) || btwSession.title || "(no prompt)";
469
469
  }
470
470
  const assistantMessages = messageList.filter((msg) => msg.role === "assistant").sort((a, b) => (b.index || 0) - (a.index || 0));
471
471
  let responseText = "";
@@ -547,7 +547,7 @@ var TasksService = class extends DrizzleService {
547
547
  return;
548
548
  }
549
549
  const includeOriginalPrompt = childSession.callback_config?.include_original_prompt ?? targetSession.callback_config?.include_original_prompt ?? false;
550
- const spawnPrompt = includeOriginalPrompt ? task.description || "(no prompt available)" : void 0;
550
+ const spawnPrompt = includeOriginalPrompt ? task.full_prompt?.substring(0, 120) || "(no prompt available)" : void 0;
551
551
  let lastAssistantMessage;
552
552
  const includeLastMessage = childSession.callback_config?.include_last_message ?? targetSession.callback_config?.include_last_message ?? true;
553
553
  if (includeLastMessage) {
@@ -596,7 +596,6 @@ var TasksService = class extends DrizzleService {
596
596
  };
597
597
  const customTemplate = targetSession.callback_config?.template;
598
598
  const callbackMessage = renderChildCompletionCallback(context, customTemplate);
599
- const messageRepo = new MessagesRepository(this.db);
600
599
  if (!targetSession.created_by) {
601
600
  console.warn(
602
601
  `\u26A0\uFE0F [TasksService] Cannot queue callback: target session ${targetSessionId.substring(0, 8)} has no creator (anonymous session)`
@@ -604,15 +603,22 @@ var TasksService = class extends DrizzleService {
604
603
  return;
605
604
  }
606
605
  const callbackCreator = childSession.callback_config?.callback_created_by ?? targetSession.created_by;
607
- await messageRepo.createQueued(targetSessionId, callbackMessage, {
608
- is_agor_callback: true,
609
- source: "agor",
610
- child_session_id: childSession.session_id,
611
- child_task_id: task.task_id,
612
- queued_by_user_id: callbackCreator
606
+ const callbackTask = await this.taskRepo.createPending({
607
+ session_id: targetSessionId,
608
+ full_prompt: callbackMessage,
609
+ created_by: callbackCreator,
610
+ status: TaskStatus.QUEUED,
611
+ metadata: {
612
+ is_agor_callback: true,
613
+ source: "agor",
614
+ child_session_id: childSession.session_id,
615
+ child_task_id: task.task_id,
616
+ queued_by_user_id: callbackCreator
617
+ }
613
618
  });
619
+ this.emit?.("queued", callbackTask);
614
620
  console.log(
615
- `\u{1F514} Queued callback to ${targetSessionId.substring(0, 8)} from child ${childSession.session_id.substring(0, 8)}`
621
+ `\u{1F514} Queued callback task ${callbackTask.task_id.substring(0, 8)} on session ${targetSessionId.substring(0, 8)} from child ${childSession.session_id.substring(0, 8)}`
616
622
  );
617
623
  } catch (error) {
618
624
  console.error(
@@ -114,7 +114,9 @@ function spawnExecutorLocal(payload, options) {
114
114
  ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY,
115
115
  ANTHROPIC_AUTH_TOKEN: env.ANTHROPIC_AUTH_TOKEN,
116
116
  ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL,
117
+ CLAUDE_CODE_OAUTH_TOKEN: env.CLAUDE_CODE_OAUTH_TOKEN,
117
118
  OPENAI_API_KEY: env.OPENAI_API_KEY,
119
+ OPENAI_BASE_URL: env.OPENAI_BASE_URL,
118
120
  GEMINI_API_KEY: env.GEMINI_API_KEY,
119
121
  GOOGLE_API_KEY: env.GOOGLE_API_KEY
120
122
  }).filter(([_, v]) => v !== void 0)
@@ -1,5 +1,5 @@
1
1
  import * as _agor_core_types from '@agor/core/types';
2
- import { Params, Paginated, User, UserID, UserRole, EnvVarScope } from '@agor/core/types';
2
+ import { Params, Paginated, User, UserID, UserRole, AgenticToolsUpdate, EnvVarScope, AgenticToolName, AgenticToolsConfig } from '@agor/core/types';
3
3
  import { Database } from '@agor/core/db';
4
4
 
5
5
  /**
@@ -28,11 +28,12 @@ interface UpdateUserData {
28
28
  avatar?: string;
29
29
  preferences?: Record<string, unknown>;
30
30
  onboarding_completed?: boolean;
31
- api_keys?: {
32
- ANTHROPIC_API_KEY?: string | null;
33
- OPENAI_API_KEY?: string | null;
34
- GEMINI_API_KEY?: string | null;
35
- };
31
+ /**
32
+ * Per-tool credential patch. Each tool's sub-object is a partial patch —
33
+ * `string` sets and encrypts, `null` clears, omitted fields are untouched.
34
+ * Field names are env var names exported into the SDK CLI environment.
35
+ */
36
+ agentic_tools?: AgenticToolsUpdate;
36
37
  env_vars?: Record<string, string | null>;
37
38
  env_var_scopes?: Record<string, EnvVarScope>;
38
39
  default_agentic_config?: _agor_core_types.DefaultAgenticConfig;
@@ -50,7 +51,7 @@ declare class UsersService {
50
51
  /**
51
52
  * Get user by ID
52
53
  */
53
- get(id: UserID, _params?: Params): Promise<User>;
54
+ get(id: UserID, params?: Params): Promise<User>;
54
55
  /**
55
56
  * Create new user
56
57
  */
@@ -58,7 +59,7 @@ declare class UsersService {
58
59
  /**
59
60
  * Update user
60
61
  */
61
- patch(id: UserID, data: UpdateUserData, _params?: Params): Promise<User>;
62
+ patch(id: UserID, data: UpdateUserData, params?: Params): Promise<User>;
62
63
  /**
63
64
  * Delete user
64
65
  */
@@ -72,10 +73,19 @@ declare class UsersService {
72
73
  */
73
74
  verifyPassword(user: User, password: string): Promise<boolean>;
74
75
  /**
75
- * Get decrypted API key for a user
76
- * Used by key resolution service
76
+ * Get a single decrypted credential field scoped to a specific agentic tool.
77
+ *
78
+ * Replaces the legacy flat-namespace `getApiKey(userId, 'ANTHROPIC_API_KEY')`
79
+ * call site with `(userId, 'claude-code', 'ANTHROPIC_API_KEY')` so an
80
+ * Anthropic key stored on the user can no longer leak into a Codex spawn.
81
+ */
82
+ getToolConfigField<T extends AgenticToolName>(userId: UserID, tool: T, field: keyof AgenticToolsConfig[T] & string): Promise<string | undefined>;
83
+ /**
84
+ * Get the full decrypted credential bag for one tool. Used when spawning an
85
+ * SDK so the executor environment receives only that tool's env vars.
86
+ * Returns `null` if the user has no stored config for the tool.
77
87
  */
78
- getApiKey(userId: UserID, keyName: 'ANTHROPIC_API_KEY' | 'OPENAI_API_KEY' | 'GEMINI_API_KEY'): Promise<string | undefined>;
88
+ getToolConfig<T extends AgenticToolName>(userId: UserID, tool: T): Promise<AgenticToolsConfig[T] | null>;
79
89
  /**
80
90
  * Get decrypted environment variables for a user (ALL scopes).
81
91
  *
@@ -89,6 +99,12 @@ declare class UsersService {
89
99
  *
90
100
  * @param row - Database row
91
101
  * @param includePassword - Include password field (for authentication only)
102
+ * @param requesterId - Authenticated user making the request. When equal to
103
+ * the row's `user_id`, the returned DTO includes `agentic_tools_public_values`
104
+ * (decrypted plaintext for the whitelisted non-secret fields like
105
+ * `OPENAI_BASE_URL` / `ANTHROPIC_BASE_URL`). For any other requester —
106
+ * including admins viewing someone else's profile — public values are
107
+ * omitted, since base URLs can leak internal hostnames.
92
108
  */
93
109
  private rowToUser;
94
110
  }
@@ -20,7 +20,38 @@ import {
20
20
  users
21
21
  } from "@agor/core/db";
22
22
  import { isLikelyGitToken } from "@agor/core/git";
23
- import { normalizeRole, ROLES } from "@agor/core/types";
23
+ import {
24
+ extractAgenticToolsPublicValues,
25
+ normalizeRole,
26
+ ROLES,
27
+ toAgenticToolsStatus
28
+ } from "@agor/core/types";
29
+ function applyAgenticToolsPatch(current, patch) {
30
+ const next = { ...current };
31
+ for (const [tool, fields] of Object.entries(patch)) {
32
+ if (!fields) continue;
33
+ const bucket = { ...next[tool] ?? {} };
34
+ for (const [field, value] of Object.entries(fields)) {
35
+ if (value === null || value === void 0) {
36
+ delete bucket[field];
37
+ } else {
38
+ try {
39
+ bucket[field] = encryptApiKey(value);
40
+ console.log(`\u{1F510} Encrypted user agentic_tools.${tool}.${field}`);
41
+ } catch (err) {
42
+ console.error(`Failed to encrypt agentic_tools.${tool}.${field}:`, err);
43
+ throw new Error(`Failed to encrypt agentic_tools.${tool}.${field}`);
44
+ }
45
+ }
46
+ }
47
+ if (Object.keys(bucket).length > 0) {
48
+ next[tool] = bucket;
49
+ } else {
50
+ delete next[tool];
51
+ }
52
+ }
53
+ return next;
54
+ }
24
55
  var UsersService = class {
25
56
  constructor(db) {
26
57
  this.db = db;
@@ -31,6 +62,7 @@ var UsersService = class {
31
62
  async find(params) {
32
63
  const email = params?.query?.email;
33
64
  const includePassword = !!email;
65
+ const requesterId = params?.user?.user_id;
34
66
  let rows;
35
67
  if (email) {
36
68
  const row = await select(this.db).from(users).where(eq(users.email, email)).one();
@@ -38,7 +70,7 @@ var UsersService = class {
38
70
  } else {
39
71
  rows = await select(this.db).from(users).all();
40
72
  }
41
- const results = rows.map((row) => this.rowToUser(row, includePassword));
73
+ const results = rows.map((row) => this.rowToUser(row, includePassword, requesterId));
42
74
  return {
43
75
  total: results.length,
44
76
  limit: results.length,
@@ -49,12 +81,13 @@ var UsersService = class {
49
81
  /**
50
82
  * Get user by ID
51
83
  */
52
- async get(id, _params) {
84
+ async get(id, params) {
53
85
  const row = await select(this.db).from(users).where(eq(users.user_id, id)).one();
54
86
  if (!row) {
55
87
  throw new Error(`User not found: ${id}`);
56
88
  }
57
- return this.rowToUser(row);
89
+ const requesterId = params?.user?.user_id;
90
+ return this.rowToUser(row, false, requesterId);
58
91
  }
59
92
  /**
60
93
  * Create new user
@@ -89,7 +122,7 @@ var UsersService = class {
89
122
  /**
90
123
  * Update user
91
124
  */
92
- async patch(id, data, _params) {
125
+ async patch(id, data, params) {
93
126
  const now = /* @__PURE__ */ new Date();
94
127
  const updates = { updated_at: now };
95
128
  if (data.password) {
@@ -105,26 +138,11 @@ var UsersService = class {
105
138
  if (data.unix_username !== void 0) updates.unix_username = data.unix_username;
106
139
  if (data.onboarding_completed !== void 0)
107
140
  updates.onboarding_completed = data.onboarding_completed;
108
- if (data.avatar || data.preferences || data.api_keys || data.env_vars || data.env_var_scopes || data.default_agentic_config) {
141
+ if (data.avatar || data.preferences || data.agentic_tools || data.env_vars || data.env_var_scopes || data.default_agentic_config) {
109
142
  const current = await this.get(id);
110
143
  const currentRow = await select(this.db).from(users).where(eq(users.user_id, id)).one();
111
144
  const currentData = currentRow?.data;
112
- const encryptedKeys = currentData?.api_keys || {};
113
- if (data.api_keys) {
114
- for (const [key, value] of Object.entries(data.api_keys)) {
115
- if (value === null || value === void 0) {
116
- delete encryptedKeys[key];
117
- } else {
118
- try {
119
- encryptedKeys[key] = encryptApiKey(value);
120
- console.log(`\u{1F510} Encrypted user API key: ${key}`);
121
- } catch (err) {
122
- console.error(`Failed to encrypt ${key}:`, err);
123
- throw new Error(`Failed to encrypt ${key}`);
124
- }
125
- }
126
- }
127
- }
145
+ const nextAgenticTools = data.agentic_tools ? applyAgenticToolsPatch(currentData?.agentic_tools ?? {}, data.agentic_tools) : currentData?.agentic_tools ?? {};
128
146
  const normalizedExisting = normalizeStoredEnvMap(currentData?.env_vars);
129
147
  const nextEnvVars = { ...normalizedExisting };
130
148
  if (data.env_vars) {
@@ -182,7 +200,7 @@ var UsersService = class {
182
200
  updates.data = {
183
201
  avatar: data.avatar ?? current.avatar,
184
202
  preferences: data.preferences ?? current.preferences,
185
- api_keys: Object.keys(encryptedKeys).length > 0 ? encryptedKeys : void 0,
203
+ agentic_tools: Object.keys(nextAgenticTools).length > 0 ? nextAgenticTools : void 0,
186
204
  env_vars: Object.keys(nextEnvVars).length > 0 ? nextEnvVars : void 0,
187
205
  default_agentic_config: data.default_agentic_config ?? current.default_agentic_config
188
206
  };
@@ -191,7 +209,8 @@ var UsersService = class {
191
209
  if (!row) {
192
210
  throw new Error(`User not found: ${id}`);
193
211
  }
194
- return this.rowToUser(row);
212
+ const requesterId = params?.user?.user_id;
213
+ return this.rowToUser(row, false, requesterId);
195
214
  }
196
215
  /**
197
216
  * Delete user
@@ -217,22 +236,47 @@ var UsersService = class {
217
236
  return compare(password, row.password);
218
237
  }
219
238
  /**
220
- * Get decrypted API key for a user
221
- * Used by key resolution service
239
+ * Get a single decrypted credential field scoped to a specific agentic tool.
240
+ *
241
+ * Replaces the legacy flat-namespace `getApiKey(userId, 'ANTHROPIC_API_KEY')`
242
+ * call site with `(userId, 'claude-code', 'ANTHROPIC_API_KEY')` so an
243
+ * Anthropic key stored on the user can no longer leak into a Codex spawn.
222
244
  */
223
- async getApiKey(userId, keyName) {
245
+ async getToolConfigField(userId, tool, field) {
224
246
  const row = await select(this.db).from(users).where(eq(users.user_id, userId)).one();
225
247
  if (!row) return void 0;
226
248
  const data = row.data;
227
- const encryptedKey = data.api_keys?.[keyName];
228
- if (!encryptedKey) return void 0;
249
+ const encrypted = data.agentic_tools?.[tool]?.[field];
250
+ if (!encrypted) return void 0;
229
251
  try {
230
- return decryptApiKey(encryptedKey);
252
+ return decryptApiKey(encrypted);
231
253
  } catch (err) {
232
- console.error(`Failed to decrypt ${keyName} for user ${userId}:`, err);
254
+ console.error(`Failed to decrypt agentic_tools.${tool}.${field} for user ${userId}:`, err);
233
255
  return void 0;
234
256
  }
235
257
  }
258
+ /**
259
+ * Get the full decrypted credential bag for one tool. Used when spawning an
260
+ * SDK so the executor environment receives only that tool's env vars.
261
+ * Returns `null` if the user has no stored config for the tool.
262
+ */
263
+ async getToolConfig(userId, tool) {
264
+ const row = await select(this.db).from(users).where(eq(users.user_id, userId)).one();
265
+ if (!row) return null;
266
+ const data = row.data;
267
+ const fields = data.agentic_tools?.[tool];
268
+ if (!fields || Object.keys(fields).length === 0) return null;
269
+ const out = {};
270
+ for (const [field, encrypted] of Object.entries(fields)) {
271
+ if (!encrypted) continue;
272
+ try {
273
+ out[field] = decryptApiKey(encrypted);
274
+ } catch (err) {
275
+ console.error(`Failed to decrypt agentic_tools.${tool}.${field} for user ${userId}:`, err);
276
+ }
277
+ }
278
+ return Object.keys(out).length > 0 ? out : null;
279
+ }
236
280
  /**
237
281
  * Get decrypted environment variables for a user (ALL scopes).
238
282
  *
@@ -260,8 +304,14 @@ var UsersService = class {
260
304
  *
261
305
  * @param row - Database row
262
306
  * @param includePassword - Include password field (for authentication only)
307
+ * @param requesterId - Authenticated user making the request. When equal to
308
+ * the row's `user_id`, the returned DTO includes `agentic_tools_public_values`
309
+ * (decrypted plaintext for the whitelisted non-secret fields like
310
+ * `OPENAI_BASE_URL` / `ANTHROPIC_BASE_URL`). For any other requester —
311
+ * including admins viewing someone else's profile — public values are
312
+ * omitted, since base URLs can leak internal hostnames.
263
313
  */
264
- rowToUser(row, includePassword = false) {
314
+ rowToUser(row, includePassword = false, requesterId) {
265
315
  const data = row.data;
266
316
  const normalizedEnvVars = normalizeStoredEnvMap(data.env_vars);
267
317
  const envVarMetadata = Object.keys(normalizedEnvVars).length > 0 ? Object.fromEntries(
@@ -283,12 +333,12 @@ var UsersService = class {
283
333
  must_change_password: !!row.must_change_password,
284
334
  created_at: row.created_at,
285
335
  updated_at: row.updated_at ?? void 0,
286
- // Return key status (boolean), NOT actual keys
287
- api_keys: data.api_keys ? {
288
- ANTHROPIC_API_KEY: !!data.api_keys.ANTHROPIC_API_KEY,
289
- OPENAI_API_KEY: !!data.api_keys.OPENAI_API_KEY,
290
- GEMINI_API_KEY: !!data.api_keys.GEMINI_API_KEY
291
- } : void 0,
336
+ // Per-tool credential presence (boolean only never expose decrypted values).
337
+ agentic_tools: toAgenticToolsStatus(data.agentic_tools),
338
+ // Self-only: return plaintext for whitelisted non-secret fields
339
+ // (base URLs) so the UI can render the saved value back. Field-level
340
+ // secrets are NEVER on the whitelist; see `AGENTIC_TOOLS_PUBLIC_FIELDS`.
341
+ agentic_tools_public_values: requesterId === row.user_id ? extractAgenticToolsPublicValues(data.agentic_tools, decryptApiKey) : void 0,
292
342
  // Return env var metadata (presence + scope), NOT actual values
293
343
  env_vars: envVarMetadata,
294
344
  // Return default agentic config
@@ -332,11 +382,7 @@ var UsersServiceWithAuth = class extends UsersService {
332
382
  must_change_password: !!row.must_change_password,
333
383
  created_at: row.created_at,
334
384
  updated_at: row.updated_at ?? void 0,
335
- api_keys: data.api_keys ? {
336
- ANTHROPIC_API_KEY: !!data.api_keys.ANTHROPIC_API_KEY,
337
- OPENAI_API_KEY: !!data.api_keys.OPENAI_API_KEY,
338
- GEMINI_API_KEY: !!data.api_keys.GEMINI_API_KEY
339
- } : void 0,
385
+ agentic_tools: toAgenticToolsStatus(data.agentic_tools),
340
386
  env_vars: envVarMetadata
341
387
  };
342
388
  }
@@ -99,7 +99,9 @@ function spawnExecutorLocal(payload, options) {
99
99
  ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY,
100
100
  ANTHROPIC_AUTH_TOKEN: env.ANTHROPIC_AUTH_TOKEN,
101
101
  ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL,
102
+ CLAUDE_CODE_OAUTH_TOKEN: env.CLAUDE_CODE_OAUTH_TOKEN,
102
103
  OPENAI_API_KEY: env.OPENAI_API_KEY,
104
+ OPENAI_BASE_URL: env.OPENAI_BASE_URL,
103
105
  GEMINI_API_KEY: env.GEMINI_API_KEY,
104
106
  GOOGLE_API_KEY: env.GOOGLE_API_KEY
105
107
  }).filter(([_, v]) => v !== void 0)
@@ -363,7 +363,9 @@ function spawnExecutorLocal(payload, options) {
363
363
  ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY,
364
364
  ANTHROPIC_AUTH_TOKEN: env.ANTHROPIC_AUTH_TOKEN,
365
365
  ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL,
366
+ CLAUDE_CODE_OAUTH_TOKEN: env.CLAUDE_CODE_OAUTH_TOKEN,
366
367
  OPENAI_API_KEY: env.OPENAI_API_KEY,
368
+ OPENAI_BASE_URL: env.OPENAI_BASE_URL,
367
369
  GEMINI_API_KEY: env.GEMINI_API_KEY,
368
370
  GOOGLE_API_KEY: env.GOOGLE_API_KEY
369
371
  }).filter(([_, v]) => v !== void 0)
@@ -313,6 +313,9 @@ function createTokenBucket(capacity, refillPerSec, now = Date.now) {
313
313
  return false;
314
314
  };
315
315
  }
316
+ function userRoomName(userId) {
317
+ return `user:${userId}`;
318
+ }
316
319
  function parseTerminalChannel(channel) {
317
320
  if (typeof channel !== "string") return null;
318
321
  if (!channel.startsWith("user/") || !channel.endsWith("/terminal")) return null;
@@ -406,7 +409,7 @@ function createSocketIOConfig(app, options) {
406
409
  });
407
410
  }
408
411
  if (user?.user_id) {
409
- socket.join(`user:${user.user_id}`);
412
+ socket.join(userRoomName(user.user_id));
410
413
  console.log(
411
414
  `\u{1F3E0} Socket ${socket.id} joined user room at connection: user:${user.user_id.substring(0, 8)}`
412
415
  );
@@ -601,7 +604,7 @@ function createSocketIOConfig(app, options) {
601
604
  if (!userId) return;
602
605
  for (const [, socket] of io.sockets.sockets) {
603
606
  if (socket.feathers === context.connection) {
604
- socket.join(`user:${userId}`);
607
+ socket.join(userRoomName(userId));
605
608
  console.log(
606
609
  `\u{1F3E0} Socket ${socket.id} joined user room after login: user:${userId.substring(0, 8)}`
607
610
  );