@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
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { describe, test, expect } from 'vitest';
|
|
2
|
+
import { UtcpClientConfigSerializer } from '@utcp/sdk';
|
|
2
3
|
import {
|
|
3
4
|
BevelSecretsVariableLoader,
|
|
5
|
+
DEFAULT_SECRETS_SCOPE,
|
|
6
|
+
bevelSecretsLoaderConfig,
|
|
4
7
|
registerBevelSecretsVariableLoader,
|
|
8
|
+
unregisterBevelSecretsVariableLoader,
|
|
5
9
|
} from '../secrets-variable-loader.js';
|
|
6
10
|
import type { ISecretsVaultService } from '../secrets-vault.contract.js';
|
|
7
11
|
|
|
@@ -51,4 +55,40 @@ describe('BevelSecretsVariableLoader', () => {
|
|
|
51
55
|
const loader = new BevelSecretsVariableLoader('');
|
|
52
56
|
expect(await loader.get('m_X')).toBeNull();
|
|
53
57
|
});
|
|
58
|
+
|
|
59
|
+
test('two knowledge bases in one process resolve the same user and key from their own vaults', async () => {
|
|
60
|
+
// One process, two vaults, one user id in each (ids are only unique
|
|
61
|
+
// within a knowledge base): a loader reads the vault registered under
|
|
62
|
+
// ITS scope, and a scope nobody registered resolves nothing.
|
|
63
|
+
registerBevelSecretsVariableLoader(fakeVault('user-1', { weather_WEATHER_KEY: 'sk-acme' }), 'acme');
|
|
64
|
+
registerBevelSecretsVariableLoader(fakeVault('user-1', { weather_WEATHER_KEY: 'sk-globex' }), 'globex');
|
|
65
|
+
expect(await new BevelSecretsVariableLoader('user-1', 'acme').get('weather_WEATHER_KEY')).toBe('sk-acme');
|
|
66
|
+
expect(await new BevelSecretsVariableLoader('user-1', 'globex').get('weather_WEATHER_KEY')).toBe('sk-globex');
|
|
67
|
+
expect(await new BevelSecretsVariableLoader('user-1', 'nobody').get('weather_WEATHER_KEY')).toBeNull();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('the descriptor round-trips the scope through the serializer registry', async () => {
|
|
71
|
+
registerBevelSecretsVariableLoader(fakeVault('user-1', { weather_WEATHER_KEY: 'sk-acme' }), 'acme');
|
|
72
|
+
const config = new UtcpClientConfigSerializer().validateDict({
|
|
73
|
+
variables: {},
|
|
74
|
+
load_variables_from: [bevelSecretsLoaderConfig('user-1', 'acme')],
|
|
75
|
+
});
|
|
76
|
+
const [loader] = config.load_variables_from as BevelSecretsVariableLoader[];
|
|
77
|
+
expect(loader.scope).toBe('acme');
|
|
78
|
+
expect(await loader.get('weather_WEATHER_KEY')).toBe('sk-acme');
|
|
79
|
+
// Without a scope the descriptor names the single knowledge base's.
|
|
80
|
+
const [plain] = new UtcpClientConfigSerializer().validateDict({
|
|
81
|
+
variables: {},
|
|
82
|
+
load_variables_from: [bevelSecretsLoaderConfig('user-1')],
|
|
83
|
+
}).load_variables_from as BevelSecretsVariableLoader[];
|
|
84
|
+
expect(plain.scope).toBe(DEFAULT_SECRETS_SCOPE);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('unregistering a scope makes its loaders resolve nothing', async () => {
|
|
88
|
+
registerBevelSecretsVariableLoader(fakeVault('user-1', { weather_WEATHER_KEY: 'sk-acme' }), 'evicted');
|
|
89
|
+
const loader = new BevelSecretsVariableLoader('user-1', 'evicted');
|
|
90
|
+
expect(await loader.get('weather_WEATHER_KEY')).toBe('sk-acme');
|
|
91
|
+
unregisterBevelSecretsVariableLoader('evicted');
|
|
92
|
+
expect(await loader.get('weather_WEATHER_KEY')).toBeNull();
|
|
93
|
+
});
|
|
54
94
|
});
|
|
@@ -2,6 +2,7 @@ import type { Server as HttpServer } from 'node:http';
|
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
4
4
|
import { createSecretsVaultRoutes } from '../secrets-vault.routes.js';
|
|
5
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* THE OWNER GATE: a tool's shared (admin) secrets — plain values and OAuth
|
|
@@ -91,6 +92,7 @@ async function baseUrlAs(email: string): Promise<string> {
|
|
|
91
92
|
app.use(
|
|
92
93
|
'/api',
|
|
93
94
|
createSecretsVaultRoutes({
|
|
95
|
+
kb: testKbContext(),
|
|
94
96
|
secretsVault,
|
|
95
97
|
toolManualService,
|
|
96
98
|
accessControl,
|
|
@@ -21,6 +21,8 @@ export {
|
|
|
21
21
|
} from './secrets-vault.contract.js';
|
|
22
22
|
export {
|
|
23
23
|
registerBevelSecretsVariableLoader,
|
|
24
|
+
unregisterBevelSecretsVariableLoader,
|
|
24
25
|
bevelSecretsLoaderConfig,
|
|
25
26
|
BEVEL_SECRETS_LOADER_TYPE,
|
|
27
|
+
DEFAULT_SECRETS_SCOPE,
|
|
26
28
|
} from './secrets-variable-loader.js';
|
|
@@ -18,29 +18,43 @@ const log = logger('secrets-vault');
|
|
|
18
18
|
* The `UtcpClient.create` path re-validates the whole config through the
|
|
19
19
|
* serializer registry, so a loader can't be handed in as a bare live object — it
|
|
20
20
|
* must round-trip through a registered serializer. We therefore put a plain
|
|
21
|
-
* descriptor `{ variable_loader_type, user_id }` in `load_variables_from`
|
|
22
|
-
* {@link bevelSecretsLoaderConfig}) and let the registered serializer
|
|
23
|
-
* live loader bound to the
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* descriptor `{ variable_loader_type, user_id, scope }` in `load_variables_from`
|
|
22
|
+
* (via {@link bevelSecretsLoaderConfig}) and let the registered serializer
|
|
23
|
+
* rebuild a live loader bound to the vault registered under that scope.
|
|
24
|
+
*
|
|
25
|
+
* ONE VAULT PER SCOPE, NOT PER PROCESS. The serializer registry is UTCP's and
|
|
26
|
+
* process-wide, but a process can host several knowledge bases, each with a
|
|
27
|
+
* vault of its own, and a user id is only unique within one of them. So the
|
|
28
|
+
* descriptor names the scope its vault was registered under, and a loader
|
|
29
|
+
* reads through that vault alone: two knowledge bases whose users both stored
|
|
30
|
+
* `weather_WEATHER_KEY` never see each other's value. A single-tenant
|
|
31
|
+
* deployment registers under {@link DEFAULT_SECRETS_SCOPE} and names nothing.
|
|
32
|
+
* Swapping the vault backend (e.g. to a client's external secret manager) is
|
|
33
|
+
* just a different `ISecretsVaultService` passed to
|
|
34
|
+
* {@link registerBevelSecretsVariableLoader}.
|
|
26
35
|
*/
|
|
27
36
|
export const BEVEL_SECRETS_LOADER_TYPE = 'bevel_secrets';
|
|
28
37
|
|
|
38
|
+
/** The scope a deployment that hosts one knowledge base registers under. */
|
|
39
|
+
export const DEFAULT_SECRETS_SCOPE = 'default';
|
|
40
|
+
|
|
29
41
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
42
|
+
* The vaults the reconstructed loaders read through, by scope. A composition
|
|
43
|
+
* root registers its vault before any client is built; a graph that is torn
|
|
44
|
+
* down unregisters it so a stale descriptor resolves nothing.
|
|
33
45
|
*/
|
|
34
|
-
|
|
46
|
+
const vaults = new Map<string, ISecretsVaultService>();
|
|
35
47
|
|
|
36
48
|
export class BevelSecretsVariableLoader implements VariableLoader {
|
|
37
49
|
readonly variable_loader_type = BEVEL_SECRETS_LOADER_TYPE;
|
|
38
50
|
readonly user_id: string;
|
|
51
|
+
readonly scope: string;
|
|
39
52
|
// VariableLoader is an open shape; allow arbitrary extra props.
|
|
40
53
|
[key: string]: unknown;
|
|
41
54
|
|
|
42
|
-
constructor(userId: string) {
|
|
55
|
+
constructor(userId: string, scope: string = DEFAULT_SECRETS_SCOPE) {
|
|
43
56
|
this.user_id = userId;
|
|
57
|
+
this.scope = scope;
|
|
44
58
|
}
|
|
45
59
|
|
|
46
60
|
/**
|
|
@@ -52,9 +66,10 @@ export class BevelSecretsVariableLoader implements VariableLoader {
|
|
|
52
66
|
* harvest a secret the user configured for a different manual.
|
|
53
67
|
*/
|
|
54
68
|
async get(effectiveKey: string): Promise<string | null> {
|
|
55
|
-
|
|
69
|
+
const vault = vaults.get(this.scope);
|
|
70
|
+
if (!vault || !this.user_id) return null;
|
|
56
71
|
try {
|
|
57
|
-
return await
|
|
72
|
+
return await vault.resolve(this.user_id, effectiveKey);
|
|
58
73
|
} catch (err) {
|
|
59
74
|
// Log the fault so a backend failure is distinguishable from a merely
|
|
60
75
|
// unset secret (resolve returning null) when troubleshooting.
|
|
@@ -66,15 +81,18 @@ export class BevelSecretsVariableLoader implements VariableLoader {
|
|
|
66
81
|
|
|
67
82
|
class BevelSecretsVariableLoaderSerializer extends Serializer<VariableLoader> {
|
|
68
83
|
toDict(obj: VariableLoader): Record<string, unknown> {
|
|
84
|
+
const loader = obj as BevelSecretsVariableLoader;
|
|
69
85
|
return {
|
|
70
86
|
variable_loader_type: BEVEL_SECRETS_LOADER_TYPE,
|
|
71
|
-
user_id:
|
|
87
|
+
user_id: loader.user_id ?? '',
|
|
88
|
+
scope: loader.scope ?? DEFAULT_SECRETS_SCOPE,
|
|
72
89
|
};
|
|
73
90
|
}
|
|
74
91
|
|
|
75
92
|
validateDict(obj: Record<string, unknown>): VariableLoader {
|
|
76
93
|
const userId = typeof obj.user_id === 'string' ? obj.user_id : '';
|
|
77
|
-
|
|
94
|
+
const scope = typeof obj.scope === 'string' && obj.scope ? obj.scope : DEFAULT_SECRETS_SCOPE;
|
|
95
|
+
return new BevelSecretsVariableLoader(userId, scope);
|
|
78
96
|
}
|
|
79
97
|
}
|
|
80
98
|
|
|
@@ -91,14 +109,26 @@ VariableLoaderSerializer.registerVariableLoader(
|
|
|
91
109
|
);
|
|
92
110
|
|
|
93
111
|
/**
|
|
94
|
-
* Bind the
|
|
95
|
-
*
|
|
112
|
+
* Bind the vault the loaders of `scope` read through. Called once per
|
|
113
|
+
* knowledge base at composition time; before it runs, loaders of that scope
|
|
114
|
+
* resolve to null.
|
|
96
115
|
*/
|
|
97
|
-
export function registerBevelSecretsVariableLoader(
|
|
98
|
-
|
|
116
|
+
export function registerBevelSecretsVariableLoader(
|
|
117
|
+
secretsVault: ISecretsVaultService,
|
|
118
|
+
scope: string = DEFAULT_SECRETS_SCOPE,
|
|
119
|
+
): void {
|
|
120
|
+
vaults.set(scope, secretsVault);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Forget a scope's vault — the last step of tearing a knowledge base's graph down. */
|
|
124
|
+
export function unregisterBevelSecretsVariableLoader(scope: string = DEFAULT_SECRETS_SCOPE): void {
|
|
125
|
+
vaults.delete(scope);
|
|
99
126
|
}
|
|
100
127
|
|
|
101
|
-
/**
|
|
102
|
-
|
|
103
|
-
|
|
128
|
+
/**
|
|
129
|
+
* The plain descriptor to place in a `UtcpClientConfig.load_variables_from`
|
|
130
|
+
* for a given user of the knowledge base registered under `scope`.
|
|
131
|
+
*/
|
|
132
|
+
export function bevelSecretsLoaderConfig(userId: string, scope: string = DEFAULT_SECRETS_SCOPE): Record<string, unknown> {
|
|
133
|
+
return { variable_loader_type: BEVEL_SECRETS_LOADER_TYPE, user_id: userId, scope };
|
|
104
134
|
}
|
|
@@ -3,7 +3,6 @@ import { logger } from '../../shared/logging.js';
|
|
|
3
3
|
|
|
4
4
|
const log = logger('secrets');
|
|
5
5
|
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
6
|
-
import { DEFAULT_BRANCH } from '@bevel-software/platform-shared';
|
|
7
6
|
import {
|
|
8
7
|
InvalidSecretError,
|
|
9
8
|
SecretNotFoundError,
|
|
@@ -17,11 +16,13 @@ import type { IToolManualService, ToolManualSummary, ToolVariable } from '../too
|
|
|
17
16
|
import type { IConnectionProbeService } from '../connection-probe/connection-probe.contract.js';
|
|
18
17
|
import { utcpNamespacedKey } from '../../shared/utcp-namespace.js';
|
|
19
18
|
import type { IAccessControl } from '../access/access-control.interface.js';
|
|
20
|
-
import {
|
|
19
|
+
import type { KbContext } from '../../shared/kb-context.js';
|
|
21
20
|
import '../auth/auth.middleware.js'; // Express Request augmentation (req.userId / req.userEmail)
|
|
22
21
|
|
|
23
22
|
export interface SecretsVaultRoutesDeps {
|
|
24
23
|
secretsVault: ISecretsVaultService;
|
|
24
|
+
/** The released branch's clone — where the `.tool` files the access verdicts are read from live. */
|
|
25
|
+
kb: Pick<KbContext, 'defaultWorkspaceId'>;
|
|
25
26
|
/** Source of `.tool` manuals + their declared variable scopes (default-branch catalog). */
|
|
26
27
|
toolManualService: IToolManualService;
|
|
27
28
|
/** Gates who may set a tool's ADMIN (shared) secrets — writers of the `.tool` file. */
|
|
@@ -79,16 +80,16 @@ export function isSafeReturnPath(returnTo: unknown): returnTo is string {
|
|
|
79
80
|
* `req.userId` — secrets are private per user. Mounted behind the JWT middleware.
|
|
80
81
|
*/
|
|
81
82
|
export function createSecretsVaultRoutes(deps: SecretsVaultRoutesDeps): express.Router {
|
|
82
|
-
const { secretsVault, toolManualService, accessControl, connectionProbe } = deps;
|
|
83
|
+
const { secretsVault, toolManualService, accessControl, connectionProbe, kb } = deps;
|
|
83
84
|
const router = express.Router();
|
|
84
85
|
// A FUNCTION, not a constant. Routers are constructed at boot, and on a
|
|
85
86
|
// deployment configured through the setup screen the branch model does not
|
|
86
|
-
// exist yet at that moment —
|
|
87
|
-
//
|
|
87
|
+
// exist yet at that moment — the default branch is still ''. The context
|
|
88
|
+
// learns it when setup applies the model, but only reads INSIDE a function
|
|
88
89
|
// body see it; a construction-time capture would keep handing an empty
|
|
89
90
|
// workspace id to the access resolver until the next restart ("Invalid
|
|
90
91
|
// workspace ID" on every /secrets/tools call).
|
|
91
|
-
const defaultWs = () =>
|
|
92
|
+
const defaultWs = () => kb.defaultWorkspaceId();
|
|
92
93
|
|
|
93
94
|
// The vault key = the exact key UTCP looks the var up under (doubles underscores
|
|
94
95
|
// in the manual namespace), so storage and resolution agree for snake_case ids.
|
|
@@ -149,20 +149,12 @@ describe('DeploymentSettingsService — secrets', () => {
|
|
|
149
149
|
expect(token).not.toHaveProperty('value');
|
|
150
150
|
});
|
|
151
151
|
|
|
152
|
-
it('
|
|
152
|
+
it('keeps a stored token out of the process environment: git reads it per call', async () => {
|
|
153
153
|
const { db } = makeDb();
|
|
154
154
|
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
155
155
|
await settings.save({ gitToken: 'ghp_fromsetup' }, null);
|
|
156
|
-
expect(process.env.GITHUB_TOKEN).
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
it('does not overwrite a git token the environment supplied', async () => {
|
|
160
|
-
process.env.GIT_TOKEN = 'ghp_fromenv';
|
|
161
|
-
process.env.GITHUB_TOKEN = 'ghp_fromenv';
|
|
162
|
-
const { db } = makeDb();
|
|
163
|
-
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
164
|
-
settings.syncGitTokenEnv();
|
|
165
|
-
expect(process.env.GITHUB_TOKEN).toBe('ghp_fromenv');
|
|
156
|
+
expect(process.env.GITHUB_TOKEN).toBeUndefined();
|
|
157
|
+
expect(settings.resolve('gitToken')).toBe('ghp_fromsetup');
|
|
166
158
|
});
|
|
167
159
|
|
|
168
160
|
it('refuses to store a secret with no encryption key rather than writing plaintext', async () => {
|
|
@@ -528,3 +520,24 @@ describe('DeploymentSettingsService — validation', () => {
|
|
|
528
520
|
).toEqual([]);
|
|
529
521
|
});
|
|
530
522
|
});
|
|
523
|
+
|
|
524
|
+
describe('DeploymentSettingsService — an environment of its own', () => {
|
|
525
|
+
it('resolves the env-first layer from the environment it was given, not the process\'s', async () => {
|
|
526
|
+
process.env.KB_REPO_URL = 'https://host.example/leaks-into-every-tenant.git';
|
|
527
|
+
const { db } = makeDb();
|
|
528
|
+
const own = new DeploymentSettingsService(db, ENC_KEY, undefined, {
|
|
529
|
+
env: { KB_REPO_URL: 'https://github.com/acme/kb.git', GIT_USERNAME: 'oauth2' },
|
|
530
|
+
});
|
|
531
|
+
await own.load();
|
|
532
|
+
expect(own.resolve('kbRepoUrl')).toBe('https://github.com/acme/kb.git');
|
|
533
|
+
expect(own.sourceOf('kbRepoUrl')).toBe('env');
|
|
534
|
+
expect(own.resolve('gitUsername')).toBe('oauth2');
|
|
535
|
+
// What the given environment leaves out is not taken from the process either.
|
|
536
|
+
expect(own.resolve('gitToken')).toBe('');
|
|
537
|
+
expect(own.sourceOf('gitToken')).toBe('unset');
|
|
538
|
+
// A service built without one keeps reading the process, as before.
|
|
539
|
+
const shared = new DeploymentSettingsService(db, ENC_KEY);
|
|
540
|
+
await shared.load();
|
|
541
|
+
expect(shared.resolve('kbRepoUrl')).toBe('https://host.example/leaks-into-every-tenant.git');
|
|
542
|
+
});
|
|
543
|
+
});
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
rootFolderListerFor,
|
|
11
11
|
type GitRunner,
|
|
12
12
|
} from '../git-root-folders.js';
|
|
13
|
-
import type
|
|
13
|
+
import { NO_GIT_CREDENTIALS, type IGitRunner } from '../../../shared/git.contract.js';
|
|
14
14
|
|
|
15
15
|
const LISTING = {
|
|
16
16
|
url: 'https://example.com/acme/kb.git',
|
|
@@ -226,6 +226,7 @@ describe('rootFolderListerFor — the listing runs through the deployment git po
|
|
|
226
226
|
const outcomes = ['', 'KnowledgeBase\0Plugins\0'];
|
|
227
227
|
const port: IGitRunner = {
|
|
228
228
|
defaultTimeoutMs: 1000,
|
|
229
|
+
credentials: NO_GIT_CREDENTIALS,
|
|
229
230
|
run: (async (cwd: string, args: string[], opts: { env?: NodeJS.ProcessEnv; timeoutMs?: number } = {}) => {
|
|
230
231
|
calls.push({ cwd, args, opts });
|
|
231
232
|
return { stdout: outcomes.shift() ?? '', stderr: '' };
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { NodeGitRunner } from '../../workflow/git/node-git-runner.js';
|
|
6
|
+
import { ManagedRepository, MANAGED_REPOSITORY_DIR } from '../managed-repository.js';
|
|
7
|
+
import { RepositorySource, type GitHubAppRepository } from '../repository-source.js';
|
|
8
|
+
|
|
9
|
+
let root: string;
|
|
10
|
+
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
root = await fs.mkdtemp(path.join(os.tmpdir(), 'hexis-managed-'));
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
afterEach(async () => {
|
|
16
|
+
await fs.rm(root, { recursive: true, force: true });
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const reading = (values: Record<string, string>) => (key: string) => values[key] ?? '';
|
|
20
|
+
|
|
21
|
+
function source(values: Record<string, string>, extra: { fallbackToken?: string; githubApp?: GitHubAppRepository } = {}) {
|
|
22
|
+
const managed = new ManagedRepository(path.join(root, 'managed-repository'));
|
|
23
|
+
return {
|
|
24
|
+
managed,
|
|
25
|
+
source: new RepositorySource({
|
|
26
|
+
read: reading(values),
|
|
27
|
+
fallback: { username: 'x-access-token', token: extra.fallbackToken ?? '' },
|
|
28
|
+
managed,
|
|
29
|
+
...(extra.githubApp ? { githubApp: extra.githubApp } : {}),
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const HOSTED = { kbRepoUrl: 'https://git.example.com/acme/kb.git', gitToken: 'the-token', gitUsername: 'oauth2' };
|
|
35
|
+
|
|
36
|
+
describe('RepositorySource: which way a deployment has its repository', () => {
|
|
37
|
+
it('has none while nothing is configured', () => {
|
|
38
|
+
const { source: s } = source({});
|
|
39
|
+
expect(s.mode()).toBeNull();
|
|
40
|
+
expect(s.url()).toBe('');
|
|
41
|
+
expect(s.answered()).toBe(false);
|
|
42
|
+
expect(s.credentials.token()).toBeNull();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('reads a deployment configured before there was a choice as what it has: an address and a token', () => {
|
|
46
|
+
const { source: s } = source(HOSTED);
|
|
47
|
+
expect(s.mode()).toBe('token');
|
|
48
|
+
expect(s.url()).toBe(HOSTED.kbRepoUrl);
|
|
49
|
+
expect(s.credentials.token()).toBe('the-token');
|
|
50
|
+
expect(s.credentials.username()).toBe('oauth2');
|
|
51
|
+
expect(s.answered()).toBe(true);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('reads a token the environment spells the old way', () => {
|
|
55
|
+
const { source: s } = source({ kbRepoUrl: HOSTED.kbRepoUrl }, { fallbackToken: 'from-GITHUB_TOKEN' });
|
|
56
|
+
expect(s.mode()).toBe('token');
|
|
57
|
+
expect(s.credentials.token()).toBe('from-GITHUB_TOKEN');
|
|
58
|
+
expect(s.answered()).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('is not answered by half of an address and a token', () => {
|
|
62
|
+
expect(source({ kbRepoUrl: HOSTED.kbRepoUrl }).source.answered()).toBe(false);
|
|
63
|
+
expect(source({ gitToken: 'the-token' }).source.answered()).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('ignores a mode it does not know, and reads what is configured', () => {
|
|
67
|
+
expect(source({ ...HOSTED, gitMode: 'carrier-pigeon' }).source.mode()).toBe('token');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('answers for the values a save would put in effect, without the save', () => {
|
|
71
|
+
const { source: s, managed } = source(HOSTED);
|
|
72
|
+
const after = reading({ ...HOSTED, gitMode: 'managed' });
|
|
73
|
+
expect(s.mode(after)).toBe('managed');
|
|
74
|
+
expect(s.url(after)).toBe(managed.path);
|
|
75
|
+
// What is in effect has not moved.
|
|
76
|
+
expect(s.mode()).toBe('token');
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe('RepositorySource: a repository the deployment keeps', () => {
|
|
81
|
+
it('is reached by its path, and presented nothing', () => {
|
|
82
|
+
const { source: s, managed } = source({ gitMode: 'managed' });
|
|
83
|
+
expect(s.url()).toBe(managed.path);
|
|
84
|
+
expect(s.url()).toBe(path.join(root, 'managed-repository', MANAGED_REPOSITORY_DIR));
|
|
85
|
+
expect(s.answered()).toBe(true);
|
|
86
|
+
expect(s.credentials.token()).toBeNull();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* One mode's credential is never presented to another mode's repository.
|
|
91
|
+
* A deployment that moved still has its old token stored, and it must not
|
|
92
|
+
* ride along in the environment of every git call made against a folder.
|
|
93
|
+
*/
|
|
94
|
+
it('is never presented the token of the repository the deployment had before', () => {
|
|
95
|
+
const { source: s } = source({ ...HOSTED, gitMode: 'managed' }, { fallbackToken: 'from-the-environment' });
|
|
96
|
+
expect(s.credentials.token()).toBeNull();
|
|
97
|
+
expect(s.credentials.username()).toBe('x-access-token');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('RepositorySource: a repository reached through a GitHub App', () => {
|
|
102
|
+
const app = (overrides: Partial<GitHubAppRepository> = {}): GitHubAppRepository => ({
|
|
103
|
+
url: () => 'https://github.com/acme/kb.git',
|
|
104
|
+
token: () => 'an-installation-token',
|
|
105
|
+
prepare: async () => undefined,
|
|
106
|
+
answered: () => true,
|
|
107
|
+
...overrides,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('asks the app for the address and the token', () => {
|
|
111
|
+
const { source: s } = source({ gitMode: 'github-app', gitToken: 'a-leftover' }, { githubApp: app() });
|
|
112
|
+
expect(s.url()).toBe('https://github.com/acme/kb.git');
|
|
113
|
+
expect(s.credentials.token()).toBe('an-installation-token');
|
|
114
|
+
expect(s.credentials.username()).toBe('x-access-token');
|
|
115
|
+
expect(s.answered()).toBe(true);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('renews the token before git is run, and only in this mode', async () => {
|
|
119
|
+
let renewed = 0;
|
|
120
|
+
const githubApp = app({ prepare: async () => void (renewed += 1) });
|
|
121
|
+
await source({ gitMode: 'github-app' }, { githubApp }).source.credentials.prepare?.();
|
|
122
|
+
await source(HOSTED, { githubApp }).source.credentials.prepare?.();
|
|
123
|
+
await source({ gitMode: 'managed' }, { githubApp }).source.credentials.prepare?.();
|
|
124
|
+
expect(renewed).toBe(1);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('is unanswered on a deployment that has no such app', () => {
|
|
128
|
+
const { source: s } = source({ gitMode: 'github-app' });
|
|
129
|
+
expect(s.answered()).toBe(false);
|
|
130
|
+
expect(s.url()).toBe('');
|
|
131
|
+
expect(s.credentials.token()).toBeNull();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('ManagedRepository', () => {
|
|
136
|
+
const runner = new NodeGitRunner(30_000);
|
|
137
|
+
const git = async (cwd: string, ...args: string[]) => (await runner.run(cwd, args)).stdout.trim();
|
|
138
|
+
|
|
139
|
+
it('is created empty, bare, on the branch it is given', async () => {
|
|
140
|
+
const managed = new ManagedRepository(path.join(root, 'managed-repository'));
|
|
141
|
+
expect(await managed.exists()).toBe(false);
|
|
142
|
+
await managed.ensure(runner, 'trunk');
|
|
143
|
+
expect(await managed.exists()).toBe(true);
|
|
144
|
+
expect(await git(managed.path, 'rev-parse', '--is-bare-repository')).toBe('true');
|
|
145
|
+
expect(await git(managed.path, 'symbolic-ref', 'HEAD')).toBe('refs/heads/trunk');
|
|
146
|
+
expect(await git(managed.path, 'for-each-ref')).toBe('');
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('is cloned from, pushed to and fetched from like any remote', async () => {
|
|
150
|
+
const managed = new ManagedRepository(path.join(root, 'managed-repository'));
|
|
151
|
+
await managed.ensure(runner);
|
|
152
|
+
const one = path.join(root, 'one');
|
|
153
|
+
await fs.mkdir(one);
|
|
154
|
+
await git(one, 'init', '--initial-branch=main');
|
|
155
|
+
await fs.writeFile(path.join(one, 'README.md'), 'hello\n');
|
|
156
|
+
await git(one, 'add', '.');
|
|
157
|
+
await git(one, '-c', 'user.name=t', '-c', 'user.email=t@example.test', 'commit', '-m', 'first');
|
|
158
|
+
await git(one, 'push', managed.path, 'main');
|
|
159
|
+
|
|
160
|
+
const two = path.join(root, 'two');
|
|
161
|
+
await git(root, 'clone', '-b', 'main', managed.path, two);
|
|
162
|
+
// Whatever this machine's git makes of line endings on checkout.
|
|
163
|
+
expect((await fs.readFile(path.join(two, 'README.md'), 'utf8')).replace(/\r\n/g, '\n')).toBe('hello\n');
|
|
164
|
+
expect(await git(two, 'config', '--get', 'remote.origin.url')).toBe(managed.path);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('is left exactly as it is when it already exists', async () => {
|
|
168
|
+
const managed = new ManagedRepository(path.join(root, 'managed-repository'));
|
|
169
|
+
await managed.ensure(runner);
|
|
170
|
+
const work = path.join(root, 'work');
|
|
171
|
+
await fs.mkdir(work);
|
|
172
|
+
await git(work, 'init', '--initial-branch=main');
|
|
173
|
+
await fs.writeFile(path.join(work, 'a.md'), 'a\n');
|
|
174
|
+
await git(work, 'add', '.');
|
|
175
|
+
await git(work, '-c', 'user.name=t', '-c', 'user.email=t@example.test', 'commit', '-m', 'first');
|
|
176
|
+
await git(work, 'push', managed.path, 'main');
|
|
177
|
+
const before = await git(managed.path, 'for-each-ref');
|
|
178
|
+
|
|
179
|
+
await managed.ensure(runner, 'another-branch');
|
|
180
|
+
expect(await git(managed.path, 'for-each-ref')).toBe(before);
|
|
181
|
+
expect(await git(managed.path, 'symbolic-ref', 'HEAD')).toBe('refs/heads/main');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('refuses a folder that holds something that is not a repository', async () => {
|
|
185
|
+
const managed = new ManagedRepository(path.join(root, 'managed-repository'));
|
|
186
|
+
await fs.mkdir(managed.path, { recursive: true });
|
|
187
|
+
await fs.writeFile(path.join(managed.path, 'somebody.txt'), 'theirs');
|
|
188
|
+
await expect(managed.ensure(runner)).rejects.toThrow(/is not a git repository/);
|
|
189
|
+
expect(await fs.readFile(path.join(managed.path, 'somebody.txt'), 'utf8')).toBe('theirs');
|
|
190
|
+
});
|
|
191
|
+
});
|
|
@@ -6,6 +6,7 @@ import { createSetupRoutes } from '../setup.routes.js';
|
|
|
6
6
|
import { DeploymentSettingsService } from '../deployment-settings.service.js';
|
|
7
7
|
import type { Database } from '../../database/connection.js';
|
|
8
8
|
import type { IAdminAccessService } from '../../admin/admin.interface.js';
|
|
9
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* A boot that survived an unreachable remote leaves the RUNNER standing on a
|
|
@@ -68,7 +69,7 @@ function listen(runner: { runAll(): Promise<void>; lastFailure(): string | null
|
|
|
68
69
|
});
|
|
69
70
|
app.use(
|
|
70
71
|
'/api',
|
|
71
|
-
createSetupRoutes(settings, { isAdmin: async () => true } as IAdminAccessService, runner),
|
|
72
|
+
createSetupRoutes(settings, { isAdmin: async () => true } as IAdminAccessService, runner, testKbContext()),
|
|
72
73
|
);
|
|
73
74
|
server = app.listen(0);
|
|
74
75
|
const { port } = server.address() as AddressInfo;
|