@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
|
@@ -42,6 +42,8 @@ import {
|
|
|
42
42
|
retiredToolMessage,
|
|
43
43
|
needsAuthorizationResult,
|
|
44
44
|
skillPromptText,
|
|
45
|
+
ONBOARD_PROMPT,
|
|
46
|
+
promptsForSkills,
|
|
45
47
|
toListedResource,
|
|
46
48
|
toReadResourceResult,
|
|
47
49
|
type McpAppManifest,
|
|
@@ -50,7 +52,7 @@ import {
|
|
|
50
52
|
type LoadedSkill,
|
|
51
53
|
} from '@bevel-software/platform-mcp-core';
|
|
52
54
|
import type { KbLayout } from '@bevel-software/platform-shared';
|
|
53
|
-
import { bevelSecretsLoaderConfig, type ForcedRefreshOutcome, type ISecretsVaultService, userSecretGap } from '../secrets-vault/index.js';
|
|
55
|
+
import { bevelSecretsLoaderConfig, type ForcedRefreshOutcome, type ISecretsVaultService, scopesCovered, userSecretGap } from '../secrets-vault/index.js';
|
|
54
56
|
import { EXTERNAL_KB_MANUAL_NAME } from '../tool-manuals/index.js';
|
|
55
57
|
import type { IToolManualService } from '../tool-manuals/index.js';
|
|
56
58
|
import type { SpillStore } from '../workspace/index.js';
|
|
@@ -109,12 +111,19 @@ export interface McpProxyOptions {
|
|
|
109
111
|
*/
|
|
110
112
|
readAgentPreamble?: AgentPreambleReader;
|
|
111
113
|
/**
|
|
112
|
-
* The layout in effect, read per request: the shared file rules
|
|
113
|
-
*
|
|
114
|
-
* a layout without a restart. A GETTER, so nothing
|
|
115
|
-
* pre-setup default. Absent, the rules
|
|
114
|
+
* The layout in effect, read per request: the shared file rules spell the
|
|
115
|
+
* root folders and platform files by the names a deployment saved, and the
|
|
116
|
+
* setup save applies a layout without a restart. A GETTER, so nothing
|
|
117
|
+
* snapshots the pre-setup default. Absent, the rules use the default
|
|
118
|
+
* layout. The guide is `AGENTS.md` either way.
|
|
116
119
|
*/
|
|
117
120
|
kbLayout?: () => KbLayout;
|
|
121
|
+
/**
|
|
122
|
+
* The default branch in effect, read per request: the shared file rules
|
|
123
|
+
* name it as the branch people read. A GETTER for the same reason as the
|
|
124
|
+
* layout. Absent, the rules name no branch.
|
|
125
|
+
*/
|
|
126
|
+
defaultBranch?: () => string;
|
|
118
127
|
/** Bounds of the downstream (`mcp.json`) connection pool; defaults are 4h idle / 5000 entries. */
|
|
119
128
|
downstreamPool?: Pick<DownstreamPoolOptions<unknown>, 'idleTtlMs' | 'maxEntries' | 'now'>;
|
|
120
129
|
/**
|
|
@@ -378,7 +387,7 @@ export class McpService {
|
|
|
378
387
|
private readonly manualFailures = new ManualFailureMemo();
|
|
379
388
|
private readonly surfaceLog = new SurfaceLogThrottle();
|
|
380
389
|
// One forced token refresh per (user, manual) per minute — see downstream-token-refresh.
|
|
381
|
-
private readonly tokenRefreshes: DownstreamRefreshGuard<ForcedRefreshOutcome>;
|
|
390
|
+
private readonly tokenRefreshes: DownstreamRefreshGuard<ForcedRefreshOutcome | 'rejected-shared'>;
|
|
382
391
|
/**
|
|
383
392
|
* The tools each pooled manual last advertised, by manual definition. A
|
|
384
393
|
* downstream can only be asked what its tools are over a connection, and a
|
|
@@ -859,17 +868,32 @@ export class McpService {
|
|
|
859
868
|
// loopback with the caller's key — so the default-branch catalog, access
|
|
860
869
|
// filtering, and progressive disclosure all live ONCE behind that REST
|
|
861
870
|
// surface, never duplicated here. Neither handler needs the tool catalog.
|
|
871
|
+
// The one prompt that is not a skill is the platform's `onboard`, offered
|
|
872
|
+
// only on a connection not narrowed to an agent, and only while no skill
|
|
873
|
+
// takes its name (see `promptsForSkills`).
|
|
874
|
+
const offerOnboard = agentPath === null;
|
|
862
875
|
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
863
876
|
const skills = await this.fetchSkillList(loopbackBearer);
|
|
864
|
-
const prompts: Prompt[] = skills
|
|
865
|
-
name: s.name,
|
|
866
|
-
description: s.description,
|
|
867
|
-
arguments: [],
|
|
868
|
-
}));
|
|
877
|
+
const prompts: Prompt[] = promptsForSkills(skills, offerOnboard);
|
|
869
878
|
return { prompts };
|
|
870
879
|
});
|
|
871
880
|
|
|
872
881
|
server.setRequestHandler(GetPromptRequestSchema, async (request): Promise<GetPromptResult> => {
|
|
882
|
+
// The platform's own prompt is served exactly when `prompts/list`
|
|
883
|
+
// offered it: the connection is not narrowed and no released skill
|
|
884
|
+
// takes the name — judged on the skill LIST, the same answer the
|
|
885
|
+
// listing used, never on a read that failed. A workspace's own
|
|
886
|
+
// `onboard` skill is then read like any other prompt, and a read that
|
|
887
|
+
// fails is a failed read, not a reason to serve the platform's text.
|
|
888
|
+
if (offerOnboard && request.params.name === ONBOARD_PROMPT.name) {
|
|
889
|
+
const released = await this.fetchSkillList(loopbackBearer);
|
|
890
|
+
if (!released.some((s) => s.name === ONBOARD_PROMPT.name)) {
|
|
891
|
+
return {
|
|
892
|
+
description: ONBOARD_PROMPT.description,
|
|
893
|
+
messages: [{ role: 'user', content: { type: 'text', text: ONBOARD_PROMPT.text } }],
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
}
|
|
873
897
|
const started = performance.now();
|
|
874
898
|
const skill = await this.fetchSkill(loopbackBearer, request.params.name);
|
|
875
899
|
// A prompt IS a skill read — the same event `get_skill` produces.
|
|
@@ -1059,13 +1083,14 @@ export class McpService {
|
|
|
1059
1083
|
*/
|
|
1060
1084
|
private async composeAgentInstructions(): Promise<ComposedAgentInstructions> {
|
|
1061
1085
|
const layout = this.opts.kbLayout?.();
|
|
1086
|
+
const defaultBranch = this.opts.defaultBranch?.();
|
|
1062
1087
|
const read = this.opts.readAgentPreamble;
|
|
1063
|
-
if (!read) return composeAgentInstructions(null, layout);
|
|
1088
|
+
if (!read) return composeAgentInstructions(null, layout, defaultBranch);
|
|
1064
1089
|
try {
|
|
1065
|
-
return composeAgentInstructions(await read(), layout);
|
|
1090
|
+
return composeAgentInstructions(await read(), layout, defaultBranch);
|
|
1066
1091
|
} catch (err) {
|
|
1067
1092
|
log.warn('could not read mcp-description.md; this request gets the platform text alone:', { err });
|
|
1068
|
-
return composeAgentInstructions(null, layout);
|
|
1093
|
+
return composeAgentInstructions(null, layout, defaultBranch);
|
|
1069
1094
|
}
|
|
1070
1095
|
}
|
|
1071
1096
|
|
|
@@ -1559,7 +1584,7 @@ export class McpService {
|
|
|
1559
1584
|
this.downstream.evictWhere((k) => k === poolKey);
|
|
1560
1585
|
return { retry: true };
|
|
1561
1586
|
}
|
|
1562
|
-
if (outcome === 'rejected') {
|
|
1587
|
+
if (outcome === 'rejected' || outcome === 'rejected-shared') {
|
|
1563
1588
|
// The connection was dialed with a grant that no longer exists; the
|
|
1564
1589
|
// vault's mutation signal drops it too, this keeps the next request
|
|
1565
1590
|
// honest whether or not that is wired.
|
|
@@ -1568,8 +1593,11 @@ export class McpService {
|
|
|
1568
1593
|
retry: false,
|
|
1569
1594
|
credentialTransient: false,
|
|
1570
1595
|
error: new Error(
|
|
1571
|
-
|
|
1572
|
-
`
|
|
1596
|
+
outcome === 'rejected-shared'
|
|
1597
|
+
? `The workspace connection for "${manualName}" was rejected by the provider and has been disconnected. ` +
|
|
1598
|
+
`A tool owner has to reconnect it on ${this.opts.publicFrontendUrl}/connect; then run the tool again.`
|
|
1599
|
+
: `Your sign-in for "${manualName}" was rejected and has been disconnected. ` +
|
|
1600
|
+
`Re-authorize it on ${this.opts.publicFrontendUrl}/connect, then run the tool again.`,
|
|
1573
1601
|
),
|
|
1574
1602
|
};
|
|
1575
1603
|
}
|
|
@@ -1596,12 +1624,21 @@ export class McpService {
|
|
|
1596
1624
|
private async refreshDownstreamToken(
|
|
1597
1625
|
userId: string,
|
|
1598
1626
|
manualName: string,
|
|
1599
|
-
): Promise<ForcedRefreshOutcome | 'guarded' | undefined> {
|
|
1627
|
+
): Promise<ForcedRefreshOutcome | 'rejected-shared' | 'guarded' | undefined> {
|
|
1600
1628
|
const vault = this.secretsVault;
|
|
1601
1629
|
if (!vault || !this.toolManuals || !manualName) return undefined;
|
|
1602
1630
|
let keys: string[];
|
|
1631
|
+
let sharedKeys = new Set<string>();
|
|
1603
1632
|
try {
|
|
1604
|
-
|
|
1633
|
+
// Every sign-in the manual declares: the caller's own, and a workspace
|
|
1634
|
+
// connection every caller resolves (the vault's forceRefresh reads the
|
|
1635
|
+
// shared row for an admin-scoped key, as resolve does).
|
|
1636
|
+
const [own, shared] = await Promise.all([
|
|
1637
|
+
this.toolManuals.userScopedKeysForManual(manualName),
|
|
1638
|
+
this.toolManuals.sharedSignInKeysForManual(manualName),
|
|
1639
|
+
]);
|
|
1640
|
+
keys = [...own.filter((v) => v.oauth).map((v) => v.key), ...shared.map((v) => v.key)];
|
|
1641
|
+
sharedKeys = new Set(shared.map((v) => v.key));
|
|
1605
1642
|
} catch (err) {
|
|
1606
1643
|
// The error's own message is caller-controlled as well (it quotes the
|
|
1607
1644
|
// manual, and may quote a provider's reply), and a raw Error handed to
|
|
@@ -1616,12 +1653,20 @@ export class McpService {
|
|
|
1616
1653
|
if (keys.length === 0) return undefined;
|
|
1617
1654
|
const attempt = this.tokenRefreshes.run(`${userId}${POOL_KEY_SEPARATOR}${manualName}`, async () => {
|
|
1618
1655
|
const outcomes: ForcedRefreshOutcome[] = [];
|
|
1656
|
+
// A dead WORKSPACE connection is told apart from a dead personal one:
|
|
1657
|
+
// the caller cannot repair it, a writer of the tool can, and the words
|
|
1658
|
+
// the caller gets have to say so.
|
|
1659
|
+
let rejectedShared = false;
|
|
1619
1660
|
for (const key of keys) {
|
|
1620
1661
|
// A vault fault is not a verdict on the grant: keep the token, try later.
|
|
1621
|
-
|
|
1662
|
+
const result = await vault.forceRefresh(userId, key).catch((): ForcedRefreshOutcome => 'transient');
|
|
1663
|
+
if (result === 'rejected' && sharedKeys.has(key)) rejectedShared = true;
|
|
1664
|
+
outcomes.push(result);
|
|
1622
1665
|
}
|
|
1623
|
-
const outcome: ForcedRefreshOutcome = outcomes.includes('rejected')
|
|
1624
|
-
?
|
|
1666
|
+
const outcome: ForcedRefreshOutcome | 'rejected-shared' = outcomes.includes('rejected')
|
|
1667
|
+
? rejectedShared
|
|
1668
|
+
? 'rejected-shared'
|
|
1669
|
+
: 'rejected'
|
|
1625
1670
|
: outcomes.includes('transient')
|
|
1626
1671
|
? 'transient'
|
|
1627
1672
|
: outcomes.includes('refreshed')
|
|
@@ -1681,14 +1726,30 @@ export class McpService {
|
|
|
1681
1726
|
manualName: string,
|
|
1682
1727
|
): Promise<{ name: string; label?: string | null; brokenSignIn: boolean }[]> {
|
|
1683
1728
|
if (!this.secretsVault || !this.toolManuals || !manualName) return [];
|
|
1684
|
-
const userVars = await
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1729
|
+
const [userVars, sharedSignIns] = await Promise.all([
|
|
1730
|
+
this.toolManuals.userScopedKeysForManual(manualName),
|
|
1731
|
+
this.toolManuals.sharedSignInKeysForManual(manualName),
|
|
1732
|
+
]);
|
|
1733
|
+
if (userVars.length === 0 && sharedSignIns.length === 0) return [];
|
|
1734
|
+
const status = await this.secretsVault.statusFor(userId, [
|
|
1735
|
+
...userVars.map((v) => v.key),
|
|
1736
|
+
...sharedSignIns.map((v) => v.key),
|
|
1737
|
+
]);
|
|
1690
1738
|
const statusMap = new Map(status.map((s) => [s.key, s]));
|
|
1691
1739
|
const missing: { name: string; label?: string | null; brokenSignIn: boolean }[] = [];
|
|
1740
|
+
// A WORKSPACE sign-in (a managed connector enabled as one shared
|
|
1741
|
+
// connection) is nobody's personal credential, but a tool whose one
|
|
1742
|
+
// connection has not been made — or no longer covers what the tool
|
|
1743
|
+
// declares — fails just as opaquely at the provider. Reported like a
|
|
1744
|
+
// personal one, with words that say whose job it is; never a "broken
|
|
1745
|
+
// sign-in" of the caller's, since there is nothing of theirs to reset.
|
|
1746
|
+
for (const v of sharedSignIns) {
|
|
1747
|
+
const st = statusMap.get(v.key);
|
|
1748
|
+
const connected = st?.adminAuthorized === true && scopesCovered(v.oauthScopes, st.adminGrantedScopes);
|
|
1749
|
+
if (!connected) {
|
|
1750
|
+
missing.push({ name: v.name, label: `${v.label ?? v.name} (a tool owner connects this for the workspace)`, brokenSignIn: false });
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1692
1753
|
for (const v of userVars) {
|
|
1693
1754
|
// The one readiness rule `list_tool_setup` reports from (`userSecretGap`).
|
|
1694
1755
|
// A sign-in the caller already HAS a row for but that isn't (or is no
|
|
@@ -2,10 +2,10 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
import { DEFAULT_KB_LAYOUT, type AuthUser, type
|
|
5
|
+
import { DEFAULT_KB_LAYOUT, type AuthUser, type IVersionControlService, type KbLayout } from '@bevel-software/platform-shared';
|
|
6
6
|
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
7
|
-
import {
|
|
8
|
-
import { WorkspaceMutex } from '../../kb-fs/
|
|
7
|
+
import { realDisk } from '../../../__tests__/real-disk.js';
|
|
8
|
+
import { WorkspaceMutex } from '../../kb-fs/index.js';
|
|
9
9
|
import { KbPluginSource } from '../../plugins/index.js';
|
|
10
10
|
import { CLAIM_TTL_MS, StarterPackError, StarterPackService, commitSubjectOf, summaryOf } from '../starter-pack.service.js';
|
|
11
11
|
|
|
@@ -70,7 +70,7 @@ function harness({
|
|
|
70
70
|
return locks.runAll(keys, fn);
|
|
71
71
|
},
|
|
72
72
|
};
|
|
73
|
-
const
|
|
73
|
+
const versionControl = {
|
|
74
74
|
acquireLock: vi.fn(async () => ({ acquired: true, lock: { holderName: 'x' } })),
|
|
75
75
|
releaseLock: vi.fn(async () => null),
|
|
76
76
|
releaseLockNoCommit: vi.fn(async () => undefined),
|
|
@@ -92,22 +92,22 @@ function harness({
|
|
|
92
92
|
const svc = new StarterPackService({
|
|
93
93
|
packsDir,
|
|
94
94
|
kb,
|
|
95
|
-
disk:
|
|
96
|
-
pluginSource: new KbPluginSource(
|
|
95
|
+
disk: realDisk(),
|
|
96
|
+
pluginSource: new KbPluginSource(realDisk(), kb),
|
|
97
97
|
pluginLocks,
|
|
98
98
|
workspaceService: {
|
|
99
99
|
getOrCreateForBranch: vi.fn(async () => ({ id: 'ws-main' })),
|
|
100
100
|
getWorkspacePath: vi.fn(async () => wsDir),
|
|
101
101
|
hasBootstrappedWorkspace: vi.fn(async () => true),
|
|
102
102
|
} as never,
|
|
103
|
-
|
|
103
|
+
versionControl: versionControl as unknown as IVersionControlService,
|
|
104
104
|
adminAccess: { isAdmin: async (email) => admins.includes(email ?? '') },
|
|
105
105
|
settings: settings as never,
|
|
106
106
|
accessControl,
|
|
107
107
|
events,
|
|
108
108
|
choosing: new WorkspaceMutex(),
|
|
109
109
|
});
|
|
110
|
-
return { svc, store, settings, locks, lockRequests,
|
|
110
|
+
return { svc, store, settings, locks, lockRequests, versionControl, events, accessControl, unreadable };
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
beforeEach(async () => {
|
|
@@ -195,7 +195,7 @@ describe('who is asked', () => {
|
|
|
195
195
|
|
|
196
196
|
describe('choosing a pack', () => {
|
|
197
197
|
it('adds the pack in ONE commit by the admin, records the choice, and refreshes the tree', async () => {
|
|
198
|
-
const { svc, store, settings,
|
|
198
|
+
const { svc, store, settings, versionControl, events, accessControl } = harness();
|
|
199
199
|
|
|
200
200
|
const applied = await svc.choose(ADMIN, 'sales');
|
|
201
201
|
|
|
@@ -203,17 +203,17 @@ describe('choosing a pack', () => {
|
|
|
203
203
|
// nothing is written twice; it is released once the choice is recorded.
|
|
204
204
|
expect(settings.recordIfAbsent).toHaveBeenCalledWith('starterPackClaim', expect.stringMatching(/^u-admin \d+$/), ADMIN.id);
|
|
205
205
|
expect(settings.recordIfAbsent.mock.invocationCallOrder[0]!).toBeLessThan(
|
|
206
|
-
|
|
206
|
+
versionControl.commitChanges.mock.invocationCallOrder[0]!,
|
|
207
207
|
);
|
|
208
208
|
// The answer is recorded after the commit, and only where none is.
|
|
209
209
|
const answered = settings.recordIfAbsent.mock.calls.findIndex(([key]) => key === 'starterPack');
|
|
210
|
-
expect(settings.recordIfAbsent.mock.invocationCallOrder[answered]!).toBeGreaterThan(
|
|
210
|
+
expect(settings.recordIfAbsent.mock.invocationCallOrder[answered]!).toBeGreaterThan(versionControl.commitChanges.mock.invocationCallOrder[0]!);
|
|
211
211
|
expect(settings.record).not.toHaveBeenCalled();
|
|
212
212
|
expect(store.starterPackClaim).toBeUndefined();
|
|
213
213
|
|
|
214
214
|
expect(applied).toEqual({ id: 'sales', name: 'Sales', pages: 2, skills: 2, summary: 'Added 2 pages and 2 skills for Sales.' });
|
|
215
|
-
expect(
|
|
216
|
-
const [wsId, author, subject, paths] =
|
|
215
|
+
expect(versionControl.commitChanges).toHaveBeenCalledTimes(1);
|
|
216
|
+
const [wsId, author, subject, paths] = versionControl.commitChanges.mock.calls[0] as unknown as [string, AuthUser, string, string[]];
|
|
217
217
|
expect([wsId, author, subject]).toEqual(['ws-main', ADMIN, 'Add starter pages and skills for Sales']);
|
|
218
218
|
expect(paths).toEqual([
|
|
219
219
|
`${KB}/KnowledgeBase/About us.md`,
|
|
@@ -255,9 +255,9 @@ describe('choosing a pack', () => {
|
|
|
255
255
|
});
|
|
256
256
|
|
|
257
257
|
it('writes only what is absent: a page made meanwhile is never replaced', async () => {
|
|
258
|
-
const { svc,
|
|
258
|
+
const { svc, versionControl } = harness();
|
|
259
259
|
// Between the question and the locks, someone writes About us.
|
|
260
|
-
|
|
260
|
+
versionControl.acquireLock.mockImplementationOnce(async () => {
|
|
261
261
|
await put(wsDir, `${KB}/KnowledgeBase/About us.md`, '# Ours\n');
|
|
262
262
|
return { acquired: true, lock: { holderName: 'x' } };
|
|
263
263
|
});
|
|
@@ -265,18 +265,18 @@ describe('choosing a pack', () => {
|
|
|
265
265
|
const applied = await svc.choose(ADMIN, 'sales');
|
|
266
266
|
|
|
267
267
|
expect(await fs.readFile(path.join(wsDir, KB, 'KnowledgeBase/About us.md'), 'utf8')).toBe('# Ours\n');
|
|
268
|
-
const paths = (
|
|
268
|
+
const paths = (versionControl.commitChanges.mock.calls[0] as unknown as [string, AuthUser, string, string[]])[3];
|
|
269
269
|
expect(paths).not.toContain(`${KB}/KnowledgeBase/About us.md`);
|
|
270
270
|
expect(applied.pages).toBe(1);
|
|
271
271
|
});
|
|
272
272
|
|
|
273
273
|
it('leaves a plugin that is already there alone, files and rules', async () => {
|
|
274
274
|
await put(wsDir, `${KB}/Plugins/Sales-Starter/access.md`, '# theirs\n');
|
|
275
|
-
const { svc,
|
|
275
|
+
const { svc, versionControl } = harness();
|
|
276
276
|
|
|
277
277
|
const applied = await svc.choose(ADMIN, 'sales');
|
|
278
278
|
|
|
279
|
-
const paths = (
|
|
279
|
+
const paths = (versionControl.commitChanges.mock.calls[0] as unknown as [string, AuthUser, string, string[]])[3];
|
|
280
280
|
expect(paths.filter((p) => p.includes('/Plugins/'))).toEqual([]);
|
|
281
281
|
expect(applied).toMatchObject({ pages: 2, skills: 0 });
|
|
282
282
|
});
|
|
@@ -285,11 +285,11 @@ describe('choosing a pack', () => {
|
|
|
285
285
|
// Not at the plugins root: discovery lists it, a folder listing would not.
|
|
286
286
|
await put(wsDir, `${KB}/Plugins/teams/Sales Starter/plugin.json`, '{"name":"sales-starter"}\n');
|
|
287
287
|
await put(wsDir, `${KB}/Plugins/teams/Sales Starter/access.md`, '# theirs\n');
|
|
288
|
-
const { svc,
|
|
288
|
+
const { svc, versionControl } = harness();
|
|
289
289
|
|
|
290
290
|
const applied = await svc.choose(ADMIN, 'sales');
|
|
291
291
|
|
|
292
|
-
const paths = (
|
|
292
|
+
const paths = (versionControl.commitChanges.mock.calls[0] as unknown as [string, AuthUser, string, string[]])[3];
|
|
293
293
|
expect(paths.filter((p) => p.includes('/Plugins/'))).toEqual([]);
|
|
294
294
|
expect(applied).toMatchObject({ pages: 2, skills: 0 });
|
|
295
295
|
});
|
|
@@ -297,39 +297,39 @@ describe('choosing a pack', () => {
|
|
|
297
297
|
it('writes under the folder names this deployment chose', async () => {
|
|
298
298
|
await fs.rm(path.join(wsDir, KB), { recursive: true });
|
|
299
299
|
await put(wsDir, `${KB}/Wiki/How to get started.md`, '# How to get started\n');
|
|
300
|
-
const { svc,
|
|
300
|
+
const { svc, versionControl } = harness({ layout: { ...DEFAULT_KB_LAYOUT, knowledgeBaseDir: 'Wiki', pluginsDir: 'Teams' } });
|
|
301
301
|
|
|
302
302
|
await svc.choose(ADMIN, 'sales');
|
|
303
303
|
|
|
304
|
-
const paths = (
|
|
304
|
+
const paths = (versionControl.commitChanges.mock.calls[0] as unknown as [string, AuthUser, string, string[]])[3];
|
|
305
305
|
expect(paths).toContain(`${KB}/Wiki/About us.md`);
|
|
306
306
|
expect(paths).toContain(`${KB}/Teams/sales-starter/skills/forecast/SKILL.md`);
|
|
307
307
|
expect(paths.some((p) => p.includes('KnowledgeBase/') || p.includes('/Plugins/'))).toBe(false);
|
|
308
308
|
});
|
|
309
309
|
|
|
310
310
|
it('skipping records "none" and writes nothing', async () => {
|
|
311
|
-
const { svc, store,
|
|
311
|
+
const { svc, store, versionControl } = harness();
|
|
312
312
|
|
|
313
313
|
expect(await svc.choose(ADMIN, 'none')).toEqual({ id: 'none', name: null, pages: 0, skills: 0, summary: '' });
|
|
314
314
|
expect(store.starterPack).toBe('none');
|
|
315
|
-
expect(
|
|
315
|
+
expect(versionControl.commitChanges).not.toHaveBeenCalled();
|
|
316
316
|
});
|
|
317
317
|
|
|
318
318
|
it('is asked once: a second choice is 409, and so is one on a knowledge base with pages', async () => {
|
|
319
|
-
const { svc,
|
|
319
|
+
const { svc, versionControl } = harness();
|
|
320
320
|
await svc.choose(ADMIN, 'none');
|
|
321
321
|
await expect(svc.choose(ADMIN, 'sales')).rejects.toMatchObject({ status: 409 });
|
|
322
322
|
|
|
323
323
|
const fresh = harness();
|
|
324
324
|
await put(wsDir, `${KB}/KnowledgeBase/Ours.md`, '# Ours\n');
|
|
325
325
|
await expect(fresh.svc.choose(ADMIN, 'sales')).rejects.toMatchObject({ status: 409 });
|
|
326
|
-
expect(
|
|
327
|
-
expect(fresh.
|
|
326
|
+
expect(versionControl.commitChanges).not.toHaveBeenCalled();
|
|
327
|
+
expect(fresh.versionControl.commitChanges).not.toHaveBeenCalled();
|
|
328
328
|
});
|
|
329
329
|
|
|
330
330
|
it('judges the question under the claim: an answer recorded meanwhile is found, not written over', async () => {
|
|
331
331
|
const store: Record<string, string> = {};
|
|
332
|
-
const { svc, settings,
|
|
332
|
+
const { svc, settings, versionControl } = harness({ store });
|
|
333
333
|
// Another replica answered `none` and released while this call was on its way to its claim.
|
|
334
334
|
settings.recordIfAbsent.mockImplementationOnce(async (key: string, value: string) => {
|
|
335
335
|
store[key] = value;
|
|
@@ -340,16 +340,16 @@ describe('choosing a pack', () => {
|
|
|
340
340
|
expect(settings.recordIfAbsent.mock.invocationCallOrder[0]!).toBeLessThan(
|
|
341
341
|
settings.reload.mock.invocationCallOrder.find((_, i) => settings.reload.mock.calls[i]![0] === 'starterPack')!,
|
|
342
342
|
);
|
|
343
|
-
expect(
|
|
343
|
+
expect(versionControl.commitChanges).not.toHaveBeenCalled();
|
|
344
344
|
expect(store.starterPack).toBe('none');
|
|
345
345
|
expect(store.starterPackClaim).toBeUndefined();
|
|
346
346
|
});
|
|
347
347
|
|
|
348
348
|
it('two quick clicks add the pack once', async () => {
|
|
349
|
-
const { svc,
|
|
349
|
+
const { svc, versionControl } = harness();
|
|
350
350
|
const results = await Promise.allSettled([svc.choose(ADMIN, 'sales'), svc.choose(ADMIN, 'sales')]);
|
|
351
351
|
expect(results.map((r) => r.status).sort()).toEqual(['fulfilled', 'rejected']);
|
|
352
|
-
expect(
|
|
352
|
+
expect(versionControl.commitChanges).toHaveBeenCalledTimes(1);
|
|
353
353
|
});
|
|
354
354
|
|
|
355
355
|
it('two replicas choosing at once add the pack once: the second finds the first’s claim', async () => {
|
|
@@ -360,28 +360,28 @@ describe('choosing a pack', () => {
|
|
|
360
360
|
expect(results.map((r) => r.status).sort()).toEqual(['fulfilled', 'rejected']);
|
|
361
361
|
const refused = results.find((r) => r.status === 'rejected') as PromiseRejectedResult;
|
|
362
362
|
expect(refused.reason).toMatchObject({ status: 409 });
|
|
363
|
-
expect(one.
|
|
363
|
+
expect(one.versionControl.commitChanges.mock.calls.length + two.versionControl.commitChanges.mock.calls.length).toBe(1);
|
|
364
364
|
expect(store.starterPack).toBe('sales');
|
|
365
365
|
expect(store.starterPackClaim).toBeUndefined();
|
|
366
366
|
});
|
|
367
367
|
|
|
368
368
|
it('refuses while another admin’s claim is live, and takes over one left by a process that died', async () => {
|
|
369
369
|
const store: Record<string, string> = { starterPackClaim: `u-other ${Date.now()}` };
|
|
370
|
-
const { svc,
|
|
370
|
+
const { svc, versionControl } = harness({ store });
|
|
371
371
|
await expect(svc.choose(ADMIN, 'sales')).rejects.toMatchObject({ status: 409 });
|
|
372
372
|
await expect(svc.choose(ADMIN, 'sales')).rejects.toThrow(/being added right now/);
|
|
373
|
-
expect(
|
|
373
|
+
expect(versionControl.commitChanges).not.toHaveBeenCalled();
|
|
374
374
|
|
|
375
375
|
store.starterPackClaim = `u-other ${Date.now() - CLAIM_TTL_MS - 1}`;
|
|
376
376
|
await expect(svc.choose(ADMIN, 'sales')).resolves.toMatchObject({ id: 'sales' });
|
|
377
|
-
expect(
|
|
377
|
+
expect(versionControl.commitChanges).toHaveBeenCalledTimes(1);
|
|
378
378
|
expect(store.starterPack).toBe('sales');
|
|
379
379
|
});
|
|
380
380
|
|
|
381
381
|
it('takes over an expired claim by replacing THAT claim, so two replicas cannot both take it', async () => {
|
|
382
382
|
const stale = `u-other ${Date.now() - CLAIM_TTL_MS - 1}`;
|
|
383
383
|
const store: Record<string, string> = { starterPackClaim: stale };
|
|
384
|
-
const { svc, settings,
|
|
384
|
+
const { svc, settings, versionControl } = harness({ store });
|
|
385
385
|
// Another replica took the expired claim over between this one's read and its take-over.
|
|
386
386
|
settings.reload.mockImplementation(async (key: string) => {
|
|
387
387
|
const held = store[key] ?? '';
|
|
@@ -390,14 +390,14 @@ describe('choosing a pack', () => {
|
|
|
390
390
|
});
|
|
391
391
|
await expect(svc.choose(ADMIN, 'sales')).rejects.toThrow(/being added right now/);
|
|
392
392
|
expect(settings.swapIfValue).toHaveBeenCalledWith('starterPackClaim', stale, expect.stringMatching(/^u-admin /), ADMIN.id);
|
|
393
|
-
expect(
|
|
393
|
+
expect(versionControl.commitChanges).not.toHaveBeenCalled();
|
|
394
394
|
expect(store.starterPackClaim).toMatch(/^u-fast /);
|
|
395
395
|
});
|
|
396
396
|
|
|
397
397
|
it('claims an expired claim whose holder finished and released it meanwhile, rather than refusing', async () => {
|
|
398
398
|
const stale = `u-other ${Date.now() - CLAIM_TTL_MS - 1}`;
|
|
399
399
|
const store: Record<string, string> = { starterPackClaim: stale };
|
|
400
|
-
const { svc, settings,
|
|
400
|
+
const { svc, settings, versionControl } = harness({ store });
|
|
401
401
|
// Between this replica's read and its take-over, the holder finished and released: the row is gone.
|
|
402
402
|
settings.reload.mockImplementation(async (key: string) => {
|
|
403
403
|
const held = store[key] ?? '';
|
|
@@ -407,16 +407,16 @@ describe('choosing a pack', () => {
|
|
|
407
407
|
await expect(svc.choose(ADMIN, 'sales')).resolves.toMatchObject({ id: 'sales' });
|
|
408
408
|
// The refused first try, the one at the empty row — and the answer itself.
|
|
409
409
|
expect(settings.recordIfAbsent.mock.calls.map(([key]) => key)).toEqual(['starterPackClaim', 'starterPackClaim', 'starterPack']);
|
|
410
|
-
expect(
|
|
410
|
+
expect(versionControl.commitChanges).toHaveBeenCalledTimes(1);
|
|
411
411
|
expect(store.starterPack).toBe('sales');
|
|
412
412
|
});
|
|
413
413
|
|
|
414
414
|
it('releases only its own claim: one taken over after it expired is left to its new holder', async () => {
|
|
415
415
|
const store: Record<string, string> = {};
|
|
416
|
-
const { svc,
|
|
416
|
+
const { svc, versionControl } = harness({ store });
|
|
417
417
|
// While this write was failing — past the fence, in the commit — its
|
|
418
418
|
// claim expired and another replica took it over.
|
|
419
|
-
|
|
419
|
+
versionControl.commitChanges.mockImplementationOnce(async () => {
|
|
420
420
|
store.starterPackClaim = `u-other ${Date.now()}`;
|
|
421
421
|
throw new Error('disk full');
|
|
422
422
|
});
|
|
@@ -426,16 +426,16 @@ describe('choosing a pack', () => {
|
|
|
426
426
|
|
|
427
427
|
it('checks its claim at the last moment: one taken over mid-write adds nothing, and leaves the answer the new holder gave', async () => {
|
|
428
428
|
const store: Record<string, string> = {};
|
|
429
|
-
const { svc, settings,
|
|
429
|
+
const { svc, settings, versionControl } = harness({ store });
|
|
430
430
|
// The clone took longer than the claim lives; another replica took the
|
|
431
431
|
// claim over and answered `none` while this one was taking its locks.
|
|
432
|
-
|
|
432
|
+
versionControl.acquireLock.mockImplementationOnce(async () => {
|
|
433
433
|
store.starterPackClaim = 'u-other 1';
|
|
434
434
|
store.starterPack = 'none';
|
|
435
435
|
return { acquired: true, lock: { holderName: 'x' } };
|
|
436
436
|
});
|
|
437
437
|
await expect(svc.choose(ADMIN, 'sales')).rejects.toMatchObject({ status: 409 });
|
|
438
|
-
expect(
|
|
438
|
+
expect(versionControl.commitChanges).not.toHaveBeenCalled();
|
|
439
439
|
expect(store.starterPack).toBe('none');
|
|
440
440
|
expect(store.starterPackClaim).toBe('u-other 1');
|
|
441
441
|
// Asked the database with the locks held, not before them: the renewal
|
|
@@ -445,12 +445,12 @@ describe('choosing a pack', () => {
|
|
|
445
445
|
.filter((c) => c.key === 'starterPackClaim' && c.next !== null);
|
|
446
446
|
expect(renewals).toHaveLength(1);
|
|
447
447
|
expect(renewals[0]!.expected).toMatch(/^u-admin /);
|
|
448
|
-
expect(renewals[0]!.at).toBeGreaterThan(
|
|
448
|
+
expect(renewals[0]!.at).toBeGreaterThan(versionControl.acquireLock.mock.invocationCallOrder[0]!);
|
|
449
449
|
});
|
|
450
450
|
|
|
451
451
|
it('renews its claim as it checks it, so the commit that follows has the whole lease to itself', async () => {
|
|
452
452
|
const store: Record<string, string> = {};
|
|
453
|
-
const { svc, settings,
|
|
453
|
+
const { svc, settings, versionControl } = harness({ store });
|
|
454
454
|
let claimed = '';
|
|
455
455
|
settings.recordIfAbsent.mockImplementationOnce(async (key: string, value: string) => {
|
|
456
456
|
store[key] = value;
|
|
@@ -458,12 +458,12 @@ describe('choosing a pack', () => {
|
|
|
458
458
|
return true;
|
|
459
459
|
});
|
|
460
460
|
// The work before the commit takes a moment, so a renewal is dated later than the claim.
|
|
461
|
-
|
|
461
|
+
versionControl.acquireLock.mockImplementationOnce(async () => {
|
|
462
462
|
await new Promise((r) => setTimeout(r, 5));
|
|
463
463
|
return { acquired: true, lock: { holderName: 'x' } };
|
|
464
464
|
});
|
|
465
465
|
let claimAtCommit = '';
|
|
466
|
-
|
|
466
|
+
versionControl.commitChanges.mockImplementationOnce(async () => {
|
|
467
467
|
claimAtCommit = store.starterPackClaim!;
|
|
468
468
|
return { sha: 'abc' };
|
|
469
469
|
});
|
|
@@ -477,14 +477,14 @@ describe('choosing a pack', () => {
|
|
|
477
477
|
|
|
478
478
|
it('releases a renewal whose outcome it never learned: the row is not left closed until it expires', async () => {
|
|
479
479
|
const store: Record<string, string> = {};
|
|
480
|
-
const { svc, settings,
|
|
480
|
+
const { svc, settings, versionControl } = harness({ store });
|
|
481
481
|
// The renewal reached the database and landed, but its answer did not come back.
|
|
482
482
|
settings.swapIfValue.mockImplementationOnce(async (key: string, expected: string, next: string | null) => {
|
|
483
483
|
if (store[key] === expected && next !== null) store[key] = next;
|
|
484
484
|
throw new Error('connection reset');
|
|
485
485
|
});
|
|
486
486
|
await expect(svc.choose(ADMIN, 'sales')).rejects.toThrow('connection reset');
|
|
487
|
-
expect(
|
|
487
|
+
expect(versionControl.commitChanges).not.toHaveBeenCalled();
|
|
488
488
|
expect(store.starterPackClaim).toBeUndefined();
|
|
489
489
|
// Open again at once, not in ten minutes.
|
|
490
490
|
await expect(svc.choose(ADMIN, 'sales')).resolves.toMatchObject({ id: 'sales' });
|
|
@@ -510,9 +510,9 @@ describe('choosing a pack', () => {
|
|
|
510
510
|
|
|
511
511
|
it('never writes its answer over another: a pack added as another replica answered keeps that answer', async () => {
|
|
512
512
|
const store: Record<string, string> = {};
|
|
513
|
-
const { svc,
|
|
513
|
+
const { svc, versionControl } = harness({ store });
|
|
514
514
|
// The commit landed; in the moment before the record, another replica answered.
|
|
515
|
-
|
|
515
|
+
versionControl.commitChanges.mockImplementationOnce(async () => {
|
|
516
516
|
store.starterPack = 'none';
|
|
517
517
|
return { sha: 'abc' };
|
|
518
518
|
});
|
|
@@ -522,7 +522,7 @@ describe('choosing a pack', () => {
|
|
|
522
522
|
});
|
|
523
523
|
|
|
524
524
|
it('waits for a plugin creation of the same name, on the lock creations take', async () => {
|
|
525
|
-
const { svc, locks, lockRequests,
|
|
525
|
+
const { svc, locks, lockRequests, versionControl } = harness();
|
|
526
526
|
let released = false;
|
|
527
527
|
let finishCreating!: () => void;
|
|
528
528
|
const creating = locks.run(
|
|
@@ -536,7 +536,7 @@ describe('choosing a pack', () => {
|
|
|
536
536
|
}),
|
|
537
537
|
);
|
|
538
538
|
const commits: string[] = [];
|
|
539
|
-
|
|
539
|
+
versionControl.commitChanges.mockImplementation(async () => {
|
|
540
540
|
commits.push(released ? 'after the creation released the lock' : 'while the creation held the lock');
|
|
541
541
|
return { sha: 'abc' };
|
|
542
542
|
});
|
|
@@ -545,7 +545,7 @@ describe('choosing a pack', () => {
|
|
|
545
545
|
// The pack has asked for the lock the creation holds, and nothing is
|
|
546
546
|
// committed until that creation lets go.
|
|
547
547
|
await vi.waitFor(() => expect(lockRequests).toEqual(['plugin:sales-starter']));
|
|
548
|
-
expect(
|
|
548
|
+
expect(versionControl.commitChanges).not.toHaveBeenCalled();
|
|
549
549
|
finishCreating();
|
|
550
550
|
await creating;
|
|
551
551
|
await expect(choosing).resolves.toMatchObject({ id: 'sales' });
|
|
@@ -553,7 +553,7 @@ describe('choosing a pack', () => {
|
|
|
553
553
|
});
|
|
554
554
|
|
|
555
555
|
it('adds the pack even when recording the choice fails afterwards: the pages close the question', async () => {
|
|
556
|
-
const { svc, store,
|
|
556
|
+
const { svc, store, versionControl, settings } = harness();
|
|
557
557
|
settings.recordIfAbsent.mockImplementation(async (key: string, value: string) => {
|
|
558
558
|
if (key === 'starterPack') throw new Error('database unreachable');
|
|
559
559
|
if (key in store) return false;
|
|
@@ -561,7 +561,7 @@ describe('choosing a pack', () => {
|
|
|
561
561
|
return true;
|
|
562
562
|
});
|
|
563
563
|
await expect(svc.choose(ADMIN, 'sales')).resolves.toMatchObject({ id: 'sales', pages: 2 });
|
|
564
|
-
expect(
|
|
564
|
+
expect(versionControl.commitChanges).toHaveBeenCalledTimes(1);
|
|
565
565
|
expect(store.starterPack).toBeUndefined();
|
|
566
566
|
expect(store.starterPackClaim).toBeUndefined();
|
|
567
567
|
expect((await svc.status(ADMIN)).offered).toBe(false);
|
|
@@ -577,8 +577,8 @@ describe('choosing a pack', () => {
|
|
|
577
577
|
});
|
|
578
578
|
|
|
579
579
|
it('leaves the question open when the commit fails: the claim is taken back', async () => {
|
|
580
|
-
const { svc, store, settings,
|
|
581
|
-
|
|
580
|
+
const { svc, store, settings, versionControl } = harness();
|
|
581
|
+
versionControl.commitChanges.mockRejectedValueOnce(new Error('disk full'));
|
|
582
582
|
await expect(svc.choose(ADMIN, 'sales')).rejects.toThrow('disk full');
|
|
583
583
|
expect(settings.recordIfAbsent).toHaveBeenCalledTimes(1);
|
|
584
584
|
expect(settings.swapIfValue).toHaveBeenCalledWith('starterPackClaim', expect.stringMatching(/^u-admin /), null, null);
|
|
@@ -73,7 +73,7 @@ export interface PluginIdentityLocks {
|
|
|
73
73
|
/**
|
|
74
74
|
* What the onboarding routes depend on. `status` answers anyone signed in;
|
|
75
75
|
* `choose` refuses a member (403), a question no longer asked (409) and a
|
|
76
|
-
* pack that does not exist (404) with a `
|
|
76
|
+
* pack that does not exist (404) with a `VersionControlDomainError` carrying that
|
|
77
77
|
* status. One failure without a status is read by the route all the same:
|
|
78
78
|
* the batch write's "locked by …" refusal, which it answers as a 409 to
|
|
79
79
|
* try again, since nothing was committed. Any other failure is the
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import type { AuthUser } from '@bevel-software/platform-shared';
|
|
3
3
|
import { logger } from '../../shared/logging.js';
|
|
4
|
-
import {
|
|
4
|
+
import { VersionControlDomainError } from '../../shared/domain-errors.js';
|
|
5
5
|
import type { IStarterPackService } from './onboarding.contract.js';
|
|
6
6
|
import '../auth/index.js'; // Express Request augmentation (req.userId)
|
|
7
7
|
|
|
@@ -66,7 +66,7 @@ export function createOnboardingRoutes(
|
|
|
66
66
|
try {
|
|
67
67
|
res.json(await starterPacks.choose(user, id.trim()));
|
|
68
68
|
} catch (err) {
|
|
69
|
-
if (err instanceof
|
|
69
|
+
if (err instanceof VersionControlDomainError) {
|
|
70
70
|
res.status(err.status).json({ error: err.message });
|
|
71
71
|
return;
|
|
72
72
|
}
|