@bevel-software/platform-core-backend 0.35.0 → 0.37.0
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 +72 -57
- 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/connection.d.ts.map +1 -1
- package/dist/modules/database/connection.js +11 -0
- package/dist/modules/database/connection.js.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 +51 -26
- package/dist/modules/kb-fs/file-change-notifier.d.ts.map +1 -1
- package/dist/modules/kb-fs/file-change-notifier.js +6 -8
- package/dist/modules/kb-fs/file-change-notifier.js.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.d.ts +9 -16
- package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.js +31 -39
- 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 +5 -7
- 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 +26 -8
- package/dist/modules/version-control/git/git.service.d.ts.map +1 -0
- package/dist/modules/{workflow → version-control}/git/git.service.js +106 -55
- 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} +33 -6
- 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} +20 -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 -46
- 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} +93 -107
- 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/fire-and-forget.d.ts +14 -0
- package/dist/shared/fire-and-forget.d.ts.map +1 -0
- package/dist/shared/fire-and-forget.js +23 -0
- package/dist/shared/fire-and-forget.js.map +1 -0
- 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__/capturing-logger.ts +36 -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__/real-access.ts +16 -0
- package/src/__tests__/real-auth.ts +13 -0
- package/src/__tests__/real-readers.ts +27 -0
- package/src/__tests__/real-version-control.ts +22 -0
- 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__/commit-announcements-wired-once.test.ts +53 -0
- 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 +83 -65
- 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 +23 -23
- 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 +44 -44
- package/src/modules/access/__tests__/roles-admin.security.test.ts +14 -13
- package/src/modules/access/__tests__/roles-admin.service.test.ts +34 -34
- package/src/modules/access/__tests__/roles-capabilities.test.ts +29 -29
- package/src/modules/access/__tests__/roles.routes.test.ts +11 -11
- package/src/modules/access/__tests__/synced-groups-committer.test.ts +14 -14
- package/src/modules/access/__tests__/user-access-removal.service.test.ts +33 -33
- 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__/connection.pg.test.ts +55 -0
- package/src/modules/database/__tests__/connection.test.ts +30 -0
- package/src/modules/database/__tests__/migrations-unqualified.test.ts +32 -32
- package/src/modules/database/connection.ts +12 -0
- 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 +48 -62
- 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__/file-change-notifier.test.ts +23 -4
- package/src/modules/kb-fs/__tests__/locking-filesystem.test.ts +264 -305
- package/src/modules/kb-fs/__tests__/move-with-edits.test.ts +103 -40
- 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 +55 -32
- package/src/modules/kb-fs/locking-filesystem.ts +34 -48
- 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 +59 -59
- 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 +7 -9
- 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__/plugin-rename.service.test.ts +46 -21
- package/src/modules/plugins/__tests__/plugins.routes.test.ts +31 -31
- 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} +100 -102
- 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} +85 -75
- 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/version-control/git/__tests__/git.service.commitLanded.test.ts +199 -0
- 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 +99 -22
- 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 +112 -59
- 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} +44 -5
- 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} +96 -109
- 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__/fire-and-forget.test.ts +39 -0
- 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/fire-and-forget.ts +26 -0
- 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
|
@@ -2,13 +2,13 @@ import type { BranchSyncOutcome } from '@bevel-software/platform-shared';
|
|
|
2
2
|
import { logger } from '../../shared/logging.js';
|
|
3
3
|
|
|
4
4
|
const log = logger('sync');
|
|
5
|
-
import { sanitizeError } from '../
|
|
5
|
+
import { sanitizeError } from '../version-control/index.js';
|
|
6
6
|
import type {
|
|
7
7
|
IKbSyncService,
|
|
8
8
|
LastSync,
|
|
9
9
|
SyncRequest,
|
|
10
10
|
SyncResult,
|
|
11
|
-
|
|
11
|
+
SyncVersionControlPort,
|
|
12
12
|
SyncWorkspacePort,
|
|
13
13
|
} from './kb-sync.interface.js';
|
|
14
14
|
|
|
@@ -44,7 +44,7 @@ export class KbSyncService implements IKbSyncService {
|
|
|
44
44
|
private last: LastSync | null = null;
|
|
45
45
|
|
|
46
46
|
constructor(
|
|
47
|
-
private readonly
|
|
47
|
+
private readonly versionControl: SyncVersionControlPort,
|
|
48
48
|
private readonly workspaces: SyncWorkspacePort,
|
|
49
49
|
private readonly now: () => number = () => Date.now(),
|
|
50
50
|
) {}
|
|
@@ -152,9 +152,9 @@ export class KbSyncService implements IKbSyncService {
|
|
|
152
152
|
}
|
|
153
153
|
let outcome: BranchSyncOutcome;
|
|
154
154
|
try {
|
|
155
|
-
outcome = await this.
|
|
155
|
+
outcome = await this.versionControl.syncWorkspaceFromRemote(id);
|
|
156
156
|
} catch (err) {
|
|
157
|
-
// The
|
|
157
|
+
// The version-control sync step promises outcomes, not throws — but one broken
|
|
158
158
|
// clone must never take the other branches, the sweep, or every
|
|
159
159
|
// coalesced caller down with it, so the promise is enforced here too.
|
|
160
160
|
const message = sanitizeError(err);
|
|
@@ -165,11 +165,11 @@ export class KbSyncService implements IKbSyncService {
|
|
|
165
165
|
if (outcome.outcome === 'remote-gone') {
|
|
166
166
|
// The host deleted the branch. Left in place, the stale clone would
|
|
167
167
|
// fail its fetch on every following full sync — and a webhook host
|
|
168
|
-
// disables a subscription that keeps failing. The
|
|
168
|
+
// disables a subscription that keeps failing. The version-control service retires it
|
|
169
169
|
// under the branch-lifecycle lock, after asking origin again, so a
|
|
170
170
|
// branch recreated since the pull keeps its clone. Best-effort.
|
|
171
171
|
try {
|
|
172
|
-
const removed = await this.
|
|
172
|
+
const removed = await this.versionControl.retireRemoteGoneClone(id);
|
|
173
173
|
if (removed) log.info(`removed the clone of "${branch}" — deleted on the host`);
|
|
174
174
|
else log.info(`kept the clone of "${branch}" — it is back on the host, or already gone`);
|
|
175
175
|
} catch (err) {
|
|
@@ -183,7 +183,7 @@ export class KbSyncService implements IKbSyncService {
|
|
|
183
183
|
// pointed at it. Best-effort — it fails safe by closing nothing.
|
|
184
184
|
let closedDeletedBranch = 0;
|
|
185
185
|
try {
|
|
186
|
-
closedDeletedBranch = await this.
|
|
186
|
+
closedDeletedBranch = await this.versionControl.closeChangeRequestsWithDeletedBranches();
|
|
187
187
|
} catch (err) {
|
|
188
188
|
log.warn('deleted-branch sweep failed:', { err });
|
|
189
189
|
}
|
|
@@ -192,7 +192,7 @@ export class KbSyncService implements IKbSyncService {
|
|
|
192
192
|
// large repository, and the sync (often a webhook with a short timeout)
|
|
193
193
|
// must not wait on it. It never throws; the catch is for a mock or a
|
|
194
194
|
// future change that does.
|
|
195
|
-
void this.
|
|
195
|
+
void this.versionControl.tidyAfterSweep().catch((err: unknown) => log.warn('post-sync tidy-up failed:', { err }));
|
|
196
196
|
|
|
197
197
|
const result: SyncResult = {
|
|
198
198
|
status: KbSyncService.statusOf(results),
|
|
@@ -9,7 +9,7 @@ import express from 'express';
|
|
|
9
9
|
import type { AuthUser } from '@bevel-software/platform-shared';
|
|
10
10
|
|
|
11
11
|
import { MarketplaceRepoService, type MarketplaceCompiler } from '../marketplace-repo.service.js';
|
|
12
|
-
import { NodeGitRunner } from '../../
|
|
12
|
+
import { NodeGitRunner } from '../../version-control/git/node-git-runner.js';
|
|
13
13
|
import {
|
|
14
14
|
GitHubFacadeCredentialsService,
|
|
15
15
|
GitHubFacade,
|
|
@@ -10,7 +10,7 @@ import type { AuthUser } from '@bevel-software/platform-shared';
|
|
|
10
10
|
|
|
11
11
|
import { MarketplaceRepoService, type MarketplaceCompiler } from '../marketplace-repo.service.js';
|
|
12
12
|
import { createMarketplaceGitRoutes } from '../git-http.routes.js';
|
|
13
|
-
import { NodeGitRunner } from '../../
|
|
13
|
+
import { NodeGitRunner } from '../../version-control/git/node-git-runner.js';
|
|
14
14
|
import type { VirtualTree } from '../../plugins/compile/compile-marketplace.js';
|
|
15
15
|
|
|
16
16
|
const execFileAsync = promisify(execFile);
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
flattenDiscoveredTool,
|
|
7
7
|
toCallToolResult,
|
|
8
8
|
toListedTool,
|
|
9
|
-
} from '
|
|
10
|
-
import type { ProxiedTool } from '
|
|
9
|
+
} from '@bevel-software/platform-mcp-core';
|
|
10
|
+
import type { ProxiedTool } from '@bevel-software/platform-mcp-core';
|
|
11
11
|
|
|
12
12
|
function utcpTool(name: string, bodyProps: Record<string, unknown>, required: string[] = []): UtcpTool {
|
|
13
13
|
return {
|
|
@@ -72,8 +72,10 @@ describe('toListedTool', () => {
|
|
|
72
72
|
const listed = toListedTool(proxied({ mcpName: 'gmail_send_email' }));
|
|
73
73
|
expect(listed).toEqual({
|
|
74
74
|
name: 'gmail_send_email',
|
|
75
|
+
title: 'Gmail send email',
|
|
75
76
|
description: 'Call: m.t({})\n\na tool',
|
|
76
77
|
inputSchema: { type: 'object', properties: {} },
|
|
78
|
+
annotations: { readOnlyHint: false },
|
|
77
79
|
});
|
|
78
80
|
});
|
|
79
81
|
|
|
@@ -12,16 +12,15 @@ import { tmpdir } from 'node:os';
|
|
|
12
12
|
import { join } from 'node:path';
|
|
13
13
|
import { createMcpRoutes } from '../mcp.routes.js';
|
|
14
14
|
import { McpService } from '../mcp.service.js';
|
|
15
|
-
import { SpillStore } from '../../workspace/
|
|
16
|
-
import { createManualRoutes } from '../../tool-registry/
|
|
17
|
-
import {
|
|
18
|
-
import { toolDef } from '../../tool-helpers/tool-def.js';
|
|
15
|
+
import { SpillStore } from '../../workspace/index.js';
|
|
16
|
+
import { ToolRegistry, createManualRoutes } from '../../tool-registry/index.js';
|
|
17
|
+
import { toolDef } from '../../tool-helpers/index.js';
|
|
19
18
|
import { DEFAULT_KB_LAYOUT } from '@bevel-software/platform-shared';
|
|
20
19
|
import { platformInstructions } from '../../agent-instructions/index.js';
|
|
21
20
|
import { startFakeDownstreamMcpServer, type FakeDownstreamMcpServer } from './fake-downstream-mcp-server.js';
|
|
22
|
-
import { registerBevelSecretsVariableLoader } from '../../secrets-vault/
|
|
23
|
-
import type { ForcedRefreshOutcome, ISecretsVaultService } from '../../secrets-vault/
|
|
24
|
-
import type { IToolManualService } from '../../tool-manuals/
|
|
21
|
+
import { registerBevelSecretsVariableLoader } from '../../secrets-vault/index.js';
|
|
22
|
+
import type { ForcedRefreshOutcome, ISecretsVaultService } from '../../secrets-vault/index.js';
|
|
23
|
+
import type { IToolManualService } from '../../tool-manuals/index.js';
|
|
25
24
|
import { setLogger } from '../../../shared/logging.js';
|
|
26
25
|
import type { ILogger } from '../../../shared/logger.contract.js';
|
|
27
26
|
import { formatProbeReport, probeFirstCall } from '../first-call-probe.js';
|
|
@@ -117,6 +116,8 @@ interface PlatformOptions {
|
|
|
117
116
|
/** Bind this port — how a "restarted" platform comes back at the same address. */
|
|
118
117
|
port?: number;
|
|
119
118
|
readAgentPreamble?: () => Promise<string | null>;
|
|
119
|
+
/** The default branch the instructions name, read per request as the composition root wires it. */
|
|
120
|
+
defaultBranch?: () => string;
|
|
120
121
|
/** Extra manuals the catalog serves each caller (beyond the KB manual). */
|
|
121
122
|
manualsFor?: (bearer: string) => unknown[];
|
|
122
123
|
poolNow?: () => number;
|
|
@@ -185,6 +186,7 @@ async function startPlatform(opts: PlatformOptions = {}): Promise<Platform> {
|
|
|
185
186
|
spillStore: new SpillStore(join(tmpdir(), 'bevel-test-spills')),
|
|
186
187
|
publicFrontendUrl: 'http://localhost:5173',
|
|
187
188
|
readAgentPreamble: opts.readAgentPreamble,
|
|
189
|
+
defaultBranch: opts.defaultBranch,
|
|
188
190
|
downstreamPool: opts.poolNow ? { now: opts.poolNow } : undefined,
|
|
189
191
|
}, opts.secretsVault, opts.toolManuals);
|
|
190
192
|
const stub = {} as never;
|
|
@@ -487,11 +489,28 @@ describe('agent instructions over the real transport', () => {
|
|
|
487
489
|
it('the initialize result carries the platform text and the preamble body inline', async () => {
|
|
488
490
|
const { baseUrl } = await startPlatform({
|
|
489
491
|
readAgentPreamble: async () => 'Acme builds solar farms.\n\n<!-- private -->Look in Projects/ first.',
|
|
492
|
+
defaultBranch: () => 'target-company-state',
|
|
490
493
|
});
|
|
491
494
|
const { client } = await connectSdkClient(baseUrl);
|
|
492
495
|
const instructions = client.getInstructions();
|
|
493
|
-
expect(instructions).toBe(
|
|
496
|
+
expect(instructions).toBe(
|
|
497
|
+
`${platformInstructions(DEFAULT_KB_LAYOUT, 'target-company-state')}\n\nAcme builds solar farms.\n\nLook in Projects/ first.`,
|
|
498
|
+
);
|
|
494
499
|
expect(instructions).not.toContain('private');
|
|
500
|
+
// The deployment's default branch, by its own name — not `main`.
|
|
501
|
+
expect(instructions).toContain("This knowledge base's default branch is `target-company-state`");
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
it('a default branch renamed between two initializes is the one the second names', async () => {
|
|
505
|
+
let branch = 'target-company-state';
|
|
506
|
+
const { baseUrl } = await startPlatform({ defaultBranch: () => branch });
|
|
507
|
+
const { client: before } = await connectSdkClient(baseUrl);
|
|
508
|
+
branch = 'company-state';
|
|
509
|
+
const { client: after } = await connectSdkClient(baseUrl);
|
|
510
|
+
expect(after.getInstructions()).toContain("This knowledge base's default branch is `company-state`");
|
|
511
|
+
expect(after.getInstructions()).not.toContain('target-company-state');
|
|
512
|
+
// Nothing else moved: the text is the old one with the name swapped.
|
|
513
|
+
expect(after.getInstructions()).toBe(before.getInstructions()!.replaceAll('target-company-state', 'company-state'));
|
|
495
514
|
});
|
|
496
515
|
|
|
497
516
|
it('a later initialize on the SAME process after the file changed carries the new text — read per request', async () => {
|
|
@@ -651,6 +670,7 @@ describe('proxied third-party MCP servers: a rejected token gets one refresh and
|
|
|
651
670
|
} as unknown as ISecretsVaultService;
|
|
652
671
|
registerBevelSecretsVariableLoader(vault);
|
|
653
672
|
const toolManuals = {
|
|
673
|
+
sharedSignInKeysForManual: async () => [],
|
|
654
674
|
userScopedKeysForManual: async (manual: string) =>
|
|
655
675
|
manual === 'notion' ? [{ key: KEY, name: 'ACCESS_TOKEN', label: 'Notion sign-in', oauth: true }] : [],
|
|
656
676
|
} as unknown as IToolManualService;
|
|
@@ -770,6 +790,45 @@ describe('proxied third-party MCP servers: a rejected token gets one refresh and
|
|
|
770
790
|
expect(refreshLines(logs)[0]).toContain('manual=\\"notion\\" user=\\"user-A\\" outcome=rejected');
|
|
771
791
|
});
|
|
772
792
|
|
|
793
|
+
it('a WORKSPACE connection rejected on refresh tells the caller a tool owner has to reconnect it, and does not retry', async () => {
|
|
794
|
+
quiet();
|
|
795
|
+
let valid = 'token-1';
|
|
796
|
+
downstream = await startFakeDownstreamMcpServer({ acceptsToken: (t) => t === valid });
|
|
797
|
+
// The same sign-in, declared as one shared connection: the manual reports
|
|
798
|
+
// it under `sharedSignInKeysForManual`, the vault under the owner's row.
|
|
799
|
+
const state = { token: 'token-1' as string | null, refreshes: 0 };
|
|
800
|
+
const vault = {
|
|
801
|
+
resolve: async (_userId: string, key: string) => (key === KEY ? state.token : null),
|
|
802
|
+
statusFor: async (_userId: string, keys: string[]) =>
|
|
803
|
+
keys.map((key) => ({ key, adminConfigured: true, adminKind: 'oauth', userConfigured: false, adminAuthorized: state.token !== null })),
|
|
804
|
+
forceRefresh: async (_userId: string, key: string) => {
|
|
805
|
+
expect(key).toBe(KEY);
|
|
806
|
+
state.refreshes += 1;
|
|
807
|
+
state.token = null;
|
|
808
|
+
return 'rejected' as const;
|
|
809
|
+
},
|
|
810
|
+
} as unknown as ISecretsVaultService;
|
|
811
|
+
registerBevelSecretsVariableLoader(vault);
|
|
812
|
+
const toolManuals = {
|
|
813
|
+
sharedSignInKeysForManual: async (manual: string) =>
|
|
814
|
+
manual === 'notion' ? [{ key: KEY, name: 'ACCESS_TOKEN', label: 'Notion sign-in' }] : [],
|
|
815
|
+
userScopedKeysForManual: async () => [],
|
|
816
|
+
} as unknown as IToolManualService;
|
|
817
|
+
const { baseUrl } = await startPlatform({ manualsFor: notionManual(downstream), secretsVault: vault, toolManuals });
|
|
818
|
+
const { client } = await connectSdkClient(baseUrl);
|
|
819
|
+
await client.callTool({ name: 'notion_srv_echo', arguments: { text: 'one' } });
|
|
820
|
+
|
|
821
|
+
valid = 'nothing-valid-any-more';
|
|
822
|
+
|
|
823
|
+
const res = await client.callTool({ name: 'notion_srv_echo', arguments: { text: 'two' } });
|
|
824
|
+
expect(res.isError).toBe(true);
|
|
825
|
+
expect(toolText(res)).toContain('The workspace connection for "notion" was rejected by the provider and has been disconnected');
|
|
826
|
+
expect(toolText(res)).toContain('A tool owner has to reconnect it on http://localhost:5173/connect');
|
|
827
|
+
expect(toolText(res)).not.toContain('Your sign-in');
|
|
828
|
+
expect(state.refreshes).toBe(1);
|
|
829
|
+
expect(downstream.executions()).toBe(1); // nothing was retried against a dead workspace grant
|
|
830
|
+
});
|
|
831
|
+
|
|
773
832
|
it('transient refresh failure: the original error comes back, the token is kept, and a later call tries again', async () => {
|
|
774
833
|
quiet();
|
|
775
834
|
let now = 1_000_000;
|
|
@@ -940,6 +999,7 @@ describe('proxied third-party MCP servers: a rejected token gets one refresh and
|
|
|
940
999
|
const { state, vault } = fakeSignIn('token-1', () => 'refreshed');
|
|
941
1000
|
const boom = new Error('catalog read failed\u009b31m\nerror: forged by the manual name\u2028tail');
|
|
942
1001
|
const toolManuals = {
|
|
1002
|
+
sharedSignInKeysForManual: async () => [],
|
|
943
1003
|
userScopedKeysForManual: async (manual: string) => {
|
|
944
1004
|
if (broken) throw boom;
|
|
945
1005
|
return manual === 'notion' ? [{ key: KEY, name: 'ACCESS_TOKEN', label: 'Notion sign-in', oauth: true }] : [];
|
|
@@ -1061,6 +1121,7 @@ describe('proxied third-party MCP servers: a rejected token gets one refresh and
|
|
|
1061
1121
|
} as unknown as ISecretsVaultService;
|
|
1062
1122
|
registerBevelSecretsVariableLoader(withKind);
|
|
1063
1123
|
const toolManuals = {
|
|
1124
|
+
sharedSignInKeysForManual: async () => [],
|
|
1064
1125
|
userScopedKeysForManual: async (manual: string) =>
|
|
1065
1126
|
manual === 'notion' ? [{ key: KEY, name: 'ACCESS_TOKEN', label: 'Notion key', oauth: false }] : [],
|
|
1066
1127
|
} as unknown as IToolManualService;
|
|
@@ -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
|
+
});
|