agor-live 0.23.1 → 0.23.2
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/core/claude/index.cjs +51 -27
- package/dist/core/claude/index.js +51 -27
- package/dist/core/claude-cli/index.cjs +13 -0
- package/dist/core/claude-cli/index.js +13 -0
- package/dist/core/claude-cli/pricing.d.ts.map +1 -1
- package/dist/core/client/index.cjs +17 -0
- package/dist/core/client/index.js +16 -0
- package/dist/core/db/index.cjs +618 -421
- package/dist/core/db/index.js +550 -353
- package/dist/core/db/repositories/boards.d.ts +27 -0
- package/dist/core/db/repositories/boards.d.ts.map +1 -1
- package/dist/core/db/repositories/branches.d.ts +11 -1
- package/dist/core/db/repositories/branches.d.ts.map +1 -1
- package/dist/core/db/repositories/gateway-channels.d.ts +9 -0
- package/dist/core/db/repositories/gateway-channels.d.ts.map +1 -1
- package/dist/core/db/repositories/sessions.d.ts +7 -0
- package/dist/core/db/repositories/sessions.d.ts.map +1 -1
- package/dist/core/environment/render-snapshot.cjs +6 -2
- package/dist/core/environment/render-snapshot.d.ts +2 -0
- package/dist/core/environment/render-snapshot.d.ts.map +1 -1
- package/dist/core/environment/render-snapshot.js +6 -2
- package/dist/core/environment/variable-resolver.cjs +3 -1
- package/dist/core/environment/variable-resolver.js +3 -1
- package/dist/core/index.cjs +684 -486
- package/dist/core/index.js +684 -486
- package/dist/core/lib/feathers-validation.cjs +3 -0
- package/dist/core/lib/feathers-validation.d.ts +1 -0
- package/dist/core/lib/feathers-validation.d.ts.map +1 -1
- package/dist/core/lib/feathers-validation.js +3 -0
- package/dist/core/local-actions/index.cjs +123 -56
- package/dist/core/local-actions/index.js +121 -54
- package/dist/core/mcp/index.cjs +21 -3
- package/dist/core/mcp/index.d.ts +1 -1
- package/dist/core/mcp/index.d.ts.map +1 -1
- package/dist/core/mcp/index.js +18 -3
- package/dist/core/mcp/template-patterns.d.ts +15 -0
- package/dist/core/mcp/template-patterns.d.ts.map +1 -0
- package/dist/core/mcp/template-resolver.d.ts +13 -0
- package/dist/core/mcp/template-resolver.d.ts.map +1 -1
- package/dist/core/models/browser.cjs +6 -0
- package/dist/core/models/browser.js +6 -0
- package/dist/core/models/claude.d.ts.map +1 -1
- package/dist/core/models/index.cjs +6 -0
- package/dist/core/models/index.js +6 -0
- package/dist/core/seed/index.cjs +360 -216
- package/dist/core/seed/index.js +329 -185
- package/dist/core/templates/handlebars-helpers.cjs +3 -1
- package/dist/core/templates/handlebars-helpers.d.ts +5 -0
- package/dist/core/templates/handlebars-helpers.d.ts.map +1 -1
- package/dist/core/templates/handlebars-helpers.js +3 -1
- package/dist/core/tools/mcp/auth-secrets.cjs +3460 -3
- package/dist/core/tools/mcp/auth-secrets.d.ts.map +1 -1
- package/dist/core/tools/mcp/auth-secrets.js +3477 -3
- package/dist/core/tools/mcp/http-headers.cjs +17 -1
- package/dist/core/tools/mcp/http-headers.d.ts.map +1 -1
- package/dist/core/tools/mcp/http-headers.js +15 -1
- package/dist/core/tools/mcp/oauth-refresh.cjs +67 -43
- package/dist/core/tools/mcp/oauth-refresh.js +65 -41
- package/dist/core/types/board.d.ts +12 -0
- package/dist/core/types/board.d.ts.map +1 -1
- package/dist/core/types/gateway.d.ts +14 -0
- package/dist/core/types/gateway.d.ts.map +1 -1
- package/dist/core/types/index.cjs +17 -0
- package/dist/core/types/index.js +16 -0
- package/dist/core/unix/index.cjs +67 -0
- package/dist/core/unix/index.js +67 -0
- package/dist/daemon/auth/executor-runtime-scope.d.ts.map +1 -1
- package/dist/daemon/auth/executor-runtime-scope.js +19 -5
- package/dist/daemon/auth/executor-session-token.d.ts +15 -0
- package/dist/daemon/auth/executor-session-token.d.ts.map +1 -0
- package/dist/daemon/auth/executor-session-token.js +17 -0
- package/dist/daemon/auth/issue-browser-tokens-hook.d.ts +24 -0
- package/dist/daemon/auth/issue-browser-tokens-hook.d.ts.map +1 -0
- package/dist/daemon/auth/issue-browser-tokens-hook.js +95 -0
- package/dist/daemon/auth/service-jwt-strategy.d.ts.map +1 -1
- package/dist/daemon/auth/service-jwt-strategy.js +14 -2
- package/dist/daemon/declarations.d.ts +1 -0
- package/dist/daemon/declarations.d.ts.map +1 -1
- package/dist/daemon/index.js +1365 -418
- package/dist/daemon/main.js +1365 -418
- package/dist/daemon/mcp/server.js +294 -31
- package/dist/daemon/mcp/tools/analytics.js +73 -24
- package/dist/daemon/mcp/tools/artifacts.js +73 -24
- package/dist/daemon/mcp/tools/boards.js +73 -24
- package/dist/daemon/mcp/tools/branches.js +73 -24
- package/dist/daemon/mcp/tools/card-types.js +73 -24
- package/dist/daemon/mcp/tools/cards.js +73 -24
- package/dist/daemon/mcp/tools/environment.js +73 -24
- package/dist/daemon/mcp/tools/gateway-channels.d.ts.map +1 -1
- package/dist/daemon/mcp/tools/gateway-channels.js +190 -38
- package/dist/daemon/mcp/tools/knowledge.js +73 -24
- package/dist/daemon/mcp/tools/mcp-servers.js +73 -24
- package/dist/daemon/mcp/tools/messages.js +73 -24
- package/dist/daemon/mcp/tools/proxies.js +73 -24
- package/dist/daemon/mcp/tools/repos.js +73 -24
- package/dist/daemon/mcp/tools/schedules.js +73 -24
- package/dist/daemon/mcp/tools/search.js +73 -24
- package/dist/daemon/mcp/tools/sessions.js +73 -24
- package/dist/daemon/mcp/tools/tasks.js +73 -24
- package/dist/daemon/mcp/tools/users.js +76 -27
- package/dist/daemon/mcp/tools/widgets.d.ts.map +1 -1
- package/dist/daemon/mcp/tools/widgets.js +257 -99
- package/dist/daemon/oauth-auth-helpers.d.ts +35 -0
- package/dist/daemon/oauth-auth-helpers.d.ts.map +1 -0
- package/dist/daemon/oauth-auth-helpers.js +14 -0
- package/dist/daemon/register-hooks.d.ts +1 -0
- package/dist/daemon/register-hooks.d.ts.map +1 -1
- package/dist/daemon/register-hooks.js +304 -53
- package/dist/daemon/register-routes.d.ts.map +1 -1
- package/dist/daemon/register-routes.js +738 -288
- package/dist/daemon/register-services.d.ts.map +1 -1
- package/dist/daemon/register-services.js +386 -155
- package/dist/daemon/services/boards.d.ts +5 -0
- package/dist/daemon/services/boards.d.ts.map +1 -1
- package/dist/daemon/services/boards.js +7 -0
- package/dist/daemon/services/branches.d.ts.map +1 -1
- package/dist/daemon/services/branches.js +31 -2
- package/dist/daemon/services/claude-models.d.ts.map +1 -1
- package/dist/daemon/services/claude-models.js +4 -1
- package/dist/daemon/services/gateway.d.ts +15 -0
- package/dist/daemon/services/gateway.d.ts.map +1 -1
- package/dist/daemon/services/gateway.js +34 -0
- package/dist/daemon/services/health-monitor.d.ts.map +1 -1
- package/dist/daemon/services/health-monitor.js +10 -7
- package/dist/daemon/services/session-streams.d.ts +29 -0
- package/dist/daemon/services/session-streams.d.ts.map +1 -0
- package/dist/daemon/services/session-streams.js +84 -0
- package/dist/daemon/services/session-token-service.d.ts.map +1 -1
- package/dist/daemon/services/session-token-service.js +8 -4
- package/dist/daemon/setup/index.js +43 -11
- package/dist/daemon/setup/socketio.d.ts.map +1 -1
- package/dist/daemon/setup/socketio.js +43 -11
- package/dist/daemon/startup.d.ts.map +1 -1
- package/dist/daemon/startup.js +37 -16
- package/dist/daemon/utils/authorization.js +19 -5
- package/dist/daemon/utils/emit-service-event.d.ts +56 -0
- package/dist/daemon/utils/emit-service-event.d.ts.map +1 -0
- package/dist/daemon/utils/emit-service-event.js +23 -0
- package/dist/daemon/utils/mcp-header-secrets.d.ts +3 -5
- package/dist/daemon/utils/mcp-header-secrets.d.ts.map +1 -1
- package/dist/daemon/utils/mcp-header-secrets.js +31 -2
- package/dist/daemon/utils/realtime-access-cache.d.ts +9 -0
- package/dist/daemon/utils/realtime-access-cache.d.ts.map +1 -1
- package/dist/daemon/utils/realtime-access-cache.js +24 -0
- package/dist/daemon/utils/realtime-publish.d.ts +24 -0
- package/dist/daemon/utils/realtime-publish.d.ts.map +1 -1
- package/dist/daemon/utils/realtime-publish.js +120 -2
- package/dist/daemon/utils/session-queue-tenant-scope.d.ts +24 -0
- package/dist/daemon/utils/session-queue-tenant-scope.d.ts.map +1 -0
- package/dist/daemon/utils/session-queue-tenant-scope.js +133 -0
- package/dist/daemon/widgets/gateway-token/index.d.ts +114 -0
- package/dist/daemon/widgets/gateway-token/index.d.ts.map +1 -0
- package/dist/daemon/widgets/gateway-token/index.js +14711 -0
- package/dist/daemon/widgets/index.d.ts.map +1 -1
- package/dist/daemon/widgets/index.js +190 -16
- package/dist/daemon/widgets/registry.d.ts +7 -0
- package/dist/daemon/widgets/registry.d.ts.map +1 -1
- package/dist/daemon/widgets/submissions.js +12 -9
- package/dist/executor/commands/git.d.ts.map +1 -1
- package/dist/executor/commands/git.js +2 -0
- package/dist/executor/db/feathers-repositories.d.ts +19 -1
- package/dist/executor/db/feathers-repositories.d.ts.map +1 -1
- package/dist/executor/db/feathers-repositories.js +31 -1
- package/dist/executor/handlers/sdk/claude.d.ts.map +1 -1
- package/dist/executor/handlers/sdk/claude.js +1 -1
- package/dist/executor/handlers/sdk/codex.d.ts.map +1 -1
- package/dist/executor/handlers/sdk/codex.js +1 -1
- package/dist/executor/handlers/sdk/copilot.d.ts.map +1 -1
- package/dist/executor/handlers/sdk/copilot.js +1 -1
- package/dist/executor/handlers/sdk/cursor.d.ts.map +1 -1
- package/dist/executor/handlers/sdk/cursor.js +1 -0
- package/dist/executor/handlers/sdk/gemini.d.ts.map +1 -1
- package/dist/executor/handlers/sdk/gemini.js +1 -1
- package/dist/executor/handlers/sdk/opencode.d.ts.map +1 -1
- package/dist/executor/handlers/sdk/opencode.js +1 -1
- package/dist/executor/payload-types.d.ts +5 -5
- package/dist/executor/sdk-handlers/base/mcp-scoping.d.ts +8 -1
- package/dist/executor/sdk-handlers/base/mcp-scoping.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/base/mcp-scoping.js +58 -6
- package/dist/executor/sdk-handlers/claude/claude-tool.d.ts +2 -2
- package/dist/executor/sdk-handlers/claude/claude-tool.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/claude/claude-tool.js +2 -2
- package/dist/executor/sdk-handlers/claude/prompt-service.d.ts +13 -3
- package/dist/executor/sdk-handlers/claude/prompt-service.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/claude/prompt-service.js +16 -3
- package/dist/executor/sdk-handlers/claude/query-builder.d.ts +2 -1
- package/dist/executor/sdk-handlers/claude/query-builder.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/claude/query-builder.js +2 -1
- package/dist/executor/sdk-handlers/codex/codex-tool.d.ts +2 -2
- package/dist/executor/sdk-handlers/codex/codex-tool.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/codex/codex-tool.js +2 -2
- package/dist/executor/sdk-handlers/codex/prompt-service.d.ts +3 -2
- package/dist/executor/sdk-handlers/codex/prompt-service.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/codex/prompt-service.js +70 -6
- package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts +2 -2
- package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/copilot/copilot-tool.js +2 -2
- package/dist/executor/sdk-handlers/copilot/prompt-service.d.ts +3 -2
- package/dist/executor/sdk-handlers/copilot/prompt-service.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/copilot/prompt-service.js +4 -1
- package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts +2 -2
- package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/gemini/gemini-tool.js +2 -2
- package/dist/executor/sdk-handlers/gemini/prompt-service.d.ts +3 -2
- package/dist/executor/sdk-handlers/gemini/prompt-service.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/gemini/prompt-service.js +4 -1
- package/dist/executor/sdk-handlers/opencode/opencode-tool.d.ts +3 -2
- package/dist/executor/sdk-handlers/opencode/opencode-tool.d.ts.map +1 -1
- package/dist/executor/sdk-handlers/opencode/opencode-tool.js +4 -1
- package/dist/executor/services/feathers-client.d.ts.map +1 -1
- package/dist/executor/services/feathers-client.js +119 -20
- package/dist/ui/assets/AgorEmojiPickerInner-leeNywMc.js +1 -0
- package/dist/ui/assets/App-Dpl4Cc0U.js +4 -0
- package/dist/ui/assets/App-Dpl4Cc0U.js.gz +0 -0
- package/dist/ui/assets/AppNode-wN3UZlFK.js +1 -0
- package/dist/ui/assets/AppNode-wN3UZlFK.js.gz +0 -0
- package/dist/ui/assets/{ArtifactConsentModal-oMMzRn8L.js → ArtifactConsentModal-DjzXcP_L.js} +1 -1
- package/dist/ui/assets/ArtifactConsentModal-DjzXcP_L.js.gz +0 -0
- package/dist/ui/assets/ArtifactFullscreenPage-B3b_EZ0F.js +9 -0
- package/dist/ui/assets/ArtifactFullscreenPage-B3b_EZ0F.js.gz +0 -0
- package/dist/ui/assets/ArtifactNode-DISy2T-6.js +9 -0
- package/dist/ui/assets/ArtifactNode-DISy2T-6.js.gz +0 -0
- package/dist/ui/assets/AutocompleteTextarea-DUpsoEGr.js +19 -0
- package/dist/ui/assets/AutocompleteTextarea-DUpsoEGr.js.gz +0 -0
- package/dist/ui/assets/BoardObjectNodes-BakeGpIX.js +34 -0
- package/dist/ui/assets/BoardObjectNodes-BakeGpIX.js.gz +0 -0
- package/dist/ui/assets/{CodeEditor.inner-Cuj6RuLL.js → CodeEditor.inner-HmSdTLW5.js} +1 -1
- package/dist/ui/assets/CodeEditor.inner-HmSdTLW5.js.gz +0 -0
- package/dist/ui/assets/ConversationView-mWaA-B1f.js +1 -0
- package/dist/ui/assets/ConversationView-mWaA-B1f.js.gz +0 -0
- package/dist/ui/assets/{EmbeddedTerminal-Lx5I9EOJ.js → EmbeddedTerminal-NNoyPA81.js} +1 -1
- package/dist/ui/assets/EmbeddedTerminal-NNoyPA81.js.gz +0 -0
- package/dist/ui/assets/KnowledgePage-CkxVnRvz.js +24 -0
- package/dist/ui/assets/KnowledgePage-CkxVnRvz.js.gz +0 -0
- package/dist/ui/assets/{MarketingScreenshotPage-CmDPBHOl.js → MarketingScreenshotPage-B86Gs8jx.js} +2 -2
- package/dist/ui/assets/MarketingScreenshotPage-B86Gs8jx.js.gz +0 -0
- package/dist/ui/assets/MobileApp-BPs-SXvz.js +1 -0
- package/dist/ui/assets/MobileApp-BPs-SXvz.js.gz +0 -0
- package/dist/ui/assets/SessionCanvas-xVfDoEtz.js +13 -0
- package/dist/ui/assets/SessionCanvas-xVfDoEtz.js.gz +0 -0
- package/dist/ui/assets/{StreamdownDemoPage-okKKR2QH.js → StreamdownDemoPage-CvWLzVsv.js} +2 -2
- package/dist/ui/assets/StreamdownDemoPage-CvWLzVsv.js.gz +0 -0
- package/dist/ui/assets/{TerminalModal-D9jMGZXv.js → TerminalModal-ExOgsuOP.js} +2 -2
- package/dist/ui/assets/TerminalModal-ExOgsuOP.js.gz +0 -0
- package/dist/ui/assets/ThemeSwitcher-Cgyp5ruu.js +1 -0
- package/dist/ui/assets/ThemeSwitcher-Cgyp5ruu.js.gz +0 -0
- package/dist/ui/assets/{ThemedSyntaxHighlighter.inner-C1FdIHn0.js → ThemedSyntaxHighlighter.inner-rpCN9S6K.js} +1 -1
- package/dist/ui/assets/{antd-DT5ackd0.js → antd-BCqimh1J.js} +5 -5
- package/dist/ui/assets/{antd-DT5ackd0.js.gz → antd-BCqimh1J.js.gz} +0 -0
- package/dist/ui/assets/architecture-U656AL7Q-BxSQIjrE.js +1 -0
- package/dist/ui/assets/{architectureDiagram-VXUJARFQ-DwTJGGoj.js → architectureDiagram-VXUJARFQ-pDpGHSqT.js} +1 -1
- package/dist/ui/assets/architectureDiagram-VXUJARFQ-pDpGHSqT.js.gz +0 -0
- package/dist/ui/assets/{blockDiagram-VD42YOAC-Dh1_TVW2.js → blockDiagram-VD42YOAC-uP8JTJpK.js} +1 -1
- package/dist/ui/assets/blockDiagram-VD42YOAC-uP8JTJpK.js.gz +0 -0
- package/dist/ui/assets/{c4Diagram-YG6GDRKO-B1e96AcB.js → c4Diagram-YG6GDRKO-qQe72Mm7.js} +1 -1
- package/dist/ui/assets/c4Diagram-YG6GDRKO-qQe72Mm7.js.gz +0 -0
- package/dist/ui/assets/channel-CoUBs6Zn.js +1 -0
- package/dist/ui/assets/{chunk-4BX2VUAB-BODpCjJx.js → chunk-4BX2VUAB-sz-YE8Nt.js} +1 -1
- package/dist/ui/assets/chunk-4ZMWKKQ3-3oKtfWXp.js +3 -0
- package/dist/ui/assets/chunk-4ZMWKKQ3-3oKtfWXp.js.gz +0 -0
- package/dist/ui/assets/chunk-55IACEB6-BS04dgKF.js +1 -0
- package/dist/ui/assets/{chunk-ABZYJK2D-DCTXWSzV.js → chunk-ABZYJK2D-t3Gkphds.js} +3 -3
- package/dist/ui/assets/chunk-ABZYJK2D-t3Gkphds.js.gz +0 -0
- package/dist/ui/assets/{chunk-AGHRB4JF-CbNphBjE.js → chunk-AGHRB4JF-D_QmWxbY.js} +1 -1
- package/dist/ui/assets/chunk-AGHRB4JF-D_QmWxbY.js.gz +0 -0
- package/dist/ui/assets/{chunk-ATLVNIR6-rWg3qxof.js → chunk-ATLVNIR6-Bmg7-Ufz.js} +1 -1
- package/dist/ui/assets/chunk-ATLVNIR6-Bmg7-Ufz.js.gz +0 -0
- package/dist/ui/assets/{chunk-B4BG7PRW-CgtLCbpE.js → chunk-B4BG7PRW-dnSEE1u-.js} +1 -1
- package/dist/ui/assets/chunk-B4BG7PRW-dnSEE1u-.js.gz +0 -0
- package/dist/ui/assets/{chunk-CVBHYZKI-DTL6Zgr0.js → chunk-CVBHYZKI-BStaYnF0.js} +1 -1
- package/dist/ui/assets/{chunk-DI55MBZ5-Dwvx2Kva.js → chunk-DI55MBZ5-28dvx6o3.js} +1 -1
- package/dist/ui/assets/chunk-DI55MBZ5-28dvx6o3.js.gz +0 -0
- package/dist/ui/assets/chunk-EXTU4WIE-X-FURkEh.js +1 -0
- package/dist/ui/assets/{chunk-FMBD7UC4-BogA_9CV.js → chunk-FMBD7UC4-C_63gC9S.js} +1 -1
- package/dist/ui/assets/{chunk-HN2XXSSU-2blQO3Gb.js → chunk-HN2XXSSU-UFD374KI.js} +1 -1
- package/dist/ui/assets/chunk-HN2XXSSU-UFD374KI.js.gz +0 -0
- package/dist/ui/assets/{chunk-JA3XYJ7Z-Cr1rmOui.js → chunk-JA3XYJ7Z-B60hLNeR.js} +1 -1
- package/dist/ui/assets/chunk-JA3XYJ7Z-B60hLNeR.js.gz +0 -0
- package/dist/ui/assets/{chunk-JZLCHNYA-BsgZ79Fa.js → chunk-JZLCHNYA-ButC6pwN.js} +1 -1
- package/dist/ui/assets/chunk-JZLCHNYA-ButC6pwN.js.gz +0 -0
- package/dist/ui/assets/{chunk-MI3HLSF2-dwYeUy5S.js → chunk-MI3HLSF2-BivYzoSV.js} +1 -1
- package/dist/ui/assets/chunk-MI3HLSF2-BivYzoSV.js.gz +0 -0
- package/dist/ui/assets/chunk-N4CR4FBY-mVWzo5wJ.js +2 -0
- package/dist/ui/assets/chunk-N4CR4FBY-mVWzo5wJ.js.gz +0 -0
- package/dist/ui/assets/{chunk-QN33PNHL-DxdIDCAa.js → chunk-QN33PNHL-tXtHZpaG.js} +1 -1
- package/dist/ui/assets/{chunk-QXUST7PY-BCK2V0i-.js → chunk-QXUST7PY-DATib_Vv.js} +1 -1
- package/dist/ui/assets/chunk-QXUST7PY-DATib_Vv.js.gz +0 -0
- package/dist/ui/assets/chunk-QZHKN3VN-y6l249e5.js +1 -0
- package/dist/ui/assets/{chunk-S3R3BYOJ-GP3zIxrB.js → chunk-S3R3BYOJ-BEtfmflI.js} +1 -1
- package/dist/ui/assets/chunk-S3R3BYOJ-BEtfmflI.js.gz +0 -0
- package/dist/ui/assets/{chunk-TZMSLE5B-dX5RaM6g.js → chunk-TZMSLE5B-BY1ZtogK.js} +1 -1
- package/dist/ui/assets/chunk-TZMSLE5B-BY1ZtogK.js.gz +0 -0
- package/dist/ui/assets/classDiagram-2ON5EDUG-BYvq-uPY.js +1 -0
- package/dist/ui/assets/classDiagram-v2-WZHVMYZB-BYvq-uPY.js +1 -0
- package/dist/ui/assets/constants-CYzQKfD1.js +1 -0
- package/dist/ui/assets/{cose-bilkent-S5V4N54A-Dx0BJVDl.js → cose-bilkent-S5V4N54A-DPvYrqGG.js} +1 -1
- package/dist/ui/assets/cose-bilkent-S5V4N54A-DPvYrqGG.js.gz +0 -0
- package/dist/ui/assets/{dagre-6UL2VRFP-DiQSUxqN.js → dagre-6UL2VRFP-D800J6qb.js} +1 -1
- package/dist/ui/assets/dagre-6UL2VRFP-D800J6qb.js.gz +0 -0
- package/dist/ui/assets/{dagre-Bekd9Vdj.js → dagre-TNc4wezg.js} +1 -1
- package/dist/ui/assets/dagre-TNc4wezg.js.gz +0 -0
- package/dist/ui/assets/{diagram-PSM6KHXK-DtJnDQjc.js → diagram-PSM6KHXK-CGdP9F-X.js} +1 -1
- package/dist/ui/assets/diagram-PSM6KHXK-CGdP9F-X.js.gz +0 -0
- package/dist/ui/assets/{diagram-QEK2KX5R-CobkCRdj.js → diagram-QEK2KX5R-BD5lOCe5.js} +1 -1
- package/dist/ui/assets/diagram-QEK2KX5R-BD5lOCe5.js.gz +0 -0
- package/dist/ui/assets/{diagram-S2PKOQOG-DHEZYivc.js → diagram-S2PKOQOG-cp3l22vN.js} +1 -1
- package/dist/ui/assets/diagram-S2PKOQOG-cp3l22vN.js.gz +0 -0
- package/dist/ui/assets/editor-Cr0W5BQI.js +39 -0
- package/dist/ui/assets/editor-Cr0W5BQI.js.gz +0 -0
- package/dist/ui/assets/{emoji-B0hLmSLZ.js → emoji-Bv3m24sO.js} +1 -1
- package/dist/ui/assets/emoji-Bv3m24sO.js.gz +0 -0
- package/dist/ui/assets/{erDiagram-Q2GNP2WA-BVNeTZPQ.js → erDiagram-Q2GNP2WA-CQSXRgqr.js} +1 -1
- package/dist/ui/assets/erDiagram-Q2GNP2WA-CQSXRgqr.js.gz +0 -0
- package/dist/ui/assets/{flowDiagram-NV44I4VS-C73VFdyk.js → flowDiagram-NV44I4VS-CKcKpkph.js} +1 -1
- package/dist/ui/assets/flowDiagram-NV44I4VS-CKcKpkph.js.gz +0 -0
- package/dist/ui/assets/{ganttDiagram-LVOFAZNH-B_RosuD1.js → ganttDiagram-LVOFAZNH-DlAHzXO5.js} +1 -1
- package/dist/ui/assets/ganttDiagram-LVOFAZNH-DlAHzXO5.js.gz +0 -0
- package/dist/ui/assets/{gitGraph-F6HP7TQM-DMFIqn4h.js → gitGraph-F6HP7TQM-DeuXy4B1.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-NY62KEGX-hxbgwNA1.js → gitGraphDiagram-NY62KEGX-aB-AI4Vq.js} +1 -1
- package/dist/ui/assets/gitGraphDiagram-NY62KEGX-aB-AI4Vq.js.gz +0 -0
- package/dist/ui/assets/index-B-qHc0o5.js +63 -0
- package/dist/ui/assets/index-B-qHc0o5.js.gz +0 -0
- package/dist/ui/assets/{info-NVLQJR56-DZ3K-w48.js → info-NVLQJR56-B9PG7xsc.js} +1 -1
- package/dist/ui/assets/{infoDiagram-ER5ION4S-CxnBJQu6.js → infoDiagram-ER5ION4S-C5Wpoqim.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-XKPGCS4Q-CHYNj-f8.js → journeyDiagram-XKPGCS4Q-CHLziqfS.js} +1 -1
- package/dist/ui/assets/journeyDiagram-XKPGCS4Q-CHLziqfS.js.gz +0 -0
- package/dist/ui/assets/{kanban-definition-3W4ZIXB7-DQPCCsj2.js → kanban-definition-3W4ZIXB7-Dq7GzQE_.js} +1 -1
- package/dist/ui/assets/kanban-definition-3W4ZIXB7-Dq7GzQE_.js.gz +0 -0
- package/dist/ui/assets/{line-DBRjKmfa.js → line-DHKNg83I.js} +1 -1
- package/dist/ui/assets/{linear-DFao5Wyp.js → linear-BvUfn0I8.js} +1 -1
- package/dist/ui/assets/linear-BvUfn0I8.js.gz +0 -0
- package/dist/ui/assets/{mermaid-parser.core-DYCfacHj.js → mermaid-parser.core-C6d9tKoo.js} +2 -2
- package/dist/ui/assets/mermaid-parser.core-C6d9tKoo.js.gz +0 -0
- package/dist/ui/assets/{mermaid.core-C6xGFSdE.js → mermaid.core-CxE5KezR.js} +3 -3
- package/dist/ui/assets/mermaid.core-CxE5KezR.js.gz +0 -0
- package/dist/ui/assets/{mindmap-definition-VGOIOE7T-L3Pw-YM7.js → mindmap-definition-VGOIOE7T-DmPoQ48w.js} +1 -1
- package/dist/ui/assets/mindmap-definition-VGOIOE7T-DmPoQ48w.js.gz +0 -0
- package/dist/ui/assets/{packet-BFZMPI3H-CpL6iNoa.js → packet-BFZMPI3H-JZEkVZxU.js} +1 -1
- package/dist/ui/assets/{particles-CT8hcJOA.js → particles-CxMmUw86.js} +1 -1
- package/dist/ui/assets/particles-CxMmUw86.js.gz +0 -0
- package/dist/ui/assets/{pie-7BOR55EZ-hTqChbTo.js → pie-7BOR55EZ-_1II5pYQ.js} +1 -1
- package/dist/ui/assets/{pieDiagram-ADFJNKIX-Bf4Nou75.js → pieDiagram-ADFJNKIX-DrNkH33i.js} +1 -1
- package/dist/ui/assets/pieDiagram-ADFJNKIX-DrNkH33i.js.gz +0 -0
- package/dist/ui/assets/{quadrantDiagram-AYHSOK5B-DpjUTLB1.js → quadrantDiagram-AYHSOK5B-DOpC-HEF.js} +1 -1
- package/dist/ui/assets/quadrantDiagram-AYHSOK5B-DOpC-HEF.js.gz +0 -0
- package/dist/ui/assets/{radar-NHE76QYJ-myy7OENC.js → radar-NHE76QYJ-DDmqhzEZ.js} +1 -1
- package/dist/ui/assets/{reactflow-Cubtnk8i.js → reactflow-D98uPOMq.js} +1 -1
- package/dist/ui/assets/reactflow-D98uPOMq.js.gz +0 -0
- package/dist/ui/assets/{requirementDiagram-UZGBJVZJ-Bfrfh-0-.js → requirementDiagram-UZGBJVZJ-Bzx0iEPP.js} +1 -1
- package/dist/ui/assets/requirementDiagram-UZGBJVZJ-Bzx0iEPP.js.gz +0 -0
- package/dist/ui/assets/{sandpack-C58bwfIS.js → sandpack-059Z4UWP.js} +1 -1
- package/dist/ui/assets/sandpack-059Z4UWP.js.gz +0 -0
- package/dist/ui/assets/sandpackDefaults-CPMNDsw7.js +1 -0
- package/dist/ui/assets/sandpackDefaults-CPMNDsw7.js.gz +0 -0
- package/dist/ui/assets/{sankeyDiagram-TZEHDZUN-ClZAZ6va.js → sankeyDiagram-TZEHDZUN-Do9pvfDv.js} +1 -1
- package/dist/ui/assets/sankeyDiagram-TZEHDZUN-Do9pvfDv.js.gz +0 -0
- package/dist/ui/assets/{sequenceDiagram-WL72ISMW-CNgly63p.js → sequenceDiagram-WL72ISMW-CN8neUTA.js} +1 -1
- package/dist/ui/assets/sequenceDiagram-WL72ISMW-CN8neUTA.js.gz +0 -0
- package/dist/ui/assets/{src-DAeyG22O.js → src-DEbsv3pp.js} +2 -2
- package/dist/ui/assets/src-DEbsv3pp.js.gz +0 -0
- package/dist/ui/assets/{stateDiagram-FKZM4ZOC-BrEAoDpE.js → stateDiagram-FKZM4ZOC-BluWJi8n.js} +1 -1
- package/dist/ui/assets/stateDiagram-FKZM4ZOC-BluWJi8n.js.gz +0 -0
- package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-DeyqBMDR.js +1 -0
- package/dist/ui/assets/{streamdown-BdAVfkeF.js → streamdown-BT1twtFc.js} +5 -5
- package/dist/ui/assets/streamdown-BT1twtFc.js.gz +0 -0
- package/dist/ui/assets/{syntax-BOfTnQiy.js → syntax-CBu6nLfm.js} +1 -1
- package/dist/ui/assets/syntax-CBu6nLfm.js.gz +0 -0
- package/dist/ui/assets/{timeline-definition-IT6M3QCI-CaRH3k4l.js → timeline-definition-IT6M3QCI-WdUNkiRj.js} +1 -1
- package/dist/ui/assets/timeline-definition-IT6M3QCI-WdUNkiRj.js.gz +0 -0
- package/dist/ui/assets/{treemap-KMMF4GRG-CUaLOV_B.js → treemap-KMMF4GRG-CoriU4Jl.js} +1 -1
- package/dist/ui/assets/{useUserLocalStorage-C8sgXgXR.js → useUserLocalStorage-GidNiOPC.js} +1 -1
- package/dist/ui/assets/useUserLocalStorage-GidNiOPC.js.gz +0 -0
- package/dist/ui/assets/{xychartDiagram-PRI3JC2R-BlhkI9T_.js → xychartDiagram-PRI3JC2R-CgBAKNt2.js} +1 -1
- package/dist/ui/assets/xychartDiagram-PRI3JC2R-CgBAKNt2.js.gz +0 -0
- package/dist/ui/index.html +9 -8
- package/dist/ui/index.html.gz +0 -0
- package/package.json +2 -2
- package/dist/ui/assets/AgorEmojiPickerInner-DQjr8M3_.js +0 -1
- package/dist/ui/assets/App-hJtcOxHv.js +0 -5
- package/dist/ui/assets/App-hJtcOxHv.js.gz +0 -0
- package/dist/ui/assets/AppNode-BhuMpn8O.js +0 -1
- package/dist/ui/assets/AppNode-BhuMpn8O.js.gz +0 -0
- package/dist/ui/assets/ArtifactConsentModal-oMMzRn8L.js.gz +0 -0
- package/dist/ui/assets/ArtifactFullscreenPage-B3wT8t8f.js +0 -9
- package/dist/ui/assets/ArtifactFullscreenPage-B3wT8t8f.js.gz +0 -0
- package/dist/ui/assets/ArtifactNode-BzQcrwFS.js +0 -9
- package/dist/ui/assets/ArtifactNode-BzQcrwFS.js.gz +0 -0
- package/dist/ui/assets/AutocompleteTextarea-Dau-V_30.js +0 -19
- package/dist/ui/assets/AutocompleteTextarea-Dau-V_30.js.gz +0 -0
- package/dist/ui/assets/BoardObjectNodes-DdKWv_ZT.js +0 -34
- package/dist/ui/assets/BoardObjectNodes-DdKWv_ZT.js.gz +0 -0
- package/dist/ui/assets/CodeEditor.inner-Cuj6RuLL.js.gz +0 -0
- package/dist/ui/assets/ConversationView-9-3ma1u-.js +0 -1
- package/dist/ui/assets/ConversationView-9-3ma1u-.js.gz +0 -0
- package/dist/ui/assets/EmbeddedTerminal-Lx5I9EOJ.js.gz +0 -0
- package/dist/ui/assets/KnowledgePage-Dz8YAMYC.js +0 -24
- package/dist/ui/assets/KnowledgePage-Dz8YAMYC.js.gz +0 -0
- package/dist/ui/assets/MarketingScreenshotPage-CmDPBHOl.js.gz +0 -0
- package/dist/ui/assets/MobileApp-BpgSG_gz.js +0 -1
- package/dist/ui/assets/MobileApp-BpgSG_gz.js.gz +0 -0
- package/dist/ui/assets/SessionCanvas-B6_mtlxK.js +0 -13
- package/dist/ui/assets/SessionCanvas-B6_mtlxK.js.gz +0 -0
- package/dist/ui/assets/StreamdownDemoPage-okKKR2QH.js.gz +0 -0
- package/dist/ui/assets/TerminalModal-D9jMGZXv.js.gz +0 -0
- package/dist/ui/assets/ThemeSwitcher-D9HgT37l.js +0 -1
- package/dist/ui/assets/ThemeSwitcher-D9HgT37l.js.gz +0 -0
- package/dist/ui/assets/architecture-U656AL7Q-DMnxkQRZ.js +0 -1
- package/dist/ui/assets/architectureDiagram-VXUJARFQ-DwTJGGoj.js.gz +0 -0
- package/dist/ui/assets/blockDiagram-VD42YOAC-Dh1_TVW2.js.gz +0 -0
- package/dist/ui/assets/c4Diagram-YG6GDRKO-B1e96AcB.js.gz +0 -0
- package/dist/ui/assets/channel-Jv4dT4S5.js +0 -1
- package/dist/ui/assets/chunk-55IACEB6-lJXvUquf.js +0 -1
- package/dist/ui/assets/chunk-ABZYJK2D-DCTXWSzV.js.gz +0 -0
- package/dist/ui/assets/chunk-AGHRB4JF-CbNphBjE.js.gz +0 -0
- package/dist/ui/assets/chunk-ATLVNIR6-rWg3qxof.js.gz +0 -0
- package/dist/ui/assets/chunk-B4BG7PRW-CgtLCbpE.js.gz +0 -0
- package/dist/ui/assets/chunk-DI55MBZ5-Dwvx2Kva.js.gz +0 -0
- package/dist/ui/assets/chunk-EXTU4WIE-DHyaqTsP.js +0 -1
- package/dist/ui/assets/chunk-HN2XXSSU-2blQO3Gb.js.gz +0 -0
- package/dist/ui/assets/chunk-JA3XYJ7Z-Cr1rmOui.js.gz +0 -0
- package/dist/ui/assets/chunk-JZLCHNYA-BsgZ79Fa.js.gz +0 -0
- package/dist/ui/assets/chunk-MI3HLSF2-dwYeUy5S.js.gz +0 -0
- package/dist/ui/assets/chunk-N4CR4FBY-DEMgSRVe.js +0 -2
- package/dist/ui/assets/chunk-N4CR4FBY-DEMgSRVe.js.gz +0 -0
- package/dist/ui/assets/chunk-QXUST7PY-BCK2V0i-.js.gz +0 -0
- package/dist/ui/assets/chunk-QZHKN3VN-CALjGrEE.js +0 -1
- package/dist/ui/assets/chunk-S3R3BYOJ-GP3zIxrB.js.gz +0 -0
- package/dist/ui/assets/chunk-TZMSLE5B-dX5RaM6g.js.gz +0 -0
- package/dist/ui/assets/classDiagram-2ON5EDUG-C3_RVP70.js +0 -1
- package/dist/ui/assets/classDiagram-v2-WZHVMYZB-C3_RVP70.js +0 -1
- package/dist/ui/assets/constants-GjIDNVyt.js +0 -1
- package/dist/ui/assets/cose-bilkent-S5V4N54A-Dx0BJVDl.js.gz +0 -0
- package/dist/ui/assets/dagre-6UL2VRFP-DiQSUxqN.js.gz +0 -0
- package/dist/ui/assets/dagre-Bekd9Vdj.js.gz +0 -0
- package/dist/ui/assets/diagram-PSM6KHXK-DtJnDQjc.js.gz +0 -0
- package/dist/ui/assets/diagram-QEK2KX5R-CobkCRdj.js.gz +0 -0
- package/dist/ui/assets/diagram-S2PKOQOG-DHEZYivc.js.gz +0 -0
- package/dist/ui/assets/editor-DQIG-JYZ.js +0 -43
- package/dist/ui/assets/editor-DQIG-JYZ.js.gz +0 -0
- package/dist/ui/assets/emoji-B0hLmSLZ.js.gz +0 -0
- package/dist/ui/assets/erDiagram-Q2GNP2WA-BVNeTZPQ.js.gz +0 -0
- package/dist/ui/assets/flowDiagram-NV44I4VS-C73VFdyk.js.gz +0 -0
- package/dist/ui/assets/ganttDiagram-LVOFAZNH-B_RosuD1.js.gz +0 -0
- package/dist/ui/assets/gitGraphDiagram-NY62KEGX-hxbgwNA1.js.gz +0 -0
- package/dist/ui/assets/index-DTz1Dif6.js +0 -64
- package/dist/ui/assets/index-DTz1Dif6.js.gz +0 -0
- package/dist/ui/assets/journeyDiagram-XKPGCS4Q-CHYNj-f8.js.gz +0 -0
- package/dist/ui/assets/kanban-definition-3W4ZIXB7-DQPCCsj2.js.gz +0 -0
- package/dist/ui/assets/linear-DFao5Wyp.js.gz +0 -0
- package/dist/ui/assets/mermaid-parser.core-DYCfacHj.js.gz +0 -0
- package/dist/ui/assets/mermaid.core-C6xGFSdE.js.gz +0 -0
- package/dist/ui/assets/mindmap-definition-VGOIOE7T-L3Pw-YM7.js.gz +0 -0
- package/dist/ui/assets/particles-CT8hcJOA.js.gz +0 -0
- package/dist/ui/assets/pieDiagram-ADFJNKIX-Bf4Nou75.js.gz +0 -0
- package/dist/ui/assets/quadrantDiagram-AYHSOK5B-DpjUTLB1.js.gz +0 -0
- package/dist/ui/assets/reactflow-Cubtnk8i.js.gz +0 -0
- package/dist/ui/assets/requirementDiagram-UZGBJVZJ-Bfrfh-0-.js.gz +0 -0
- package/dist/ui/assets/sandpack-C58bwfIS.js.gz +0 -0
- package/dist/ui/assets/sandpackDefaults-Bkga8XAE.js +0 -1
- package/dist/ui/assets/sankeyDiagram-TZEHDZUN-ClZAZ6va.js.gz +0 -0
- package/dist/ui/assets/sequenceDiagram-WL72ISMW-CNgly63p.js.gz +0 -0
- package/dist/ui/assets/src-DAeyG22O.js.gz +0 -0
- package/dist/ui/assets/stateDiagram-FKZM4ZOC-BrEAoDpE.js.gz +0 -0
- package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-BNL52_oN.js +0 -1
- package/dist/ui/assets/streamdown-BdAVfkeF.js.gz +0 -0
- package/dist/ui/assets/syntax-BOfTnQiy.js.gz +0 -0
- package/dist/ui/assets/timeline-definition-IT6M3QCI-CaRH3k4l.js.gz +0 -0
- package/dist/ui/assets/useUserLocalStorage-C8sgXgXR.js.gz +0 -0
- package/dist/ui/assets/xychartDiagram-PRI3JC2R-BlhkI9T_.js.gz +0 -0
|
@@ -1761,13 +1761,13 @@ var init_identity_token = __esm({
|
|
|
1761
1761
|
function oidcFederationProvider(config) {
|
|
1762
1762
|
return async () => {
|
|
1763
1763
|
requireSecureTokenEndpoint(config.baseURL);
|
|
1764
|
-
const
|
|
1765
|
-
if (
|
|
1766
|
-
throw new WorkloadIdentityError(`Identity token is ${Math.ceil(
|
|
1764
|
+
const jwt8 = await config.identityTokenProvider();
|
|
1765
|
+
if (jwt8.length > 16 * 1024) {
|
|
1766
|
+
throw new WorkloadIdentityError(`Identity token is ${Math.ceil(jwt8.length / 1024)} KiB, exceeds the 16 KiB assertion limit`);
|
|
1767
1767
|
}
|
|
1768
1768
|
const body = {
|
|
1769
1769
|
grant_type: GRANT_TYPE_JWT_BEARER,
|
|
1770
|
-
assertion:
|
|
1770
|
+
assertion: jwt8,
|
|
1771
1771
|
federation_rule_id: config.federationRuleId,
|
|
1772
1772
|
organization_id: config.organizationId
|
|
1773
1773
|
};
|
|
@@ -12143,6 +12143,24 @@ var init_sdk = __esm({
|
|
|
12143
12143
|
}
|
|
12144
12144
|
});
|
|
12145
12145
|
|
|
12146
|
+
// src/auth/executor-session-token.ts
|
|
12147
|
+
function isExecutorSessionTokenPayload(payload) {
|
|
12148
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return false;
|
|
12149
|
+
const record = payload;
|
|
12150
|
+
return record.type === EXECUTOR_SESSION_TOKEN_TYPE && record.purpose === EXECUTOR_SESSION_TOKEN_PURPOSE;
|
|
12151
|
+
}
|
|
12152
|
+
function getExecutorSessionTokenSessionId(payload) {
|
|
12153
|
+
return payload.session_id ?? payload.sessionId;
|
|
12154
|
+
}
|
|
12155
|
+
var EXECUTOR_SESSION_TOKEN_TYPE, EXECUTOR_SESSION_TOKEN_PURPOSE;
|
|
12156
|
+
var init_executor_session_token = __esm({
|
|
12157
|
+
"src/auth/executor-session-token.ts"() {
|
|
12158
|
+
"use strict";
|
|
12159
|
+
EXECUTOR_SESSION_TOKEN_TYPE = "executor-session";
|
|
12160
|
+
EXECUTOR_SESSION_TOKEN_PURPOSE = "executor-task";
|
|
12161
|
+
}
|
|
12162
|
+
});
|
|
12163
|
+
|
|
12146
12164
|
// src/mcp/tokens.ts
|
|
12147
12165
|
var tokens_exports = {};
|
|
12148
12166
|
__export(tokens_exports, {
|
|
@@ -12157,8 +12175,8 @@ __export(tokens_exports, {
|
|
|
12157
12175
|
import { MCP_TOKEN } from "@agor/core/config";
|
|
12158
12176
|
import {
|
|
12159
12177
|
generateId as generateId4,
|
|
12160
|
-
SessionRepository as
|
|
12161
|
-
shortId as
|
|
12178
|
+
SessionRepository as SessionRepository5,
|
|
12179
|
+
shortId as shortId17
|
|
12162
12180
|
} from "@agor/core/db";
|
|
12163
12181
|
import {
|
|
12164
12182
|
MCP_TOKEN_AUDIENCE,
|
|
@@ -12183,7 +12201,7 @@ function initMcpTokens(options) {
|
|
|
12183
12201
|
const expirationMs = options.expirationMs ?? MCP_TOKEN.DEFAULT_EXPIRATION_MS;
|
|
12184
12202
|
const now = options.now ?? (() => Date.now());
|
|
12185
12203
|
_state = {
|
|
12186
|
-
sessionRepo: new
|
|
12204
|
+
sessionRepo: new SessionRepository5(options.db),
|
|
12187
12205
|
expirationMs,
|
|
12188
12206
|
now,
|
|
12189
12207
|
tokenCache: /* @__PURE__ */ new Map(),
|
|
@@ -12213,7 +12231,7 @@ async function generateSessionToken2(app, sessionId, userId) {
|
|
|
12213
12231
|
const cached = s.tokenCache.get(cacheKey);
|
|
12214
12232
|
const refreshBufferMs = Math.min(5 * 60 * 1e3, Math.max(30 * 1e3, s.expirationMs * 0.1));
|
|
12215
12233
|
if (cached && cached.expiresAtMs - nowMs > refreshBufferMs) {
|
|
12216
|
-
mcpTokenDebug(`\u{1F3AB} MCP token cache hit: session=${
|
|
12234
|
+
mcpTokenDebug(`\u{1F3AB} MCP token cache hit: session=${shortId17(sessionId)}`);
|
|
12217
12235
|
return cached.token;
|
|
12218
12236
|
}
|
|
12219
12237
|
const sessionExists = await s.sessionRepo.exists(sessionId);
|
|
@@ -12239,7 +12257,7 @@ async function generateSessionToken2(app, sessionId, userId) {
|
|
|
12239
12257
|
const token = jwt4.sign(payload, jwtSecret, { algorithm: "HS256" });
|
|
12240
12258
|
s.tokenCache.set(cacheKey, { token, expiresAtMs });
|
|
12241
12259
|
mcpTokenDebug(
|
|
12242
|
-
`\u{1F3AB} MCP token issued: session=${
|
|
12260
|
+
`\u{1F3AB} MCP token issued: session=${shortId17(sessionId)} jti=${jti.substring(0, 8)} exp=+${Math.floor(s.expirationMs / 1e3)}s`
|
|
12243
12261
|
);
|
|
12244
12262
|
return token;
|
|
12245
12263
|
}
|
|
@@ -12279,7 +12297,7 @@ async function validateSessionToken(app, token) {
|
|
|
12279
12297
|
}
|
|
12280
12298
|
const sessionExists = await s.sessionRepo.exists(sessionId);
|
|
12281
12299
|
if (!sessionExists) {
|
|
12282
|
-
console.warn(`[mcp-tokens] token rejected: session ${
|
|
12300
|
+
console.warn(`[mcp-tokens] token rejected: session ${shortId17(sessionId)} not found`);
|
|
12283
12301
|
return null;
|
|
12284
12302
|
}
|
|
12285
12303
|
return { sessionId, userId, jti: payload.jti };
|
|
@@ -12299,8 +12317,8 @@ var session_token_service_exports = {};
|
|
|
12299
12317
|
__export(session_token_service_exports, {
|
|
12300
12318
|
SessionTokenService: () => SessionTokenService
|
|
12301
12319
|
});
|
|
12302
|
-
import { getCurrentTenantId as
|
|
12303
|
-
import
|
|
12320
|
+
import { getCurrentTenantId as getCurrentTenantId5 } from "@agor/core/db";
|
|
12321
|
+
import jwt7 from "jsonwebtoken";
|
|
12304
12322
|
function sessionTokenDebug(...args) {
|
|
12305
12323
|
if (DEBUG_SESSION_TOKENS) {
|
|
12306
12324
|
console.debug(...args);
|
|
@@ -12310,6 +12328,7 @@ var DEBUG_SESSION_TOKENS, SessionTokenService;
|
|
|
12310
12328
|
var init_session_token_service = __esm({
|
|
12311
12329
|
"src/services/session-token-service.ts"() {
|
|
12312
12330
|
"use strict";
|
|
12331
|
+
init_executor_session_token();
|
|
12313
12332
|
DEBUG_SESSION_TOKENS = process.env.AGOR_DEBUG_SESSION_TOKENS === "1" || process.env.DEBUG?.includes("session-token");
|
|
12314
12333
|
SessionTokenService = class {
|
|
12315
12334
|
constructor(config) {
|
|
@@ -12335,14 +12354,12 @@ var init_session_token_service = __esm({
|
|
|
12335
12354
|
}
|
|
12336
12355
|
const now = /* @__PURE__ */ new Date();
|
|
12337
12356
|
const expiresAt = new Date(now.getTime() + this.config.expiration_ms);
|
|
12338
|
-
const tenantId =
|
|
12357
|
+
const tenantId = getCurrentTenantId5();
|
|
12339
12358
|
const payload = {
|
|
12340
12359
|
sub: userId,
|
|
12341
12360
|
// Standard JWT subject claim (used by Feathers for user lookup)
|
|
12342
|
-
type:
|
|
12343
|
-
purpose:
|
|
12344
|
-
sessionId,
|
|
12345
|
-
// Custom claim for session tracking
|
|
12361
|
+
type: EXECUTOR_SESSION_TOKEN_TYPE,
|
|
12362
|
+
purpose: EXECUTOR_SESSION_TOKEN_PURPOSE,
|
|
12346
12363
|
session_id: sessionId,
|
|
12347
12364
|
task_id: scope.taskId,
|
|
12348
12365
|
branch_id: scope.branchId,
|
|
@@ -12356,7 +12373,7 @@ var init_session_token_service = __esm({
|
|
|
12356
12373
|
iss: "agor"
|
|
12357
12374
|
// Must match Feathers jwtOptions.issuer
|
|
12358
12375
|
};
|
|
12359
|
-
const token =
|
|
12376
|
+
const token = jwt7.sign(payload, this.jwtSecret, {
|
|
12360
12377
|
algorithm: "HS256"
|
|
12361
12378
|
// Must match Feathers jwtOptions.algorithm
|
|
12362
12379
|
// No expiresIn here - we set exp directly in payload
|
|
@@ -12557,12 +12574,14 @@ import {
|
|
|
12557
12574
|
BoardRepository as BoardRepository5,
|
|
12558
12575
|
BranchRepository as BranchRepository9,
|
|
12559
12576
|
eq as eq4,
|
|
12577
|
+
getCurrentTenantId as getCurrentTenantId6,
|
|
12560
12578
|
inArray as inArray2,
|
|
12579
|
+
isPostgresDatabase as isPostgresDatabase7,
|
|
12561
12580
|
MCPServerRepository as MCPServerRepository4,
|
|
12562
12581
|
SessionMCPServerRepository as SessionMCPServerRepository3,
|
|
12563
12582
|
select as select4,
|
|
12564
12583
|
sessionMcpServers,
|
|
12565
|
-
shortId as
|
|
12584
|
+
shortId as shortId22,
|
|
12566
12585
|
UserMCPOAuthTokenRepository as UserMCPOAuthTokenRepository3,
|
|
12567
12586
|
visibleSessionReferenceAccessExists
|
|
12568
12587
|
} from "@agor/core/db";
|
|
@@ -12571,7 +12590,7 @@ import {
|
|
|
12571
12590
|
AGENTIC_TOOL_CAPABILITIES,
|
|
12572
12591
|
isSessionExecuting,
|
|
12573
12592
|
isTaskExecuting,
|
|
12574
|
-
ROLES as
|
|
12593
|
+
ROLES as ROLES17,
|
|
12575
12594
|
SessionStatus as SessionStatus5,
|
|
12576
12595
|
TaskStatus as TaskStatus3
|
|
12577
12596
|
} from "@agor/core/types";
|
|
@@ -12586,6 +12605,13 @@ function untrackExecutorProcess(sessionId) {
|
|
|
12586
12605
|
executorProcesses.delete(sessionId);
|
|
12587
12606
|
}
|
|
12588
12607
|
|
|
12608
|
+
// src/oauth-auth-helpers.ts
|
|
12609
|
+
import { runWithTenantDatabaseScope } from "@agor/core/db";
|
|
12610
|
+
async function runInOAuthTenantScope(db, tenantId, work) {
|
|
12611
|
+
if (!tenantId) return work();
|
|
12612
|
+
return runWithTenantDatabaseScope(db, tenantId, work);
|
|
12613
|
+
}
|
|
12614
|
+
|
|
12589
12615
|
// src/oauth-cache.ts
|
|
12590
12616
|
import { MCPServerRepository, UserMCPOAuthTokenRepository } from "@agor/core/db";
|
|
12591
12617
|
import { resolveTokenExpiry } from "@agor/core/tools/mcp/oauth-token-expiry";
|
|
@@ -15874,6 +15900,13 @@ var BoardsService = class extends DrizzleService {
|
|
|
15874
15900
|
async batchUpsertBoardObjects(boardId, objects, _params) {
|
|
15875
15901
|
return this.boardRepo.batchUpsertBoardObjects(boardId, objects);
|
|
15876
15902
|
}
|
|
15903
|
+
/**
|
|
15904
|
+
* Custom method: Atomically shallow-merge field patches into existing board
|
|
15905
|
+
* objects (used by z-order reorder to persist only the changed zIndex).
|
|
15906
|
+
*/
|
|
15907
|
+
async mergeBoardObjectFields(boardId, patches, _params) {
|
|
15908
|
+
return this.boardRepo.mergeBoardObjectFields(boardId, patches);
|
|
15909
|
+
}
|
|
15877
15910
|
/**
|
|
15878
15911
|
* Custom method: Delete a zone and handle associated sessions
|
|
15879
15912
|
*/
|
|
@@ -16853,6 +16886,27 @@ function shouldUseCloneReferencePath() {
|
|
|
16853
16886
|
return (config.execution?.unix_user_mode ?? "simple") !== "strict";
|
|
16854
16887
|
}
|
|
16855
16888
|
|
|
16889
|
+
// src/utils/emit-service-event.ts
|
|
16890
|
+
var DEFAULT_EVENT_METHOD = {
|
|
16891
|
+
created: "create",
|
|
16892
|
+
updated: "update",
|
|
16893
|
+
patched: "patch",
|
|
16894
|
+
removed: "remove"
|
|
16895
|
+
};
|
|
16896
|
+
function emitServiceEvent(app, event) {
|
|
16897
|
+
const service = app.service(event.path);
|
|
16898
|
+
service.emit?.(event.event, event.data, {
|
|
16899
|
+
app,
|
|
16900
|
+
service,
|
|
16901
|
+
path: event.path,
|
|
16902
|
+
method: event.method ?? DEFAULT_EVENT_METHOD[event.event] ?? "patch",
|
|
16903
|
+
event: event.event,
|
|
16904
|
+
id: event.id,
|
|
16905
|
+
result: event.data,
|
|
16906
|
+
params: event.params ?? {}
|
|
16907
|
+
});
|
|
16908
|
+
}
|
|
16909
|
+
|
|
16856
16910
|
// src/utils/git-impersonation.ts
|
|
16857
16911
|
async function resolveDaemonUserForGroupRefresh() {
|
|
16858
16912
|
const { getDaemonUser: getDaemonUser2, isUnixGroupRefreshNeeded } = await import("@agor/core/config");
|
|
@@ -16893,7 +16947,7 @@ import {
|
|
|
16893
16947
|
enqueueTenantDatabasePostCommitCallback,
|
|
16894
16948
|
getCurrentTenantId,
|
|
16895
16949
|
runWithoutTenantDatabaseScope,
|
|
16896
|
-
runWithTenantDatabaseScope
|
|
16950
|
+
runWithTenantDatabaseScope as runWithTenantDatabaseScope2
|
|
16897
16951
|
} from "@agor/core/db";
|
|
16898
16952
|
import { NotAuthenticated as NotAuthenticated4 } from "@agor/core/feathers";
|
|
16899
16953
|
import jwt2 from "jsonwebtoken";
|
|
@@ -16915,7 +16969,7 @@ function deferWithTenantDatabaseScope(db, params, work, onError) {
|
|
|
16915
16969
|
const schedule = () => {
|
|
16916
16970
|
runWithoutTenantDatabaseScope(() => {
|
|
16917
16971
|
setImmediate(() => {
|
|
16918
|
-
void
|
|
16972
|
+
void runWithTenantDatabaseScope2(db, tenantId, work).catch((error) => {
|
|
16919
16973
|
if (onError) {
|
|
16920
16974
|
onError(error);
|
|
16921
16975
|
return;
|
|
@@ -18295,7 +18349,13 @@ var BranchesService = class extends DrizzleService {
|
|
|
18295
18349
|
},
|
|
18296
18350
|
resolvedParams
|
|
18297
18351
|
);
|
|
18298
|
-
this.app
|
|
18352
|
+
emitServiceEvent(this.app, {
|
|
18353
|
+
path: "branches",
|
|
18354
|
+
event: "patched",
|
|
18355
|
+
data: branch,
|
|
18356
|
+
params: resolvedParams,
|
|
18357
|
+
id
|
|
18358
|
+
});
|
|
18299
18359
|
return branch;
|
|
18300
18360
|
}
|
|
18301
18361
|
/**
|
|
@@ -18730,7 +18790,9 @@ var BranchesService = class extends DrizzleService {
|
|
|
18730
18790
|
path: branch.path,
|
|
18731
18791
|
custom_context: branch.custom_context,
|
|
18732
18792
|
unix_gid: unixGid,
|
|
18733
|
-
host_ip_address: hostIpAddress
|
|
18793
|
+
host_ip_address: hostIpAddress,
|
|
18794
|
+
base_ref: branch.base_ref,
|
|
18795
|
+
ref_type: branch.ref_type
|
|
18734
18796
|
},
|
|
18735
18797
|
requestedVariant
|
|
18736
18798
|
);
|
|
@@ -19185,6 +19247,9 @@ function isAlias(id) {
|
|
|
19185
19247
|
}
|
|
19186
19248
|
var CONTEXT_1M_BETA = "context-1m-2025-08-07";
|
|
19187
19249
|
var ONE_MILLION_TOKENS = 9e5;
|
|
19250
|
+
function hasNativeMillionContext(id) {
|
|
19251
|
+
return id.startsWith("claude-fable");
|
|
19252
|
+
}
|
|
19188
19253
|
function toModelOptions(models) {
|
|
19189
19254
|
const aliases = models.filter((m) => isAlias(m.id));
|
|
19190
19255
|
const options = [];
|
|
@@ -19195,7 +19260,7 @@ function toModelOptions(models) {
|
|
|
19195
19260
|
description: void 0,
|
|
19196
19261
|
source: "dynamic"
|
|
19197
19262
|
});
|
|
19198
|
-
if (m.max_input_tokens && m.max_input_tokens >= ONE_MILLION_TOKENS) {
|
|
19263
|
+
if (m.max_input_tokens && m.max_input_tokens >= ONE_MILLION_TOKENS && !hasNativeMillionContext(m.id)) {
|
|
19199
19264
|
options.push({
|
|
19200
19265
|
id: `${m.id}[1m]`,
|
|
19201
19266
|
displayName: `${m.display_name} (1M context)`,
|
|
@@ -19539,6 +19604,7 @@ import { Forbidden as Forbidden7, NotAuthenticated as NotAuthenticated7 } from "
|
|
|
19539
19604
|
import { hasMinimumRole as hasMinimumRole5, ROLES as ROLES5 } from "@agor/core/types";
|
|
19540
19605
|
|
|
19541
19606
|
// src/auth/executor-runtime-scope.ts
|
|
19607
|
+
init_executor_session_token();
|
|
19542
19608
|
import { Forbidden as Forbidden6 } from "@agor/core/feathers";
|
|
19543
19609
|
|
|
19544
19610
|
// src/utils/authorization.ts
|
|
@@ -20278,7 +20344,8 @@ import {
|
|
|
20278
20344
|
getHiddenTenantId,
|
|
20279
20345
|
MCPServerRepository as MCPServerRepository2,
|
|
20280
20346
|
runWithoutTenantDatabaseScope as runWithoutTenantDatabaseScope2,
|
|
20281
|
-
runWithTenantDatabaseScope as
|
|
20347
|
+
runWithTenantDatabaseScope as runWithTenantDatabaseScope3,
|
|
20348
|
+
SessionRepository as SessionRepository2,
|
|
20282
20349
|
shortId as shortId10,
|
|
20283
20350
|
ThreadSessionMapRepository,
|
|
20284
20351
|
UserMCPOAuthTokenRepository as UserMCPOAuthTokenRepository2,
|
|
@@ -20373,6 +20440,13 @@ function oneLineForPrompt(text, maxChars = 900) {
|
|
|
20373
20440
|
if (normalized.length <= maxChars) return normalized;
|
|
20374
20441
|
return `${normalized.slice(0, Math.max(0, maxChars - 1))}\u2026`;
|
|
20375
20442
|
}
|
|
20443
|
+
var SLACK_GATEWAY_REPLY_NOTE = "Note: Any assistant message you send in this current Agor session is streamed back directly to the Slack conversation. Only use outbound gateway tools when you intentionally need to start a separate thread, DM, or message.";
|
|
20444
|
+
function prependSlackGatewayReplyNote(prompt) {
|
|
20445
|
+
if (prompt.includes(SLACK_GATEWAY_REPLY_NOTE)) return prompt;
|
|
20446
|
+
return `${SLACK_GATEWAY_REPLY_NOTE}
|
|
20447
|
+
|
|
20448
|
+
${prompt}`;
|
|
20449
|
+
}
|
|
20376
20450
|
function formatSlackCatchUpPrompt(args) {
|
|
20377
20451
|
const slackChannelName = typeof args.metadata?.slack_channel_name === "string" ? args.metadata.slack_channel_name : null;
|
|
20378
20452
|
const slackChannelId = typeof args.metadata?.channel === "string" ? args.metadata.channel : args.threadId.split("-")[0];
|
|
@@ -20559,6 +20633,7 @@ var GatewayService = class _GatewayService {
|
|
|
20559
20633
|
threadMapRepo;
|
|
20560
20634
|
outboundRepo;
|
|
20561
20635
|
branchRepo;
|
|
20636
|
+
sessionRepo;
|
|
20562
20637
|
usersRepo;
|
|
20563
20638
|
mcpServerRepo;
|
|
20564
20639
|
userTokenRepo;
|
|
@@ -20601,6 +20676,7 @@ var GatewayService = class _GatewayService {
|
|
|
20601
20676
|
this.threadMapRepo = new ThreadSessionMapRepository(db);
|
|
20602
20677
|
this.outboundRepo = new GatewayOutboundMessageRepository(db);
|
|
20603
20678
|
this.branchRepo = new BranchRepository5(db);
|
|
20679
|
+
this.sessionRepo = new SessionRepository2(db);
|
|
20604
20680
|
this.usersRepo = new UsersRepository5(db);
|
|
20605
20681
|
this.mcpServerRepo = new MCPServerRepository2(db);
|
|
20606
20682
|
this.userTokenRepo = new UserMCPOAuthTokenRepository2(db);
|
|
@@ -21096,6 +21172,24 @@ ${chunk}` : chunk;
|
|
|
21096
21172
|
console.warn("[gateway] Failed to mirror message stream to Slack:", error);
|
|
21097
21173
|
}
|
|
21098
21174
|
}
|
|
21175
|
+
/**
|
|
21176
|
+
* Session-context emits are hard-bound to the session's branch, with no
|
|
21177
|
+
* admin-role bypass — agent sessions run as admin users, so a role bypass
|
|
21178
|
+
* would let any session impersonate another assistant's channel. The error
|
|
21179
|
+
* deliberately never echoes the channel's target branch, so a denied emit
|
|
21180
|
+
* cannot be used to enumerate which branch a foreign channel serves.
|
|
21181
|
+
*/
|
|
21182
|
+
async ensureSessionBranchBoundToChannel(channel, sessionId) {
|
|
21183
|
+
const session = await this.sessionRepo.findById(sessionId);
|
|
21184
|
+
if (!session) {
|
|
21185
|
+
throw new Error("Gateway outbound denied: emitting session not found");
|
|
21186
|
+
}
|
|
21187
|
+
if (session.branch_id !== channel.target_branch_id) {
|
|
21188
|
+
throw new Error(
|
|
21189
|
+
`Gateway outbound denied: session ${shortId10(sessionId)} runs on branch ${shortId10(session.branch_id)}, but this channel targets a different branch. Sessions can emit only through gateway channels whose target branch matches their own. Call agor_gateway_outbound_targets_list to see usable channels.`
|
|
21190
|
+
);
|
|
21191
|
+
}
|
|
21192
|
+
}
|
|
21099
21193
|
async ensureCanEmitFromChannel(channel, userId, userRole) {
|
|
21100
21194
|
if (hasMinimumRole6(userRole, ROLES8.ADMIN)) return;
|
|
21101
21195
|
const branch = await this.branchRepo.findById(channel.target_branch_id);
|
|
@@ -21129,6 +21223,9 @@ ${chunk}` : chunk;
|
|
|
21129
21223
|
if (config.outbound_enabled !== true) {
|
|
21130
21224
|
throw new Error("Gateway outbound is disabled for this channel");
|
|
21131
21225
|
}
|
|
21226
|
+
if (data.emittedBySessionId) {
|
|
21227
|
+
await this.ensureSessionBranchBoundToChannel(channel, data.emittedBySessionId);
|
|
21228
|
+
}
|
|
21132
21229
|
await this.ensureCanEmitFromChannel(channel, data.emittedByUserId, data.userRole);
|
|
21133
21230
|
const target = data.target ?? (typeof config.default_outbound_target === "string" ? config.default_outbound_target : void 0);
|
|
21134
21231
|
if (!target) throw new Error("No usable default outbound target configured");
|
|
@@ -21703,6 +21800,9 @@ ${chunk}` : chunk;
|
|
|
21703
21800
|
promptText = contextPrefix + promptText;
|
|
21704
21801
|
}
|
|
21705
21802
|
}
|
|
21803
|
+
if (channel.channel_type === "slack") {
|
|
21804
|
+
promptText = prependSlackGatewayReplyNote(promptText);
|
|
21805
|
+
}
|
|
21706
21806
|
if (created && mcpAuthWarning) {
|
|
21707
21807
|
promptText = `${mcpAuthWarning}
|
|
21708
21808
|
|
|
@@ -22010,7 +22110,7 @@ ${promptText}`;
|
|
|
22010
22110
|
if (!tenantId) {
|
|
22011
22111
|
throw new Error(`Missing tenant context for gateway listener channel ${channel.id}`);
|
|
22012
22112
|
}
|
|
22013
|
-
await
|
|
22113
|
+
await runWithTenantDatabaseScope3(this.db, tenantId, async () => {
|
|
22014
22114
|
await this.create({
|
|
22015
22115
|
channel_key: channel.channel_key,
|
|
22016
22116
|
thread_id: msg.threadId,
|
|
@@ -26783,6 +26883,80 @@ function createSessionMCPServersService(db) {
|
|
|
26783
26883
|
return new SessionMCPServersService(db);
|
|
26784
26884
|
}
|
|
26785
26885
|
|
|
26886
|
+
// src/services/session-streams.ts
|
|
26887
|
+
import { BadRequest as BadRequest12 } from "@agor/core/feathers";
|
|
26888
|
+
|
|
26889
|
+
// src/utils/realtime-publish.ts
|
|
26890
|
+
import {
|
|
26891
|
+
resolveTenantContext as resolveTenantContext2,
|
|
26892
|
+
TenantResolutionError as TenantResolutionError2
|
|
26893
|
+
} from "@agor/core/config";
|
|
26894
|
+
import { getCurrentTenantId as getCurrentTenantId3, shortId as shortId14 } from "@agor/core/db";
|
|
26895
|
+
import { hasMinimumRole as hasMinimumRole9, ROLES as ROLES11 } from "@agor/core/types";
|
|
26896
|
+
|
|
26897
|
+
// src/utils/realtime-access-cache.ts
|
|
26898
|
+
var DEFAULT_BRANCH_VISIBILITY_TTL_MS = 5 * 6e4;
|
|
26899
|
+
var DEFAULT_SESSION_BRANCH_TTL_MS = 60 * 6e4;
|
|
26900
|
+
|
|
26901
|
+
// src/utils/realtime-publish.ts
|
|
26902
|
+
var SESSION_STREAM_CHANNEL_PREFIX = "session-stream:";
|
|
26903
|
+
function sessionStreamChannelName(sessionId) {
|
|
26904
|
+
return `${SESSION_STREAM_CHANNEL_PREFIX}${sessionId}`;
|
|
26905
|
+
}
|
|
26906
|
+
function existingChannel(app, name) {
|
|
26907
|
+
return (app.channels ?? []).includes(name) ? app.channel(name) : null;
|
|
26908
|
+
}
|
|
26909
|
+
function joinSessionStreamChannel(app, sessionId, connection) {
|
|
26910
|
+
app.channel(sessionStreamChannelName(sessionId)).join(connection);
|
|
26911
|
+
}
|
|
26912
|
+
function leaveSessionStreamChannel(app, sessionId, connection) {
|
|
26913
|
+
existingChannel(app, sessionStreamChannelName(sessionId))?.leave(connection);
|
|
26914
|
+
}
|
|
26915
|
+
var DEBUG_REALTIME_PUBLISH = process.env.AGOR_DEBUG_REALTIME_PUBLISH === "1" || process.env.DEBUG?.includes("realtime-publish");
|
|
26916
|
+
|
|
26917
|
+
// src/services/session-streams.ts
|
|
26918
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
26919
|
+
function isCanonicalSessionId(id) {
|
|
26920
|
+
return UUID_RE.test(id);
|
|
26921
|
+
}
|
|
26922
|
+
function createSessionStreamsService(app) {
|
|
26923
|
+
const resolveAccessibleSessionId = async (sessionId, params) => {
|
|
26924
|
+
const session = await app.service("sessions").get(sessionId, { ...params ?? {}, query: {} });
|
|
26925
|
+
return session?.session_id ?? null;
|
|
26926
|
+
};
|
|
26927
|
+
return {
|
|
26928
|
+
async create(data, params) {
|
|
26929
|
+
const connection = params?.connection;
|
|
26930
|
+
if (!connection) {
|
|
26931
|
+
throw new BadRequest12("session stream subscription requires a realtime connection");
|
|
26932
|
+
}
|
|
26933
|
+
const sessionId = data?.session_id ?? data?.sessionId;
|
|
26934
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
26935
|
+
throw new BadRequest12("session_id is required");
|
|
26936
|
+
}
|
|
26937
|
+
const canonicalId = await resolveAccessibleSessionId(sessionId, params) ?? sessionId;
|
|
26938
|
+
joinSessionStreamChannel(app, canonicalId, connection);
|
|
26939
|
+
return { session_id: canonicalId, subscribed: true };
|
|
26940
|
+
},
|
|
26941
|
+
async remove(id, params) {
|
|
26942
|
+
const connection = params?.connection;
|
|
26943
|
+
const sessionId = typeof id === "string" ? id : "";
|
|
26944
|
+
if (!connection || !sessionId) {
|
|
26945
|
+
return { session_id: sessionId, subscribed: false };
|
|
26946
|
+
}
|
|
26947
|
+
let canonicalId = sessionId;
|
|
26948
|
+
if (!isCanonicalSessionId(sessionId)) {
|
|
26949
|
+
try {
|
|
26950
|
+
canonicalId = await resolveAccessibleSessionId(sessionId, params) ?? sessionId;
|
|
26951
|
+
} catch {
|
|
26952
|
+
}
|
|
26953
|
+
}
|
|
26954
|
+
leaveSessionStreamChannel(app, canonicalId, connection);
|
|
26955
|
+
return { session_id: canonicalId, subscribed: false };
|
|
26956
|
+
}
|
|
26957
|
+
};
|
|
26958
|
+
}
|
|
26959
|
+
|
|
26786
26960
|
// src/services/sessions.ts
|
|
26787
26961
|
import { PAGINATION as PAGINATION15 } from "@agor/core/config";
|
|
26788
26962
|
import {
|
|
@@ -26790,10 +26964,10 @@ import {
|
|
|
26790
26964
|
SessionEnvSelectionRepository as SessionEnvSelectionRepository2,
|
|
26791
26965
|
SessionMCPServerRepository as SessionMCPServerRepository2,
|
|
26792
26966
|
SessionRelationshipRepository,
|
|
26793
|
-
SessionRepository as
|
|
26967
|
+
SessionRepository as SessionRepository3,
|
|
26794
26968
|
UsersRepository as UsersRepository6
|
|
26795
26969
|
} from "@agor/core/db";
|
|
26796
|
-
import { BadRequest as
|
|
26970
|
+
import { BadRequest as BadRequest13, Forbidden as Forbidden15 } from "@agor/core/feathers";
|
|
26797
26971
|
import {
|
|
26798
26972
|
formatModelToolMismatchWarning,
|
|
26799
26973
|
formatUnsupportedAgorCodexModelMessage,
|
|
@@ -26801,7 +26975,7 @@ import {
|
|
|
26801
26975
|
lintModelToolMatch
|
|
26802
26976
|
} from "@agor/core/models";
|
|
26803
26977
|
import { resolveChildSessionConfig } from "@agor/core/sessions";
|
|
26804
|
-
import { ROLES as
|
|
26978
|
+
import { ROLES as ROLES12, SessionStatus as SessionStatus2 } from "@agor/core/types";
|
|
26805
26979
|
function getInheritableConfig(parent) {
|
|
26806
26980
|
return {
|
|
26807
26981
|
permission_config: parent.permission_config,
|
|
@@ -26842,11 +27016,11 @@ var SessionsService = class extends DrizzleService {
|
|
|
26842
27016
|
branchRepo;
|
|
26843
27017
|
assertSupportedModelConfig(agenticTool, modelConfig) {
|
|
26844
27018
|
if (agenticTool === "codex" && modelConfig?.model && isUnsupportedAgorCodexModel(modelConfig.model)) {
|
|
26845
|
-
throw new
|
|
27019
|
+
throw new BadRequest13(formatUnsupportedAgorCodexModelMessage(modelConfig.model));
|
|
26846
27020
|
}
|
|
26847
27021
|
}
|
|
26848
27022
|
constructor(db, app) {
|
|
26849
|
-
const sessionRepo = new
|
|
27023
|
+
const sessionRepo = new SessionRepository3(db);
|
|
26850
27024
|
super(sessionRepo, {
|
|
26851
27025
|
id: "session_id",
|
|
26852
27026
|
resourceType: "Session",
|
|
@@ -27195,7 +27369,7 @@ ${data.extraInstructions}`;
|
|
|
27195
27369
|
}
|
|
27196
27370
|
const callerUserId = params?.user?.user_id;
|
|
27197
27371
|
const callerRole = params?.user?.role;
|
|
27198
|
-
const callerIsCreatorOrAdmin = callerUserId === parent.created_by || callerRole ===
|
|
27372
|
+
const callerIsCreatorOrAdmin = callerUserId === parent.created_by || callerRole === ROLES12.ADMIN || isSuperAdmin(callerRole);
|
|
27199
27373
|
if (data.envVarNames !== void 0 && callerIsCreatorOrAdmin) {
|
|
27200
27374
|
await this.sessionEnvSelectionRepo.setAll(session.session_id, data.envVarNames);
|
|
27201
27375
|
} else {
|
|
@@ -27403,7 +27577,7 @@ import {
|
|
|
27403
27577
|
import { PAGINATION as PAGINATION16, resolveExecutorHeartbeatConfig as resolveExecutorHeartbeatConfig2 } from "@agor/core/config";
|
|
27404
27578
|
import {
|
|
27405
27579
|
enqueueTenantDatabasePostCommitCallback as enqueueTenantDatabasePostCommitCallback2,
|
|
27406
|
-
shortId as
|
|
27580
|
+
shortId as shortId16,
|
|
27407
27581
|
TaskRepository
|
|
27408
27582
|
} from "@agor/core/db";
|
|
27409
27583
|
import {
|
|
@@ -27413,7 +27587,7 @@ import {
|
|
|
27413
27587
|
} from "@agor/core/types";
|
|
27414
27588
|
|
|
27415
27589
|
// src/utils/append-system-message.ts
|
|
27416
|
-
import { generateId as generateId2, SessionRepository as
|
|
27590
|
+
import { generateId as generateId2, SessionRepository as SessionRepository4 } from "@agor/core/db";
|
|
27417
27591
|
import { MessageRole } from "@agor/core/types";
|
|
27418
27592
|
async function appendSystemMessage(opts) {
|
|
27419
27593
|
const {
|
|
@@ -27428,7 +27602,7 @@ async function appendSystemMessage(opts) {
|
|
|
27428
27602
|
metadata,
|
|
27429
27603
|
params
|
|
27430
27604
|
} = opts;
|
|
27431
|
-
const index = await new
|
|
27605
|
+
const index = await new SessionRepository4(db).countMessages(sessionId);
|
|
27432
27606
|
const preview = contentPreview ?? (typeof content === "string" ? content.substring(0, 200) : "");
|
|
27433
27607
|
const message = {
|
|
27434
27608
|
message_id: generateId2(),
|
|
@@ -27448,7 +27622,7 @@ async function appendSystemMessage(opts) {
|
|
|
27448
27622
|
|
|
27449
27623
|
// src/utils/executor-heartbeat-callback.ts
|
|
27450
27624
|
import { spawn as spawn3 } from "child_process";
|
|
27451
|
-
import { shortId as
|
|
27625
|
+
import { shortId as shortId15 } from "@agor/core/db";
|
|
27452
27626
|
var ExecutorHeartbeatCallbackRunner = class {
|
|
27453
27627
|
constructor(config) {
|
|
27454
27628
|
this.config = config;
|
|
@@ -27460,7 +27634,7 @@ var ExecutorHeartbeatCallbackRunner = class {
|
|
|
27460
27634
|
if (!command) return;
|
|
27461
27635
|
if (this.runningByTask.has(payload.task_id)) {
|
|
27462
27636
|
console.warn(
|
|
27463
|
-
`[executor-heartbeat] Previous callback still running for task ${
|
|
27637
|
+
`[executor-heartbeat] Previous callback still running for task ${shortId15(payload.task_id)}; skipping heartbeat callback`
|
|
27464
27638
|
);
|
|
27465
27639
|
return;
|
|
27466
27640
|
}
|
|
@@ -27654,7 +27828,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27654
27828
|
);
|
|
27655
27829
|
if (data.status === TaskStatus.RUNNING && !Array.isArray(result) && this.app) {
|
|
27656
27830
|
console.log(`\u{1F50D} [TasksService.create] ENTERING session status update block`);
|
|
27657
|
-
console.log(`\u{1F50D} [TasksService.create] About to patch session ${
|
|
27831
|
+
console.log(`\u{1F50D} [TasksService.create] About to patch session ${shortId16(result.session_id)}`);
|
|
27658
27832
|
try {
|
|
27659
27833
|
const patchResult = await this.app.service("sessions").patch(
|
|
27660
27834
|
result.session_id,
|
|
@@ -27665,7 +27839,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27665
27839
|
params
|
|
27666
27840
|
);
|
|
27667
27841
|
console.log(
|
|
27668
|
-
`\u2705 [TasksService] Session ${
|
|
27842
|
+
`\u2705 [TasksService] Session ${shortId16(result.session_id)} status updated to RUNNING (task ${shortId16(result.task_id)} created)`,
|
|
27669
27843
|
`Patch result status: ${patchResult.status}`
|
|
27670
27844
|
);
|
|
27671
27845
|
} catch (error) {
|
|
@@ -27753,7 +27927,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27753
27927
|
const heartbeatFailureWon = failedTask.status === TaskStatus.FAILED && failedTask.error_message === data.error_message && (!data.completed_at || failedTask.completed_at === data.completed_at);
|
|
27754
27928
|
if (!heartbeatFailureWon) {
|
|
27755
27929
|
console.log(
|
|
27756
|
-
`\u23ED\uFE0F [TasksService] Skipping heartbeat session failure for task ${
|
|
27930
|
+
`\u23ED\uFE0F [TasksService] Skipping heartbeat session failure for task ${shortId16(failedTask.task_id)}; heartbeat failure did not win (status=${failedTask.status})`
|
|
27757
27931
|
);
|
|
27758
27932
|
return failedTask;
|
|
27759
27933
|
}
|
|
@@ -27773,7 +27947,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27773
27947
|
updatedSession = s;
|
|
27774
27948
|
}).catch((error) => {
|
|
27775
27949
|
console.warn(
|
|
27776
|
-
`[executor-heartbeat] Failed to mark session ${
|
|
27950
|
+
`[executor-heartbeat] Failed to mark session ${shortId16(failedTask.session_id)} failed after stale heartbeat:`,
|
|
27777
27951
|
error instanceof Error ? error.message : String(error)
|
|
27778
27952
|
);
|
|
27779
27953
|
});
|
|
@@ -27781,7 +27955,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27781
27955
|
void this.dispatchCompletionCallbacksAfterCommit(failedTask, updatedSession, params).catch(
|
|
27782
27956
|
(error) => {
|
|
27783
27957
|
console.warn(
|
|
27784
|
-
`[executor-heartbeat] Failed to dispatch completion callbacks for task ${
|
|
27958
|
+
`[executor-heartbeat] Failed to dispatch completion callbacks for task ${shortId16(failedTask.task_id)}:`,
|
|
27785
27959
|
error instanceof Error ? error.message : String(error)
|
|
27786
27960
|
);
|
|
27787
27961
|
}
|
|
@@ -27803,7 +27977,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27803
27977
|
}
|
|
27804
27978
|
} catch (error) {
|
|
27805
27979
|
console.warn(
|
|
27806
|
-
`\u26A0\uFE0F [TasksService] Could not resolve branch_id for heartbeat task ${
|
|
27980
|
+
`\u26A0\uFE0F [TasksService] Could not resolve branch_id for heartbeat task ${shortId16(task.task_id)}:`,
|
|
27807
27981
|
error instanceof Error ? error.message : String(error)
|
|
27808
27982
|
);
|
|
27809
27983
|
}
|
|
@@ -27852,7 +28026,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27852
28026
|
const currentTask = nextStatus !== void 0 ? await this.get(id, params) : void 0;
|
|
27853
28027
|
if (currentTask && isTerminalTaskStatus(currentTask.status) && nextStatus !== void 0) {
|
|
27854
28028
|
console.warn(
|
|
27855
|
-
`\u23ED\uFE0F [TasksService] Ignoring status rewrite for terminal task ${
|
|
28029
|
+
`\u23ED\uFE0F [TasksService] Ignoring status rewrite for terminal task ${shortId16(currentTask.task_id)} (${currentTask.status} \u2192 ${nextStatus})`
|
|
27856
28030
|
);
|
|
27857
28031
|
return currentTask;
|
|
27858
28032
|
}
|
|
@@ -27901,7 +28075,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27901
28075
|
this.handleExecutorHeartbeat(result, data.last_executor_heartbeat_at).catch(
|
|
27902
28076
|
(error) => {
|
|
27903
28077
|
console.warn(
|
|
27904
|
-
`\u26A0\uFE0F [TasksService] Executor heartbeat callback failed for task ${
|
|
28078
|
+
`\u26A0\uFE0F [TasksService] Executor heartbeat callback failed for task ${shortId16(result.task_id)}:`,
|
|
27905
28079
|
error
|
|
27906
28080
|
);
|
|
27907
28081
|
}
|
|
@@ -27924,7 +28098,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27924
28098
|
}).catch((err) => {
|
|
27925
28099
|
const message = err instanceof Error ? err.message : String(err);
|
|
27926
28100
|
console.warn(
|
|
27927
|
-
`\u26A0\uFE0F [TasksService] ensureRepoOriginAlignedById failed for session ${task.session_id ?
|
|
28101
|
+
`\u26A0\uFE0F [TasksService] ensureRepoOriginAlignedById failed for session ${task.session_id ? shortId16(task.session_id) : "unknown"}: ${message}`
|
|
27928
28102
|
);
|
|
27929
28103
|
});
|
|
27930
28104
|
}
|
|
@@ -27934,7 +28108,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27934
28108
|
const isStop = data.status === TaskStatus.STOPPED;
|
|
27935
28109
|
if (latestTaskId && latestTaskId !== task.task_id) {
|
|
27936
28110
|
console.log(
|
|
27937
|
-
`\u23ED\uFE0F [TasksService] Skipping session terminal-state update - task ${
|
|
28111
|
+
`\u23ED\uFE0F [TasksService] Skipping session terminal-state update - task ${shortId16(task.task_id)} is not the latest (latest: ${shortId16(latestTaskId)})`
|
|
27938
28112
|
);
|
|
27939
28113
|
if (!suppressCompletionCallbacks && !isStop) {
|
|
27940
28114
|
await this.dispatchCompletionCallbacksAfterCommit(task, session, params);
|
|
@@ -27943,11 +28117,11 @@ var TasksService = class extends DrizzleService {
|
|
|
27943
28117
|
}
|
|
27944
28118
|
if (isStop && params?.suppressTerminalQueueProcessing) {
|
|
27945
28119
|
console.log(
|
|
27946
|
-
`\u23ED\uFE0F [TasksService] Skipping session terminal-state update for STOPPED task ${
|
|
28120
|
+
`\u23ED\uFE0F [TasksService] Skipping session terminal-state update for STOPPED task ${shortId16(task.task_id)} \u2014 caller suppresses terminal queue processing`
|
|
27947
28121
|
);
|
|
27948
28122
|
} else if (params?.suppressTerminalSessionStateUpdate) {
|
|
27949
28123
|
console.log(
|
|
27950
|
-
`\u23ED\uFE0F [TasksService] Skipping session terminal-state update for task ${
|
|
28124
|
+
`\u23ED\uFE0F [TasksService] Skipping session terminal-state update for task ${shortId16(task.task_id)} (${data.status}) due to internal patch params`
|
|
27951
28125
|
);
|
|
27952
28126
|
} else {
|
|
27953
28127
|
await this.app.service("sessions").patch(
|
|
@@ -27959,7 +28133,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27959
28133
|
params
|
|
27960
28134
|
);
|
|
27961
28135
|
console.log(
|
|
27962
|
-
`\u2705 [TasksService] Session ${
|
|
28136
|
+
`\u2705 [TasksService] Session ${shortId16(task.session_id)} status updated after terminal task (task ${shortId16(task.task_id)} ${data.status})`
|
|
27963
28137
|
);
|
|
27964
28138
|
}
|
|
27965
28139
|
if (!suppressCompletionCallbacks && !isStop) {
|
|
@@ -27973,7 +28147,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27973
28147
|
archived_reason: "btw_completed"
|
|
27974
28148
|
});
|
|
27975
28149
|
console.log(
|
|
27976
|
-
`\u{1F4E6} [TasksService] Auto-archived btw fork session ${
|
|
28150
|
+
`\u{1F4E6} [TasksService] Auto-archived btw fork session ${shortId16(session.session_id)}`
|
|
27977
28151
|
);
|
|
27978
28152
|
} catch (error) {
|
|
27979
28153
|
console.warn(`\u26A0\uFE0F [TasksService] Failed to auto-archive btw fork:`, error);
|
|
@@ -27987,7 +28161,7 @@ var TasksService = class extends DrizzleService {
|
|
|
27987
28161
|
await this.triggerQueueProcessingAfterCommit(task.session_id, params);
|
|
27988
28162
|
} else if (params?.suppressTerminalQueueProcessing) {
|
|
27989
28163
|
console.log(
|
|
27990
|
-
`\u23ED\uFE0F [TasksService] Queue trigger suppressed for session ${
|
|
28164
|
+
`\u23ED\uFE0F [TasksService] Queue trigger suppressed for session ${shortId16(task.session_id)} (suppressTerminalQueueProcessing)`
|
|
27991
28165
|
);
|
|
27992
28166
|
}
|
|
27993
28167
|
} catch (error) {
|
|
@@ -28068,7 +28242,7 @@ var TasksService = class extends DrizzleService {
|
|
|
28068
28242
|
}
|
|
28069
28243
|
});
|
|
28070
28244
|
console.log(
|
|
28071
|
-
`\u{1F4AC} [TasksService] Injected btw result message into parent session ${
|
|
28245
|
+
`\u{1F4AC} [TasksService] Injected btw result message into parent session ${shortId16(parentSessionId)} from btw fork ${shortId16(btwSession.session_id)}`
|
|
28072
28246
|
);
|
|
28073
28247
|
} catch (error) {
|
|
28074
28248
|
console.warn(`\u26A0\uFE0F [TasksService] Failed to inject btw result message:`, error);
|
|
@@ -28096,7 +28270,7 @@ var TasksService = class extends DrizzleService {
|
|
|
28096
28270
|
if (dispatchResult.callbackTask) {
|
|
28097
28271
|
try {
|
|
28098
28272
|
console.log(
|
|
28099
|
-
`\u{1F504} [TasksService] Triggering callback target queue processing for ${
|
|
28273
|
+
`\u{1F504} [TasksService] Triggering callback target queue processing for ${shortId16(targetSessionId)} (callback queued)`
|
|
28100
28274
|
);
|
|
28101
28275
|
await this.triggerQueueProcessingAfterCommit(targetSessionId, {});
|
|
28102
28276
|
} catch (error) {
|
|
@@ -28116,7 +28290,7 @@ var TasksService = class extends DrizzleService {
|
|
|
28116
28290
|
}
|
|
28117
28291
|
});
|
|
28118
28292
|
console.log(
|
|
28119
|
-
`\u{1F515} [TasksService] Auto-disabled callback for session ${
|
|
28293
|
+
`\u{1F515} [TasksService] Auto-disabled callback for session ${shortId16(childSession.session_id)} (once mode)`
|
|
28120
28294
|
);
|
|
28121
28295
|
} catch (error) {
|
|
28122
28296
|
console.warn(`\u26A0\uFE0F [TasksService] Failed to auto-disable callback:`, error);
|
|
@@ -28162,7 +28336,7 @@ var TasksService = class extends DrizzleService {
|
|
|
28162
28336
|
const latestTask = await this.taskRepo.findById(task.task_id) ?? task;
|
|
28163
28337
|
if (this.hasCompletionCallbackDispatch(latestTask.metadata, targetSessionId)) {
|
|
28164
28338
|
console.log(
|
|
28165
|
-
`\u23ED\uFE0F [TasksService] Completion callback for task ${
|
|
28339
|
+
`\u23ED\uFE0F [TasksService] Completion callback for task ${shortId16(task.task_id)} to ${shortId16(targetSessionId)} already dispatched`
|
|
28166
28340
|
);
|
|
28167
28341
|
return {};
|
|
28168
28342
|
}
|
|
@@ -28182,7 +28356,7 @@ var TasksService = class extends DrizzleService {
|
|
|
28182
28356
|
);
|
|
28183
28357
|
} catch (error) {
|
|
28184
28358
|
console.warn(
|
|
28185
|
-
`\u26A0\uFE0F [TasksService] Failed to mark completion callback dispatched for task ${
|
|
28359
|
+
`\u26A0\uFE0F [TasksService] Failed to mark completion callback dispatched for task ${shortId16(task.task_id)} to ${shortId16(targetSessionId)} after queueing:`,
|
|
28186
28360
|
error
|
|
28187
28361
|
);
|
|
28188
28362
|
}
|
|
@@ -28208,7 +28382,7 @@ var TasksService = class extends DrizzleService {
|
|
|
28208
28382
|
const callbackEnabled = childSession.callback_config?.enabled ?? targetSession.callback_config?.enabled ?? true;
|
|
28209
28383
|
if (!callbackEnabled) {
|
|
28210
28384
|
console.log(
|
|
28211
|
-
`\u23ED\uFE0F [TasksService] Callbacks disabled for child session ${
|
|
28385
|
+
`\u23ED\uFE0F [TasksService] Callbacks disabled for child session ${shortId16(childSession.session_id)}`
|
|
28212
28386
|
);
|
|
28213
28387
|
return void 0;
|
|
28214
28388
|
}
|
|
@@ -28245,13 +28419,13 @@ var TasksService = class extends DrizzleService {
|
|
|
28245
28419
|
}
|
|
28246
28420
|
}
|
|
28247
28421
|
const context = {
|
|
28248
|
-
childSessionId:
|
|
28422
|
+
childSessionId: shortId16(childSession.session_id),
|
|
28249
28423
|
childSessionFullId: childSession.session_id,
|
|
28250
|
-
childTaskId:
|
|
28424
|
+
childTaskId: shortId16(task.task_id),
|
|
28251
28425
|
childTaskFullId: task.task_id,
|
|
28252
|
-
parentSessionId:
|
|
28426
|
+
parentSessionId: shortId16(targetSessionId),
|
|
28253
28427
|
// backward compat
|
|
28254
|
-
callbackSessionId:
|
|
28428
|
+
callbackSessionId: shortId16(targetSessionId),
|
|
28255
28429
|
spawnPrompt,
|
|
28256
28430
|
status: task.status,
|
|
28257
28431
|
// COMPLETED, FAILED, etc.
|
|
@@ -28264,7 +28438,7 @@ var TasksService = class extends DrizzleService {
|
|
|
28264
28438
|
const callbackMessage = renderChildCompletionCallback(context, customTemplate);
|
|
28265
28439
|
if (!targetSession.created_by) {
|
|
28266
28440
|
console.warn(
|
|
28267
|
-
`\u26A0\uFE0F [TasksService] Cannot queue callback: target session ${
|
|
28441
|
+
`\u26A0\uFE0F [TasksService] Cannot queue callback: target session ${shortId16(targetSessionId)} has no creator (anonymous session)`
|
|
28268
28442
|
);
|
|
28269
28443
|
return void 0;
|
|
28270
28444
|
}
|
|
@@ -28284,7 +28458,7 @@ var TasksService = class extends DrizzleService {
|
|
|
28284
28458
|
});
|
|
28285
28459
|
this.emit?.("queued", callbackTask);
|
|
28286
28460
|
console.log(
|
|
28287
|
-
`\u{1F514} Queued callback task ${
|
|
28461
|
+
`\u{1F514} Queued callback task ${shortId16(callbackTask.task_id)} on session ${shortId16(targetSessionId)} from child ${shortId16(childSession.session_id)}`
|
|
28288
28462
|
);
|
|
28289
28463
|
return callbackTask;
|
|
28290
28464
|
} catch (error) {
|
|
@@ -28364,14 +28538,14 @@ function createTasksService(db, app) {
|
|
|
28364
28538
|
}
|
|
28365
28539
|
|
|
28366
28540
|
// src/services/templates.ts
|
|
28367
|
-
import { BadRequest as
|
|
28541
|
+
import { BadRequest as BadRequest14 } from "@agor/core/feathers";
|
|
28368
28542
|
import { renderTemplate } from "@agor/core/templates/handlebars-helpers";
|
|
28369
|
-
import { ROLES as
|
|
28543
|
+
import { ROLES as ROLES13 } from "@agor/core/types";
|
|
28370
28544
|
var TemplatesService = class {
|
|
28371
28545
|
async create(data, params) {
|
|
28372
|
-
ensureMinimumRole(params,
|
|
28546
|
+
ensureMinimumRole(params, ROLES13.MEMBER, "render templates");
|
|
28373
28547
|
if (typeof data?.template !== "string") {
|
|
28374
|
-
throw new
|
|
28548
|
+
throw new BadRequest14("template (string) is required");
|
|
28375
28549
|
}
|
|
28376
28550
|
const context = data.context && typeof data.context === "object" ? data.context : {};
|
|
28377
28551
|
const rendered = renderTemplate(data.template, context, { onError: data.onError ?? "empty" });
|
|
@@ -28395,8 +28569,8 @@ import {
|
|
|
28395
28569
|
} from "@agor/core/config";
|
|
28396
28570
|
import {
|
|
28397
28571
|
BranchRepository as BranchRepository8,
|
|
28398
|
-
SessionRepository as
|
|
28399
|
-
shortId as
|
|
28572
|
+
SessionRepository as SessionRepository7,
|
|
28573
|
+
shortId as shortId19,
|
|
28400
28574
|
UsersRepository as UsersRepository7
|
|
28401
28575
|
} from "@agor/core/db";
|
|
28402
28576
|
import { Forbidden as Forbidden16 } from "@agor/core/feathers";
|
|
@@ -28408,15 +28582,15 @@ import {
|
|
|
28408
28582
|
} from "@agor/core/unix";
|
|
28409
28583
|
|
|
28410
28584
|
// src/utils/mcp-token-authorization.ts
|
|
28411
|
-
import { hasMinimumRole as
|
|
28585
|
+
import { hasMinimumRole as hasMinimumRole10, ROLES as ROLES14 } from "@agor/core/types";
|
|
28412
28586
|
function hasExplicitMinimumRole(userRole, minimumRole) {
|
|
28413
|
-
return !!userRole &&
|
|
28587
|
+
return !!userRole && hasMinimumRole10(userRole, minimumRole);
|
|
28414
28588
|
}
|
|
28415
28589
|
function canControlCliSession(params) {
|
|
28416
28590
|
const { callerUserId, callerRole, sessionCreatedBy } = params;
|
|
28417
|
-
const isSuperadmin = hasExplicitMinimumRole(callerRole,
|
|
28591
|
+
const isSuperadmin = hasExplicitMinimumRole(callerRole, ROLES14.SUPERADMIN);
|
|
28418
28592
|
const isServiceExecutor = callerRole === "service";
|
|
28419
|
-
const isCreatorMember = !!callerUserId && callerUserId === sessionCreatedBy && hasExplicitMinimumRole(callerRole,
|
|
28593
|
+
const isCreatorMember = !!callerUserId && callerUserId === sessionCreatedBy && hasExplicitMinimumRole(callerRole, ROLES14.MEMBER);
|
|
28420
28594
|
return isCreatorMember || isSuperadmin || isServiceExecutor;
|
|
28421
28595
|
}
|
|
28422
28596
|
|
|
@@ -28436,11 +28610,11 @@ import {
|
|
|
28436
28610
|
import { resolveMultiTenancyConfig as resolveMultiTenancyConfig2 } from "@agor/core/config";
|
|
28437
28611
|
import {
|
|
28438
28612
|
generateId as generateId5,
|
|
28439
|
-
getCurrentTenantId as
|
|
28613
|
+
getCurrentTenantId as getCurrentTenantId4,
|
|
28440
28614
|
runWithoutTenantDatabaseScope as runWithoutTenantDatabaseScope3,
|
|
28441
|
-
runWithTenantDatabaseScope as
|
|
28442
|
-
SessionRepository as
|
|
28443
|
-
shortId as
|
|
28615
|
+
runWithTenantDatabaseScope as runWithTenantDatabaseScope4,
|
|
28616
|
+
SessionRepository as SessionRepository6,
|
|
28617
|
+
shortId as shortId18,
|
|
28444
28618
|
TaskRepository as TaskRepository2
|
|
28445
28619
|
} from "@agor/core/db";
|
|
28446
28620
|
import {
|
|
@@ -28495,7 +28669,7 @@ function buildSpawnConfigForSession(session, branchCwd, opts = {}) {
|
|
|
28495
28669
|
return {
|
|
28496
28670
|
sessionId: transcriptExists ? void 0 : session.session_id,
|
|
28497
28671
|
resumeSessionId: transcriptExists ? session.session_id : void 0,
|
|
28498
|
-
displayName: `cli-${
|
|
28672
|
+
displayName: `cli-${shortId18(session.session_id)}`,
|
|
28499
28673
|
model: session.model_config?.model,
|
|
28500
28674
|
effort: session.model_config?.effort,
|
|
28501
28675
|
advisorModel: session.model_config?.advisorModel,
|
|
@@ -28612,7 +28786,7 @@ async function writeClaudeCliMcpConfigForSession(app, session, opts = {}) {
|
|
|
28612
28786
|
sessionCreatedBy: session.created_by
|
|
28613
28787
|
})) {
|
|
28614
28788
|
console.warn(
|
|
28615
|
-
`[claude-cli-integration] not writing owner-scoped MCP config for session ${
|
|
28789
|
+
`[claude-cli-integration] not writing owner-scoped MCP config for session ${shortId18(session.session_id)}: caller ${opts.actor.user_id ?? "anonymous"} is not allowed to control the owner-scoped CLI MCP config`
|
|
28616
28790
|
);
|
|
28617
28791
|
return void 0;
|
|
28618
28792
|
}
|
|
@@ -28629,12 +28803,12 @@ async function writeClaudeCliMcpConfigForSession(app, session, opts = {}) {
|
|
|
28629
28803
|
});
|
|
28630
28804
|
return writeClaudeCliMcpConfigFile({
|
|
28631
28805
|
mcpConfig,
|
|
28632
|
-
sessionShortId:
|
|
28806
|
+
sessionShortId: shortId18(session.session_id),
|
|
28633
28807
|
targetUnixUser: resolveClaudeCliMcpConfigTargetUnixUser(config, session)
|
|
28634
28808
|
});
|
|
28635
28809
|
} catch (err) {
|
|
28636
28810
|
console.warn(
|
|
28637
|
-
`[claude-cli-integration] failed to write MCP config for session ${
|
|
28811
|
+
`[claude-cli-integration] failed to write MCP config for session ${shortId18(session.session_id)}; Agor MCP tools will be unavailable in Claude CLI/RemoteTrigger:`,
|
|
28638
28812
|
err instanceof Error ? err.message : String(err)
|
|
28639
28813
|
);
|
|
28640
28814
|
return void 0;
|
|
@@ -28643,7 +28817,7 @@ async function writeClaudeCliMcpConfigForSession(app, session, opts = {}) {
|
|
|
28643
28817
|
|
|
28644
28818
|
// src/services/terminals.ts
|
|
28645
28819
|
function buildBranchShellTabName(branch) {
|
|
28646
|
-
return `${branch.name} \xB7 ${
|
|
28820
|
+
return `${branch.name} \xB7 ${shortId19(branch.branch_id)}`;
|
|
28647
28821
|
}
|
|
28648
28822
|
function safeRealpath(pathToResolve) {
|
|
28649
28823
|
try {
|
|
@@ -28674,7 +28848,7 @@ function writeEnvFile(userId, env, chownTo) {
|
|
|
28674
28848
|
if (!userId) return null;
|
|
28675
28849
|
try {
|
|
28676
28850
|
const tmpDir = os2.tmpdir();
|
|
28677
|
-
const envFile = path11.join(tmpDir, `agor-env-${
|
|
28851
|
+
const envFile = path11.join(tmpDir, `agor-env-${shortId19(userId)}.sh`);
|
|
28678
28852
|
const exportLines = Object.entries(env).filter(([key]) => {
|
|
28679
28853
|
const skipKeys = ["PATH", "HOME", "USER", "SHELL", "PWD", "OLDPWD", "TERM", "COLORTERM"];
|
|
28680
28854
|
return !skipKeys.includes(key);
|
|
@@ -28860,7 +29034,7 @@ var TerminalsService = class {
|
|
|
28860
29034
|
async resolveEnsureCliTab(sessionId, claimedBranchId, params) {
|
|
28861
29035
|
if (!sessionId) return null;
|
|
28862
29036
|
try {
|
|
28863
|
-
const sessionRepo = new
|
|
29037
|
+
const sessionRepo = new SessionRepository7(this.db);
|
|
28864
29038
|
const session = await sessionRepo.findById(sessionId).catch(() => null);
|
|
28865
29039
|
if (session?.agentic_tool !== "claude-code-cli") return null;
|
|
28866
29040
|
if (claimedBranchId && claimedBranchId !== session.branch_id) {
|
|
@@ -28915,7 +29089,7 @@ var TerminalsService = class {
|
|
|
28915
29089
|
});
|
|
28916
29090
|
const spawnCfg = buildSpawnConfigForSession(session, branch.path, { mcpConfigPath });
|
|
28917
29091
|
const built = buildClaudeCliSpawn2(spawnCfg);
|
|
28918
|
-
const tabName = session.cli_state?.zellij_tab_name ?? spawnCfg.displayName ?? `cli-${
|
|
29092
|
+
const tabName = session.cli_state?.zellij_tab_name ?? spawnCfg.displayName ?? `cli-${shortId19(session.session_id)}`;
|
|
28919
29093
|
return {
|
|
28920
29094
|
tabName,
|
|
28921
29095
|
cwd: branch.path,
|
|
@@ -28944,12 +29118,12 @@ var TerminalsService = class {
|
|
|
28944
29118
|
if (await waitForPendingStart()) {
|
|
28945
29119
|
return this.createExecutorTerminal(data, params);
|
|
28946
29120
|
}
|
|
28947
|
-
const expectedSessionName = `agor-${
|
|
29121
|
+
const expectedSessionName = `agor-${shortId19(userId)}`;
|
|
28948
29122
|
if (!this.executorTerminals.get(userId)) {
|
|
28949
29123
|
const adopted = await this.detectExistingExecutor(expectedSessionName);
|
|
28950
29124
|
if (adopted) {
|
|
28951
29125
|
console.log(
|
|
28952
|
-
`[TerminalsService] adopting existing zellij executor for user ${
|
|
29126
|
+
`[TerminalsService] adopting existing zellij executor for user ${shortId19(userId)} (sessionName=${expectedSessionName})`
|
|
28953
29127
|
);
|
|
28954
29128
|
this.executorTerminals.set(userId, {
|
|
28955
29129
|
sessionName: expectedSessionName,
|
|
@@ -29076,7 +29250,7 @@ var TerminalsService = class {
|
|
|
29076
29250
|
cwd = resolveBranchShellCwd(branch, finalUnixUser);
|
|
29077
29251
|
}
|
|
29078
29252
|
}
|
|
29079
|
-
const userSessionSuffix =
|
|
29253
|
+
const userSessionSuffix = shortId19(userId);
|
|
29080
29254
|
const sessionName = `agor-${userSessionSuffix}`;
|
|
29081
29255
|
const daemonUrl = `http://localhost:${config.daemon?.port || 3030}`;
|
|
29082
29256
|
const sessionToken = generateScopedServiceToken(this.app, params);
|
|
@@ -29105,7 +29279,7 @@ var TerminalsService = class {
|
|
|
29105
29279
|
}
|
|
29106
29280
|
},
|
|
29107
29281
|
{
|
|
29108
|
-
logPrefix: `[TerminalsService.executor ${
|
|
29282
|
+
logPrefix: `[TerminalsService.executor ${shortId19(userId)}]`,
|
|
29109
29283
|
asUser: finalUnixUser || void 0,
|
|
29110
29284
|
env: executorEnv,
|
|
29111
29285
|
// Clean up map when executor exits (handles crashes too)
|
|
@@ -29197,7 +29371,7 @@ var TerminalsService = class {
|
|
|
29197
29371
|
*/
|
|
29198
29372
|
handleExecutorExit(userId) {
|
|
29199
29373
|
this.executorTerminals.delete(userId);
|
|
29200
|
-
console.log(`[TerminalsService] Executor terminal exited for user ${
|
|
29374
|
+
console.log(`[TerminalsService] Executor terminal exited for user ${shortId19(userId)}`);
|
|
29201
29375
|
}
|
|
29202
29376
|
};
|
|
29203
29377
|
|
|
@@ -29257,9 +29431,9 @@ import { Forbidden as Forbidden18, NotAuthenticated as NotAuthenticated10 } from
|
|
|
29257
29431
|
import { isLikelyGitToken } from "@agor/core/git/pure";
|
|
29258
29432
|
import {
|
|
29259
29433
|
extractAgenticToolsPublicValues,
|
|
29260
|
-
hasMinimumRole as
|
|
29434
|
+
hasMinimumRole as hasMinimumRole12,
|
|
29261
29435
|
normalizeRole,
|
|
29262
|
-
ROLES as
|
|
29436
|
+
ROLES as ROLES16,
|
|
29263
29437
|
toAgenticToolsStatus
|
|
29264
29438
|
} from "@agor/core/types";
|
|
29265
29439
|
|
|
@@ -29271,7 +29445,7 @@ import {
|
|
|
29271
29445
|
} from "@agor/core/db";
|
|
29272
29446
|
import { Forbidden as Forbidden17 } from "@agor/core/feathers";
|
|
29273
29447
|
import { SlackConnector } from "@agor/core/gateway";
|
|
29274
|
-
import { hasMinimumRole as
|
|
29448
|
+
import { hasMinimumRole as hasMinimumRole11, ROLES as ROLES15 } from "@agor/core/types";
|
|
29275
29449
|
var NAMESPACE = "user_avatars";
|
|
29276
29450
|
var SETTINGS_KEY = "settings";
|
|
29277
29451
|
var DEFAULT_SETTINGS = {
|
|
@@ -29280,7 +29454,7 @@ var DEFAULT_SETTINGS = {
|
|
|
29280
29454
|
gateway_channel_id: null
|
|
29281
29455
|
};
|
|
29282
29456
|
function isAdmin(params) {
|
|
29283
|
-
return
|
|
29457
|
+
return hasMinimumRole11(params?.user?.role, ROLES15.ADMIN);
|
|
29284
29458
|
}
|
|
29285
29459
|
function requireAdmin(params) {
|
|
29286
29460
|
if (params?.provider && !isAdmin(params)) {
|
|
@@ -29398,7 +29572,7 @@ var UserAvatarSyncManager = class {
|
|
|
29398
29572
|
user: {
|
|
29399
29573
|
user_id: "user-avatars-service",
|
|
29400
29574
|
email: "user-avatars@agor.internal",
|
|
29401
|
-
role:
|
|
29575
|
+
role: ROLES15.ADMIN,
|
|
29402
29576
|
_isServiceAccount: true
|
|
29403
29577
|
}
|
|
29404
29578
|
}
|
|
@@ -29504,7 +29678,7 @@ var UserAvatarSyncManager = class {
|
|
|
29504
29678
|
user: {
|
|
29505
29679
|
user_id: "user-avatars-service",
|
|
29506
29680
|
email: "user-avatars@agor.internal",
|
|
29507
|
-
role:
|
|
29681
|
+
role: ROLES15.ADMIN,
|
|
29508
29682
|
_isServiceAccount: true
|
|
29509
29683
|
}
|
|
29510
29684
|
}
|
|
@@ -29571,7 +29745,7 @@ function isServiceAccount(params) {
|
|
|
29571
29745
|
return !!params?.user?._isServiceAccount;
|
|
29572
29746
|
}
|
|
29573
29747
|
function isAdmin2(params) {
|
|
29574
|
-
return
|
|
29748
|
+
return hasMinimumRole12(params?.user?.role, ROLES16.ADMIN);
|
|
29575
29749
|
}
|
|
29576
29750
|
function isSelfEmailLookup(params, email) {
|
|
29577
29751
|
const requesterEmail = params?.user?.email;
|
|
@@ -29700,8 +29874,8 @@ var UsersService = class {
|
|
|
29700
29874
|
const hashedPassword = await hash(data.password, 10);
|
|
29701
29875
|
const now = /* @__PURE__ */ new Date();
|
|
29702
29876
|
const user_id = generateId6();
|
|
29703
|
-
const role = data.role ||
|
|
29704
|
-
const defaultEmoji = role ===
|
|
29877
|
+
const role = data.role || ROLES16.MEMBER;
|
|
29878
|
+
const defaultEmoji = role === ROLES16.ADMIN ? "\u2B50" : "\u{1F464}";
|
|
29705
29879
|
const row = await insert(this.db, users2).values({
|
|
29706
29880
|
user_id,
|
|
29707
29881
|
email: data.email,
|
|
@@ -30060,21 +30234,37 @@ function createUsersService(db, app) {
|
|
|
30060
30234
|
}
|
|
30061
30235
|
|
|
30062
30236
|
// src/setup/socketio.ts
|
|
30063
|
-
import { resolveTenantContext as
|
|
30064
|
-
import { shortId as
|
|
30237
|
+
import { resolveTenantContext as resolveTenantContext3 } from "@agor/core/config";
|
|
30238
|
+
import { shortId as shortId20 } from "@agor/core/db";
|
|
30065
30239
|
import jwt5 from "jsonwebtoken";
|
|
30066
30240
|
function userRoomName(userId) {
|
|
30067
30241
|
return `user:${userId}`;
|
|
30068
30242
|
}
|
|
30069
30243
|
|
|
30070
30244
|
// src/utils/mcp-header-secrets.ts
|
|
30245
|
+
init_executor_session_token();
|
|
30071
30246
|
import { redactMCPAuthSecrets } from "@agor/core/tools/mcp/auth-secrets";
|
|
30072
30247
|
import { redactMCPCustomHeaders } from "@agor/core/tools/mcp/http-headers";
|
|
30248
|
+
import jwt6 from "jsonwebtoken";
|
|
30073
30249
|
function shouldExposeMCPServerSecretsForSessionToken(params, options = {}) {
|
|
30074
|
-
const payload = params?.authentication?.payload;
|
|
30075
|
-
const sessionId = params?.session_id ?? payload
|
|
30250
|
+
const payload = params?.authentication?.payload ?? decodeExecutorSessionPayload(params);
|
|
30251
|
+
const sessionId = params?.session_id ?? getPayloadSessionId(payload);
|
|
30076
30252
|
return !!params?.provider && (params.authentication?.strategy === "session-token" || payload?.type === "executor-session") && !!sessionId && (!options.sessionId || sessionId === options.sessionId);
|
|
30077
30253
|
}
|
|
30254
|
+
function decodeExecutorSessionPayload(params) {
|
|
30255
|
+
if (params?.authentication?.strategy !== "jwt" || !params.authentication.accessToken) {
|
|
30256
|
+
return void 0;
|
|
30257
|
+
}
|
|
30258
|
+
const decoded = jwt6.decode(params.authentication.accessToken);
|
|
30259
|
+
if (!decoded || typeof decoded !== "object" || Array.isArray(decoded)) {
|
|
30260
|
+
return void 0;
|
|
30261
|
+
}
|
|
30262
|
+
if (!isExecutorSessionTokenPayload(decoded)) return void 0;
|
|
30263
|
+
return decoded;
|
|
30264
|
+
}
|
|
30265
|
+
function getPayloadSessionId(payload) {
|
|
30266
|
+
return payload ? getExecutorSessionTokenSessionId(payload) : void 0;
|
|
30267
|
+
}
|
|
30078
30268
|
function shouldExposeMCPServerSecrets(params, options = {}) {
|
|
30079
30269
|
if (!params?.provider) return true;
|
|
30080
30270
|
if (params.user?._isServiceAccount || params.user?.role === "service") return true;
|
|
@@ -30175,7 +30365,7 @@ async function restoreFile(filePath, payload) {
|
|
|
30175
30365
|
}
|
|
30176
30366
|
|
|
30177
30367
|
// src/utils/session-state-hooks.ts
|
|
30178
|
-
import { SerializedSessionRepository, shortId as
|
|
30368
|
+
import { SerializedSessionRepository, shortId as shortId21 } from "@agor/core/db";
|
|
30179
30369
|
var STALE_PROCESSING_THRESHOLD_MS = 3e4;
|
|
30180
30370
|
async function pullIfNeeded(ctx) {
|
|
30181
30371
|
const repo = new SerializedSessionRepository(ctx.db);
|
|
@@ -30193,7 +30383,7 @@ async function pullIfNeeded(ctx) {
|
|
|
30193
30383
|
const age = Date.now() - latest.created_at;
|
|
30194
30384
|
if (age > STALE_PROCESSING_THRESHOLD_MS) {
|
|
30195
30385
|
console.log(
|
|
30196
|
-
`[session-state] Cleaning stale 'processing' row ${
|
|
30386
|
+
`[session-state] Cleaning stale 'processing' row ${shortId21(latest.id)} (age: ${Math.round(age / 1e3)}s)`
|
|
30197
30387
|
);
|
|
30198
30388
|
await repo.deleteById(latest.id);
|
|
30199
30389
|
latest = await repo.findLatestDone(ctx.sessionId);
|
|
@@ -30216,12 +30406,12 @@ async function pullIfNeeded(ctx) {
|
|
|
30216
30406
|
}
|
|
30217
30407
|
if (!latest.payload) {
|
|
30218
30408
|
console.warn(
|
|
30219
|
-
`[session-state] 'done' row ${
|
|
30409
|
+
`[session-state] 'done' row ${shortId21(latest.id)} has no payload, skipping restore`
|
|
30220
30410
|
);
|
|
30221
30411
|
return;
|
|
30222
30412
|
}
|
|
30223
30413
|
console.log(
|
|
30224
|
-
`[session-state] Restoring session file from DB (row ${
|
|
30414
|
+
`[session-state] Restoring session file from DB (row ${shortId21(latest.id)}, turn ${latest.turn_index})`
|
|
30225
30415
|
);
|
|
30226
30416
|
await restoreFile(filePath, latest.payload);
|
|
30227
30417
|
}
|
|
@@ -30297,6 +30487,13 @@ async function registerServices(ctx) {
|
|
|
30297
30487
|
sessionsService.setExecuteHandler(
|
|
30298
30488
|
createExecuteHandler(ctx, sessionsService, sessionTokenService)
|
|
30299
30489
|
);
|
|
30490
|
+
app.use("/session-streams", createSessionStreamsService(app), {
|
|
30491
|
+
methods: ["create", "remove"]
|
|
30492
|
+
});
|
|
30493
|
+
app.service("/session-streams").hooks({
|
|
30494
|
+
before: { all: [ctx.requireAuth] }
|
|
30495
|
+
});
|
|
30496
|
+
app.service("/session-streams").publish(() => []);
|
|
30300
30497
|
app.use("/tasks", createTasksService(db, app), {
|
|
30301
30498
|
// Custom events not in this list are dropped at the FeathersJS transport
|
|
30302
30499
|
// boundary — they fire on the local EventEmitter but never reach socket
|
|
@@ -30499,7 +30696,7 @@ async function registerServices(ctx) {
|
|
|
30499
30696
|
app.use("/gateway-channels/test", createGatewayChannelsTestService(db));
|
|
30500
30697
|
app.service("gateway-channels/test").hooks({
|
|
30501
30698
|
before: {
|
|
30502
|
-
create: [ctx.requireAuth, requireMinimumRole(
|
|
30699
|
+
create: [ctx.requireAuth, requireMinimumRole(ROLES17.ADMIN, "test gateway channels")]
|
|
30503
30700
|
}
|
|
30504
30701
|
});
|
|
30505
30702
|
app.use("/thread-session-map", createThreadSessionMapService(db));
|
|
@@ -30537,9 +30734,9 @@ async function registerServices(ctx) {
|
|
|
30537
30734
|
app.use("/cursor-models", createCursorModelsService(db));
|
|
30538
30735
|
app.service("/cursor-models").hooks({ before: { find: [ctx.requireAuth] } });
|
|
30539
30736
|
const branchRepository = new BranchRepository9(db);
|
|
30540
|
-
const { UsersRepository: UsersRepository9, SessionRepository:
|
|
30737
|
+
const { UsersRepository: UsersRepository9, SessionRepository: SessionRepository8 } = await import("@agor/core/db");
|
|
30541
30738
|
const usersRepository = new UsersRepository9(db);
|
|
30542
|
-
const sessionsRepository = new
|
|
30739
|
+
const sessionsRepository = new SessionRepository8(db);
|
|
30543
30740
|
if (svcEnabled("file_browser")) {
|
|
30544
30741
|
app.use("/context", createContextService(branchRepository));
|
|
30545
30742
|
app.use("/file", createFileService(branchRepository));
|
|
@@ -30800,7 +30997,7 @@ function createExecuteHandler(ctx, sessionsService, sessionTokenService) {
|
|
|
30800
30997
|
);
|
|
30801
30998
|
}
|
|
30802
30999
|
}
|
|
30803
|
-
const logPrefix = `[Executor ${
|
|
31000
|
+
const logPrefix = `[Executor ${shortId22(sessionId)}]`;
|
|
30804
31001
|
spawnExecutor(executorPayload, {
|
|
30805
31002
|
cwd,
|
|
30806
31003
|
asUser: executorUnixUser || void 0,
|
|
@@ -30825,7 +31022,7 @@ function createExecuteHandler(ctx, sessionsService, sessionTokenService) {
|
|
|
30825
31022
|
const latestTaskId = currentSession.tasks?.[currentSession.tasks.length - 1];
|
|
30826
31023
|
if (latestTaskId && latestTaskId !== taskId) {
|
|
30827
31024
|
console.log(
|
|
30828
|
-
`\u23ED\uFE0F [Executor] Task ${
|
|
31025
|
+
`\u23ED\uFE0F [Executor] Task ${shortId22(taskId)} is not the latest (latest: ${shortId22(latestTaskId)}), skipping safety net`
|
|
30829
31026
|
);
|
|
30830
31027
|
} else if (isSessionExecuting(currentSession) || currentSession.status === SessionStatus5.TIMED_OUT) {
|
|
30831
31028
|
try {
|
|
@@ -30840,27 +31037,27 @@ function createExecuteHandler(ctx, sessionsService, sessionTokenService) {
|
|
|
30840
31037
|
params
|
|
30841
31038
|
);
|
|
30842
31039
|
console.log(
|
|
30843
|
-
`\u2705 [Executor] Task ${
|
|
31040
|
+
`\u2705 [Executor] Task ${shortId22(taskId)} marked as FAILED after executor exit (code: ${code})`
|
|
30844
31041
|
);
|
|
30845
31042
|
} else {
|
|
30846
31043
|
console.log(
|
|
30847
|
-
`\u26A0\uFE0F [Executor] Task ${
|
|
31044
|
+
`\u26A0\uFE0F [Executor] Task ${shortId22(taskId)} already ${currentTask.status}, but session still ${currentSession.status} \u2014 repairing session state`
|
|
30848
31045
|
);
|
|
30849
31046
|
await app.service("sessions").patch(sessionId, { status: SessionStatus5.IDLE, ready_for_prompt: true }, params);
|
|
30850
31047
|
}
|
|
30851
31048
|
} catch (taskError) {
|
|
30852
31049
|
console.error(
|
|
30853
|
-
`\u26A0\uFE0F [Executor] Failed to mark task ${
|
|
31050
|
+
`\u26A0\uFE0F [Executor] Failed to mark task ${shortId22(taskId)} as FAILED, falling back to session IDLE update:`,
|
|
30854
31051
|
taskError
|
|
30855
31052
|
);
|
|
30856
31053
|
await app.service("sessions").patch(sessionId, { status: SessionStatus5.IDLE, ready_for_prompt: true }, params);
|
|
30857
31054
|
console.log(
|
|
30858
|
-
`\u2705 [Executor] Session ${
|
|
31055
|
+
`\u2705 [Executor] Session ${shortId22(sessionId)} status updated to IDLE after executor exit (was: ${currentSession.status})`
|
|
30859
31056
|
);
|
|
30860
31057
|
}
|
|
30861
31058
|
} else {
|
|
30862
31059
|
console.log(
|
|
30863
|
-
`\u2139\uFE0F [Executor] Session ${
|
|
31060
|
+
`\u2139\uFE0F [Executor] Session ${shortId22(sessionId)} already in ${currentSession.status} state, skipping IDLE update`
|
|
30864
31061
|
);
|
|
30865
31062
|
}
|
|
30866
31063
|
} catch (error) {
|
|
@@ -31016,6 +31213,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31016
31213
|
mcpServerId: opts.mcpServerId,
|
|
31017
31214
|
userId: opts.userId,
|
|
31018
31215
|
oauthMode: opts.oauthMode,
|
|
31216
|
+
tenantId: opts.tenantId ?? getCurrentTenantId6(),
|
|
31019
31217
|
socketId: opts.socketId,
|
|
31020
31218
|
createdAt: Date.now(),
|
|
31021
31219
|
tokenResolve,
|
|
@@ -31039,6 +31237,31 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31039
31237
|
}
|
|
31040
31238
|
return base;
|
|
31041
31239
|
}
|
|
31240
|
+
const tenantIdFromParams = (params) => params?.tenant?.tenant_id ?? getCurrentTenantId6();
|
|
31241
|
+
const persistOAuthTokenForPendingFlow = async (tokenResponse, pendingFlow, logPrefix) => {
|
|
31242
|
+
const work = () => persistOAuthToken(
|
|
31243
|
+
db,
|
|
31244
|
+
tokenResponse,
|
|
31245
|
+
pendingFlow.mcpUrl,
|
|
31246
|
+
{
|
|
31247
|
+
...pendingFlow,
|
|
31248
|
+
clientId: pendingFlow.context.clientId,
|
|
31249
|
+
clientSecret: pendingFlow.context.clientSecret,
|
|
31250
|
+
tokenEndpoint: pendingFlow.context.tokenEndpoint
|
|
31251
|
+
},
|
|
31252
|
+
logPrefix
|
|
31253
|
+
);
|
|
31254
|
+
if (pendingFlow.tenantId) {
|
|
31255
|
+
await runInOAuthTenantScope(db, pendingFlow.tenantId, work);
|
|
31256
|
+
return;
|
|
31257
|
+
}
|
|
31258
|
+
if (isPostgresDatabase7(db) && pendingFlow.mcpServerId) {
|
|
31259
|
+
throw new Error(
|
|
31260
|
+
"Missing tenant context for MCP OAuth callback. Please restart the OAuth flow."
|
|
31261
|
+
);
|
|
31262
|
+
}
|
|
31263
|
+
await work();
|
|
31264
|
+
};
|
|
31042
31265
|
const oauthCallbackHandler = async (req, res) => {
|
|
31043
31266
|
res.setHeader("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'");
|
|
31044
31267
|
res.setHeader("X-Content-Type-Options", "nosniff");
|
|
@@ -31081,18 +31304,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31081
31304
|
const { completeMCPOAuthFlow } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
|
|
31082
31305
|
const tokenResponse = await completeMCPOAuthFlow(pendingFlow.context, code, state);
|
|
31083
31306
|
pendingOAuthFlows.delete(state);
|
|
31084
|
-
await
|
|
31085
|
-
db,
|
|
31086
|
-
tokenResponse,
|
|
31087
|
-
pendingFlow.mcpUrl,
|
|
31088
|
-
{
|
|
31089
|
-
...pendingFlow,
|
|
31090
|
-
clientId: pendingFlow.context.clientId,
|
|
31091
|
-
clientSecret: pendingFlow.context.clientSecret,
|
|
31092
|
-
tokenEndpoint: pendingFlow.context.tokenEndpoint
|
|
31093
|
-
},
|
|
31094
|
-
"OAuth Callback"
|
|
31095
|
-
);
|
|
31307
|
+
await persistOAuthTokenForPendingFlow(tokenResponse, pendingFlow, "OAuth Callback");
|
|
31096
31308
|
if (app.io) {
|
|
31097
31309
|
const oauthEvent = {
|
|
31098
31310
|
state,
|
|
@@ -31221,6 +31433,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31221
31433
|
// call (writes to the shared MCP server row, not per-user).
|
|
31222
31434
|
oauthMode: "shared",
|
|
31223
31435
|
clientId: data.client_id,
|
|
31436
|
+
tenantId: tenantIdFromParams(params),
|
|
31224
31437
|
socketId: connection?.id
|
|
31225
31438
|
});
|
|
31226
31439
|
} catch (err) {
|
|
@@ -31423,6 +31636,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31423
31636
|
try {
|
|
31424
31637
|
console.log("[OAuth Start] Starting two-phase OAuth flow for:", data.mcp_url);
|
|
31425
31638
|
const userId = params?.user?.user_id;
|
|
31639
|
+
const tenantId = tenantIdFromParams(params);
|
|
31426
31640
|
let oauthMode;
|
|
31427
31641
|
let authorizationUrlOverride;
|
|
31428
31642
|
let tokenUrlOverride;
|
|
@@ -31430,8 +31644,10 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31430
31644
|
let clientIdFromConfig;
|
|
31431
31645
|
let scopeOverride;
|
|
31432
31646
|
if (data.mcp_server_id) {
|
|
31433
|
-
const
|
|
31434
|
-
|
|
31647
|
+
const server = await runInOAuthTenantScope(db, tenantId, () => {
|
|
31648
|
+
const mcpServerRepo = new MCPServerRepository4(db);
|
|
31649
|
+
return mcpServerRepo.findById(data.mcp_server_id);
|
|
31650
|
+
});
|
|
31435
31651
|
if (server?.auth?.type === "oauth") {
|
|
31436
31652
|
oauthMode = server.auth.oauth_mode || "per_user";
|
|
31437
31653
|
authorizationUrlOverride = server.auth.oauth_authorization_url;
|
|
@@ -31479,6 +31695,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31479
31695
|
authorizationUrlOverride,
|
|
31480
31696
|
tokenUrlOverride,
|
|
31481
31697
|
scope: scopeOverride,
|
|
31698
|
+
tenantId,
|
|
31482
31699
|
socketId
|
|
31483
31700
|
});
|
|
31484
31701
|
} catch (err) {
|
|
@@ -31523,18 +31740,13 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31523
31740
|
};
|
|
31524
31741
|
const tokenResponse = await completeMCPOAuthFlow(pendingFlow.context, code, state);
|
|
31525
31742
|
pendingOAuthFlows.delete(state);
|
|
31526
|
-
|
|
31527
|
-
|
|
31528
|
-
|
|
31529
|
-
|
|
31530
|
-
|
|
31531
|
-
|
|
31532
|
-
|
|
31533
|
-
clientSecret: pendingFlow.context.clientSecret,
|
|
31534
|
-
tokenEndpoint: pendingFlow.context.tokenEndpoint
|
|
31535
|
-
},
|
|
31536
|
-
"OAuth Complete"
|
|
31537
|
-
);
|
|
31743
|
+
const activeTenantId = getCurrentTenantId6();
|
|
31744
|
+
if (pendingFlow.tenantId && activeTenantId && pendingFlow.tenantId !== activeTenantId) {
|
|
31745
|
+
throw new Error(
|
|
31746
|
+
"OAuth flow belongs to a different tenant. Please restart the OAuth flow."
|
|
31747
|
+
);
|
|
31748
|
+
}
|
|
31749
|
+
await persistOAuthTokenForPendingFlow(tokenResponse, pendingFlow, "OAuth Complete");
|
|
31538
31750
|
return { success: true, message: "OAuth authentication successful!", tokenObtained: true };
|
|
31539
31751
|
} catch (error) {
|
|
31540
31752
|
console.error("[OAuth Complete] Error:", error);
|
|
@@ -31591,17 +31803,35 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31591
31803
|
}
|
|
31592
31804
|
const sessionId = params?.session_id;
|
|
31593
31805
|
const trustedInternalOrService = shouldExposeMCPServerSecrets(params);
|
|
31594
|
-
|
|
31806
|
+
let trustedSessionExecutor = shouldExposeMCPServerSecretsForSessionToken(params, {
|
|
31595
31807
|
sessionId
|
|
31596
31808
|
});
|
|
31809
|
+
let executorSessionId = sessionId;
|
|
31810
|
+
if (!trustedSessionExecutor && params?.provider && data.executorSessionToken) {
|
|
31811
|
+
const executorTokenService = app.sessionTokenService;
|
|
31812
|
+
const sessionInfo = await executorTokenService?.validateToken(
|
|
31813
|
+
data.executorSessionToken,
|
|
31814
|
+
{}
|
|
31815
|
+
);
|
|
31816
|
+
if (sessionInfo?.session_id) {
|
|
31817
|
+
executorSessionId = sessionInfo.session_id;
|
|
31818
|
+
trustedSessionExecutor = true;
|
|
31819
|
+
}
|
|
31820
|
+
}
|
|
31597
31821
|
if (!trustedInternalOrService && !trustedSessionExecutor) {
|
|
31598
31822
|
throw new Forbidden19("oauth-auth-headers is only available to trusted executor paths");
|
|
31599
31823
|
}
|
|
31600
31824
|
const userTokenRepo = new UserMCPOAuthTokenRepository3(db);
|
|
31601
31825
|
const mcpServerRepo = new MCPServerRepository4(db);
|
|
31602
31826
|
if (trustedSessionExecutor) {
|
|
31827
|
+
if (!executorSessionId) {
|
|
31828
|
+
throw new Forbidden19("oauth-auth-headers requires executor session scope");
|
|
31829
|
+
}
|
|
31603
31830
|
const sessionMcpRepo = new SessionMCPServerRepository3(db);
|
|
31604
|
-
const attachedServers = await sessionMcpRepo.listServers(
|
|
31831
|
+
const attachedServers = await sessionMcpRepo.listServers(
|
|
31832
|
+
executorSessionId,
|
|
31833
|
+
true
|
|
31834
|
+
);
|
|
31605
31835
|
const globalServers = await mcpServerRepo.findAll({ scope: "global", enabled: true });
|
|
31606
31836
|
const allowedServerIds = /* @__PURE__ */ new Set([
|
|
31607
31837
|
...globalServers.map((server) => server.mcp_server_id),
|
|
@@ -31741,7 +31971,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31741
31971
|
const { restoreRedactedMCPAuthSecrets } = await import("@agor/core/tools/mcp/auth-secrets");
|
|
31742
31972
|
const { resolveMCPAuthHeaders } = await import("@agor/core/tools/mcp/jwt-auth");
|
|
31743
31973
|
const { mergeMCPRemoteHeaders, restoreRedactedMCPCustomHeaders } = await import("@agor/core/tools/mcp/http-headers");
|
|
31744
|
-
const { hasMinimumRole:
|
|
31974
|
+
const { hasMinimumRole: hasMinimumRole13, ROLES: ROLES18 } = await import("@agor/core/types");
|
|
31745
31975
|
const mcpServerRepo = new MCPServerRepository4(db);
|
|
31746
31976
|
const validateUrl = (url) => {
|
|
31747
31977
|
try {
|
|
@@ -31776,7 +32006,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31776
32006
|
if (params?.provider && params.user) {
|
|
31777
32007
|
const userId2 = params.user.user_id;
|
|
31778
32008
|
const userRole = params.user.role?.toLowerCase();
|
|
31779
|
-
const isAdmin3 =
|
|
32009
|
+
const isAdmin3 = hasMinimumRole13(userRole, ROLES18.ADMIN);
|
|
31780
32010
|
const isOwner = server.owner_user_id === userId2;
|
|
31781
32011
|
if (server.scope === "global" && !isOwner && !isAdmin3)
|
|
31782
32012
|
return {
|
|
@@ -31805,7 +32035,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31805
32035
|
if (params?.provider && params.user) {
|
|
31806
32036
|
const userId2 = params.user.user_id;
|
|
31807
32037
|
const userRole = params.user.role?.toLowerCase();
|
|
31808
|
-
const isAdmin3 =
|
|
32038
|
+
const isAdmin3 = hasMinimumRole13(userRole, ROLES18.ADMIN);
|
|
31809
32039
|
const isOwner = server.owner_user_id === userId2;
|
|
31810
32040
|
if (server.scope === "global" && !isOwner && !isAdmin3)
|
|
31811
32041
|
return {
|
|
@@ -31898,6 +32128,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
31898
32128
|
// call). Without a serverId nothing is persisted to the DB; the
|
|
31899
32129
|
// daemon-level cache below carries the token for this request.
|
|
31900
32130
|
oauthMode: "shared",
|
|
32131
|
+
tenantId: tenantIdFromParams(params),
|
|
31901
32132
|
socketId: connection?.id
|
|
31902
32133
|
});
|
|
31903
32134
|
const tokenResponse = await started.awaitToken();
|
|
@@ -32072,7 +32303,7 @@ async function registerMCPServices(ctx, sessionsService) {
|
|
|
32072
32303
|
return { oauthCallbackHandler };
|
|
32073
32304
|
}
|
|
32074
32305
|
async function bootstrapSuperadminUsers(config, usersService, allowSuperadmin) {
|
|
32075
|
-
const { ROLES:
|
|
32306
|
+
const { ROLES: ROLES18 } = await import("@agor/core/types");
|
|
32076
32307
|
const bootstrapUsers = config.execution?.bootstrap_superadmin_users ?? [];
|
|
32077
32308
|
if (bootstrapUsers.length === 0) return;
|
|
32078
32309
|
if (!allowSuperadmin) {
|
|
@@ -32087,15 +32318,15 @@ async function bootstrapSuperadminUsers(config, usersService, allowSuperadmin) {
|
|
|
32087
32318
|
if (!userId) continue;
|
|
32088
32319
|
try {
|
|
32089
32320
|
const user = await usersService.get(userId);
|
|
32090
|
-
if (user.role ===
|
|
32091
|
-
await usersService.patch(userId, { role:
|
|
32321
|
+
if (user.role === ROLES18.SUPERADMIN) continue;
|
|
32322
|
+
await usersService.patch(userId, { role: ROLES18.SUPERADMIN });
|
|
32092
32323
|
promotedCount++;
|
|
32093
32324
|
console.log(
|
|
32094
|
-
`[RBAC] Bootstrap promoted user ${
|
|
32325
|
+
`[RBAC] Bootstrap promoted user ${shortId22(userId)} (${user.email}) to superadmin`
|
|
32095
32326
|
);
|
|
32096
32327
|
} catch (error) {
|
|
32097
32328
|
console.warn(
|
|
32098
|
-
`[RBAC] Failed to bootstrap superadmin for user ${
|
|
32329
|
+
`[RBAC] Failed to bootstrap superadmin for user ${shortId22(userId)}: ${error instanceof Error ? error.message : String(error)}`
|
|
32099
32330
|
);
|
|
32100
32331
|
}
|
|
32101
32332
|
}
|