@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
|
@@ -4,7 +4,7 @@ import { KbPluginSource } from '../discovery/kb-plugin-source.js';
|
|
|
4
4
|
import fs from 'node:fs/promises';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import os from 'node:os';
|
|
7
|
-
import { DEFAULT_BRANCH, type AuthUser } from '@bevel-software/platform-shared';
|
|
7
|
+
import { DEFAULT_BRANCH, withLinkedSkillRoots, type AuthUser } from '@bevel-software/platform-shared';
|
|
8
8
|
|
|
9
9
|
import type { WorkspaceService } from '../../workspace/workspace.service.js';
|
|
10
10
|
import { AccessControlService } from '../../access/access-control.service.js';
|
|
@@ -13,6 +13,7 @@ import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
|
|
|
13
13
|
import { PluginLinkIndex } from '../plugin-links.js';
|
|
14
14
|
import { PluginLinksService, PluginLinkError } from '../plugin-links.service.js';
|
|
15
15
|
import type { ProvisionCommitDriver } from '../plugin-provision.service.js';
|
|
16
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Linking end to end over a real tree: the real resolver decides who may
|
|
@@ -36,6 +37,10 @@ describe('PluginLinksService', () => {
|
|
|
36
37
|
let root: string;
|
|
37
38
|
let repo: string;
|
|
38
39
|
let commits: string[];
|
|
40
|
+
/** The commit SUBJECT each of those landed with — `undefined` = the default. */
|
|
41
|
+
let subjects: (string | undefined)[];
|
|
42
|
+
/** Set to make the commit driver refuse every path containing it. */
|
|
43
|
+
let failCommitsUnder: string | null;
|
|
39
44
|
let access: AccessControlService;
|
|
40
45
|
let skills: SkillService;
|
|
41
46
|
let index: PluginLinkIndex;
|
|
@@ -52,6 +57,8 @@ describe('PluginLinksService', () => {
|
|
|
52
57
|
root = await fs.mkdtemp(path.join(os.tmpdir(), 'bevel-links-'));
|
|
53
58
|
repo = path.join(root, wsId, KB_DIR);
|
|
54
59
|
commits = [];
|
|
60
|
+
subjects = [];
|
|
61
|
+
failCommitsUnder = null;
|
|
55
62
|
const workspaceService = {
|
|
56
63
|
getOrCreateForBranch: async () => ({ id: wsId }),
|
|
57
64
|
getWorkspacePath: async (id: string) => path.join(root, id),
|
|
@@ -64,8 +71,12 @@ describe('PluginLinksService', () => {
|
|
|
64
71
|
ensureRemotesFetched: async () => undefined,
|
|
65
72
|
} as unknown as WorkspaceService;
|
|
66
73
|
const driver: ProvisionCommitDriver = {
|
|
67
|
-
runPendingCommit: async (_ws, _branch, target) => {
|
|
74
|
+
runPendingCommit: async (_ws, _branch, target, _user, opts) => {
|
|
75
|
+
if (failCommitsUnder !== null && target.includes(failCommitsUnder)) {
|
|
76
|
+
throw new Error('the push gate said no');
|
|
77
|
+
}
|
|
68
78
|
commits.push(target);
|
|
79
|
+
subjects.push(opts?.summary);
|
|
69
80
|
},
|
|
70
81
|
};
|
|
71
82
|
|
|
@@ -84,9 +95,10 @@ describe('PluginLinksService', () => {
|
|
|
84
95
|
|
|
85
96
|
const disk = new NodeFs();
|
|
86
97
|
access = new AccessControlService(workspaceService, KB_DIR, disk);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
const kb = testKbContext({ kbDirName: KB_DIR });
|
|
99
|
+
skills = new SkillService(workspaceService, access, kb, disk);
|
|
100
|
+
index = new PluginLinkIndex(workspaceService, skills, access, kb, new KbPluginSource(disk, kb));
|
|
101
|
+
svc = new PluginLinksService(workspaceService, driver, access, skills, index, kb);
|
|
90
102
|
});
|
|
91
103
|
afterEach(() => fs.rm(root, { recursive: true, force: true }));
|
|
92
104
|
|
|
@@ -281,4 +293,207 @@ describe('PluginLinksService', () => {
|
|
|
281
293
|
index.invalidate();
|
|
282
294
|
expect(await index.pluginsOf('Plugins/GTM/skills/outreach')).toEqual([{ name: 'gtm', linked: false, granted: true }]);
|
|
283
295
|
});
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* A link written into the manifest WITHOUT its grants — the hand edit this
|
|
299
|
+
* whole surface exists for. `link()` writes both lines; every test below is
|
|
300
|
+
* about what the index and the repair say when they are absent.
|
|
301
|
+
*/
|
|
302
|
+
const linkByHand = async (...roots: string[]) => {
|
|
303
|
+
await write(
|
|
304
|
+
'Plugins/GTM/plugin.json',
|
|
305
|
+
`${JSON.stringify(withLinkedSkillRoots({ name: 'gtm', version: '1.0.0' }, roots), null, 2)}\n`,
|
|
306
|
+
);
|
|
307
|
+
access.invalidate(wsId);
|
|
308
|
+
skills.invalidate();
|
|
309
|
+
index.invalidate();
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
/** Whether the index calls the link to one skill healthy. */
|
|
313
|
+
const grantedOf = async (skillPath: string) =>
|
|
314
|
+
(await index.pluginsOf(skillPath)).find((m) => m.name === 'gtm')?.granted;
|
|
315
|
+
|
|
316
|
+
describe('granted — the two lines at the root, and nothing else', () => {
|
|
317
|
+
it('a PUBLIC root is not granted: the grant is the link, not the readability', async () => {
|
|
318
|
+
// The demo-core shape: the repository root says `read: everyone`, so
|
|
319
|
+
// GTM's members can read the skill and the link still names nothing.
|
|
320
|
+
await write('access.md', '---\n---\nread:\n - everyone\nwrite:\n - Admin\n');
|
|
321
|
+
await linkByHand('Skills/Eng/deploy');
|
|
322
|
+
|
|
323
|
+
expect(await access.canRead(wsId, member.email, 'Skills/Eng/deploy/SKILL.md')).toBe(true);
|
|
324
|
+
expect(await grantedOf('Skills/Eng/deploy')).toBe(false);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it('a plugin grant INHERITED from a folder above the root does not count', async () => {
|
|
328
|
+
await write(
|
|
329
|
+
'Skills/Eng/access.md',
|
|
330
|
+
'---\n---\nread:\n - plugin/gtm/read\nwrite:\n - Eve <eve@x.io>\n - plugin/gtm/write\n',
|
|
331
|
+
);
|
|
332
|
+
await linkByHand('Skills/Eng/deploy');
|
|
333
|
+
|
|
334
|
+
// The members CAN read it — and the root the manifest names still says
|
|
335
|
+
// nothing about GTM, so the link is one edit of Skills/Eng away from
|
|
336
|
+
// silently sharing nothing.
|
|
337
|
+
expect(await access.canRead(wsId, member.email, 'Skills/Eng/deploy/SKILL.md')).toBe(true);
|
|
338
|
+
expect(await grantedOf('Skills/Eng/deploy')).toBe(false);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it('both lines at the root are granted; a deny BELOW the root is not', async () => {
|
|
342
|
+
await write(
|
|
343
|
+
'Skills/Eng/access.md',
|
|
344
|
+
'---\n---\nread:\n - plugin/gtm/read\nwrite:\n - Eve <eve@x.io>\n - plugin/gtm/write\n',
|
|
345
|
+
);
|
|
346
|
+
await write('Skills/Eng/rollback/access.md', '---\n---\nread:\n - deny plugin/gtm/read\n');
|
|
347
|
+
await linkByHand('Skills/Eng');
|
|
348
|
+
|
|
349
|
+
expect(await grantedOf('Skills/Eng/deploy')).toBe(true);
|
|
350
|
+
expect(await grantedOf('Skills/Eng/rollback')).toBe(false);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('a deny AT the root beside the lines is not granted — the deny is the operator\'s', async () => {
|
|
354
|
+
// What a repair leaves behind when someone has denied the plugin: the
|
|
355
|
+
// grant is spliced in, the deny stays, and the link stays broken.
|
|
356
|
+
await write(
|
|
357
|
+
'Skills/Eng/deploy/access.md',
|
|
358
|
+
'---\n---\nread:\n - plugin/gtm/read\n - deny plugin/gtm/read\nwrite:\n - plugin/gtm/write\n',
|
|
359
|
+
);
|
|
360
|
+
await linkByHand('Skills/Eng/deploy');
|
|
361
|
+
|
|
362
|
+
expect(await grantedOf('Skills/Eng/deploy')).toBe(false);
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
describe('repairAll — what opening the plugin page runs', () => {
|
|
367
|
+
it('does not call a link denied at its root repaired: nothing to write, and the banner keeps it', async () => {
|
|
368
|
+
// The lines are there; a `deny` beside them is what breaks the link.
|
|
369
|
+
// The repair has nothing to write, and a root it did not write is not
|
|
370
|
+
// one it fixed — reporting it repaired would hide it from the one
|
|
371
|
+
// person who could act, and reload the page for nothing.
|
|
372
|
+
await write(
|
|
373
|
+
'Skills/Eng/deploy/access.md',
|
|
374
|
+
'---\n---\nread:\n - plugin/gtm/read\n - deny plugin/gtm/read\nwrite:\n - Mia <mia@x.io>\n - plugin/gtm/write\n',
|
|
375
|
+
);
|
|
376
|
+
await linkByHand('Skills/Eng/deploy');
|
|
377
|
+
commits.length = 0;
|
|
378
|
+
|
|
379
|
+
const report = await svc.repairAll(manager, 'gtm');
|
|
380
|
+
expect(report.repaired).toEqual([]);
|
|
381
|
+
expect(report.skipped).toMatchObject([
|
|
382
|
+
{ root: 'Skills/Eng/deploy', reason: 'denied', skills: [{ path: 'Skills/Eng/deploy', name: 'deploy' }] },
|
|
383
|
+
]);
|
|
384
|
+
// Eve edits Skills/Eng (the fixture's own rule) and Mia the root itself:
|
|
385
|
+
// both can remove the deny, so both are named.
|
|
386
|
+
expect(report.skipped[0].editors.users.map((u) => u.email).sort()).toEqual(['eve@x.io', 'mia@x.io']);
|
|
387
|
+
expect(commits).toEqual([]);
|
|
388
|
+
expect(await grantedOf('Skills/Eng/deploy')).toBe(false);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
it('repairs every link the writer may write, silently, and says nothing about them', async () => {
|
|
392
|
+
await write('Skills/Eng/access.md', '---\n---\nwrite:\n - Eve <eve@x.io>\n - Mia <mia@x.io>\n');
|
|
393
|
+
await linkByHand('Skills/Eng/deploy', 'Skills/Eng/rollback');
|
|
394
|
+
commits.length = 0;
|
|
395
|
+
subjects.length = 0;
|
|
396
|
+
|
|
397
|
+
expect(await svc.repairAll(manager, 'gtm')).toEqual({
|
|
398
|
+
repaired: ['Skills/Eng/deploy', 'Skills/Eng/rollback'],
|
|
399
|
+
skipped: [],
|
|
400
|
+
});
|
|
401
|
+
expect(commits).toEqual([
|
|
402
|
+
`${KB_DIR}/Skills/Eng/deploy/access.md`,
|
|
403
|
+
`${KB_DIR}/Skills/Eng/rollback/access.md`,
|
|
404
|
+
]);
|
|
405
|
+
// The commit is the only trace a silent repair leaves, so it has to
|
|
406
|
+
// explain itself.
|
|
407
|
+
expect(subjects).toEqual([
|
|
408
|
+
'Repair link: gtm → Skills/Eng/deploy (automatic, on opening the plugin page)',
|
|
409
|
+
'Repair link: gtm → Skills/Eng/rollback (automatic, on opening the plugin page)',
|
|
410
|
+
]);
|
|
411
|
+
expect(await grantedOf('Skills/Eng/deploy')).toBe(true);
|
|
412
|
+
expect(await grantedOf('Skills/Eng/rollback')).toBe(true);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
it('writes exactly what the manual repair writes', async () => {
|
|
416
|
+
await write('Skills/Eng/access.md', '---\n---\nwrite:\n - Mia <mia@x.io>\n');
|
|
417
|
+
await linkByHand('Skills/Eng/deploy', 'Skills/Eng/rollback');
|
|
418
|
+
|
|
419
|
+
await svc.repair(manager, 'gtm', 'Skills/Eng/deploy');
|
|
420
|
+
await svc.repairAll(manager, 'gtm');
|
|
421
|
+
expect(await read('Skills/Eng/rollback/access.md')).toEqual(
|
|
422
|
+
await read('Skills/Eng/deploy/access.md'),
|
|
423
|
+
);
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
it('leaves a link the writer may not repair alone, and names who can', async () => {
|
|
427
|
+
// Skills/Eng is Eve's. Mia manages GTM and nothing else.
|
|
428
|
+
await linkByHand('Skills/Eng/deploy');
|
|
429
|
+
commits.length = 0;
|
|
430
|
+
|
|
431
|
+
const report = await svc.repairAll(manager, 'gtm');
|
|
432
|
+
expect(report.repaired).toEqual([]);
|
|
433
|
+
expect(report.skipped).toEqual([
|
|
434
|
+
{
|
|
435
|
+
root: 'Skills/Eng/deploy',
|
|
436
|
+
reason: 'needs-skill-write',
|
|
437
|
+
skills: [{ path: 'Skills/Eng/deploy', name: 'deploy' }],
|
|
438
|
+
// Admin holds the write floor on any access.md, so an admin can
|
|
439
|
+
// always repair a link; the eligible lists carry no display names,
|
|
440
|
+
// so Eve is named by the address a reader can write to.
|
|
441
|
+
editors: { roles: ['Admin'], users: [{ name: 'eve@x.io', email: 'eve@x.io' }] },
|
|
442
|
+
},
|
|
443
|
+
]);
|
|
444
|
+
expect(commits).toEqual([]);
|
|
445
|
+
expect(await grantedOf('Skills/Eng/deploy')).toBe(false);
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('is refused for someone who may not write the plugin — the same 404 as an unknown one', async () => {
|
|
449
|
+
await write('Skills/Eng/access.md', '---\n---\nwrite:\n - Sam <sam@x.io>\n');
|
|
450
|
+
await linkByHand('Skills/Eng/deploy');
|
|
451
|
+
|
|
452
|
+
await expect(svc.repairAll(member, 'gtm')).rejects.toMatchObject({ status: 404 });
|
|
453
|
+
await expect(svc.repairAll(manager, 'Ghost')).rejects.toMatchObject({ status: 404 });
|
|
454
|
+
// Sam may write the skill; being unable to write GTM is what stopped it.
|
|
455
|
+
expect(commits).toEqual([]);
|
|
456
|
+
expect(await grantedOf('Skills/Eng/deploy')).toBe(false);
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
it('writes nothing the second time: a root that already carries both lines is left alone', async () => {
|
|
460
|
+
await write('Skills/Eng/access.md', '---\n---\nwrite:\n - Mia <mia@x.io>\n');
|
|
461
|
+
await linkByHand('Skills/Eng/deploy');
|
|
462
|
+
await svc.repairAll(manager, 'gtm');
|
|
463
|
+
commits.length = 0;
|
|
464
|
+
|
|
465
|
+
expect(await svc.repairAll(manager, 'gtm')).toEqual({ repaired: [], skipped: [] });
|
|
466
|
+
expect(commits).toEqual([]);
|
|
467
|
+
const rules = await read('Skills/Eng/deploy/access.md');
|
|
468
|
+
expect(rules.match(/plugin\/gtm\/read/g)).toHaveLength(1);
|
|
469
|
+
expect(rules.match(/plugin\/gtm\/write/g)).toHaveLength(1);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it('a repair that fails leaves the others repaired, and stays in the report', async () => {
|
|
473
|
+
await write('Skills/Eng/access.md', '---\n---\nwrite:\n - Eve <eve@x.io>\n - Mia <mia@x.io>\n');
|
|
474
|
+
await linkByHand('Skills/Eng/deploy', 'Skills/Eng/rollback');
|
|
475
|
+
failCommitsUnder = 'Skills/Eng/rollback';
|
|
476
|
+
commits.length = 0;
|
|
477
|
+
|
|
478
|
+
const report = await svc.repairAll(manager, 'gtm');
|
|
479
|
+
expect(report.repaired).toEqual(['Skills/Eng/deploy']);
|
|
480
|
+
expect(report.skipped).toMatchObject([{ root: 'Skills/Eng/rollback', reason: 'failed' }]);
|
|
481
|
+
// Eve and Mia both edit the scope, so both are named as able to repair it.
|
|
482
|
+
expect(report.skipped[0].editors.users.map((u) => u.email).sort()).toEqual([
|
|
483
|
+
'eve@x.io',
|
|
484
|
+
'mia@x.io',
|
|
485
|
+
]);
|
|
486
|
+
expect(commits).toEqual([`${KB_DIR}/Skills/Eng/deploy/access.md`]);
|
|
487
|
+
expect(await read('Skills/Eng/deploy/access.md')).toContain('plugin/gtm/read');
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it('has nothing to do for a plugin whose links are all healthy', async () => {
|
|
491
|
+
await write('Skills/Eng/access.md', '---\n---\nwrite:\n - Mia <mia@x.io>\n');
|
|
492
|
+
await svc.link(manager, 'gtm', 'Skills/Eng/deploy');
|
|
493
|
+
commits.length = 0;
|
|
494
|
+
|
|
495
|
+
expect(await svc.repairAll(manager, 'gtm')).toEqual({ repaired: [], skipped: [] });
|
|
496
|
+
expect(commits).toEqual([]);
|
|
497
|
+
});
|
|
498
|
+
});
|
|
284
499
|
});
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
pluginAccessMd,
|
|
16
16
|
personalAccessMd,
|
|
17
17
|
} from '../plugin-provision.service.js';
|
|
18
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
18
19
|
|
|
19
20
|
const KB = 'knowledge-base';
|
|
20
21
|
const USER: AuthUser = { id: 'u1-abcd', email: 'ali@example.com', name: 'Ali Vega' } as AuthUser;
|
|
@@ -50,7 +51,8 @@ async function makeHarness() {
|
|
|
50
51
|
const commits = { runPendingCommit: vi.fn(async () => undefined) };
|
|
51
52
|
const accessControl = { invalidate: vi.fn() } as unknown as IAccessControl;
|
|
52
53
|
const events = { emit: vi.fn() };
|
|
53
|
-
const
|
|
54
|
+
const kb = testKbContext({ kbDirName: KB });
|
|
55
|
+
const svc = new PluginProvisionService(workspaceService, commits, accessControl, kb, events, new KbPluginSource(new NodeFs(), kb), new NodeFs());
|
|
54
56
|
return { svc, dir, commits, accessControl, events, writeFile };
|
|
55
57
|
}
|
|
56
58
|
|
|
@@ -12,6 +12,7 @@ import { PushNeedsAgentResolutionError } from '../../../shared/domain-errors.js'
|
|
|
12
12
|
import { workspaceIdForBranch } from '../../../shared/workspace-id.js';
|
|
13
13
|
import { KbPluginSource } from '../discovery/kb-plugin-source.js';
|
|
14
14
|
import { PluginRenameError, PluginRenameService, renamePluginPrincipalInText } from '../plugin-rename.service.js';
|
|
15
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
15
16
|
|
|
16
17
|
// The one walk of the checkout, with a switch that makes it report a hole —
|
|
17
18
|
// the way a folder it cannot list would — to every listener on it. The
|
|
@@ -115,7 +116,7 @@ describe('PluginRenameService', () => {
|
|
|
115
116
|
|
|
116
117
|
access = new AccessControlService(workspaceService, KB_DIR, new NodeFs());
|
|
117
118
|
const disk = new HoledFs();
|
|
118
|
-
svc = new PluginRenameService(workspaceService, driver, access, new KbPluginSource(disk), disk, KB_DIR, undefined, () => {
|
|
119
|
+
svc = new PluginRenameService(workspaceService, driver, access, new KbPluginSource(disk, testKbContext({ kbDirName: KB_DIR })), disk, testKbContext({ kbDirName: KB_DIR }), undefined, () => {
|
|
119
120
|
invalidated += 1;
|
|
120
121
|
});
|
|
121
122
|
});
|
|
@@ -124,7 +125,7 @@ describe('PluginRenameService', () => {
|
|
|
124
125
|
it('refuses to claim a name against a listing with a hole in it — an unreadable folder may hold that very plugin', async () => {
|
|
125
126
|
// Discovery as the walker reports it when a folder exists but could not
|
|
126
127
|
// be read: the plugins it did see, plus the hole.
|
|
127
|
-
const real = new KbPluginSource(new NodeFs());
|
|
128
|
+
const real = new KbPluginSource(new NodeFs(), testKbContext({ kbDirName: KB_DIR }));
|
|
128
129
|
const holed = {
|
|
129
130
|
dialect: 'kb',
|
|
130
131
|
discover: async (root: string) => ({ ...(await real.discover(root)), unreadable: ['Plugins/Hidden'] }),
|
|
@@ -135,7 +136,7 @@ describe('PluginRenameService', () => {
|
|
|
135
136
|
access,
|
|
136
137
|
holed,
|
|
137
138
|
new NodeFs(),
|
|
138
|
-
KB_DIR,
|
|
139
|
+
testKbContext({ kbDirName: KB_DIR }),
|
|
139
140
|
);
|
|
140
141
|
await expect(svcOverHole.rename(manager, 'gtm', { name: 'go-to-market' })).rejects.toMatchObject({
|
|
141
142
|
status: 503,
|
|
@@ -155,7 +156,7 @@ describe('PluginRenameService', () => {
|
|
|
155
156
|
});
|
|
156
157
|
|
|
157
158
|
it('tells a NON-manager nothing about the tree — a holed discovery is still just "unknown plugin" to them', async () => {
|
|
158
|
-
const real = new KbPluginSource(new NodeFs());
|
|
159
|
+
const real = new KbPluginSource(new NodeFs(), testKbContext({ kbDirName: KB_DIR }));
|
|
159
160
|
const holed = {
|
|
160
161
|
dialect: 'kb',
|
|
161
162
|
discover: async (root: string) => ({ ...(await real.discover(root)), unreadable: ['Plugins/Hidden'] }),
|
|
@@ -166,7 +167,7 @@ describe('PluginRenameService', () => {
|
|
|
166
167
|
access,
|
|
167
168
|
holed,
|
|
168
169
|
new NodeFs(),
|
|
169
|
-
KB_DIR,
|
|
170
|
+
testKbContext({ kbDirName: KB_DIR }),
|
|
170
171
|
);
|
|
171
172
|
const refusal = await svcOverHole.rename(member, 'gtm', { name: 'go-to-market' }).catch((e: unknown) => e);
|
|
172
173
|
expect(refusal).toMatchObject({ status: 404, payload: { kind: 'unknown-plugin' } });
|
|
@@ -269,7 +270,7 @@ describe('PluginRenameService', () => {
|
|
|
269
270
|
expect(await read('Skills/Eng/deploy/access.md')).toBe(DEPLOY_RULES);
|
|
270
271
|
// The three answers that must never diverge: the rename's, the
|
|
271
272
|
// discovery source's, and the shared reader's over the file itself.
|
|
272
|
-
const { plugins } = await new KbPluginSource(new NodeFs()).discover(repo);
|
|
273
|
+
const { plugins } = await new KbPluginSource(new NodeFs(), testKbContext({ kbDirName: KB_DIR })).discover(repo);
|
|
273
274
|
const found = plugins.find((p) => p.folder === 'Plugins/GTM')!;
|
|
274
275
|
expect([found.name, found.displayName]).toEqual([result.name, result.displayName]);
|
|
275
276
|
expect(pluginDisplayNameOf(JSON.parse(await read('Plugins/GTM/plugin.json')))).toBe(result.displayName);
|
|
@@ -22,6 +22,7 @@ import { PluginJoinRequestJobs } from '../join-request-jobs.service.js';
|
|
|
22
22
|
import { pluginFolderBelowRoot } from '../plugins.service.js';
|
|
23
23
|
import { FakeJoinRequestStore } from './fake-join-request-store.js';
|
|
24
24
|
import type { PluginSummary, IPluginIndexService } from '../plugins.contract.js';
|
|
25
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* HTTP-level contract for the plugin routes: the auth gate, the three-tier
|
|
@@ -155,7 +156,14 @@ async function makeHarness(opts: HarnessOpts = {}) {
|
|
|
155
156
|
|
|
156
157
|
const index =
|
|
157
158
|
opts.index ??
|
|
158
|
-
new PluginIndexService(
|
|
159
|
+
new PluginIndexService(
|
|
160
|
+
workspaceService,
|
|
161
|
+
accessControl,
|
|
162
|
+
skillService,
|
|
163
|
+
toolService,
|
|
164
|
+
testKbContext({ kbDirName: KB }),
|
|
165
|
+
new KbPluginSource(new NodeFs(), testKbContext({ kbDirName: KB })),
|
|
166
|
+
);
|
|
159
167
|
|
|
160
168
|
const email = opts.email === undefined ? ALI : opts.email;
|
|
161
169
|
const app = express();
|
|
@@ -185,7 +193,7 @@ async function makeHarness(opts: HarnessOpts = {}) {
|
|
|
185
193
|
const joinRequestJobs = new PluginJoinRequestJobs(joinRequestStore, {
|
|
186
194
|
workflow,
|
|
187
195
|
workspaceService,
|
|
188
|
-
kbDirName: KB,
|
|
196
|
+
kb: testKbContext({ kbDirName: KB }),
|
|
189
197
|
target: async (pluginKey) => {
|
|
190
198
|
const entry = (await index.catalog()).find(
|
|
191
199
|
(g) => pluginFolderBelowRoot(g.folders[0]) === pluginKey,
|
|
@@ -221,6 +229,7 @@ async function makeHarness(opts: HarnessOpts = {}) {
|
|
|
221
229
|
joinRequestJobs,
|
|
222
230
|
provision as never,
|
|
223
231
|
async (req) => (req.userEmail ? { ...ALI_USER, email: req.userEmail } : null),
|
|
232
|
+
testKbContext({ kbDirName: KB }),
|
|
224
233
|
),
|
|
225
234
|
);
|
|
226
235
|
|
|
@@ -821,7 +830,7 @@ describe('/api/plugins routes', () => {
|
|
|
821
830
|
expect(await res.json()).toEqual({ requests: [] });
|
|
822
831
|
expect(h.joinRequests.list).toHaveBeenCalledWith(
|
|
823
832
|
'GTM',
|
|
824
|
-
'Plugins/GTM',
|
|
833
|
+
{ path: 'Plugins/GTM', kind: 'folder' },
|
|
825
834
|
expect.anything(),
|
|
826
835
|
expect.objectContaining({ email: ALI }),
|
|
827
836
|
);
|
|
@@ -8,6 +8,7 @@ import type { ISkillService, SkillSummary } from '../../skills/skills.contract.j
|
|
|
8
8
|
import type { IToolManualService, ToolManualSummary } from '../../tool-manuals/tool-manuals.contract.js';
|
|
9
9
|
import type { IPluginIndexService, PluginCatalogEntry } from '../plugins.contract.js';
|
|
10
10
|
import { createTeamsRoutes } from '../teams.routes.js';
|
|
11
|
+
import { testKbContext } from '../../../__tests__/kb-context.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* `GET /api/teams` — what each group can use, by id, sliced to what the
|
|
@@ -92,7 +93,7 @@ async function harness(opts: HarnessOpts = {}) {
|
|
|
92
93
|
if (email) req.userEmail = email;
|
|
93
94
|
next();
|
|
94
95
|
});
|
|
95
|
-
app.use('/api', createTeamsRoutes(accessControl, index, skills, tools));
|
|
96
|
+
app.use('/api', createTeamsRoutes(accessControl, index, skills, tools, testKbContext()));
|
|
96
97
|
const server = await new Promise<Server>((resolve) => {
|
|
97
98
|
const s = app.listen(0, () => resolve(s));
|
|
98
99
|
});
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { DEFAULT_BRANCH } from '@bevel-software/platform-shared';
|
|
3
2
|
import type { WorkspaceService } from '../../workspace/workspace.service.js';
|
|
4
3
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
5
4
|
import type { ISkillService } from '../../skills/skills.contract.js';
|
|
6
|
-
import {
|
|
5
|
+
import type { KbContext } from '../../../shared/kb-context.js';
|
|
7
6
|
import type { PluginLinkIndex } from '../plugin-links.js';
|
|
8
7
|
import type { PluginSource } from '../discovery/plugin-source.js';
|
|
9
8
|
import type { ITreeWalker } from '../../../shared/fs.contract.js';
|
|
@@ -31,7 +30,7 @@ export class MarketplaceCompilerService {
|
|
|
31
30
|
private readonly accessControl: IAccessControl,
|
|
32
31
|
private readonly skillService: ISkillService,
|
|
33
32
|
private readonly links: PluginLinkIndex,
|
|
34
|
-
private readonly
|
|
33
|
+
private readonly kb: KbContext,
|
|
35
34
|
private readonly marketplace: {
|
|
36
35
|
name: string;
|
|
37
36
|
owner: string;
|
|
@@ -45,6 +44,10 @@ export class MarketplaceCompilerService {
|
|
|
45
44
|
private readonly gitRunner: IGitRunner,
|
|
46
45
|
) {}
|
|
47
46
|
|
|
47
|
+
private get kbDirName(): string {
|
|
48
|
+
return this.kb.kbDirName;
|
|
49
|
+
}
|
|
50
|
+
|
|
48
51
|
/**
|
|
49
52
|
* The default-branch commit the next compile would read. Throws when git
|
|
50
53
|
* cannot say: the repo service keys freshness on this value, and a stable
|
|
@@ -108,7 +111,7 @@ export class MarketplaceCompilerService {
|
|
|
108
111
|
// --- internal --------------------------------------------------------------
|
|
109
112
|
|
|
110
113
|
private async checkout(): Promise<{ wsId: string; kbRoot: string }> {
|
|
111
|
-
const wsId = (await this.workspaceService.getOrCreateForBranch(
|
|
114
|
+
const wsId = (await this.workspaceService.getOrCreateForBranch(this.kb.defaultBranch)).id;
|
|
112
115
|
return { wsId, kbRoot: path.join(await this.workspaceService.getWorkspacePath(wsId), this.kbDirName) };
|
|
113
116
|
}
|
|
114
117
|
|
|
@@ -144,8 +147,3 @@ export class MarketplaceCompilerService {
|
|
|
144
147
|
};
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
|
-
|
|
148
|
-
/** The default-branch workspace id compiles run against. */
|
|
149
|
-
export function compileWorkspaceId(): string {
|
|
150
|
-
return workspaceIdForBranch(DEFAULT_BRANCH);
|
|
151
|
-
}
|
|
@@ -3,8 +3,12 @@ import { NodeFs } from '../../../kb-fs/node-fs.js';
|
|
|
3
3
|
import fs from 'node:fs/promises';
|
|
4
4
|
import os from 'node:os';
|
|
5
5
|
import path from 'node:path';
|
|
6
|
-
import {
|
|
6
|
+
import { pluginDisplayNameOf } from '@bevel-software/platform-shared';
|
|
7
7
|
import { KbPluginSource } from '../kb-plugin-source.js';
|
|
8
|
+
import { testKbContext } from '../../../../__tests__/kb-context.js';
|
|
9
|
+
|
|
10
|
+
/** The layout the source under test reads; a suite swaps it for the customer's names. */
|
|
11
|
+
let kbContext = testKbContext();
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
14
|
* The customer's tree, in their own root names (lowercase `plugins/` and
|
|
@@ -37,7 +41,7 @@ describe('KbPluginSource — bundles', () => {
|
|
|
37
41
|
|
|
38
42
|
beforeEach(async () => {
|
|
39
43
|
kb = await fs.mkdtemp(path.join(os.tmpdir(), 'bevel-bundle-'));
|
|
40
|
-
|
|
44
|
+
kbContext = testKbContext({ layout: { knowledgeBaseDir: 'docs', skillsDir: 'skills', pluginsDir: 'plugins' } });
|
|
41
45
|
await write('configs/mcp/registry.json', JSON.stringify(REGISTRY));
|
|
42
46
|
await write(
|
|
43
47
|
'plugins/functional/cluster-a/example-plugin/plugin.bundle.json',
|
|
@@ -66,12 +70,12 @@ describe('KbPluginSource — bundles', () => {
|
|
|
66
70
|
await write('plugins/broken/plugin.bundle.json', '{ not json');
|
|
67
71
|
});
|
|
68
72
|
afterEach(async () => {
|
|
69
|
-
|
|
73
|
+
kbContext = testKbContext();
|
|
70
74
|
await fs.rm(kb, { recursive: true, force: true });
|
|
71
75
|
});
|
|
72
76
|
|
|
73
77
|
it('finds bundles at any depth and reads them as plugins that link skill roots', async () => {
|
|
74
|
-
const { plugins, warnings } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
78
|
+
const { plugins, warnings } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
75
79
|
const byName = new Map(plugins.map((p) => [p.name, p]));
|
|
76
80
|
expect([...byName.keys()].sort()).toEqual(['close', 'example-plugin', 'ledger', 'padded', 'unnamed']);
|
|
77
81
|
// The bundle dialect's own rule — a declared display name, else the
|
|
@@ -119,7 +123,7 @@ describe('KbPluginSource — bundles', () => {
|
|
|
119
123
|
});
|
|
120
124
|
|
|
121
125
|
it('expands mcpProfile through the registry, following extends and reporting unknowns', async () => {
|
|
122
|
-
const { plugins, warnings } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
126
|
+
const { plugins, warnings } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
123
127
|
const example = plugins.find((p) => p.name === 'example-plugin')!;
|
|
124
128
|
expect(example.mcpServers).toEqual({
|
|
125
129
|
confluence: { type: 'streamable-http', url: 'https://mcp.confluence.example' },
|
|
@@ -156,7 +160,7 @@ describe('KbPluginSource — bundles', () => {
|
|
|
156
160
|
],
|
|
157
161
|
}),
|
|
158
162
|
);
|
|
159
|
-
const { plugins, warnings } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
163
|
+
const { plugins, warnings } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
160
164
|
const example = plugins.find((p) => p.name === 'example-plugin')!;
|
|
161
165
|
expect(example.mcpServers).toEqual({
|
|
162
166
|
jira: { type: 'stdio', command: 'npx', args: ['-y', 'jira-mcp'] },
|
|
@@ -174,7 +178,7 @@ describe('KbPluginSource — bundles', () => {
|
|
|
174
178
|
|
|
175
179
|
it('cuts an extends cycle instead of hanging, and keeps what it collected', async () => {
|
|
176
180
|
await write('plugins/loop/plugin.bundle.json', JSON.stringify({ name: 'loop', mcpProfile: 'loop-a' }));
|
|
177
|
-
const { plugins, warnings } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
181
|
+
const { plugins, warnings } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
178
182
|
const loop = plugins.find((p) => p.name === 'loop')!;
|
|
179
183
|
expect(loop.mcpServers).toEqual({ 'flat-http': { type: 'streamable-http', url: 'https://flat.example' } });
|
|
180
184
|
expect(warnings.some((w) => w.includes('cycle'))).toBe(true);
|
|
@@ -182,7 +186,7 @@ describe('KbPluginSource — bundles', () => {
|
|
|
182
186
|
|
|
183
187
|
it('a missing registry leaves the plugins standing, servers-less, with a warning per profile', async () => {
|
|
184
188
|
await fs.rm(path.join(kb, 'configs'), { recursive: true });
|
|
185
|
-
const { plugins, warnings } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
189
|
+
const { plugins, warnings } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
186
190
|
expect(plugins.find((p) => p.name === 'example-plugin')!.mcpServers).toBeNull();
|
|
187
191
|
expect(warnings.some((w) => w.includes('no registry'))).toBe(true);
|
|
188
192
|
});
|
|
@@ -200,7 +204,7 @@ describe('KbPluginSource — one walk, both shapes', () => {
|
|
|
200
204
|
kb = await fs.mkdtemp(path.join(os.tmpdir(), 'bevel-mixed-'));
|
|
201
205
|
});
|
|
202
206
|
afterEach(async () => {
|
|
203
|
-
|
|
207
|
+
kbContext = testKbContext();
|
|
204
208
|
await fs.rm(kb, { recursive: true, force: true });
|
|
205
209
|
});
|
|
206
210
|
|
|
@@ -226,7 +230,7 @@ describe('KbPluginSource — one walk, both shapes', () => {
|
|
|
226
230
|
// beneath: a container, not a plugin.
|
|
227
231
|
await write('Plugins/functional/access.md', '---\n---\nread:\n - everyone\n');
|
|
228
232
|
|
|
229
|
-
const { plugins, warnings } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
233
|
+
const { plugins, warnings } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
230
234
|
// Folders are visited in locale order (case-insensitive), depth first.
|
|
231
235
|
// Position means nothing: only the two files make a plugin.
|
|
232
236
|
expect(plugins.map((p) => [p.name, p.folder, p.linksAreManaged, p.exists])).toEqual([
|
|
@@ -245,7 +249,7 @@ describe('KbPluginSource — one walk, both shapes', () => {
|
|
|
245
249
|
await write('Plugins/b/GTM/plugin.json', '{}');
|
|
246
250
|
// Different spelling, same manifest slug: still one plugin.
|
|
247
251
|
await write('Plugins/c/gtm/plugin.json', '{}');
|
|
248
|
-
const { plugins, warnings } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
252
|
+
const { plugins, warnings } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
249
253
|
expect(plugins.map((p) => p.folder)).toEqual(['Plugins/a/GTM']);
|
|
250
254
|
expect(warnings).toEqual([
|
|
251
255
|
'Plugins/b/GTM: plugin name "gtm" is already used by Plugins/a/GTM — plugin skipped',
|
|
@@ -261,7 +265,7 @@ describe('KbPluginSource — one walk, both shapes', () => {
|
|
|
261
265
|
await write('Plugins/Nested/plugin.json', `{"name":${'['.repeat(20000)}${']'.repeat(20000)}}`);
|
|
262
266
|
await write('Plugins/Ops/plugin.json', JSON.stringify({ name: 'Not An Identifier' }));
|
|
263
267
|
await write('Plugins/Plain/plugin.json', '{}');
|
|
264
|
-
const { plugins, warnings } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
268
|
+
const { plugins, warnings } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
265
269
|
expect(plugins.map((p) => [p.name, p.displayName, p.folder])).toEqual([
|
|
266
270
|
// Both fields present: both are read, and `Plugins/GTM` says nothing.
|
|
267
271
|
['go-to-market', 'Go To Market', 'Plugins/GTM'],
|
|
@@ -303,7 +307,7 @@ describe('KbPluginSource — one walk, both shapes', () => {
|
|
|
303
307
|
: (realReadFile as (f: string, o: unknown) => Promise<unknown>).call(fs, file, opts)) as never),
|
|
304
308
|
];
|
|
305
309
|
try {
|
|
306
|
-
const { plugins, warnings, unreadable } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
310
|
+
const { plugins, warnings, unreadable } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
307
311
|
// The container could not be listed: nothing beneath it was seen. The
|
|
308
312
|
// manifest could not be read: an identity nobody could see, so the
|
|
309
313
|
// plugin is not listed under a guessed one. Both are holes, not absence.
|
|
@@ -331,7 +335,7 @@ describe('KbPluginSource — one walk, both shapes', () => {
|
|
|
331
335
|
? Promise.reject(Object.assign(new Error('EACCES: permission denied'), { code: 'EACCES' }))
|
|
332
336
|
: (realReadFile as (f: string, o: unknown) => Promise<unknown>).call(fs, file, opts)) as never);
|
|
333
337
|
try {
|
|
334
|
-
const { plugins, unreadable } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
338
|
+
const { plugins, unreadable } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
335
339
|
expect(unreadable).toEqual(['Plugins/Hidden/plugin.json']);
|
|
336
340
|
expect(plugins.map((p) => p.name)).toEqual(['gtm']);
|
|
337
341
|
} finally {
|
|
@@ -348,7 +352,7 @@ describe('KbPluginSource — one walk, both shapes', () => {
|
|
|
348
352
|
? Promise.reject(Object.assign(new Error('ENOENT: no such file'), { code: 'ENOENT' }))
|
|
349
353
|
: (realReadFile as (f: string, o: unknown) => Promise<unknown>).call(fs, file, opts)) as never);
|
|
350
354
|
try {
|
|
351
|
-
const { plugins, unreadable } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
355
|
+
const { plugins, unreadable } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
352
356
|
expect(plugins.map((p) => p.name)).toEqual(['gtm']);
|
|
353
357
|
expect(unreadable).toEqual([]);
|
|
354
358
|
} finally {
|
|
@@ -357,7 +361,7 @@ describe('KbPluginSource — one walk, both shapes', () => {
|
|
|
357
361
|
});
|
|
358
362
|
|
|
359
363
|
it('a knowledge base without a plugins root has no plugins and no complaint', async () => {
|
|
360
|
-
const { plugins, warnings, unreadable } = await new KbPluginSource(new NodeFs()).discover(kb);
|
|
364
|
+
const { plugins, warnings, unreadable } = await new KbPluginSource(new NodeFs(), kbContext).discover(kb);
|
|
361
365
|
expect(plugins).toEqual([]);
|
|
362
366
|
expect(warnings).toEqual([]);
|
|
363
367
|
expect(unreadable).toEqual([]);
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
isPersonalPluginDir,
|
|
5
|
+
normalizeSkillRoot,
|
|
6
|
+
pluginManifestName,
|
|
7
|
+
type KbLayout,
|
|
8
|
+
} from '@bevel-software/platform-shared';
|
|
4
9
|
import { isAbsence } from '../../../../shared/fs.contract.js';
|
|
5
10
|
import type { DiscoveredPlugin } from '../plugin-source.js';
|
|
6
11
|
import { expandProfile, parseRegistry, type McpRegistry } from './registry.js';
|
|
@@ -67,6 +72,8 @@ export async function readBundlePlugin(
|
|
|
67
72
|
registry: McpRegistry | null,
|
|
68
73
|
warnings: string[],
|
|
69
74
|
unreadable: string[],
|
|
75
|
+
/** Names the plugins root a personal folder sits directly under. */
|
|
76
|
+
layout: KbLayout,
|
|
70
77
|
): Promise<DiscoveredPlugin | null> {
|
|
71
78
|
// Reading and parsing are two failures with two meanings: a file that
|
|
72
79
|
// cannot be read is a plugin nobody could see (counted, so a writer can
|
|
@@ -149,7 +156,7 @@ export async function readBundlePlugin(
|
|
|
149
156
|
relFolder,
|
|
150
157
|
// The same rule as the native reader: a reserved personal folder directly
|
|
151
158
|
// under the root is a place, not a plugin, whatever file it carries.
|
|
152
|
-
personal: isPersonalPluginDir(folder),
|
|
159
|
+
personal: isPersonalPluginDir(folder, layout),
|
|
153
160
|
exists: true,
|
|
154
161
|
manifest,
|
|
155
162
|
manifestText: null,
|