@bevel-software/platform-core-backend 0.35.0 → 0.36.1
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/agent-guide/directory-structure.md +1 -1
- package/agent-guide/onboarding.md +111 -0
- package/agent-guide/start-here.md +1 -0
- package/agent-guide/tool-manuals.md +1 -0
- package/dist/core/catalog-cache-invalidation.d.ts +2 -2
- package/dist/core/catalog-cache-invalidation.d.ts.map +1 -1
- package/dist/core/compose-embed.d.ts +2 -2
- package/dist/core/compose-embed.d.ts.map +1 -1
- package/dist/core/compose-embed.js +1 -1
- package/dist/core/compose-embed.js.map +1 -1
- package/dist/core/core-ports.d.ts +19 -4
- package/dist/core/core-ports.d.ts.map +1 -1
- package/dist/core/core-ports.js.map +1 -1
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +26 -24
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +19 -13
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +68 -56
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core/lifecycle.d.ts +4 -4
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/core/lifecycle.js +5 -5
- package/dist/core/lifecycle.js.map +1 -1
- package/dist/core-config.d.ts +2 -2
- package/dist/core-config.js +3 -3
- package/dist/core-config.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/modules/access/access-control.service.js +1 -1
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access-declarations.d.ts +2 -2
- package/dist/modules/access/access-declarations.d.ts.map +1 -1
- package/dist/modules/access/access-declarations.js +2 -2
- package/dist/modules/access/access-declarations.js.map +1 -1
- package/dist/modules/access/access-mutation.service.d.ts +2 -2
- package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
- package/dist/modules/access/access-mutation.service.js +2 -2
- package/dist/modules/access/access-mutation.service.js.map +1 -1
- package/dist/modules/access/access-requests.routes.d.ts +2 -2
- package/dist/modules/access/access-requests.routes.d.ts.map +1 -1
- package/dist/modules/access/access-requests.routes.js +5 -5
- package/dist/modules/access/access-requests.routes.js.map +1 -1
- package/dist/modules/access/access-requests.service.d.ts +2 -2
- package/dist/modules/access/access-requests.service.d.ts.map +1 -1
- package/dist/modules/access/access-requests.service.js +11 -11
- package/dist/modules/access/access-requests.service.js.map +1 -1
- package/dist/modules/access/access.routes.d.ts +2 -2
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +9 -9
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access/admin-locked-commit.d.ts +5 -5
- package/dist/modules/access/admin-locked-commit.d.ts.map +1 -1
- package/dist/modules/access/admin-locked-commit.js +7 -7
- package/dist/modules/access/admin-locked-commit.js.map +1 -1
- package/dist/modules/access/admin-route-helpers.d.ts +1 -1
- package/dist/modules/access/admin-route-helpers.js +5 -5
- package/dist/modules/access/admin-route-helpers.js.map +1 -1
- package/dist/modules/access/change-read-gate.d.ts +1 -1
- package/dist/modules/access/change-read-gate.js +1 -1
- package/dist/modules/access/groups-admin.service.d.ts +7 -7
- package/dist/modules/access/groups-admin.service.d.ts.map +1 -1
- package/dist/modules/access/groups-admin.service.js +6 -6
- package/dist/modules/access/groups-admin.service.js.map +1 -1
- package/dist/modules/access/reference-scan.d.ts +1 -1
- package/dist/modules/access/roles-admin.service.d.ts +7 -7
- package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
- package/dist/modules/access/roles-admin.service.js +8 -8
- package/dist/modules/access/roles-admin.service.js.map +1 -1
- package/dist/modules/access/synced-groups-committer.d.ts +4 -4
- package/dist/modules/access/synced-groups-committer.d.ts.map +1 -1
- package/dist/modules/access/synced-groups-committer.js +7 -7
- package/dist/modules/access/synced-groups-committer.js.map +1 -1
- package/dist/modules/access/user-access-removal.service.d.ts +6 -6
- package/dist/modules/access/user-access-removal.service.d.ts.map +1 -1
- package/dist/modules/access/user-access-removal.service.js +4 -4
- package/dist/modules/access/user-access-removal.service.js.map +1 -1
- package/dist/modules/access-model/access-errors.d.ts +4 -4
- package/dist/modules/access-model/access-errors.d.ts.map +1 -1
- package/dist/modules/access-model/access-errors.js +4 -4
- package/dist/modules/access-model/access-errors.js.map +1 -1
- package/dist/modules/access-model/access-grammar.d.ts +1 -1
- package/dist/modules/access-model/access-grammar.js +4 -4
- package/dist/modules/access-model/change-gate.d.ts +1 -1
- package/dist/modules/access-model/change-gate.js +1 -1
- package/dist/modules/access-model/roles-yaml-guard.d.ts +4 -4
- package/dist/modules/access-model/roles-yaml-guard.d.ts.map +1 -1
- package/dist/modules/access-model/roles-yaml-guard.js +4 -4
- package/dist/modules/access-model/roles-yaml-guard.js.map +1 -1
- package/dist/modules/agent-guide/agent-guide.d.ts +19 -14
- package/dist/modules/agent-guide/agent-guide.d.ts.map +1 -1
- package/dist/modules/agent-guide/agent-guide.js +42 -18
- package/dist/modules/agent-guide/agent-guide.js.map +1 -1
- package/dist/modules/agent-guide/guide-budget.d.ts +5 -2
- package/dist/modules/agent-guide/guide-budget.d.ts.map +1 -1
- package/dist/modules/agent-guide/guide-budget.js +6 -2
- package/dist/modules/agent-guide/guide-budget.js.map +1 -1
- package/dist/modules/agent-instructions/agent-instructions.routes.d.ts +12 -5
- package/dist/modules/agent-instructions/agent-instructions.routes.d.ts.map +1 -1
- package/dist/modules/agent-instructions/agent-instructions.routes.js +13 -6
- package/dist/modules/agent-instructions/agent-instructions.routes.js.map +1 -1
- package/dist/modules/agent-instructions/compose.d.ts +15 -8
- package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
- package/dist/modules/agent-instructions/compose.js +24 -10
- package/dist/modules/agent-instructions/compose.js.map +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.d.ts +14 -6
- package/dist/modules/agent-instructions/shared-file-rules.d.ts.map +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.js +51 -11
- package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
- package/dist/modules/auth/account-erasure.service.d.ts +36 -7
- package/dist/modules/auth/account-erasure.service.d.ts.map +1 -1
- package/dist/modules/auth/account-erasure.service.js +30 -10
- package/dist/modules/auth/account-erasure.service.js.map +1 -1
- package/dist/modules/auth/account-hooks.d.ts +20 -0
- package/dist/modules/auth/account-hooks.d.ts.map +1 -1
- package/dist/modules/auth/account-hooks.js +10 -0
- package/dist/modules/auth/account-hooks.js.map +1 -1
- package/dist/modules/auth/account-switch-lock.js +2 -2
- package/dist/modules/auth/account-switch-lock.js.map +1 -1
- package/dist/modules/auth/account.routes.d.ts +7 -2
- package/dist/modules/auth/account.routes.d.ts.map +1 -1
- package/dist/modules/auth/account.routes.js +23 -4
- package/dist/modules/auth/account.routes.js.map +1 -1
- package/dist/modules/auth/auth.service.d.ts +1 -1
- package/dist/modules/auth/auth.service.js +4 -4
- package/dist/modules/auth/auth.service.js.map +1 -1
- package/dist/modules/auth/index.d.ts +1 -0
- package/dist/modules/auth/index.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +2 -2
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/diff/diff.routes.d.ts +3 -3
- package/dist/modules/diff/diff.routes.d.ts.map +1 -1
- package/dist/modules/diff/diff.routes.js +7 -7
- package/dist/modules/diff/diff.routes.js.map +1 -1
- package/dist/modules/embed/embed.routes.js +1 -1
- package/dist/modules/embed/embed.routes.js.map +1 -1
- package/dist/modules/embed/embed.service.d.ts +4 -4
- package/dist/modules/embed/embed.service.d.ts.map +1 -1
- package/dist/modules/embed/embed.service.js +18 -18
- package/dist/modules/embed/embed.service.js.map +1 -1
- package/dist/modules/kb-fs/branch-name.js +8 -8
- package/dist/modules/kb-fs/branch-name.js.map +1 -1
- package/dist/modules/kb-fs/file-change-notifier.d.ts +2 -2
- package/dist/modules/kb-fs/locking-filesystem.d.ts +9 -9
- package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.js +27 -27
- package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
- package/dist/modules/kb-fs/repo-path.js +5 -5
- package/dist/modules/kb-fs/repo-path.js.map +1 -1
- package/dist/modules/kb-fs/tmp-ref.d.ts +2 -2
- package/dist/modules/kb-fs/tmp-ref.d.ts.map +1 -1
- package/dist/modules/kb-fs/tmp-ref.js +2 -2
- package/dist/modules/kb-fs/tmp-ref.js.map +1 -1
- package/dist/modules/kb-sync/index.d.ts +1 -1
- package/dist/modules/kb-sync/index.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.interface.d.ts +3 -3
- package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.service.d.ts +3 -3
- package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.service.js +10 -10
- package/dist/modules/kb-sync/kb-sync.service.js.map +1 -1
- package/dist/modules/mcp/mcp.service.d.ts +11 -4
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.service.js +75 -19
- package/dist/modules/mcp/mcp.service.js.map +1 -1
- package/dist/modules/onboarding/onboarding.contract.d.ts +1 -1
- package/dist/modules/onboarding/onboarding.routes.js +2 -2
- package/dist/modules/onboarding/onboarding.routes.js.map +1 -1
- package/dist/modules/onboarding/starter-pack.service.d.ts +4 -4
- package/dist/modules/onboarding/starter-pack.service.d.ts.map +1 -1
- package/dist/modules/onboarding/starter-pack.service.js +4 -4
- package/dist/modules/onboarding/starter-pack.service.js.map +1 -1
- package/dist/modules/plugins/join-request-jobs.service.d.ts +2 -2
- package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
- package/dist/modules/plugins/join-request-jobs.service.js +7 -7
- package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
- package/dist/modules/plugins/join-requests.service.d.ts +3 -3
- package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
- package/dist/modules/plugins/join-requests.service.js +5 -5
- package/dist/modules/plugins/join-requests.service.js.map +1 -1
- package/dist/modules/plugins/plugin-rename.service.js +1 -1
- package/dist/modules/plugins/plugin-rename.service.js.map +1 -1
- package/dist/modules/plugins/plugins.routes.d.ts +2 -2
- package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.js +8 -8
- package/dist/modules/plugins/plugins.routes.js.map +1 -1
- package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +77 -2
- package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -1
- package/dist/modules/secrets-vault/db-secrets-vault.service.js +479 -53
- package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -1
- package/dist/modules/secrets-vault/index.d.ts +2 -1
- package/dist/modules/secrets-vault/index.d.ts.map +1 -1
- package/dist/modules/secrets-vault/index.js +1 -0
- package/dist/modules/secrets-vault/index.js.map +1 -1
- package/dist/modules/secrets-vault/managed-sign-in-erasure.d.ts +36 -0
- package/dist/modules/secrets-vault/managed-sign-in-erasure.d.ts.map +1 -0
- package/dist/modules/secrets-vault/managed-sign-in-erasure.js +37 -0
- package/dist/modules/secrets-vault/managed-sign-in-erasure.js.map +1 -0
- package/dist/modules/secrets-vault/secrets-vault.contract.d.ts +152 -0
- package/dist/modules/secrets-vault/secrets-vault.contract.d.ts.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.contract.js.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +7 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.js +125 -10
- package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
- package/dist/modules/settings/connection-check.js +1 -1
- package/dist/modules/settings/connection-check.js.map +1 -1
- package/dist/modules/settings/deployment-settings.service.js +1 -1
- package/dist/modules/settings/git-root-folders.js +1 -1
- package/dist/modules/settings/git-root-folders.js.map +1 -1
- package/dist/modules/settings/setup.routes.d.ts +1 -1
- package/dist/modules/settings/setup.routes.js +1 -1
- package/dist/modules/skills/pending-skills.service.d.ts +3 -3
- package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
- package/dist/modules/skills/pending-skills.service.js +4 -4
- package/dist/modules/skills/pending-skills.service.js.map +1 -1
- package/dist/modules/skills/skill-access-requests.routes.d.ts +2 -2
- package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
- package/dist/modules/skills/skill-access-requests.routes.js +5 -5
- package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
- package/dist/modules/tool-helpers/tool-context.d.ts +4 -4
- package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-context.js +2 -2
- package/dist/modules/tool-helpers/tool-context.js.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.js +2 -2
- package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.d.ts +4 -4
- package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
- package/dist/modules/tool-manuals/mcp-server-edit.service.js +1 -1
- package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
- package/dist/modules/tool-manuals/pending-tools.service.d.ts +3 -3
- package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/pending-tools.service.js +4 -4
- package/dist/modules/tool-manuals/pending-tools.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-delete.service.js +1 -1
- package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +43 -3
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts +6 -0
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.js +51 -5
- package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +3 -0
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.js +36 -15
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
- package/dist/modules/version-control/agent-tools/change-request-read-shape.d.ts.map +1 -0
- package/dist/modules/version-control/agent-tools/change-request-read-shape.js.map +1 -0
- package/dist/modules/version-control/agent-tools/change-request-read.tools.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/agent-tools/change-request-read.tools.js +2 -2
- package/dist/modules/version-control/agent-tools/change-request-read.tools.js.map +1 -0
- package/dist/modules/version-control/agent-tools/change-request-summary.d.ts.map +1 -0
- package/dist/modules/version-control/agent-tools/change-request-summary.js.map +1 -0
- package/dist/modules/{workflow/agent-tools/workflow.tools.d.ts → version-control/agent-tools/version-control.tools.d.ts} +4 -4
- package/dist/modules/version-control/agent-tools/version-control.tools.d.ts.map +1 -0
- package/dist/modules/{workflow/agent-tools/workflow.tools.js → version-control/agent-tools/version-control.tools.js} +31 -31
- package/dist/modules/version-control/agent-tools/version-control.tools.js.map +1 -0
- package/dist/modules/{workflow → version-control}/change-request-hooks.d.ts +1 -1
- package/dist/modules/version-control/change-request-hooks.d.ts.map +1 -0
- package/dist/modules/version-control/change-request-hooks.js.map +1 -0
- package/dist/modules/version-control/change-request-review/approval-lock.d.ts.map +1 -0
- package/dist/modules/version-control/change-request-review/approval-lock.js.map +1 -0
- package/dist/modules/{workflow/review-workflow/review-workflow.interface.d.ts → version-control/change-request-review/change-request-review.interface.d.ts} +2 -2
- package/dist/modules/version-control/change-request-review/change-request-review.interface.d.ts.map +1 -0
- package/dist/modules/version-control/change-request-review/change-request-review.interface.js +2 -0
- package/dist/modules/version-control/change-request-review/change-request-review.interface.js.map +1 -0
- package/dist/modules/{workflow/review-workflow/review-workflow.service.d.ts → version-control/change-request-review/change-request-review.service.d.ts} +3 -3
- package/dist/modules/version-control/change-request-review/change-request-review.service.d.ts.map +1 -0
- package/dist/modules/{workflow/review-workflow/review-workflow.service.js → version-control/change-request-review/change-request-review.service.js} +26 -26
- package/dist/modules/version-control/change-request-review/change-request-review.service.js.map +1 -0
- package/dist/modules/{workflow → version-control}/event-bus.d.ts +8 -8
- package/dist/modules/version-control/event-bus.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/event-bus.js +4 -4
- package/dist/modules/version-control/event-bus.js.map +1 -0
- package/dist/modules/{workflow → version-control}/events-delivery.d.ts +4 -4
- package/dist/modules/version-control/events-delivery.d.ts.map +1 -0
- package/dist/modules/version-control/events-delivery.js.map +1 -0
- package/dist/modules/{workflow → version-control}/events.routes.d.ts +4 -4
- package/dist/modules/version-control/events.routes.d.ts.map +1 -0
- package/dist/modules/version-control/events.routes.js.map +1 -0
- package/dist/modules/{workflow → version-control}/file-lock.service.d.ts +2 -2
- package/dist/modules/version-control/file-lock.service.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/file-lock.service.js +6 -6
- package/dist/modules/version-control/file-lock.service.js.map +1 -0
- package/dist/modules/version-control/git/change-request-link.d.ts.map +1 -0
- package/dist/modules/version-control/git/change-request-link.js.map +1 -0
- package/dist/modules/version-control/git/git-version.d.ts.map +1 -0
- package/dist/modules/version-control/git/git-version.js.map +1 -0
- package/dist/modules/{workflow → version-control}/git/git.service.d.ts +8 -8
- package/dist/modules/version-control/git/git.service.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/git/git.service.js +53 -53
- package/dist/modules/version-control/git/git.service.js.map +1 -0
- package/dist/modules/version-control/git/merge-commit.d.ts.map +1 -0
- package/dist/modules/version-control/git/merge-commit.js.map +1 -0
- package/dist/modules/version-control/git/node-git-runner.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/git/node-git-runner.js +1 -1
- package/dist/modules/version-control/git/node-git-runner.js.map +1 -0
- package/dist/modules/{workflow → version-control}/git/pull-request.service.d.ts +5 -5
- package/dist/modules/version-control/git/pull-request.service.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/git/pull-request.service.js +10 -10
- package/dist/modules/version-control/git/pull-request.service.js.map +1 -0
- package/dist/modules/{workflow → version-control}/index.d.ts +6 -5
- package/dist/modules/version-control/index.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/index.js +3 -2
- package/dist/modules/version-control/index.js.map +1 -0
- package/dist/modules/{workflow → version-control}/pending-commits.service.d.ts +2 -2
- package/dist/modules/version-control/pending-commits.service.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/pending-commits.service.js +2 -2
- package/dist/modules/version-control/pending-commits.service.js.map +1 -0
- package/dist/modules/{workflow → version-control}/pending-commits.worker.d.ts +5 -5
- package/dist/modules/version-control/pending-commits.worker.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/pending-commits.worker.js +3 -3
- package/dist/modules/version-control/pending-commits.worker.js.map +1 -0
- package/dist/modules/{workflow → version-control}/read-on-branch.d.ts +2 -2
- package/dist/modules/version-control/read-on-branch.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/read-on-branch.js +2 -2
- package/dist/modules/version-control/read-on-branch.js.map +1 -0
- package/dist/modules/version-control/recovery-bot.d.ts.map +1 -0
- package/dist/modules/version-control/recovery-bot.js.map +1 -0
- package/dist/modules/version-control/sanitize-error.d.ts.map +1 -0
- package/dist/modules/version-control/sanitize-error.js.map +1 -0
- package/dist/modules/{workflow/workflow-hooks.d.ts → version-control/version-control-hooks.d.ts} +4 -4
- package/dist/modules/version-control/version-control-hooks.d.ts.map +1 -0
- package/dist/modules/{workflow/workflow-hooks.js → version-control/version-control-hooks.js} +3 -3
- package/dist/modules/version-control/version-control-hooks.js.map +1 -0
- package/dist/modules/{workflow/workflow.routes.d.ts → version-control/version-control.routes.d.ts} +6 -5
- package/dist/modules/version-control/version-control.routes.d.ts.map +1 -0
- package/dist/modules/{workflow/workflow.routes.js → version-control/version-control.routes.js} +61 -60
- package/dist/modules/version-control/version-control.routes.js.map +1 -0
- package/dist/modules/{workflow/workflow.service.d.ts → version-control/version-control.service.d.ts} +26 -31
- package/dist/modules/version-control/version-control.service.d.ts.map +1 -0
- package/dist/modules/{workflow/workflow.service.js → version-control/version-control.service.js} +89 -94
- package/dist/modules/version-control/version-control.service.js.map +1 -0
- package/dist/modules/workspace/agent-access.gate.d.ts +5 -5
- package/dist/modules/workspace/agent-access.gate.d.ts.map +1 -1
- package/dist/modules/workspace/agent-access.gate.js +1 -1
- package/dist/modules/workspace/git-internals.middleware.d.ts +1 -1
- package/dist/modules/workspace/git-internals.middleware.js +2 -2
- package/dist/modules/workspace/kb-repository.js +1 -1
- package/dist/modules/workspace/kb-repository.js.map +1 -1
- package/dist/modules/workspace/startup/kb-git.d.ts +1 -1
- package/dist/modules/workspace/startup/kb-git.d.ts.map +1 -1
- package/dist/modules/workspace/startup/kb-git.js +1 -1
- package/dist/modules/workspace/startup/kb-git.js.map +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.d.ts +2 -2
- package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.js +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts +2 -2
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/template-files.step.js +2 -2
- package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/template-source.d.ts +17 -4
- package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/template-source.js +8 -5
- package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
- package/dist/modules/workspace/workspace-tmp.js +3 -3
- package/dist/modules/workspace/workspace-tmp.js.map +1 -1
- package/dist/modules/workspace/workspace.routes.d.ts +4 -4
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +22 -22
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +6 -6
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +11 -11
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.d.ts +2 -1
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +15 -10
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/shared/canonical-file-identity.d.ts +2 -2
- package/dist/shared/canonical-file-identity.js +5 -5
- package/dist/shared/canonical-file-identity.js.map +1 -1
- package/dist/shared/domain-errors.d.ts +39 -39
- package/dist/shared/domain-errors.d.ts.map +1 -1
- package/dist/shared/domain-errors.js +44 -44
- package/dist/shared/domain-errors.js.map +1 -1
- package/dist/shared/git.contract.d.ts +1 -1
- package/dist/shared/git.contract.js +1 -1
- package/dist/shared/http-errors.d.ts +3 -3
- package/dist/shared/http-errors.d.ts.map +1 -1
- package/dist/shared/http-errors.js +1 -1
- package/dist/shared/http-errors.js.map +1 -1
- package/dist/shared/pending-proposals.d.ts +3 -3
- package/dist/shared/pending-proposals.d.ts.map +1 -1
- package/dist/shared/pending-proposals.js +2 -2
- package/dist/shared/pending-proposals.js.map +1 -1
- package/dist/tenancy/static-tenant-source.js +1 -1
- package/dist/tenancy/static-tenant-source.js.map +1 -1
- package/migrations/0012_agent_audit.sql +40 -40
- package/migrations/0013_agent_identity_and_key_soft_delete.sql +29 -29
- package/migrations/meta/0012_snapshot.json +2246 -2246
- package/migrations/meta/0013_snapshot.json +2258 -2258
- package/package.json +4 -4
- package/src/__tests__/account-admin.ts +27 -0
- package/src/__tests__/hexis-catalog.ts +4 -4
- package/src/__tests__/kb-context.ts +30 -30
- package/src/__tests__/kb-layout-config.test.ts +21 -0
- package/src/__tests__/open-change-gate.ts +1 -1
- package/src/__tests__/tool-handler.ts +15 -0
- package/src/__tests__/tool-wiring.ts +10 -4
- package/src/__tests__/workspace-service.ts +1 -1
- package/src/core/__tests__/catalog-cache-invalidation.test.ts +3 -3
- package/src/core/__tests__/compose-embed.test.ts +1 -1
- package/src/core/__tests__/damaged-document.tools.test.ts +3 -3
- package/src/core/__tests__/erasure-slices-wired-once.test.ts +46 -0
- package/src/core/__tests__/gated-boot.test.ts +2 -2
- package/src/core/__tests__/lifecycle.test.ts +9 -9
- package/src/core/catalog-cache-invalidation.ts +2 -2
- package/src/core/compose-embed.ts +3 -3
- package/src/core/core-ports.ts +19 -4
- package/src/core/create-core-server.ts +39 -25
- package/src/core/create-core-services.ts +79 -63
- package/src/core/lifecycle.ts +9 -9
- package/src/core-config.ts +3 -3
- package/src/index.ts +5 -5
- package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +4 -4
- package/src/modules/access/__tests__/access-own-read-grant.test.ts +14 -14
- package/src/modules/access/__tests__/access-requests.routes.test.ts +20 -20
- package/src/modules/access/__tests__/access.routes.admins.test.ts +4 -4
- package/src/modules/access/__tests__/access.routes.batch.test.ts +4 -4
- package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +6 -6
- package/src/modules/access/__tests__/access.routes.group-grant.test.ts +6 -6
- package/src/modules/access/__tests__/access.routes.overrides.test.ts +5 -5
- package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +6 -6
- package/src/modules/access/__tests__/access.routes.prospective.test.ts +3 -3
- package/src/modules/access/__tests__/access.routes.revoke.test.ts +6 -6
- package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +6 -6
- package/src/modules/access/__tests__/admin-locked-commit.test.ts +6 -6
- package/src/modules/access/__tests__/admin-route-helpers.test.ts +5 -5
- package/src/modules/access/__tests__/groups-admin.service.test.ts +27 -27
- package/src/modules/access/__tests__/roles-admin.security.test.ts +14 -13
- package/src/modules/access/__tests__/roles-admin.service.test.ts +27 -27
- package/src/modules/access/__tests__/roles-capabilities.test.ts +19 -19
- package/src/modules/access/__tests__/roles.routes.test.ts +6 -6
- package/src/modules/access/__tests__/synced-groups-committer.test.ts +13 -13
- package/src/modules/access/__tests__/user-access-removal.service.test.ts +29 -29
- package/src/modules/access/access-control.service.ts +1 -1
- package/src/modules/access/access-declarations.ts +2 -2
- package/src/modules/access/access-mutation.service.ts +2 -2
- package/src/modules/access/access-requests.routes.ts +7 -7
- package/src/modules/access/access-requests.service.ts +13 -13
- package/src/modules/access/access.routes.ts +11 -11
- package/src/modules/access/admin-locked-commit.ts +11 -11
- package/src/modules/access/admin-route-helpers.ts +5 -5
- package/src/modules/access/change-read-gate.ts +1 -1
- package/src/modules/access/groups-admin.service.ts +7 -7
- package/src/modules/access/reference-scan.ts +1 -1
- package/src/modules/access/roles-admin.service.ts +9 -9
- package/src/modules/access/synced-groups-committer.ts +11 -11
- package/src/modules/access/user-access-removal.service.ts +7 -7
- package/src/modules/access-model/__tests__/access-grammar.test.ts +2 -2
- package/src/modules/access-model/access-errors.ts +4 -4
- package/src/modules/access-model/access-grammar.ts +4 -4
- package/src/modules/access-model/change-gate.ts +1 -1
- package/src/modules/access-model/roles-yaml-guard.ts +4 -4
- package/src/modules/agent-guide/__tests__/agent-guide.test.ts +19 -4
- package/src/modules/agent-guide/__tests__/agent-guide.tools.test.ts +1 -1
- package/src/modules/agent-guide/__tests__/guide-matches-code.test.ts +2 -2
- package/src/modules/agent-guide/agent-guide.ts +48 -22
- package/src/modules/agent-guide/guide-budget.ts +6 -2
- package/src/modules/agent-instructions/__tests__/agent-instructions.route.test.ts +4 -5
- package/src/modules/agent-instructions/__tests__/compose.test.ts +1 -1
- package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +113 -7
- package/src/modules/agent-instructions/agent-instructions.routes.ts +12 -5
- package/src/modules/agent-instructions/compose.ts +24 -9
- package/src/modules/agent-instructions/shared-file-rules.ts +53 -11
- package/src/modules/agent-scope/__tests__/agent-surfaces.connect-as.test.ts +1 -1
- package/src/modules/audit/__tests__/agent-rest-audit.middleware.test.ts +113 -113
- package/src/modules/audit/__tests__/event-classifier.test.ts +121 -121
- package/src/modules/audit/event-classifier.ts +155 -155
- package/src/modules/auth/__tests__/account-deactivation.test.ts +1 -1
- package/src/modules/auth/__tests__/account-erasure.approval-gate.test.ts +4 -4
- package/src/modules/auth/__tests__/account-erasure.participants.test.ts +56 -0
- package/src/modules/auth/__tests__/account-switch-lock.pg.test.ts +2 -2
- package/src/modules/auth/__tests__/account-switch-lock.test.ts +2 -2
- package/src/modules/auth/__tests__/account.routes.test.ts +73 -11
- package/src/modules/auth/__tests__/auth.service.test.ts +1 -1
- package/src/modules/auth/account-erasure.service.ts +27 -9
- package/src/modules/auth/account-hooks.ts +34 -0
- package/src/modules/auth/account-switch-lock.ts +2 -2
- package/src/modules/auth/account.routes.ts +23 -5
- package/src/modules/auth/auth.service.ts +4 -4
- package/src/modules/auth/index.ts +1 -0
- package/src/modules/database/__tests__/advisory-lock.test.ts +169 -169
- package/src/modules/database/__tests__/migrations-unqualified.test.ts +32 -32
- package/src/modules/database/core-schema.ts +2 -2
- package/src/modules/diff/__tests__/diff.routes.read-gate.test.ts +2 -2
- package/src/modules/diff/__tests__/diff.routes.rejectPathsLocked.test.ts +12 -12
- package/src/modules/diff/diff.routes.ts +8 -8
- package/src/modules/embed/__tests__/embed.service.lock.test.ts +7 -7
- package/src/modules/embed/__tests__/embed.service.test.ts +42 -42
- package/src/modules/embed/__tests__/embed.tools.test.ts +1 -1
- package/src/modules/embed/embed.routes.ts +1 -1
- package/src/modules/embed/embed.service.ts +17 -17
- package/src/modules/kb-fs/__tests__/branch-name.test.ts +2 -2
- package/src/modules/kb-fs/__tests__/locking-filesystem.test.ts +260 -260
- package/src/modules/kb-fs/__tests__/move-with-edits.test.ts +34 -34
- package/src/modules/kb-fs/__tests__/repo-path.test.ts +8 -8
- package/src/modules/kb-fs/branch-name.ts +8 -8
- package/src/modules/kb-fs/file-change-notifier.ts +2 -2
- package/src/modules/kb-fs/locking-filesystem.ts +30 -30
- package/src/modules/kb-fs/repo-path.ts +5 -5
- package/src/modules/kb-fs/tmp-ref.ts +3 -3
- package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +36 -36
- package/src/modules/kb-sync/index.ts +1 -1
- package/src/modules/kb-sync/kb-sync.interface.ts +3 -3
- package/src/modules/kb-sync/kb-sync.service.ts +9 -9
- package/src/modules/marketplace/__tests__/github-facade.test.ts +1 -1
- package/src/modules/marketplace/__tests__/marketplace-git.test.ts +1 -1
- package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +4 -2
- package/src/modules/mcp/__tests__/mcp.e2e.test.ts +69 -8
- package/src/modules/mcp/__tests__/mcp.service.test.ts +91 -13
- package/src/modules/mcp/__tests__/read-only-hint.pg.test.ts +194 -0
- package/src/modules/mcp/mcp.service.ts +89 -28
- package/src/modules/onboarding/__tests__/starter-pack.service.test.ts +55 -55
- package/src/modules/onboarding/onboarding.contract.ts +1 -1
- package/src/modules/onboarding/onboarding.routes.ts +2 -2
- package/src/modules/onboarding/starter-pack.service.ts +6 -6
- package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +1 -1
- package/src/modules/plugins/__tests__/compile-marketplace.test.ts +1 -1
- package/src/modules/plugins/__tests__/join-request-jobs.service.test.ts +43 -43
- package/src/modules/plugins/__tests__/join-requests.service.test.ts +19 -19
- package/src/modules/plugins/__tests__/join-requests.settlement.test.ts +26 -26
- package/src/modules/plugins/__tests__/plugins.routes.test.ts +25 -25
- package/src/modules/plugins/join-request-jobs.service.ts +10 -10
- package/src/modules/plugins/join-requests.service.ts +4 -4
- package/src/modules/plugins/plugin-rename.service.ts +1 -1
- package/src/modules/plugins/plugins.routes.ts +9 -9
- package/src/modules/secrets-vault/__tests__/db-secrets-vault.managed.test.ts +773 -0
- package/src/modules/secrets-vault/__tests__/db-secrets-vault.oauth.test.ts +28 -1
- package/src/modules/secrets-vault/__tests__/managed-sign-in.route.test.ts +351 -0
- package/src/modules/secrets-vault/db-secrets-vault.service.ts +562 -95
- package/src/modules/secrets-vault/index.ts +7 -0
- package/src/modules/secrets-vault/managed-sign-in-erasure.ts +41 -0
- package/src/modules/secrets-vault/secrets-variable-loader.ts +134 -134
- package/src/modules/secrets-vault/secrets-vault.contract.ts +152 -0
- package/src/modules/secrets-vault/secrets-vault.routes.ts +157 -10
- package/src/modules/settings/__tests__/repository-source.test.ts +1 -1
- package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +1 -1
- package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +1 -1
- package/src/modules/settings/connection-check.ts +1 -1
- package/src/modules/settings/deployment-settings.service.ts +1 -1
- package/src/modules/settings/git-root-folders.ts +1 -1
- package/src/modules/settings/setup.routes.ts +1 -1
- package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +3 -3
- package/src/modules/skills/__tests__/branch-skills.tools.test.ts +1 -1
- package/src/modules/skills/__tests__/pending-skills.service.test.ts +8 -8
- package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +18 -18
- package/src/modules/skills/__tests__/skills.service.test.ts +3 -3
- package/src/modules/skills/pending-skills.service.ts +3 -3
- package/src/modules/skills/skill-access-requests.routes.ts +7 -7
- package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +4 -4
- package/src/modules/tool-helpers/__tests__/branch-declaration.test.ts +3 -3
- package/src/modules/tool-helpers/__tests__/can-write.tools.test.ts +3 -3
- package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +4 -4
- package/src/modules/tool-helpers/__tests__/tools-surface.test.ts +3 -3
- package/src/modules/tool-helpers/__tests__/validate-token.test.ts +1 -1
- package/src/modules/tool-helpers/tool-context.ts +6 -6
- package/src/modules/tool-helpers/tool-handler.ts +2 -2
- package/src/modules/tool-helpers/tool.contract.ts +4 -4
- package/src/modules/tool-manuals/__tests__/pending-tools.service.test.ts +9 -9
- package/src/modules/tool-manuals/__tests__/tool-manuals.managed-sign-in.test.ts +89 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.restart.test.ts +1 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +36 -1
- package/src/modules/tool-manuals/mcp-server-edit.service.ts +1 -1
- package/src/modules/tool-manuals/pending-tools.service.ts +3 -3
- package/src/modules/tool-manuals/tool-delete.service.ts +1 -1
- package/src/modules/tool-manuals/tool-manuals.contract.ts +41 -3
- package/src/modules/tool-manuals/tool-manuals.service.ts +53 -5
- package/src/modules/tool-manuals/tool-manuals.tools.ts +41 -15
- package/src/modules/tool-registry/__tests__/own-tool-schemas.test.ts +4 -4
- package/src/modules/tool-registry/__tests__/read-only-hints.test.ts +3 -3
- package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +6 -6
- package/src/modules/{workflow → version-control}/__tests__/apply-failure.test.ts +54 -54
- package/src/modules/{workflow → version-control}/__tests__/event-bus.test.ts +27 -27
- package/src/modules/{workflow → version-control}/__tests__/events-delivery.test.ts +37 -37
- package/src/modules/{workflow → version-control}/__tests__/file-lock.service.deletion-gate.test.ts +2 -2
- package/src/modules/{workflow → version-control}/__tests__/file-lock.service.path-identity.test.ts +8 -8
- package/src/modules/{workflow → version-control}/__tests__/merge-announces-tree.test.ts +11 -11
- package/src/modules/{workflow → version-control}/__tests__/pending-commits.worker.concurrency.test.ts +9 -9
- package/src/modules/{workflow → version-control}/__tests__/pending-commits.worker.test.ts +25 -25
- package/src/modules/{workflow → version-control}/__tests__/preserve-roles-yaml.test.ts +42 -42
- package/src/modules/version-control/__tests__/public-surface.test.ts +114 -0
- package/src/modules/{workflow/__tests__/workflow.routes.folder-proposals.test.ts → version-control/__tests__/version-control.routes.folder-proposals.test.ts} +18 -18
- package/src/modules/{workflow/__tests__/workflow.routes.fork-point-file.test.ts → version-control/__tests__/version-control.routes.fork-point-file.test.ts} +19 -19
- package/src/modules/{workflow/__tests__/workflow.routes.history-read-gate.test.ts → version-control/__tests__/version-control.routes.history-read-gate.test.ts} +13 -13
- package/src/modules/{workflow/__tests__/workflow.routes.lock-path.test.ts → version-control/__tests__/version-control.routes.lock-path.test.ts} +18 -18
- package/src/modules/{workflow/__tests__/workflow.routes.open-change-request.test.ts → version-control/__tests__/version-control.routes.open-change-request.test.ts} +7 -7
- package/src/modules/{workflow/__tests__/workflow.routes.push-refused.test.ts → version-control/__tests__/version-control.routes.push-refused.test.ts} +14 -14
- package/src/modules/{workflow/__tests__/workflow.service.branch-in-use.test.ts → version-control/__tests__/version-control.service.branch-in-use.test.ts} +6 -6
- package/src/modules/{workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts → version-control/__tests__/version-control.service.commitFileWhileLocked.test.ts} +14 -14
- package/src/modules/{workflow/__tests__/workflow.service.delete-branch.test.ts → version-control/__tests__/version-control.service.delete-branch.test.ts} +14 -14
- package/src/modules/{workflow/__tests__/workflow.service.deleted-branch-sweep.test.ts → version-control/__tests__/version-control.service.deleted-branch-sweep.test.ts} +4 -4
- package/src/modules/{workflow/__tests__/workflow.service.facade.test.ts → version-control/__tests__/version-control.service.facade.test.ts} +97 -99
- package/src/modules/{workflow/__tests__/workflow.service.folder-proposals.test.ts → version-control/__tests__/version-control.service.folder-proposals.test.ts} +7 -7
- package/src/modules/{workflow/__tests__/workflow.service.platform-restore.test.ts → version-control/__tests__/version-control.service.platform-restore.test.ts} +6 -6
- package/src/modules/{workflow/__tests__/workflow.service.read-gate.test.ts → version-control/__tests__/version-control.service.read-gate.test.ts} +9 -9
- package/src/modules/{workflow/__tests__/workflow.service.releaseLock.test.ts → version-control/__tests__/version-control.service.releaseLock.test.ts} +42 -42
- package/src/modules/{workflow/__tests__/workflow.service.repository-replaced.test.ts → version-control/__tests__/version-control.service.repository-replaced.test.ts} +4 -4
- package/src/modules/{workflow/__tests__/workflow.service.sync.test.ts → version-control/__tests__/version-control.service.sync.test.ts} +17 -17
- package/src/modules/{workflow/__tests__/workflow.service.update-change-request.pg.test.ts → version-control/__tests__/version-control.service.update-change-request.pg.test.ts} +6 -6
- package/src/modules/{workflow/__tests__/workflow.service.update-change-request.test.ts → version-control/__tests__/version-control.service.update-change-request.test.ts} +11 -11
- package/src/modules/{workflow/__tests__/workflow.service.update-from-target.test.ts → version-control/__tests__/version-control.service.update-from-target.test.ts} +22 -22
- package/src/modules/{workflow → version-control}/agent-tools/__tests__/change-request-read.tools.test.ts +3 -3
- package/src/modules/{workflow → version-control}/agent-tools/__tests__/update-change-request.parity.test.ts +16 -16
- package/src/modules/{workflow/agent-tools/__tests__/workflow.tools.test.ts → version-control/agent-tools/__tests__/version-control.tools.test.ts} +9 -9
- package/src/modules/{workflow → version-control}/agent-tools/change-request-read.tools.ts +2 -2
- package/src/modules/{workflow/agent-tools/workflow.tools.ts → version-control/agent-tools/version-control.tools.ts} +30 -30
- package/src/modules/{workflow → version-control}/change-request-hooks.ts +1 -1
- package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/approval-states.test.ts +5 -5
- package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/cancel-pr.test.ts +8 -8
- package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/carry-approvals-forward.test.ts +6 -6
- package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/erase-approver.test.ts +5 -5
- package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/merge-gate.test.ts +3 -3
- package/src/modules/{workflow/review-workflow → version-control/change-request-review}/__tests__/merge-records-own-commit.test.ts +3 -3
- package/src/modules/{workflow/review-workflow/review-workflow.interface.ts → version-control/change-request-review/change-request-review.interface.ts} +1 -1
- package/src/modules/{workflow/review-workflow/review-workflow.service.ts → version-control/change-request-review/change-request-review.service.ts} +28 -28
- package/src/modules/{workflow → version-control}/event-bus.ts +14 -14
- package/src/modules/{workflow → version-control}/events-delivery.ts +11 -11
- package/src/modules/{workflow → version-control}/events.routes.ts +5 -5
- package/src/modules/{workflow → version-control}/file-lock.service.ts +6 -6
- package/src/modules/{workflow → version-control}/git/__tests__/git-test-helpers.ts +3 -3
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.accessGating.test.ts +5 -5
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.appliedChange.test.ts +4 -4
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.changedFilesForPr.test.ts +16 -16
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.changedPathsMemo.test.ts +2 -2
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.commitChanges.test.ts +3 -3
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.commitFile.strayPath.test.ts +10 -10
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.commitFile.test.ts +3 -3
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.createBranch.test.ts +3 -3
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.deleteBranch.test.ts +7 -7
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.diffFileAtCommit.test.ts +9 -9
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.diffFileBetweenBranches.test.ts +23 -23
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.fileBytesAtCommit.test.ts +7 -7
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.fileContentsAtCommit.test.ts +3 -3
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.forkPoint.test.ts +2 -2
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.history-guards.test.ts +2 -2
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.list-branches.test.ts +12 -12
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.listTrackedFiles.test.ts +2 -2
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.logForFile.test.ts +6 -6
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.mergeChangeRequest.test.ts +20 -20
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.mergeIntoBranch.test.ts +16 -16
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.pendingChanges.test.ts +2 -2
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.postMergePull.test.ts +5 -5
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.prFetchFailure.test.ts +2 -2
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.pull.test.ts +12 -12
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.readFileAtRef.test.ts +3 -3
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.revertPathsAndPush.test.ts +2 -2
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.status.test.ts +4 -4
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.syncFromRemote.test.ts +8 -8
- package/src/modules/{workflow → version-control}/git/__tests__/git.service.worktrees.test.ts +4 -4
- package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.list-fetch.test.ts +2 -2
- package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.test.ts +6 -6
- package/src/modules/{workflow → version-control}/git/git.service.ts +57 -57
- package/src/modules/{workflow → version-control}/git/node-git-runner.ts +1 -1
- package/src/modules/{workflow → version-control}/git/pull-request.service.ts +12 -12
- package/src/modules/{workflow → version-control}/index.ts +6 -5
- package/src/modules/{workflow → version-control}/pending-commits.service.ts +2 -2
- package/src/modules/{workflow → version-control}/pending-commits.worker.ts +8 -8
- package/src/modules/{workflow → version-control}/read-on-branch.ts +2 -2
- package/src/modules/{workflow/workflow-hooks.ts → version-control/version-control-hooks.ts} +3 -3
- package/src/modules/{workflow/workflow.routes.ts → version-control/version-control.routes.ts} +64 -63
- package/src/modules/{workflow/workflow.service.ts → version-control/version-control.service.ts} +92 -97
- package/src/modules/workspace/__tests__/agent-access.gate.test.ts +8 -8
- package/src/modules/workspace/__tests__/agent-downloads.test.ts +13 -16
- package/src/modules/workspace/__tests__/agent-uploads.test.ts +11 -12
- package/src/modules/workspace/__tests__/escape-sequences.routes.test.ts +11 -16
- package/src/modules/workspace/__tests__/file-stat-access.test.ts +3 -3
- package/src/modules/workspace/__tests__/git-internals.security.test.ts +27 -27
- package/src/modules/workspace/__tests__/kb-repository.test.ts +1 -1
- package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +3 -3
- package/src/modules/workspace/__tests__/start-session.default-branch.test.ts +152 -0
- package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +6 -6
- package/src/modules/workspace/__tests__/workspace-tmp.tools.test.ts +13 -14
- package/src/modules/workspace/__tests__/workspace.routes.at-ref.test.ts +6 -6
- package/src/modules/workspace/__tests__/workspace.routes.branch-errors.test.ts +4 -4
- package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +6 -6
- package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +8 -8
- package/src/modules/workspace/__tests__/workspace.routes.download-implies-read.test.ts +4 -4
- package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +6 -6
- package/src/modules/workspace/__tests__/workspace.routes.file-writes.test.ts +6 -6
- package/src/modules/workspace/__tests__/workspace.routes.folder-zip-access.test.ts +4 -4
- package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +6 -6
- package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +7 -7
- package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +13 -13
- package/src/modules/workspace/__tests__/workspace.service.any-workspace-credentials.test.ts +1 -1
- package/src/modules/workspace/__tests__/workspace.service.replaced-repository.test.ts +1 -1
- package/src/modules/workspace/__tests__/workspace.service.worktrees.test.ts +1 -1
- package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +5 -5
- package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +5 -5
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +27 -27
- package/src/modules/workspace/agent-access.gate.ts +5 -5
- package/src/modules/workspace/git-internals.middleware.ts +2 -2
- package/src/modules/workspace/kb-repository.ts +1 -1
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +1 -1
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +1 -1
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.worktrees.test.ts +1 -1
- package/src/modules/workspace/startup/kb-git.ts +1 -1
- package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +94 -70
- package/src/modules/workspace/startup/steps/seed-tree.ts +4 -5
- package/src/modules/workspace/startup/steps/template-files.step.ts +4 -5
- package/src/modules/workspace/startup/steps/template-source.ts +21 -6
- package/src/modules/workspace/workspace-tmp.ts +4 -4
- package/src/modules/workspace/workspace.routes.ts +26 -26
- package/src/modules/workspace/workspace.service.ts +11 -11
- package/src/modules/workspace/workspace.tools.ts +17 -10
- package/src/shared/__tests__/canonical-file-identity.test.ts +5 -5
- package/src/shared/__tests__/http-errors.test.ts +4 -4
- package/src/shared/canonical-file-identity.ts +5 -5
- package/src/shared/domain-errors.ts +44 -44
- package/src/shared/git.contract.ts +1 -1
- package/src/shared/http-errors.ts +3 -3
- package/src/shared/kb-context.ts +130 -130
- package/src/shared/pending-proposals.ts +4 -4
- package/src/tenancy/__tests__/tenant-host.test.ts +372 -372
- package/src/tenancy/__tests__/tenant-runtime.test.ts +221 -221
- package/src/tenancy/__tests__/tenant-secrets.test.ts +35 -35
- package/src/tenancy/index.ts +35 -35
- package/src/tenancy/static-tenant-source.ts +1 -1
- package/src/tenancy/tenant-host.ts +261 -261
- package/src/tenancy/tenant-runtime.ts +208 -208
- package/src/tenancy/tenant-source.contract.ts +59 -59
- package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts.map +0 -1
- package/dist/modules/workflow/agent-tools/change-request-read-shape.js.map +0 -1
- package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts.map +0 -1
- package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +0 -1
- package/dist/modules/workflow/agent-tools/change-request-summary.d.ts.map +0 -1
- package/dist/modules/workflow/agent-tools/change-request-summary.js.map +0 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +0 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +0 -1
- package/dist/modules/workflow/change-request-hooks.d.ts.map +0 -1
- package/dist/modules/workflow/change-request-hooks.js.map +0 -1
- package/dist/modules/workflow/event-bus.d.ts.map +0 -1
- package/dist/modules/workflow/event-bus.js.map +0 -1
- package/dist/modules/workflow/events-delivery.d.ts.map +0 -1
- package/dist/modules/workflow/events-delivery.js.map +0 -1
- package/dist/modules/workflow/events.routes.d.ts.map +0 -1
- package/dist/modules/workflow/events.routes.js.map +0 -1
- package/dist/modules/workflow/file-lock.service.d.ts.map +0 -1
- package/dist/modules/workflow/file-lock.service.js.map +0 -1
- package/dist/modules/workflow/git/change-request-link.d.ts.map +0 -1
- package/dist/modules/workflow/git/change-request-link.js.map +0 -1
- package/dist/modules/workflow/git/git-version.d.ts.map +0 -1
- package/dist/modules/workflow/git/git-version.js.map +0 -1
- package/dist/modules/workflow/git/git.service.d.ts.map +0 -1
- package/dist/modules/workflow/git/git.service.js.map +0 -1
- package/dist/modules/workflow/git/merge-commit.d.ts.map +0 -1
- package/dist/modules/workflow/git/merge-commit.js.map +0 -1
- package/dist/modules/workflow/git/node-git-runner.d.ts.map +0 -1
- package/dist/modules/workflow/git/node-git-runner.js.map +0 -1
- package/dist/modules/workflow/git/pull-request.service.d.ts.map +0 -1
- package/dist/modules/workflow/git/pull-request.service.js.map +0 -1
- package/dist/modules/workflow/index.d.ts.map +0 -1
- package/dist/modules/workflow/index.js.map +0 -1
- package/dist/modules/workflow/pending-commits.service.d.ts.map +0 -1
- package/dist/modules/workflow/pending-commits.service.js.map +0 -1
- package/dist/modules/workflow/pending-commits.worker.d.ts.map +0 -1
- package/dist/modules/workflow/pending-commits.worker.js.map +0 -1
- package/dist/modules/workflow/read-on-branch.d.ts.map +0 -1
- package/dist/modules/workflow/read-on-branch.js.map +0 -1
- package/dist/modules/workflow/recovery-bot.d.ts.map +0 -1
- package/dist/modules/workflow/recovery-bot.js.map +0 -1
- package/dist/modules/workflow/review-workflow/approval-lock.d.ts.map +0 -1
- package/dist/modules/workflow/review-workflow/approval-lock.js.map +0 -1
- package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts.map +0 -1
- package/dist/modules/workflow/review-workflow/review-workflow.interface.js +0 -2
- package/dist/modules/workflow/review-workflow/review-workflow.interface.js.map +0 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +0 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +0 -1
- package/dist/modules/workflow/sanitize-error.d.ts.map +0 -1
- package/dist/modules/workflow/sanitize-error.js.map +0 -1
- package/dist/modules/workflow/workflow-hooks.d.ts.map +0 -1
- package/dist/modules/workflow/workflow-hooks.js.map +0 -1
- package/dist/modules/workflow/workflow.routes.d.ts.map +0 -1
- package/dist/modules/workflow/workflow.routes.js.map +0 -1
- package/dist/modules/workflow/workflow.service.d.ts.map +0 -1
- package/dist/modules/workflow/workflow.service.js.map +0 -1
- package/src/modules/mcp/__tests__/read-only-hint.e2e.test.ts +0 -213
- /package/dist/modules/{workflow → version-control}/agent-tools/change-request-read-shape.d.ts +0 -0
- /package/dist/modules/{workflow → version-control}/agent-tools/change-request-read-shape.js +0 -0
- /package/dist/modules/{workflow → version-control}/agent-tools/change-request-read.tools.d.ts +0 -0
- /package/dist/modules/{workflow → version-control}/agent-tools/change-request-summary.d.ts +0 -0
- /package/dist/modules/{workflow → version-control}/agent-tools/change-request-summary.js +0 -0
- /package/dist/modules/{workflow → version-control}/change-request-hooks.js +0 -0
- /package/dist/modules/{workflow/review-workflow → version-control/change-request-review}/approval-lock.d.ts +0 -0
- /package/dist/modules/{workflow/review-workflow → version-control/change-request-review}/approval-lock.js +0 -0
- /package/dist/modules/{workflow → version-control}/events-delivery.js +0 -0
- /package/dist/modules/{workflow → version-control}/events.routes.js +0 -0
- /package/dist/modules/{workflow → version-control}/git/change-request-link.d.ts +0 -0
- /package/dist/modules/{workflow → version-control}/git/change-request-link.js +0 -0
- /package/dist/modules/{workflow → version-control}/git/git-version.d.ts +0 -0
- /package/dist/modules/{workflow → version-control}/git/git-version.js +0 -0
- /package/dist/modules/{workflow → version-control}/git/merge-commit.d.ts +0 -0
- /package/dist/modules/{workflow → version-control}/git/merge-commit.js +0 -0
- /package/dist/modules/{workflow → version-control}/git/node-git-runner.d.ts +0 -0
- /package/dist/modules/{workflow → version-control}/recovery-bot.d.ts +0 -0
- /package/dist/modules/{workflow → version-control}/recovery-bot.js +0 -0
- /package/dist/modules/{workflow → version-control}/sanitize-error.d.ts +0 -0
- /package/dist/modules/{workflow → version-control}/sanitize-error.js +0 -0
- /package/src/modules/{workflow → version-control}/__tests__/change-request-hooks.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/__tests__/fake-file-lock-db.ts +0 -0
- /package/src/modules/{workflow → version-control}/__tests__/pending-commits.canonical.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/__tests__/pending-commits.enqueue-if-absent.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/__tests__/pending-commits.repository-replaced.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/__tests__/sanitize-error.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/agent-tools/__tests__/change-request-read-shape.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/agent-tools/change-request-read-shape.ts +0 -0
- /package/src/modules/{workflow → version-control}/agent-tools/change-request-summary.ts +0 -0
- /package/src/modules/{workflow/review-workflow → version-control/change-request-review}/approval-lock.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/branchAuthor.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/change-request-link.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/git-version.failure.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/git-version.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/node-git-runner.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.getPrDetail.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.placeholder.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.viewer-can-cancel.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.viewer-can-delete.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/__tests__/pull-request.service.viewer-can-update.test.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/change-request-link.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/git-version.ts +0 -0
- /package/src/modules/{workflow → version-control}/git/merge-commit.ts +0 -0
- /package/src/modules/{workflow → version-control}/recovery-bot.ts +0 -0
- /package/src/modules/{workflow → version-control}/sanitize-error.ts +0 -0
|
@@ -7,18 +7,16 @@ import { tmpdir } from 'node:os';
|
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import type { CallTemplate } from '@utcp/sdk';
|
|
9
9
|
import { McpService } from '../mcp.service.js';
|
|
10
|
-
import { SpillStore } from '../../workspace/
|
|
11
|
-
import { createManualRoutes } from '../../tool-registry/
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
10
|
+
import { SpillStore } from '../../workspace/index.js';
|
|
11
|
+
import { createManualRoutes, ToolRegistry, GUIDE_FIRST_SENTENCE } from '../../tool-registry/index.js';
|
|
12
|
+
import { toolDef } from '../../tool-helpers/index.js';
|
|
13
|
+
import type { AgentEventInput, IAgentEventRecorder } from '../../audit/index.js';
|
|
14
14
|
import { DEFAULT_KB_LAYOUT } from '@bevel-software/platform-shared';
|
|
15
15
|
import { TOOL_PREFIX_LINE, platformInstructions } from '../../agent-instructions/index.js';
|
|
16
|
-
import { GUIDE_FIRST_SENTENCE } from '../../tool-registry/guide-first.js';
|
|
17
16
|
import { splitCallLine } from '@bevel-software/platform-mcp-core';
|
|
18
|
-
import type { AgentEventInput, IAgentEventRecorder } from '../../audit/audit.contract.js';
|
|
19
17
|
|
|
20
18
|
/** The platform-owned part of the handshake text: the header plus the shared file rules. */
|
|
21
|
-
const PLATFORM = platformInstructions(DEFAULT_KB_LAYOUT);
|
|
19
|
+
const PLATFORM = platformInstructions(DEFAULT_KB_LAYOUT, '');
|
|
22
20
|
|
|
23
21
|
/**
|
|
24
22
|
* End-to-end proxy test: a real express app serving the registry-driven tool
|
|
@@ -56,6 +54,10 @@ async function setup(deps?: {
|
|
|
56
54
|
auditRecorder?: IAgentEventRecorder;
|
|
57
55
|
/** The agent connection an OAuth caller arrived through (with `tokenId: null`). */
|
|
58
56
|
connectionId?: string | null;
|
|
57
|
+
/** The agent the credential connects as; absent = Everything. */
|
|
58
|
+
agentPath?: string | null;
|
|
59
|
+
/** Released skills listed beside `rfi` — listed only: `get_skill` answers not-found for them. */
|
|
60
|
+
listedOnly?: { name: string; description: string; path: string }[];
|
|
59
61
|
}) {
|
|
60
62
|
skillRequests = [];
|
|
61
63
|
const registry = new ToolRegistry();
|
|
@@ -117,7 +119,7 @@ async function setup(deps?: {
|
|
|
117
119
|
app.post('/api/agent/tools/list_skills', (req, res) => {
|
|
118
120
|
const b = (req.body ?? {}) as Record<string, unknown>;
|
|
119
121
|
skillRequests.push({ tool: 'list_skills', body: b });
|
|
120
|
-
const released = [{ name: 'rfi', description: 'RFI answers', path: 'Plugins/Sales/rfi' }];
|
|
122
|
+
const released = [{ name: 'rfi', description: 'RFI answers', path: 'Plugins/Sales/rfi' }, ...(deps?.listedOnly ?? [])];
|
|
121
123
|
res.json({
|
|
122
124
|
skills:
|
|
123
125
|
typeof b.branch === 'string'
|
|
@@ -194,6 +196,10 @@ async function setup(deps?: {
|
|
|
194
196
|
httpServer = await new Promise<HttpServer>((resolve) => {
|
|
195
197
|
const s = app.listen(0, () => resolve(s));
|
|
196
198
|
});
|
|
199
|
+
// Every server a test opens is closed after it, not only the last: a test
|
|
200
|
+
// that sets up twice would otherwise leave the first one listening.
|
|
201
|
+
const opened = httpServer;
|
|
202
|
+
cleanups.push(() => new Promise<void>((r) => opened.close(() => r())));
|
|
197
203
|
const port = (httpServer.address() as { port: number }).port;
|
|
198
204
|
loopbackBase = `http://127.0.0.1:${port}`;
|
|
199
205
|
|
|
@@ -215,7 +221,7 @@ async function setup(deps?: {
|
|
|
215
221
|
);
|
|
216
222
|
lastService = mcp;
|
|
217
223
|
const tokenId = deps?.tokenId === undefined ? 'tok-1' : deps.tokenId;
|
|
218
|
-
return connectClient(mcp, tokenId, deps?.connectionId ?? null);
|
|
224
|
+
return connectClient(mcp, tokenId, deps?.connectionId ?? null, deps?.agentPath ?? null);
|
|
219
225
|
}
|
|
220
226
|
|
|
221
227
|
/** The service `setup` built last — for a test that needs a SECOND request against the same service. */
|
|
@@ -228,9 +234,14 @@ let lastService: McpService | undefined;
|
|
|
228
234
|
* The initialize message is passed so the server carries instructions,
|
|
229
235
|
* exactly as the route's initialize request would.
|
|
230
236
|
*/
|
|
231
|
-
async function connectClient(
|
|
237
|
+
async function connectClient(
|
|
238
|
+
mcp: McpService,
|
|
239
|
+
tokenId: string | null,
|
|
240
|
+
connectionId: string | null = null,
|
|
241
|
+
agentPath: string | null = null,
|
|
242
|
+
): Promise<Client> {
|
|
232
243
|
const server = await mcp.createRequestServer(
|
|
233
|
-
{ userId: 'user-A', tokenId, connectionId, bearer: 'bevel_testkey' },
|
|
244
|
+
{ userId: 'user-A', tokenId, connectionId, agentPath, bearer: 'bevel_testkey' },
|
|
234
245
|
{ jsonrpc: '2.0', id: 0, method: 'initialize', params: { protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'test-client', version: '0.0.0' } } },
|
|
235
246
|
);
|
|
236
247
|
|
|
@@ -356,12 +367,14 @@ describe('McpService — per-user credential pre-check', () => {
|
|
|
356
367
|
keys.map((key) => ({ key, adminConfigured: false, userConfigured, userAuthorized, grantedScopes })),
|
|
357
368
|
});
|
|
358
369
|
const manualsWithUserVar = {
|
|
370
|
+
sharedSignInKeysForManual: async () => [],
|
|
359
371
|
userScopedKeysForManual: async (manual: string) =>
|
|
360
372
|
manual === 'KNOWLEDGE_BASE'
|
|
361
373
|
? [{ key: 'KNOWLEDGE_BASE_API_KEY', name: 'API_KEY', label: 'Your API key', oauth: false }]
|
|
362
374
|
: [],
|
|
363
375
|
};
|
|
364
376
|
const manualsWithOAuthVar = {
|
|
377
|
+
sharedSignInKeysForManual: async () => [],
|
|
365
378
|
userScopedKeysForManual: async (manual: string) =>
|
|
366
379
|
manual === 'KNOWLEDGE_BASE'
|
|
367
380
|
? [{ key: 'KNOWLEDGE_BASE_GOOGLE', name: 'GOOGLE', label: 'Google', oauth: true }]
|
|
@@ -369,6 +382,7 @@ describe('McpService — per-user credential pre-check', () => {
|
|
|
369
382
|
};
|
|
370
383
|
// An OAuth var that requires two scopes — for the scope-coverage cases.
|
|
371
384
|
const manualsWithScopedOAuthVar = {
|
|
385
|
+
sharedSignInKeysForManual: async () => [],
|
|
372
386
|
userScopedKeysForManual: async (manual: string) =>
|
|
373
387
|
manual === 'KNOWLEDGE_BASE'
|
|
374
388
|
? [
|
|
@@ -383,9 +397,46 @@ describe('McpService — per-user credential pre-check', () => {
|
|
|
383
397
|
: [],
|
|
384
398
|
};
|
|
385
399
|
const manualsNoUserVar = {
|
|
400
|
+
sharedSignInKeysForManual: async () => [],
|
|
386
401
|
userScopedKeysForManual: async () =>
|
|
387
402
|
[] as { key: string; name: string; label: string | null; oauth: boolean }[],
|
|
388
403
|
};
|
|
404
|
+
// A WORKSPACE connection (a managed connector an owner connects once for
|
|
405
|
+
// everyone): no personal variable, one shared sign-in.
|
|
406
|
+
const manualsWithSharedSignIn = {
|
|
407
|
+
sharedSignInKeysForManual: async (manual: string) =>
|
|
408
|
+
manual === 'KNOWLEDGE_BASE'
|
|
409
|
+
? [{ key: 'KNOWLEDGE_BASE_ACCESS_TOKEN', name: 'ACCESS_TOKEN', label: 'HubSpot sign-in', oauthScopes: ['crm.objects.contacts.read'] }]
|
|
410
|
+
: [],
|
|
411
|
+
userScopedKeysForManual: async () => [] as { key: string; name: string; label: string | null; oauth: boolean }[],
|
|
412
|
+
};
|
|
413
|
+
const sharedVault = (adminAuthorized: boolean, adminGrantedScopes?: string) => ({
|
|
414
|
+
statusFor: async (_userId: string, keys: string[]) =>
|
|
415
|
+
keys.map((key) => ({ key, adminConfigured: adminAuthorized, userConfigured: false, adminAuthorized, adminGrantedScopes })),
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
describe('a workspace connection nobody has made', () => {
|
|
419
|
+
it('refuses the call with words that say an owner connects it, without resetting the caller’s own grant', async () => {
|
|
420
|
+
const revokeOAuthAccess = vi.fn(async () => undefined);
|
|
421
|
+
const client = await setup({ secretsVault: sharedVault(false), toolManuals: manualsWithSharedSignIn, tokenId: null, revokeOAuthAccess });
|
|
422
|
+
const res = await client.callTool({ name: 'ask', arguments: { body: { prompt: 'hello' } } });
|
|
423
|
+
expect(res.isError).toBe(true);
|
|
424
|
+
const text = (res.content as Array<{ text: string }>)[0].text;
|
|
425
|
+
expect(text).toMatch(/HubSpot sign-in \(a tool owner connects this for the workspace\)/);
|
|
426
|
+
expect(text).toMatch(/\/connect/);
|
|
427
|
+
expect(revokeOAuthAccess).not.toHaveBeenCalled();
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it('is hidden from a connection-key listing until an owner connects it with a covering token', async () => {
|
|
431
|
+
const names = async (c: Awaited<ReturnType<typeof setup>>) => (await c.listTools()).tools.map((t) => t.name).sort();
|
|
432
|
+
const unconnected = await setup({ secretsVault: sharedVault(false), toolManuals: manualsWithSharedSignIn });
|
|
433
|
+
expect(await names(unconnected)).toEqual(['call_tool_chain', 'list_tools', 'tools_info']);
|
|
434
|
+
const underScoped = await setup({ secretsVault: sharedVault(true, 'oauth'), toolManuals: manualsWithSharedSignIn });
|
|
435
|
+
expect(await names(underScoped)).toEqual(['call_tool_chain', 'list_tools', 'tools_info']);
|
|
436
|
+
const connected = await setup({ secretsVault: sharedVault(true, 'oauth crm.objects.contacts.read'), toolManuals: manualsWithSharedSignIn });
|
|
437
|
+
expect(await names(connected)).toEqual(['ask', 'boom', 'call_tool_chain', 'list_tools', 'refy', 'tools_info']);
|
|
438
|
+
});
|
|
439
|
+
});
|
|
389
440
|
|
|
390
441
|
it('gates a tool whose personal credential is unset — returns the setup link, not the tool', async () => {
|
|
391
442
|
const client = await setup({ secretsVault: vault(false), toolManuals: manualsWithUserVar });
|
|
@@ -657,7 +708,7 @@ describe('McpService — agent instructions', () => {
|
|
|
657
708
|
// The listing filter registers only ready tools; the fake manual catalog
|
|
658
709
|
// says every tool is ready, so the four survive it and carry the prefix.
|
|
659
710
|
const vault = { statusFor: async (_u: string, keys: string[]) => keys.map((key) => ({ key, userConfigured: true })) };
|
|
660
|
-
const manuals = { userScopedKeysForManual: async () => [{ key: 'KNOWLEDGE_BASE_X', name: 'X', oauth: false }] };
|
|
711
|
+
const manuals = { sharedSignInKeysForManual: async () => [], userScopedKeysForManual: async () => [{ key: 'KNOWLEDGE_BASE_X', name: 'X', oauth: false }] };
|
|
661
712
|
const client = await setup({
|
|
662
713
|
readAgentPreamble: async () => 'Acme.',
|
|
663
714
|
extraTools: KB_TOOLS,
|
|
@@ -886,7 +937,7 @@ describe('McpService — the Audit log records what an agent calls', () => {
|
|
|
886
937
|
it('serves prompts from the default branch only, never a draft', async () => {
|
|
887
938
|
const client = await setup();
|
|
888
939
|
const { prompts } = await client.listPrompts();
|
|
889
|
-
expect(prompts.map((p) => p.name)).toEqual(['rfi']);
|
|
940
|
+
expect(prompts.map((p) => p.name)).toEqual(['onboard', 'rfi']);
|
|
890
941
|
|
|
891
942
|
const got = await client.getPrompt({ name: 'rfi' });
|
|
892
943
|
const text = got.messages[0].content.text as string;
|
|
@@ -899,10 +950,37 @@ describe('McpService — the Audit log records what an agent calls', () => {
|
|
|
899
950
|
expect(skillRequests.every((r) => r.body.branch === undefined)).toBe(true);
|
|
900
951
|
});
|
|
901
952
|
|
|
953
|
+
it('offers the platform onboard prompt, pointing at the guide section, while no skill takes its name', async () => {
|
|
954
|
+
const client = await setup();
|
|
955
|
+
const got = await client.getPrompt({ name: 'onboard' });
|
|
956
|
+
expect(got.messages[0].content.text).toContain('get_agent_guide({ body: { section: "onboarding" } })');
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
it("serves a workspace's own onboard skill in the platform prompt's place, and never the platform text when reading it fails", async () => {
|
|
960
|
+
const client = await setup({ listedOnly: [{ name: 'onboard', description: 'Our own onboarding', path: 'Plugins/People/onboard' }] });
|
|
961
|
+
const { prompts } = await client.listPrompts();
|
|
962
|
+
// The workspace's skill, in the catalog's own order; the platform's prompt is not added beside it.
|
|
963
|
+
expect(prompts.map((p) => [p.name, p.description])).toEqual([
|
|
964
|
+
['rfi', 'RFI answers'],
|
|
965
|
+
['onboard', 'Our own onboarding'],
|
|
966
|
+
]);
|
|
967
|
+
// The skill is listed but its read answers not-found (the harness knows
|
|
968
|
+
// only `rfi`): the same failed read any prompt gets, never the platform's
|
|
969
|
+
// onboarding text under the workspace's name.
|
|
970
|
+
await expect(client.getPrompt({ name: 'onboard' })).rejects.toThrow(/Unknown skill "onboard"/);
|
|
971
|
+
});
|
|
972
|
+
|
|
973
|
+
it('serves a connection narrowed to an agent its skills and nothing beside them', async () => {
|
|
974
|
+
const client = await setup({ agentPath: 'Agents/support.agent' });
|
|
975
|
+
expect((await client.listPrompts()).prompts.map((p) => p.name)).toEqual(['rfi']);
|
|
976
|
+
await expect(client.getPrompt({ name: 'onboard' })).rejects.toThrow(/Unknown skill "onboard"/);
|
|
977
|
+
});
|
|
978
|
+
|
|
902
979
|
it('records a call refused for a missing sign-in as denied, without running the tool', async () => {
|
|
903
980
|
const recorder = spyRecorder();
|
|
904
981
|
const vault = { statusFor: async (_u: string, keys: string[]) => keys.map((key) => ({ key, adminConfigured: false, userConfigured: false })) };
|
|
905
982
|
const manuals = {
|
|
983
|
+
sharedSignInKeysForManual: async () => [],
|
|
906
984
|
userScopedKeysForManual: async (manual: string) =>
|
|
907
985
|
manual === 'KNOWLEDGE_BASE' ? [{ key: 'KNOWLEDGE_BASE_API_KEY', name: 'API_KEY', label: 'Your API key', oauth: false }] : [],
|
|
908
986
|
};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import type { AddressInfo } from 'node:net';
|
|
3
|
+
import { cp, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
import { randomBytes } from 'node:crypto';
|
|
7
|
+
import { tmpdir } from 'node:os';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { afterAll, afterEach, describe, expect, it } from 'vitest';
|
|
10
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
11
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
12
|
+
import { createCoreServices, createCoreServer, stopCore, defaultKbTemplateDir, defaultStarterPacksDir, type TenantConfig } from '../../../index.js';
|
|
13
|
+
import { PG_ADMIN_URL, PG_TEST_TIMEOUT, scratchDatabaseUrl, dropScratchDatabases } from '../../../__tests__/pg-scratch.js';
|
|
14
|
+
import { startFakeDownstreamMcpServer, type FakeDownstreamMcpServer } from './fake-downstream-mcp-server.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A client of the public server composition, over real Streamable HTTP and a
|
|
18
|
+
* scratch Postgres. The catalog source is supplied through its public overlay
|
|
19
|
+
* hook; tool registration, manuals, hints, authentication and MCP routing are
|
|
20
|
+
* the production composition. Admin edits go through the public HTTP API too.
|
|
21
|
+
*/
|
|
22
|
+
const stops: Array<() => Promise<void>> = [];
|
|
23
|
+
afterEach(async () => {
|
|
24
|
+
for (const stop of stops.splice(0).reverse()) await stop();
|
|
25
|
+
}, PG_TEST_TIMEOUT);
|
|
26
|
+
afterAll(dropScratchDatabases, PG_TEST_TIMEOUT);
|
|
27
|
+
|
|
28
|
+
async function startPlatform(opts: { downstream?: FakeDownstreamMcpServer; catalogRevision?: boolean } = {}) {
|
|
29
|
+
const root = await mkdtemp(join(tmpdir(), 'hosted-mcp-hints-'));
|
|
30
|
+
stops.push(() => rm(root, { recursive: true, force: true }));
|
|
31
|
+
const repository = join(root, 'repository');
|
|
32
|
+
await cp(defaultKbTemplateDir(), repository, { recursive: true });
|
|
33
|
+
await writeFile(join(repository, 'roles.yaml'), 'roles:\n Admin:\n - admin@example.com\n');
|
|
34
|
+
const git = (args: string[]) => promisify(execFile)('git', args, { cwd: repository });
|
|
35
|
+
await git(['init', '-q', '-b', 'main']);
|
|
36
|
+
await git(['add', '.']);
|
|
37
|
+
await git(['-c', 'user.name=Test', '-c', 'user.email=admin@example.com', 'commit', '-qm', 'Seed test knowledge base']);
|
|
38
|
+
// Bind before constructing the graph so its loopback URL has the real port.
|
|
39
|
+
const server = createServer();
|
|
40
|
+
await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
|
|
41
|
+
stops.push(async () => {
|
|
42
|
+
server.closeAllConnections();
|
|
43
|
+
await new Promise<void>((resolve, reject) => server.close((error) => error ? reject(error) : resolve()));
|
|
44
|
+
});
|
|
45
|
+
const port = (server.address() as AddressInfo).port;
|
|
46
|
+
const baseUrl = `http://127.0.0.1:${port}`;
|
|
47
|
+
const config: TenantConfig = {
|
|
48
|
+
port, databaseUrl: await scratchDatabaseUrl('hexis_mcp_hints'), dbSchema: 'public', nodeEnv: 'test',
|
|
49
|
+
tenantId: 'bevel', externalApiKeyPrefix: 'bevel_', internalTokenPrefix: 'bevel-internal_',
|
|
50
|
+
uploadTokenPrefix: 'bevel-upload_', mcpOAuthTokenPrefix: 'bevel-mcp_',
|
|
51
|
+
workspacesRoot: join(root, 'workspaces'), backupsRoot: join(root, 'backups'),
|
|
52
|
+
spillRoot: join(root, 'spills'), agentUploadsRoot: join(root, 'uploads'), docExtractCacheRoot: join(root, 'extracts'),
|
|
53
|
+
jwtSecret: 'hosted-hints-test-secret', adminEmail: 'admin@example.com', adminPassword: 'test-password',
|
|
54
|
+
oidcIssuerUrl: '', oidcClientId: '', oidcClientSecret: '', oidcScopes: 'openid', oidcProviderLabel: 'SSO',
|
|
55
|
+
kbRepoUrl: repository, kbDirName: 'knowledge-base', gitUsername: '', gitToken: '',
|
|
56
|
+
kbTemplateDir: defaultKbTemplateDir(), starterPacksDir: defaultStarterPacksDir(),
|
|
57
|
+
updateCheckEnabled: false, loginPasswordEnabled: true, allowedEmailDomains: [],
|
|
58
|
+
secretsEncKey: randomBytes(32).toString('base64'), internalTokenSecret: 'hosted-hints-internal-secret',
|
|
59
|
+
embedSharedSecret: '', trustProxy: '', gitTimeoutMs: 30_000,
|
|
60
|
+
publicBackendUrl: baseUrl, publicFrontendUrl: baseUrl, configuredPublicFrontendUrl: baseUrl,
|
|
61
|
+
settingsEnv: { KB_REPO_URL: repository, DEFAULT_BRANCH: 'main', PROTECTED_BRANCHES: 'main' },
|
|
62
|
+
};
|
|
63
|
+
const core = await createCoreServices(config, { mirrorSharedBindings: false });
|
|
64
|
+
stops.push(() => stopCore(core));
|
|
65
|
+
const app = await createCoreServer(core, {
|
|
66
|
+
preAuth(app) {
|
|
67
|
+
app.get('/api/agent/all-tools', core.manualAuthMiddleware, (_req, res) => {
|
|
68
|
+
res.json({ manuals: [
|
|
69
|
+
{ name: 'KNOWLEDGE_BASE', call_template_type: 'http', http_method: 'GET',
|
|
70
|
+
url: '${API_URL}/api/agent/utcp', content_type: 'application/json',
|
|
71
|
+
headers: { Authorization: 'Bearer ${CONNECTION_KEY}' } },
|
|
72
|
+
...(opts.downstream ? [{ name: 'notion', call_template_type: 'mcp',
|
|
73
|
+
config: { mcpServers: { srv: { transport: 'http', url: opts.downstream.url } } } }] : []),
|
|
74
|
+
] });
|
|
75
|
+
});
|
|
76
|
+
app.get('/api/agent/catalog-revision', core.manualAuthMiddleware, (_req, res) => {
|
|
77
|
+
if (opts.catalogRevision) res.json({ revision: 'unchanged-catalog' });
|
|
78
|
+
else res.sendStatus(404);
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
}, { boot: false });
|
|
82
|
+
server.on('request', app);
|
|
83
|
+
const login = await fetch(`${baseUrl}/api/auth/login`, {
|
|
84
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
85
|
+
body: JSON.stringify({ email: config.adminEmail, password: config.adminPassword }),
|
|
86
|
+
});
|
|
87
|
+
expect(login.status).toBe(200);
|
|
88
|
+
const { token, user } = await login.json() as { token: string; user: { id: string } };
|
|
89
|
+
const { plaintext: key } = await core.externalApiKeyService.mint(user.id, 'metadata-test');
|
|
90
|
+
const setHint = async (name: string, readOnly: boolean | null) => {
|
|
91
|
+
const response = await fetch(`${baseUrl}/api/tool-hints/${name}`, {
|
|
92
|
+
method: 'PUT', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
93
|
+
body: JSON.stringify({ readOnly }),
|
|
94
|
+
});
|
|
95
|
+
expect(response.status).toBe(200);
|
|
96
|
+
};
|
|
97
|
+
return { baseUrl, key, setHint };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function connect(baseUrl: string, key: string): Promise<Client> {
|
|
101
|
+
const transport = new StreamableHTTPClientTransport(new URL(`${baseUrl}/api/mcp`), {
|
|
102
|
+
requestInit: { headers: { Authorization: `Bearer ${key}` } },
|
|
103
|
+
});
|
|
104
|
+
const client = new Client({ name: 'hint-client', version: '0.0.0' }, { capabilities: {} });
|
|
105
|
+
await client.connect(transport);
|
|
106
|
+
stops.push(() => client.close());
|
|
107
|
+
return client;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const annotationsOf = async (client: Client) =>
|
|
111
|
+
Object.fromEntries((await client.listTools()).tools.map((t) => [t.name, t.annotations]));
|
|
112
|
+
|
|
113
|
+
describe.skipIf(!PG_ADMIN_URL)('the hosted MCP endpoint lists the read-only hint', () => {
|
|
114
|
+
it('on every platform tool and every meta-tool, and no other annotation', async () => {
|
|
115
|
+
const { baseUrl, key } = await startPlatform();
|
|
116
|
+
const tools = (await (await connect(baseUrl, key)).listTools()).tools;
|
|
117
|
+
for (const tool of tools) {
|
|
118
|
+
expect(tool.title).toEqual(expect.any(String));
|
|
119
|
+
expect(tool.title!.trim()).not.toBe('');
|
|
120
|
+
expect(tool.annotations).toEqual({ readOnlyHint: expect.any(Boolean) });
|
|
121
|
+
}
|
|
122
|
+
expect(Object.fromEntries(tools.map((t) => [t.name, t.title]))).toMatchObject({
|
|
123
|
+
list_tools: 'List tools',
|
|
124
|
+
tools_info: 'Tools info',
|
|
125
|
+
call_tool_chain: 'Call tool chain',
|
|
126
|
+
read_file: 'Read file',
|
|
127
|
+
write_file: 'Write file',
|
|
128
|
+
});
|
|
129
|
+
expect(Object.fromEntries(tools.map((t) => [t.name, t.annotations]))).toMatchObject({
|
|
130
|
+
list_tools: { readOnlyHint: true },
|
|
131
|
+
tools_info: { readOnlyHint: true },
|
|
132
|
+
call_tool_chain: { readOnlyHint: false },
|
|
133
|
+
read_file: { readOnlyHint: true },
|
|
134
|
+
write_file: { readOnlyHint: false },
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("lists an admin's change on the client's NEXT tools/list, with no reconnect, and a reset undoes it", async () => {
|
|
139
|
+
const { baseUrl, key, setHint } = await startPlatform();
|
|
140
|
+
const client = await connect(baseUrl, key);
|
|
141
|
+
expect((await annotationsOf(client)).read_file).toEqual({ readOnlyHint: true });
|
|
142
|
+
|
|
143
|
+
await setHint('read_file', false);
|
|
144
|
+
await setHint('write_file', true);
|
|
145
|
+
await setHint('call_tool_chain', true);
|
|
146
|
+
let listed = await annotationsOf(client);
|
|
147
|
+
expect(listed.read_file).toEqual({ readOnlyHint: false });
|
|
148
|
+
expect(listed.write_file).toEqual({ readOnlyHint: true });
|
|
149
|
+
expect(listed.call_tool_chain).toEqual({ readOnlyHint: true });
|
|
150
|
+
|
|
151
|
+
for (const name of ['read_file', 'write_file', 'call_tool_chain']) await setHint(name, null);
|
|
152
|
+
listed = await annotationsOf(client);
|
|
153
|
+
expect(listed.read_file).toEqual({ readOnlyHint: true });
|
|
154
|
+
expect(listed.write_file).toEqual({ readOnlyHint: false });
|
|
155
|
+
expect(listed.call_tool_chain).toEqual({ readOnlyHint: false });
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("lists an admin's change and its reset on the next tools/list when the tool surface is cached", async () => {
|
|
159
|
+
const { baseUrl, key, setHint } = await startPlatform({ catalogRevision: true });
|
|
160
|
+
const client = await connect(baseUrl, key);
|
|
161
|
+
expect((await annotationsOf(client)).read_file).toEqual({ readOnlyHint: true });
|
|
162
|
+
|
|
163
|
+
await setHint('read_file', false);
|
|
164
|
+
await setHint('write_file', true);
|
|
165
|
+
let listed = await annotationsOf(client);
|
|
166
|
+
expect(listed.read_file).toEqual({ readOnlyHint: false });
|
|
167
|
+
expect(listed.write_file).toEqual({ readOnlyHint: true });
|
|
168
|
+
|
|
169
|
+
for (const name of ['read_file', 'write_file']) await setHint(name, null);
|
|
170
|
+
listed = await annotationsOf(client);
|
|
171
|
+
expect(listed.read_file).toEqual({ readOnlyHint: true });
|
|
172
|
+
expect(listed.write_file).toEqual({ readOnlyHint: false });
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('does not keep an override in the cached surface: one set before the surface is built is undone by its reset', async () => {
|
|
176
|
+
const { baseUrl, key, setHint } = await startPlatform({ catalogRevision: true });
|
|
177
|
+
await setHint('read_file', false);
|
|
178
|
+
const client = await connect(baseUrl, key);
|
|
179
|
+
expect((await annotationsOf(client)).read_file).toEqual({ readOnlyHint: false });
|
|
180
|
+
|
|
181
|
+
await setHint('read_file', null);
|
|
182
|
+
expect((await annotationsOf(client)).read_file).toEqual({ readOnlyHint: true });
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('lists a tool from a plugin MCP server with conservative effects', async () => {
|
|
186
|
+
const downstream = await startFakeDownstreamMcpServer();
|
|
187
|
+
stops.push(() => downstream.stop());
|
|
188
|
+
const { baseUrl, key } = await startPlatform({ downstream });
|
|
189
|
+
const tools = (await (await connect(baseUrl, key)).listTools()).tools;
|
|
190
|
+
const proxied = tools.find((t) => t.name.endsWith('echo'));
|
|
191
|
+
expect(proxied).toBeDefined();
|
|
192
|
+
expect(proxied?.annotations).toEqual({ readOnlyHint: false });
|
|
193
|
+
});
|
|
194
|
+
});
|
|
@@ -42,6 +42,8 @@ import {
|
|
|
42
42
|
retiredToolMessage,
|
|
43
43
|
needsAuthorizationResult,
|
|
44
44
|
skillPromptText,
|
|
45
|
+
ONBOARD_PROMPT,
|
|
46
|
+
promptsForSkills,
|
|
45
47
|
toListedResource,
|
|
46
48
|
toReadResourceResult,
|
|
47
49
|
type McpAppManifest,
|
|
@@ -50,7 +52,7 @@ import {
|
|
|
50
52
|
type LoadedSkill,
|
|
51
53
|
} from '@bevel-software/platform-mcp-core';
|
|
52
54
|
import type { KbLayout } from '@bevel-software/platform-shared';
|
|
53
|
-
import { bevelSecretsLoaderConfig, type ForcedRefreshOutcome, type ISecretsVaultService, userSecretGap } from '../secrets-vault/index.js';
|
|
55
|
+
import { bevelSecretsLoaderConfig, type ForcedRefreshOutcome, type ISecretsVaultService, scopesCovered, userSecretGap } from '../secrets-vault/index.js';
|
|
54
56
|
import { EXTERNAL_KB_MANUAL_NAME } from '../tool-manuals/index.js';
|
|
55
57
|
import type { IToolManualService } from '../tool-manuals/index.js';
|
|
56
58
|
import type { SpillStore } from '../workspace/index.js';
|
|
@@ -109,12 +111,19 @@ export interface McpProxyOptions {
|
|
|
109
111
|
*/
|
|
110
112
|
readAgentPreamble?: AgentPreambleReader;
|
|
111
113
|
/**
|
|
112
|
-
* The layout in effect, read per request: the shared file rules
|
|
113
|
-
*
|
|
114
|
-
* a layout without a restart. A GETTER, so nothing
|
|
115
|
-
* pre-setup default. Absent, the rules
|
|
114
|
+
* The layout in effect, read per request: the shared file rules spell the
|
|
115
|
+
* root folders and platform files by the names a deployment saved, and the
|
|
116
|
+
* setup save applies a layout without a restart. A GETTER, so nothing
|
|
117
|
+
* snapshots the pre-setup default. Absent, the rules use the default
|
|
118
|
+
* layout. The guide is `AGENTS.md` either way.
|
|
116
119
|
*/
|
|
117
120
|
kbLayout?: () => KbLayout;
|
|
121
|
+
/**
|
|
122
|
+
* The default branch in effect, read per request: the shared file rules
|
|
123
|
+
* name it as the branch people read. A GETTER for the same reason as the
|
|
124
|
+
* layout. Absent, the rules name no branch.
|
|
125
|
+
*/
|
|
126
|
+
defaultBranch?: () => string;
|
|
118
127
|
/** Bounds of the downstream (`mcp.json`) connection pool; defaults are 4h idle / 5000 entries. */
|
|
119
128
|
downstreamPool?: Pick<DownstreamPoolOptions<unknown>, 'idleTtlMs' | 'maxEntries' | 'now'>;
|
|
120
129
|
/**
|
|
@@ -378,7 +387,7 @@ export class McpService {
|
|
|
378
387
|
private readonly manualFailures = new ManualFailureMemo();
|
|
379
388
|
private readonly surfaceLog = new SurfaceLogThrottle();
|
|
380
389
|
// One forced token refresh per (user, manual) per minute — see downstream-token-refresh.
|
|
381
|
-
private readonly tokenRefreshes: DownstreamRefreshGuard<ForcedRefreshOutcome>;
|
|
390
|
+
private readonly tokenRefreshes: DownstreamRefreshGuard<ForcedRefreshOutcome | 'rejected-shared'>;
|
|
382
391
|
/**
|
|
383
392
|
* The tools each pooled manual last advertised, by manual definition. A
|
|
384
393
|
* downstream can only be asked what its tools are over a connection, and a
|
|
@@ -859,17 +868,32 @@ export class McpService {
|
|
|
859
868
|
// loopback with the caller's key — so the default-branch catalog, access
|
|
860
869
|
// filtering, and progressive disclosure all live ONCE behind that REST
|
|
861
870
|
// surface, never duplicated here. Neither handler needs the tool catalog.
|
|
871
|
+
// The one prompt that is not a skill is the platform's `onboard`, offered
|
|
872
|
+
// only on a connection not narrowed to an agent, and only while no skill
|
|
873
|
+
// takes its name (see `promptsForSkills`).
|
|
874
|
+
const offerOnboard = agentPath === null;
|
|
862
875
|
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
863
876
|
const skills = await this.fetchSkillList(loopbackBearer);
|
|
864
|
-
const prompts: Prompt[] = skills
|
|
865
|
-
name: s.name,
|
|
866
|
-
description: s.description,
|
|
867
|
-
arguments: [],
|
|
868
|
-
}));
|
|
877
|
+
const prompts: Prompt[] = promptsForSkills(skills, offerOnboard);
|
|
869
878
|
return { prompts };
|
|
870
879
|
});
|
|
871
880
|
|
|
872
881
|
server.setRequestHandler(GetPromptRequestSchema, async (request): Promise<GetPromptResult> => {
|
|
882
|
+
// The platform's own prompt is served exactly when `prompts/list`
|
|
883
|
+
// offered it: the connection is not narrowed and no released skill
|
|
884
|
+
// takes the name — judged on the skill LIST, the same answer the
|
|
885
|
+
// listing used, never on a read that failed. A workspace's own
|
|
886
|
+
// `onboard` skill is then read like any other prompt, and a read that
|
|
887
|
+
// fails is a failed read, not a reason to serve the platform's text.
|
|
888
|
+
if (offerOnboard && request.params.name === ONBOARD_PROMPT.name) {
|
|
889
|
+
const released = await this.fetchSkillList(loopbackBearer);
|
|
890
|
+
if (!released.some((s) => s.name === ONBOARD_PROMPT.name)) {
|
|
891
|
+
return {
|
|
892
|
+
description: ONBOARD_PROMPT.description,
|
|
893
|
+
messages: [{ role: 'user', content: { type: 'text', text: ONBOARD_PROMPT.text } }],
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
}
|
|
873
897
|
const started = performance.now();
|
|
874
898
|
const skill = await this.fetchSkill(loopbackBearer, request.params.name);
|
|
875
899
|
// A prompt IS a skill read — the same event `get_skill` produces.
|
|
@@ -1059,13 +1083,14 @@ export class McpService {
|
|
|
1059
1083
|
*/
|
|
1060
1084
|
private async composeAgentInstructions(): Promise<ComposedAgentInstructions> {
|
|
1061
1085
|
const layout = this.opts.kbLayout?.();
|
|
1086
|
+
const defaultBranch = this.opts.defaultBranch?.();
|
|
1062
1087
|
const read = this.opts.readAgentPreamble;
|
|
1063
|
-
if (!read) return composeAgentInstructions(null, layout);
|
|
1088
|
+
if (!read) return composeAgentInstructions(null, layout, defaultBranch);
|
|
1064
1089
|
try {
|
|
1065
|
-
return composeAgentInstructions(await read(), layout);
|
|
1090
|
+
return composeAgentInstructions(await read(), layout, defaultBranch);
|
|
1066
1091
|
} catch (err) {
|
|
1067
1092
|
log.warn('could not read mcp-description.md; this request gets the platform text alone:', { err });
|
|
1068
|
-
return composeAgentInstructions(null, layout);
|
|
1093
|
+
return composeAgentInstructions(null, layout, defaultBranch);
|
|
1069
1094
|
}
|
|
1070
1095
|
}
|
|
1071
1096
|
|
|
@@ -1559,7 +1584,7 @@ export class McpService {
|
|
|
1559
1584
|
this.downstream.evictWhere((k) => k === poolKey);
|
|
1560
1585
|
return { retry: true };
|
|
1561
1586
|
}
|
|
1562
|
-
if (outcome === 'rejected') {
|
|
1587
|
+
if (outcome === 'rejected' || outcome === 'rejected-shared') {
|
|
1563
1588
|
// The connection was dialed with a grant that no longer exists; the
|
|
1564
1589
|
// vault's mutation signal drops it too, this keeps the next request
|
|
1565
1590
|
// honest whether or not that is wired.
|
|
@@ -1568,8 +1593,11 @@ export class McpService {
|
|
|
1568
1593
|
retry: false,
|
|
1569
1594
|
credentialTransient: false,
|
|
1570
1595
|
error: new Error(
|
|
1571
|
-
|
|
1572
|
-
`
|
|
1596
|
+
outcome === 'rejected-shared'
|
|
1597
|
+
? `The workspace connection for "${manualName}" was rejected by the provider and has been disconnected. ` +
|
|
1598
|
+
`A tool owner has to reconnect it on ${this.opts.publicFrontendUrl}/connect; then run the tool again.`
|
|
1599
|
+
: `Your sign-in for "${manualName}" was rejected and has been disconnected. ` +
|
|
1600
|
+
`Re-authorize it on ${this.opts.publicFrontendUrl}/connect, then run the tool again.`,
|
|
1573
1601
|
),
|
|
1574
1602
|
};
|
|
1575
1603
|
}
|
|
@@ -1596,12 +1624,21 @@ export class McpService {
|
|
|
1596
1624
|
private async refreshDownstreamToken(
|
|
1597
1625
|
userId: string,
|
|
1598
1626
|
manualName: string,
|
|
1599
|
-
): Promise<ForcedRefreshOutcome | 'guarded' | undefined> {
|
|
1627
|
+
): Promise<ForcedRefreshOutcome | 'rejected-shared' | 'guarded' | undefined> {
|
|
1600
1628
|
const vault = this.secretsVault;
|
|
1601
1629
|
if (!vault || !this.toolManuals || !manualName) return undefined;
|
|
1602
1630
|
let keys: string[];
|
|
1631
|
+
let sharedKeys = new Set<string>();
|
|
1603
1632
|
try {
|
|
1604
|
-
|
|
1633
|
+
// Every sign-in the manual declares: the caller's own, and a workspace
|
|
1634
|
+
// connection every caller resolves (the vault's forceRefresh reads the
|
|
1635
|
+
// shared row for an admin-scoped key, as resolve does).
|
|
1636
|
+
const [own, shared] = await Promise.all([
|
|
1637
|
+
this.toolManuals.userScopedKeysForManual(manualName),
|
|
1638
|
+
this.toolManuals.sharedSignInKeysForManual(manualName),
|
|
1639
|
+
]);
|
|
1640
|
+
keys = [...own.filter((v) => v.oauth).map((v) => v.key), ...shared.map((v) => v.key)];
|
|
1641
|
+
sharedKeys = new Set(shared.map((v) => v.key));
|
|
1605
1642
|
} catch (err) {
|
|
1606
1643
|
// The error's own message is caller-controlled as well (it quotes the
|
|
1607
1644
|
// manual, and may quote a provider's reply), and a raw Error handed to
|
|
@@ -1616,12 +1653,20 @@ export class McpService {
|
|
|
1616
1653
|
if (keys.length === 0) return undefined;
|
|
1617
1654
|
const attempt = this.tokenRefreshes.run(`${userId}${POOL_KEY_SEPARATOR}${manualName}`, async () => {
|
|
1618
1655
|
const outcomes: ForcedRefreshOutcome[] = [];
|
|
1656
|
+
// A dead WORKSPACE connection is told apart from a dead personal one:
|
|
1657
|
+
// the caller cannot repair it, a writer of the tool can, and the words
|
|
1658
|
+
// the caller gets have to say so.
|
|
1659
|
+
let rejectedShared = false;
|
|
1619
1660
|
for (const key of keys) {
|
|
1620
1661
|
// A vault fault is not a verdict on the grant: keep the token, try later.
|
|
1621
|
-
|
|
1662
|
+
const result = await vault.forceRefresh(userId, key).catch((): ForcedRefreshOutcome => 'transient');
|
|
1663
|
+
if (result === 'rejected' && sharedKeys.has(key)) rejectedShared = true;
|
|
1664
|
+
outcomes.push(result);
|
|
1622
1665
|
}
|
|
1623
|
-
const outcome: ForcedRefreshOutcome = outcomes.includes('rejected')
|
|
1624
|
-
?
|
|
1666
|
+
const outcome: ForcedRefreshOutcome | 'rejected-shared' = outcomes.includes('rejected')
|
|
1667
|
+
? rejectedShared
|
|
1668
|
+
? 'rejected-shared'
|
|
1669
|
+
: 'rejected'
|
|
1625
1670
|
: outcomes.includes('transient')
|
|
1626
1671
|
? 'transient'
|
|
1627
1672
|
: outcomes.includes('refreshed')
|
|
@@ -1681,14 +1726,30 @@ export class McpService {
|
|
|
1681
1726
|
manualName: string,
|
|
1682
1727
|
): Promise<{ name: string; label?: string | null; brokenSignIn: boolean }[]> {
|
|
1683
1728
|
if (!this.secretsVault || !this.toolManuals || !manualName) return [];
|
|
1684
|
-
const userVars = await
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1729
|
+
const [userVars, sharedSignIns] = await Promise.all([
|
|
1730
|
+
this.toolManuals.userScopedKeysForManual(manualName),
|
|
1731
|
+
this.toolManuals.sharedSignInKeysForManual(manualName),
|
|
1732
|
+
]);
|
|
1733
|
+
if (userVars.length === 0 && sharedSignIns.length === 0) return [];
|
|
1734
|
+
const status = await this.secretsVault.statusFor(userId, [
|
|
1735
|
+
...userVars.map((v) => v.key),
|
|
1736
|
+
...sharedSignIns.map((v) => v.key),
|
|
1737
|
+
]);
|
|
1690
1738
|
const statusMap = new Map(status.map((s) => [s.key, s]));
|
|
1691
1739
|
const missing: { name: string; label?: string | null; brokenSignIn: boolean }[] = [];
|
|
1740
|
+
// A WORKSPACE sign-in (a managed connector enabled as one shared
|
|
1741
|
+
// connection) is nobody's personal credential, but a tool whose one
|
|
1742
|
+
// connection has not been made — or no longer covers what the tool
|
|
1743
|
+
// declares — fails just as opaquely at the provider. Reported like a
|
|
1744
|
+
// personal one, with words that say whose job it is; never a "broken
|
|
1745
|
+
// sign-in" of the caller's, since there is nothing of theirs to reset.
|
|
1746
|
+
for (const v of sharedSignIns) {
|
|
1747
|
+
const st = statusMap.get(v.key);
|
|
1748
|
+
const connected = st?.adminAuthorized === true && scopesCovered(v.oauthScopes, st.adminGrantedScopes);
|
|
1749
|
+
if (!connected) {
|
|
1750
|
+
missing.push({ name: v.name, label: `${v.label ?? v.name} (a tool owner connects this for the workspace)`, brokenSignIn: false });
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1692
1753
|
for (const v of userVars) {
|
|
1693
1754
|
// The one readiness rule `list_tool_setup` reports from (`userSecretGap`).
|
|
1694
1755
|
// A sign-in the caller already HAS a row for but that isn't (or is no
|