@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
|
@@ -1,155 +1,155 @@
|
|
|
1
|
-
import type { AgentEventKind } from './audit.contract.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Pure classification of one UTCP tool call into what the Audit log records:
|
|
5
|
-
* a hexis capability, a manual's tool, or a skill read. No I/O — the one
|
|
6
|
-
* catalog it may need (the skill folders) is handed in by the caller, which
|
|
7
|
-
* asks {@link skillReadPath} first whether that catalog is worth fetching.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/** What a call is logged as: the kind, the manual (or skill folder), and the bare name. */
|
|
11
|
-
export interface ClassifiedCall {
|
|
12
|
-
kind: AgentEventKind;
|
|
13
|
-
manual: string | null;
|
|
14
|
-
name: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** A skill as the classifier needs it: its name and its repo-relative folder. */
|
|
18
|
-
export interface SkillFolder {
|
|
19
|
-
name: string;
|
|
20
|
-
path: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface ClassifierContext {
|
|
24
|
-
/** The registered name of the platform's own manual (`KNOWLEDGE_BASE`). */
|
|
25
|
-
kbManualName: string;
|
|
26
|
-
/** Registered (rewritten) manual name → catalog name, for pooled MCP manuals. */
|
|
27
|
-
catalogNames: ReadonlyMap<string, string>;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* The platform tools whose `path` argument may point INTO a skill folder — a
|
|
32
|
-
* read of `Plugins/Sales/rfi/SKILL.md` or of a file bundled beside it is the
|
|
33
|
-
* agent reading that skill, and is logged as such rather than as a file read.
|
|
34
|
-
*/
|
|
35
|
-
const SKILL_FOLDER_READ_TOOLS: ReadonlySet<string> = new Set(['read_file', 'grep', 'list_files']);
|
|
36
|
-
|
|
37
|
-
/** The platform tool that loads a skill by name. */
|
|
38
|
-
const GET_SKILL = 'get_skill';
|
|
39
|
-
|
|
40
|
-
/** `<manual>.<tool>` → its two halves; a bare name has no manual. */
|
|
41
|
-
export function splitUtcpName(utcpName: string): { manual: string; tool: string } {
|
|
42
|
-
const dot = utcpName.indexOf('.');
|
|
43
|
-
return dot < 0
|
|
44
|
-
? { manual: '', tool: utcpName }
|
|
45
|
-
: { manual: utcpName.slice(0, dot), tool: utcpName.slice(dot + 1) };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* The `path` a platform tool was called with, wherever the caller put it.
|
|
50
|
-
* Bevel-hosted http tools take their arguments inside a `body` envelope
|
|
51
|
-
* (`{ body: { path } }`); a caller that flattened it (`{ path }`) is read too.
|
|
52
|
-
*/
|
|
53
|
-
function pathArgument(args: Record<string, unknown>): string | null {
|
|
54
|
-
const body = args.body;
|
|
55
|
-
const inner = body && typeof body === 'object' ? (body as Record<string, unknown>).path : undefined;
|
|
56
|
-
const candidate = typeof inner === 'string' ? inner : args.path;
|
|
57
|
-
return typeof candidate === 'string' && candidate.length > 0 ? candidate : null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** The `name` a `get_skill` call asked for, from the envelope or flattened. */
|
|
61
|
-
function skillNameArgument(args: Record<string, unknown>): string | null {
|
|
62
|
-
const body = args.body;
|
|
63
|
-
const inner = body && typeof body === 'object' ? (body as Record<string, unknown>).name : undefined;
|
|
64
|
-
const candidate = typeof inner === 'string' ? inner : args.name;
|
|
65
|
-
return typeof candidate === 'string' && candidate.length > 0 ? candidate : null;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* When a platform read names a path, the path — the signal that the caller
|
|
70
|
-
* should fetch the skill catalog before classifying (a folder match turns
|
|
71
|
-
* the read into a skill event). Null for every other call, so the catalog is
|
|
72
|
-
* never fetched for a `notion.search` or a `write_file`.
|
|
73
|
-
*/
|
|
74
|
-
export function skillReadPath(utcpName: string, args: Record<string, unknown>, kbManualName: string): string | null {
|
|
75
|
-
const { manual, tool } = splitUtcpName(utcpName);
|
|
76
|
-
if (manual !== kbManualName) return null;
|
|
77
|
-
if (tool === GET_SKILL) return skillNameArgument(args) === null ? null : '';
|
|
78
|
-
if (!SKILL_FOLDER_READ_TOOLS.has(tool)) return null;
|
|
79
|
-
return pathArgument(args);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* The path as segments, resolved: forward slashes, `.` dropped, `..` taken
|
|
84
|
-
* back a segment, no empty segments — so two spellings of one place compare
|
|
85
|
-
* equal, and a path that climbs OUT of a folder is never matched to it. A
|
|
86
|
-
* path that climbs above its own start has no place at all and resolves to
|
|
87
|
-
* the empty string, which matches nothing. (The file tools refuse `..`
|
|
88
|
-
* outright; the log must still not credit a refused read to a skill.)
|
|
89
|
-
*/
|
|
90
|
-
function normalizePath(p: string): string {
|
|
91
|
-
const out: string[] = [];
|
|
92
|
-
for (const segment of p.replace(/\\/g, '/').split('/')) {
|
|
93
|
-
if (segment === '' || segment === '.') continue;
|
|
94
|
-
if (segment === '..') {
|
|
95
|
-
if (out.length === 0) return '';
|
|
96
|
-
out.pop();
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
out.push(segment);
|
|
100
|
-
}
|
|
101
|
-
return out.join('/');
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* The skill whose folder contains `path`, if any. Matched on a segment
|
|
106
|
-
* boundary anywhere in the path — a caller may spell the path from the
|
|
107
|
-
* repository root (`Plugins/Sales/rfi/SKILL.md`) or from one level above it
|
|
108
|
-
* (`knowledge-base/Plugins/Sales/rfi/SKILL.md`), and both are that skill.
|
|
109
|
-
* The longest folder wins, so a skill nested under another's folder is not
|
|
110
|
-
* mistaken for its parent.
|
|
111
|
-
*/
|
|
112
|
-
export function skillContaining(path: string, skills: readonly SkillFolder[]): SkillFolder | null {
|
|
113
|
-
const normalized = normalizePath(path);
|
|
114
|
-
if (!normalized) return null;
|
|
115
|
-
const haystack = `/${normalized}/`;
|
|
116
|
-
let best: SkillFolder | null = null;
|
|
117
|
-
for (const skill of skills) {
|
|
118
|
-
const folder = normalizePath(skill.path);
|
|
119
|
-
if (!folder) continue;
|
|
120
|
-
if (haystack.includes(`/${folder}/`) && (!best || folder.length > normalizePath(best.path).length)) {
|
|
121
|
-
best = skill;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return best;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Classify one call. `skills` is the catalog when {@link skillReadPath} asked
|
|
129
|
-
* for it and the caller could fetch it; null otherwise (the read is then
|
|
130
|
-
* logged as the capability it is, which is the honest fallback).
|
|
131
|
-
*/
|
|
132
|
-
export function classifyToolCall(
|
|
133
|
-
utcpName: string,
|
|
134
|
-
args: Record<string, unknown>,
|
|
135
|
-
ctx: ClassifierContext,
|
|
136
|
-
skills: readonly SkillFolder[] | null,
|
|
137
|
-
): ClassifiedCall {
|
|
138
|
-
const { manual, tool } = splitUtcpName(utcpName);
|
|
139
|
-
// A meta-tool (`call_tool_chain`, `list_tools`, …) has no manual: the platform's own.
|
|
140
|
-
if (manual === '' || manual === ctx.kbManualName) {
|
|
141
|
-
if (tool === GET_SKILL) {
|
|
142
|
-
const name = skillNameArgument(args);
|
|
143
|
-
if (name) {
|
|
144
|
-
const folder = skills?.find((s) => s.name === name)?.path ?? null;
|
|
145
|
-
return { kind: 'skill', manual: folder, name };
|
|
146
|
-
}
|
|
147
|
-
} else if (SKILL_FOLDER_READ_TOOLS.has(tool) && skills) {
|
|
148
|
-
const path = pathArgument(args);
|
|
149
|
-
const skill = path ? skillContaining(path, skills) : null;
|
|
150
|
-
if (skill) return { kind: 'skill', manual: skill.path, name: skill.name };
|
|
151
|
-
}
|
|
152
|
-
return { kind: 'capability', manual: null, name: tool };
|
|
153
|
-
}
|
|
154
|
-
return { kind: 'tool', manual: ctx.catalogNames.get(manual) ?? manual, name: tool };
|
|
155
|
-
}
|
|
1
|
+
import type { AgentEventKind } from './audit.contract.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pure classification of one UTCP tool call into what the Audit log records:
|
|
5
|
+
* a hexis capability, a manual's tool, or a skill read. No I/O — the one
|
|
6
|
+
* catalog it may need (the skill folders) is handed in by the caller, which
|
|
7
|
+
* asks {@link skillReadPath} first whether that catalog is worth fetching.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** What a call is logged as: the kind, the manual (or skill folder), and the bare name. */
|
|
11
|
+
export interface ClassifiedCall {
|
|
12
|
+
kind: AgentEventKind;
|
|
13
|
+
manual: string | null;
|
|
14
|
+
name: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A skill as the classifier needs it: its name and its repo-relative folder. */
|
|
18
|
+
export interface SkillFolder {
|
|
19
|
+
name: string;
|
|
20
|
+
path: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ClassifierContext {
|
|
24
|
+
/** The registered name of the platform's own manual (`KNOWLEDGE_BASE`). */
|
|
25
|
+
kbManualName: string;
|
|
26
|
+
/** Registered (rewritten) manual name → catalog name, for pooled MCP manuals. */
|
|
27
|
+
catalogNames: ReadonlyMap<string, string>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The platform tools whose `path` argument may point INTO a skill folder — a
|
|
32
|
+
* read of `Plugins/Sales/rfi/SKILL.md` or of a file bundled beside it is the
|
|
33
|
+
* agent reading that skill, and is logged as such rather than as a file read.
|
|
34
|
+
*/
|
|
35
|
+
const SKILL_FOLDER_READ_TOOLS: ReadonlySet<string> = new Set(['read_file', 'grep', 'list_files']);
|
|
36
|
+
|
|
37
|
+
/** The platform tool that loads a skill by name. */
|
|
38
|
+
const GET_SKILL = 'get_skill';
|
|
39
|
+
|
|
40
|
+
/** `<manual>.<tool>` → its two halves; a bare name has no manual. */
|
|
41
|
+
export function splitUtcpName(utcpName: string): { manual: string; tool: string } {
|
|
42
|
+
const dot = utcpName.indexOf('.');
|
|
43
|
+
return dot < 0
|
|
44
|
+
? { manual: '', tool: utcpName }
|
|
45
|
+
: { manual: utcpName.slice(0, dot), tool: utcpName.slice(dot + 1) };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The `path` a platform tool was called with, wherever the caller put it.
|
|
50
|
+
* Bevel-hosted http tools take their arguments inside a `body` envelope
|
|
51
|
+
* (`{ body: { path } }`); a caller that flattened it (`{ path }`) is read too.
|
|
52
|
+
*/
|
|
53
|
+
function pathArgument(args: Record<string, unknown>): string | null {
|
|
54
|
+
const body = args.body;
|
|
55
|
+
const inner = body && typeof body === 'object' ? (body as Record<string, unknown>).path : undefined;
|
|
56
|
+
const candidate = typeof inner === 'string' ? inner : args.path;
|
|
57
|
+
return typeof candidate === 'string' && candidate.length > 0 ? candidate : null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The `name` a `get_skill` call asked for, from the envelope or flattened. */
|
|
61
|
+
function skillNameArgument(args: Record<string, unknown>): string | null {
|
|
62
|
+
const body = args.body;
|
|
63
|
+
const inner = body && typeof body === 'object' ? (body as Record<string, unknown>).name : undefined;
|
|
64
|
+
const candidate = typeof inner === 'string' ? inner : args.name;
|
|
65
|
+
return typeof candidate === 'string' && candidate.length > 0 ? candidate : null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* When a platform read names a path, the path — the signal that the caller
|
|
70
|
+
* should fetch the skill catalog before classifying (a folder match turns
|
|
71
|
+
* the read into a skill event). Null for every other call, so the catalog is
|
|
72
|
+
* never fetched for a `notion.search` or a `write_file`.
|
|
73
|
+
*/
|
|
74
|
+
export function skillReadPath(utcpName: string, args: Record<string, unknown>, kbManualName: string): string | null {
|
|
75
|
+
const { manual, tool } = splitUtcpName(utcpName);
|
|
76
|
+
if (manual !== kbManualName) return null;
|
|
77
|
+
if (tool === GET_SKILL) return skillNameArgument(args) === null ? null : '';
|
|
78
|
+
if (!SKILL_FOLDER_READ_TOOLS.has(tool)) return null;
|
|
79
|
+
return pathArgument(args);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The path as segments, resolved: forward slashes, `.` dropped, `..` taken
|
|
84
|
+
* back a segment, no empty segments — so two spellings of one place compare
|
|
85
|
+
* equal, and a path that climbs OUT of a folder is never matched to it. A
|
|
86
|
+
* path that climbs above its own start has no place at all and resolves to
|
|
87
|
+
* the empty string, which matches nothing. (The file tools refuse `..`
|
|
88
|
+
* outright; the log must still not credit a refused read to a skill.)
|
|
89
|
+
*/
|
|
90
|
+
function normalizePath(p: string): string {
|
|
91
|
+
const out: string[] = [];
|
|
92
|
+
for (const segment of p.replace(/\\/g, '/').split('/')) {
|
|
93
|
+
if (segment === '' || segment === '.') continue;
|
|
94
|
+
if (segment === '..') {
|
|
95
|
+
if (out.length === 0) return '';
|
|
96
|
+
out.pop();
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
out.push(segment);
|
|
100
|
+
}
|
|
101
|
+
return out.join('/');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The skill whose folder contains `path`, if any. Matched on a segment
|
|
106
|
+
* boundary anywhere in the path — a caller may spell the path from the
|
|
107
|
+
* repository root (`Plugins/Sales/rfi/SKILL.md`) or from one level above it
|
|
108
|
+
* (`knowledge-base/Plugins/Sales/rfi/SKILL.md`), and both are that skill.
|
|
109
|
+
* The longest folder wins, so a skill nested under another's folder is not
|
|
110
|
+
* mistaken for its parent.
|
|
111
|
+
*/
|
|
112
|
+
export function skillContaining(path: string, skills: readonly SkillFolder[]): SkillFolder | null {
|
|
113
|
+
const normalized = normalizePath(path);
|
|
114
|
+
if (!normalized) return null;
|
|
115
|
+
const haystack = `/${normalized}/`;
|
|
116
|
+
let best: SkillFolder | null = null;
|
|
117
|
+
for (const skill of skills) {
|
|
118
|
+
const folder = normalizePath(skill.path);
|
|
119
|
+
if (!folder) continue;
|
|
120
|
+
if (haystack.includes(`/${folder}/`) && (!best || folder.length > normalizePath(best.path).length)) {
|
|
121
|
+
best = skill;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return best;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Classify one call. `skills` is the catalog when {@link skillReadPath} asked
|
|
129
|
+
* for it and the caller could fetch it; null otherwise (the read is then
|
|
130
|
+
* logged as the capability it is, which is the honest fallback).
|
|
131
|
+
*/
|
|
132
|
+
export function classifyToolCall(
|
|
133
|
+
utcpName: string,
|
|
134
|
+
args: Record<string, unknown>,
|
|
135
|
+
ctx: ClassifierContext,
|
|
136
|
+
skills: readonly SkillFolder[] | null,
|
|
137
|
+
): ClassifiedCall {
|
|
138
|
+
const { manual, tool } = splitUtcpName(utcpName);
|
|
139
|
+
// A meta-tool (`call_tool_chain`, `list_tools`, …) has no manual: the platform's own.
|
|
140
|
+
if (manual === '' || manual === ctx.kbManualName) {
|
|
141
|
+
if (tool === GET_SKILL) {
|
|
142
|
+
const name = skillNameArgument(args);
|
|
143
|
+
if (name) {
|
|
144
|
+
const folder = skills?.find((s) => s.name === name)?.path ?? null;
|
|
145
|
+
return { kind: 'skill', manual: folder, name };
|
|
146
|
+
}
|
|
147
|
+
} else if (SKILL_FOLDER_READ_TOOLS.has(tool) && skills) {
|
|
148
|
+
const path = pathArgument(args);
|
|
149
|
+
const skill = path ? skillContaining(path, skills) : null;
|
|
150
|
+
if (skill) return { kind: 'skill', manual: skill.path, name: skill.name };
|
|
151
|
+
}
|
|
152
|
+
return { kind: 'capability', manual: null, name: tool };
|
|
153
|
+
}
|
|
154
|
+
return { kind: 'tool', manual: ctx.catalogNames.get(manual) ?? manual, name: tool };
|
|
155
|
+
}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
type IAccountAdmission,
|
|
14
14
|
} from '../account-admission.js';
|
|
15
15
|
import { hashPassword } from '../password-hash.js';
|
|
16
|
-
import { RECOVERY_BOT_EMAIL } from '../../
|
|
16
|
+
import { RECOVERY_BOT_EMAIL } from '../../version-control/recovery-bot.js';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Drizzle chain stub, as in `auth.service.test.ts`: each db.select() /
|
|
@@ -4,7 +4,7 @@ import { PgDialect } from 'drizzle-orm/pg-core';
|
|
|
4
4
|
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
5
5
|
import { AccountErasureService, type IErasureParticipant } from '../account-erasure.service.js';
|
|
6
6
|
import type { Database } from '../../database/connection.js';
|
|
7
|
-
import {
|
|
7
|
+
import { ChangeRequestReviewService } from '../../version-control/change-request-review/change-request-review.service.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Erasing an account rewrites the person's name and address out of every
|
|
@@ -122,13 +122,13 @@ function harness(opts: { participants?: IErasureParticipant[] } = {}) {
|
|
|
122
122
|
transaction: async <T,>(fn: (t: typeof tx) => Promise<T>) => fn(tx),
|
|
123
123
|
} as unknown as Database;
|
|
124
124
|
return {
|
|
125
|
-
// The REAL review
|
|
125
|
+
// The REAL change-request review, so what is pinned below is the contract as
|
|
126
126
|
// wired: erasure asks it to rewrite the approvals inside the erasure's
|
|
127
|
-
// transaction, and it is the
|
|
127
|
+
// transaction, and it is the version-control service that takes the lock. Its other
|
|
128
128
|
// collaborators are never reached by `eraseApprover`.
|
|
129
129
|
svc: new AccountErasureService(
|
|
130
130
|
db,
|
|
131
|
-
new
|
|
131
|
+
new ChangeRequestReviewService(db, {} as never, {} as never, {} as never),
|
|
132
132
|
opts.participants ?? [],
|
|
133
133
|
),
|
|
134
134
|
order,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { AccountErasureService, type IErasureParticipant } from '../account-erasure.service.js';
|
|
3
|
+
import type { Database } from '../../database/index.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whose slices an erasure runs, and in what order: core's own first (the
|
|
7
|
+
* vault's managed sign-ins, say), then the distribution's, read from the
|
|
8
|
+
* port's array as it IS at erasure time. The array is the root's and is held
|
|
9
|
+
* by reference (`CorePorts.erasureParticipants`): a root may fill it after
|
|
10
|
+
* construction, and core never writes into it — a root building a second
|
|
11
|
+
* graph over the same array must not inherit the first graph's slices.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** A database that answers the one read erasure makes and swallows every write, outside the transaction and in it. */
|
|
15
|
+
function silentDb(): Database {
|
|
16
|
+
const done = Promise.resolve([]);
|
|
17
|
+
const tx = {
|
|
18
|
+
execute: async () => ({ rows: [] }),
|
|
19
|
+
select: () => ({ from: () => ({ where: async () => [] }) }),
|
|
20
|
+
delete: () => ({ where: () => done }),
|
|
21
|
+
update: () => ({ set: () => ({ where: () => done }) }),
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
select: () => ({
|
|
25
|
+
from: () => ({
|
|
26
|
+
where: () => ({ limit: async () => [{ id: 'u1', email: 'bob@bevel.software', name: 'Bob' }] }),
|
|
27
|
+
}),
|
|
28
|
+
}),
|
|
29
|
+
update: () => ({ set: () => ({ where: async () => undefined }) }),
|
|
30
|
+
transaction: async <T,>(fn: (t: typeof tx) => Promise<T>) => fn(tx),
|
|
31
|
+
} as unknown as Database;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe('AccountErasureService: whose slices run, and in what order', () => {
|
|
35
|
+
it('runs core’s own slices first, then the port’s array as it is at erasure time — the array held, never copied', async () => {
|
|
36
|
+
const steps: string[] = [];
|
|
37
|
+
const slice = (name: string): IErasureParticipant => ({
|
|
38
|
+
before: async () => {
|
|
39
|
+
steps.push(`before:${name}`);
|
|
40
|
+
},
|
|
41
|
+
inTransaction: async () => {
|
|
42
|
+
steps.push(`tx:${name}`);
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
// The port's array, as a root hands it over: one slice now …
|
|
46
|
+
const fromPort = [slice('distribution-1')];
|
|
47
|
+
const svc = new AccountErasureService(silentDb(), { eraseApprover: async () => undefined }, fromPort, [slice('vault')]);
|
|
48
|
+
// … and one it appends AFTER construction. Core's slice is not in that
|
|
49
|
+
// array, so the array holds exactly what the root put there.
|
|
50
|
+
fromPort.push(slice('distribution-2'));
|
|
51
|
+
expect(fromPort).toHaveLength(2);
|
|
52
|
+
|
|
53
|
+
await expect(svc.eraseUser('u1')).resolves.toBe(true);
|
|
54
|
+
expect(steps).toEqual(['before:vault', 'before:distribution-1', 'before:distribution-2', 'tx:vault', 'tx:distribution-1', 'tx:distribution-2']);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -5,7 +5,7 @@ import { closeDb, createDb, type Database } from '../../database/connection.js';
|
|
|
5
5
|
import { runCoreMigrations } from '../../database/migrate.js';
|
|
6
6
|
import { coreMigrationsDir } from '../../../assets.js';
|
|
7
7
|
import { PG_ADMIN_URL, PG_TEST_TIMEOUT, dropScratchDatabases, scratchDatabaseUrl } from '../../../__tests__/pg-scratch.js';
|
|
8
|
-
import {
|
|
8
|
+
import { VersionControlDomainError } from '../../../shared/domain-errors.js';
|
|
9
9
|
import { AuthService } from '../auth.service.js';
|
|
10
10
|
import { ACCOUNT_BUSY_MESSAGE, takeAccountSwitchLock } from '../account-switch-lock.js';
|
|
11
11
|
|
|
@@ -51,7 +51,7 @@ describe.skipIf(!PG_ADMIN_URL)('the account switch lock under contention, on a r
|
|
|
51
51
|
const { db, url } = await migratedDatabase();
|
|
52
52
|
const holder = await holdLock(url, 'alice@acme.test');
|
|
53
53
|
const refusal = db.transaction((tx) => takeAccountSwitchLock(tx, 'Alice@Acme.test', 200));
|
|
54
|
-
await expect(refusal).rejects.toBeInstanceOf(
|
|
54
|
+
await expect(refusal).rejects.toBeInstanceOf(VersionControlDomainError);
|
|
55
55
|
await expect(refusal).rejects.toMatchObject({ status: 409, message: ACCOUNT_BUSY_MESSAGE, payload: { kind: 'account-busy' } });
|
|
56
56
|
// Released, the lock is taken at once.
|
|
57
57
|
await holder.query('commit');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from 'vitest';
|
|
2
2
|
import { PgDialect } from 'drizzle-orm/pg-core';
|
|
3
3
|
import type { SQL } from 'drizzle-orm';
|
|
4
|
-
import {
|
|
4
|
+
import { VersionControlDomainError } from '../../../shared/domain-errors.js';
|
|
5
5
|
import { ACCOUNT_BUSY_MESSAGE, ACCOUNT_SWITCH_LOCK_WAIT_MS, takeAccountSwitchLock } from '../account-switch-lock.js';
|
|
6
6
|
|
|
7
7
|
/** A transaction handle that records what it ran, and fails the lock statement when told to. */
|
|
@@ -32,7 +32,7 @@ describe('takeAccountSwitchLock', () => {
|
|
|
32
32
|
it('answers a wait that ran out as a 409 account-busy, in the words the admin is told', async () => {
|
|
33
33
|
const { tx } = fakeTx({ code: '55P03', message: 'canceling statement due to lock timeout' });
|
|
34
34
|
const refusal = takeAccountSwitchLock(tx, 'alice@example.com');
|
|
35
|
-
await expect(refusal).rejects.toBeInstanceOf(
|
|
35
|
+
await expect(refusal).rejects.toBeInstanceOf(VersionControlDomainError);
|
|
36
36
|
await expect(refusal).rejects.toMatchObject({ status: 409, message: ACCOUNT_BUSY_MESSAGE, payload: { kind: 'account-busy' } });
|
|
37
37
|
});
|
|
38
38
|
|
|
@@ -2,13 +2,13 @@ import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import type { Server } from 'node:http';
|
|
4
4
|
import { createAccountRoutes } from '../account.routes.js';
|
|
5
|
-
import type
|
|
5
|
+
import { AccountHooks, type AccountInvitedEvent } from '../account-hooks.js';
|
|
6
6
|
import { AuthService } from '../auth.service.js';
|
|
7
7
|
import { AccountAdmissionRefusedError, AccountChangeRefusedError } from '../account-admission.js';
|
|
8
|
-
import {
|
|
8
|
+
import { VersionControlDomainError } from '../../../shared/domain-errors.js';
|
|
9
9
|
import { hashPassword } from '../password-hash.js';
|
|
10
|
-
import type { Database } from '../../database/
|
|
11
|
-
import type { IAdminAccessService } from '../../admin/
|
|
10
|
+
import type { Database } from '../../database/index.js';
|
|
11
|
+
import type { IAdminAccessService } from '../../admin/index.js';
|
|
12
12
|
|
|
13
13
|
const authService = {
|
|
14
14
|
listAccounts: vi.fn(async () => [
|
|
@@ -38,9 +38,10 @@ const accountErasure = {
|
|
|
38
38
|
/** The invite listeners: nobody registered unless a test says so (see "an invite tells the listeners"). */
|
|
39
39
|
const accountHooks = {
|
|
40
40
|
runAccountInvited: vi.fn<(event: AccountInvitedEvent) => Promise<string[]>>(async () => []),
|
|
41
|
+
runAccountDeactivated: vi.fn<(event: { userId: string; email: string }) => Promise<string[]>>(async () => []),
|
|
41
42
|
};
|
|
42
43
|
|
|
43
|
-
function makeApp(opts: { admin: boolean; email?: string }) {
|
|
44
|
+
function makeApp(opts: { admin: boolean; email?: string; hooks?: typeof accountHooks | AccountHooks }) {
|
|
44
45
|
const adminAccess: IAdminAccessService = {
|
|
45
46
|
isAdmin: vi.fn(async () => opts.admin),
|
|
46
47
|
};
|
|
@@ -53,7 +54,7 @@ function makeApp(opts: { admin: boolean; email?: string }) {
|
|
|
53
54
|
req.userEmail = opts.email ?? 'caller@example.com';
|
|
54
55
|
next();
|
|
55
56
|
});
|
|
56
|
-
app.use('/api', createAccountRoutes(authService, adminAccess, accountErasure, accountHooks));
|
|
57
|
+
app.use('/api', createAccountRoutes(authService, adminAccess, accountErasure, opts.hooks ?? accountHooks));
|
|
57
58
|
return app;
|
|
58
59
|
}
|
|
59
60
|
|
|
@@ -487,9 +488,9 @@ describe('account routes — removing the erased address from access files', ()
|
|
|
487
488
|
|
|
488
489
|
it('the guards refuse up front: nothing is erased', async () => {
|
|
489
490
|
const { app, accessRemoval } = makeRemovalApp();
|
|
490
|
-
const {
|
|
491
|
+
const { VersionControlDomainError } = await import('../../../shared/domain-errors.js');
|
|
491
492
|
accessRemoval.assertRemovable.mockRejectedValueOnce(
|
|
492
|
-
new
|
|
493
|
+
new VersionControlDomainError('This is the last Admin; the Admin role must keep at least one direct email member.', 409),
|
|
493
494
|
);
|
|
494
495
|
const base = await listen(app);
|
|
495
496
|
const res = await fetch(`${base}/api/admin/accounts/u2?removeFromAccess=1`, { method: 'DELETE' });
|
|
@@ -503,14 +504,75 @@ describe('account routes — removing the erased address from access files', ()
|
|
|
503
504
|
describe('account routes — switching an account off and on', () => {
|
|
504
505
|
const post = (base: string, path: string) => fetch(`${base}/api/admin/accounts/${path}`, { method: 'POST' });
|
|
505
506
|
|
|
506
|
-
it('switches another account off and back on', async () => {
|
|
507
|
+
it('switches another account off and back on, telling the deactivated listeners and waiting for them', async () => {
|
|
508
|
+
// The listeners settle when the test says: the answer must not come first.
|
|
509
|
+
let settle!: () => void;
|
|
510
|
+
const settled = new Promise<string[]>((resolve) => {
|
|
511
|
+
settle = () => resolve(['managed-connections']);
|
|
512
|
+
});
|
|
513
|
+
vi.mocked(accountHooks.runAccountDeactivated).mockReset().mockReturnValueOnce(settled);
|
|
507
514
|
const base = await listen(makeApp({ admin: true }));
|
|
508
|
-
|
|
515
|
+
let answered = false;
|
|
516
|
+
const pending = post(base, 'u2/deactivate').then((res) => {
|
|
517
|
+
answered = true;
|
|
518
|
+
return res;
|
|
519
|
+
});
|
|
520
|
+
await vi.waitFor(() => expect(accountHooks.runAccountDeactivated).toHaveBeenCalledTimes(1));
|
|
521
|
+
expect(accountHooks.runAccountDeactivated).toHaveBeenCalledWith({ userId: 'u2', email: 'u2@example.com' });
|
|
522
|
+
expect(answered).toBe(false);
|
|
523
|
+
settle();
|
|
524
|
+
expect((await pending).status).toBe(204);
|
|
509
525
|
expect(authService.deactivate).toHaveBeenCalledWith('u2');
|
|
526
|
+
vi.mocked(accountHooks.runAccountDeactivated).mockResolvedValue([]);
|
|
510
527
|
expect((await post(base, 'u2/reactivate')).status).toBe(204);
|
|
511
528
|
expect(authService.reactivate).toHaveBeenCalledWith('u2');
|
|
512
529
|
});
|
|
513
530
|
|
|
531
|
+
it('reads the address again after the switch when the first read failed, and tells the listeners \'\' only when both do', async () => {
|
|
532
|
+
vi.mocked(accountHooks.runAccountDeactivated).mockReset().mockResolvedValue([]);
|
|
533
|
+
const base = await listen(makeApp({ admin: true }));
|
|
534
|
+
// First read away, second one back: the listeners get the address.
|
|
535
|
+
vi.mocked(authService.getUserById).mockRejectedValueOnce(new Error('users table is away'));
|
|
536
|
+
expect((await post(base, 'u2/deactivate')).status).toBe(204);
|
|
537
|
+
expect(accountHooks.runAccountDeactivated).toHaveBeenLastCalledWith({ userId: 'u2', email: 'u2@example.com' });
|
|
538
|
+
// Both reads away: the switch-off still happens, the listeners get ''.
|
|
539
|
+
vi.mocked(authService.getUserById)
|
|
540
|
+
.mockRejectedValueOnce(new Error('users table is away'))
|
|
541
|
+
.mockRejectedValueOnce(new Error('users table is still away'));
|
|
542
|
+
expect((await post(base, 'u2/deactivate')).status).toBe(204);
|
|
543
|
+
expect(accountHooks.runAccountDeactivated).toHaveBeenLastCalledWith({ userId: 'u2', email: '' });
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
it('a deactivation listener that throws is logged and skipped: the later listeners run and the switch-off still answers 204', async () => {
|
|
547
|
+
// The real seam, not the mock: the account is off whether or not a
|
|
548
|
+
// listener cleaned up after it, and one that fails must not keep the next
|
|
549
|
+
// from running or turn the admin's answer into an error.
|
|
550
|
+
const hooks = new AccountHooks();
|
|
551
|
+
const ran: string[] = [];
|
|
552
|
+
hooks.onAccountDeactivated(async () => {
|
|
553
|
+
ran.push('first');
|
|
554
|
+
throw new Error('the broker is down');
|
|
555
|
+
});
|
|
556
|
+
hooks.onAccountDeactivated(async (event) => {
|
|
557
|
+
ran.push(`second:${event.userId}`);
|
|
558
|
+
return 'managed-connections';
|
|
559
|
+
});
|
|
560
|
+
// Logged, so a listener that let go of nothing is diagnosable from the
|
|
561
|
+
// server's log (the seam writes through the default logger, which prints
|
|
562
|
+
// to the console) — the same way the invite seam's failures are pinned.
|
|
563
|
+
const logged = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
564
|
+
try {
|
|
565
|
+
const base = await listen(makeApp({ admin: true, hooks }));
|
|
566
|
+
expect((await post(base, 'u2/deactivate')).status).toBe(204);
|
|
567
|
+
expect(authService.deactivate).toHaveBeenCalledWith('u2');
|
|
568
|
+
expect(ran).toEqual(['first', 'second:u2']);
|
|
569
|
+
const lines = logged.mock.calls.map((args) => args.map(String).join(' '));
|
|
570
|
+
expect(lines.some((l) => l.includes('an account-deactivated listener failed') && l.includes('the broker is down'))).toBe(true);
|
|
571
|
+
} finally {
|
|
572
|
+
logged.mockRestore();
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
|
|
514
576
|
it('refuses an admin switching off their own account, so an admin who can sign in always remains', async () => {
|
|
515
577
|
vi.mocked(authService.deactivate).mockClear();
|
|
516
578
|
const base = await listen(makeApp({ admin: true }));
|
|
@@ -543,7 +605,7 @@ describe('account routes — switching an account off and on', () => {
|
|
|
543
605
|
|
|
544
606
|
it('answers a switch lock that timed out with the 409 account-busy the lock promises, not a 500', async () => {
|
|
545
607
|
vi.mocked(authService.deactivate).mockRejectedValueOnce(
|
|
546
|
-
new
|
|
608
|
+
new VersionControlDomainError('Another change to this account is still being saved; try again in a moment.', 409, {
|
|
547
609
|
kind: 'account-busy',
|
|
548
610
|
}),
|
|
549
611
|
);
|
|
@@ -7,7 +7,7 @@ import jwt from 'jsonwebtoken';
|
|
|
7
7
|
import { AuthService, PasswordChangedMeanwhileError, PasswordRefusedError } from '../auth.service.js';
|
|
8
8
|
import { AccountAdmissionRefusedError, SessionEndedError, type IAccountAdmission } from '../account-admission.js';
|
|
9
9
|
import { hashPassword, verifyPassword } from '../password-hash.js';
|
|
10
|
-
import { RECOVERY_BOT_EMAIL } from '../../
|
|
10
|
+
import { RECOVERY_BOT_EMAIL } from '../../version-control/index.js';
|
|
11
11
|
import { DIRECTORY_SYNC_BOT_EMAIL } from '../../access/index.js';
|
|
12
12
|
|
|
13
13
|
/**
|