@bevel-software/platform-core-backend 0.20.0 → 0.22.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/catalog-cache-invalidation.d.ts +7 -2
- package/dist/core/catalog-cache-invalidation.d.ts.map +1 -1
- package/dist/core/catalog-cache-invalidation.js +8 -9
- package/dist/core/catalog-cache-invalidation.js.map +1 -1
- package/dist/core/core-ports.d.ts +19 -0
- 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 +2 -0
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +55 -107
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +41 -4
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +183 -82
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core/lifecycle.d.ts +74 -28
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/core/lifecycle.js +157 -20
- package/dist/core/lifecycle.js.map +1 -1
- package/dist/core/public-config.d.ts +5 -1
- package/dist/core/public-config.d.ts.map +1 -1
- package/dist/core/public-config.js +7 -5
- package/dist/core/public-config.js.map +1 -1
- package/dist/core-config.d.ts +95 -1
- package/dist/core-config.d.ts.map +1 -1
- package/dist/core-config.js +24 -8
- package/dist/core-config.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +18 -1
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +19 -8
- 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 +2 -1
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +10 -10
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access/change-read-gate.d.ts +6 -3
- package/dist/modules/access/change-read-gate.d.ts.map +1 -1
- package/dist/modules/access/change-read-gate.js +9 -6
- package/dist/modules/access/change-read-gate.js.map +1 -1
- package/dist/modules/access/creator-access.d.ts +4 -2
- package/dist/modules/access/creator-access.d.ts.map +1 -1
- package/dist/modules/access/creator-access.js +7 -4
- package/dist/modules/access/creator-access.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/agent-instructions/read-preamble.d.ts +2 -1
- package/dist/modules/agent-instructions/read-preamble.d.ts.map +1 -1
- package/dist/modules/agent-instructions/read-preamble.js +6 -9
- package/dist/modules/agent-instructions/read-preamble.js.map +1 -1
- package/dist/modules/auth/account-admission.d.ts +40 -0
- package/dist/modules/auth/account-admission.d.ts.map +1 -0
- package/dist/modules/auth/account-admission.js +17 -0
- package/dist/modules/auth/account-admission.js.map +1 -0
- package/dist/modules/auth/account.routes.d.ts.map +1 -1
- package/dist/modules/auth/account.routes.js +4 -1
- package/dist/modules/auth/account.routes.js.map +1 -1
- package/dist/modules/auth/auth.service.d.ts +45 -2
- package/dist/modules/auth/auth.service.d.ts.map +1 -1
- package/dist/modules/auth/auth.service.js +44 -3
- 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 +9 -0
- package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
- package/dist/modules/connection-probe/connection-probe.service.d.ts +13 -1
- package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
- package/dist/modules/connection-probe/connection-probe.service.js +10 -2
- package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
- package/dist/modules/database/advisory-lock.d.ts +17 -0
- package/dist/modules/database/advisory-lock.d.ts.map +1 -1
- package/dist/modules/database/advisory-lock.js +24 -3
- package/dist/modules/database/advisory-lock.js.map +1 -1
- package/dist/modules/database/connection.d.ts +67 -2
- package/dist/modules/database/connection.d.ts.map +1 -1
- package/dist/modules/database/connection.js +118 -12
- package/dist/modules/database/connection.js.map +1 -1
- package/dist/modules/database/migrate.d.ts +1 -1
- package/dist/modules/database/migrate.d.ts.map +1 -1
- package/dist/modules/database/migrate.js +27 -3
- package/dist/modules/database/migrate.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 +0 -1
- package/dist/modules/kb-fs/branch-name.d.ts.map +1 -1
- package/dist/modules/kb-fs/branch-name.js +3 -3
- package/dist/modules/kb-fs/branch-name.js.map +1 -1
- package/dist/modules/kb-fs/clone-config.d.ts +9 -8
- package/dist/modules/kb-fs/clone-config.d.ts.map +1 -1
- package/dist/modules/kb-fs/clone-config.js +14 -12
- package/dist/modules/kb-fs/clone-config.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/mcp/mcp.service.d.ts +7 -0
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.service.js +4 -4
- package/dist/modules/mcp/mcp.service.js.map +1 -1
- package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +4 -4
- package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -1
- package/dist/modules/plugins/compile/marketplace-compiler.service.js +7 -10
- package/dist/modules/plugins/compile/marketplace-compiler.service.js.map +1 -1
- package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts +4 -1
- package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts.map +1 -1
- package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js +5 -3
- package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js.map +1 -1
- package/dist/modules/plugins/discovery/kb-plugin-source.d.ts +6 -1
- package/dist/modules/plugins/discovery/kb-plugin-source.d.ts.map +1 -1
- package/dist/modules/plugins/discovery/kb-plugin-source.js +14 -9
- package/dist/modules/plugins/discovery/kb-plugin-source.js.map +1 -1
- package/dist/modules/plugins/discovery/native.source.d.ts +4 -1
- package/dist/modules/plugins/discovery/native.source.d.ts.map +1 -1
- package/dist/modules/plugins/discovery/native.source.js +4 -2
- package/dist/modules/plugins/discovery/native.source.js.map +1 -1
- package/dist/modules/plugins/index.d.ts +1 -1
- package/dist/modules/plugins/index.d.ts.map +1 -1
- package/dist/modules/plugins/index.js +1 -1
- package/dist/modules/plugins/index.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-request-jobs.service.d.ts +3 -1
- package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
- package/dist/modules/plugins/join-request-jobs.service.js +6 -6
- package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
- package/dist/modules/plugins/join-requests.service.d.ts +113 -18
- package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
- package/dist/modules/plugins/join-requests.service.js +178 -33
- package/dist/modules/plugins/join-requests.service.js.map +1 -1
- package/dist/modules/plugins/plugin-links.d.ts +65 -10
- package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-links.js +136 -31
- package/dist/modules/plugins/plugin-links.js.map +1 -1
- package/dist/modules/plugins/plugin-links.service.d.ts +107 -5
- package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-links.service.js +151 -21
- package/dist/modules/plugins/plugin-links.service.js.map +1 -1
- package/dist/modules/plugins/plugin-provision.service.d.ts +10 -3
- package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-provision.service.js +33 -26
- package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
- package/dist/modules/plugins/plugin-rename.service.d.ts +4 -2
- package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-rename.service.js +10 -12
- package/dist/modules/plugins/plugin-rename.service.js.map +1 -1
- package/dist/modules/plugins/plugins.routes.d.ts +3 -0
- package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.js +48 -17
- package/dist/modules/plugins/plugins.routes.js.map +1 -1
- package/dist/modules/plugins/plugins.service.d.ts +4 -4
- package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.service.js +7 -10
- package/dist/modules/plugins/plugins.service.js.map +1 -1
- package/dist/modules/plugins/teams.routes.d.ts +4 -1
- package/dist/modules/plugins/teams.routes.d.ts.map +1 -1
- package/dist/modules/plugins/teams.routes.js +11 -9
- package/dist/modules/plugins/teams.routes.js.map +1 -1
- package/dist/modules/secrets-vault/index.d.ts +1 -1
- package/dist/modules/secrets-vault/index.d.ts.map +1 -1
- package/dist/modules/secrets-vault/index.js +1 -1
- package/dist/modules/secrets-vault/index.js.map +1 -1
- package/dist/modules/secrets-vault/secrets-variable-loader.d.ts +29 -11
- package/dist/modules/secrets-vault/secrets-variable-loader.d.ts.map +1 -1
- package/dist/modules/secrets-vault/secrets-variable-loader.js +46 -21
- package/dist/modules/secrets-vault/secrets-variable-loader.js.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +3 -0
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.js +4 -6
- package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
- package/dist/modules/settings/deployment-settings.service.d.ts +34 -9
- package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
- package/dist/modules/settings/deployment-settings.service.js +113 -26
- 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 +34 -4
- package/dist/modules/settings/setup.routes.d.ts.map +1 -1
- package/dist/modules/settings/setup.routes.js +198 -18
- package/dist/modules/settings/setup.routes.js.map +1 -1
- package/dist/modules/skills/allowed-tools-check.d.ts +4 -3
- package/dist/modules/skills/allowed-tools-check.d.ts.map +1 -1
- package/dist/modules/skills/allowed-tools-check.js +8 -8
- package/dist/modules/skills/allowed-tools-check.js.map +1 -1
- package/dist/modules/skills/pending-skills.service.d.ts +3 -1
- package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
- package/dist/modules/skills/pending-skills.service.js +9 -6
- package/dist/modules/skills/pending-skills.service.js.map +1 -1
- package/dist/modules/skills/skill-access-requests.routes.d.ts +8 -9
- package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
- package/dist/modules/skills/skill-access-requests.routes.js +26 -65
- package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
- package/dist/modules/skills/skills.routes.d.ts +4 -1
- package/dist/modules/skills/skills.routes.d.ts.map +1 -1
- package/dist/modules/skills/skills.routes.js +4 -4
- package/dist/modules/skills/skills.routes.js.map +1 -1
- package/dist/modules/skills/skills.service.d.ts +4 -2
- package/dist/modules/skills/skills.service.d.ts.map +1 -1
- package/dist/modules/skills/skills.service.js +13 -11
- package/dist/modules/skills/skills.service.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-manuals/mcp-json-discovery.d.ts +2 -1
- package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
- package/dist/modules/tool-manuals/mcp-json-discovery.js +6 -5
- package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
- package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +4 -2
- package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/mcp-server-edit.service.js +12 -10
- package/dist/modules/tool-manuals/mcp-server-edit.service.js.map +1 -1
- package/dist/modules/tool-manuals/pending-tools.service.d.ts +3 -1
- package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/pending-tools.service.js +19 -16
- package/dist/modules/tool-manuals/pending-tools.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-delete.service.d.ts +4 -2
- package/dist/modules/tool-manuals/tool-delete.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-delete.service.js +14 -12
- package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +3 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.js +7 -7
- package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts +4 -2
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.js +15 -12
- 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 +4 -6
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +3 -2
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js +47 -11
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +14 -6
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +40 -18
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/git/node-git-runner.d.ts +26 -2
- package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
- package/dist/modules/workflow/git/node-git-runner.js +40 -5
- 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/review-workflow/review-workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.js +9 -4
- package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
- package/dist/modules/workflow/session-ontology.service.d.ts +6 -1
- package/dist/modules/workflow/session-ontology.service.d.ts.map +1 -1
- package/dist/modules/workflow/session-ontology.service.js +6 -2
- package/dist/modules/workflow/session-ontology.service.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 +42 -10
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +181 -71
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/session-ontology.gate.d.ts +3 -1
- package/dist/modules/workspace/session-ontology.gate.d.ts.map +1 -1
- package/dist/modules/workspace/session-ontology.gate.js +3 -3
- package/dist/modules/workspace/session-ontology.gate.js.map +1 -1
- package/dist/modules/workspace/startup/kb-git.d.ts +4 -3
- package/dist/modules/workspace/startup/kb-git.d.ts.map +1 -1
- package/dist/modules/workspace/startup/kb-git.js +15 -13
- package/dist/modules/workspace/startup/kb-git.js.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts +70 -7
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.js +183 -38
- package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts +7 -1
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +23 -16
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts +7 -1
- package/dist/modules/workspace/startup/steps/personal-spaces.step.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/personal-spaces.step.js +12 -5
- package/dist/modules/workspace/startup/steps/personal-spaces.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts +7 -1
- package/dist/modules/workspace/startup/steps/plugin-display-names.step.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/plugin-display-names.step.js +12 -5
- package/dist/modules/workspace/startup/steps/plugin-display-names.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts +7 -1
- package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/plugin-manifests.step.js +12 -5
- package/dist/modules/workspace/startup/steps/plugin-manifests.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.d.ts +4 -1
- package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.js +14 -11
- package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts +17 -3
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/template-files.step.js +36 -30
- package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/template-source.d.ts +6 -1
- package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/template-source.js +10 -6
- package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
- package/dist/modules/workspace/workspace.routes.d.ts +2 -1
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +8 -7
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +18 -12
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +49 -29
- 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 +48 -20
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/modules/workspace/write-denial.d.ts +3 -2
- package/dist/modules/workspace/write-denial.d.ts.map +1 -1
- package/dist/modules/workspace/write-denial.js +6 -5
- package/dist/modules/workspace/write-denial.js.map +1 -1
- package/dist/shared/domain-errors.d.ts +39 -0
- package/dist/shared/domain-errors.d.ts.map +1 -1
- package/dist/shared/domain-errors.js +55 -0
- package/dist/shared/domain-errors.js.map +1 -1
- package/dist/shared/git.contract.d.ts +62 -7
- package/dist/shared/git.contract.d.ts.map +1 -1
- package/dist/shared/git.contract.js +30 -8
- package/dist/shared/git.contract.js.map +1 -1
- package/dist/shared/kb-context.d.ts +76 -0
- package/dist/shared/kb-context.d.ts.map +1 -0
- package/dist/shared/kb-context.js +108 -0
- package/dist/shared/kb-context.js.map +1 -0
- package/dist/shared/kb-layout.d.ts +3 -2
- package/dist/shared/kb-layout.d.ts.map +1 -1
- package/dist/shared/kb-layout.js +4 -3
- package/dist/shared/kb-layout.js.map +1 -1
- package/dist/shared/kb-layout.test.js +35 -27
- package/dist/shared/kb-layout.test.js.map +1 -1
- package/dist/shared/pending-proposals.d.ts +4 -1
- package/dist/shared/pending-proposals.d.ts.map +1 -1
- package/dist/shared/pending-proposals.js +3 -4
- package/dist/shared/pending-proposals.js.map +1 -1
- package/dist/shared/redact-secret.d.ts +5 -5
- package/dist/shared/redact-secret.js +5 -5
- package/dist/tenancy/index.d.ts +13 -0
- package/dist/tenancy/index.d.ts.map +1 -0
- package/dist/tenancy/index.js +13 -0
- package/dist/tenancy/index.js.map +1 -0
- package/dist/tenancy/static-tenant-source.d.ts +98 -0
- package/dist/tenancy/static-tenant-source.d.ts.map +1 -0
- package/dist/tenancy/static-tenant-source.js +220 -0
- package/dist/tenancy/static-tenant-source.js.map +1 -0
- package/dist/tenancy/tenant-host.d.ts +80 -0
- package/dist/tenancy/tenant-host.d.ts.map +1 -0
- package/dist/tenancy/tenant-host.js +217 -0
- package/dist/tenancy/tenant-host.js.map +1 -0
- package/dist/tenancy/tenant-runtime.d.ts +91 -0
- package/dist/tenancy/tenant-runtime.d.ts.map +1 -0
- package/dist/tenancy/tenant-runtime.js +174 -0
- package/dist/tenancy/tenant-runtime.js.map +1 -0
- package/dist/tenancy/tenant-secrets.d.ts +24 -0
- package/dist/tenancy/tenant-secrets.d.ts.map +1 -0
- package/dist/tenancy/tenant-secrets.js +30 -0
- package/dist/tenancy/tenant-secrets.js.map +1 -0
- package/dist/tenancy/tenant-source.contract.d.ts +45 -0
- package/dist/tenancy/tenant-source.contract.d.ts.map +1 -0
- package/dist/tenancy/tenant-source.contract.js +21 -0
- package/dist/tenancy/tenant-source.contract.js.map +1 -0
- package/migrations/0000_core_init.sql +14 -14
- package/migrations/0003_deployment_settings.sql +1 -1
- package/migrations/0005_github_facade.sql +1 -1
- package/migrations/0012_agent_audit.sql +6 -6
- package/package.json +3 -3
- package/src/__tests__/branch-model.test.ts +7 -6
- package/src/__tests__/kb-context.ts +30 -0
- package/src/__tests__/kb-layout-config.test.ts +35 -30
- package/src/core/__tests__/catalog-cache-invalidation.test.ts +2 -1
- package/src/core/__tests__/lifecycle.test.ts +78 -1
- package/src/core/__tests__/public-config.test.ts +5 -1
- package/src/core/catalog-cache-invalidation.ts +16 -11
- package/src/core/core-ports.ts +19 -0
- package/src/core/create-core-server.ts +64 -107
- package/src/core/create-core-services.ts +238 -96
- package/src/core/lifecycle.ts +214 -29
- package/src/core/public-config.ts +8 -5
- package/src/core-config.ts +107 -8
- package/src/index.ts +25 -2
- package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +2 -1
- 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.batch.test.ts +2 -1
- package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +2 -1
- package/src/modules/access/__tests__/access.routes.group-grant.test.ts +2 -1
- package/src/modules/access/__tests__/access.routes.overrides.test.ts +2 -1
- package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +2 -1
- package/src/modules/access/__tests__/access.routes.prospective.test.ts +2 -1
- package/src/modules/access/__tests__/access.routes.revoke.test.ts +2 -1
- package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -1
- package/src/modules/access/__tests__/change-read-gate.test.ts +13 -11
- package/src/modules/access/__tests__/creator-access.test.ts +3 -2
- package/src/modules/access/__tests__/roles.routes.test.ts +2 -1
- package/src/modules/access/access-control.service.ts +20 -6
- 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 +10 -13
- package/src/modules/access/change-read-gate.ts +10 -4
- package/src/modules/access/creator-access.ts +7 -2
- package/src/modules/access-model/access-grammar.ts +22 -0
- package/src/modules/agent-instructions/__tests__/read-preamble.test.ts +13 -12
- package/src/modules/agent-instructions/read-preamble.ts +10 -12
- package/src/modules/auth/__tests__/account.routes.test.ts +15 -0
- package/src/modules/auth/__tests__/auth.service.test.ts +98 -0
- package/src/modules/auth/account-admission.ts +44 -0
- package/src/modules/auth/account.routes.ts +4 -1
- package/src/modules/auth/auth.service.ts +61 -2
- package/src/modules/auth/oidc-auth-provider.ts +9 -0
- package/src/modules/connection-probe/connection-probe.service.ts +7 -1
- package/src/modules/database/__tests__/advisory-lock.test.ts +23 -1
- package/src/modules/database/__tests__/connection.test.ts +98 -0
- package/src/modules/database/__tests__/migrations-unqualified.test.ts +32 -0
- package/src/modules/database/advisory-lock.ts +28 -4
- package/src/modules/database/connection.ts +143 -13
- package/src/modules/database/migrate.ts +48 -14
- package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +2 -1
- package/src/modules/diff/__tests__/diff.service.test.ts +2 -1
- 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 +6 -6
- package/src/modules/kb-fs/__tests__/clone-config.test.ts +24 -20
- package/src/modules/kb-fs/__tests__/remote-url.test.ts +38 -0
- package/src/modules/kb-fs/branch-name.ts +3 -3
- package/src/modules/kb-fs/clone-config.ts +15 -12
- package/src/modules/kb-fs/remote-url.ts +35 -0
- package/src/modules/marketplace/__tests__/marketplace-repo.head.test.ts +2 -1
- package/src/modules/mcp/mcp.service.ts +11 -4
- package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +12 -11
- package/src/modules/plugins/__tests__/bundle-dialect.test.ts +2 -1
- package/src/modules/plugins/__tests__/compile-marketplace.test.ts +6 -4
- package/src/modules/plugins/__tests__/join-proposals.test.ts +100 -19
- package/src/modules/plugins/__tests__/join-request-jobs.service.test.ts +2 -1
- package/src/modules/plugins/__tests__/join-requests.service.test.ts +28 -11
- package/src/modules/plugins/__tests__/join-requests.settlement.test.ts +371 -0
- package/src/modules/plugins/__tests__/plugin-creation-display-name.test.ts +4 -3
- package/src/modules/plugins/__tests__/plugin-index.service.test.ts +6 -4
- package/src/modules/plugins/__tests__/plugin-links.service.test.ts +220 -5
- package/src/modules/plugins/__tests__/plugin-provision.service.test.ts +3 -1
- package/src/modules/plugins/__tests__/plugin-rename.service.test.ts +7 -6
- package/src/modules/plugins/__tests__/plugins.routes.test.ts +12 -3
- package/src/modules/plugins/__tests__/teams.routes.test.ts +2 -1
- package/src/modules/plugins/compile/marketplace-compiler.service.ts +7 -9
- package/src/modules/plugins/discovery/__tests__/kb-plugin-source.test.ts +20 -16
- package/src/modules/plugins/discovery/bundle-dialect/bundle.source.ts +9 -2
- package/src/modules/plugins/discovery/kb-plugin-source.ts +15 -8
- package/src/modules/plugins/discovery/native.source.ts +4 -1
- package/src/modules/plugins/index.ts +1 -1
- package/src/modules/plugins/join-proposals.ts +87 -19
- package/src/modules/plugins/join-request-jobs.service.ts +8 -7
- package/src/modules/plugins/join-requests.service.ts +203 -43
- package/src/modules/plugins/plugin-links.service.ts +192 -19
- package/src/modules/plugins/plugin-links.ts +147 -27
- package/src/modules/plugins/plugin-provision.service.ts +54 -27
- package/src/modules/plugins/plugin-rename.service.ts +10 -10
- package/src/modules/plugins/plugins.routes.ts +48 -17
- package/src/modules/plugins/plugins.service.ts +7 -11
- package/src/modules/plugins/teams.routes.ts +16 -8
- package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +7 -0
- package/src/modules/secrets-vault/__tests__/secrets-variable-loader.test.ts +40 -0
- package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +2 -0
- package/src/modules/secrets-vault/index.ts +2 -0
- package/src/modules/secrets-vault/secrets-variable-loader.ts +51 -21
- package/src/modules/secrets-vault/secrets-vault.routes.ts +7 -6
- package/src/modules/settings/__tests__/deployment-settings.service.test.ts +24 -11
- package/src/modules/settings/__tests__/git-root-folders.test.ts +2 -1
- package/src/modules/settings/__tests__/repository-source.test.ts +191 -0
- package/src/modules/settings/__tests__/setup.routes.boot-failure.test.ts +2 -1
- package/src/modules/settings/__tests__/setup.routes.git-mode.test.ts +353 -0
- package/src/modules/settings/__tests__/setup.routes.github-app.test.ts +282 -0
- package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +7 -4
- package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +233 -0
- package/src/modules/settings/__tests__/setup.routes.oidc.test.ts +2 -0
- package/src/modules/settings/__tests__/setup.routes.sync-status.test.ts +2 -0
- package/src/modules/settings/__tests__/setup.routes.test.ts +33 -52
- package/src/modules/settings/deployment-settings.service.ts +130 -23
- 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 +233 -19
- package/src/modules/skills/__tests__/allowed-tools-check.test.ts +11 -10
- package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +4 -3
- package/src/modules/skills/__tests__/pending-skills.service.test.ts +3 -1
- package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +7 -2
- package/src/modules/skills/__tests__/skills.routes.warnings.test.ts +2 -1
- package/src/modules/skills/__tests__/skills.service.test.ts +3 -2
- package/src/modules/skills/allowed-tools-check.ts +7 -6
- package/src/modules/skills/pending-skills.service.ts +9 -8
- package/src/modules/skills/skill-access-requests.routes.ts +29 -79
- package/src/modules/skills/skills.routes.ts +4 -3
- package/src/modules/skills/skills.service.ts +13 -9
- package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +3 -2
- package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +3 -2
- package/src/modules/tool-helpers/tool-context.ts +15 -0
- package/src/modules/tool-manuals/__tests__/mcp-json-discovery.test.ts +17 -12
- package/src/modules/tool-manuals/__tests__/mcp-server-edit.service.test.ts +2 -1
- package/src/modules/tool-manuals/__tests__/pending-tools.service.test.ts +4 -1
- package/src/modules/tool-manuals/__tests__/tool-delete.service.test.ts +2 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +2 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.cli.test.ts +5 -4
- package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +2 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.routes.test.ts +4 -2
- package/src/modules/tool-manuals/__tests__/tool-manuals.invalid.test.ts +13 -5
- package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +2 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.restart.test.ts +9 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +3 -2
- package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +2 -0
- package/src/modules/tool-manuals/mcp-json-discovery.ts +6 -4
- package/src/modules/tool-manuals/mcp-server-edit.service.ts +13 -11
- package/src/modules/tool-manuals/pending-tools.service.ts +19 -16
- package/src/modules/tool-manuals/tool-delete.service.ts +13 -10
- package/src/modules/tool-manuals/tool-manuals.routes.ts +10 -8
- package/src/modules/tool-manuals/tool-manuals.service.ts +15 -13
- package/src/modules/tool-manuals/tool-manuals.tools.ts +7 -6
- package/src/modules/workflow/__tests__/apply-failure.test.ts +11 -2
- package/src/modules/workflow/__tests__/merge-announces-tree.test.ts +14 -26
- package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +2 -1
- package/src/modules/workflow/__tests__/session-ontology.service.test.ts +3 -2
- package/src/modules/workflow/__tests__/workflow.routes.lock-path.test.ts +2 -1
- package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +3 -10
- package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +2 -1
- package/src/modules/workflow/__tests__/workflow.service.deleted-branch-sweep.test.ts +3 -10
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +187 -35
- package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +2 -1
- package/src/modules/workflow/__tests__/workflow.service.platform-restore.test.ts +2 -1
- package/src/modules/workflow/__tests__/workflow.service.read-gate.test.ts +3 -2
- package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +2 -1
- package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +5 -4
- package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +148 -41
- package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +143 -2
- package/src/modules/workflow/agent-tools/workflow.tools.ts +60 -12
- package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +5 -4
- package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +12 -11
- package/src/modules/workflow/git/__tests__/git.service.commitChanges.test.ts +9 -8
- package/src/modules/workflow/git/__tests__/git.service.commitFile.strayPath.test.ts +8 -7
- package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +6 -5
- package/src/modules/workflow/git/__tests__/git.service.createBranch.test.ts +3 -2
- package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +3 -2
- package/src/modules/workflow/git/__tests__/git.service.diffFileAtCommit.test.ts +7 -6
- package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +16 -15
- package/src/modules/workflow/git/__tests__/git.service.fileContentsAtCommit.test.ts +3 -2
- package/src/modules/workflow/git/__tests__/git.service.forkPoint.test.ts +2 -1
- package/src/modules/workflow/git/__tests__/git.service.history-guards.test.ts +2 -1
- package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +10 -9
- package/src/modules/workflow/git/__tests__/git.service.listTrackedFiles.test.ts +2 -1
- package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +6 -5
- package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +9 -8
- package/src/modules/workflow/git/__tests__/git.service.pendingChanges.test.ts +2 -1
- package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +4 -3
- package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +130 -8
- package/src/modules/workflow/git/__tests__/git.service.readFileAtRef.test.ts +2 -1
- package/src/modules/workflow/git/__tests__/git.service.revertPathsAndPush.test.ts +2 -1
- package/src/modules/workflow/git/__tests__/git.service.status.test.ts +4 -3
- package/src/modules/workflow/git/__tests__/git.service.syncFromRemote.test.ts +8 -7
- package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +41 -3
- 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 +49 -17
- package/src/modules/workflow/git/node-git-runner.ts +43 -4
- package/src/modules/workflow/git/pull-request.service.ts +119 -0
- package/src/modules/workflow/review-workflow/review-workflow.service.ts +9 -6
- package/src/modules/workflow/session-ontology.service.ts +7 -2
- package/src/modules/workflow/workflow.routes.ts +3 -1
- package/src/modules/workflow/workflow.service.ts +201 -76
- package/src/modules/workspace/__tests__/file-stat-access.test.ts +3 -2
- package/src/modules/workspace/__tests__/git-internals.security.test.ts +10 -9
- package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +4 -2
- package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -2
- package/src/modules/workspace/__tests__/workspace.routes.branch-errors.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.routes.download-implies-read.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.routes.file-writes.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +5 -4
- package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +6 -5
- package/src/modules/workspace/__tests__/workspace.service.move-never-overwrites.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.test.ts +84 -50
- package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +45 -1
- package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +10 -7
- package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +237 -10
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +44 -11
- package/src/modules/workspace/__tests__/write-denial.test.ts +5 -4
- package/src/modules/workspace/session-ontology.gate.ts +6 -4
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +6 -2
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +240 -21
- package/src/modules/workspace/startup/kb-git.ts +15 -22
- package/src/modules/workspace/startup/kb-startup-runner.ts +198 -45
- package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +104 -98
- package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +24 -16
- package/src/modules/workspace/startup/steps/personal-spaces.step.ts +14 -5
- package/src/modules/workspace/startup/steps/plugin-display-names.step.ts +13 -5
- package/src/modules/workspace/startup/steps/plugin-manifests.step.ts +14 -5
- package/src/modules/workspace/startup/steps/seed-tree.ts +11 -9
- package/src/modules/workspace/startup/steps/template-files.step.ts +43 -34
- package/src/modules/workspace/startup/steps/template-source.ts +8 -5
- package/src/modules/workspace/workspace.routes.ts +8 -7
- package/src/modules/workspace/workspace.service.ts +47 -28
- package/src/modules/workspace/workspace.tools.ts +56 -20
- package/src/modules/workspace/write-denial.ts +7 -5
- package/src/shared/__tests__/kb-layout.plugin.test.ts +19 -16
- package/src/shared/domain-errors.ts +58 -0
- package/src/shared/git.contract.ts +80 -8
- package/src/shared/kb-context.ts +130 -0
- package/src/shared/kb-layout.test.ts +37 -27
- package/src/shared/kb-layout.ts +4 -3
- package/src/shared/pending-proposals.ts +7 -4
- package/src/shared/redact-secret.ts +5 -5
- package/src/tenancy/__tests__/static-tenant-source.test.ts +177 -0
- package/src/tenancy/__tests__/tenant-host.test.ts +372 -0
- package/src/tenancy/__tests__/tenant-runtime.test.ts +221 -0
- package/src/tenancy/__tests__/tenant-secrets.test.ts +35 -0
- package/src/tenancy/index.ts +35 -0
- package/src/tenancy/static-tenant-source.ts +296 -0
- package/src/tenancy/tenant-host.ts +261 -0
- package/src/tenancy/tenant-runtime.ts +208 -0
- package/src/tenancy/tenant-secrets.ts +41 -0
- package/src/tenancy/tenant-source.contract.ts +59 -0
|
@@ -43,6 +43,7 @@ import type {
|
|
|
43
43
|
ChangeRequestApplyFailureKind,
|
|
44
44
|
ChangeRequestComment,
|
|
45
45
|
ChangeRequestDetail,
|
|
46
|
+
ChangeRequestUpdateResult,
|
|
46
47
|
ChangeRequestState,
|
|
47
48
|
ChangedFile,
|
|
48
49
|
FileApproval,
|
|
@@ -57,16 +58,16 @@ import type {
|
|
|
57
58
|
RemoteSyncPullResult,
|
|
58
59
|
} from '@bevel-software/platform-shared';
|
|
59
60
|
import {
|
|
60
|
-
isProtectedBranch,
|
|
61
|
-
DEFAULT_BRANCH,
|
|
62
61
|
isFolderPlaceholder,
|
|
63
62
|
folderPlaceholderPath,
|
|
64
63
|
isPlatformRestoreShape,
|
|
65
64
|
} from '@bevel-software/platform-shared';
|
|
66
|
-
import {
|
|
65
|
+
import type { KbContext } from '../../shared/kb-context.js';
|
|
66
|
+
import { and, desc, eq, inArray, isNotNull, isNull, lt, ne, or } from 'drizzle-orm';
|
|
67
67
|
import type { Database } from '../database/connection.js';
|
|
68
68
|
import { changeRequests } from '../database/schema.js';
|
|
69
69
|
import type { GitService } from './git/git.service.js';
|
|
70
|
+
import { redactSecret } from '../../shared/redact-secret.js';
|
|
70
71
|
import type { PullRequestService } from './git/pull-request.service.js';
|
|
71
72
|
import type { IReviewWorkflowService } from './review-workflow/review-workflow.interface.js';
|
|
72
73
|
import type { WorkspaceService } from '../workspace/workspace.service.js';
|
|
@@ -156,12 +157,13 @@ export function syncConflictMessage(branch: string, conflictedPaths: string[]):
|
|
|
156
157
|
/** How many conflicted files the sync-conflict sentence names before "and N more". */
|
|
157
158
|
const SYNC_CONFLICT_FILES_NAMED = 3;
|
|
158
159
|
|
|
159
|
-
/**
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Redact a git token from an error string before surfacing it: the one the
|
|
162
|
+
* knowledge base's runner authenticates with, plus whatever the environment
|
|
163
|
+
* holds (`redactSecret` names those itself).
|
|
164
|
+
*/
|
|
165
|
+
function redactTokens(msg: string, token: string | null | undefined): string {
|
|
166
|
+
return redactSecret(msg, [token]);
|
|
165
167
|
}
|
|
166
168
|
|
|
167
169
|
/**
|
|
@@ -275,6 +277,10 @@ export class WorkflowService implements IWorkflowService {
|
|
|
275
277
|
* implementation detail of the workflow auto-merge story; nothing outside
|
|
276
278
|
* the facade should call it directly.
|
|
277
279
|
*/
|
|
280
|
+
private get kbDirName(): string {
|
|
281
|
+
return this.kb.kbDirName;
|
|
282
|
+
}
|
|
283
|
+
|
|
278
284
|
constructor(
|
|
279
285
|
private readonly db: Database,
|
|
280
286
|
private readonly git: GitService,
|
|
@@ -291,7 +297,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
291
297
|
* See `lock-decoupling-plan.md` for the full design.
|
|
292
298
|
*/
|
|
293
299
|
private readonly pendingCommits: PendingCommitsService,
|
|
294
|
-
private readonly
|
|
300
|
+
private readonly kb: KbContext,
|
|
295
301
|
/**
|
|
296
302
|
* The read-before-write gate `acquireLock` asks on every branch (see
|
|
297
303
|
* `access-model/change-gate.ts`). Required, and checked at construction:
|
|
@@ -419,7 +425,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
419
425
|
fn: () => Promise<T>,
|
|
420
426
|
): Promise<T> {
|
|
421
427
|
const keys = [`branch:${source}`];
|
|
422
|
-
if (!isProtectedBranch(target)) keys.push(`branch:${target}`);
|
|
428
|
+
if (!this.kb.isProtectedBranch(target)) keys.push(`branch:${target}`);
|
|
423
429
|
return this.branchLifecycle.runAll(keys, fn);
|
|
424
430
|
}
|
|
425
431
|
|
|
@@ -571,10 +577,14 @@ export class WorkflowService implements IWorkflowService {
|
|
|
571
577
|
* and nothing else. The pull itself reports the change, since it is the
|
|
572
578
|
* only code that can observe it under the workspace mutex.
|
|
573
579
|
*/
|
|
574
|
-
private async pullWorkspace(
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
580
|
+
private async pullWorkspace(
|
|
581
|
+
workspaceId: string,
|
|
582
|
+
opts: { preserveMerges?: boolean } = {},
|
|
583
|
+
): Promise<boolean> {
|
|
584
|
+
const { treeChanged } = await this.git.pull(workspaceId, opts);
|
|
585
|
+
const defaultBranch = this.kb.defaultBranch;
|
|
586
|
+
if (treeChanged && branchForWorkspaceId(workspaceId) === defaultBranch) {
|
|
587
|
+
this.events?.emit({ kind: 'fs-tree-changed', workspaceId, branch: defaultBranch });
|
|
578
588
|
return true;
|
|
579
589
|
}
|
|
580
590
|
return false;
|
|
@@ -961,7 +971,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
961
971
|
// future caller can make that claim by passing a flag.
|
|
962
972
|
if (
|
|
963
973
|
typeof platformRestore?.source === 'string' &&
|
|
964
|
-
isPlatformRestoreShape(toRepoRelative(platformRestore.source), repoRelative) &&
|
|
974
|
+
isPlatformRestoreShape(toRepoRelative(platformRestore.source), repoRelative, this.kb.layout) &&
|
|
965
975
|
(await this.accessControl.canRestorePlatformFile(workspaceId, userEmail, repoRelative))
|
|
966
976
|
) {
|
|
967
977
|
return 'restore';
|
|
@@ -1037,7 +1047,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
1037
1047
|
// coordination hold as write possession (see those methods).
|
|
1038
1048
|
if (!opts?.coordination) {
|
|
1039
1049
|
let via: 'granted' | 'restore' = 'granted';
|
|
1040
|
-
if (isProtectedBranch(branch)) {
|
|
1050
|
+
if (this.kb.isProtectedBranch(branch)) {
|
|
1041
1051
|
// `assertCanWriteAtPath` throws AccessDeniedError on denial, with the
|
|
1042
1052
|
// eligible-writers payload so the frontend can render a useful refusal.
|
|
1043
1053
|
via = await this.assertCanWriteAtPath(
|
|
@@ -1321,7 +1331,8 @@ export class WorkflowService implements IWorkflowService {
|
|
|
1321
1331
|
branch: string,
|
|
1322
1332
|
targetPath: string,
|
|
1323
1333
|
user: AuthUser,
|
|
1324
|
-
|
|
1334
|
+
/** `summary` overrides the path-derived commit subject; see `commitFile`. */
|
|
1335
|
+
opts?: { systemAuthorized?: boolean; skipValidation?: boolean; summary?: string },
|
|
1325
1336
|
): Promise<void> {
|
|
1326
1337
|
// `skipValidation` is the worker telling us this commit is not the last of
|
|
1327
1338
|
// a burst. The validator is advisory — it parses the whole KB to produce a
|
|
@@ -1332,7 +1343,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
1332
1343
|
workspaceId,
|
|
1333
1344
|
user,
|
|
1334
1345
|
targetPath,
|
|
1335
|
-
|
|
1346
|
+
opts?.summary,
|
|
1336
1347
|
opts?.skipValidation,
|
|
1337
1348
|
);
|
|
1338
1349
|
if (!change) {
|
|
@@ -1722,6 +1733,38 @@ export class WorkflowService implements IWorkflowService {
|
|
|
1722
1733
|
return this.prs.getPr(number);
|
|
1723
1734
|
}
|
|
1724
1735
|
|
|
1736
|
+
/**
|
|
1737
|
+
* The newest non-open change request from `sourceBranch` by `authorEmail`.
|
|
1738
|
+
*
|
|
1739
|
+
* Read straight off `change_requests` rather than through the PR listing,
|
|
1740
|
+
* which serves OPEN requests only: the whole point here is the closed ones.
|
|
1741
|
+
* `author_email` is stored lowercased at insert, so the needle is too.
|
|
1742
|
+
* Ordered by `closed_at` with `created_at` as the tiebreak, because a row
|
|
1743
|
+
* closed before the column existed (or by a path that forgot to stamp it)
|
|
1744
|
+
* still has a creation time and must not sort as the oldest.
|
|
1745
|
+
*/
|
|
1746
|
+
async latestClosedChangeRequest(
|
|
1747
|
+
authorEmail: string,
|
|
1748
|
+
sourceBranch: string,
|
|
1749
|
+
): Promise<{ number: number; state: ChangeRequestState } | null> {
|
|
1750
|
+
const email = authorEmail.trim().toLowerCase();
|
|
1751
|
+
if (!email || !sourceBranch) return null;
|
|
1752
|
+
const [row] = await this.db
|
|
1753
|
+
.select({ number: changeRequests.number, state: changeRequests.state })
|
|
1754
|
+
.from(changeRequests)
|
|
1755
|
+
.where(
|
|
1756
|
+
and(
|
|
1757
|
+
eq(changeRequests.authorEmail, email),
|
|
1758
|
+
eq(changeRequests.sourceBranch, sourceBranch),
|
|
1759
|
+
ne(changeRequests.state, 'open'),
|
|
1760
|
+
),
|
|
1761
|
+
)
|
|
1762
|
+
.orderBy(desc(changeRequests.closedAt), desc(changeRequests.createdAt))
|
|
1763
|
+
.limit(1);
|
|
1764
|
+
if (!row) return null;
|
|
1765
|
+
return { number: row.number, state: row.state as ChangeRequestState };
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1725
1768
|
getChangeRequestDetail(
|
|
1726
1769
|
number: number,
|
|
1727
1770
|
opts?: { fresh?: boolean; workspaceId?: string; viewerEmail?: string; patches?: boolean },
|
|
@@ -1759,7 +1802,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
1759
1802
|
throw new WorkflowValidationError('source and target branches must differ');
|
|
1760
1803
|
}
|
|
1761
1804
|
if (!input.title?.trim()) throw new WorkflowValidationError('title is required');
|
|
1762
|
-
if (isProtectedBranch(input.sourceBranch)) {
|
|
1805
|
+
if (this.kb.isProtectedBranch(input.sourceBranch)) {
|
|
1763
1806
|
throw new WorkflowValidationError(
|
|
1764
1807
|
`Cannot open a change request *from* a protected branch ("${input.sourceBranch}").`,
|
|
1765
1808
|
{ kind: 'source-is-protected', sourceBranch: input.sourceBranch },
|
|
@@ -1897,7 +1940,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
1897
1940
|
// up-to-date) auto-merge, and inserts the row.
|
|
1898
1941
|
const rawMsg = err instanceof Error ? err.message : String(err);
|
|
1899
1942
|
throw new WorkflowValidationError(
|
|
1900
|
-
`Failed to open change request: ${redactTokens(rawMsg)}`,
|
|
1943
|
+
`Failed to open change request: ${redactTokens(rawMsg, this.git.credentials?.token())}`,
|
|
1901
1944
|
{ kind: 'open-change-request-failed' },
|
|
1902
1945
|
);
|
|
1903
1946
|
}
|
|
@@ -1946,13 +1989,29 @@ export class WorkflowService implements IWorkflowService {
|
|
|
1946
1989
|
* the enforcement read one predicate. A conflicting merge is aborted
|
|
1947
1990
|
* inside `mergeFromOrigin`: nothing is committed or pushed, and the branch
|
|
1948
1991
|
* is exactly what it was.
|
|
1992
|
+
*
|
|
1993
|
+
* ONE detail read after the merge. The read before it exists only to
|
|
1994
|
+
* decide authority and to name the two branches, so it asks for no patches
|
|
1995
|
+
* — that is one git subprocess per changed file it does not spend. The
|
|
1996
|
+
* approvals carry-forward runs BEFORE the final read rather than after it,
|
|
1997
|
+
* against a head resolved with `resolvePrShas` (two rev-parses) instead of
|
|
1998
|
+
* a whole second detail, so the detail that goes back already describes the
|
|
1999
|
+
* approvals it carried. What used to be three detail reads is now one.
|
|
1949
2000
|
*/
|
|
1950
2001
|
async updateFromTarget(
|
|
1951
2002
|
workspaceId: string,
|
|
1952
2003
|
user: AuthUser,
|
|
1953
2004
|
number: number,
|
|
1954
|
-
): Promise<
|
|
1955
|
-
|
|
2005
|
+
): Promise<ChangeRequestUpdateResult> {
|
|
2006
|
+
// No patches: all this read decides is authority, state and the two
|
|
2007
|
+
// branch names. Asking for patch text here would diff every changed file
|
|
2008
|
+
// in a request that is about to be merged and read in full anyway.
|
|
2009
|
+
const detail = await this.prs.getPrDetail(number, {
|
|
2010
|
+
fresh: true,
|
|
2011
|
+
workspaceId,
|
|
2012
|
+
viewerEmail: user.email,
|
|
2013
|
+
patches: false,
|
|
2014
|
+
});
|
|
1956
2015
|
if (!detail) {
|
|
1957
2016
|
throw new WorkflowValidationError(
|
|
1958
2017
|
`Change request #${number} not found.`,
|
|
@@ -1980,8 +2039,15 @@ export class WorkflowService implements IWorkflowService {
|
|
|
1980
2039
|
// merge commit that then cannot push, stranding it in the workspace. A
|
|
1981
2040
|
// rebase conflict hands the stranded saves to recovery, as every other
|
|
1982
2041
|
// pull does, before the refusal reaches the caller.
|
|
2042
|
+
//
|
|
2043
|
+
// `preserveMerges`: this is the one pull whose unpushed commit may be a
|
|
2044
|
+
// MERGE — the update that ran before this one and could not push. A plain
|
|
2045
|
+
// rebase replays it as cherry-picks of the target's commits, which drops
|
|
2046
|
+
// the target as a parent, so the branch never contains the target's head
|
|
2047
|
+
// however many times the update runs. Replayed with `--rebase-merges` it
|
|
2048
|
+
// stays a merge and the next push ends the loop.
|
|
1983
2049
|
try {
|
|
1984
|
-
await this.pullWorkspace(workspaceId);
|
|
2050
|
+
await this.pullWorkspace(workspaceId, { preserveMerges: true });
|
|
1985
2051
|
} catch (err) {
|
|
1986
2052
|
if (err instanceof PullRebaseConflictError) {
|
|
1987
2053
|
await this.queuePullConflictRecovery(workspaceId, err, user);
|
|
@@ -2019,24 +2085,53 @@ export class WorkflowService implements IWorkflowService {
|
|
|
2019
2085
|
if (outcome.kind === 'conflicts') {
|
|
2020
2086
|
throw new ChangeRequestConflictsError(detail.branch, detail.base, outcome.paths);
|
|
2021
2087
|
}
|
|
2022
|
-
//
|
|
2023
|
-
//
|
|
2024
|
-
|
|
2088
|
+
// Push whenever the CLONE holds a commit origin has not seen — not when
|
|
2089
|
+
// THIS merge authored one. The two differ in exactly the case that keeps
|
|
2090
|
+
// a request behind for good: an earlier update merged, its push failed,
|
|
2091
|
+
// and the merge is sitting in the workspace. That merge already contains
|
|
2092
|
+
// the target, so this call's `mergeFromOrigin` reports
|
|
2093
|
+
// `alreadyUpToDate` and the old gate skipped the push — leaving the
|
|
2094
|
+
// request behind on the remote, and the next open with the same work to
|
|
2095
|
+
// do. Asking git what is unpushed retries it instead.
|
|
2096
|
+
//
|
|
2097
|
+
// A failed probe falls back to the old gate rather than to "push
|
|
2098
|
+
// anyway": `trackedPush` on a clone with nothing to push is a wasted
|
|
2099
|
+
// round trip on every single update.
|
|
2100
|
+
const hasUnpushed = await this.git
|
|
2101
|
+
.hasUnpushedCommits(workspaceId)
|
|
2102
|
+
.catch((err: unknown) => {
|
|
2103
|
+
log.warn(
|
|
2104
|
+
`could not tell whether change request #${number} has unpushed commits; falling back to whether this merge authored one`,
|
|
2105
|
+
{ err },
|
|
2106
|
+
);
|
|
2107
|
+
return !outcome.alreadyUpToDate;
|
|
2108
|
+
});
|
|
2109
|
+
if (hasUnpushed) {
|
|
2025
2110
|
await this.trackedPush(workspaceId, user);
|
|
2026
|
-
// The source head moved: the refusal described a revision that is gone.
|
|
2027
|
-
await this.clearApplyFailure(number, { recordedBefore: headMovedAfter });
|
|
2028
2111
|
}
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2112
|
+
// Where the branch ended up, as PUBLISHED — two rev-parses, not a second
|
|
2113
|
+
// detail read. Everything below needs only the sha, and the detail that
|
|
2114
|
+
// goes back to the caller is read once, at the end, after the approvals
|
|
2115
|
+
// it should describe have been carried.
|
|
2116
|
+
let headAfterMerge = headBeforeMerge;
|
|
2117
|
+
try {
|
|
2118
|
+
const at = await this.git.resolvePrShas(workspaceId, detail.base, detail.branch);
|
|
2119
|
+
headAfterMerge = at.headSha;
|
|
2120
|
+
} catch (err) {
|
|
2121
|
+
log.warn(
|
|
2122
|
+
`could not resolve the published head of change request #${number} after updating it from target`,
|
|
2123
|
+
{ err },
|
|
2038
2124
|
);
|
|
2039
2125
|
}
|
|
2126
|
+
const headMoved = Boolean(headBeforeMerge) && headAfterMerge !== headBeforeMerge;
|
|
2127
|
+
// The source head moved: the refusal described a revision that is gone.
|
|
2128
|
+
// `hasUnpushed` counts as well as the sha comparison, and deliberately —
|
|
2129
|
+
// a push that just landed moved the published head by definition, and
|
|
2130
|
+
// reading the sha to confirm it is a call that can fail. A refusal left
|
|
2131
|
+
// standing over a revision nobody can apply any more is the worse error.
|
|
2132
|
+
if (headMoved || hasUnpushed) {
|
|
2133
|
+
await this.clearApplyFailure(number, { recordedBefore: headMovedAfter });
|
|
2134
|
+
}
|
|
2040
2135
|
// The merge is a commit the APPROVERS did not make. Re-pin their
|
|
2041
2136
|
// approvals onto the new head for every file whose bytes it left alone —
|
|
2042
2137
|
// git's own two-dot diff between the two heads is the verdict on which
|
|
@@ -2044,45 +2139,61 @@ export class WorkflowService implements IWorkflowService {
|
|
|
2044
2139
|
// than the bookkeeping, so a failure here is logged and the fresh detail
|
|
2045
2140
|
// still goes back.
|
|
2046
2141
|
//
|
|
2047
|
-
//
|
|
2048
|
-
//
|
|
2049
|
-
//
|
|
2050
|
-
//
|
|
2051
|
-
//
|
|
2052
|
-
//
|
|
2053
|
-
|
|
2142
|
+
// The head moving is the real gate: nothing moved, nothing moved under
|
|
2143
|
+
// anyone. It also covers the sha that is not a sha — a resolve that
|
|
2144
|
+
// failed onto a detail with no head — which `pathsChangedBetween` and
|
|
2145
|
+
// `carryApprovalsForward` would refuse anyway.
|
|
2146
|
+
//
|
|
2147
|
+
// This runs BEFORE the detail read, not after it. The rows it writes are
|
|
2148
|
+
// what the caller's `approvals` must describe, so doing it first means
|
|
2149
|
+
// the one read at the end is already correct — where carrying afterwards
|
|
2150
|
+
// needed a THIRD read to correct a detail assembled before the rows
|
|
2151
|
+
// existed.
|
|
2152
|
+
//
|
|
2153
|
+
// The same list answers the caller's `updatedPaths`: "which files did
|
|
2154
|
+
// this merge change" is one question, and the two answers must not be
|
|
2155
|
+
// allowed to differ — a file whose approval was carried (so: untouched)
|
|
2156
|
+
// that the dialog then re-read would be the dialog discarding content the
|
|
2157
|
+
// server just called unchanged.
|
|
2158
|
+
let updatedPaths: string[] = [];
|
|
2159
|
+
if (headMoved) {
|
|
2054
2160
|
try {
|
|
2055
|
-
|
|
2161
|
+
updatedPaths = await this.git.pathsChangedBetween(
|
|
2056
2162
|
workspaceId,
|
|
2057
2163
|
headBeforeMerge,
|
|
2058
|
-
|
|
2164
|
+
headAfterMerge,
|
|
2059
2165
|
);
|
|
2060
|
-
|
|
2166
|
+
await this.reviewWorkflow.carryApprovalsForward(
|
|
2061
2167
|
number,
|
|
2062
2168
|
headBeforeMerge,
|
|
2063
|
-
|
|
2064
|
-
|
|
2169
|
+
headAfterMerge,
|
|
2170
|
+
updatedPaths,
|
|
2065
2171
|
);
|
|
2066
|
-
// The detail above was assembled before those rows existed, so its
|
|
2067
|
-
// `approvals` (and the merge gate derived from them) still describe
|
|
2068
|
-
// the pre-merge head. Only re-read when something actually carried.
|
|
2069
|
-
if (carried > 0) {
|
|
2070
|
-
this.prs.invalidateDetailCache(number);
|
|
2071
|
-
const withApprovals = await this.prs.getPrDetail(number, {
|
|
2072
|
-
fresh: true,
|
|
2073
|
-
workspaceId,
|
|
2074
|
-
viewerEmail: user.email,
|
|
2075
|
-
});
|
|
2076
|
-
if (withApprovals) return withApprovals;
|
|
2077
|
-
}
|
|
2078
2172
|
} catch (err) {
|
|
2079
2173
|
log.warn(
|
|
2080
2174
|
`could not carry approvals forward on change request #${number} after updating from target`,
|
|
2081
2175
|
{ err },
|
|
2082
2176
|
);
|
|
2177
|
+
// The diff is what failed, so which files moved is unknown. Say so as
|
|
2178
|
+
// "every file this request had", which is every file a caller can
|
|
2179
|
+
// already be showing: slow beats a dialog that goes on presenting
|
|
2180
|
+
// pre-merge text as current. Anything the merge ADDED is not on the
|
|
2181
|
+
// list and does not need to be — no caller has read it yet.
|
|
2182
|
+
updatedPaths = (detail.files ?? []).map((f) => f.path);
|
|
2083
2183
|
}
|
|
2084
2184
|
}
|
|
2085
|
-
|
|
2185
|
+
this.prs.invalidateDetailCache(number);
|
|
2186
|
+
const refreshed = await this.prs.getPrDetail(number, {
|
|
2187
|
+
fresh: true,
|
|
2188
|
+
workspaceId,
|
|
2189
|
+
viewerEmail: user.email,
|
|
2190
|
+
});
|
|
2191
|
+
if (!refreshed) {
|
|
2192
|
+
throw new WorkflowValidationError(
|
|
2193
|
+
`Refreshed change request #${number} but could not re-fetch its detail.`,
|
|
2194
|
+
);
|
|
2195
|
+
}
|
|
2196
|
+
return { ...refreshed, updatedPaths };
|
|
2086
2197
|
}
|
|
2087
2198
|
|
|
2088
2199
|
listComments(number: number): Promise<ChangeRequestComment[]> {
|
|
@@ -2644,11 +2755,16 @@ export class WorkflowService implements IWorkflowService {
|
|
|
2644
2755
|
/**
|
|
2645
2756
|
* DELETE a change request outright: close it (whatever its diff says) and
|
|
2646
2757
|
* retire its source branch — the request, its proposal, and the branch that
|
|
2647
|
-
* carried it are gone in one verb.
|
|
2648
|
-
*
|
|
2649
|
-
*
|
|
2650
|
-
*
|
|
2651
|
-
*
|
|
2758
|
+
* carried it are gone in one verb. The request's AUTHOR or an admin, and
|
|
2759
|
+
* nobody else: it is the author's own proposal and their own branch to throw
|
|
2760
|
+
* away, and it is the moderation verb for a shared deployment. Admin rights
|
|
2761
|
+
* resolve the same way every other admin check here does (write on
|
|
2762
|
+
* `roles.yaml` at `origin/<base>`, never a local ref); authorship is the
|
|
2763
|
+
* STORED `authorId` hash, never anything the caller sends.
|
|
2764
|
+
*
|
|
2765
|
+
* Stronger than reject, which the changed files' owners may also do and which
|
|
2766
|
+
* leaves the branch for a second round. They keep reject and do not get this:
|
|
2767
|
+
* an owner must not be able to destroy someone else's text and branch.
|
|
2652
2768
|
*/
|
|
2653
2769
|
async deleteChangeRequest(number: number, user: AuthUser): Promise<void> {
|
|
2654
2770
|
const summary = await this.prs.getPr(number);
|
|
@@ -2707,8 +2823,17 @@ export class WorkflowService implements IWorkflowService {
|
|
|
2707
2823
|
409,
|
|
2708
2824
|
);
|
|
2709
2825
|
}
|
|
2710
|
-
|
|
2711
|
-
|
|
2826
|
+
// Authorship is decided from the STORED author hash, never from anything
|
|
2827
|
+
// the caller sends. Note what is deliberately NOT short-circuited for an
|
|
2828
|
+
// author: the strict fetch and the `null` check above still run. An
|
|
2829
|
+
// author's grant needs no `roles.yaml` read, so skipping them would look
|
|
2830
|
+
// free — but it would let a delete close the request while the branch
|
|
2831
|
+
// removal silently failed against an unreachable origin, and "the shared
|
|
2832
|
+
// repository was down, so nothing changed" is the one refusal that has to
|
|
2833
|
+
// stay honest.
|
|
2834
|
+
const callerIsAuthor = !!(summary.authorId && summary.authorId === hashEmail(user.email));
|
|
2835
|
+
if (!callerIsAuthor && isAdmin !== true) {
|
|
2836
|
+
throw new WorkflowDomainError("Only the request's author or an admin can delete it.", 403);
|
|
2712
2837
|
}
|
|
2713
2838
|
|
|
2714
2839
|
// Close first (idempotent: an already-closed request just skips to the
|
|
@@ -2851,7 +2976,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
2851
2976
|
|
|
2852
2977
|
let live: Set<string>;
|
|
2853
2978
|
try {
|
|
2854
|
-
const branches = await this.git.listBranches(
|
|
2979
|
+
const branches = await this.git.listBranches(this.kb.defaultWorkspaceId(), {
|
|
2855
2980
|
freshFetch: true,
|
|
2856
2981
|
// The list is used to PROVE absence, and the listing's normal
|
|
2857
2982
|
// degrade-to-stale behaviour would report every branch created since
|
|
@@ -3166,8 +3291,8 @@ export class WorkflowService implements IWorkflowService {
|
|
|
3166
3291
|
// outright if it disagrees with the request's own base.) The failure the
|
|
3167
3292
|
// pull reports is about OTHER people's commits not arriving, which leaves
|
|
3168
3293
|
// the catalogs no staler than they were.
|
|
3169
|
-
if (!announced && targetWorkspaceId && targetBranch ===
|
|
3170
|
-
this.events?.emit({ kind: 'fs-tree-changed', workspaceId: targetWorkspaceId, branch:
|
|
3294
|
+
if (!announced && targetWorkspaceId && targetBranch === this.kb.defaultBranch) {
|
|
3295
|
+
this.events?.emit({ kind: 'fs-tree-changed', workspaceId: targetWorkspaceId, branch: targetBranch });
|
|
3171
3296
|
}
|
|
3172
3297
|
}
|
|
3173
3298
|
|
|
@@ -3234,7 +3359,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
3234
3359
|
// change request's merge, nothing strips it here — so its presence
|
|
3235
3360
|
// is what the hook refuses on) and both sides of a rename, since the
|
|
3236
3361
|
// old name is a file this merge deletes.
|
|
3237
|
-
authorize: isProtectedBranch(targetBranch)
|
|
3362
|
+
authorize: this.kb.isProtectedBranch(targetBranch)
|
|
3238
3363
|
? async ({ sha, changedPaths }) => {
|
|
3239
3364
|
if (changedPaths.length === 0) return;
|
|
3240
3365
|
// roles.yaml never changes through a merge. A change request's
|
|
@@ -3445,7 +3570,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
3445
3570
|
.where(eq(changeRequests.number, number))
|
|
3446
3571
|
.limit(1);
|
|
3447
3572
|
const sourceBranch = rows[0]?.sourceBranch;
|
|
3448
|
-
if (!sourceBranch || isProtectedBranch(sourceBranch)) return;
|
|
3573
|
+
if (!sourceBranch || this.kb.isProtectedBranch(sourceBranch)) return;
|
|
3449
3574
|
// The open-check and the deletion hold the branch's lifecycle lock
|
|
3450
3575
|
// TOGETHER — `openChangeRequest` holds the same lock across its own
|
|
3451
3576
|
// check-then-insert, so a request being opened from this branch either
|
|
@@ -3620,7 +3745,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
3620
3745
|
return stdout.split('\n').map((s) => s.trim()).filter(Boolean);
|
|
3621
3746
|
} catch (err) {
|
|
3622
3747
|
log.warn('listChangedPathsBetweenBranches failed:', {
|
|
3623
|
-
detail: redactTokens(err instanceof Error ? err.message : String(err)),
|
|
3748
|
+
detail: redactTokens(err instanceof Error ? err.message : String(err), this.git.credentials?.token()),
|
|
3624
3749
|
});
|
|
3625
3750
|
return [];
|
|
3626
3751
|
}
|
|
@@ -4,6 +4,7 @@ import { tmpdir } from 'node:os';
|
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
5
|
import express from 'express';
|
|
6
6
|
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
7
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
7
8
|
import { LocalFilesystem } from '@mastra/core/workspace';
|
|
8
9
|
import { ToolRegistry } from '../../tool-registry/tool-registry.js';
|
|
9
10
|
import { createToolHandlerFactory } from '../../tool-helpers/tool-handler.js';
|
|
@@ -86,8 +87,8 @@ beforeAll(async () => {
|
|
|
86
87
|
new SpillStore(join(tmpdir(), 'bevel-test-spills')),
|
|
87
88
|
new DocExtractService(docCache),
|
|
88
89
|
service,
|
|
89
|
-
KB,
|
|
90
|
-
{ service: {} as never, enabled: false, kbDirName: KB, recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
|
|
90
|
+
testKbContext({ kbDirName: KB }),
|
|
91
|
+
{ service: {} as never, enabled: false, kb: testKbContext({ kbDirName: KB }), recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
|
|
91
92
|
new RoutineWritePolicyService(),
|
|
92
93
|
{} as never,
|
|
93
94
|
);
|
|
@@ -6,6 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
import AdmZip from 'adm-zip';
|
|
7
7
|
import express from 'express';
|
|
8
8
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
9
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
9
10
|
import type { IWorkflowService } from '@bevel-software/platform-shared';
|
|
10
11
|
import { GIT_INTERNALS_MESSAGE, GitInternalsError } from '../../../shared/domain-errors.js';
|
|
11
12
|
import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
|
|
@@ -241,7 +242,7 @@ describe('workspace tools refuse the git folder', () => {
|
|
|
241
242
|
|
|
242
243
|
beforeEach(async () => {
|
|
243
244
|
workflow = makeWorkflow();
|
|
244
|
-
const service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
|
|
245
|
+
const service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
|
|
245
246
|
unzipSpy = vi.spyOn(service, 'unzipFile');
|
|
246
247
|
bootstrappedSpy = vi.spyOn(service, 'hasBootstrappedWorkspace');
|
|
247
248
|
const lockingFs = new LockingFilesystem(
|
|
@@ -275,8 +276,8 @@ describe('workspace tools refuse the git folder', () => {
|
|
|
275
276
|
new SpillStore(join(root, 'spills')),
|
|
276
277
|
new DocExtractService(join(root, 'doc-cache')),
|
|
277
278
|
allowAll,
|
|
278
|
-
KB,
|
|
279
|
-
{ service: {} as never, enabled: false, kbDirName: KB, recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
|
|
279
|
+
testKbContext({ kbDirName: KB }),
|
|
280
|
+
{ service: {} as never, enabled: false, kb: testKbContext({ kbDirName: KB }), recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
|
|
280
281
|
new RoutineWritePolicyService(),
|
|
281
282
|
{} as never,
|
|
282
283
|
);
|
|
@@ -416,7 +417,7 @@ describe('workspace routes refuse the git folder', () => {
|
|
|
416
417
|
|
|
417
418
|
beforeEach(async () => {
|
|
418
419
|
workflow = makeWorkflow();
|
|
419
|
-
service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
|
|
420
|
+
service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
|
|
420
421
|
const app = express();
|
|
421
422
|
app.use(express.json());
|
|
422
423
|
app.use('/api', (req, _res, next) => {
|
|
@@ -436,7 +437,7 @@ describe('workspace routes refuse the git folder', () => {
|
|
|
436
437
|
workflow as unknown as IWorkflowService,
|
|
437
438
|
{ emit: vi.fn() } as unknown as WorkflowEventBus,
|
|
438
439
|
allowAll,
|
|
439
|
-
KB,
|
|
440
|
+
testKbContext({ kbDirName: KB }),
|
|
440
441
|
stubCreatorAccess,
|
|
441
442
|
{ isAdmin: async () => true } as unknown as IAdminAccessService,
|
|
442
443
|
new NodeFs(),
|
|
@@ -563,7 +564,7 @@ describe('WorkspaceService refuses the git folder on its own', () => {
|
|
|
563
564
|
let service: WorkspaceService;
|
|
564
565
|
|
|
565
566
|
beforeEach(() => {
|
|
566
|
-
service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
|
|
567
|
+
service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
|
|
567
568
|
});
|
|
568
569
|
|
|
569
570
|
afterEach(async () => {
|
|
@@ -620,7 +621,7 @@ describe('WorkspaceService refuses the git folder on its own', () => {
|
|
|
620
621
|
return { stdout: '.git\n', stderr: '', code: 0 };
|
|
621
622
|
}),
|
|
622
623
|
};
|
|
623
|
-
const refService = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs(),
|
|
624
|
+
const refService = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs(), gitRunner as never);
|
|
624
625
|
|
|
625
626
|
for (const [form, raw] of Object.entries(fileForms('config'))) {
|
|
626
627
|
if (!form.startsWith('symlinked')) continue;
|
|
@@ -674,7 +675,7 @@ describe('the route guard on its own', () => {
|
|
|
674
675
|
beforeEach(async () => {
|
|
675
676
|
reached = 0;
|
|
676
677
|
userId = USER.id;
|
|
677
|
-
const service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
|
|
678
|
+
const service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
|
|
678
679
|
const app = express();
|
|
679
680
|
// The server's own order: the guard ahead of the body parser, then again
|
|
680
681
|
// on the parsed body, then again once the caller is known.
|
|
@@ -774,7 +775,7 @@ describe('DiffService refuses the git folder on its own', () => {
|
|
|
774
775
|
let diffService: DiffService;
|
|
775
776
|
|
|
776
777
|
beforeEach(() => {
|
|
777
|
-
const service = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
|
|
778
|
+
const service = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
|
|
778
779
|
diffService = new DiffService(service, new WorkspaceMutex(), root, join(root, 'backups'), KB, new NodeFs());
|
|
779
780
|
});
|
|
780
781
|
|
|
@@ -11,8 +11,10 @@ import type { ToolContext } from '../../tool-helpers/tool.contract.js';
|
|
|
11
11
|
import type { ISessionOntologyService, OperationDecision } from '../../workflow/session-ontology.service.js';
|
|
12
12
|
import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
|
|
13
13
|
import { ontologyOf } from '../../../shared/kb-layout.js';
|
|
14
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
14
15
|
|
|
15
16
|
const KB = 'knowledge-base';
|
|
17
|
+
const kbContext = testKbContext({ kbDirName: KB });
|
|
16
18
|
const P_FILE = 'KnowledgeBase/Product/Knowledge/Foo.md';
|
|
17
19
|
const PL_FILE = 'KnowledgeBase/Platform/Knowledge/Bar.md';
|
|
18
20
|
const NEUTRAL = 'access.md';
|
|
@@ -28,7 +30,7 @@ function makeFakeService(): ISessionOntologyService {
|
|
|
28
30
|
const setFor = (s: string) => touched.get(s) ?? new Set<string>();
|
|
29
31
|
return {
|
|
30
32
|
async checkOperation(sessionId, wsPath, isWrite): Promise<OperationDecision> {
|
|
31
|
-
const ont = ontologyOf(wsPath, KB);
|
|
33
|
+
const ont = ontologyOf(wsPath, kbContext.layout, KB);
|
|
32
34
|
const set = setFor(sessionId);
|
|
33
35
|
if (ont === null) return { allow: true, touched: [...set].sort() };
|
|
34
36
|
if (isWrite) {
|
|
@@ -63,7 +65,7 @@ function makeFakeService(): ISessionOntologyService {
|
|
|
63
65
|
function makeGate(): SessionOntologyGate {
|
|
64
66
|
const service = makeFakeService();
|
|
65
67
|
const hooks = new WorkflowHooks();
|
|
66
|
-
return { service, enabled: true,
|
|
68
|
+
return { service, enabled: true, kb: kbContext, recoveryBotEmail: RECOVERY_EMAIL, hooks };
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
function ctx(overrides: Partial<ToolContext> = {}): ToolContext {
|
|
@@ -7,6 +7,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
import AdmZip from 'adm-zip';
|
|
8
8
|
import express from 'express';
|
|
9
9
|
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
10
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
10
11
|
import type { IWorkflowService } from '@bevel-software/platform-shared';
|
|
11
12
|
import { NodeFs } from '../../kb-fs/node-fs.js';
|
|
12
13
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
@@ -55,7 +56,7 @@ async function makeHarness(): Promise<Harness> {
|
|
|
55
56
|
const workspaceDir = path.join(root, workspaceId);
|
|
56
57
|
// The inner `.git` lets the service accept the workspace without cloning.
|
|
57
58
|
await fs.mkdir(path.join(workspaceDir, KB, '.git'), { recursive: true });
|
|
58
|
-
const workspaceService = new WorkspaceService(root, 'https://example.invalid/kb.git', KB, new NodeFs());
|
|
59
|
+
const workspaceService = new WorkspaceService(root, 'https://example.invalid/kb.git', testKbContext({ kbDirName: KB }), new NodeFs());
|
|
59
60
|
await workspaceService.getWorkspacePath(workspaceId);
|
|
60
61
|
|
|
61
62
|
const asked: string[] = [];
|
|
@@ -102,7 +103,7 @@ async function makeHarness(): Promise<Harness> {
|
|
|
102
103
|
workflowService,
|
|
103
104
|
{ emit: vi.fn() } as unknown as WorkflowEventBus,
|
|
104
105
|
accessControl,
|
|
105
|
-
KB,
|
|
106
|
+
testKbContext({ kbDirName: KB }),
|
|
106
107
|
stubCreatorAccess,
|
|
107
108
|
{ isAdmin: async () => false } as unknown as IAdminAccessService,
|
|
108
109
|
new NodeFs(),
|
|
@@ -2,6 +2,7 @@ import type { Server } from 'node:http';
|
|
|
2
2
|
import type { AddressInfo } from 'node:net';
|
|
3
3
|
import express from 'express';
|
|
4
4
|
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
5
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
5
6
|
import { NodeFs } from '../../kb-fs/node-fs.js';
|
|
6
7
|
import type { FileTreeEntry, IWorkflowService } from '@bevel-software/platform-shared';
|
|
7
8
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
@@ -55,7 +56,7 @@ async function makeHarness(
|
|
|
55
56
|
{} as unknown as IWorkflowService,
|
|
56
57
|
{ emit: vi.fn() } as unknown as WorkflowEventBus,
|
|
57
58
|
accessControl,
|
|
58
|
-
|
|
59
|
+
testKbContext(),
|
|
59
60
|
stubCreatorAccess,
|
|
60
61
|
{ isAdmin: async () => false } as unknown as IAdminAccessService,
|
|
61
62
|
new NodeFs(),
|