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
@@ -13,7 +13,7 @@ var session_token_service_exports = {};
13
13
  __export(session_token_service_exports, {
14
14
  SessionTokenService: () => SessionTokenService
15
15
  });
16
- import jwt2 from "jsonwebtoken";
16
+ import jwt3 from "jsonwebtoken";
17
17
  var SessionTokenService;
18
18
  var init_session_token_service = __esm({
19
19
  "src/services/session-token-service.ts"() {
@@ -56,7 +56,7 @@ var init_session_token_service = __esm({
56
56
  iss: "agor"
57
57
  // Must match Feathers jwtOptions.issuer
58
58
  };
59
- const token = jwt2.sign(payload, this.jwtSecret, {
59
+ const token = jwt3.sign(payload, this.jwtSecret, {
60
60
  algorithm: "HS256"
61
61
  // Must match Feathers jwtOptions.algorithm
62
62
  // No expiresIn here - we set exp directly in payload
@@ -183,7 +183,7 @@ import {
183
183
  MCP_TOKEN_AUDIENCE,
184
184
  MCP_TOKEN_ISSUER
185
185
  } from "@agor/core/types";
186
- import jwt3 from "jsonwebtoken";
186
+ import jwt4 from "jsonwebtoken";
187
187
  import { MCP_TOKEN_AUDIENCE as MCP_TOKEN_AUDIENCE2, MCP_TOKEN_ISSUER as MCP_TOKEN_ISSUER2 } from "@agor/core/types";
188
188
  function requireState() {
189
189
  if (!_state) {
@@ -230,7 +230,7 @@ async function generateSessionToken2(app, sessionId, userId) {
230
230
  exp: expSec,
231
231
  jti
232
232
  };
233
- const token = jwt3.sign(payload, jwtSecret, { algorithm: "HS256" });
233
+ const token = jwt4.sign(payload, jwtSecret, { algorithm: "HS256" });
234
234
  console.log(
235
235
  `\u{1F3AB} MCP token issued: session=${sessionId.substring(0, 8)} jti=${jti.substring(0, 8)} exp=+${Math.floor(s.expirationMs / 1e3)}s`
236
236
  );
@@ -245,15 +245,15 @@ async function validateSessionToken(app, token) {
245
245
  }
246
246
  let payload;
247
247
  try {
248
- payload = jwt3.verify(token, jwtSecret, {
248
+ payload = jwt4.verify(token, jwtSecret, {
249
249
  audience: MCP_TOKEN_AUDIENCE,
250
250
  issuer: MCP_TOKEN_ISSUER,
251
251
  algorithms: ["HS256"]
252
252
  });
253
253
  } catch (err) {
254
- if (err instanceof jwt3.TokenExpiredError) {
254
+ if (err instanceof jwt4.TokenExpiredError) {
255
255
  console.warn("[mcp-tokens] token rejected: expired");
256
- } else if (err instanceof jwt3.JsonWebTokenError) {
256
+ } else if (err instanceof jwt4.JsonWebTokenError) {
257
257
  console.warn(`[mcp-tokens] token rejected: ${err.message}`);
258
258
  } else {
259
259
  console.error("[mcp-tokens] token verify error:", err);
@@ -1956,7 +1956,7 @@ var ConfigService = class {
1956
1956
  * Called via: client.service('config').resolveApiKey({ taskId, keyName })
1957
1957
  */
1958
1958
  async resolveApiKey(data) {
1959
- const { taskId, keyName } = data;
1959
+ const { taskId, keyName, tool } = data;
1960
1960
  let userId;
1961
1961
  try {
1962
1962
  const tasksService = this.app?.service("tasks");
@@ -1969,7 +1969,8 @@ var ConfigService = class {
1969
1969
  }
1970
1970
  const result = await resolveApiKey(keyName, {
1971
1971
  userId,
1972
- db: this.db
1972
+ db: this.db,
1973
+ tool
1973
1974
  });
1974
1975
  return {
1975
1976
  apiKey: result.apiKey ?? null,
@@ -2600,8 +2601,8 @@ import {
2600
2601
  hasConnector,
2601
2602
  parseGitHubThreadId
2602
2603
  } from "@agor/core/gateway";
2603
- import { resolveModelConfig } from "@agor/core/models";
2604
- import { getDefaultPermissionMode, SessionStatus } from "@agor/core/types";
2604
+ import { resolveSessionDefaults } from "@agor/core/sessions";
2605
+ import { SessionStatus } from "@agor/core/types";
2605
2606
  function hasListeningConfig(channel) {
2606
2607
  const config = channel.config;
2607
2608
  switch (channel.channel_type) {
@@ -2921,9 +2922,23 @@ var GatewayService = class {
2921
2922
  let mcpAuthWarning;
2922
2923
  const agenticConfig = channel.agentic_config;
2923
2924
  const agenticTool = agenticConfig?.agent ?? "claude-code";
2924
- const userDefaults = user.default_agentic_config?.[agenticTool];
2925
- const permissionMode = agenticConfig?.permissionMode ?? userDefaults?.permissionMode ?? getDefaultPermissionMode(agenticTool);
2926
- const modelConfig = agenticConfig?.modelConfig ?? userDefaults?.modelConfig;
2925
+ const {
2926
+ permission_config: gatewayPermissionConfig,
2927
+ model_config: gatewayModelConfig,
2928
+ mcp_server_ids: gatewayMcpServerIds
2929
+ } = resolveSessionDefaults({
2930
+ agenticTool,
2931
+ user,
2932
+ overrides: {
2933
+ permissionMode: agenticConfig?.permissionMode,
2934
+ modelConfig: agenticConfig?.modelConfig,
2935
+ codexSandboxMode: agenticConfig?.codexSandboxMode,
2936
+ codexApprovalPolicy: agenticConfig?.codexApprovalPolicy,
2937
+ codexNetworkAccess: agenticConfig?.codexNetworkAccess,
2938
+ mcpServerIds: agenticConfig?.mcpServerIds
2939
+ }
2940
+ });
2941
+ const permissionMode = gatewayPermissionConfig.mode;
2927
2942
  if (existingMapping) {
2928
2943
  sessionId = existingMapping.session_id;
2929
2944
  await this.threadMapRepo.updateLastMessage(existingMapping.id);
@@ -2975,8 +2990,8 @@ var GatewayService = class {
2975
2990
  unix_username: user.unix_username ?? null,
2976
2991
  status: SessionStatus.IDLE,
2977
2992
  agentic_tool: agenticTool,
2978
- permission_config: { mode: permissionMode },
2979
- model_config: resolveModelConfig(modelConfig),
2993
+ permission_config: gatewayPermissionConfig,
2994
+ model_config: gatewayModelConfig,
2980
2995
  tasks: [],
2981
2996
  // Denormalized gateway metadata (immutable snapshot at creation time)
2982
2997
  // Avoids N+1 lookups when rendering board cards
@@ -2986,15 +3001,14 @@ var GatewayService = class {
2986
3001
  });
2987
3002
  sessionId = session.session_id;
2988
3003
  created = true;
2989
- const mcpServerIds = agenticConfig?.mcpServerIds;
2990
- if (mcpServerIds && mcpServerIds.length > 0) {
3004
+ if (gatewayMcpServerIds.length > 0) {
2991
3005
  await sessionsService.setMCPServers(
2992
3006
  session.session_id,
2993
- mcpServerIds,
3007
+ gatewayMcpServerIds,
2994
3008
  "gateway"
2995
3009
  );
2996
3010
  const unauthedMcpNames = [];
2997
- for (const serverId of mcpServerIds) {
3011
+ for (const serverId of gatewayMcpServerIds) {
2998
3012
  try {
2999
3013
  const server = await this.mcpServerRepo.findById(serverId);
3000
3014
  if (server?.auth?.type === "oauth") {
@@ -3068,18 +3082,18 @@ var GatewayService = class {
3068
3082
 
3069
3083
  ${promptText}`;
3070
3084
  }
3071
- const response = await promptService.create(
3085
+ const task = await promptService.create(
3072
3086
  { prompt: promptText, permissionMode, messageSource: "gateway" },
3073
3087
  { route: { id: sessionId }, user }
3074
3088
  );
3075
- if (response.queued) {
3089
+ if (task.status === "queued") {
3076
3090
  console.log(
3077
- `[gateway] Message queued for session ${sessionId.substring(0, 8)} at position ${response.queue_position}`
3091
+ `[gateway] Message queued for session ${sessionId.substring(0, 8)} at position ${task.queue_position}`
3078
3092
  );
3079
3093
  this.sendDebugMessage(
3080
3094
  channel,
3081
3095
  data.thread_id,
3082
- `Session is busy, message queued at position ${response.queue_position}`
3096
+ `Session is busy, message queued at position ${task.queue_position}`
3083
3097
  );
3084
3098
  } else {
3085
3099
  console.log(
@@ -4236,7 +4250,9 @@ function spawnExecutorLocal(payload, options) {
4236
4250
  ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY,
4237
4251
  ANTHROPIC_AUTH_TOKEN: env.ANTHROPIC_AUTH_TOKEN,
4238
4252
  ANTHROPIC_BASE_URL: env.ANTHROPIC_BASE_URL,
4253
+ CLAUDE_CODE_OAUTH_TOKEN: env.CLAUDE_CODE_OAUTH_TOKEN,
4239
4254
  OPENAI_API_KEY: env.OPENAI_API_KEY,
4255
+ OPENAI_BASE_URL: env.OPENAI_BASE_URL,
4240
4256
  GEMINI_API_KEY: env.GEMINI_API_KEY,
4241
4257
  GOOGLE_API_KEY: env.GOOGLE_API_KEY
4242
4258
  }).filter(([_, v]) => v !== void 0)
@@ -5072,7 +5088,8 @@ import {
5072
5088
  UsersRepository as UsersRepository2
5073
5089
  } from "@agor/core/db";
5074
5090
  import { Forbidden as Forbidden3 } from "@agor/core/feathers";
5075
- import { resolveModelConfig as resolveModelConfig2 } from "@agor/core/models";
5091
+ import { resolveModelConfig } from "@agor/core/models";
5092
+ import { resolveSessionDefaults as resolveSessionDefaults2 } from "@agor/core/sessions";
5076
5093
  import { ROLES as ROLES6, SessionStatus as SessionStatus2 } from "@agor/core/types";
5077
5094
 
5078
5095
  // src/utils/worktree-authorization.ts
@@ -5384,25 +5401,16 @@ var SessionsService = class extends DrizzleService {
5384
5401
  if (userId && this.app) {
5385
5402
  try {
5386
5403
  const user = await this.app.service("users").get(userId, params);
5387
- const toolDefaults = user?.default_agentic_config?.[targetTool];
5388
- if (toolDefaults) {
5389
- permissionConfig = {
5390
- mode: toolDefaults.permissionMode,
5391
- ...targetTool === "codex" && toolDefaults.codexSandboxMode && toolDefaults.codexApprovalPolicy ? {
5392
- codex: {
5393
- sandboxMode: toolDefaults.codexSandboxMode,
5394
- approvalPolicy: toolDefaults.codexApprovalPolicy,
5395
- networkAccess: toolDefaults.codexNetworkAccess
5396
- }
5397
- } : {}
5398
- };
5399
- modelConfig = resolveModelConfig2(toolDefaults.modelConfig) ?? modelConfig;
5400
- }
5404
+ const userResolved = resolveSessionDefaults2({ agenticTool: targetTool, user });
5405
+ permissionConfig = userResolved.permission_config;
5406
+ modelConfig = userResolved.model_config ?? modelConfig;
5401
5407
  } catch (error) {
5402
5408
  console.warn(
5403
- "Could not fetch user preferences for spawned session, using parent settings:",
5409
+ "Could not fetch user preferences for spawned session, using system defaults:",
5404
5410
  error
5405
5411
  );
5412
+ const sysResolved = resolveSessionDefaults2({ agenticTool: targetTool });
5413
+ permissionConfig = sysResolved.permission_config;
5406
5414
  }
5407
5415
  }
5408
5416
  }
@@ -5418,7 +5426,7 @@ var SessionsService = class extends DrizzleService {
5418
5426
  } : permissionConfig?.codex ? { codex: permissionConfig.codex } : {}
5419
5427
  };
5420
5428
  }
5421
- modelConfig = resolveModelConfig2(data.modelConfig) ?? modelConfig;
5429
+ modelConfig = resolveModelConfig(data.modelConfig) ?? modelConfig;
5422
5430
  const isCallbackEnabled = data.enableCallback !== false;
5423
5431
  const callbackConfig = {
5424
5432
  ...data.enableCallback !== void 0 ? { enabled: data.enableCallback } : {},
@@ -5523,7 +5531,7 @@ ${data.extraInstructions}`;
5523
5531
  /**
5524
5532
  * Custom method: Trigger queue processing
5525
5533
  *
5526
- * Processes the next queued message for an idle session.
5534
+ * Drains the next queued task for an idle session.
5527
5535
  * Used by callback system to trigger immediate queue processing.
5528
5536
  *
5529
5537
  * NOTE: The actual implementation is provided by index.ts via setQueueProcessor
@@ -5868,7 +5876,7 @@ var TasksService = class extends DrizzleService {
5868
5876
  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") : "";
5869
5877
  }
5870
5878
  if (!promptText) {
5871
- promptText = task.description || btwSession.title || "(no prompt)";
5879
+ promptText = task.full_prompt?.substring(0, 120) || btwSession.title || "(no prompt)";
5872
5880
  }
5873
5881
  const assistantMessages = messageList.filter((msg) => msg.role === "assistant").sort((a, b) => (b.index || 0) - (a.index || 0));
5874
5882
  let responseText = "";
@@ -5950,7 +5958,7 @@ var TasksService = class extends DrizzleService {
5950
5958
  return;
5951
5959
  }
5952
5960
  const includeOriginalPrompt = childSession.callback_config?.include_original_prompt ?? targetSession.callback_config?.include_original_prompt ?? false;
5953
- const spawnPrompt = includeOriginalPrompt ? task.description || "(no prompt available)" : void 0;
5961
+ const spawnPrompt = includeOriginalPrompt ? task.full_prompt?.substring(0, 120) || "(no prompt available)" : void 0;
5954
5962
  let lastAssistantMessage;
5955
5963
  const includeLastMessage = childSession.callback_config?.include_last_message ?? targetSession.callback_config?.include_last_message ?? true;
5956
5964
  if (includeLastMessage) {
@@ -5999,7 +6007,6 @@ var TasksService = class extends DrizzleService {
5999
6007
  };
6000
6008
  const customTemplate = targetSession.callback_config?.template;
6001
6009
  const callbackMessage = renderChildCompletionCallback(context, customTemplate);
6002
- const messageRepo = new MessagesRepository2(this.db);
6003
6010
  if (!targetSession.created_by) {
6004
6011
  console.warn(
6005
6012
  `\u26A0\uFE0F [TasksService] Cannot queue callback: target session ${targetSessionId.substring(0, 8)} has no creator (anonymous session)`
@@ -6007,15 +6014,22 @@ var TasksService = class extends DrizzleService {
6007
6014
  return;
6008
6015
  }
6009
6016
  const callbackCreator = childSession.callback_config?.callback_created_by ?? targetSession.created_by;
6010
- await messageRepo.createQueued(targetSessionId, callbackMessage, {
6011
- is_agor_callback: true,
6012
- source: "agor",
6013
- child_session_id: childSession.session_id,
6014
- child_task_id: task.task_id,
6015
- queued_by_user_id: callbackCreator
6017
+ const callbackTask = await this.taskRepo.createPending({
6018
+ session_id: targetSessionId,
6019
+ full_prompt: callbackMessage,
6020
+ created_by: callbackCreator,
6021
+ status: TaskStatus.QUEUED,
6022
+ metadata: {
6023
+ is_agor_callback: true,
6024
+ source: "agor",
6025
+ child_session_id: childSession.session_id,
6026
+ child_task_id: task.task_id,
6027
+ queued_by_user_id: callbackCreator
6028
+ }
6016
6029
  });
6030
+ this.emit?.("queued", callbackTask);
6017
6031
  console.log(
6018
- `\u{1F514} Queued callback to ${targetSessionId.substring(0, 8)} from child ${childSession.session_id.substring(0, 8)}`
6032
+ `\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)}`
6019
6033
  );
6020
6034
  } catch (error) {
6021
6035
  console.error(
@@ -6453,7 +6467,38 @@ import {
6453
6467
  users as users2
6454
6468
  } from "@agor/core/db";
6455
6469
  import { isLikelyGitToken } from "@agor/core/git";
6456
- import { normalizeRole, ROLES as ROLES7 } from "@agor/core/types";
6470
+ import {
6471
+ extractAgenticToolsPublicValues,
6472
+ normalizeRole,
6473
+ ROLES as ROLES7,
6474
+ toAgenticToolsStatus
6475
+ } from "@agor/core/types";
6476
+ function applyAgenticToolsPatch(current, patch) {
6477
+ const next = { ...current };
6478
+ for (const [tool, fields] of Object.entries(patch)) {
6479
+ if (!fields) continue;
6480
+ const bucket = { ...next[tool] ?? {} };
6481
+ for (const [field, value] of Object.entries(fields)) {
6482
+ if (value === null || value === void 0) {
6483
+ delete bucket[field];
6484
+ } else {
6485
+ try {
6486
+ bucket[field] = encryptApiKey(value);
6487
+ console.log(`\u{1F510} Encrypted user agentic_tools.${tool}.${field}`);
6488
+ } catch (err) {
6489
+ console.error(`Failed to encrypt agentic_tools.${tool}.${field}:`, err);
6490
+ throw new Error(`Failed to encrypt agentic_tools.${tool}.${field}`);
6491
+ }
6492
+ }
6493
+ }
6494
+ if (Object.keys(bucket).length > 0) {
6495
+ next[tool] = bucket;
6496
+ } else {
6497
+ delete next[tool];
6498
+ }
6499
+ }
6500
+ return next;
6501
+ }
6457
6502
  var UsersService = class {
6458
6503
  constructor(db) {
6459
6504
  this.db = db;
@@ -6464,6 +6509,7 @@ var UsersService = class {
6464
6509
  async find(params) {
6465
6510
  const email = params?.query?.email;
6466
6511
  const includePassword = !!email;
6512
+ const requesterId = params?.user?.user_id;
6467
6513
  let rows;
6468
6514
  if (email) {
6469
6515
  const row = await select(this.db).from(users2).where(eq2(users2.email, email)).one();
@@ -6471,7 +6517,7 @@ var UsersService = class {
6471
6517
  } else {
6472
6518
  rows = await select(this.db).from(users2).all();
6473
6519
  }
6474
- const results = rows.map((row) => this.rowToUser(row, includePassword));
6520
+ const results = rows.map((row) => this.rowToUser(row, includePassword, requesterId));
6475
6521
  return {
6476
6522
  total: results.length,
6477
6523
  limit: results.length,
@@ -6482,12 +6528,13 @@ var UsersService = class {
6482
6528
  /**
6483
6529
  * Get user by ID
6484
6530
  */
6485
- async get(id, _params) {
6531
+ async get(id, params) {
6486
6532
  const row = await select(this.db).from(users2).where(eq2(users2.user_id, id)).one();
6487
6533
  if (!row) {
6488
6534
  throw new Error(`User not found: ${id}`);
6489
6535
  }
6490
- return this.rowToUser(row);
6536
+ const requesterId = params?.user?.user_id;
6537
+ return this.rowToUser(row, false, requesterId);
6491
6538
  }
6492
6539
  /**
6493
6540
  * Create new user
@@ -6522,7 +6569,7 @@ var UsersService = class {
6522
6569
  /**
6523
6570
  * Update user
6524
6571
  */
6525
- async patch(id, data, _params) {
6572
+ async patch(id, data, params) {
6526
6573
  const now = /* @__PURE__ */ new Date();
6527
6574
  const updates = { updated_at: now };
6528
6575
  if (data.password) {
@@ -6538,26 +6585,11 @@ var UsersService = class {
6538
6585
  if (data.unix_username !== void 0) updates.unix_username = data.unix_username;
6539
6586
  if (data.onboarding_completed !== void 0)
6540
6587
  updates.onboarding_completed = data.onboarding_completed;
6541
- if (data.avatar || data.preferences || data.api_keys || data.env_vars || data.env_var_scopes || data.default_agentic_config) {
6588
+ if (data.avatar || data.preferences || data.agentic_tools || data.env_vars || data.env_var_scopes || data.default_agentic_config) {
6542
6589
  const current = await this.get(id);
6543
6590
  const currentRow = await select(this.db).from(users2).where(eq2(users2.user_id, id)).one();
6544
6591
  const currentData = currentRow?.data;
6545
- const encryptedKeys = currentData?.api_keys || {};
6546
- if (data.api_keys) {
6547
- for (const [key, value] of Object.entries(data.api_keys)) {
6548
- if (value === null || value === void 0) {
6549
- delete encryptedKeys[key];
6550
- } else {
6551
- try {
6552
- encryptedKeys[key] = encryptApiKey(value);
6553
- console.log(`\u{1F510} Encrypted user API key: ${key}`);
6554
- } catch (err) {
6555
- console.error(`Failed to encrypt ${key}:`, err);
6556
- throw new Error(`Failed to encrypt ${key}`);
6557
- }
6558
- }
6559
- }
6560
- }
6592
+ const nextAgenticTools = data.agentic_tools ? applyAgenticToolsPatch(currentData?.agentic_tools ?? {}, data.agentic_tools) : currentData?.agentic_tools ?? {};
6561
6593
  const normalizedExisting = normalizeStoredEnvMap(currentData?.env_vars);
6562
6594
  const nextEnvVars = { ...normalizedExisting };
6563
6595
  if (data.env_vars) {
@@ -6615,7 +6647,7 @@ var UsersService = class {
6615
6647
  updates.data = {
6616
6648
  avatar: data.avatar ?? current.avatar,
6617
6649
  preferences: data.preferences ?? current.preferences,
6618
- api_keys: Object.keys(encryptedKeys).length > 0 ? encryptedKeys : void 0,
6650
+ agentic_tools: Object.keys(nextAgenticTools).length > 0 ? nextAgenticTools : void 0,
6619
6651
  env_vars: Object.keys(nextEnvVars).length > 0 ? nextEnvVars : void 0,
6620
6652
  default_agentic_config: data.default_agentic_config ?? current.default_agentic_config
6621
6653
  };
@@ -6624,7 +6656,8 @@ var UsersService = class {
6624
6656
  if (!row) {
6625
6657
  throw new Error(`User not found: ${id}`);
6626
6658
  }
6627
- return this.rowToUser(row);
6659
+ const requesterId = params?.user?.user_id;
6660
+ return this.rowToUser(row, false, requesterId);
6628
6661
  }
6629
6662
  /**
6630
6663
  * Delete user
@@ -6650,22 +6683,47 @@ var UsersService = class {
6650
6683
  return compare(password, row.password);
6651
6684
  }
6652
6685
  /**
6653
- * Get decrypted API key for a user
6654
- * Used by key resolution service
6686
+ * Get a single decrypted credential field scoped to a specific agentic tool.
6687
+ *
6688
+ * Replaces the legacy flat-namespace `getApiKey(userId, 'ANTHROPIC_API_KEY')`
6689
+ * call site with `(userId, 'claude-code', 'ANTHROPIC_API_KEY')` so an
6690
+ * Anthropic key stored on the user can no longer leak into a Codex spawn.
6655
6691
  */
6656
- async getApiKey(userId, keyName) {
6692
+ async getToolConfigField(userId, tool, field) {
6657
6693
  const row = await select(this.db).from(users2).where(eq2(users2.user_id, userId)).one();
6658
6694
  if (!row) return void 0;
6659
6695
  const data = row.data;
6660
- const encryptedKey = data.api_keys?.[keyName];
6661
- if (!encryptedKey) return void 0;
6696
+ const encrypted = data.agentic_tools?.[tool]?.[field];
6697
+ if (!encrypted) return void 0;
6662
6698
  try {
6663
- return decryptApiKey(encryptedKey);
6699
+ return decryptApiKey(encrypted);
6664
6700
  } catch (err) {
6665
- console.error(`Failed to decrypt ${keyName} for user ${userId}:`, err);
6701
+ console.error(`Failed to decrypt agentic_tools.${tool}.${field} for user ${userId}:`, err);
6666
6702
  return void 0;
6667
6703
  }
6668
6704
  }
6705
+ /**
6706
+ * Get the full decrypted credential bag for one tool. Used when spawning an
6707
+ * SDK so the executor environment receives only that tool's env vars.
6708
+ * Returns `null` if the user has no stored config for the tool.
6709
+ */
6710
+ async getToolConfig(userId, tool) {
6711
+ const row = await select(this.db).from(users2).where(eq2(users2.user_id, userId)).one();
6712
+ if (!row) return null;
6713
+ const data = row.data;
6714
+ const fields = data.agentic_tools?.[tool];
6715
+ if (!fields || Object.keys(fields).length === 0) return null;
6716
+ const out = {};
6717
+ for (const [field, encrypted] of Object.entries(fields)) {
6718
+ if (!encrypted) continue;
6719
+ try {
6720
+ out[field] = decryptApiKey(encrypted);
6721
+ } catch (err) {
6722
+ console.error(`Failed to decrypt agentic_tools.${tool}.${field} for user ${userId}:`, err);
6723
+ }
6724
+ }
6725
+ return Object.keys(out).length > 0 ? out : null;
6726
+ }
6669
6727
  /**
6670
6728
  * Get decrypted environment variables for a user (ALL scopes).
6671
6729
  *
@@ -6693,8 +6751,14 @@ var UsersService = class {
6693
6751
  *
6694
6752
  * @param row - Database row
6695
6753
  * @param includePassword - Include password field (for authentication only)
6696
- */
6697
- rowToUser(row, includePassword = false) {
6754
+ * @param requesterId - Authenticated user making the request. When equal to
6755
+ * the row's `user_id`, the returned DTO includes `agentic_tools_public_values`
6756
+ * (decrypted plaintext for the whitelisted non-secret fields like
6757
+ * `OPENAI_BASE_URL` / `ANTHROPIC_BASE_URL`). For any other requester —
6758
+ * including admins viewing someone else's profile — public values are
6759
+ * omitted, since base URLs can leak internal hostnames.
6760
+ */
6761
+ rowToUser(row, includePassword = false, requesterId) {
6698
6762
  const data = row.data;
6699
6763
  const normalizedEnvVars = normalizeStoredEnvMap(data.env_vars);
6700
6764
  const envVarMetadata = Object.keys(normalizedEnvVars).length > 0 ? Object.fromEntries(
@@ -6716,12 +6780,12 @@ var UsersService = class {
6716
6780
  must_change_password: !!row.must_change_password,
6717
6781
  created_at: row.created_at,
6718
6782
  updated_at: row.updated_at ?? void 0,
6719
- // Return key status (boolean), NOT actual keys
6720
- api_keys: data.api_keys ? {
6721
- ANTHROPIC_API_KEY: !!data.api_keys.ANTHROPIC_API_KEY,
6722
- OPENAI_API_KEY: !!data.api_keys.OPENAI_API_KEY,
6723
- GEMINI_API_KEY: !!data.api_keys.GEMINI_API_KEY
6724
- } : void 0,
6783
+ // Per-tool credential presence (boolean only never expose decrypted values).
6784
+ agentic_tools: toAgenticToolsStatus(data.agentic_tools),
6785
+ // Self-only: return plaintext for whitelisted non-secret fields
6786
+ // (base URLs) so the UI can render the saved value back. Field-level
6787
+ // secrets are NEVER on the whitelist; see `AGENTIC_TOOLS_PUBLIC_FIELDS`.
6788
+ agentic_tools_public_values: requesterId === row.user_id ? extractAgenticToolsPublicValues(data.agentic_tools, decryptApiKey) : void 0,
6725
6789
  // Return env var metadata (presence + scope), NOT actual values
6726
6790
  env_vars: envVarMetadata,
6727
6791
  // Return default agentic config
@@ -6765,11 +6829,7 @@ var UsersServiceWithAuth = class extends UsersService {
6765
6829
  must_change_password: !!row.must_change_password,
6766
6830
  created_at: row.created_at,
6767
6831
  updated_at: row.updated_at ?? void 0,
6768
- api_keys: data.api_keys ? {
6769
- ANTHROPIC_API_KEY: !!data.api_keys.ANTHROPIC_API_KEY,
6770
- OPENAI_API_KEY: !!data.api_keys.OPENAI_API_KEY,
6771
- GEMINI_API_KEY: !!data.api_keys.GEMINI_API_KEY
6772
- } : void 0,
6832
+ agentic_tools: toAgenticToolsStatus(data.agentic_tools),
6773
6833
  env_vars: envVarMetadata
6774
6834
  };
6775
6835
  }
@@ -8107,6 +8167,12 @@ function createWorktreesService(db, app) {
8107
8167
  return new WorktreesService(db, app);
8108
8168
  }
8109
8169
 
8170
+ // src/setup/socketio.ts
8171
+ import jwt2 from "jsonwebtoken";
8172
+ function userRoomName(userId) {
8173
+ return `user:${userId}`;
8174
+ }
8175
+
8110
8176
  // src/utils/session-state.ts
8111
8177
  import { createHash as createHash2 } from "crypto";
8112
8178
  import { createReadStream, createWriteStream } from "fs";
@@ -8330,10 +8396,18 @@ async function registerServices(ctx) {
8330
8396
  createExecuteHandler(ctx, sessionsService, sessionTokenService)
8331
8397
  );
8332
8398
  app.use("/tasks", createTasksService(db, app), {
8333
- // 'failed' is emitted by the prompt route when executor spawn throws so
8334
- // clients can surface the error instead of silently seeing an idle
8335
- // session with a ghost task.
8336
- events: ["tool:start", "tool:complete", "thinking:chunk", "failed"]
8399
+ // Custom events not in this list are dropped at the FeathersJS transport
8400
+ // boundary they fire on the local EventEmitter but never reach socket
8401
+ // clients. Keep this in sync with every `app.service('tasks').emit(...)`
8402
+ // call site.
8403
+ // - 'queued': prompt route auto-queues a task (session not idle / queue
8404
+ // not empty) — UI's queue drawer subscribes to this.
8405
+ // - 'failed': prompt route reports executor-spawn failures so clients
8406
+ // surface the error instead of seeing an idle session with a ghost
8407
+ // task.
8408
+ // - 'tool:start' / 'tool:complete' / 'thinking:chunk': forwarded from
8409
+ // the executor for live tool/thinking visualization.
8410
+ events: ["queued", "tool:start", "tool:complete", "thinking:chunk", "failed"]
8337
8411
  });
8338
8412
  if (svcEnabled("leaderboard")) {
8339
8413
  app.use("/leaderboard", createLeaderboardService(db));
@@ -8667,7 +8741,8 @@ ${possiblePaths.map((p) => ` - ${p}`).join("\n")}`
8667
8741
  void 0,
8668
8742
  !!executorUnixUser,
8669
8743
  gatewayEnv,
8670
- sessionId
8744
+ sessionId,
8745
+ session.agentic_tool
8671
8746
  );
8672
8747
  const { SessionRepository: SessRepo, MessagesRepository: _MsgRepo } = await import("@agor/core/db");
8673
8748
  const sessionsRepository = new SessRepo(db);
@@ -8897,6 +8972,7 @@ async function registerMCPServices(ctx, sessionsService) {
8897
8972
  }
8898
8973
  }
8899
8974
  }, 6e4);
8975
+ const DISCOVERY_CASCADE_TRIED = "Tried: (1) WWW-Authenticate resource_metadata hint, (2) /.well-known/oauth-protected-resource (RFC 9728), (3) /.well-known/oauth-authorization-server at MCP origin (RFC 8414), (4) /.well-known/openid-configuration at MCP origin (OIDC).";
8900
8976
  async function startTwoPhaseMCPOAuthFlow(opts) {
8901
8977
  return startTwoPhaseMCPOAuthFlowInternal(opts, false);
8902
8978
  }
@@ -8910,12 +8986,23 @@ async function registerMCPServices(ctx, sessionsService) {
8910
8986
  const { startMCPOAuthFlow } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
8911
8987
  const baseUrl = await requirePublicBaseUrl();
8912
8988
  const redirectUri = new URL("/mcp-servers/oauth-callback", baseUrl).toString();
8989
+ const hasRfc9728 = !!opts.resourceMetadataUrl;
8990
+ const hasAsDirect = !!opts.prefetchedAuthServerMetadata;
8991
+ if (hasRfc9728 === hasAsDirect) {
8992
+ throw new Error(
8993
+ `startTwoPhaseMCPOAuthFlow requires exactly one of resourceMetadataUrl (RFC 9728) or prefetchedAuthServerMetadata (AS-direct discovery), received resourceMetadataUrl=${hasRfc9728}, prefetchedAuthServerMetadata=${hasAsDirect}.`
8994
+ );
8995
+ }
8913
8996
  const context = await startMCPOAuthFlow(opts.wwwAuthenticate, opts.clientId, redirectUri, {
8914
8997
  authorizationUrlOverride: opts.authorizationUrlOverride,
8915
8998
  tokenUrlOverride: opts.tokenUrlOverride,
8916
8999
  clientSecret: opts.clientSecret,
8917
9000
  scope: opts.scope,
8918
- resourceMetadataUrl: opts.resourceMetadataUrl
9001
+ resourceMetadataUrl: opts.resourceMetadataUrl,
9002
+ prefetchedAuthServerMetadata: opts.prefetchedAuthServerMetadata,
9003
+ // Cache key for AS-direct path: use the MCP URL itself (origin matches
9004
+ // what `getCachedOAuth21Token` looks up later).
9005
+ cacheKey: opts.prefetchedAuthServerMetadata ? opts.mcpUrl : void 0
8919
9006
  });
8920
9007
  let tokenPromise;
8921
9008
  let tokenResolve;
@@ -9033,10 +9120,16 @@ async function registerMCPServices(ctx, sessionsService) {
9033
9120
  mcp_server_id: pendingFlow.mcpServerId,
9034
9121
  oauth_mode: pendingFlow.oauthMode || "per_user"
9035
9122
  };
9036
- if (pendingFlow.socketId) {
9123
+ if (oauthEvent.oauth_mode === "per_user" && pendingFlow.userId) {
9124
+ app.io.to(userRoomName(pendingFlow.userId)).emit("oauth:completed", oauthEvent);
9125
+ } else if (oauthEvent.oauth_mode === "shared") {
9126
+ app.io.emit("oauth:completed", oauthEvent);
9127
+ } else if (pendingFlow.socketId) {
9037
9128
  app.io.to(pendingFlow.socketId).emit("oauth:completed", oauthEvent);
9038
9129
  } else {
9039
- app.io.emit("oauth:completed", oauthEvent);
9130
+ console.warn(
9131
+ `[OAuth Callback] per_user flow ${state} has no userId or socketId \u2014 skipping oauth:completed emit (UI will catch up on next mcp-servers find)`
9132
+ );
9040
9133
  }
9041
9134
  }
9042
9135
  pendingFlow.tokenResolve?.(tokenResponse);
@@ -9114,15 +9207,22 @@ async function registerMCPServices(ctx, sessionsService) {
9114
9207
  headers: allHeaders
9115
9208
  });
9116
9209
  let metadataUrl = null;
9210
+ let prefetchedAuthServerMetadata = null;
9211
+ let discoverySource = null;
9117
9212
  if (probeResponse.status === 401) {
9118
- const { resolveResourceMetadataUrl } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
9119
- const resolved = await resolveResourceMetadataUrl(wwwAuthenticate, data.mcp_url);
9120
- if (resolved) {
9121
- metadataUrl = resolved.metadataUrl;
9122
- console.log(`[OAuth Test] Resolved metadata URL (${resolved.source}):`, metadataUrl);
9213
+ const { resolveMCPOAuthDiscovery } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
9214
+ const discovery = await resolveMCPOAuthDiscovery(wwwAuthenticate, data.mcp_url);
9215
+ if (discovery?.kind === "resource-metadata") {
9216
+ metadataUrl = discovery.metadataUrl;
9217
+ discoverySource = `RFC 9728 ${discovery.source}`;
9218
+ console.log(`[OAuth Test] Resolved metadata URL (${discovery.source}):`, metadataUrl);
9219
+ } else if (discovery?.kind === "authorization-server") {
9220
+ prefetchedAuthServerMetadata = discovery.authServerMetadata;
9221
+ discoverySource = `AS-direct (${discovery.discoveredAt})`;
9222
+ console.log("[OAuth Test] Resolved AS metadata directly at:", discovery.discoveredAt);
9123
9223
  }
9124
9224
  }
9125
- if (probeResponse.status === 401 && metadataUrl) {
9225
+ if (probeResponse.status === 401 && (metadataUrl || prefetchedAuthServerMetadata)) {
9126
9226
  console.log("[OAuth Test] OAuth 2.1 auto-discovery detected");
9127
9227
  if (data.start_browser_flow) {
9128
9228
  console.log("[OAuth Test] Starting browser-based OAuth 2.1 flow...");
@@ -9133,7 +9233,8 @@ async function registerMCPServices(ctx, sessionsService) {
9133
9233
  started = await startTwoPhaseMCPOAuthFlowAndAwaitToken({
9134
9234
  mcpUrl: data.mcp_url,
9135
9235
  wwwAuthenticate: wwwAuthenticate || "",
9136
- resourceMetadataUrl: metadataUrl,
9236
+ resourceMetadataUrl: metadataUrl ?? void 0,
9237
+ prefetchedAuthServerMetadata: prefetchedAuthServerMetadata ?? void 0,
9137
9238
  mcpServerId: data.mcp_server_id,
9138
9239
  userId: params?.user?.user_id,
9139
9240
  // Test endpoint mirrors the previous saveOAuth21TokenToDB
@@ -9177,13 +9278,29 @@ async function registerMCPServices(ctx, sessionsService) {
9177
9278
  }
9178
9279
  }
9179
9280
  try {
9180
- const metadataResponse = await fetch(metadataUrl);
9281
+ if (prefetchedAuthServerMetadata) {
9282
+ return {
9283
+ success: true,
9284
+ oauthType: "oauth2.1",
9285
+ message: prefetchedAuthServerMetadata.registration_endpoint ? `OAuth 2.1 auto-discovery successful via ${discoverySource} (DCR supported). Click "Start OAuth Flow" to authenticate.` : `OAuth 2.1 auto-discovery successful via ${discoverySource}. Click "Start OAuth Flow" to authenticate.`,
9286
+ authServerMetadata: {
9287
+ authorizationEndpoint: prefetchedAuthServerMetadata.authorization_endpoint,
9288
+ tokenEndpoint: prefetchedAuthServerMetadata.token_endpoint,
9289
+ registrationEndpoint: prefetchedAuthServerMetadata.registration_endpoint
9290
+ },
9291
+ supportsDynamicClientRegistration: !!prefetchedAuthServerMetadata.registration_endpoint,
9292
+ requiresBrowserFlow: true,
9293
+ discoverySource
9294
+ };
9295
+ }
9296
+ const rfc9728Url = metadataUrl;
9297
+ const metadataResponse = await fetch(rfc9728Url);
9181
9298
  if (!metadataResponse.ok) {
9182
9299
  return {
9183
9300
  success: false,
9184
9301
  error: `OAuth resource metadata endpoint returned ${metadataResponse.status}`,
9185
9302
  oauthType: "oauth2.1",
9186
- metadataUrl,
9303
+ metadataUrl: rfc9728Url,
9187
9304
  requiresBrowserFlow: true
9188
9305
  };
9189
9306
  }
@@ -9193,31 +9310,27 @@ async function registerMCPServices(ctx, sessionsService) {
9193
9310
  success: false,
9194
9311
  error: "OAuth resource metadata missing authorization_servers",
9195
9312
  oauthType: "oauth2.1",
9196
- metadataUrl,
9313
+ metadataUrl: rfc9728Url,
9197
9314
  metadata
9198
9315
  };
9199
9316
  }
9200
9317
  const authServerUrl = metadata.authorization_servers[0];
9318
+ const { fetchAuthorizationServerMetadata } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
9201
9319
  let authServerMetadata = null;
9202
- for (const wellKnownPath of [
9203
- "/.well-known/oauth-authorization-server",
9204
- "/.well-known/openid-configuration"
9205
- ]) {
9206
- try {
9207
- const authMetaResponse = await fetch(`${authServerUrl}${wellKnownPath}`);
9208
- if (authMetaResponse.ok) {
9209
- authServerMetadata = await authMetaResponse.json();
9210
- console.log("[OAuth Test] Auth server metadata:", authServerMetadata);
9211
- break;
9212
- }
9213
- } catch {
9214
- }
9320
+ try {
9321
+ authServerMetadata = await fetchAuthorizationServerMetadata(authServerUrl);
9322
+ console.log("[OAuth Test] Auth server metadata:", authServerMetadata);
9323
+ } catch (asMetaError) {
9324
+ console.log(
9325
+ "[OAuth Test] Auth server metadata unavailable:",
9326
+ asMetaError instanceof Error ? asMetaError.message : String(asMetaError)
9327
+ );
9215
9328
  }
9216
9329
  return {
9217
9330
  success: true,
9218
9331
  oauthType: "oauth2.1",
9219
9332
  message: authServerMetadata?.registration_endpoint ? 'OAuth 2.1 auto-discovery successful (DCR supported). Click "Start OAuth Flow" to authenticate.' : 'OAuth 2.1 auto-discovery successful. Click "Start OAuth Flow" to authenticate.',
9220
- metadataUrl,
9333
+ metadataUrl: rfc9728Url,
9221
9334
  authorizationServers: metadata.authorization_servers,
9222
9335
  scopesSupported: metadata.scopes_supported,
9223
9336
  authServerMetadata: authServerMetadata ? {
@@ -9233,7 +9346,7 @@ async function registerMCPServices(ctx, sessionsService) {
9233
9346
  success: false,
9234
9347
  error: `Failed to fetch OAuth metadata: ${metadataError instanceof Error ? metadataError.message : String(metadataError)}`,
9235
9348
  oauthType: "oauth2.1",
9236
- metadataUrl
9349
+ metadataUrl: metadataUrl ?? void 0
9237
9350
  };
9238
9351
  }
9239
9352
  }
@@ -9305,13 +9418,13 @@ async function registerMCPServices(ctx, sessionsService) {
9305
9418
  }
9306
9419
  return {
9307
9420
  success: false,
9308
- error: `Server requires authentication (401) but no OAuth 2.1 auto-discovery headers found.`,
9421
+ error: "Server requires authentication (401) but OAuth 2.1 auto-discovery failed at every step.",
9309
9422
  oauthType: "unknown",
9310
9423
  mcpStatus: probeResponse.status,
9311
9424
  wwwAuthenticate: wwwAuthenticate || "<not present>",
9312
9425
  responseHeaders: allHeaders,
9313
9426
  responseBody: responseBody.substring(0, 500),
9314
- hint: "The server may require: (1) OAuth 2.1 setup on server side, (2) Client Credentials with explicit token URL, or (3) Different auth method."
9427
+ hint: `${DISCOVERY_CASCADE_TRIED} None returned valid metadata. Options: (a) provide Client Credentials with explicit token URL, (b) ask the MCP server operator to publish OAuth metadata, or (c) configure manual OAuth URLs in the server settings.`
9315
9428
  };
9316
9429
  }
9317
9430
  return {
@@ -9361,12 +9474,12 @@ async function registerMCPServices(ctx, sessionsService) {
9361
9474
  };
9362
9475
  }
9363
9476
  const wwwAuthenticate = probeResponse.headers.get("www-authenticate") || "";
9364
- const { resolveResourceMetadataUrl } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
9365
- const resolved = await resolveResourceMetadataUrl(wwwAuthenticate, data.mcp_url);
9366
- if (!resolved) {
9477
+ const { resolveMCPOAuthDiscovery } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
9478
+ const discovery = await resolveMCPOAuthDiscovery(wwwAuthenticate, data.mcp_url);
9479
+ if (!discovery) {
9367
9480
  return {
9368
9481
  success: false,
9369
- error: "Server returned 401 but does not advertise OAuth metadata. No resource_metadata in WWW-Authenticate header and no .well-known/oauth-protected-resource endpoint found."
9482
+ error: `Server returned 401 but does not advertise OAuth metadata. ${DISCOVERY_CASCADE_TRIED} None succeeded.`
9370
9483
  };
9371
9484
  }
9372
9485
  const connection = params?.connection;
@@ -9376,7 +9489,8 @@ async function registerMCPServices(ctx, sessionsService) {
9376
9489
  result = await startTwoPhaseMCPOAuthFlow({
9377
9490
  mcpUrl: data.mcp_url,
9378
9491
  wwwAuthenticate,
9379
- resourceMetadataUrl: resolved.metadataUrl,
9492
+ resourceMetadataUrl: discovery.kind === "resource-metadata" ? discovery.metadataUrl : void 0,
9493
+ prefetchedAuthServerMetadata: discovery.kind === "authorization-server" ? discovery.authServerMetadata : void 0,
9380
9494
  mcpServerId: data.mcp_server_id,
9381
9495
  userId,
9382
9496
  oauthMode,
@@ -9694,14 +9808,15 @@ async function registerMCPServices(ctx, sessionsService) {
9694
9808
  });
9695
9809
  const wwwAuthenticate = probeResponse.headers.get("www-authenticate");
9696
9810
  if (probeResponse.status !== 401) return void 0;
9697
- const { resolveResourceMetadataUrl } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
9698
- const resolved = await resolveResourceMetadataUrl(wwwAuthenticate, mcpUrl);
9699
- if (!resolved) return void 0;
9811
+ const { resolveMCPOAuthDiscovery } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
9812
+ const discovery = await resolveMCPOAuthDiscovery(wwwAuthenticate, mcpUrl);
9813
+ if (!discovery) return void 0;
9700
9814
  const connection = params?.connection;
9701
9815
  const started = await startTwoPhaseMCPOAuthFlowAndAwaitToken({
9702
9816
  mcpUrl,
9703
9817
  wwwAuthenticate: wwwAuthenticate || "",
9704
- resourceMetadataUrl: resolved.metadataUrl,
9818
+ resourceMetadataUrl: discovery.kind === "resource-metadata" ? discovery.metadataUrl : void 0,
9819
+ prefetchedAuthServerMetadata: discovery.kind === "authorization-server" ? discovery.authServerMetadata : void 0,
9705
9820
  mcpServerId: serverId,
9706
9821
  userId: params?.user?.user_id,
9707
9822
  // Discover writes the token via the shared MCP server row when