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.
- package/dist/cli/lib/banner.d.ts +1 -1
- package/dist/cli/lib/banner.js +1 -1
- package/dist/cli/lib/check-migrations.test.js +9627 -9112
- package/dist/cli/lib/daemon-manager.test.js +9632 -9117
- package/dist/cli/lib/help.js +1 -1
- package/dist/core/api/index.d.cts +3 -3
- package/dist/core/api/index.d.ts +3 -3
- package/dist/core/{board-comment-DIdOJrSF.d.cts → board-comment-CCFVVN7K.d.cts} +0 -2
- package/dist/core/{board-comment-3N-jSgsk.d.ts → board-comment-iT3DgZb4.d.ts} +0 -2
- package/dist/core/claude/index.cjs +29 -19
- package/dist/core/claude/index.d.cts +2 -2
- package/dist/core/claude/index.d.ts +2 -2
- package/dist/core/claude/index.js +32 -33
- package/dist/core/client/index.cjs +49 -0
- package/dist/core/client/index.d.cts +7 -7
- package/dist/core/client/index.d.ts +7 -7
- package/dist/core/client/index.js +46 -0
- package/dist/core/{client-B5PyIvNc.d.cts → client-CemqXk0v.d.cts} +116 -100
- package/dist/core/{client-C1CsRi19.d.ts → client-uYEOha6g.d.ts} +116 -100
- package/dist/core/config/browser.d.cts +3 -3
- package/dist/core/config/browser.d.ts +3 -3
- package/dist/core/config/index.cjs +84 -41
- package/dist/core/config/index.d.cts +59 -17
- package/dist/core/config/index.d.ts +59 -17
- package/dist/core/config/index.js +86 -55
- package/dist/core/{config-manager-TxxjFMRd.d.cts → config-manager-B8TP9Kz0.d.cts} +12 -3
- package/dist/core/{config-manager-DTrsj6G3.d.ts → config-manager-CDEB0FY4.d.ts} +12 -3
- package/dist/core/{config-services-YEZ4DwCD.d.cts → config-services-CXyQKEK5.d.cts} +1 -1
- package/dist/core/{config-services-DcO2GRgh.d.ts → config-services-DhM7_yWn.d.ts} +1 -1
- package/dist/core/db/index.cjs +235 -175
- package/dist/core/db/index.d.cts +190 -147
- package/dist/core/db/index.d.ts +190 -147
- package/dist/core/db/index.js +239 -190
- package/dist/core/db/session-guard.d.cts +4 -4
- package/dist/core/db/session-guard.d.ts +4 -4
- package/dist/core/drizzle/postgres/0028_queued_tasks.sql +8 -0
- package/dist/core/drizzle/postgres/0030_migrate_queued_messages.sql +24 -0
- package/dist/core/drizzle/postgres/0031_restructure_agentic_tool_config.sql +201 -0
- package/dist/core/drizzle/postgres/meta/_journal.json +21 -0
- package/dist/core/drizzle/sqlite/0039_queued_tasks.sql +13 -0
- package/dist/core/drizzle/sqlite/0040_migrate_queued_messages.sql +61 -0
- package/dist/core/drizzle/sqlite/0041_restructure_agentic_tool_config.sql +204 -0
- package/dist/core/drizzle/sqlite/meta/_journal.json +21 -0
- package/dist/core/gateway/index.d.cts +2 -2
- package/dist/core/gateway/index.d.ts +2 -2
- package/dist/core/{gateway-BnOlAelY.d.cts → gateway-BWq4j_Ll.d.cts} +1 -1
- package/dist/core/{gateway-B_4X-v07.d.ts → gateway-C3Jm_akw.d.ts} +1 -1
- package/dist/core/git/index.d.cts +4 -4
- package/dist/core/git/index.d.ts +4 -4
- package/dist/core/index.cjs +474 -201
- package/dist/core/index.d.cts +12 -10
- package/dist/core/index.d.ts +12 -10
- package/dist/core/index.js +473 -216
- package/dist/core/lib/feathers-validation.cjs +2 -1
- package/dist/core/lib/feathers-validation.d.cts +1 -1
- package/dist/core/lib/feathers-validation.d.ts +1 -1
- package/dist/core/lib/feathers-validation.js +2 -1
- package/dist/core/mcp/index.cjs +26 -16
- package/dist/core/mcp/index.js +26 -16
- package/dist/core/{message-DinITA7a.d.cts → message-CSWOsdcZ.d.cts} +1 -9
- package/dist/core/{message-CHUUP6OS.d.ts → message-DZa8g0s0.d.ts} +1 -9
- package/dist/core/models/index.d.cts +3 -73
- package/dist/core/models/index.d.ts +3 -73
- package/dist/core/package.json +5 -0
- package/dist/core/permissions/index.d.cts +1 -1
- package/dist/core/permissions/index.d.ts +1 -1
- package/dist/core/resolve-config-BcL-Hv8k.d.ts +74 -0
- package/dist/core/resolve-config-DTCxuSBx.d.cts +74 -0
- package/dist/core/seed/index.cjs +145 -98
- package/dist/core/seed/index.js +148 -112
- package/dist/core/{session-guard-C0LkDEN7.d.ts → session-guard-BFqVtBoS.d.ts} +1 -1
- package/dist/core/{session-guard-kvAx_8Fb.d.cts → session-guard-KHh0cnET.d.cts} +1 -1
- package/dist/core/sessions/index.cjs +184 -0
- package/dist/core/sessions/index.d.cts +79 -0
- package/dist/core/sessions/index.d.ts +79 -0
- package/dist/core/sessions/index.js +157 -0
- package/dist/core/{task-BLPFCORT.d.ts → task-BHV-YHg1.d.ts} +41 -3
- package/dist/core/{task-wht1RJEL.d.cts → task-C2Hy7H6u.d.cts} +41 -3
- package/dist/core/templates/session-context.d.cts +1 -1
- package/dist/core/templates/session-context.d.ts +1 -1
- package/dist/core/tools/mcp/oauth-mcp-transport.cjs +168 -66
- package/dist/core/tools/mcp/oauth-mcp-transport.d.cts +92 -16
- package/dist/core/tools/mcp/oauth-mcp-transport.d.ts +92 -16
- package/dist/core/tools/mcp/oauth-mcp-transport.js +165 -66
- package/dist/core/tools/mcp/oauth-refresh.cjs +43 -53
- package/dist/core/tools/mcp/oauth-refresh.d.cts +3 -3
- package/dist/core/tools/mcp/oauth-refresh.d.ts +3 -3
- package/dist/core/tools/mcp/oauth-refresh.js +58 -78
- package/dist/core/types/index.cjs +49 -0
- package/dist/core/types/index.d.cts +7 -7
- package/dist/core/types/index.d.ts +7 -7
- package/dist/core/types/index.js +46 -0
- package/dist/core/{types-DNqfdt1z.d.cts → types-D4Rl6ZKN.d.cts} +18 -2
- package/dist/core/{types-DqPMmTad.d.ts → types-n61iaXub.d.ts} +18 -2
- package/dist/core/unix/index.cjs +164 -110
- package/dist/core/unix/index.d.cts +7 -8
- package/dist/core/unix/index.d.ts +7 -8
- package/dist/core/unix/index.js +167 -124
- package/dist/core/{user-DkNdeFoz.d.cts → user-CpfkcV2C.d.cts} +139 -13
- package/dist/core/{user-BfVWBmXA.d.ts → user-DP-XZMIM.d.ts} +139 -13
- package/dist/core/utils/permission-mode-mapper.d.cts +0 -2
- package/dist/core/utils/permission-mode-mapper.d.ts +0 -2
- package/dist/daemon/index.js +2976 -2791
- package/dist/daemon/main.js +2976 -2791
- package/dist/daemon/mcp/server.js +177 -134
- package/dist/daemon/mcp/tools/analytics.js +19 -5
- package/dist/daemon/mcp/tools/artifacts.js +19 -5
- package/dist/daemon/mcp/tools/boards.js +19 -5
- package/dist/daemon/mcp/tools/card-types.js +19 -5
- package/dist/daemon/mcp/tools/cards.js +19 -5
- package/dist/daemon/mcp/tools/environment.js +19 -5
- package/dist/daemon/mcp/tools/mcp-servers.d.ts +29 -2
- package/dist/daemon/mcp/tools/mcp-servers.js +64 -54
- package/dist/daemon/mcp/tools/messages.js +19 -5
- package/dist/daemon/mcp/tools/repos.js +19 -5
- package/dist/daemon/mcp/tools/search.js +19 -5
- package/dist/daemon/mcp/tools/sessions.js +175 -53
- package/dist/daemon/mcp/tools/tasks.js +19 -5
- package/dist/daemon/mcp/tools/users.js +19 -5
- package/dist/daemon/mcp/tools/worktrees.js +37 -38
- package/dist/daemon/register-hooks.js +52 -1
- package/dist/daemon/register-routes.js +436 -424
- package/dist/daemon/register-services.js +255 -140
- package/dist/daemon/services/config.d.ts +7 -1
- package/dist/daemon/services/config.js +3 -2
- package/dist/daemon/services/gateway.js +28 -15
- package/dist/daemon/services/mcp-servers.d.ts +7 -2
- package/dist/daemon/services/repos.js +2 -0
- package/dist/daemon/services/sessions.d.ts +1 -1
- package/dist/daemon/services/sessions.js +8 -16
- package/dist/daemon/services/tasks.js +16 -10
- package/dist/daemon/services/terminals.js +2 -0
- package/dist/daemon/services/users.d.ts +27 -11
- package/dist/daemon/services/users.js +89 -43
- package/dist/daemon/services/worktree-owners.js +2 -0
- package/dist/daemon/services/worktrees.js +2 -0
- package/dist/daemon/setup/index.js +5 -2
- package/dist/daemon/setup/socketio.d.ts +10 -1
- package/dist/daemon/setup/socketio.js +7 -3
- package/dist/daemon/startup.js +13 -1
- package/dist/daemon/utils/apply-session-config-defaults.d.ts +54 -0
- package/dist/daemon/utils/apply-session-config-defaults.js +46 -0
- package/dist/daemon/utils/spawn-executor.js +2 -0
- package/dist/daemon/utils/worktree-authorization.d.ts +2 -4
- package/dist/executor/commands/zellij.d.ts.map +1 -1
- package/dist/executor/commands/zellij.js +2 -2
- package/dist/executor/handlers/sdk/base-executor.d.ts +4 -3
- package/dist/executor/handlers/sdk/base-executor.d.ts.map +1 -1
- package/dist/executor/handlers/sdk/base-executor.js +11 -5
- package/dist/executor/payload-types.d.ts +14 -14
- package/dist/executor/sdk-handlers/claude/claude-tool.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/claude/claude-tool.js +9 -4
- package/dist/executor/sdk-handlers/claude/import/task-extractor.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/claude/import/task-extractor.js +0 -5
- package/dist/executor/sdk-handlers/claude/message-builder.d.ts +23 -2
- package/dist/executor/sdk-handlers/claude/message-builder.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/claude/message-builder.js +33 -2
- package/dist/executor/sdk-handlers/claude/permissions/permission-hooks.d.ts +9 -1
- package/dist/executor/sdk-handlers/claude/permissions/permission-hooks.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/claude/permissions/permission-hooks.js +12 -0
- package/dist/executor/sdk-handlers/claude/query-builder.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/claude/query-builder.js +11 -6
- package/dist/executor/sdk-handlers/codex/codex-tool.d.ts +0 -5
- package/dist/executor/sdk-handlers/codex/codex-tool.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/codex/codex-tool.js +9 -24
- package/dist/executor/sdk-handlers/codex/prompt-service.d.ts +15 -2
- package/dist/executor/sdk-handlers/codex/prompt-service.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/codex/prompt-service.js +39 -10
- package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts +0 -5
- package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/copilot/copilot-tool.js +5 -22
- package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts +0 -5
- package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/gemini/gemini-tool.js +9 -24
- package/dist/ui/assets/{CodeEditor.inner-CO-5PAnZ.js → CodeEditor.inner-CVLqZBtM.js} +1 -1
- package/dist/ui/assets/{CodeEditor.inner-CO-5PAnZ.js.gz → CodeEditor.inner-CVLqZBtM.js.gz} +0 -0
- package/dist/ui/assets/{_basePickBy-DfxojsEt.js → _basePickBy-CFq5ES2J.js} +1 -1
- package/dist/ui/assets/_basePickBy-CFq5ES2J.js.gz +0 -0
- package/dist/ui/assets/{_baseUniq-DWFPJOTC.js → _baseUniq-C4uKBvNt.js} +1 -1
- package/dist/ui/assets/_baseUniq-C4uKBvNt.js.gz +0 -0
- package/dist/ui/assets/{arc-vMZ_XGSI.js → arc-BnrcXDJJ.js} +1 -1
- package/dist/ui/assets/arc-BnrcXDJJ.js.gz +0 -0
- package/dist/ui/assets/{architectureDiagram-VXUJARFQ-DGpk_uOD.js → architectureDiagram-VXUJARFQ-DD9HD-WR.js} +1 -1
- package/dist/ui/assets/architectureDiagram-VXUJARFQ-DD9HD-WR.js.gz +0 -0
- package/dist/ui/assets/{base-80a1f760-BsVlOKqO.js → base-80a1f760-BK1VmxWU.js} +1 -1
- package/dist/ui/assets/{blockDiagram-VD42YOAC-BkRnxc94.js → blockDiagram-VD42YOAC-LBAckZZe.js} +1 -1
- package/dist/ui/assets/blockDiagram-VD42YOAC-LBAckZZe.js.gz +0 -0
- package/dist/ui/assets/{c4Diagram-YG6GDRKO-Dcf-anJy.js → c4Diagram-YG6GDRKO-yEdylcYP.js} +1 -1
- package/dist/ui/assets/{c4Diagram-YG6GDRKO-Dcf-anJy.js.gz → c4Diagram-YG6GDRKO-yEdylcYP.js.gz} +0 -0
- package/dist/ui/assets/channel-CMN-iY3Q.js +1 -0
- package/dist/ui/assets/{chunk-4BX2VUAB-C4oVWDo8.js → chunk-4BX2VUAB-IHtzKbmQ.js} +1 -1
- package/dist/ui/assets/{chunk-55IACEB6-CsBbTu57.js → chunk-55IACEB6-C4o5tv_F.js} +1 -1
- package/dist/ui/assets/{chunk-B4BG7PRW-DtkeCZab.js → chunk-B4BG7PRW-EPkzLvlB.js} +1 -1
- package/dist/ui/assets/chunk-B4BG7PRW-EPkzLvlB.js.gz +0 -0
- package/dist/ui/assets/{chunk-DI55MBZ5-BQ_asW-1.js → chunk-DI55MBZ5-CW-Bzkzj.js} +1 -1
- package/dist/ui/assets/chunk-DI55MBZ5-CW-Bzkzj.js.gz +0 -0
- package/dist/ui/assets/{chunk-FMBD7UC4-DAdcLNG-.js → chunk-FMBD7UC4-DvGU02Io.js} +1 -1
- package/dist/ui/assets/{chunk-QN33PNHL-Do2zad3m.js → chunk-QN33PNHL-C-PIlz9n.js} +1 -1
- package/dist/ui/assets/{chunk-QZHKN3VN-CyhMmSdC.js → chunk-QZHKN3VN-BhpJFm6h.js} +1 -1
- package/dist/ui/assets/{chunk-TZMSLE5B-DlPypnIq.js → chunk-TZMSLE5B-Biake8IU.js} +1 -1
- package/dist/ui/assets/chunk-TZMSLE5B-Biake8IU.js.gz +0 -0
- package/dist/ui/assets/classDiagram-2ON5EDUG-Bz1et8oA.js +1 -0
- package/dist/ui/assets/classDiagram-v2-WZHVMYZB-Bz1et8oA.js +1 -0
- package/dist/ui/assets/clone-Dxo5sEAf.js +1 -0
- package/dist/ui/assets/{consoleHook-59e792cb-DHYIclEd.js → consoleHook-59e792cb-BzEkHWE8.js} +1 -1
- package/dist/ui/assets/consoleHook-59e792cb-BzEkHWE8.js.gz +0 -0
- package/dist/ui/assets/{cose-bilkent-S5V4N54A-DotJH9qH.js → cose-bilkent-S5V4N54A-vAiVi74s.js} +1 -1
- package/dist/ui/assets/cose-bilkent-S5V4N54A-vAiVi74s.js.gz +0 -0
- package/dist/ui/assets/{dagre-6UL2VRFP-Btssr8QF.js → dagre-6UL2VRFP-C8w7TshD.js} +1 -1
- package/dist/ui/assets/dagre-6UL2VRFP-C8w7TshD.js.gz +0 -0
- package/dist/ui/assets/{diagram-PSM6KHXK-D5_Jkog3.js → diagram-PSM6KHXK-CvnjEmtQ.js} +1 -1
- package/dist/ui/assets/diagram-PSM6KHXK-CvnjEmtQ.js.gz +0 -0
- package/dist/ui/assets/{diagram-QEK2KX5R-DlPEVSL5.js → diagram-QEK2KX5R-D245unng.js} +1 -1
- package/dist/ui/assets/diagram-QEK2KX5R-D245unng.js.gz +0 -0
- package/dist/ui/assets/{diagram-S2PKOQOG-CjO1k8aG.js → diagram-S2PKOQOG-DgGUHL8Z.js} +1 -1
- package/dist/ui/assets/diagram-S2PKOQOG-DgGUHL8Z.js.gz +0 -0
- package/dist/ui/assets/{erDiagram-Q2GNP2WA-3cO02-K3.js → erDiagram-Q2GNP2WA-Cf5paK9b.js} +1 -1
- package/dist/ui/assets/erDiagram-Q2GNP2WA-Cf5paK9b.js.gz +0 -0
- package/dist/ui/assets/{flowDiagram-NV44I4VS-CajTpSxI.js → flowDiagram-NV44I4VS-BJpHmEXV.js} +1 -1
- package/dist/ui/assets/flowDiagram-NV44I4VS-BJpHmEXV.js.gz +0 -0
- package/dist/ui/assets/{ganttDiagram-LVOFAZNH-CnY_bV3o.js → ganttDiagram-LVOFAZNH-zOyTZcXC.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-LVOFAZNH-CnY_bV3o.js.gz → ganttDiagram-LVOFAZNH-zOyTZcXC.js.gz} +0 -0
- package/dist/ui/assets/{gitGraphDiagram-NY62KEGX-CH16bg-j.js → gitGraphDiagram-NY62KEGX-B0uxwqMv.js} +1 -1
- package/dist/ui/assets/gitGraphDiagram-NY62KEGX-B0uxwqMv.js.gz +0 -0
- package/dist/ui/assets/{graph-IQoZvE3o.js → graph-NWXc73TO.js} +1 -1
- package/dist/ui/assets/graph-NWXc73TO.js.gz +0 -0
- package/dist/ui/assets/{index-599aeaf7-RUCkgwsg.js → index-599aeaf7-BKmNqoNF.js} +1 -1
- package/dist/ui/assets/index-599aeaf7-BKmNqoNF.js.gz +0 -0
- package/dist/ui/assets/{index-B3AvIgqP.js → index-BRYNiHLB.js} +345 -349
- package/dist/ui/assets/index-BRYNiHLB.js.gz +0 -0
- package/dist/ui/assets/{index-QV5-5yA2.js → index-BX6Xmhes.js} +1 -1
- package/dist/ui/assets/index-BX6Xmhes.js.gz +0 -0
- package/dist/ui/assets/{index-ChmRuj_T.js → index-W1hIq1uU.js} +1 -1
- package/dist/ui/assets/index-W1hIq1uU.js.gz +0 -0
- package/dist/ui/assets/{index-C-quzPWC.js → index-ctuok0zf.js} +1 -1
- package/dist/ui/assets/index-ctuok0zf.js.gz +0 -0
- package/dist/ui/assets/{infoDiagram-ER5ION4S-2e4gZVGT.js → infoDiagram-ER5ION4S-CquCuoTH.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-XKPGCS4Q-B5bgV3GH.js → journeyDiagram-XKPGCS4Q-B_XkufZ8.js} +1 -1
- package/dist/ui/assets/journeyDiagram-XKPGCS4Q-B_XkufZ8.js.gz +0 -0
- package/dist/ui/assets/{kanban-definition-3W4ZIXB7-Bp-aWRSc.js → kanban-definition-3W4ZIXB7-C2Bo9HkB.js} +1 -1
- package/dist/ui/assets/kanban-definition-3W4ZIXB7-C2Bo9HkB.js.gz +0 -0
- package/dist/ui/assets/katex-C6wkUDai.css +1 -0
- package/dist/ui/assets/{katex-DGRguze2.css.gz → katex-C6wkUDai.css.gz} +0 -0
- package/dist/ui/assets/{layout-BH-2XJZq.js → layout-D9A7Uaku.js} +1 -1
- package/dist/ui/assets/layout-D9A7Uaku.js.gz +0 -0
- package/dist/ui/assets/{linear-DCYXhl_f.js → linear-BJUwJsxE.js} +1 -1
- package/dist/ui/assets/linear-BJUwJsxE.js.gz +0 -0
- package/dist/ui/assets/{mermaid.core-BAuL6kgQ.js → mermaid.core-DcOEcjcA.js} +5 -5
- package/dist/ui/assets/mermaid.core-DcOEcjcA.js.gz +0 -0
- package/dist/ui/assets/{mindmap-definition-VGOIOE7T-DpH5N-N0.js → mindmap-definition-VGOIOE7T-BFT1m7BG.js} +1 -1
- package/dist/ui/assets/mindmap-definition-VGOIOE7T-BFT1m7BG.js.gz +0 -0
- package/dist/ui/assets/{pieDiagram-ADFJNKIX-BB8fBxj1.js → pieDiagram-ADFJNKIX-BFaX1oBV.js} +1 -1
- package/dist/ui/assets/pieDiagram-ADFJNKIX-BFaX1oBV.js.gz +0 -0
- package/dist/ui/assets/{quadrantDiagram-AYHSOK5B-D6oZLdUD.js → quadrantDiagram-AYHSOK5B-DQps5392.js} +1 -1
- package/dist/ui/assets/quadrantDiagram-AYHSOK5B-DQps5392.js.gz +0 -0
- package/dist/ui/assets/{requirementDiagram-UZGBJVZJ-B4uGPp8w.js → requirementDiagram-UZGBJVZJ-3EZ5KWEi.js} +1 -1
- package/dist/ui/assets/requirementDiagram-UZGBJVZJ-3EZ5KWEi.js.gz +0 -0
- package/dist/ui/assets/{sankeyDiagram-TZEHDZUN-MXhIjhme.js → sankeyDiagram-TZEHDZUN-D0qcydqq.js} +1 -1
- package/dist/ui/assets/sankeyDiagram-TZEHDZUN-D0qcydqq.js.gz +0 -0
- package/dist/ui/assets/{sequenceDiagram-WL72ISMW-Cm53TYug.js → sequenceDiagram-WL72ISMW-BCR5gaaN.js} +1 -1
- package/dist/ui/assets/sequenceDiagram-WL72ISMW-BCR5gaaN.js.gz +0 -0
- package/dist/ui/assets/{stateDiagram-FKZM4ZOC-BVuxUkj5.js → stateDiagram-FKZM4ZOC-BvX4FLQ9.js} +1 -1
- package/dist/ui/assets/stateDiagram-FKZM4ZOC-BvX4FLQ9.js.gz +0 -0
- package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-CxLDvgTF.js +1 -0
- package/dist/ui/assets/{timeline-definition-IT6M3QCI-CMypNiEP.js → timeline-definition-IT6M3QCI-_AWp5LJn.js} +1 -1
- package/dist/ui/assets/timeline-definition-IT6M3QCI-_AWp5LJn.js.gz +0 -0
- package/dist/ui/assets/{treemap-KMMF4GRG-BEtnV3BT.js → treemap-KMMF4GRG-BZ9FBl5-.js} +1 -1
- package/dist/ui/assets/treemap-KMMF4GRG-BZ9FBl5-.js.gz +0 -0
- package/dist/ui/assets/{xychartDiagram-PRI3JC2R-BnioEYUM.js → xychartDiagram-PRI3JC2R-_wB7yuVd.js} +1 -1
- package/dist/ui/assets/xychartDiagram-PRI3JC2R-_wB7yuVd.js.gz +0 -0
- package/dist/ui/index.html +1 -1
- package/package.json +8 -8
- package/dist/ui/assets/_basePickBy-DfxojsEt.js.gz +0 -0
- package/dist/ui/assets/_baseUniq-DWFPJOTC.js.gz +0 -0
- package/dist/ui/assets/arc-vMZ_XGSI.js.gz +0 -0
- package/dist/ui/assets/architectureDiagram-VXUJARFQ-DGpk_uOD.js.gz +0 -0
- package/dist/ui/assets/blockDiagram-VD42YOAC-BkRnxc94.js.gz +0 -0
- package/dist/ui/assets/channel-B9aI4bYN.js +0 -1
- package/dist/ui/assets/chunk-B4BG7PRW-DtkeCZab.js.gz +0 -0
- package/dist/ui/assets/chunk-DI55MBZ5-BQ_asW-1.js.gz +0 -0
- package/dist/ui/assets/chunk-TZMSLE5B-DlPypnIq.js.gz +0 -0
- package/dist/ui/assets/classDiagram-2ON5EDUG-p-68WO4Z.js +0 -1
- package/dist/ui/assets/classDiagram-v2-WZHVMYZB-p-68WO4Z.js +0 -1
- package/dist/ui/assets/clone-DzK5ogfn.js +0 -1
- package/dist/ui/assets/consoleHook-59e792cb-DHYIclEd.js.gz +0 -0
- package/dist/ui/assets/cose-bilkent-S5V4N54A-DotJH9qH.js.gz +0 -0
- package/dist/ui/assets/dagre-6UL2VRFP-Btssr8QF.js.gz +0 -0
- package/dist/ui/assets/diagram-PSM6KHXK-D5_Jkog3.js.gz +0 -0
- package/dist/ui/assets/diagram-QEK2KX5R-DlPEVSL5.js.gz +0 -0
- package/dist/ui/assets/diagram-S2PKOQOG-CjO1k8aG.js.gz +0 -0
- package/dist/ui/assets/erDiagram-Q2GNP2WA-3cO02-K3.js.gz +0 -0
- package/dist/ui/assets/flowDiagram-NV44I4VS-CajTpSxI.js.gz +0 -0
- package/dist/ui/assets/gitGraphDiagram-NY62KEGX-CH16bg-j.js.gz +0 -0
- package/dist/ui/assets/graph-IQoZvE3o.js.gz +0 -0
- package/dist/ui/assets/index-599aeaf7-RUCkgwsg.js.gz +0 -0
- package/dist/ui/assets/index-B3AvIgqP.js.gz +0 -0
- package/dist/ui/assets/index-C-quzPWC.js.gz +0 -0
- package/dist/ui/assets/index-ChmRuj_T.js.gz +0 -0
- package/dist/ui/assets/index-QV5-5yA2.js.gz +0 -0
- package/dist/ui/assets/journeyDiagram-XKPGCS4Q-B5bgV3GH.js.gz +0 -0
- package/dist/ui/assets/kanban-definition-3W4ZIXB7-Bp-aWRSc.js.gz +0 -0
- package/dist/ui/assets/katex-DGRguze2.css +0 -1
- package/dist/ui/assets/layout-BH-2XJZq.js.gz +0 -0
- package/dist/ui/assets/linear-DCYXhl_f.js.gz +0 -0
- package/dist/ui/assets/mermaid.core-BAuL6kgQ.js.gz +0 -0
- package/dist/ui/assets/mindmap-definition-VGOIOE7T-DpH5N-N0.js.gz +0 -0
- package/dist/ui/assets/pieDiagram-ADFJNKIX-BB8fBxj1.js.gz +0 -0
- package/dist/ui/assets/quadrantDiagram-AYHSOK5B-D6oZLdUD.js.gz +0 -0
- package/dist/ui/assets/requirementDiagram-UZGBJVZJ-B4uGPp8w.js.gz +0 -0
- package/dist/ui/assets/sankeyDiagram-TZEHDZUN-MXhIjhme.js.gz +0 -0
- package/dist/ui/assets/sequenceDiagram-WL72ISMW-Cm53TYug.js.gz +0 -0
- package/dist/ui/assets/stateDiagram-FKZM4ZOC-BVuxUkj5.js.gz +0 -0
- package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-8Jeww6Dc.js +0 -1
- package/dist/ui/assets/timeline-definition-IT6M3QCI-CMypNiEP.js.gz +0 -0
- package/dist/ui/assets/treemap-KMMF4GRG-BEtnV3BT.js.gz +0 -0
- 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
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
254
|
+
if (err instanceof jwt4.TokenExpiredError) {
|
|
255
255
|
console.warn("[mcp-tokens] token rejected: expired");
|
|
256
|
-
} else if (err instanceof
|
|
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 {
|
|
2604
|
-
import {
|
|
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
|
|
2925
|
-
|
|
2926
|
-
|
|
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:
|
|
2979
|
-
model_config:
|
|
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
|
-
|
|
2990
|
-
if (mcpServerIds && mcpServerIds.length > 0) {
|
|
3004
|
+
if (gatewayMcpServerIds.length > 0) {
|
|
2991
3005
|
await sessionsService.setMCPServers(
|
|
2992
3006
|
session.session_id,
|
|
2993
|
-
|
|
3007
|
+
gatewayMcpServerIds,
|
|
2994
3008
|
"gateway"
|
|
2995
3009
|
);
|
|
2996
3010
|
const unauthedMcpNames = [];
|
|
2997
|
-
for (const serverId of
|
|
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
|
|
3085
|
+
const task = await promptService.create(
|
|
3072
3086
|
{ prompt: promptText, permissionMode, messageSource: "gateway" },
|
|
3073
3087
|
{ route: { id: sessionId }, user }
|
|
3074
3088
|
);
|
|
3075
|
-
if (
|
|
3089
|
+
if (task.status === "queued") {
|
|
3076
3090
|
console.log(
|
|
3077
|
-
`[gateway] Message queued for session ${sessionId.substring(0, 8)} at 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 ${
|
|
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
|
|
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
|
|
5388
|
-
|
|
5389
|
-
|
|
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
|
|
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 =
|
|
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
|
-
*
|
|
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.
|
|
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.
|
|
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
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
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
|
|
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 {
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
6654
|
-
*
|
|
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
|
|
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
|
|
6661
|
-
if (!
|
|
6696
|
+
const encrypted = data.agentic_tools?.[tool]?.[field];
|
|
6697
|
+
if (!encrypted) return void 0;
|
|
6662
6698
|
try {
|
|
6663
|
-
return decryptApiKey(
|
|
6699
|
+
return decryptApiKey(encrypted);
|
|
6664
6700
|
} catch (err) {
|
|
6665
|
-
console.error(`Failed to decrypt
|
|
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
|
-
|
|
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
|
-
//
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
8334
|
-
//
|
|
8335
|
-
//
|
|
8336
|
-
|
|
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.
|
|
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
|
-
|
|
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 {
|
|
9119
|
-
const
|
|
9120
|
-
if (
|
|
9121
|
-
metadataUrl =
|
|
9122
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9203
|
-
|
|
9204
|
-
"
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
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:
|
|
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:
|
|
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 {
|
|
9365
|
-
const
|
|
9366
|
-
if (!
|
|
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:
|
|
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:
|
|
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 {
|
|
9698
|
-
const
|
|
9699
|
-
if (!
|
|
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:
|
|
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
|