@bevel-software/platform-core-backend 0.21.0 → 0.23.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/dist/core/core-ports.d.ts +11 -1
- 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 +3 -3
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +62 -13
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +22 -3
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +158 -23
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core/lifecycle.d.ts +34 -1
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/core/lifecycle.js +89 -13
- package/dist/core/lifecycle.js.map +1 -1
- package/dist/core-config.d.ts +0 -12
- package/dist/core-config.d.ts.map +1 -1
- package/dist/core-config.js +11 -13
- package/dist/core-config.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +42 -12
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +67 -10
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +214 -35
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access-requests.contract.d.ts +75 -0
- package/dist/modules/access/access-requests.contract.d.ts.map +1 -0
- package/dist/modules/access/access-requests.contract.js +20 -0
- package/dist/modules/access/access-requests.contract.js.map +1 -0
- package/dist/modules/access/access-requests.routes.d.ts +35 -0
- package/dist/modules/access/access-requests.routes.d.ts.map +1 -0
- package/dist/modules/access/access-requests.routes.js +237 -0
- package/dist/modules/access/access-requests.routes.js.map +1 -0
- package/dist/modules/access/access-requests.service.d.ts +123 -0
- package/dist/modules/access/access-requests.service.d.ts.map +1 -0
- package/dist/modules/access/access-requests.service.js +337 -0
- package/dist/modules/access/access-requests.service.js.map +1 -0
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +13 -15
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access-model/access-grammar.d.ts +12 -0
- package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
- package/dist/modules/access-model/access-grammar.js +24 -0
- package/dist/modules/access-model/access-grammar.js.map +1 -1
- package/dist/modules/auth/account-admission.d.ts +58 -7
- package/dist/modules/auth/account-admission.d.ts.map +1 -1
- package/dist/modules/auth/account-admission.js +44 -1
- package/dist/modules/auth/account-admission.js.map +1 -1
- package/dist/modules/auth/account.routes.d.ts +1 -1
- package/dist/modules/auth/account.routes.d.ts.map +1 -1
- package/dist/modules/auth/account.routes.js +61 -5
- package/dist/modules/auth/account.routes.js.map +1 -1
- package/dist/modules/auth/auth.middleware.d.ts +1 -1
- package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
- package/dist/modules/auth/auth.middleware.js +18 -7
- package/dist/modules/auth/auth.middleware.js.map +1 -1
- package/dist/modules/auth/auth.routes.d.ts.map +1 -1
- package/dist/modules/auth/auth.routes.js +8 -0
- package/dist/modules/auth/auth.routes.js.map +1 -1
- package/dist/modules/auth/auth.service.d.ts +96 -3
- package/dist/modules/auth/auth.service.d.ts.map +1 -1
- package/dist/modules/auth/auth.service.js +187 -9
- package/dist/modules/auth/auth.service.js.map +1 -1
- package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
- package/dist/modules/auth/oidc-auth-provider.js +7 -2
- package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
- package/dist/modules/database/core-schema.d.ts +41 -24
- package/dist/modules/database/core-schema.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +35 -27
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/github-app/github-app.client.d.ts +101 -0
- package/dist/modules/github-app/github-app.client.d.ts.map +1 -0
- package/dist/modules/github-app/github-app.client.js +222 -0
- package/dist/modules/github-app/github-app.client.js.map +1 -0
- package/dist/modules/github-app/github-app.connection.d.ts +102 -0
- package/dist/modules/github-app/github-app.connection.d.ts.map +1 -0
- package/dist/modules/github-app/github-app.connection.js +185 -0
- package/dist/modules/github-app/github-app.connection.js.map +1 -0
- package/dist/modules/github-app/github-app.routes.d.ts +59 -0
- package/dist/modules/github-app/github-app.routes.d.ts.map +1 -0
- package/dist/modules/github-app/github-app.routes.js +323 -0
- package/dist/modules/github-app/github-app.routes.js.map +1 -0
- package/dist/modules/github-app/index.d.ts +4 -0
- package/dist/modules/github-app/index.d.ts.map +1 -0
- package/dist/modules/github-app/index.js +4 -0
- package/dist/modules/github-app/index.js.map +1 -0
- package/dist/modules/kb-fs/branch-name.d.ts.map +1 -1
- package/dist/modules/kb-fs/branch-name.js +12 -2
- package/dist/modules/kb-fs/branch-name.js.map +1 -1
- package/dist/modules/kb-fs/remote-url.d.ts +22 -0
- package/dist/modules/kb-fs/remote-url.d.ts.map +1 -0
- package/dist/modules/kb-fs/remote-url.js +35 -0
- package/dist/modules/kb-fs/remote-url.js.map +1 -0
- package/dist/modules/kb-fs/repo-path.d.ts +11 -16
- package/dist/modules/kb-fs/repo-path.d.ts.map +1 -1
- package/dist/modules/kb-fs/repo-path.js +79 -0
- package/dist/modules/kb-fs/repo-path.js.map +1 -1
- package/dist/modules/kb-sync/kb-sync.routes.d.ts +2 -2
- package/dist/modules/kb-sync/kb-sync.routes.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.routes.js +14 -3
- package/dist/modules/kb-sync/kb-sync.routes.js.map +1 -1
- package/dist/modules/kb-sync/sync-auth.d.ts +3 -1
- package/dist/modules/kb-sync/sync-auth.d.ts.map +1 -1
- package/dist/modules/kb-sync/sync-auth.js +1 -1
- package/dist/modules/kb-sync/sync-auth.js.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.js +21 -6
- package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js +3 -2
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
- package/dist/modules/plugins/join-proposals.d.ts +17 -5
- package/dist/modules/plugins/join-proposals.d.ts.map +1 -1
- package/dist/modules/plugins/join-proposals.js +76 -22
- package/dist/modules/plugins/join-proposals.js.map +1 -1
- package/dist/modules/plugins/join-requests.service.d.ts +111 -18
- package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
- package/dist/modules/plugins/join-requests.service.js +173 -29
- package/dist/modules/plugins/join-requests.service.js.map +1 -1
- package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.js +3 -2
- package/dist/modules/plugins/plugins.routes.js.map +1 -1
- package/dist/modules/settings/deployment-settings.service.d.ts +22 -1
- package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
- package/dist/modules/settings/deployment-settings.service.js +101 -7
- package/dist/modules/settings/deployment-settings.service.js.map +1 -1
- package/dist/modules/settings/managed-repository.d.ts +43 -0
- package/dist/modules/settings/managed-repository.d.ts.map +1 -0
- package/dist/modules/settings/managed-repository.js +60 -0
- package/dist/modules/settings/managed-repository.js.map +1 -0
- package/dist/modules/settings/repository-source.d.ts +128 -0
- package/dist/modules/settings/repository-source.d.ts.map +1 -0
- package/dist/modules/settings/repository-source.js +150 -0
- package/dist/modules/settings/repository-source.js.map +1 -0
- package/dist/modules/settings/setup.routes.d.ts +78 -4
- package/dist/modules/settings/setup.routes.d.ts.map +1 -1
- package/dist/modules/settings/setup.routes.js +379 -17
- package/dist/modules/settings/setup.routes.js.map +1 -1
- package/dist/modules/skills/skill-access-requests.routes.d.ts +6 -8
- package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
- package/dist/modules/skills/skill-access-requests.routes.js +24 -63
- package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
- package/dist/modules/skills/skills.contract.d.ts +90 -18
- package/dist/modules/skills/skills.contract.d.ts.map +1 -1
- package/dist/modules/skills/skills.contract.js +4 -1
- package/dist/modules/skills/skills.contract.js.map +1 -1
- package/dist/modules/skills/skills.service.d.ts +98 -9
- package/dist/modules/skills/skills.service.d.ts.map +1 -1
- package/dist/modules/skills/skills.service.js +239 -37
- package/dist/modules/skills/skills.service.js.map +1 -1
- package/dist/modules/skills/skills.tools.d.ts +7 -0
- package/dist/modules/skills/skills.tools.d.ts.map +1 -1
- package/dist/modules/skills/skills.tools.js +71 -7
- package/dist/modules/skills/skills.tools.js.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.js +4 -2
- package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
- package/dist/modules/tool-auth/internal-token.service.d.ts +3 -3
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts +16 -7
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.js +34 -12
- package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
- package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-context.js +15 -0
- package/dist/modules/tool-helpers/tool-context.js.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.d.ts +2 -1
- package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.js +25 -4
- package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.d.ts +3 -2
- package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
- package/dist/modules/tool-helpers/validate-token.js +1 -1
- package/dist/modules/tool-helpers/validate-token.js.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-summary.d.ts +98 -0
- package/dist/modules/workflow/agent-tools/change-request-summary.d.ts.map +1 -0
- package/dist/modules/workflow/agent-tools/change-request-summary.js +81 -0
- package/dist/modules/workflow/agent-tools/change-request-summary.js.map +1 -0
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js +113 -37
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
- package/dist/modules/workflow/file-lock.service.d.ts +24 -0
- package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
- package/dist/modules/workflow/file-lock.service.js +30 -0
- package/dist/modules/workflow/file-lock.service.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +72 -1
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +170 -6
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
- package/dist/modules/workflow/git/node-git-runner.js +5 -0
- package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.d.ts +45 -0
- package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.js +99 -0
- package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
- package/dist/modules/workflow/pending-commits.service.d.ts +38 -0
- package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
- package/dist/modules/workflow/pending-commits.service.js +55 -0
- package/dist/modules/workflow/pending-commits.service.js.map +1 -1
- package/dist/modules/workflow/workflow-hooks.d.ts +54 -32
- package/dist/modules/workflow/workflow-hooks.d.ts.map +1 -1
- package/dist/modules/workflow/workflow-hooks.js +16 -1
- package/dist/modules/workflow/workflow-hooks.js.map +1 -1
- package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.routes.js +3 -1
- package/dist/modules/workflow/workflow.routes.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +94 -13
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +258 -51
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/agent-access.gate.d.ts +94 -0
- package/dist/modules/workspace/agent-access.gate.d.ts.map +1 -0
- package/dist/modules/workspace/agent-access.gate.js +123 -0
- package/dist/modules/workspace/agent-access.gate.js.map +1 -0
- package/dist/modules/workspace/routine-write-policy.d.ts +5 -6
- package/dist/modules/workspace/routine-write-policy.d.ts.map +1 -1
- package/dist/modules/workspace/routine-write-policy.js +5 -6
- package/dist/modules/workspace/routine-write-policy.js.map +1 -1
- package/dist/modules/workspace/session-sink.d.ts +5 -5
- package/dist/modules/workspace/set-aside-clone.d.ts +46 -0
- package/dist/modules/workspace/set-aside-clone.d.ts.map +1 -0
- package/dist/modules/workspace/set-aside-clone.js +92 -0
- package/dist/modules/workspace/set-aside-clone.js.map +1 -0
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts +117 -1
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.js +190 -1
- package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +92 -3
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +115 -5
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +272 -26
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.d.ts +2 -2
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +337 -117
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/modules/write-access/write-access.d.ts +60 -0
- package/dist/modules/write-access/write-access.d.ts.map +1 -0
- package/dist/modules/write-access/write-access.js +129 -0
- package/dist/modules/write-access/write-access.js.map +1 -0
- package/dist/shared/domain-errors.d.ts +64 -0
- package/dist/shared/domain-errors.d.ts.map +1 -1
- package/dist/shared/domain-errors.js +83 -0
- package/dist/shared/domain-errors.js.map +1 -1
- package/dist/shared/git.contract.d.ts +30 -0
- package/dist/shared/git.contract.d.ts.map +1 -1
- package/dist/shared/git.contract.js +26 -0
- package/dist/shared/git.contract.js.map +1 -1
- package/dist/tenancy/static-tenant-source.d.ts +0 -1
- package/dist/tenancy/static-tenant-source.d.ts.map +1 -1
- package/dist/tenancy/static-tenant-source.js +0 -2
- package/dist/tenancy/static-tenant-source.js.map +1 -1
- package/migrations/0014_change_request_closed_reason.sql +1 -0
- package/migrations/0015_account_deactivation.sql +3 -0
- package/migrations/meta/0014_snapshot.json +2265 -0
- package/migrations/meta/0015_snapshot.json +2271 -0
- package/migrations/meta/_journal.json +14 -0
- package/package.json +3 -3
- package/src/__tests__/kb-layout-config.test.ts +0 -2
- package/src/__tests__/retired-settings.test.ts +96 -0
- package/src/core/__tests__/gated-boot.test.ts +132 -0
- package/src/core/__tests__/lifecycle.test.ts +170 -1
- package/src/core/__tests__/set-aside-root-is-one-place.test.ts +63 -0
- package/src/core/core-ports.ts +11 -1
- package/src/core/create-core-server.ts +69 -15
- package/src/core/create-core-services.ts +190 -27
- package/src/core/lifecycle.ts +98 -13
- package/src/core-config.ts +13 -14
- package/src/index.ts +12 -1
- package/src/modules/access/__tests__/access-control.preview-relocation.test.ts +385 -0
- package/src/modules/access/__tests__/access-control.prospective.test.ts +94 -18
- package/src/modules/access/__tests__/access-requests.recut.test.ts +134 -0
- package/src/modules/access/__tests__/access-requests.routes.test.ts +610 -0
- package/src/modules/access/__tests__/access.routes.prospective.test.ts +6 -7
- package/src/modules/access/access-control.interface.ts +43 -12
- package/src/modules/access/access-control.service.ts +234 -36
- package/src/modules/access/access-requests.contract.ts +93 -0
- package/src/modules/access/access-requests.routes.ts +286 -0
- package/src/modules/access/access-requests.service.ts +420 -0
- package/src/modules/access/access.routes.ts +13 -15
- package/src/modules/access-model/access-grammar.ts +22 -0
- package/src/modules/agent-instructions/__tests__/agent-instructions.route.test.ts +3 -1
- package/src/modules/auth/__tests__/account-deactivation.test.ts +252 -0
- package/src/modules/auth/__tests__/account.routes.test.ts +81 -3
- package/src/modules/auth/__tests__/auth.middleware.test.ts +45 -22
- package/src/modules/auth/__tests__/auth.service.test.ts +39 -1
- package/src/modules/auth/account-admission.ts +78 -9
- package/src/modules/auth/account.routes.ts +63 -7
- package/src/modules/auth/auth.middleware.ts +19 -8
- package/src/modules/auth/auth.routes.ts +8 -0
- package/src/modules/auth/auth.service.ts +207 -7
- package/src/modules/auth/oidc-auth-provider.ts +7 -2
- package/src/modules/database/core-schema.ts +35 -27
- package/src/modules/github-app/__tests__/github-app.test.ts +848 -0
- package/src/modules/github-app/github-app.client.ts +268 -0
- package/src/modules/github-app/github-app.connection.ts +204 -0
- package/src/modules/github-app/github-app.routes.ts +359 -0
- package/src/modules/github-app/index.ts +19 -0
- package/src/modules/kb-fs/__tests__/branch-name.test.ts +10 -0
- package/src/modules/kb-fs/__tests__/remote-url.test.ts +38 -0
- package/src/modules/kb-fs/__tests__/repo-path.test.ts +123 -0
- package/src/modules/kb-fs/branch-name.ts +14 -1
- package/src/modules/kb-fs/remote-url.ts +35 -0
- package/src/modules/kb-fs/repo-path.ts +85 -0
- package/src/modules/kb-sync/__tests__/kb-sync.routes.test.ts +26 -1
- package/src/modules/kb-sync/kb-sync.routes.ts +14 -4
- package/src/modules/kb-sync/sync-auth.ts +2 -2
- package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +60 -3
- package/src/modules/mcp/__tests__/mcp.service.test.ts +68 -6
- package/src/modules/mcp/mcp-auth.middleware.ts +20 -6
- package/src/modules/mcp/oauth/bevel-oauth-provider.ts +3 -1
- package/src/modules/plugins/__tests__/join-proposals.test.ts +100 -19
- package/src/modules/plugins/__tests__/join-requests.service.test.ts +27 -11
- package/src/modules/plugins/__tests__/join-requests.settlement.test.ts +371 -0
- package/src/modules/plugins/__tests__/plugins.routes.test.ts +1 -1
- package/src/modules/plugins/__tests__/plugins.tools.test.ts +2 -1
- package/src/modules/plugins/join-proposals.ts +87 -19
- package/src/modules/plugins/join-requests.service.ts +199 -39
- package/src/modules/plugins/plugins.routes.ts +3 -2
- package/src/modules/settings/__tests__/deployment-settings.service.test.ts +16 -0
- package/src/modules/settings/__tests__/repository-source.test.ts +191 -0
- package/src/modules/settings/__tests__/setup.routes.git-mode.test.ts +386 -0
- package/src/modules/settings/__tests__/setup.routes.github-app.test.ts +299 -0
- package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +236 -0
- package/src/modules/settings/__tests__/setup.routes.repository-change.test.ts +390 -0
- package/src/modules/settings/__tests__/setup.routes.test.ts +3 -0
- package/src/modules/settings/deployment-settings.service.ts +117 -6
- package/src/modules/settings/managed-repository.ts +68 -0
- package/src/modules/settings/repository-source.ts +197 -0
- package/src/modules/settings/setup.routes.ts +463 -15
- package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +2 -1
- package/src/modules/skills/__tests__/branch-skills.tools.test.ts +218 -0
- package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +5 -1
- package/src/modules/skills/__tests__/skills.service.test.ts +229 -5
- package/src/modules/skills/skill-access-requests.routes.ts +25 -75
- package/src/modules/skills/skills.contract.ts +91 -18
- package/src/modules/skills/skills.service.ts +278 -41
- package/src/modules/skills/skills.tools.ts +80 -8
- package/src/modules/tool-auth/__tests__/manual-auth.middleware.test.ts +14 -1
- package/src/modules/tool-auth/external-api-key.service.ts +4 -2
- package/src/modules/tool-auth/internal-token.service.ts +3 -3
- package/src/modules/tool-auth/tool-auth.middleware.ts +34 -11
- package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +5 -3
- package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +3 -3
- package/src/modules/tool-helpers/__tests__/validate-token.test.ts +11 -1
- package/src/modules/tool-helpers/tool-context.ts +15 -0
- package/src/modules/tool-helpers/tool-handler.ts +24 -4
- package/src/modules/tool-helpers/tool.contract.ts +3 -2
- package/src/modules/tool-helpers/validate-token.ts +1 -1
- package/src/modules/workflow/__tests__/apply-failure.test.ts +9 -1
- package/src/modules/workflow/__tests__/pending-commits.repository-replaced.test.ts +111 -0
- package/src/modules/workflow/__tests__/workflow.routes.history-read-gate.test.ts +25 -0
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +159 -8
- package/src/modules/workflow/__tests__/workflow.service.repository-replaced.test.ts +249 -0
- package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +146 -40
- package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +405 -7
- package/src/modules/workflow/agent-tools/change-request-summary.ts +182 -0
- package/src/modules/workflow/agent-tools/workflow.tools.ts +135 -38
- package/src/modules/workflow/file-lock.service.ts +31 -0
- package/src/modules/workflow/git/__tests__/git.service.fileBytesAtCommit.test.ts +260 -0
- package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +121 -0
- package/src/modules/workflow/git/__tests__/pull-request.service.getPrDetail.test.ts +145 -2
- package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-delete.test.ts +166 -0
- package/src/modules/workflow/git/git.service.ts +193 -4
- package/src/modules/workflow/git/node-git-runner.ts +6 -0
- package/src/modules/workflow/git/pull-request.service.ts +119 -0
- package/src/modules/workflow/pending-commits.service.ts +59 -1
- package/src/modules/workflow/workflow-hooks.ts +64 -26
- package/src/modules/workflow/workflow.routes.ts +3 -1
- package/src/modules/workflow/workflow.service.ts +290 -55
- package/src/modules/workspace/__tests__/agent-access.gate.test.ts +208 -0
- package/src/modules/workspace/__tests__/escape-sequences.routes.test.ts +384 -0
- package/src/modules/workspace/__tests__/file-stat-access.test.ts +2 -1
- package/src/modules/workspace/__tests__/git-internals.security.test.ts +2 -1
- package/src/modules/workspace/__tests__/set-aside-clone.test.ts +52 -0
- package/src/modules/workspace/__tests__/workspace.routes.at-ref.test.ts +305 -0
- package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +2 -0
- package/src/modules/workspace/__tests__/workspace.service.forget-clone-races.test.ts +147 -0
- package/src/modules/workspace/__tests__/workspace.service.replaced-repository.test.ts +326 -0
- package/src/modules/workspace/__tests__/workspace.service.test.ts +20 -9
- package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +43 -0
- package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +2 -3
- package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +235 -10
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +720 -17
- package/src/modules/workspace/agent-access.gate.ts +164 -0
- package/src/modules/workspace/routine-write-policy.ts +5 -6
- package/src/modules/workspace/session-sink.ts +5 -5
- package/src/modules/workspace/set-aside-clone.ts +96 -0
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +297 -0
- package/src/modules/workspace/startup/kb-startup-runner.ts +242 -2
- package/src/modules/workspace/workspace.routes.ts +95 -3
- package/src/modules/workspace/workspace.service.ts +273 -25
- package/src/modules/workspace/workspace.tools.ts +373 -119
- package/src/modules/write-access/__tests__/write-access.test.ts +248 -0
- package/src/modules/write-access/write-access.ts +153 -0
- package/src/shared/domain-errors.ts +89 -0
- package/src/shared/git.contract.ts +37 -0
- package/src/tenancy/__tests__/static-tenant-source.test.ts +0 -1
- package/src/tenancy/static-tenant-source.ts +0 -3
- package/dist/modules/workflow/session-ontology.policy.d.ts +0 -52
- package/dist/modules/workflow/session-ontology.policy.d.ts.map +0 -1
- package/dist/modules/workflow/session-ontology.policy.js +0 -62
- package/dist/modules/workflow/session-ontology.policy.js.map +0 -1
- package/dist/modules/workflow/session-ontology.service.d.ts +0 -105
- package/dist/modules/workflow/session-ontology.service.d.ts.map +0 -1
- package/dist/modules/workflow/session-ontology.service.js +0 -147
- package/dist/modules/workflow/session-ontology.service.js.map +0 -1
- package/dist/modules/workspace/session-ontology.gate.d.ts +0 -114
- package/dist/modules/workspace/session-ontology.gate.d.ts.map +0 -1
- package/dist/modules/workspace/session-ontology.gate.js +0 -161
- package/dist/modules/workspace/session-ontology.gate.js.map +0 -1
- package/dist/shared/kb-layout.d.ts +0 -39
- package/dist/shared/kb-layout.d.ts.map +0 -1
- package/dist/shared/kb-layout.js +0 -103
- package/dist/shared/kb-layout.js.map +0 -1
- package/dist/shared/kb-layout.test.d.ts +0 -2
- package/dist/shared/kb-layout.test.d.ts.map +0 -1
- package/dist/shared/kb-layout.test.js +0 -75
- package/dist/shared/kb-layout.test.js.map +0 -1
- package/src/modules/workflow/__tests__/session-ontology.policy.test.ts +0 -62
- package/src/modules/workflow/__tests__/session-ontology.service.test.ts +0 -201
- package/src/modules/workflow/session-ontology.policy.ts +0 -70
- package/src/modules/workflow/session-ontology.service.ts +0 -183
- package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +0 -239
- package/src/modules/workspace/session-ontology.gate.ts +0 -191
- package/src/shared/kb-layout.test.ts +0 -98
- package/src/shared/kb-layout.ts +0 -102
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import type { AuthUser } from '@bevel-software/platform-shared';
|
|
3
|
+
import type { IWorkflowService } from '@bevel-software/platform-shared';
|
|
4
|
+
import { logger } from '../../shared/logging.js';
|
|
5
|
+
import type { KbContext } from '../../shared/kb-context.js';
|
|
6
|
+
import { branchForWorkspaceId } from '../../shared/workspace-id.js';
|
|
7
|
+
import type { AuthService } from '../auth/auth.service.js';
|
|
8
|
+
import type { WorkspaceService } from '../workspace/workspace.service.js';
|
|
9
|
+
import type { IAccessControl } from './access-control.interface.js';
|
|
10
|
+
import {
|
|
11
|
+
AccessMutationError,
|
|
12
|
+
AccessMutationService,
|
|
13
|
+
fileCarriesAccessRules,
|
|
14
|
+
governingFolderOf,
|
|
15
|
+
type TargetKind,
|
|
16
|
+
} from './access-mutation.service.js';
|
|
17
|
+
import { toHttpError as sharedToHttpError } from './admin-route-helpers.js';
|
|
18
|
+
import {
|
|
19
|
+
isRequestLevel,
|
|
20
|
+
rulesFileFor,
|
|
21
|
+
REQUEST_NOTE_MAX,
|
|
22
|
+
type AccessRequestTarget,
|
|
23
|
+
type IAccessRequestLifecycle,
|
|
24
|
+
} from './access-requests.contract.js';
|
|
25
|
+
import {
|
|
26
|
+
AccessRequestsService,
|
|
27
|
+
extractRequestNote,
|
|
28
|
+
itemNameOf,
|
|
29
|
+
} from './access-requests.service.js';
|
|
30
|
+
import '../auth/auth.middleware.js'; // Express Request.userId augmentation
|
|
31
|
+
|
|
32
|
+
const log = logger('access.request');
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Asking for Can edit or Owner on one item, and the editors' answer.
|
|
36
|
+
*
|
|
37
|
+
* POST /api/workspace/:id/access/request → { ok, number, state, level }
|
|
38
|
+
* GET /api/workspace/:id/access/request?path=&kind= → { state, level?, number? }
|
|
39
|
+
* GET /api/workspace/:id/access/requests?path=&kind= → { requests } (editors)
|
|
40
|
+
* POST /api/workspace/:id/access/requests/:n/reconcile → { closed }
|
|
41
|
+
*
|
|
42
|
+
* LIVE WORKSPACE ONLY. A draft branch's rules may differ from the ones the
|
|
43
|
+
* person is asking about, and a request opened against a draft would propose a
|
|
44
|
+
* grant into a branch nobody merges — so every route here refuses any
|
|
45
|
+
* workspace but the default one, rather than quietly retargeting.
|
|
46
|
+
*
|
|
47
|
+
* Fail-closed like the rest of the access family: an item the caller cannot
|
|
48
|
+
* read answers as unknown, and the editors' listing answers `[]` to everyone
|
|
49
|
+
* else rather than 403 — "am I an editor here" stays a question only the
|
|
50
|
+
* server answers.
|
|
51
|
+
*/
|
|
52
|
+
export function createAccessRequestRoutes(deps: {
|
|
53
|
+
accessControl: IAccessControl;
|
|
54
|
+
workspaceService: WorkspaceService;
|
|
55
|
+
authService: AuthService;
|
|
56
|
+
workflow: IWorkflowService;
|
|
57
|
+
lifecycle: IAccessRequestLifecycle;
|
|
58
|
+
kb: KbContext;
|
|
59
|
+
}): express.Router {
|
|
60
|
+
const { accessControl, workspaceService, authService, workflow, lifecycle, kb } = deps;
|
|
61
|
+
const { kbDirName } = kb;
|
|
62
|
+
const router = express.Router({ mergeParams: true });
|
|
63
|
+
const mutation = new AccessMutationService(workspaceService, accessControl, kbDirName);
|
|
64
|
+
const requests = new AccessRequestsService({ workflow, workspaceService, lifecycle, kb });
|
|
65
|
+
|
|
66
|
+
async function requireUser(
|
|
67
|
+
req: express.Request,
|
|
68
|
+
res: express.Response,
|
|
69
|
+
): Promise<AuthUser | null> {
|
|
70
|
+
if (!req.userId) {
|
|
71
|
+
res.status(401).json({ error: 'Unauthenticated' });
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const user = await authService.getUserById(req.userId);
|
|
75
|
+
if (!user) {
|
|
76
|
+
res.status(401).json({ error: 'User not found' });
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
return user;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Workspace-relative (what the dialog holds) → repo-relative (what the model speaks). */
|
|
83
|
+
function toRepoRelative(p: string): string {
|
|
84
|
+
const prefix = `${kbDirName}/`;
|
|
85
|
+
if (p === kbDirName) return '';
|
|
86
|
+
return p.startsWith(prefix) ? p.slice(prefix.length) : p;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Refuse a target that could escape the KB repo, or that is spelled in more
|
|
91
|
+
* than one way. Mirrors the grant route's guard — the branch name and the
|
|
92
|
+
* spliced path are both derived from this string, so two spellings of one
|
|
93
|
+
* item would be two different requests.
|
|
94
|
+
*/
|
|
95
|
+
function assertSafeTarget(repoRelTarget: string, kind: TargetKind): void {
|
|
96
|
+
if (kind === 'file' && !repoRelTarget) {
|
|
97
|
+
throw new AccessMutationError('file path is required');
|
|
98
|
+
}
|
|
99
|
+
if (
|
|
100
|
+
repoRelTarget.startsWith('/') ||
|
|
101
|
+
repoRelTarget.includes('\\') ||
|
|
102
|
+
repoRelTarget.includes('\0') ||
|
|
103
|
+
repoRelTarget.split('/').some((s) => s === '..' || s === '.')
|
|
104
|
+
) {
|
|
105
|
+
throw new AccessMutationError('path must stay inside the KB repo');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The (live workspace, readable item) pair every route here needs, or null
|
|
111
|
+
* after the refusal has been answered.
|
|
112
|
+
*
|
|
113
|
+
* The two refusals are deliberately different shapes: a non-default
|
|
114
|
+
* workspace is the CALLER asking the wrong question (400), while an item the
|
|
115
|
+
* caller cannot read answers exactly as one that does not exist (404) — a
|
|
116
|
+
* 403 would confirm the item is there.
|
|
117
|
+
*/
|
|
118
|
+
async function resolveTarget(
|
|
119
|
+
req: express.Request,
|
|
120
|
+
res: express.Response,
|
|
121
|
+
rawPath: unknown,
|
|
122
|
+
rawKind: unknown,
|
|
123
|
+
): Promise<{ user: AuthUser; target: AccessRequestTarget; wsId: string } | null> {
|
|
124
|
+
const user = await requireUser(req, res);
|
|
125
|
+
if (!user) return null;
|
|
126
|
+
const wsId = kb.defaultWorkspaceId();
|
|
127
|
+
if (branchForWorkspaceId(String(req.params.id)) !== kb.defaultBranch) {
|
|
128
|
+
res.status(400).json({
|
|
129
|
+
error: 'Access requests are only made on the live workspace.',
|
|
130
|
+
kind: 'not-live-workspace',
|
|
131
|
+
});
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
if (typeof rawPath !== 'string') {
|
|
135
|
+
res.status(400).json({ error: 'path is required', kind: 'access-error' });
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const kind: TargetKind = rawKind === 'folder' ? 'folder' : 'file';
|
|
139
|
+
const target: AccessRequestTarget = { path: toRepoRelative(rawPath), kind };
|
|
140
|
+
try {
|
|
141
|
+
assertSafeTarget(target.path, kind);
|
|
142
|
+
} catch (err) {
|
|
143
|
+
const { status, body } = sharedToHttpError(err, 'access');
|
|
144
|
+
res.status(status).json(body);
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
if (!(await accessControl.canRead(wsId, user.email, target.path))) {
|
|
148
|
+
res.status(404).json({ error: 'Not found', kind: 'unknown-target' });
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
return { user, target, wsId };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Can the caller change this item's rules — the gate an Accept runs through. */
|
|
155
|
+
const isEditor = (wsId: string, email: string, target: AccessRequestTarget) =>
|
|
156
|
+
accessControl.canWrite(wsId, email, rulesFileFor(target));
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* A FILE that cannot hold rules of its own is governed by its folder, and
|
|
160
|
+
* there is nothing here to request. The dialog already points at the folder
|
|
161
|
+
* for these; the route says the same thing rather than splicing YAML into a
|
|
162
|
+
* PDF. Content counts as much as the name — bytes that are not text refuse
|
|
163
|
+
* too, exactly as the grant route refuses them.
|
|
164
|
+
*/
|
|
165
|
+
async function assertCanCarryRules(wsId: string, target: AccessRequestTarget): Promise<void> {
|
|
166
|
+
if (target.kind !== 'file') return;
|
|
167
|
+
if (fileCarriesAccessRules(target.path) && (await mutation.targetHoldsText(wsId, target.path))) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
throw new AccessMutationError(
|
|
171
|
+
`Access for this file is managed on its folder. Ask there instead.`,
|
|
172
|
+
409,
|
|
173
|
+
{ kind: 'folder-governs', folder: governingFolderOf(target.path) },
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
router.post('/workspace/:id/access/request', async (req, res) => {
|
|
178
|
+
const body = (req.body ?? {}) as Record<string, unknown>;
|
|
179
|
+
const ctx = await resolveTarget(req, res, body.path, body.kind);
|
|
180
|
+
if (!ctx) return;
|
|
181
|
+
const { user, target, wsId } = ctx;
|
|
182
|
+
try {
|
|
183
|
+
if (!isRequestLevel(body.level)) {
|
|
184
|
+
throw new AccessMutationError('level must be "write" or "owner"');
|
|
185
|
+
}
|
|
186
|
+
const note = typeof body.note === 'string' ? body.note : '';
|
|
187
|
+
if (typeof body.note !== 'undefined' && typeof body.note !== 'string') {
|
|
188
|
+
throw new AccessMutationError('note must be text');
|
|
189
|
+
}
|
|
190
|
+
if (note.length > REQUEST_NOTE_MAX) {
|
|
191
|
+
throw new AccessMutationError(`A note can be at most ${REQUEST_NOTE_MAX} characters.`);
|
|
192
|
+
}
|
|
193
|
+
await assertCanCarryRules(wsId, target);
|
|
194
|
+
if (await isEditor(wsId, user.email, target)) {
|
|
195
|
+
throw new AccessMutationError(
|
|
196
|
+
`You can already change who can use this ${target.kind}.`,
|
|
197
|
+
409,
|
|
198
|
+
{ kind: 'already-writable' },
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
const opened = await requests.open({
|
|
202
|
+
user,
|
|
203
|
+
target,
|
|
204
|
+
itemName: itemNameOf(target.path),
|
|
205
|
+
level: body.level,
|
|
206
|
+
note,
|
|
207
|
+
});
|
|
208
|
+
res.json({ ok: true, state: 'pending', number: opened.number, level: opened.level });
|
|
209
|
+
} catch (err) {
|
|
210
|
+
const { status, body: errBody } = sharedToHttpError(err, 'access');
|
|
211
|
+
if (status >= 500) log.error('failed to open an access request:', { err });
|
|
212
|
+
res.status(status).json(errBody);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
router.get('/workspace/:id/access/request', async (req, res) => {
|
|
217
|
+
const ctx = await resolveTarget(req, res, req.query.path, req.query.kind);
|
|
218
|
+
if (!ctx) return;
|
|
219
|
+
try {
|
|
220
|
+
res.json(await requests.status(ctx.user, ctx.target));
|
|
221
|
+
} catch (err) {
|
|
222
|
+
log.error('failed to read an access request:', { err });
|
|
223
|
+
res.status(500).json({ error: 'Failed to read the request' });
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
router.get('/workspace/:id/access/requests', async (req, res) => {
|
|
228
|
+
const ctx = await resolveTarget(req, res, req.query.path, req.query.kind);
|
|
229
|
+
if (!ctx) return;
|
|
230
|
+
const { user, target, wsId } = ctx;
|
|
231
|
+
try {
|
|
232
|
+
if (!(await isEditor(wsId, user.email, target))) {
|
|
233
|
+
res.json({ requests: [] });
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const crs = await workflow.listChangeRequests();
|
|
237
|
+
const rows = await lifecycle.list(target.path, target, crs, user);
|
|
238
|
+
// The note lives in the request's description and nowhere else, so it
|
|
239
|
+
// is read back per request. Bounded by the open requests on ONE item —
|
|
240
|
+
// a handful at most — and a detail that cannot be fetched costs the
|
|
241
|
+
// note, never the line it belongs to.
|
|
242
|
+
const withNotes = await Promise.all(
|
|
243
|
+
rows.map(async (row) => {
|
|
244
|
+
const detail = await workflow
|
|
245
|
+
.getChangeRequestDetail(row.number, { patches: false })
|
|
246
|
+
.catch(() => null);
|
|
247
|
+
const note = extractRequestNote(detail?.body);
|
|
248
|
+
return note ? { ...row, note } : row;
|
|
249
|
+
}),
|
|
250
|
+
);
|
|
251
|
+
res.json({ requests: withNotes });
|
|
252
|
+
} catch (err) {
|
|
253
|
+
log.error('failed to list access requests:', { err });
|
|
254
|
+
res.status(500).json({ error: 'Failed to list access requests' });
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
router.post('/workspace/:id/access/requests/:number/reconcile', async (req, res) => {
|
|
259
|
+
const body = (req.body ?? {}) as Record<string, unknown>;
|
|
260
|
+
const ctx = await resolveTarget(req, res, body.path, body.kind);
|
|
261
|
+
if (!ctx) return;
|
|
262
|
+
const { user, target, wsId } = ctx;
|
|
263
|
+
try {
|
|
264
|
+
if (!(await isEditor(wsId, user.email, target))) {
|
|
265
|
+
res.status(404).json({ error: 'Not found' });
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const number = Number(req.params.number);
|
|
269
|
+
if (!Number.isSafeInteger(number) || number <= 0) {
|
|
270
|
+
res.status(400).json({ error: 'Invalid change request number' });
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const cr = await workflow.getChangeRequest(number);
|
|
274
|
+
if (!cr) {
|
|
275
|
+
res.status(404).json({ error: 'Not found' });
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
res.json({ closed: await lifecycle.reconcile(target.path, target, cr, user) });
|
|
279
|
+
} catch (err) {
|
|
280
|
+
log.error('failed to reconcile an access request:', { err });
|
|
281
|
+
res.status(500).json({ error: 'Failed to reconcile the request' });
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
return router;
|
|
286
|
+
}
|