@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
|
@@ -9,7 +9,6 @@ import type { IAdminAccessService } from '../admin/admin.interface.js';
|
|
|
9
9
|
import express from 'express';
|
|
10
10
|
import type { AuthUser, IWorkflowService } from '@bevel-software/platform-shared';
|
|
11
11
|
import {
|
|
12
|
-
DEFAULT_BRANCH,
|
|
13
12
|
KNOWLEDGE_DIR,
|
|
14
13
|
canonicalRelativePath,
|
|
15
14
|
folderPlaceholderPath,
|
|
@@ -21,6 +20,7 @@ import {
|
|
|
21
20
|
} from '@bevel-software/platform-shared';
|
|
22
21
|
import { FolderTooLargeError, type ReadTreeFilter } from './workspace.service.js';
|
|
23
22
|
import { branchForWorkspaceId } from '../../shared/workspace-id.js';
|
|
23
|
+
import type { KbContext } from '../../shared/kb-context.js';
|
|
24
24
|
import { EntryExistsError, type WorkspaceService } from './workspace.service.js';
|
|
25
25
|
import type { AuthService } from '../auth/auth.service.js';
|
|
26
26
|
import type { IAccessControl } from '../access/access-control.interface.js';
|
|
@@ -82,7 +82,7 @@ export function createWorkspaceRoutes(
|
|
|
82
82
|
workflowService: IWorkflowService,
|
|
83
83
|
eventBus: WorkflowEventBus,
|
|
84
84
|
accessControl: IAccessControl,
|
|
85
|
-
|
|
85
|
+
kb: KbContext,
|
|
86
86
|
creatorAccess: ICreatorAccess,
|
|
87
87
|
adminAccess: IAdminAccessService,
|
|
88
88
|
disk: ITreeWalker,
|
|
@@ -97,6 +97,7 @@ export function createWorkspaceRoutes(
|
|
|
97
97
|
changeGate?: IChangeReadGate,
|
|
98
98
|
): express.Router {
|
|
99
99
|
const router = express.Router();
|
|
100
|
+
const { kbDirName } = kb;
|
|
100
101
|
const gitInternalsRouteGuard = createGitInternalsRouteGuard(workspaceService);
|
|
101
102
|
|
|
102
103
|
// The git folder is refused ahead of every route here by
|
|
@@ -463,7 +464,7 @@ export function createWorkspaceRoutes(
|
|
|
463
464
|
}
|
|
464
465
|
const branch = typeof req.query.branch === 'string' && req.query.branch.length > 0
|
|
465
466
|
? req.query.branch
|
|
466
|
-
:
|
|
467
|
+
: kb.defaultBranch;
|
|
467
468
|
const workspace = await workspaceService.getOrCreateForBranch(branch);
|
|
468
469
|
// Bootstrap must use the same read-filtered tree as GET /workspace/:id/files.
|
|
469
470
|
// Otherwise the first sidebar render can expose restricted nodes until the
|
|
@@ -663,7 +664,7 @@ export function createWorkspaceRoutes(
|
|
|
663
664
|
// same treatment so legacy clones don't collapse. Only the folders
|
|
664
665
|
// themselves are forced visible — their contents stay gated by the
|
|
665
666
|
// verdict above.
|
|
666
|
-
const structuralRoots = new Set([...reservedRootDirNames(), KNOWLEDGE_DIR]);
|
|
667
|
+
const structuralRoots = new Set([...reservedRootDirNames(kb.layout), KNOWLEDGE_DIR]);
|
|
667
668
|
for (const wp of wsRelPaths) {
|
|
668
669
|
const rel = toKbRelative(wp, kbDirName);
|
|
669
670
|
if (rel !== null && structuralRoots.has(rel)) verdict.set(wp, true);
|
|
@@ -1128,11 +1129,11 @@ export function createWorkspaceRoutes(
|
|
|
1128
1129
|
const oldRel = toKbRelative(oldPath, kbDirName);
|
|
1129
1130
|
const newRel = toKbRelative(newPath, kbDirName);
|
|
1130
1131
|
let platformRestore = false;
|
|
1131
|
-
if (oldRel !== null && newRel !== null && isPlatformRestoreShape(oldRel, newRel)) {
|
|
1132
|
+
if (oldRel !== null && newRel !== null && isPlatformRestoreShape(oldRel, newRel, kb.layout)) {
|
|
1132
1133
|
platformRestore = await accessControl.canRestorePlatformFile(id, user.email, newRel);
|
|
1133
1134
|
}
|
|
1134
1135
|
// A platform file stays where the platform reads it …
|
|
1135
|
-
if (oldRel !== null && isPlatformFile(oldRel) && !platformRestore) {
|
|
1136
|
+
if (oldRel !== null && isPlatformFile(oldRel, kb.layout) && !platformRestore) {
|
|
1136
1137
|
res.status(409).json({ error: platformFileRefusal(oldRel) });
|
|
1137
1138
|
return;
|
|
1138
1139
|
}
|
|
@@ -1145,7 +1146,7 @@ export function createWorkspaceRoutes(
|
|
|
1145
1146
|
// from the same place. Only the restore lands on a platform path, and
|
|
1146
1147
|
// only where the file is missing (`canRestorePlatformFile` checked the
|
|
1147
1148
|
// disk; the destination lock below checks it again, under the lock).
|
|
1148
|
-
if (newRel !== null && isPlatformFile(newRel) && !platformRestore) {
|
|
1149
|
+
if (newRel !== null && isPlatformFile(newRel, kb.layout) && !platformRestore) {
|
|
1149
1150
|
res.status(409).json({ error: platformFileCreationRefusal(newRel) });
|
|
1150
1151
|
return;
|
|
1151
1152
|
}
|
|
@@ -9,7 +9,6 @@ import { AsyncLocalStorage } from 'node:async_hooks';
|
|
|
9
9
|
import {
|
|
10
10
|
validateRelativePath,
|
|
11
11
|
validateFilename,
|
|
12
|
-
DEFAULT_BRANCH,
|
|
13
12
|
FOLDER_PLACEHOLDER,
|
|
14
13
|
isFolderPlaceholder,
|
|
15
14
|
entryExistsMessage,
|
|
@@ -22,6 +21,7 @@ import {
|
|
|
22
21
|
renameNoReplace,
|
|
23
22
|
} from '../../shared/rename-no-replace.js';
|
|
24
23
|
import type { IGitRunner } from '../../shared/git.contract.js';
|
|
24
|
+
import type { KbContext } from '../../shared/kb-context.js';
|
|
25
25
|
import { NodeGitRunner } from '../workflow/git/node-git-runner.js';
|
|
26
26
|
import { assertWithinDirectory } from '../../shared/path-containment.js';
|
|
27
27
|
import { assertRepoRootNameFree, normalizeWorkspacePath } from '../kb-fs/repo-path.js';
|
|
@@ -149,9 +149,8 @@ const CLONE_TIMEOUT_MS = 600_000;
|
|
|
149
149
|
const BOT_NAME = 'Bevel Workflow';
|
|
150
150
|
const BOT_EMAIL = 'bevel-workflow@bevel.software';
|
|
151
151
|
|
|
152
|
-
/** Redact
|
|
153
|
-
function redactError(err: unknown): string {
|
|
154
|
-
const token = process.env.GITHUB_TOKEN;
|
|
152
|
+
/** Redact the token the runner authenticates with from an error message. */
|
|
153
|
+
function redactError(err: unknown, token: string | null): string {
|
|
155
154
|
const msg = err instanceof Error ? err.message : String(err);
|
|
156
155
|
return token ? msg.replaceAll(token, '***') : msg;
|
|
157
156
|
}
|
|
@@ -297,23 +296,26 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
297
296
|
* buy an inconsistency rather than a feature.
|
|
298
297
|
*/
|
|
299
298
|
kbRepoUrl: string | (() => string),
|
|
300
|
-
|
|
299
|
+
/** The checkout folder's name, and which branch a caller lands on when naming none. */
|
|
300
|
+
private readonly kb: Pick<KbContext, 'kbDirName' | 'defaultBranch'>,
|
|
301
301
|
private readonly disk: ITreeWalker,
|
|
302
|
-
gitUsername: string | (() => string) = 'x-access-token',
|
|
303
302
|
/**
|
|
304
303
|
* How git is run — see `shared/git.contract.ts`. The composition root
|
|
305
|
-
* passes the one runner carrying the deployment's deadline
|
|
306
|
-
*
|
|
307
|
-
*
|
|
304
|
+
* passes the one runner carrying the deployment's deadline and the
|
|
305
|
+
* credentials every clone authenticates with; the default is the same
|
|
306
|
+
* runner on its default deadline and no token, for a directly
|
|
307
|
+
* constructed service.
|
|
308
308
|
*/
|
|
309
309
|
private readonly gitRunner: IGitRunner = new NodeGitRunner(),
|
|
310
310
|
) {
|
|
311
311
|
this.kbRepoUrl = typeof kbRepoUrl === 'function' ? kbRepoUrl : () => kbRepoUrl;
|
|
312
|
-
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
private get kbDirName(): string {
|
|
315
|
+
return this.kb.kbDirName;
|
|
313
316
|
}
|
|
314
317
|
|
|
315
318
|
private readonly kbRepoUrl: () => string;
|
|
316
|
-
private readonly gitUsername: () => string;
|
|
317
319
|
|
|
318
320
|
setDiffService(diffService: IDiffService): void {
|
|
319
321
|
this.diffService = diffService;
|
|
@@ -417,7 +419,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
417
419
|
// Persisted into the new repo's config (`clone --config`), not just applied
|
|
418
420
|
// to this invocation — every later push from this clone depends on finding
|
|
419
421
|
// the helper there. See `cloneCredentialArgs`.
|
|
420
|
-
args.push(...cloneCredentialArgs(this.
|
|
422
|
+
args.push(...cloneCredentialArgs(this.gitRunner.credentials));
|
|
421
423
|
args.push(this.kbRepoUrl(), targetDir);
|
|
422
424
|
return args;
|
|
423
425
|
}
|
|
@@ -531,7 +533,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
531
533
|
cloned.push({
|
|
532
534
|
id: entry.name,
|
|
533
535
|
branch,
|
|
534
|
-
unreadable: `Could not read this branch's clone: ${redactError(err)}`,
|
|
536
|
+
unreadable: `Could not read this branch's clone: ${redactError(err, this.gitRunner.credentials.token())}`,
|
|
535
537
|
});
|
|
536
538
|
continue;
|
|
537
539
|
}
|
|
@@ -566,7 +568,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
566
568
|
return;
|
|
567
569
|
} catch (err) {
|
|
568
570
|
log.warn(`referenced clone for "${branch}" failed, retrying without reference:`, {
|
|
569
|
-
detail: redactError(err),
|
|
571
|
+
detail: redactError(err, this.gitRunner.credentials.token()),
|
|
570
572
|
});
|
|
571
573
|
// Clear any partial output so the retry clones into a clean dir.
|
|
572
574
|
await fs.rm(targetDir, { recursive: true, force: true }).catch(() => {});
|
|
@@ -647,15 +649,31 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
647
649
|
}
|
|
648
650
|
this.inFlightBootstraps.set(branch, bootstrap);
|
|
649
651
|
|
|
652
|
+
// `mkdir --recursive` answers with the first path it CREATED, or undefined
|
|
653
|
+
// when the directory was already there. That is the only honest signal for
|
|
654
|
+
// what the rollback below may remove: a directory this attempt made is ours
|
|
655
|
+
// to take back, one that predates us belongs to whatever put it there.
|
|
656
|
+
let createdWorkspaceDir: string | undefined;
|
|
650
657
|
try {
|
|
651
658
|
// A clone with `-b <branch>` against a never-seeded remote fails
|
|
652
659
|
// naturally; seeding the remote is the KB startup phase's job, at boot.
|
|
653
|
-
await fs.mkdir(workspaceDir, { recursive: true });
|
|
660
|
+
createdWorkspaceDir = await fs.mkdir(workspaceDir, { recursive: true });
|
|
654
661
|
await this.cloneProcessMapForBranch(workspaceDir, branch);
|
|
655
662
|
this.registerBranchDir(branch, workspaceDir);
|
|
656
663
|
resolveBootstrap();
|
|
657
664
|
} catch (err) {
|
|
658
665
|
this.branchDirs.delete(branch);
|
|
666
|
+
// A bootstrap that failed leaves NOTHING behind. The clone rolls its own
|
|
667
|
+
// target back, but the workspace directory around it would survive as an
|
|
668
|
+
// empty shell named after the branch — and a directory named after a
|
|
669
|
+
// branch is read as the platform having known that branch: by
|
|
670
|
+
// `hasHeardOfBranch`, which would turn the next attempt's honest 404 into
|
|
671
|
+
// "no longer exists on the remote" (410), and by anyone reading the
|
|
672
|
+
// workspaces root. Best-effort: a rollback that cannot delete must not
|
|
673
|
+
// replace the real failure (the clone's) with its own.
|
|
674
|
+
if (createdWorkspaceDir !== undefined) {
|
|
675
|
+
await fs.rm(workspaceDir, { recursive: true, force: true }).catch(() => {});
|
|
676
|
+
}
|
|
659
677
|
rejectBootstrap(err);
|
|
660
678
|
throw err;
|
|
661
679
|
} finally {
|
|
@@ -675,7 +693,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
675
693
|
* `branch` is passed.
|
|
676
694
|
*/
|
|
677
695
|
async getOrCreateForUser(_user: AuthUser, branch?: string): Promise<WorkspaceInfo> {
|
|
678
|
-
return this.getOrCreateForBranch(branch ??
|
|
696
|
+
return this.getOrCreateForBranch(branch ?? this.kb.defaultBranch);
|
|
679
697
|
}
|
|
680
698
|
|
|
681
699
|
private buildWorkspaceInfo(branch: string, workspaceDir: string): WorkspaceInfo {
|
|
@@ -741,7 +759,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
741
759
|
} catch (err) {
|
|
742
760
|
// One line per branch, not per key: every key writes to the same
|
|
743
761
|
// `.git/config`, so what fails for one fails for all.
|
|
744
|
-
log.warn(`could not normalize the config of the "${branch}" clone:`, { detail: redactError(err) });
|
|
762
|
+
log.warn(`could not normalize the config of the "${branch}" clone:`, { detail: redactError(err, this.gitRunner.credentials.token()) });
|
|
745
763
|
}
|
|
746
764
|
await this.stampCredentialHelper(repoDir, branch);
|
|
747
765
|
}
|
|
@@ -750,12 +768,13 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
750
768
|
* Fingerprint of the credential state a clone's helper is derived from: the
|
|
751
769
|
* username (baked into the helper literal) and whether a token exists at all
|
|
752
770
|
* (the helper is present-or-absent on that). The token VALUE is deliberately
|
|
753
|
-
* excluded — the helper reads `$GITHUB_TOKEN`
|
|
754
|
-
* token needs no re-stamp; only
|
|
755
|
-
* disappearing does.
|
|
771
|
+
* excluded — the helper reads `$GITHUB_TOKEN` from the environment the
|
|
772
|
+
* runner hands each git call, so rotating the token needs no re-stamp; only
|
|
773
|
+
* a username change or a token appearing / disappearing does.
|
|
756
774
|
*/
|
|
757
775
|
private credentialFingerprint(): string {
|
|
758
|
-
|
|
776
|
+
const { credentials } = this.gitRunner;
|
|
777
|
+
return `${credentials.username()}::${credentials.token() ? '1' : '0'}`;
|
|
759
778
|
}
|
|
760
779
|
|
|
761
780
|
/** Last credential fingerprint stamped into each branch's clone, this process. */
|
|
@@ -772,7 +791,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
772
791
|
private async stampCredentialHelper(repoDir: string, branch: string): Promise<void> {
|
|
773
792
|
let argLists: string[][];
|
|
774
793
|
try {
|
|
775
|
-
argLists = cloneCredentialConfigArgs(this.
|
|
794
|
+
argLists = cloneCredentialConfigArgs(this.gitRunner.credentials);
|
|
776
795
|
} catch (err) {
|
|
777
796
|
// `credentialHelperValue` fails closed on a username outside its safe
|
|
778
797
|
// charset. Normally unreachable (CoreConfig and the settings service
|
|
@@ -782,7 +801,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
782
801
|
// re-clone that fails on the same validation — masking the real cause.
|
|
783
802
|
// Contain it as a loud non-stamp instead; `normalizeCloneConfig`'s
|
|
784
803
|
// never-throws contract stays true.
|
|
785
|
-
log.warn(`refusing to stamp the credential helper of the "${branch}" clone:`, { detail: redactError(err) });
|
|
804
|
+
log.warn(`refusing to stamp the credential helper of the "${branch}" clone:`, { detail: redactError(err, this.gitRunner.credentials.token()) });
|
|
786
805
|
this.stampedCredentialFingerprint.delete(branch);
|
|
787
806
|
return;
|
|
788
807
|
}
|
|
@@ -798,7 +817,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
798
817
|
if (!(args.includes('--unset-all') && code === 5)) {
|
|
799
818
|
stamped = false;
|
|
800
819
|
log.warn(`could not stamp the credential helper of the "${branch}" clone:`, {
|
|
801
|
-
detail: redactError(err),
|
|
820
|
+
detail: redactError(err, this.gitRunner.credentials.token()),
|
|
802
821
|
});
|
|
803
822
|
}
|
|
804
823
|
}
|
|
@@ -914,11 +933,11 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
914
933
|
this.onWorkspaceCloned?.(workspaceIdForBranch(branch));
|
|
915
934
|
} catch (listenerErr) {
|
|
916
935
|
log.error(`onWorkspaceCloned listener failed for branch "${branch}":`, {
|
|
917
|
-
detail: redactError(listenerErr),
|
|
936
|
+
detail: redactError(listenerErr, this.gitRunner.credentials.token()),
|
|
918
937
|
});
|
|
919
938
|
}
|
|
920
939
|
} catch (err) {
|
|
921
|
-
const redacted = redactError(err);
|
|
940
|
+
const redacted = redactError(err, this.gitRunner.credentials.token());
|
|
922
941
|
// Roll back partial state so the next bootstrap retries cleanly.
|
|
923
942
|
await fs.rm(targetDir, { recursive: true, force: true }).catch(() => {});
|
|
924
943
|
// A branch origin does not have is a fact about the branch, not a
|
|
@@ -936,7 +955,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
936
955
|
// two stories this is — and guessing either one states something
|
|
937
956
|
// about the branch that we do not know. Our failure, so: 500.
|
|
938
957
|
log.error(`Could not tell whether branch "${branch}" was ever known here:`, {
|
|
939
|
-
detail: redactError(probeErr),
|
|
958
|
+
detail: redactError(probeErr, this.gitRunner.credentials.token()),
|
|
940
959
|
});
|
|
941
960
|
throw new Error(`Failed to clone process map: ${redacted}`);
|
|
942
961
|
}
|
|
@@ -1255,7 +1274,7 @@ export class WorkspaceService implements IWorkspaceService {
|
|
|
1255
1274
|
})
|
|
1256
1275
|
.catch((err) => {
|
|
1257
1276
|
this.lastFetchOk.set(repoDir, false);
|
|
1258
|
-
log.warn('git fetch origin failed:', { detail: redactError(err) });
|
|
1277
|
+
log.warn('git fetch origin failed:', { detail: redactError(err, this.gitRunner.credentials.token()) });
|
|
1259
1278
|
})
|
|
1260
1279
|
.finally(() => {
|
|
1261
1280
|
if (this.inFlightFetches.get(repoDir) === promise) {
|
|
@@ -18,6 +18,7 @@ import type { IRoutineWritePolicy } from './routine-write-policy.js';
|
|
|
18
18
|
import type { ToolHandlerFactory } from '../tool-helpers/tool-handler.js';
|
|
19
19
|
import { requireInternalSource, requireExternalSource } from '../tool-auth/tool-auth.middleware.js';
|
|
20
20
|
import { workspaceIdForBranch } from '../../shared/workspace-id.js';
|
|
21
|
+
import { assertBranchProvided } from '../../shared/domain-errors.js';
|
|
21
22
|
// Leaf-level shared primitive (same exception `workspace.service.ts` already
|
|
22
23
|
// relies on) — not a workflow service, so this stays inside the module boundary.
|
|
23
24
|
import { assertValidBranchName } from '../kb-fs/branch-name.js';
|
|
@@ -39,21 +40,20 @@ import { createFileReaderRegistry } from './file-readers/file-reader.registry.js
|
|
|
39
40
|
import { DocumentReader } from './file-readers/document-reader.js';
|
|
40
41
|
import { mcpImageResult } from '@bevel-software/platform-mcp-core';
|
|
41
42
|
import {
|
|
42
|
-
AGENTS_FILE,
|
|
43
43
|
LEGACY_AGENTS_FILE,
|
|
44
44
|
folderPlaceholderPath,
|
|
45
45
|
isFolderPlaceholder,
|
|
46
46
|
isPlatformFile,
|
|
47
47
|
isPlatformFolder,
|
|
48
|
-
isProtectedBranch,
|
|
49
|
-
onKbLayoutApplied,
|
|
50
48
|
platformFileCreationRefusal,
|
|
51
49
|
platformFileNames,
|
|
52
50
|
platformFileRefusal,
|
|
53
51
|
platformFolderRefusal,
|
|
54
52
|
entryExistsMessage,
|
|
55
53
|
type ExistingEntryKind,
|
|
54
|
+
type KbLayout,
|
|
56
55
|
} from '@bevel-software/platform-shared';
|
|
56
|
+
import type { KbContext } from '../../shared/kb-context.js';
|
|
57
57
|
import { AccessDeniedError } from '../access-model/access-errors.js';
|
|
58
58
|
import { removeEmptyDirs } from './empty-dirs.js';
|
|
59
59
|
import { PROPOSAL_ROUTE_NOTE, rethrowAsWriteDenial } from './write-denial.js';
|
|
@@ -216,22 +216,23 @@ async function keepFolderOf(
|
|
|
216
216
|
* working in their knowledge base. Under the default name the wording collapses
|
|
217
217
|
* to the one file it has always named.
|
|
218
218
|
*
|
|
219
|
-
* A FUNCTION, called
|
|
220
|
-
*
|
|
219
|
+
* A FUNCTION of the layout, called when a description is built: the name is a
|
|
220
|
+
* deployment setting, and a module-scope string would snapshot the default.
|
|
221
221
|
*/
|
|
222
|
-
function kbConventionsNote(): string {
|
|
223
|
-
|
|
222
|
+
function kbConventionsNote(layout: KbLayout): string {
|
|
223
|
+
const agentsFile = layout.agentsFile ?? LEGACY_AGENTS_FILE;
|
|
224
|
+
if (agentsFile === LEGACY_AGENTS_FILE) {
|
|
224
225
|
return ' Before your first read or change in a workspace, read `AGENTS.md` at the KB root — or `CLAUDE.md` on a knowledge base seeded before it was renamed — if either exists: it holds the author\'s conventions for this knowledge base, and you should follow them.';
|
|
225
226
|
}
|
|
226
227
|
return (
|
|
227
|
-
` Before your first read or change in a workspace, read \`${
|
|
228
|
+
` Before your first read or change in a workspace, read \`${agentsFile}\` at the KB root, then ` +
|
|
228
229
|
'`AGENTS.md` if it also exists (the organisation\'s own conventions) — or `CLAUDE.md` on a knowledge base seeded before it was renamed: together they hold the conventions for this knowledge base, and you should follow them.'
|
|
229
230
|
);
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
/** The platform files as a tool description lists them — the guide under its own name. */
|
|
233
|
-
function platformFileList(): string {
|
|
234
|
-
return platformFileNames()
|
|
234
|
+
function platformFileList(layout: KbLayout): string {
|
|
235
|
+
return platformFileNames(layout)
|
|
235
236
|
.map((name) => `\`${name}\``)
|
|
236
237
|
.join(', ');
|
|
237
238
|
}
|
|
@@ -679,7 +680,7 @@ export function registerWorkspaceTools(
|
|
|
679
680
|
spillStore: SpillStore,
|
|
680
681
|
docExtract: DocExtractService,
|
|
681
682
|
accessControl: IAccessControl,
|
|
682
|
-
|
|
683
|
+
kb: KbContext,
|
|
683
684
|
sessionOntologyGate: SessionOntologyGate,
|
|
684
685
|
writePolicy: IRoutineWritePolicy,
|
|
685
686
|
sessionSink: ISessionSink,
|
|
@@ -697,6 +698,7 @@ export function registerWorkspaceTools(
|
|
|
697
698
|
*/
|
|
698
699
|
changeGate?: IChangeReadGate,
|
|
699
700
|
): void {
|
|
701
|
+
const { kbDirName } = kb;
|
|
700
702
|
/**
|
|
701
703
|
* The one extension→reader registry every read-shaped decision routes
|
|
702
704
|
* through: read_file dispatches on it, grep asks it for searchable text,
|
|
@@ -871,7 +873,7 @@ export function registerWorkspaceTools(
|
|
|
871
873
|
* branch only through a change request.
|
|
872
874
|
*/
|
|
873
875
|
const writeBlocked = async (branch: string, ctx: ToolContext, paths: string[]): Promise<string[]> => {
|
|
874
|
-
if (!isProtectedBranch(branch)) return [];
|
|
876
|
+
if (!kb.isProtectedBranch(branch)) return [];
|
|
875
877
|
const byRel = new Map<string, string>();
|
|
876
878
|
for (const p of paths) {
|
|
877
879
|
const rel = toKbRelative(p, kbDirName);
|
|
@@ -934,11 +936,11 @@ export function registerWorkspaceTools(
|
|
|
934
936
|
if (isGitMetadata(norm)) return `"${norm}" is git metadata and cannot be moved or deleted.`;
|
|
935
937
|
if (kind === 'file') {
|
|
936
938
|
const rel = toKbRelative(norm, kbDirName);
|
|
937
|
-
return rel !== null && isPlatformFile(rel) ? platformFileRefusal(rel) : undefined;
|
|
939
|
+
return rel !== null && isPlatformFile(rel, kb.layout) ? platformFileRefusal(rel) : undefined;
|
|
938
940
|
}
|
|
939
941
|
if (norm === '' || norm === kbDirName) return platformFolderRefusal('');
|
|
940
942
|
const rel = toKbRelative(norm, kbDirName);
|
|
941
|
-
return rel !== null && isPlatformFolder(rel) ? platformFolderRefusal(rel) : undefined;
|
|
943
|
+
return rel !== null && isPlatformFolder(rel, kb.layout) ? platformFolderRefusal(rel) : undefined;
|
|
942
944
|
};
|
|
943
945
|
|
|
944
946
|
/** The workspace root on disk for `branch`. */
|
|
@@ -1170,6 +1172,15 @@ export function registerWorkspaceTools(
|
|
|
1170
1172
|
proposable?: boolean;
|
|
1171
1173
|
/** False for a tool that is not a file tool (the shell), which the content rule does not describe. */
|
|
1172
1174
|
fileTool?: boolean;
|
|
1175
|
+
/**
|
|
1176
|
+
* This tool resolves `branch` ITSELF and must not be pre-checked here.
|
|
1177
|
+
* Only `execute_command` sets it: for an internal session that leaves the
|
|
1178
|
+
* argument off, it falls back to the caller's own focused branch (from its
|
|
1179
|
+
* signed token) rather than refusing. It still answers the same
|
|
1180
|
+
* `branch-required` kind when there is nothing to fall back on — see its
|
|
1181
|
+
* handler. Every other tool takes the check below.
|
|
1182
|
+
*/
|
|
1183
|
+
resolvesBranchItself?: boolean;
|
|
1173
1184
|
handler: ToolHandler;
|
|
1174
1185
|
}): void => {
|
|
1175
1186
|
const path = `/api/agent/tools/${spec.name}`;
|
|
@@ -1177,11 +1188,17 @@ export function registerWorkspaceTools(
|
|
|
1177
1188
|
// tool the one content rule, and every tool a permission can refuse the
|
|
1178
1189
|
// proposal route — appended once here so no tool (especially the
|
|
1179
1190
|
// read-only ones a session hits first) can miss them.
|
|
1191
|
+
// Whether a call to this tool MUST name a branch, read off the tool's own
|
|
1192
|
+
// declaration rather than assumed of the family. Every tool mounted here
|
|
1193
|
+
// requires `branch` today; keying on the schema means a tool that declares
|
|
1194
|
+
// it optional (and resolves absence itself, as `list_tool_setup` does on its
|
|
1195
|
+
// own route) is not handed a refusal it never asked for.
|
|
1196
|
+
const requiresBranch = ((spec.inputs as { required?: string[] }).required ?? []).includes('branch');
|
|
1180
1197
|
const describe = (): string =>
|
|
1181
1198
|
(typeof spec.description === 'function' ? spec.description() : spec.description) +
|
|
1182
1199
|
(spec.proposable ? PROPOSAL_ROUTE_NOTE : '') +
|
|
1183
1200
|
(spec.fileTool === false ? '' : CONTENT_RULE) +
|
|
1184
|
-
kbConventionsNote();
|
|
1201
|
+
kbConventionsNote(kb.layout);
|
|
1185
1202
|
const def = toolDef({
|
|
1186
1203
|
name: spec.name,
|
|
1187
1204
|
description: describe(),
|
|
@@ -1199,7 +1216,7 @@ export function registerWorkspaceTools(
|
|
|
1199
1216
|
// move the text with them. Rewritten in place: the registry holds this
|
|
1200
1217
|
// object, both surfaces hold the same one, and re-registering would be a
|
|
1201
1218
|
// duplicate name.
|
|
1202
|
-
|
|
1219
|
+
kb.onLayoutApplied(() => {
|
|
1203
1220
|
def.description = describe();
|
|
1204
1221
|
});
|
|
1205
1222
|
// Internal-only tools (e.g. `execute_command`) keep their route mounted —
|
|
@@ -1222,6 +1239,16 @@ export function registerWorkspaceTools(
|
|
|
1222
1239
|
// never reached the repository — the whole bug, spelled with a prefix.
|
|
1223
1240
|
toolHandler(
|
|
1224
1241
|
async (args, ctx) => {
|
|
1242
|
+
// FIRST, before the path work and before any handler: every tool
|
|
1243
|
+
// mounted here declares `branch` as a required, non-empty string, and
|
|
1244
|
+
// nothing enforced that, so a call that named none was carried down
|
|
1245
|
+
// until `workspaceIdForBranch` made a workspace directory out of the
|
|
1246
|
+
// missing value. Most of these tools would meet the same refusal one
|
|
1247
|
+
// layer down at `getFilesystem`, but not all of them do — `unzip`
|
|
1248
|
+
// hands `branch` straight to the workspace service by id — so the
|
|
1249
|
+
// check belongs on the mount every one of them shares rather than on
|
|
1250
|
+
// the resolver only some of them reach.
|
|
1251
|
+
if (requiresBranch && !spec.resolvesBranchItself) assertBranchProvided(args.branch);
|
|
1225
1252
|
// BEFORE the normaliser: see `assertToolPathsNotGitInternals`.
|
|
1226
1253
|
if (spec.fileTool !== false) await assertToolPathsNotGitInternals(args, ctx);
|
|
1227
1254
|
const normalized = normalizePathArgs(
|
|
@@ -1250,7 +1277,7 @@ export function registerWorkspaceTools(
|
|
|
1250
1277
|
err,
|
|
1251
1278
|
{ tool: spec.name, branch: args.branch, userEmail: ctx.user.email, userId: ctx.user.id },
|
|
1252
1279
|
accessControl,
|
|
1253
|
-
|
|
1280
|
+
kb,
|
|
1254
1281
|
changeGate,
|
|
1255
1282
|
);
|
|
1256
1283
|
}
|
|
@@ -1432,7 +1459,7 @@ export function registerWorkspaceTools(
|
|
|
1432
1459
|
description: () =>
|
|
1433
1460
|
'Get a file/directory\'s metadata (name, type, size, …) without returning content. A file also reports `contentMode`: `text` (read, write and edit it as text), `document` (read returns an extraction; replace it by upload) or `binary` (bytes: copy, move, delete, or replace by upload), plus `kind` (`text` | `document` | `image` | `binary`), `mime`, `mimeSource` and `textEditable` — decided by the same file readers read_file, grep and the write tools use, so an extensionless text file is `text/plain`.' +
|
|
1434
1461
|
' Every entry also reports what you may DO with it. ' +
|
|
1435
|
-
`\`managed\` is true for a platform item — a platform file (${platformFileList()}) or a platform folder (the repository root or a reserved root folder such as \`KnowledgeBase/\`); managed items are never movable or deletable through these tools. ` +
|
|
1462
|
+
`\`managed\` is true for a platform item — a platform file (${platformFileList(kb.layout)}) or a platform folder (the repository root or a reserved root folder such as \`KnowledgeBase/\`); managed items are never movable or deletable through these tools. ` +
|
|
1436
1463
|
'`access: { read, write, download, owner }` is your own verdict under the access rules; pass `explainAccess: true` to learn why, and who else holds each verb. `movable` and `deletable` say whether `move_file` / `delete_file` / `delete_folder` would be allowed for you, judged like their dry runs: not managed, no symbolic link, and on a protected branch you hold write on the item AND on every file under a folder (on a draft branch writes are not gated). `movable` judges the source side only; the destination is judged by a `move_file` dry run. ' +
|
|
1437
1464
|
'For a folder, `descendants` is the number of files under it at any depth; counting stops at 10000 and `descendantsTruncated` says so, and past that point `movable` and `deletable` are false because a folder that large was not judged in full — run the `move_file` or `delete_folder` dry run for the real verdict. ' +
|
|
1438
1465
|
'Call this before a move or delete to see what it would touch.' +
|
|
@@ -2042,7 +2069,7 @@ export function registerWorkspaceTools(
|
|
|
2042
2069
|
name: 'delete_file',
|
|
2043
2070
|
description: () =>
|
|
2044
2071
|
'Delete ONE workspace file (a symbolic link is refused: links are never followed or removed). Committed + pushed as you. Its folder stays, even when this was its last file. Files only: a folder is refused with a pointer to `delete_folder`. ' +
|
|
2045
|
-
`A platform file (\`access.md\` or \`.bevelignore\` in any folder, \`roles.yaml\` or \`${
|
|
2072
|
+
`A platform file (\`access.md\` or \`.bevelignore\` in any folder, \`roles.yaml\` or \`${kb.layout.agentsFile}\` at the repository root) and git metadata are refused.` +
|
|
2046
2073
|
ONTOLOGY_BOUNDARY_NOTE,
|
|
2047
2074
|
inputs: {
|
|
2048
2075
|
type: 'object',
|
|
@@ -2262,7 +2289,7 @@ export function registerWorkspaceTools(
|
|
|
2262
2289
|
name: 'move_file',
|
|
2263
2290
|
description: () =>
|
|
2264
2291
|
'Move or rename a workspace FILE or FOLDER; a folder moves recursively, with everything under it. `dest` is the full new path, not the folder to move into. Lands as a delete + create, committed + pushed as you. ' +
|
|
2265
|
-
`Rules: the destination must not exist — a move never overwrites a file or merges into a folder; a platform file (\`access.md\` or \`.bevelignore\` in any folder, \`roles.yaml\` or \`${
|
|
2292
|
+
`Rules: the destination must not exist — a move never overwrites a file or merges into a folder; a platform file (\`access.md\` or \`.bevelignore\` in any folder, \`roles.yaml\` or \`${kb.layout.agentsFile}\` at the repository root) is refused with "<name> is a platform file and stays in its folder." — a folder that moves takes its own platform files along, still in their folder; a platform folder (the repository root or a reserved root folder such as \`KnowledgeBase/\`) and git metadata are refused; a move cannot create a platform file or folder at \`dest\` either (renaming a note to \`access.md\` is refused); a path through a symbolic link is refused, since links are never followed; on a protected branch you must be able to write both ends — for a folder, every file under it at its old and its new path. ` +
|
|
2266
2293
|
'Access follows the destination folder. Preflight first: `dryRun: true` changes nothing and answers `{ src, dest, kind, descendants, access: { before, after }, accessChanges, allowed, reason? }` — `access` is your own `{ read, write, download, owner }` at the source and at the destination. ' +
|
|
2267
2294
|
'A move whose `accessChanges` is true runs only with `confirm: true`; without it the call moves nothing and returns the same impact with `confirmationRequired: true`. Do NOT set `confirm: true` on your first call — dry-run, check the impact, then confirm.' +
|
|
2268
2295
|
ONTOLOGY_BOUNDARY_NOTE,
|
|
@@ -2593,6 +2620,9 @@ export function registerWorkspaceTools(
|
|
|
2593
2620
|
ONTOLOGY_BOUNDARY_NOTE,
|
|
2594
2621
|
internalOnly: true,
|
|
2595
2622
|
fileTool: false,
|
|
2623
|
+
// The one tool the mount's branch check skips: the handler below resolves an
|
|
2624
|
+
// omitted `branch` to the internal caller's focused branch before refusing.
|
|
2625
|
+
resolvesBranchItself: true,
|
|
2596
2626
|
inputs: {
|
|
2597
2627
|
type: 'object',
|
|
2598
2628
|
properties: {
|
|
@@ -2649,6 +2679,11 @@ export function registerWorkspaceTools(
|
|
|
2649
2679
|
throw new ToolError(
|
|
2650
2680
|
'execute_command requires a `branch`: pass the branch (draft) whose workspace to run the command in — the one you are currently working on.',
|
|
2651
2681
|
400,
|
|
2682
|
+
// The same discriminator every other KB tool answers a branch-less
|
|
2683
|
+
// call with, so a client switches on one kind across the surface.
|
|
2684
|
+
// The MESSAGE stays this tool's own: it can name the focused-branch
|
|
2685
|
+
// fallback that only applies here.
|
|
2686
|
+
{ kind: 'branch-required' },
|
|
2652
2687
|
);
|
|
2653
2688
|
}
|
|
2654
2689
|
// A stringified absent value. Both are syntactically valid git branch names,
|
|
@@ -2661,6 +2696,7 @@ export function registerWorkspaceTools(
|
|
|
2661
2696
|
`execute_command got the literal string "${branch}" as \`branch\` — that is a stringified absent value, not a branch. ` +
|
|
2662
2697
|
'Pass the real branch (draft) whose workspace to run the command in.',
|
|
2663
2698
|
400,
|
|
2699
|
+
{ kind: 'branch-required' },
|
|
2664
2700
|
);
|
|
2665
2701
|
}
|
|
2666
2702
|
// Then the SHAPE, via the one canonical validator every other branch path
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { branchAuthorLocalpart,
|
|
1
|
+
import { branchAuthorLocalpart, suggestionsBranchPrefixFor } from '@bevel-software/platform-shared';
|
|
2
|
+
import type { KbContext } from '../../shared/kb-context.js';
|
|
2
3
|
import { ToolError } from '../tool-helpers/tool.contract.js';
|
|
3
4
|
import { AccessDeniedError } from '../access-model/access-errors.js';
|
|
4
5
|
import type { IChangeReadGate } from '../access-model/change-gate.js';
|
|
@@ -111,9 +112,10 @@ export async function writeDenial(
|
|
|
111
112
|
err: AccessDeniedError,
|
|
112
113
|
input: { tool: string; branch: string; userEmail: string; userId: string },
|
|
113
114
|
accessControl: IAccessControl,
|
|
114
|
-
|
|
115
|
+
kb: Pick<KbContext, 'kbDirName' | 'isProtectedBranch'>,
|
|
115
116
|
changeGate?: IChangeReadGate,
|
|
116
117
|
): Promise<ToolError> {
|
|
118
|
+
const { kbDirName } = kb;
|
|
117
119
|
const path = err.access.path;
|
|
118
120
|
const base = { kind: 'write-denied' as const, path, reason: reasonOf(err) };
|
|
119
121
|
const refuse = (cannotProposeReason: string): ToolError => {
|
|
@@ -121,7 +123,7 @@ export async function writeDenial(
|
|
|
121
123
|
return new ToolError(`${err.message} ${cannotProposeReason}`, 403, { ...details });
|
|
122
124
|
};
|
|
123
125
|
|
|
124
|
-
if (!isProtectedBranch(input.branch)) {
|
|
126
|
+
if (!kb.isProtectedBranch(input.branch)) {
|
|
125
127
|
return refuse(`Proposing is not available: "${input.branch}" is not a branch that accepts change requests.`);
|
|
126
128
|
}
|
|
127
129
|
// The lock gate reports workspace paths, the git gates repo-relative ones.
|
|
@@ -179,11 +181,11 @@ export async function rethrowAsWriteDenial(
|
|
|
179
181
|
err: unknown,
|
|
180
182
|
input: { tool: string; branch: unknown; userEmail: string; userId: string },
|
|
181
183
|
accessControl: IAccessControl,
|
|
182
|
-
|
|
184
|
+
kb: Pick<KbContext, 'kbDirName' | 'isProtectedBranch'>,
|
|
183
185
|
changeGate?: IChangeReadGate,
|
|
184
186
|
): Promise<never> {
|
|
185
187
|
if (err instanceof AccessDeniedError && typeof input.branch === 'string') {
|
|
186
|
-
throw await writeDenial(err, { ...input, branch: input.branch }, accessControl,
|
|
188
|
+
throw await writeDenial(err, { ...input, branch: input.branch }, accessControl, kb, changeGate);
|
|
187
189
|
}
|
|
188
190
|
throw err;
|
|
189
191
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { pluginOfPath, PLUGINS_DIR } from '@bevel-software/platform-shared';
|
|
2
|
+
import { DEFAULT_KB_LAYOUT, pluginOfPath, PLUGINS_DIR } from '@bevel-software/platform-shared';
|
|
3
|
+
|
|
4
|
+
/** `pluginOfPath` under the default layout, which these cases are written against. */
|
|
5
|
+
const plugin = (path: string) => pluginOfPath(path, DEFAULT_KB_LAYOUT);
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
* `pluginOfPath` is the whole of the grouping contract — the sidebar, the
|
|
@@ -9,9 +12,9 @@ import { pluginOfPath, PLUGINS_DIR } from '@bevel-software/platform-shared';
|
|
|
9
12
|
*/
|
|
10
13
|
describe('pluginOfPath', () => {
|
|
11
14
|
it('reads the plugin from the Plugins root', () => {
|
|
12
|
-
expect(
|
|
13
|
-
expect(
|
|
14
|
-
expect(
|
|
15
|
+
expect(plugin(`${PLUGINS_DIR}/GTM/heyreach-campaign/SKILL.md`)).toBe('GTM');
|
|
16
|
+
expect(plugin(`${PLUGINS_DIR}/GTM/heyreach.tool`)).toBe('GTM');
|
|
17
|
+
expect(plugin(`${PLUGINS_DIR}/Engineering/review/architecture-review`)).toBe(
|
|
15
18
|
'Engineering',
|
|
16
19
|
);
|
|
17
20
|
});
|
|
@@ -19,27 +22,27 @@ describe('pluginOfPath', () => {
|
|
|
19
22
|
it('returns null for content directly under the root — it has no plugin folder', () => {
|
|
20
23
|
// The regression this guards: `Plugins/slack.tool` must NOT report a plugin
|
|
21
24
|
// called "slack.tool", and `Plugins/GTM` must not report itself.
|
|
22
|
-
expect(
|
|
23
|
-
expect(
|
|
24
|
-
expect(
|
|
25
|
+
expect(plugin(`${PLUGINS_DIR}/slack.tool`)).toBeNull();
|
|
26
|
+
expect(plugin(`${PLUGINS_DIR}/GTM`)).toBeNull();
|
|
27
|
+
expect(plugin(PLUGINS_DIR)).toBeNull();
|
|
25
28
|
});
|
|
26
29
|
|
|
27
30
|
it('returns null outside the plugin root', () => {
|
|
28
|
-
expect(
|
|
29
|
-
expect(
|
|
31
|
+
expect(plugin('KnowledgeBase/Product/Knowledge/Foo.md')).toBeNull();
|
|
32
|
+
expect(plugin('Data/Engineering/Knowledge/Bar.md')).toBeNull();
|
|
30
33
|
// The retired pre-merge roots are ordinary non-plugin folders now.
|
|
31
|
-
expect(
|
|
32
|
-
expect(
|
|
33
|
-
expect(
|
|
34
|
-
expect(
|
|
34
|
+
expect(plugin('Skills/GTM/heyreach-campaign')).toBeNull();
|
|
35
|
+
expect(plugin('Tools/NewsAgent/serper.tool')).toBeNull();
|
|
36
|
+
expect(plugin('access.md')).toBeNull();
|
|
37
|
+
expect(plugin('')).toBeNull();
|
|
35
38
|
});
|
|
36
39
|
|
|
37
40
|
it('is not fooled by a prefix match on the root name', () => {
|
|
38
|
-
expect(
|
|
41
|
+
expect(plugin('PluginsOld/GTM/x')).toBeNull();
|
|
39
42
|
});
|
|
40
43
|
|
|
41
44
|
it('tolerates leading and doubled separators', () => {
|
|
42
|
-
expect(
|
|
43
|
-
expect(
|
|
45
|
+
expect(plugin(`/${PLUGINS_DIR}/GTM/x`)).toBe('GTM');
|
|
46
|
+
expect(plugin(`${PLUGINS_DIR}//GTM//x`)).toBe('GTM');
|
|
44
47
|
});
|
|
45
48
|
});
|