@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
|
@@ -23,18 +23,34 @@ import {
|
|
|
23
23
|
type RepositoryConnection,
|
|
24
24
|
} from './connection-check.js';
|
|
25
25
|
import {
|
|
26
|
-
configureBranchModel,
|
|
27
|
-
configureKbLayout,
|
|
28
|
-
isBranchModelConfigured,
|
|
29
26
|
isDefaultKbLayout,
|
|
30
27
|
validateBranchModel,
|
|
31
28
|
validateKbLayout,
|
|
32
29
|
} from '@bevel-software/platform-shared';
|
|
30
|
+
import type { KbContext } from '../../shared/kb-context.js';
|
|
33
31
|
import { failureOf, type GitFailure } from '../../shared/git-failure.js';
|
|
34
32
|
import { redactSecret, urlQuerySecrets } from '../../shared/redact-secret.js';
|
|
35
33
|
import { listRootFolders, pickListingBranch } from './git-root-folders.js';
|
|
34
|
+
import { MANAGED_DEFAULT_BRANCH } from './managed-repository.js';
|
|
35
|
+
import { GIT_MODES, type GitHubAppRepository, type RepositorySource } from './repository-source.js';
|
|
36
36
|
import '../auth/auth.middleware.js'; // Express Request augmentation
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* What setup needs of the ways a deployment can be given its repository:
|
|
40
|
+
* the source every reader of the repository asks, and the one thing a mode
|
|
41
|
+
* has to have DONE before a save that chooses it may go through.
|
|
42
|
+
*/
|
|
43
|
+
export interface RepositorySetup {
|
|
44
|
+
source: RepositorySource;
|
|
45
|
+
/** Create the repository the deployment keeps for itself, if it is not there. Never touches one that is. */
|
|
46
|
+
ensureManaged(initialBranch: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* The connection to GitHub through a GitHub App. Absent, that way is not
|
|
49
|
+
* offered, and a save that names it is refused.
|
|
50
|
+
*/
|
|
51
|
+
githubApp?: Pick<GitHubAppRepository, 'url' | 'answered' | 'prepare' | 'token' | 'permits'>;
|
|
52
|
+
}
|
|
53
|
+
|
|
38
54
|
/** Which name a host expects beside the token when none is configured. */
|
|
39
55
|
const DEFAULT_GIT_USERNAME = 'x-access-token';
|
|
40
56
|
|
|
@@ -105,6 +121,12 @@ export function createSetupRoutes(
|
|
|
105
121
|
/** That failure classified, for the setup screen; absent, the message is read instead. */
|
|
106
122
|
lastFailureKind?(): GitFailure | null;
|
|
107
123
|
},
|
|
124
|
+
/**
|
|
125
|
+
* The knowledge base's context as the running graph holds it: the save
|
|
126
|
+
* that completes setup applies the branch model and the layout to it, so
|
|
127
|
+
* every service reads the admin's answer without a restart.
|
|
128
|
+
*/
|
|
129
|
+
kb: KbContext,
|
|
108
130
|
/**
|
|
109
131
|
* The remote-sync facts the Deployment page shows beside the sync secret:
|
|
110
132
|
* the address a webhook or pipeline must call, and what the last call did.
|
|
@@ -134,8 +156,14 @@ export function createSetupRoutes(
|
|
|
134
156
|
checkOidc: (config: OidcConfiguration) => Promise<OidcCheck> = checkOidcConfiguration,
|
|
135
157
|
/** The issuer-only half, for a test with no application id or secret yet. */
|
|
136
158
|
checkIssuer: (issuerUrl: string) => Promise<IssuerCheck> = (url) => checkOidcIssuer(url),
|
|
159
|
+
/**
|
|
160
|
+
* The ways a deployment can be given its repository. Absent, there is the
|
|
161
|
+
* one there always was: an address and a token, read from the settings.
|
|
162
|
+
*/
|
|
163
|
+
repository?: RepositorySetup,
|
|
137
164
|
): express.Router {
|
|
138
165
|
const router = express.Router();
|
|
166
|
+
const source = repository?.source;
|
|
139
167
|
|
|
140
168
|
/**
|
|
141
169
|
* Why the last setup-time run of the KB startup phase FAILED, or null. While
|
|
@@ -180,7 +208,30 @@ export function createSetupRoutes(
|
|
|
180
208
|
};
|
|
181
209
|
/** The app-gate answer: settings complete AND the KB phase settled clean, whoever ran it. */
|
|
182
210
|
const kbReady = () =>
|
|
183
|
-
isComplete(settings) && kbInit === null && kbInitInFlight === null && bootFailure() === null;
|
|
211
|
+
isComplete(settings, kb, source) && kbInit === null && kbInitInFlight === null && bootFailure() === null;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Which ways of having a repository this deployment offers and which one
|
|
215
|
+
* it is on, for the setup screen. `mode` is the one IN EFFECT, inferred
|
|
216
|
+
* for a deployment that never chose; `chosen` is the one the settings
|
|
217
|
+
* say, which differs from it between a move and the restart the move
|
|
218
|
+
* owes. The screen opens on what was chosen, says a restart is pending
|
|
219
|
+
* when the two differ, and offers the first of `modes` to a deployment
|
|
220
|
+
* that has none. `pinned` names the variable that chose for the
|
|
221
|
+
* deployment, when one did. Nothing at all from a mount without the
|
|
222
|
+
* choice, which the screen reads as the one way there was.
|
|
223
|
+
*/
|
|
224
|
+
const repositoryStatus = () =>
|
|
225
|
+
source
|
|
226
|
+
? {
|
|
227
|
+
repository: {
|
|
228
|
+
mode: source.mode(),
|
|
229
|
+
chosen: source.chosen(),
|
|
230
|
+
...(settings.sourceOf('gitMode') === 'env' ? { pinned: 'GIT_MODE' } : {}),
|
|
231
|
+
modes: GIT_MODES.filter((mode) => mode !== 'github-app' || repository?.githubApp !== undefined),
|
|
232
|
+
},
|
|
233
|
+
}
|
|
234
|
+
: {};
|
|
184
235
|
|
|
185
236
|
const requireAdmin: express.RequestHandler = async (req, res, next) => {
|
|
186
237
|
if (!(await adminAccess.isAdmin(req.userEmail))) {
|
|
@@ -215,9 +266,10 @@ export function createSetupRoutes(
|
|
|
215
266
|
}
|
|
216
267
|
res.json({
|
|
217
268
|
complete: kbReady(),
|
|
218
|
-
awaitingRestart: awaitingRestart(settings),
|
|
269
|
+
awaitingRestart: awaitingRestart(settings, kb, source),
|
|
219
270
|
isAdmin: true,
|
|
220
271
|
settings: settings.describe(),
|
|
272
|
+
...repositoryStatus(),
|
|
221
273
|
oidcVerification: await settings.oidcVerification(),
|
|
222
274
|
...(kbInit ? { kbInit } : bootFailure() !== null ? { kbInit: bootFailureKind() } : {}),
|
|
223
275
|
...(sync ? { sync: { url: sync.url, last: sync.lastSync() } } : {}),
|
|
@@ -261,7 +313,13 @@ export function createSetupRoutes(
|
|
|
261
313
|
// save that flips it false→true — whichever field arrives last — is the
|
|
262
314
|
// one that must run the KB startup phase, regardless of which save
|
|
263
315
|
// configured the branch model.
|
|
264
|
-
const wasComplete = isComplete(settings);
|
|
316
|
+
const wasComplete = isComplete(settings, kb, source);
|
|
317
|
+
// A different question, asked of the GATE: whether anyone is being
|
|
318
|
+
// served. Settings that are answered are not a deployment that works
|
|
319
|
+
// — one whose first clone failed has answered everything and serves
|
|
320
|
+
// nobody.
|
|
321
|
+
const wasServing = kbReady();
|
|
322
|
+
nameBranchesOfManagedRepository(entries);
|
|
265
323
|
if (!(await connectionHoldsFor(entries, wasComplete, res))) return;
|
|
266
324
|
const oidc = await signInHoldsFor(entries, res);
|
|
267
325
|
if (!oidc) return;
|
|
@@ -273,7 +331,35 @@ export function createSetupRoutes(
|
|
|
273
331
|
if (oidc.record) {
|
|
274
332
|
await settings.recordOidcVerification(oidc.record.state, oidc.record.credentials);
|
|
275
333
|
}
|
|
276
|
-
const
|
|
334
|
+
const saved = await settings.save(entries, req.userId ?? null);
|
|
335
|
+
/**
|
|
336
|
+
* A deployment that was not serving has nothing on the mode it had:
|
|
337
|
+
* the mode chosen takes effect now, and the startup phase below is
|
|
338
|
+
* what a restart would have run. One that WAS serving stays on the
|
|
339
|
+
* mode it is on, working copies and credential alike, until it is
|
|
340
|
+
* started again.
|
|
341
|
+
*
|
|
342
|
+
* SERVING, not answered. The pin protects what is running on the
|
|
343
|
+
* mode in effect, and behind a shut gate nothing is: a first run
|
|
344
|
+
* whose initialisation failed, a boot that found its repository
|
|
345
|
+
* unreachable. Pinned there, the way out of a repository that does
|
|
346
|
+
* not work would be closed — the admin chooses another, the retry
|
|
347
|
+
* below runs against the one that just failed, and the screen asks
|
|
348
|
+
* for a restart that changes nothing.
|
|
349
|
+
*/
|
|
350
|
+
if (source && !wasServing) source.takeEffect();
|
|
351
|
+
/**
|
|
352
|
+
* The restart the mode owes is read off the two modes themselves, not
|
|
353
|
+
* off what this save wrote: it is owed for as long as the mode chosen
|
|
354
|
+
* is not the one in effect, whichever save chose it, and no longer
|
|
355
|
+
* once a save chooses the mode in effect back.
|
|
356
|
+
*/
|
|
357
|
+
const modePending = source !== undefined && source.chosen() !== source.mode();
|
|
358
|
+
const restartKeys = [
|
|
359
|
+
...saved.restartKeys.filter((key) => key !== 'gitMode'),
|
|
360
|
+
...(modePending ? ['gitMode'] : []),
|
|
361
|
+
];
|
|
362
|
+
const restartRequired = restartKeys.length > 0;
|
|
277
363
|
/** Whether this save put the stored folder names into the running process. */
|
|
278
364
|
let layoutApplied = false;
|
|
279
365
|
/** Whether this save put the stored branch model into the running process. */
|
|
@@ -292,13 +378,13 @@ export function createSetupRoutes(
|
|
|
292
378
|
* capturing it at construction, which is what makes applying it here
|
|
293
379
|
* enough.
|
|
294
380
|
*/
|
|
295
|
-
if (!isBranchModelConfigured()) {
|
|
381
|
+
if (!kb.isBranchModelConfigured()) {
|
|
296
382
|
const model = {
|
|
297
383
|
defaultBranch: settings.resolve('defaultBranch'),
|
|
298
384
|
protectedBranches: settings.resolve('protectedBranches'),
|
|
299
385
|
};
|
|
300
386
|
if (!validateBranchModel(model)) {
|
|
301
|
-
|
|
387
|
+
kb.applyBranchModel(model);
|
|
302
388
|
branchModelApplied = true;
|
|
303
389
|
}
|
|
304
390
|
}
|
|
@@ -316,7 +402,7 @@ export function createSetupRoutes(
|
|
|
316
402
|
* on a re-save of a complete, healthy setup: with the gate open,
|
|
317
403
|
* sessions may be live and that is no longer a quiet moment.
|
|
318
404
|
*/
|
|
319
|
-
if ((!wasComplete || kbInit !== null || bootFailure() !== null) && isComplete(settings)) {
|
|
405
|
+
if ((!wasComplete || kbInit !== null || bootFailure() !== null) && isComplete(settings, kb, source)) {
|
|
320
406
|
/**
|
|
321
407
|
* The folder names, applied BEFORE the phase for the same reason as
|
|
322
408
|
* the branch model above: they are otherwise applied once at boot, so
|
|
@@ -327,10 +413,10 @@ export function createSetupRoutes(
|
|
|
327
413
|
* the names an earlier setup save applied before a run that failed:
|
|
328
414
|
* the gate never opened, so the retry initializes what is saved now.
|
|
329
415
|
*/
|
|
330
|
-
if (isDefaultKbLayout() || (kbInit !== null && layoutAppliedBySetup)) {
|
|
416
|
+
if (isDefaultKbLayout(kb.layout) || (kbInit !== null && layoutAppliedBySetup)) {
|
|
331
417
|
const layout = settings.resolveKbLayout();
|
|
332
418
|
if (!validateKbLayout(layout)) {
|
|
333
|
-
|
|
419
|
+
kb.applyLayout(layout);
|
|
334
420
|
layoutApplied = true;
|
|
335
421
|
layoutAppliedBySetup = true;
|
|
336
422
|
}
|
|
@@ -356,6 +442,7 @@ export function createSetupRoutes(
|
|
|
356
442
|
const raw = initErr instanceof Error ? initErr.message : String(initErr);
|
|
357
443
|
const msg = redactSecret(raw, [
|
|
358
444
|
settings.resolve('gitToken'),
|
|
445
|
+
source?.credentials.token() ?? '',
|
|
359
446
|
...urlQuerySecrets(settings.resolve('kbRepoUrl')),
|
|
360
447
|
]);
|
|
361
448
|
log.error(`KB initialization failed after setup completed: ${msg}`);
|
|
@@ -382,8 +469,9 @@ export function createSetupRoutes(
|
|
|
382
469
|
)
|
|
383
470
|
: restartRequired,
|
|
384
471
|
complete: kbReady(),
|
|
385
|
-
awaitingRestart: awaitingRestart(settings),
|
|
472
|
+
awaitingRestart: awaitingRestart(settings, kb, source),
|
|
386
473
|
settings: settings.describe(),
|
|
474
|
+
...repositoryStatus(),
|
|
387
475
|
oidcVerification: await settings.oidcVerification(),
|
|
388
476
|
});
|
|
389
477
|
} catch (err) {
|
|
@@ -398,6 +486,101 @@ export function createSetupRoutes(
|
|
|
398
486
|
}
|
|
399
487
|
}
|
|
400
488
|
|
|
489
|
+
/**
|
|
490
|
+
* A repository the deployment keeps for itself is new, and empty, and has
|
|
491
|
+
* no branches for anyone to look up: the branch model is ours to name. It
|
|
492
|
+
* is named only when nobody has — an admin's own answer, or one the
|
|
493
|
+
* environment supplies, stands. Every other mode has a repository that
|
|
494
|
+
* already exists, whose branches are asked for, never guessed.
|
|
495
|
+
*/
|
|
496
|
+
function nameBranchesOfManagedRepository(entries: Record<string, string>): void {
|
|
497
|
+
if (!source) return;
|
|
498
|
+
const after = settings.resolveAfter(entries);
|
|
499
|
+
if (source.mode(after) !== 'managed') return;
|
|
500
|
+
if (after('defaultBranch') || after('protectedBranches')) return;
|
|
501
|
+
entries.defaultBranch = MANAGED_DEFAULT_BRANCH;
|
|
502
|
+
entries.protectedBranches = MANAGED_DEFAULT_BRANCH;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* The same rule for a repository reached through a GitHub App: a saved
|
|
507
|
+
* connection is one GitHub has accepted for reading and writing, asked
|
|
508
|
+
* with the token git will present, which is the installation's.
|
|
509
|
+
*
|
|
510
|
+
* That token is also what keeps the repository's NAME honest. It is the
|
|
511
|
+
* one part of this connection an admin types, and a name the installation
|
|
512
|
+
* does not reach is refused here by GitHub, not by a list of ours.
|
|
513
|
+
*
|
|
514
|
+
* The repository has just said what it calls its trunk, so a deployment
|
|
515
|
+
* with no branch model is given that one: the same answer the setup
|
|
516
|
+
* screen fills in for a repository reached by its address.
|
|
517
|
+
*/
|
|
518
|
+
async function githubConnectionHoldsFor(
|
|
519
|
+
setup: RepositorySetup,
|
|
520
|
+
entries: Record<string, string>,
|
|
521
|
+
after: (key: string) => string,
|
|
522
|
+
wasComplete: boolean,
|
|
523
|
+
res: express.Response,
|
|
524
|
+
): Promise<boolean> {
|
|
525
|
+
const refuse = (problem: string, field = 'githubRepository') => {
|
|
526
|
+
res.status(400).json({ error: problem, problems: { [field]: problem } });
|
|
527
|
+
return false;
|
|
528
|
+
};
|
|
529
|
+
const app = setup.githubApp;
|
|
530
|
+
if (!app) return refuse('This deployment cannot connect to GitHub through a GitHub App.', 'gitMode');
|
|
531
|
+
if (!app.answered(after)) {
|
|
532
|
+
return refuse(
|
|
533
|
+
after('githubRepository')
|
|
534
|
+
? 'Connect GitHub before choosing a repository.'
|
|
535
|
+
: 'Choose the repository the knowledge base lives in.',
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
const url = app.url(after);
|
|
539
|
+
const unanswered =
|
|
540
|
+
validateBranchModel({ defaultBranch: after('defaultBranch'), protectedBranches: after('protectedBranches') }) !== null;
|
|
541
|
+
// Against what is CHOSEN now, not what is in effect: a repository that
|
|
542
|
+
// was proven by the save that chose it is not proven again by the next.
|
|
543
|
+
const stored = (key: string) => settings.resolve(key);
|
|
544
|
+
const changes = setup.source.chosen() !== 'github-app' || url !== setup.source.url(stored);
|
|
545
|
+
if (!changes && (wasComplete || unanswered)) return true;
|
|
546
|
+
// BEFORE GitHub is asked anything with the installation token: that
|
|
547
|
+
// token reaches every repository the installation covers, and would
|
|
548
|
+
// answer for one the person connecting it could never have written to.
|
|
549
|
+
if (!app.permits(after('githubRepository'), after)) {
|
|
550
|
+
log.warn('a repository was named that the person who connected GitHub could not push to');
|
|
551
|
+
return refuse(
|
|
552
|
+
'Choose a repository your own GitHub account can write to. If this one should be, press “Refresh the list” so it is brought up to date.',
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
try {
|
|
556
|
+
await app.prepare({ asked: true });
|
|
557
|
+
} catch (err) {
|
|
558
|
+
log.error('GitHub gave no token for the installation:', { detail: err instanceof Error ? err.message : String(err) });
|
|
559
|
+
}
|
|
560
|
+
const token = app.token();
|
|
561
|
+
if (!token) {
|
|
562
|
+
return refuse('GitHub gave this deployment no access. The app may have been uninstalled: connect it again.', 'gitMode');
|
|
563
|
+
}
|
|
564
|
+
const check = await checkConnection({ url, token, username: DEFAULT_GIT_USERNAME });
|
|
565
|
+
if (check.outcome !== 'connected') {
|
|
566
|
+
return refuse(
|
|
567
|
+
check.outcome === 'read-only'
|
|
568
|
+
? 'The GitHub App can read that repository but not write to it. Grant it write access to the repository’s contents.'
|
|
569
|
+
: check.reason === 'unreachable'
|
|
570
|
+
? 'GitHub could not be reached. Try again shortly.'
|
|
571
|
+
: 'The GitHub App cannot reach that repository. Add the repository to the app’s installation on GitHub.',
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
if (!after('defaultBranch') && !after('protectedBranches')) {
|
|
575
|
+
const trunk = check.defaultBranch || check.branches[0] || (check.empty ? MANAGED_DEFAULT_BRANCH : '');
|
|
576
|
+
if (trunk) {
|
|
577
|
+
entries.defaultBranch = trunk;
|
|
578
|
+
entries.protectedBranches = trunk;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
return true;
|
|
582
|
+
}
|
|
583
|
+
|
|
401
584
|
/**
|
|
402
585
|
* A SAVED CONNECTION IS ONE THE HOST HAS ACCEPTED FOR READING AND WRITING.
|
|
403
586
|
*
|
|
@@ -423,6 +606,25 @@ export function createSetupRoutes(
|
|
|
423
606
|
res: express.Response,
|
|
424
607
|
): Promise<boolean> {
|
|
425
608
|
const after = settings.resolveAfter(entries);
|
|
609
|
+
if (repository && repository.source.mode(after) === 'managed') {
|
|
610
|
+
// Nothing to prove to a host: the repository is the deployment's own.
|
|
611
|
+
// What has to hold is that it EXISTS before the save that points
|
|
612
|
+
// everything at it, so a disk that cannot take it refuses the choice
|
|
613
|
+
// instead of failing the first clone.
|
|
614
|
+
try {
|
|
615
|
+
await repository.ensureManaged(after('defaultBranch') || MANAGED_DEFAULT_BRANCH);
|
|
616
|
+
return true;
|
|
617
|
+
} catch (err) {
|
|
618
|
+
log.error('the managed repository could not be created:', { err });
|
|
619
|
+
const problem =
|
|
620
|
+
'The repository could not be created on this deployment’s storage. Check that its backups folder is writable, or connect a repository of your own.';
|
|
621
|
+
res.status(400).json({ error: problem, problems: { gitMode: problem } });
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
if (repository && repository.source.mode(after) === 'github-app') {
|
|
626
|
+
return githubConnectionHoldsFor(repository, entries, after, wasComplete, res);
|
|
627
|
+
}
|
|
426
628
|
const now: RepositoryConnection = {
|
|
427
629
|
url: settings.resolve('kbRepoUrl'),
|
|
428
630
|
token: settings.resolve('gitToken'),
|
|
@@ -759,8 +961,12 @@ export function createSetupRoutes(
|
|
|
759
961
|
* deployment signs in perfectly well without it, and gating on it would lock
|
|
760
962
|
* an admin out of the screen where they would set it up.
|
|
761
963
|
*/
|
|
762
|
-
export function settingsAnswered(
|
|
763
|
-
|
|
964
|
+
export function settingsAnswered(
|
|
965
|
+
settings: DeploymentSettingsService,
|
|
966
|
+
/** What answers for the repository. Absent: an address and a token, the one way there was. */
|
|
967
|
+
source?: Pick<RepositorySource, 'answered'>,
|
|
968
|
+
): boolean {
|
|
969
|
+
const kb = source ? source.answered() : Boolean(settings.resolve('kbRepoUrl') && settings.resolve('gitToken'));
|
|
764
970
|
const branches =
|
|
765
971
|
validateBranchModel({
|
|
766
972
|
defaultBranch: settings.resolve('defaultBranch'),
|
|
@@ -784,11 +990,19 @@ export function settingsAnswered(settings: DeploymentSettingsService): boolean {
|
|
|
784
990
|
* that puts it there. {@link awaitingRestart} is what tells the screen to ask
|
|
785
991
|
* for one rather than claim a field is missing.
|
|
786
992
|
*/
|
|
787
|
-
export function isComplete(
|
|
788
|
-
|
|
993
|
+
export function isComplete(
|
|
994
|
+
settings: DeploymentSettingsService,
|
|
995
|
+
kb: Pick<KbContext, 'isBranchModelConfigured'>,
|
|
996
|
+
source?: Pick<RepositorySource, 'answered'>,
|
|
997
|
+
): boolean {
|
|
998
|
+
return settingsAnswered(settings, source) && kb.isBranchModelConfigured();
|
|
789
999
|
}
|
|
790
1000
|
|
|
791
1001
|
/** Answered, but not yet in effect: everything is stored, the process is stale. */
|
|
792
|
-
export function awaitingRestart(
|
|
793
|
-
|
|
1002
|
+
export function awaitingRestart(
|
|
1003
|
+
settings: DeploymentSettingsService,
|
|
1004
|
+
kb: Pick<KbContext, 'isBranchModelConfigured'>,
|
|
1005
|
+
source?: Pick<RepositorySource, 'answered'>,
|
|
1006
|
+
): boolean {
|
|
1007
|
+
return settingsAnswered(settings, source) && !kb.isBranchModelConfigured();
|
|
794
1008
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from '../allowed-tools-check.js';
|
|
8
8
|
import type { UtcpTool } from '../../tool-registry/tool.contract.js';
|
|
9
9
|
import type { ToolManualDetail, ToolManualSummary } from '../../tool-manuals/tool-manuals.contract.js';
|
|
10
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
10
11
|
|
|
11
12
|
const visible: VisibleTools = {
|
|
12
13
|
core: ['read_file', 'get_skill', 'list_skills'],
|
|
@@ -110,10 +111,10 @@ describe('checkAllowedTools', () => {
|
|
|
110
111
|
|
|
111
112
|
describe('skillFileRepoPath', () => {
|
|
112
113
|
test('recognises skill files under the plugin and skills roots only', () => {
|
|
113
|
-
expect(skillFileRepoPath(
|
|
114
|
-
expect(skillFileRepoPath(
|
|
115
|
-
expect(skillFileRepoPath(
|
|
116
|
-
expect(skillFileRepoPath(
|
|
114
|
+
expect(skillFileRepoPath(testKbContext(),'knowledge-base/Plugins/Sales/rfi/SKILL.md')).toBe('Plugins/Sales/rfi/SKILL.md');
|
|
115
|
+
expect(skillFileRepoPath(testKbContext(),'./knowledge-base/Skills/triage/SKILL.md')).toBe('Skills/triage/SKILL.md');
|
|
116
|
+
expect(skillFileRepoPath(testKbContext(),'knowledge-base/Plugins/Sales/rfi/notes.md')).toBeNull();
|
|
117
|
+
expect(skillFileRepoPath(testKbContext(),'knowledge-base/Data/SKILL.md')).toBeNull();
|
|
117
118
|
});
|
|
118
119
|
});
|
|
119
120
|
|
|
@@ -138,7 +139,7 @@ describe('AllowedToolsChecker', () => {
|
|
|
138
139
|
}
|
|
139
140
|
: null,
|
|
140
141
|
};
|
|
141
|
-
const checker = new AllowedToolsChecker(registry, manuals,
|
|
142
|
+
const checker = new AllowedToolsChecker(registry, manuals, testKbContext());
|
|
142
143
|
|
|
143
144
|
const skill = (tools: string) => `---\nname: rfi\ndescription: RFI.\nallowed-tools: ${tools}\n---\n\n# RFI\n`;
|
|
144
145
|
|
|
@@ -160,7 +161,7 @@ describe('AllowedToolsChecker', () => {
|
|
|
160
161
|
const broken = new AllowedToolsChecker(
|
|
161
162
|
{ listExternal: async () => { throw new Error('down'); } },
|
|
162
163
|
manuals,
|
|
163
|
-
|
|
164
|
+
testKbContext(),
|
|
164
165
|
);
|
|
165
166
|
await expect(
|
|
166
167
|
broken.checkSave('a@x.com', 'knowledge-base/Plugins/Sales/rfi/SKILL.md', skill('hubspot.serch')),
|
|
@@ -168,7 +169,7 @@ describe('AllowedToolsChecker', () => {
|
|
|
168
169
|
});
|
|
169
170
|
|
|
170
171
|
test('a capped capability list is treated as unknown, never as proof of absence', async () => {
|
|
171
|
-
const capped = new AllowedToolsChecker(registry, manuals,
|
|
172
|
+
const capped = new AllowedToolsChecker(registry, manuals, testKbContext(), 1);
|
|
172
173
|
expect(await capped.check('a@x.com', ['hubspot.whatever'])).toEqual([]);
|
|
173
174
|
});
|
|
174
175
|
|
|
@@ -179,7 +180,7 @@ describe('AllowedToolsChecker', () => {
|
|
|
179
180
|
const listExternal = vi.fn(registry.listExternal);
|
|
180
181
|
const listAccessible = vi.fn(manuals.listAccessible);
|
|
181
182
|
const getDetail = vi.fn(manuals.getDetail);
|
|
182
|
-
const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail },
|
|
183
|
+
const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail }, testKbContext());
|
|
183
184
|
|
|
184
185
|
expect(entries(await spying.check('alice@example.com', ['hubspot.serch']))).toEqual(['hubspot.serch']);
|
|
185
186
|
expect(listExternal).toHaveBeenCalledWith({ userEmail: 'alice@example.com' });
|
|
@@ -193,7 +194,7 @@ describe('AllowedToolsChecker', () => {
|
|
|
193
194
|
const listExternal = vi.fn(registry.listExternal);
|
|
194
195
|
const listAccessible = vi.fn(manuals.listAccessible);
|
|
195
196
|
const getDetail = vi.fn(manuals.getDetail);
|
|
196
|
-
const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail },
|
|
197
|
+
const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail }, testKbContext());
|
|
197
198
|
|
|
198
199
|
const results = await spying.checkSaves('a@x.com', [
|
|
199
200
|
{ path: 'knowledge-base/Plugins/Sales/rfi/SKILL.md', content: skill('hubspot.serch') },
|
|
@@ -214,7 +215,7 @@ describe('AllowedToolsChecker', () => {
|
|
|
214
215
|
const listExternal = vi.fn(registry.listExternal);
|
|
215
216
|
const listAccessible = vi.fn(manuals.listAccessible);
|
|
216
217
|
const getDetail = vi.fn(manuals.getDetail);
|
|
217
|
-
const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail },
|
|
218
|
+
const spying = new AllowedToolsChecker({ listExternal }, { listAccessible, getDetail }, testKbContext());
|
|
218
219
|
|
|
219
220
|
expect(await spying.check('a@x.com', ['Bash', 'Read', 'Bash(git:*)', 'mcp__github__create_issue', 'shell'])).toEqual([]);
|
|
220
221
|
expect(listExternal).not.toHaveBeenCalled();
|
|
@@ -19,6 +19,7 @@ import type { ToolManualDetail, ToolManualSummary } from '../../tool-manuals/too
|
|
|
19
19
|
import { registerSkillsTools } from '../skills.tools.js';
|
|
20
20
|
import type { ISkillService } from '../skills.contract.js';
|
|
21
21
|
import { AllowedToolsChecker } from '../allowed-tools-check.js';
|
|
22
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* The agent surfaces end to end: a SKILL.md written through the file tools
|
|
@@ -41,7 +42,7 @@ const checker = new AllowedToolsChecker(
|
|
|
41
42
|
capabilities: [{ name: 'search', description: null }],
|
|
42
43
|
}),
|
|
43
44
|
},
|
|
44
|
-
KB_DIR,
|
|
45
|
+
testKbContext({ kbDirName: KB_DIR }),
|
|
45
46
|
);
|
|
46
47
|
|
|
47
48
|
/** What the tool handed the service on its last `getSkill` — the tool's one job is to pass it on. */
|
|
@@ -109,8 +110,8 @@ async function start(): Promise<string> {
|
|
|
109
110
|
const router = express.Router();
|
|
110
111
|
registerWorkspaceTools(
|
|
111
112
|
registry, router, fakeAuth, toolHandler,
|
|
112
|
-
new SpillStore(join(tmpdir(), 'bevel-test-spills')), new DocExtractService(join(tmpdir(), 'bevel-test-doc-extract')), allowAll, KB_DIR,
|
|
113
|
-
{ service: {} as never, enabled: false, kbDirName: KB_DIR, recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
|
|
113
|
+
new SpillStore(join(tmpdir(), 'bevel-test-spills')), new DocExtractService(join(tmpdir(), 'bevel-test-doc-extract')), allowAll, testKbContext({ kbDirName: KB_DIR }),
|
|
114
|
+
{ service: {} as never, enabled: false, kb: testKbContext({ kbDirName: KB_DIR }), recoveryBotEmail: 'recovery-bot@bevel.local', hooks: new WorkflowHooks() },
|
|
114
115
|
new RoutineWritePolicyService(),
|
|
115
116
|
{} as never,
|
|
116
117
|
checker,
|
|
@@ -5,6 +5,7 @@ import { hashEmail } from '../../../shared/email-identity.js';
|
|
|
5
5
|
import type { WorkspaceService } from '../../workspace/workspace.service.js';
|
|
6
6
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
7
7
|
import type { ISkillService, SkillSummary } from '../skills.contract.js';
|
|
8
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* The half of the catalog that is NOT on the default branch.
|
|
@@ -77,7 +78,7 @@ function harness(opts: {
|
|
|
77
78
|
listChangeRequests: async () => opts.crs,
|
|
78
79
|
} as unknown as IWorkflowService;
|
|
79
80
|
|
|
80
|
-
return new PendingSkillsService(workspaceService, accessControl, skillService, workflow);
|
|
81
|
+
return new PendingSkillsService(workspaceService, accessControl, skillService, workflow, testKbContext());
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
const ADMIN_WRITES = {
|
|
@@ -210,6 +211,7 @@ describe('PendingSkillsService', () => {
|
|
|
210
211
|
{} as unknown as IAccessControl,
|
|
211
212
|
{ listSkills: async () => [] } as unknown as ISkillService,
|
|
212
213
|
workflow,
|
|
214
|
+
testKbContext(),
|
|
213
215
|
);
|
|
214
216
|
await expect(svc.listPendingSkills(AUTHOR)).resolves.toEqual([]);
|
|
215
217
|
});
|
|
@@ -11,6 +11,7 @@ import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
|
11
11
|
import type { JoinRequestsService } from '../../plugins/join-requests.service.js';
|
|
12
12
|
import type { ISkillService } from '../skills.contract.js';
|
|
13
13
|
import { createSkillAccessRequestRoutes } from '../skill-access-requests.routes.js';
|
|
14
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* The branch probe behind an access request: the listing is used to PROVE a
|
|
@@ -26,15 +27,19 @@ const FOLDER = 'Skills/Eng/deploy';
|
|
|
26
27
|
|
|
27
28
|
async function makeHarness(listBranches: IWorkflowService['listBranches']) {
|
|
28
29
|
const workflow = {
|
|
29
|
-
|
|
30
|
+
listChangeRequests: vi.fn(async () => []),
|
|
30
31
|
listBranches: vi.fn(listBranches),
|
|
31
32
|
createBranch: vi.fn(async () => ({ name: 'x', isDefault: false, isProtected: false })),
|
|
33
|
+
deleteBranch: vi.fn(async () => undefined),
|
|
32
34
|
commitChanges: vi.fn(async () => null),
|
|
33
35
|
openChangeRequest: vi.fn(async () => ({ number: 42 })),
|
|
36
|
+
getChangeRequestDetail: vi.fn(async () => ({ body: '' })),
|
|
34
37
|
} as unknown as IWorkflowService;
|
|
35
38
|
const workspaceService = {
|
|
36
39
|
getOrCreateForBranch: vi.fn(async (branch: string) => ({ id: workspaceIdForBranch(branch) })),
|
|
37
40
|
readFile: vi.fn(async () => '---\n---\nwrite:\n - Eve <eve@x.io>\n'),
|
|
41
|
+
readFileAtRef: vi.fn(async () => null),
|
|
42
|
+
ensureRemotesFetched: vi.fn(async () => undefined),
|
|
38
43
|
writeFile: vi.fn(async () => undefined),
|
|
39
44
|
} as unknown as WorkspaceService;
|
|
40
45
|
const accessControl = { canWrite: vi.fn(async () => false) } as unknown as IAccessControl;
|
|
@@ -52,7 +57,7 @@ async function makeHarness(listBranches: IWorkflowService['listBranches']) {
|
|
|
52
57
|
workflow,
|
|
53
58
|
workspaceService,
|
|
54
59
|
joinRequests: { list: vi.fn(), reconcile: vi.fn() } as unknown as JoinRequestsService,
|
|
55
|
-
kbDirName: KB,
|
|
60
|
+
kb: testKbContext({ kbDirName: KB }),
|
|
56
61
|
resolveUser: async () => MIA,
|
|
57
62
|
}),
|
|
58
63
|
);
|
|
@@ -5,6 +5,7 @@ import '../../auth/auth.middleware.js'; // Express Request.userEmail augmentatio
|
|
|
5
5
|
import { createSkillsRoutes } from '../skills.routes.js';
|
|
6
6
|
import type { ISkillService } from '../skills.contract.js';
|
|
7
7
|
import type { IAllowedToolsChecker } from '../allowed-tools-check.js';
|
|
8
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* The browser's skill read carries the same `allowed-tools` warnings as
|
|
@@ -42,7 +43,7 @@ async function start(checker?: IAllowedToolsChecker): Promise<string> {
|
|
|
42
43
|
req.userEmail = EMAIL;
|
|
43
44
|
next();
|
|
44
45
|
});
|
|
45
|
-
app.use('/api', createSkillsRoutes(skillService, undefined, undefined, undefined, checker));
|
|
46
|
+
app.use('/api', createSkillsRoutes(skillService, testKbContext(), undefined, undefined, undefined, checker));
|
|
46
47
|
server = await new Promise<Server>((resolve) => {
|
|
47
48
|
const s = app.listen(0, () => resolve(s));
|
|
48
49
|
});
|
|
@@ -13,6 +13,7 @@ import { execFile } from 'node:child_process';
|
|
|
13
13
|
import { promisify } from 'node:util';
|
|
14
14
|
import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
|
|
15
15
|
import { GitService } from '../../workflow/git/git.service.js';
|
|
16
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
16
17
|
|
|
17
18
|
const execFileAsync = promisify(execFile);
|
|
18
19
|
|
|
@@ -53,7 +54,7 @@ describe('SkillService', () => {
|
|
|
53
54
|
} as unknown as IAccessControl;
|
|
54
55
|
|
|
55
56
|
const svc = (access: IAccessControl = allowAll) =>
|
|
56
|
-
new SkillService(workspaceService, access, KB_DIR, new NodeFs());
|
|
57
|
+
new SkillService(workspaceService, access, testKbContext({ kbDirName: KB_DIR }), new NodeFs());
|
|
57
58
|
|
|
58
59
|
beforeEach(async () => {
|
|
59
60
|
root = await mkdtemp(join(tmpdir(), 'skills-'));
|
|
@@ -377,7 +378,7 @@ describe('SkillService', () => {
|
|
|
377
378
|
|
|
378
379
|
const versioned = (access: IAccessControl = allowAll) => {
|
|
379
380
|
const service = svc(access);
|
|
380
|
-
service.setHistory(new GitService(workspaceService, new WorkflowHooks(), KB_DIR));
|
|
381
|
+
service.setHistory(new GitService(workspaceService, new WorkflowHooks(), testKbContext({ kbDirName: KB_DIR })));
|
|
381
382
|
return service;
|
|
382
383
|
};
|
|
383
384
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PLUGINS_DIR, SKILLS_DIR } from '@bevel-software/platform-shared';
|
|
2
1
|
import { logger } from '../../shared/logging.js';
|
|
2
|
+
import type { KbContext } from '../../shared/kb-context.js';
|
|
3
3
|
import type { IToolRegistry } from '../tool-registry/tool.contract.js';
|
|
4
4
|
import {
|
|
5
5
|
EXTERNAL_KB_MANUAL_NAME,
|
|
@@ -236,11 +236,12 @@ function editDistance(a: string, b: string): number {
|
|
|
236
236
|
* Accepts the workspace spelling (`<kbDirName>/Plugins/…`) the save
|
|
237
237
|
* surfaces receive.
|
|
238
238
|
*/
|
|
239
|
-
export function skillFileRepoPath(
|
|
239
|
+
export function skillFileRepoPath(kb: Pick<KbContext, 'kbDirName' | 'layout'>, workspacePath: string): string | null {
|
|
240
240
|
const parts = workspacePath.split('/').filter((p) => p && p !== '.');
|
|
241
|
-
if (parts[0] === kbDirName) parts.shift();
|
|
241
|
+
if (parts[0] === kb.kbDirName) parts.shift();
|
|
242
242
|
if (parts.length < 3 || parts[parts.length - 1] !== 'SKILL.md') return null;
|
|
243
|
-
|
|
243
|
+
const { pluginsDir, skillsDir } = kb.layout;
|
|
244
|
+
return parts[0] === pluginsDir || parts[0] === skillsDir ? parts.join('/') : null;
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
/** What the save surfaces and `get_skill` depend on. */
|
|
@@ -267,7 +268,7 @@ export class AllowedToolsChecker implements IAllowedToolsChecker {
|
|
|
267
268
|
constructor(
|
|
268
269
|
private readonly registry: Pick<IToolRegistry, 'listExternal'>,
|
|
269
270
|
private readonly manuals: Pick<IToolManualService, 'listAccessible' | 'getDetail'>,
|
|
270
|
-
private readonly
|
|
271
|
+
private readonly kb: Pick<KbContext, 'kbDirName' | 'layout'>,
|
|
271
272
|
/**
|
|
272
273
|
* The cap `getDetail` applies to a manual's capabilities. Taken from the
|
|
273
274
|
* projection itself: a copy of the number here would silently start
|
|
@@ -300,7 +301,7 @@ export class AllowedToolsChecker implements IAllowedToolsChecker {
|
|
|
300
301
|
* fail because a check could not run).
|
|
301
302
|
*/
|
|
302
303
|
private declaredTools(workspacePath: string, content: string): readonly string[] | undefined {
|
|
303
|
-
if (skillFileRepoPath(this.
|
|
304
|
+
if (skillFileRepoPath(this.kb, workspacePath) === null) return undefined;
|
|
304
305
|
try {
|
|
305
306
|
return parseSkillFrontmatter(content).allowedTools;
|
|
306
307
|
} catch (err) {
|