@bevel-software/platform-core-backend 0.25.2 → 0.27.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/agent-guide/access-control.md +251 -0
- package/agent-guide/conventions.md +35 -0
- package/agent-guide/directory-structure.md +145 -0
- package/agent-guide/finding-things.md +7 -0
- package/agent-guide/html-views.md +83 -0
- package/agent-guide/introduction.md +27 -0
- package/agent-guide/new-knowledge-base.md +24 -0
- package/agent-guide/skills.md +47 -0
- package/agent-guide/tool-manuals.md +227 -0
- package/agent-guide/where-a-new-file-goes.md +36 -0
- package/dist/assets.d.ts +26 -0
- package/dist/assets.d.ts.map +1 -1
- package/dist/assets.js +35 -2
- package/dist/assets.js.map +1 -1
- package/dist/core/catalog-revision.d.ts +19 -1
- package/dist/core/catalog-revision.d.ts.map +1 -1
- package/dist/core/catalog-revision.js +14 -3
- package/dist/core/catalog-revision.js.map +1 -1
- package/dist/core/core-ports.d.ts +11 -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 +5 -0
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +65 -3
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +35 -0
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +114 -12
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core/lifecycle.d.ts +16 -1
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/core/lifecycle.js +18 -1
- package/dist/core/lifecycle.js.map +1 -1
- package/dist/core-config.d.ts +21 -0
- package/dist/core-config.d.ts.map +1 -1
- package/dist/core-config.js +22 -1
- package/dist/core-config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +17 -0
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +2 -0
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +27 -0
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/directory-sync-bot.js +1 -1
- package/dist/modules/access/directory-sync-bot.js.map +1 -1
- package/dist/modules/agent-guide/agent-guide.d.ts +145 -0
- package/dist/modules/agent-guide/agent-guide.d.ts.map +1 -0
- package/dist/modules/agent-guide/agent-guide.js +199 -0
- package/dist/modules/agent-guide/agent-guide.js.map +1 -0
- package/dist/modules/agent-guide/agent-guide.tools.d.ts +24 -0
- package/dist/modules/agent-guide/agent-guide.tools.d.ts.map +1 -0
- package/dist/modules/agent-guide/agent-guide.tools.js +100 -0
- package/dist/modules/agent-guide/agent-guide.tools.js.map +1 -0
- package/dist/modules/agent-guide/index.d.ts +4 -0
- package/dist/modules/agent-guide/index.d.ts.map +1 -0
- package/dist/modules/agent-guide/index.js +4 -0
- package/dist/modules/agent-guide/index.js.map +1 -0
- package/dist/modules/agent-instructions/agent-instructions.routes.d.ts +3 -2
- package/dist/modules/agent-instructions/agent-instructions.routes.d.ts.map +1 -1
- package/dist/modules/agent-instructions/agent-instructions.routes.js +3 -2
- package/dist/modules/agent-instructions/agent-instructions.routes.js.map +1 -1
- package/dist/modules/agent-instructions/compose.d.ts +14 -6
- package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
- package/dist/modules/agent-instructions/compose.js +28 -8
- package/dist/modules/agent-instructions/compose.js.map +1 -1
- package/dist/modules/agent-instructions/index.d.ts +1 -1
- package/dist/modules/agent-instructions/index.d.ts.map +1 -1
- package/dist/modules/agent-instructions/index.js +1 -1
- package/dist/modules/agent-instructions/index.js.map +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.d.ts +10 -50
- package/dist/modules/agent-instructions/shared-file-rules.d.ts.map +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.js +51 -104
- package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
- package/dist/modules/audit/agent-audit.service.d.ts +21 -2
- package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
- package/dist/modules/audit/agent-audit.service.js +43 -2
- package/dist/modules/audit/agent-audit.service.js.map +1 -1
- package/dist/modules/audit/agent-connection.routes.d.ts +34 -0
- package/dist/modules/audit/agent-connection.routes.d.ts.map +1 -0
- package/dist/modules/audit/agent-connection.routes.js +38 -0
- package/dist/modules/audit/agent-connection.routes.js.map +1 -0
- package/dist/modules/audit/audit.contract.d.ts +24 -0
- package/dist/modules/audit/audit.contract.d.ts.map +1 -1
- package/dist/modules/audit/audit.contract.js.map +1 -1
- package/dist/modules/audit/index.d.ts +1 -0
- package/dist/modules/audit/index.d.ts.map +1 -1
- package/dist/modules/audit/index.js +1 -0
- package/dist/modules/audit/index.js.map +1 -1
- package/dist/modules/auth/account.routes.d.ts.map +1 -1
- package/dist/modules/auth/account.routes.js +10 -3
- package/dist/modules/auth/account.routes.js.map +1 -1
- package/dist/modules/auth/auth.middleware.d.ts +7 -0
- package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
- package/dist/modules/auth/auth.middleware.js +1 -1
- package/dist/modules/auth/auth.middleware.js.map +1 -1
- package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -1
- package/dist/modules/code-mode/code-mode.tool.js +11 -3
- package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
- package/dist/modules/database/core-schema.d.ts +96 -0
- package/dist/modules/database/core-schema.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +32 -3
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/embed/account-link.service.d.ts +42 -0
- package/dist/modules/embed/account-link.service.d.ts.map +1 -0
- package/dist/modules/embed/account-link.service.js +50 -0
- package/dist/modules/embed/account-link.service.js.map +1 -0
- package/dist/modules/embed/embed-link.d.ts +58 -0
- package/dist/modules/embed/embed-link.d.ts.map +1 -0
- package/dist/modules/embed/embed-link.js +160 -0
- package/dist/modules/embed/embed-link.js.map +1 -0
- package/dist/modules/embed/embed.errors.d.ts +30 -0
- package/dist/modules/embed/embed.errors.d.ts.map +1 -0
- package/dist/modules/embed/embed.errors.js +42 -0
- package/dist/modules/embed/embed.errors.js.map +1 -0
- package/dist/modules/embed/embed.interface.d.ts +204 -0
- package/dist/modules/embed/embed.interface.d.ts.map +1 -0
- package/dist/modules/embed/embed.interface.js +2 -0
- package/dist/modules/embed/embed.interface.js.map +1 -0
- package/dist/modules/embed/embed.routes.d.ts +59 -0
- package/dist/modules/embed/embed.routes.d.ts.map +1 -0
- package/dist/modules/embed/embed.routes.js +343 -0
- package/dist/modules/embed/embed.routes.js.map +1 -0
- package/dist/modules/embed/embed.service.d.ts +169 -0
- package/dist/modules/embed/embed.service.d.ts.map +1 -0
- package/dist/modules/embed/embed.service.js +627 -0
- package/dist/modules/embed/embed.service.js.map +1 -0
- package/dist/modules/embed/embed.tools.d.ts +51 -0
- package/dist/modules/embed/embed.tools.d.ts.map +1 -0
- package/dist/modules/embed/embed.tools.js +170 -0
- package/dist/modules/embed/embed.tools.js.map +1 -0
- package/dist/modules/embed/mcp-app.d.ts +64 -0
- package/dist/modules/embed/mcp-app.d.ts.map +1 -0
- package/dist/modules/embed/mcp-app.js +147 -0
- package/dist/modules/embed/mcp-app.js.map +1 -0
- package/dist/modules/embed/mcp-app.routes.d.ts +21 -0
- package/dist/modules/embed/mcp-app.routes.d.ts.map +1 -0
- package/dist/modules/embed/mcp-app.routes.js +36 -0
- package/dist/modules/embed/mcp-app.routes.js.map +1 -0
- package/dist/modules/github-app/github-app.connection.d.ts +15 -0
- package/dist/modules/github-app/github-app.connection.d.ts.map +1 -1
- package/dist/modules/github-app/github-app.connection.js +34 -3
- package/dist/modules/github-app/github-app.connection.js.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.d.ts +65 -0
- package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.js +300 -0
- package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
- package/dist/modules/kb-sync/kb-sync.interface.d.ts +5 -0
- package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.service.js +6 -0
- package/dist/modules/kb-sync/kb-sync.service.js.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.js +2 -1
- package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
- package/dist/modules/mcp/mcp.service.d.ts +57 -3
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.service.js +177 -24
- package/dist/modules/mcp/mcp.service.js.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +24 -0
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js +32 -4
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
- package/dist/modules/mcp/tool-schema-guard.d.ts +105 -0
- package/dist/modules/mcp/tool-schema-guard.d.ts.map +1 -0
- package/dist/modules/mcp/tool-schema-guard.js +171 -0
- package/dist/modules/mcp/tool-schema-guard.js.map +1 -0
- package/dist/modules/onboarding/onboarding.contract.d.ts +80 -0
- package/dist/modules/onboarding/onboarding.contract.d.ts.map +1 -0
- package/dist/modules/onboarding/onboarding.contract.js +7 -0
- package/dist/modules/onboarding/onboarding.contract.js.map +1 -0
- package/dist/modules/onboarding/onboarding.routes.d.ts +18 -0
- package/dist/modules/onboarding/onboarding.routes.d.ts.map +1 -0
- package/dist/modules/onboarding/onboarding.routes.js +81 -0
- package/dist/modules/onboarding/onboarding.routes.js.map +1 -0
- package/dist/modules/onboarding/starter-pack.service.d.ts +213 -0
- package/dist/modules/onboarding/starter-pack.service.d.ts.map +1 -0
- package/dist/modules/onboarding/starter-pack.service.js +492 -0
- package/dist/modules/onboarding/starter-pack.service.js.map +1 -0
- package/dist/modules/onboarding/starter-packs.d.ts +78 -0
- package/dist/modules/onboarding/starter-packs.d.ts.map +1 -0
- package/dist/modules/onboarding/starter-packs.js +156 -0
- package/dist/modules/onboarding/starter-packs.js.map +1 -0
- 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/plugin-provision.service.d.ts +19 -0
- package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-provision.service.js +18 -1
- package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
- package/dist/modules/plugins/plugins.routes.d.ts +0 -36
- package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.js +31 -0
- package/dist/modules/plugins/plugins.routes.js.map +1 -1
- package/dist/modules/plugins/plugins.tools.d.ts +36 -2
- package/dist/modules/plugins/plugins.tools.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.tools.js +71 -14
- package/dist/modules/plugins/plugins.tools.js.map +1 -1
- package/dist/modules/settings/deployment-settings.service.d.ts +34 -7
- package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
- package/dist/modules/settings/deployment-settings.service.js +148 -54
- package/dist/modules/settings/deployment-settings.service.js.map +1 -1
- package/dist/modules/settings/repository-source.d.ts +1 -0
- package/dist/modules/settings/repository-source.d.ts.map +1 -1
- package/dist/modules/settings/repository-source.js +3 -3
- package/dist/modules/settings/repository-source.js.map +1 -1
- package/dist/modules/settings/setup.routes.d.ts.map +1 -1
- package/dist/modules/settings/setup.routes.js +3 -6
- package/dist/modules/settings/setup.routes.js.map +1 -1
- package/dist/modules/skills/skills.tools.d.ts.map +1 -1
- package/dist/modules/skills/skills.tools.js +103 -43
- package/dist/modules/skills/skills.tools.js.map +1 -1
- package/dist/modules/tool-auth/connection-key-rejection.d.ts +10 -1
- package/dist/modules/tool-auth/connection-key-rejection.d.ts.map +1 -1
- package/dist/modules/tool-auth/connection-key-rejection.js +11 -3
- package/dist/modules/tool-auth/connection-key-rejection.js.map +1 -1
- package/dist/modules/tool-auth/external-api-key.interface.d.ts +8 -0
- package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.d.ts +24 -2
- package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.js +59 -2
- package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.js +9 -4
- package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
- package/dist/modules/tool-helpers/index.d.ts +28 -1
- package/dist/modules/tool-helpers/index.d.ts.map +1 -1
- package/dist/modules/tool-helpers/index.js +28 -1
- package/dist/modules/tool-helpers/index.js.map +1 -1
- package/dist/modules/tool-helpers/route-argument-check.d.ts +10 -0
- package/dist/modules/tool-helpers/route-argument-check.d.ts.map +1 -0
- package/dist/modules/tool-helpers/route-argument-check.js +132 -0
- package/dist/modules/tool-helpers/route-argument-check.js.map +1 -0
- package/dist/modules/tool-helpers/route-tool-schemas.d.ts +89 -0
- package/dist/modules/tool-helpers/route-tool-schemas.d.ts.map +1 -0
- package/dist/modules/tool-helpers/route-tool-schemas.js +113 -0
- package/dist/modules/tool-helpers/route-tool-schemas.js.map +1 -0
- package/dist/modules/tool-helpers/tool-def.d.ts +71 -0
- package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-def.js +70 -6
- package/dist/modules/tool-helpers/tool-def.js.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.d.ts +46 -6
- package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.js +157 -8
- package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.d.ts +9 -0
- package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +23 -4
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.contract.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts +4 -0
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.js +14 -0
- package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +7 -0
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.js +77 -38
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
- package/dist/modules/tool-registry/description-length.d.ts +20 -16
- package/dist/modules/tool-registry/description-length.d.ts.map +1 -1
- package/dist/modules/tool-registry/description-length.js +50 -30
- package/dist/modules/tool-registry/description-length.js.map +1 -1
- package/dist/modules/tool-registry/guide-first.d.ts +27 -0
- package/dist/modules/tool-registry/guide-first.d.ts.map +1 -0
- package/dist/modules/tool-registry/guide-first.js +40 -0
- package/dist/modules/tool-registry/guide-first.js.map +1 -0
- package/dist/modules/tool-registry/tool-registry.d.ts +6 -0
- package/dist/modules/tool-registry/tool-registry.d.ts.map +1 -1
- package/dist/modules/tool-registry/tool-registry.js +9 -2
- package/dist/modules/tool-registry/tool-registry.js.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts +449 -0
- package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts.map +1 -0
- package/dist/modules/workflow/agent-tools/change-request-read-shape.js +481 -0
- package/dist/modules/workflow/agent-tools/change-request-read-shape.js.map +1 -0
- package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts +126 -0
- package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts.map +1 -0
- package/dist/modules/workflow/agent-tools/change-request-read.tools.js +611 -0
- package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +1 -0
- package/dist/modules/workflow/agent-tools/change-request-summary.d.ts +12 -1
- package/dist/modules/workflow/agent-tools/change-request-summary.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-summary.js +5 -1
- package/dist/modules/workflow/agent-tools/change-request-summary.js.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +8 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js +133 -37
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
- package/dist/modules/workflow/file-lock.service.d.ts +29 -5
- package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
- package/dist/modules/workflow/file-lock.service.js +62 -5
- package/dist/modules/workflow/file-lock.service.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +282 -14
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +627 -126
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/git/merge-commit.d.ts +73 -0
- package/dist/modules/workflow/git/merge-commit.d.ts.map +1 -0
- package/dist/modules/workflow/git/merge-commit.js +89 -0
- package/dist/modules/workflow/git/merge-commit.js.map +1 -0
- package/dist/modules/workflow/git/node-git-runner.d.ts +15 -0
- package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
- package/dist/modules/workflow/git/node-git-runner.js +78 -6
- package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.d.ts +94 -1
- package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.js +332 -37
- package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
- package/dist/modules/workflow/pending-commits.service.d.ts +15 -0
- package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
- package/dist/modules/workflow/pending-commits.service.js +25 -1
- package/dist/modules/workflow/pending-commits.service.js.map +1 -1
- package/dist/modules/workflow/pending-commits.worker.d.ts +6 -1
- package/dist/modules/workflow/pending-commits.worker.d.ts.map +1 -1
- package/dist/modules/workflow/pending-commits.worker.js +23 -6
- package/dist/modules/workflow/pending-commits.worker.js.map +1 -1
- package/dist/modules/workflow/recovery-bot.js +1 -1
- package/dist/modules/workflow/recovery-bot.js.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts +35 -0
- package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.js +180 -13
- package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
- package/dist/modules/workflow/sanitize-error.d.ts +16 -0
- package/dist/modules/workflow/sanitize-error.d.ts.map +1 -1
- package/dist/modules/workflow/sanitize-error.js +45 -0
- package/dist/modules/workflow/sanitize-error.js.map +1 -1
- package/dist/modules/workflow/workflow.routes.d.ts +6 -2
- package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.routes.js +7 -2
- package/dist/modules/workflow/workflow.routes.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +187 -15
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +808 -106
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/agent-download.builder.d.ts +105 -0
- package/dist/modules/workspace/agent-download.builder.d.ts.map +1 -0
- package/dist/modules/workspace/agent-download.builder.js +238 -0
- package/dist/modules/workspace/agent-download.builder.js.map +1 -0
- package/dist/modules/workspace/agent-download.routes.d.ts +77 -0
- package/dist/modules/workspace/agent-download.routes.d.ts.map +1 -0
- package/dist/modules/workspace/agent-download.routes.js +156 -0
- package/dist/modules/workspace/agent-download.routes.js.map +1 -0
- package/dist/modules/workspace/agent-download.store.d.ts +225 -0
- package/dist/modules/workspace/agent-download.store.d.ts.map +1 -0
- package/dist/modules/workspace/agent-download.store.js +423 -0
- package/dist/modules/workspace/agent-download.store.js.map +1 -0
- package/dist/modules/workspace/agent-upload.store.d.ts +10 -1
- package/dist/modules/workspace/agent-upload.store.d.ts.map +1 -1
- package/dist/modules/workspace/agent-upload.store.js +16 -6
- package/dist/modules/workspace/agent-upload.store.js.map +1 -1
- package/dist/modules/workspace/file-readers/raw-mime.d.ts +6 -0
- package/dist/modules/workspace/file-readers/raw-mime.d.ts.map +1 -0
- package/dist/modules/workspace/file-readers/raw-mime.js +38 -0
- package/dist/modules/workspace/file-readers/raw-mime.js.map +1 -0
- package/dist/modules/workspace/file-readers/text-reader.d.ts +5 -5
- package/dist/modules/workspace/file-readers/text-reader.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/text-reader.js +5 -8
- package/dist/modules/workspace/file-readers/text-reader.js.map +1 -1
- package/dist/modules/workspace/first-run.d.ts +111 -0
- package/dist/modules/workspace/first-run.d.ts.map +1 -0
- package/dist/modules/workspace/first-run.js +181 -0
- package/dist/modules/workspace/first-run.js.map +1 -0
- package/dist/modules/workspace/move-links.d.ts +92 -0
- package/dist/modules/workspace/move-links.d.ts.map +1 -0
- package/dist/modules/workspace/move-links.js +173 -0
- package/dist/modules/workspace/move-links.js.map +1 -0
- package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.js +24 -39
- package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts +58 -52
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/template-files.step.js +209 -223
- package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/template-source.d.ts +5 -3
- package/dist/modules/workspace/startup/steps/template-source.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/template-source.js +5 -3
- package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +63 -22
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +75 -2
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +197 -24
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.d.ts +68 -1
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +642 -71
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/modules/write-access/write-access.d.ts.map +1 -1
- package/dist/modules/write-access/write-access.js +9 -0
- package/dist/modules/write-access/write-access.js.map +1 -1
- package/dist/shared/domain-errors.d.ts +84 -1
- package/dist/shared/domain-errors.d.ts.map +1 -1
- package/dist/shared/domain-errors.js +100 -12
- package/dist/shared/domain-errors.js.map +1 -1
- package/dist/shared/git.contract.d.ts +10 -1
- package/dist/shared/git.contract.d.ts.map +1 -1
- package/dist/shared/git.contract.js.map +1 -1
- package/dist/shared/hidden-tools.d.ts +44 -0
- package/dist/shared/hidden-tools.d.ts.map +1 -0
- package/dist/shared/hidden-tools.js +13 -0
- package/dist/shared/hidden-tools.js.map +1 -0
- package/dist/shared/utf8-text.d.ts +15 -0
- package/dist/shared/utf8-text.d.ts.map +1 -0
- package/dist/shared/utf8-text.js +20 -0
- package/dist/shared/utf8-text.js.map +1 -0
- package/dist/tenancy/static-tenant-source.d.ts +2 -1
- package/dist/tenancy/static-tenant-source.d.ts.map +1 -1
- package/dist/tenancy/static-tenant-source.js +9 -2
- package/dist/tenancy/static-tenant-source.js.map +1 -1
- package/kb-template/.bevelignore +0 -5
- package/mcp-app/page.html +349 -0
- package/migrations/0017_atlassian_account_links.sql +37 -0
- package/migrations/meta/0017_snapshot.json +2396 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +6 -3
- package/src/__tests__/kb-layout-config.test.ts +10 -100
- package/src/__tests__/packaged-assets-ship.test.ts +66 -0
- package/src/assets.ts +38 -2
- package/src/core/__tests__/catalog-revision.test.ts +40 -0
- package/src/core/__tests__/gated-boot.test.ts +1 -0
- package/src/core/__tests__/lifecycle.test.ts +14 -0
- package/src/core/catalog-revision.ts +15 -2
- package/src/core/core-ports.ts +11 -0
- package/src/core/create-core-server.ts +78 -3
- package/src/core/create-core-services.ts +168 -10
- package/src/core/lifecycle.ts +28 -2
- package/src/core-config.ts +24 -1
- package/src/index.ts +2 -2
- package/src/modules/access/__tests__/access-control.atref-batch.test.ts +58 -0
- package/src/modules/access/__tests__/access-control.platform-restore.test.ts +8 -7
- package/src/modules/access/__tests__/access-control.service.test.ts +19 -0
- package/src/modules/access/__tests__/access-personal-plugin.test.ts +1 -18
- package/src/modules/access/access-control.interface.ts +28 -0
- package/src/modules/access/access-control.service.ts +37 -0
- package/src/modules/access/directory-sync-bot.ts +1 -1
- package/src/modules/agent-guide/__tests__/agent-guide.test.ts +386 -0
- package/src/modules/agent-guide/__tests__/agent-guide.tools.test.ts +207 -0
- package/src/modules/agent-guide/agent-guide.tools.ts +122 -0
- package/src/modules/agent-guide/agent-guide.ts +300 -0
- package/src/modules/agent-guide/index.ts +22 -0
- package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +39 -118
- package/src/modules/agent-instructions/agent-instructions.routes.ts +3 -2
- package/src/modules/agent-instructions/compose.ts +26 -8
- package/src/modules/agent-instructions/index.ts +0 -3
- package/src/modules/agent-instructions/shared-file-rules.ts +50 -112
- package/src/modules/audit/__tests__/agent-audit.service.test.ts +64 -4
- package/src/modules/audit/__tests__/agent-connection.routes.test.ts +102 -0
- package/src/modules/audit/agent-audit.service.ts +58 -3
- package/src/modules/audit/agent-connection.routes.ts +56 -0
- package/src/modules/audit/audit.contract.ts +26 -0
- package/src/modules/audit/index.ts +1 -0
- package/src/modules/auth/__tests__/account.routes.test.ts +5 -3
- package/src/modules/auth/account.routes.ts +10 -3
- package/src/modules/auth/auth.middleware.ts +1 -1
- package/src/modules/code-mode/__tests__/code-mode.tool.test.ts +18 -2
- package/src/modules/code-mode/code-mode.tool.ts +13 -2
- package/src/modules/database/core-schema.ts +33 -3
- package/src/modules/embed/__tests__/account-links.migration.test.ts +98 -0
- package/src/modules/embed/__tests__/embed-link.test.ts +122 -0
- package/src/modules/embed/__tests__/embed.routes.test.ts +362 -0
- package/src/modules/embed/__tests__/embed.service.lock.test.ts +193 -0
- package/src/modules/embed/__tests__/embed.service.test.ts +805 -0
- package/src/modules/embed/__tests__/embed.tools.test.ts +304 -0
- package/src/modules/embed/__tests__/mcp-app.test.ts +207 -0
- package/src/modules/embed/account-link.service.ts +76 -0
- package/src/modules/embed/embed-link.ts +180 -0
- package/src/modules/embed/embed.errors.ts +43 -0
- package/src/modules/embed/embed.interface.ts +203 -0
- package/src/modules/embed/embed.routes.ts +363 -0
- package/src/modules/embed/embed.service.ts +705 -0
- package/src/modules/embed/embed.tools.ts +206 -0
- package/src/modules/embed/mcp-app.routes.ts +41 -0
- package/src/modules/embed/mcp-app.ts +173 -0
- package/src/modules/github-app/__tests__/github-app.test.ts +76 -0
- package/src/modules/github-app/github-app.connection.ts +38 -4
- package/src/modules/kb-fs/__tests__/move-with-edits.test.ts +304 -0
- package/src/modules/kb-fs/locking-filesystem.ts +287 -0
- package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +35 -0
- package/src/modules/kb-sync/kb-sync.interface.ts +2 -0
- package/src/modules/kb-sync/kb-sync.service.ts +6 -0
- package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +68 -11
- package/src/modules/mcp/__tests__/fake-downstream-mcp-server.ts +14 -3
- package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +37 -2
- package/src/modules/mcp/__tests__/mcp.app.e2e.test.ts +200 -0
- package/src/modules/mcp/__tests__/mcp.e2e.test.ts +252 -0
- package/src/modules/mcp/__tests__/mcp.service.test.ts +42 -24
- package/src/modules/mcp/__tests__/tool-call-interface.e2e.test.ts +499 -0
- package/src/modules/mcp/__tests__/tool-schema-guard.test.ts +266 -0
- package/src/modules/mcp/mcp-auth.middleware.ts +2 -1
- package/src/modules/mcp/mcp.service.ts +218 -31
- package/src/modules/mcp/oauth/bevel-oauth-provider.ts +42 -4
- package/src/modules/mcp/tool-schema-guard.ts +196 -0
- package/src/modules/onboarding/__tests__/onboarding.routes.test.ts +163 -0
- package/src/modules/onboarding/__tests__/starter-pack.service.test.ts +635 -0
- package/src/modules/onboarding/__tests__/starter-packs.test.ts +169 -0
- package/src/modules/onboarding/onboarding.contract.ts +85 -0
- package/src/modules/onboarding/onboarding.routes.ts +85 -0
- package/src/modules/onboarding/starter-pack.service.ts +580 -0
- package/src/modules/onboarding/starter-packs.ts +182 -0
- package/src/modules/plugins/__tests__/plugins.tools.test.ts +177 -4
- package/src/modules/plugins/index.ts +1 -0
- package/src/modules/plugins/plugin-provision.service.ts +22 -1
- package/src/modules/plugins/plugins.routes.ts +29 -0
- package/src/modules/plugins/plugins.tools.ts +75 -15
- package/src/modules/settings/__tests__/deployment-settings.service.test.ts +176 -56
- package/src/modules/settings/__tests__/repository-source.test.ts +9 -0
- package/src/modules/settings/deployment-settings.service.ts +144 -55
- package/src/modules/settings/repository-source.ts +4 -4
- package/src/modules/settings/setup.routes.ts +3 -6
- package/src/modules/skills/__tests__/skills.tools.description.test.ts +95 -0
- package/src/modules/skills/skills.tools.ts +112 -46
- package/src/modules/tool-auth/__tests__/connection-key-rejection.test.ts +32 -0
- package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +65 -0
- package/src/modules/tool-auth/connection-key-rejection.ts +13 -3
- package/src/modules/tool-auth/external-api-key.interface.ts +9 -0
- package/src/modules/tool-auth/external-api-key.service.ts +61 -4
- package/src/modules/tool-auth/tool-auth.middleware.ts +13 -4
- package/src/modules/tool-helpers/__tests__/branch-declaration.test.ts +502 -0
- package/src/modules/tool-helpers/__tests__/route-argument-check.test.ts +337 -0
- package/src/modules/tool-helpers/index.ts +34 -1
- package/src/modules/tool-helpers/route-argument-check.ts +149 -0
- package/src/modules/tool-helpers/route-tool-schemas.ts +171 -0
- package/src/modules/tool-helpers/tool-def.ts +132 -7
- package/src/modules/tool-helpers/tool-handler.ts +196 -8
- package/src/modules/tool-helpers/tool.contract.ts +9 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.detail.route.test.ts +57 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +73 -4
- package/src/modules/tool-manuals/tool-manuals.contract.ts +24 -4
- package/src/modules/tool-manuals/tool-manuals.service.ts +17 -0
- package/src/modules/tool-manuals/tool-manuals.tools.ts +86 -38
- package/src/modules/tool-registry/__tests__/own-tool-schemas.test.ts +173 -0
- package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +81 -66
- package/src/modules/tool-registry/description-length.ts +57 -32
- package/src/modules/tool-registry/guide-first.ts +41 -0
- package/src/modules/tool-registry/tool-registry.ts +9 -2
- package/src/modules/workflow/__tests__/apply-failure.test.ts +6 -1
- package/src/modules/workflow/__tests__/file-lock.service.deletion-gate.test.ts +104 -0
- package/src/modules/workflow/__tests__/pending-commits.repository-replaced.test.ts +66 -0
- package/src/modules/workflow/__tests__/pending-commits.worker.test.ts +31 -2
- package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +110 -6
- package/src/modules/workflow/__tests__/sanitize-error.test.ts +89 -1
- package/src/modules/workflow/__tests__/workflow.routes.push-refused.test.ts +202 -0
- package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +6 -6
- package/src/modules/workflow/__tests__/workflow.service.delete-branch.test.ts +1026 -0
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +468 -10
- package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +4 -0
- package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +5 -4
- package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +54 -2
- package/src/modules/workflow/agent-tools/__tests__/change-request-read-shape.test.ts +705 -0
- package/src/modules/workflow/agent-tools/__tests__/change-request-read.tools.test.ts +1554 -0
- package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +150 -4
- package/src/modules/workflow/agent-tools/change-request-read-shape.ts +712 -0
- package/src/modules/workflow/agent-tools/change-request-read.tools.ts +759 -0
- package/src/modules/workflow/agent-tools/change-request-summary.ts +5 -1
- package/src/modules/workflow/agent-tools/workflow.tools.ts +137 -35
- package/src/modules/workflow/file-lock.service.ts +67 -5
- package/src/modules/workflow/git/__tests__/git.service.appliedChange.test.ts +285 -0
- package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +124 -0
- package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +164 -0
- package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +334 -0
- package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +48 -1
- package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +231 -2
- package/src/modules/workflow/git/__tests__/pull-request.service.list-fetch.test.ts +72 -2
- package/src/modules/workflow/git/__tests__/pull-request.service.placeholder.test.ts +24 -2
- package/src/modules/workflow/git/__tests__/pull-request.service.test.ts +620 -1
- package/src/modules/workflow/git/git.service.ts +714 -133
- package/src/modules/workflow/git/merge-commit.ts +88 -0
- package/src/modules/workflow/git/node-git-runner.ts +82 -7
- package/src/modules/workflow/git/pull-request.service.ts +380 -54
- package/src/modules/workflow/pending-commits.service.ts +29 -1
- package/src/modules/workflow/pending-commits.worker.ts +24 -6
- package/src/modules/workflow/recovery-bot.ts +1 -1
- package/src/modules/workflow/review-workflow/__tests__/approval-states.test.ts +7 -1
- package/src/modules/workflow/review-workflow/__tests__/merge-records-own-commit.test.ts +407 -0
- package/src/modules/workflow/review-workflow/review-workflow.service.ts +191 -12
- package/src/modules/workflow/sanitize-error.ts +50 -0
- package/src/modules/workflow/workflow.routes.ts +7 -2
- package/src/modules/workflow/workflow.service.ts +886 -112
- package/src/modules/workspace/__tests__/agent-downloads.test.ts +823 -0
- package/src/modules/workspace/__tests__/escape-sequences.routes.test.ts +4 -3
- package/src/modules/workspace/__tests__/first-run.test.ts +234 -0
- package/src/modules/workspace/__tests__/git-internals.security.test.ts +5 -2
- package/src/modules/workspace/__tests__/md-links.test.ts +353 -0
- package/src/modules/workspace/__tests__/move-links.test.ts +261 -0
- package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +219 -0
- package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -0
- package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +102 -0
- package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +52 -5
- package/src/modules/workspace/__tests__/workspace.routes.folder-zip-access.test.ts +190 -0
- package/src/modules/workspace/__tests__/workspace.routes.move-platform-files.test.ts +21 -10
- package/src/modules/workspace/__tests__/workspace.service.forget-clone-races.test.ts +8 -4
- package/src/modules/workspace/__tests__/workspace.service.test.ts +50 -8
- package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +33 -55
- package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +44 -1
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +664 -34
- package/src/modules/workspace/agent-download.builder.ts +308 -0
- package/src/modules/workspace/agent-download.routes.ts +183 -0
- package/src/modules/workspace/agent-download.store.ts +533 -0
- package/src/modules/workspace/agent-upload.store.ts +23 -7
- package/src/modules/workspace/file-readers/raw-mime.ts +40 -0
- package/src/modules/workspace/file-readers/text-reader.ts +5 -8
- package/src/modules/workspace/first-run.ts +222 -0
- package/src/modules/workspace/move-links.ts +237 -0
- package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +191 -489
- package/src/modules/workspace/startup/steps/seed-tree.ts +23 -38
- package/src/modules/workspace/startup/steps/template-files.step.ts +217 -249
- package/src/modules/workspace/startup/steps/template-source.ts +5 -3
- package/src/modules/workspace/workspace.routes.ts +64 -22
- package/src/modules/workspace/workspace.service.ts +202 -25
- package/src/modules/workspace/workspace.tools.ts +707 -68
- package/src/modules/write-access/__tests__/write-access.test.ts +13 -0
- package/src/modules/write-access/write-access.ts +9 -0
- package/src/shared/domain-errors.ts +123 -11
- package/src/shared/git.contract.ts +8 -1
- package/src/shared/hidden-tools.ts +45 -0
- package/src/shared/utf8-text.ts +21 -0
- package/src/tenancy/__tests__/static-tenant-source.test.ts +1 -0
- package/src/tenancy/static-tenant-source.ts +10 -2
- package/starter-packs/README.md +103 -0
- package/starter-packs/engineering/KnowledgeBase/About us.md +9 -0
- package/starter-packs/engineering/KnowledgeBase/Architecture.md +9 -0
- package/starter-packs/engineering/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/engineering/KnowledgeBase/How we ship.md +9 -0
- package/starter-packs/engineering/Plugins/engineering-starter/LICENSE +21 -0
- package/starter-packs/engineering/Plugins/engineering-starter/SOURCE.md +20 -0
- package/starter-packs/engineering/Plugins/engineering-starter/access.md +19 -0
- package/starter-packs/engineering/Plugins/engineering-starter/plugin.json +10 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/SKILL.md +171 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2a-startup-diagnostic.md +157 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2b-builder-brainstorm.md +39 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-ceo-review/SKILL.md +144 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-eng-review/SKILL.md +144 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/review/SKILL.md +80 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/review/checklist.md +184 -0
- package/starter-packs/engineering/pack.yaml +11 -0
- package/starter-packs/general/KnowledgeBase/About us.md +9 -0
- package/starter-packs/general/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/general/KnowledgeBase/How we work.md +9 -0
- package/starter-packs/general/Plugins/general-starter/LICENSE +202 -0
- package/starter-packs/general/Plugins/general-starter/SOURCE.md +10 -0
- package/starter-packs/general/Plugins/general-starter/access.md +19 -0
- package/starter-packs/general/Plugins/general-starter/plugin.json +10 -0
- package/starter-packs/general/Plugins/general-starter/skills/memory-management/SKILL.md +332 -0
- package/starter-packs/general/Plugins/general-starter/skills/productivity-start/SKILL.md +163 -0
- package/starter-packs/general/Plugins/general-starter/skills/productivity-update/SKILL.md +167 -0
- package/starter-packs/general/Plugins/general-starter/skills/task-management/SKILL.md +83 -0
- package/starter-packs/general/pack.yaml +10 -0
- package/starter-packs/operations/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/operations/KnowledgeBase/How we work.md +9 -0
- package/starter-packs/operations/KnowledgeBase/Processes.md +9 -0
- package/starter-packs/operations/KnowledgeBase/Tools we use.md +9 -0
- package/starter-packs/operations/KnowledgeBase/Vendors.md +9 -0
- package/starter-packs/operations/Plugins/operations-starter/LICENSE +202 -0
- package/starter-packs/operations/Plugins/operations-starter/SOURCE.md +10 -0
- package/starter-packs/operations/Plugins/operations-starter/access.md +19 -0
- package/starter-packs/operations/Plugins/operations-starter/plugin.json +10 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/capacity-plan/SKILL.md +111 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/change-request/SKILL.md +119 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/compliance-tracking/SKILL.md +44 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/process-doc/SKILL.md +80 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/process-optimization/SKILL.md +39 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/risk-assessment/SKILL.md +40 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/runbook/SKILL.md +85 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/status-report/SKILL.md +75 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/vendor-review/SKILL.md +102 -0
- package/starter-packs/operations/pack.yaml +12 -0
- package/starter-packs/sales/KnowledgeBase/About us.md +9 -0
- package/starter-packs/sales/KnowledgeBase/Customers.md +9 -0
- package/starter-packs/sales/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/sales/KnowledgeBase/How we sell.md +9 -0
- package/starter-packs/sales/KnowledgeBase/Objections.md +9 -0
- package/starter-packs/sales/KnowledgeBase/Pricing.md +9 -0
- package/starter-packs/sales/Plugins/sales-starter/LICENSE +202 -0
- package/starter-packs/sales/Plugins/sales-starter/SOURCE.md +10 -0
- package/starter-packs/sales/Plugins/sales-starter/access.md +19 -0
- package/starter-packs/sales/Plugins/sales-starter/plugin.json +10 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/account-context/SKILL.md +94 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/account-plan/SKILL.md +95 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/account-research/SKILL.md +99 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/account-tiering/SKILL.md +101 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/call-prep/SKILL.md +111 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/call-summary/SKILL.md +111 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/close-plan/SKILL.md +106 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/competitive-intelligence/SKILL.md +102 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/create-an-asset/SKILL.md +105 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/crm-hygiene-check/SKILL.md +103 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/customer-health/SKILL.md +108 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/customer-voice/SKILL.md +94 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/daily-briefing/SKILL.md +61 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/deal-advance-gap/SKILL.md +102 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/deal-review/SKILL.md +105 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/deal-signals/SKILL.md +96 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/deal-slip-scenario/SKILL.md +104 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/draft-outreach/SKILL.md +116 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/end-of-day/SKILL.md +114 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/expansion-whitespace/SKILL.md +97 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/forecast/SKILL.md +100 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/handle-objection/SKILL.md +93 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/inbox-sweep/SKILL.md +114 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/lead-triage/SKILL.md +106 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/log-activity/SKILL.md +111 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/pipeline-review/SKILL.md +97 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/renewal-radar/SKILL.md +95 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/rep-context/SKILL.md +90 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/route-lead/SKILL.md +111 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/sales-setup/SKILL.md +200 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/schedule-meeting/SKILL.md +99 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/stakeholder-map/SKILL.md +107 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/team-pipeline/SKILL.md +105 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/update-opportunity/SKILL.md +112 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/weekly-wrap/SKILL.md +90 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/win-loss-review/SKILL.md +88 -0
- package/starter-packs/sales/pack.yaml +13 -0
- package/starter-packs/support/KnowledgeBase/Escalations.md +9 -0
- package/starter-packs/support/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/support/KnowledgeBase/Known issues.md +9 -0
- package/starter-packs/support/KnowledgeBase/Products.md +9 -0
- package/starter-packs/support/KnowledgeBase/Tone of voice.md +9 -0
- package/starter-packs/support/Plugins/support-starter/LICENSE +202 -0
- package/starter-packs/support/Plugins/support-starter/SOURCE.md +10 -0
- package/starter-packs/support/Plugins/support-starter/access.md +19 -0
- package/starter-packs/support/Plugins/support-starter/plugin.json +10 -0
- package/starter-packs/support/Plugins/support-starter/skills/customer-escalation/SKILL.md +246 -0
- package/starter-packs/support/Plugins/support-starter/skills/customer-research/SKILL.md +250 -0
- package/starter-packs/support/Plugins/support-starter/skills/draft-response/SKILL.md +416 -0
- package/starter-packs/support/Plugins/support-starter/skills/kb-article/SKILL.md +350 -0
- package/starter-packs/support/Plugins/support-starter/skills/ticket-triage/SKILL.md +273 -0
- package/starter-packs/support/pack.yaml +12 -0
- package/kb-template/AGENTS.md +0 -730
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
2
|
import { randomBytes } from 'node:crypto';
|
|
3
|
+
import type { SQL } from 'drizzle-orm';
|
|
4
|
+
import { PgDialect } from 'drizzle-orm/pg-core';
|
|
3
5
|
import {
|
|
4
6
|
DeploymentSettingsService,
|
|
5
7
|
SettingsValidationError,
|
|
6
8
|
CORE_SETTINGS,
|
|
7
9
|
LEGACY_LAYOUT_ENV_VARS,
|
|
10
|
+
retireMergedBranchesOn,
|
|
8
11
|
} from '../deployment-settings.service.js';
|
|
9
12
|
import type { Database } from '../../database/connection.js';
|
|
10
13
|
|
|
@@ -28,13 +31,54 @@ function makeDb() {
|
|
|
28
31
|
else rows.push({ key: v.key, value: v.value, encrypted: v.encrypted });
|
|
29
32
|
return Promise.resolve();
|
|
30
33
|
},
|
|
34
|
+
onConflictDoNothing: () => ({
|
|
35
|
+
returning: () => {
|
|
36
|
+
if (rows.some((r) => r.key === v.key)) return Promise.resolve([]);
|
|
37
|
+
rows.push({ key: v.key, value: v.value, encrypted: v.encrypted });
|
|
38
|
+
return Promise.resolve([{ key: v.key }]);
|
|
39
|
+
},
|
|
40
|
+
}),
|
|
41
|
+
}),
|
|
42
|
+
}),
|
|
43
|
+
// `delete … where … returning` / `update … set … where … returning`: the
|
|
44
|
+
// conditional swap. The fake applies the one predicate the service sends,
|
|
45
|
+
// key AND value, by reading the bound parameters off the drizzle `where`.
|
|
46
|
+
delete: () => ({
|
|
47
|
+
where: (predicate: unknown) => {
|
|
48
|
+
const done = Promise.resolve();
|
|
49
|
+
return Object.assign(done, {
|
|
50
|
+
returning: () => {
|
|
51
|
+
const [key, value] = boundParams(predicate);
|
|
52
|
+
const at = rows.findIndex((r) => r.key === key && r.value === value);
|
|
53
|
+
if (at === -1) return Promise.resolve([]);
|
|
54
|
+
rows.splice(at, 1);
|
|
55
|
+
return Promise.resolve([{ key }]);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
update: () => ({
|
|
61
|
+
set: (v: { value: string }) => ({
|
|
62
|
+
where: (predicate: unknown) => ({
|
|
63
|
+
returning: () => {
|
|
64
|
+
const [key, value] = boundParams(predicate);
|
|
65
|
+
const row = rows.find((r) => r.key === key && r.value === value);
|
|
66
|
+
if (!row) return Promise.resolve([]);
|
|
67
|
+
row.value = v.value;
|
|
68
|
+
return Promise.resolve([{ key }]);
|
|
69
|
+
},
|
|
70
|
+
}),
|
|
31
71
|
}),
|
|
32
72
|
}),
|
|
33
|
-
delete: () => ({ where: () => Promise.resolve() }),
|
|
34
73
|
} as unknown as Database;
|
|
35
74
|
return { db, rows };
|
|
36
75
|
}
|
|
37
76
|
|
|
77
|
+
/** The parameters a drizzle predicate binds, in order — what the fake table matches on. */
|
|
78
|
+
function boundParams(predicate: unknown): unknown[] {
|
|
79
|
+
return new PgDialect().sqlToQuery(predicate as SQL).params;
|
|
80
|
+
}
|
|
81
|
+
|
|
38
82
|
let saved: NodeJS.ProcessEnv;
|
|
39
83
|
beforeEach(() => {
|
|
40
84
|
saved = { ...process.env };
|
|
@@ -119,6 +163,56 @@ describe('DeploymentSettingsService — a blank that means the default', () => {
|
|
|
119
163
|
});
|
|
120
164
|
});
|
|
121
165
|
|
|
166
|
+
describe('DeploymentSettingsService — the leftover-branch cleanup switch', () => {
|
|
167
|
+
/**
|
|
168
|
+
* On by default; an admin switches it off on the Deployment page, and the
|
|
169
|
+
* environment variable wins over the page, as for every setting.
|
|
170
|
+
*/
|
|
171
|
+
it('is on by default, off once saved as false, and on again when cleared — after a reload too', async () => {
|
|
172
|
+
const { db, rows } = makeDb();
|
|
173
|
+
// Clearing deletes the row: the fake does so for real, so a reload proves it.
|
|
174
|
+
(db as unknown as { delete: () => unknown }).delete = () => ({
|
|
175
|
+
where: () => {
|
|
176
|
+
const at = rows.findIndex((r) => r.key === 'retireMergedBranches');
|
|
177
|
+
if (at >= 0) rows.splice(at, 1);
|
|
178
|
+
return Promise.resolve();
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
182
|
+
const on = (s: DeploymentSettingsService) => retireMergedBranchesOn(s.resolve('retireMergedBranches'));
|
|
183
|
+
const reloaded = async () => {
|
|
184
|
+
const fresh = new DeploymentSettingsService(db, ENC_KEY);
|
|
185
|
+
await fresh.load();
|
|
186
|
+
return fresh;
|
|
187
|
+
};
|
|
188
|
+
expect(on(settings)).toBe(true);
|
|
189
|
+
await settings.save({ retireMergedBranches: 'false' }, null);
|
|
190
|
+
expect(on(settings)).toBe(false);
|
|
191
|
+
expect(on(await reloaded())).toBe(false);
|
|
192
|
+
await settings.save({ retireMergedBranches: '' }, null);
|
|
193
|
+
expect(on(settings)).toBe(true);
|
|
194
|
+
expect(rows.some((r) => r.key === 'retireMergedBranches')).toBe(false);
|
|
195
|
+
expect(on(await reloaded())).toBe(true);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('lets RETIRE_MERGED_BRANCHES win over the page', async () => {
|
|
199
|
+
const { db } = makeDb();
|
|
200
|
+
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
201
|
+
await settings.save({ retireMergedBranches: 'true' }, null);
|
|
202
|
+
process.env.RETIRE_MERGED_BRANCHES = 'false';
|
|
203
|
+
expect(settings.sourceOf('retireMergedBranches')).toBe('env');
|
|
204
|
+
expect(retireMergedBranchesOn(settings.resolve('retireMergedBranches'))).toBe(false);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('saves only true or false, and reads the ways a person writes "off" as off', async () => {
|
|
208
|
+
const { db } = makeDb();
|
|
209
|
+
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
210
|
+
await expect(settings.save({ retireMergedBranches: 'maybe' }, null)).rejects.toBeInstanceOf(SettingsValidationError);
|
|
211
|
+
for (const off of ['false', 'FALSE', '0', 'off', 'no']) expect(retireMergedBranchesOn(off), off).toBe(false);
|
|
212
|
+
for (const on of ['', 'true', '1', 'yes']) expect(retireMergedBranchesOn(on), on).toBe(true);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
122
216
|
describe('DeploymentSettingsService — secrets', () => {
|
|
123
217
|
it('stores the token as ciphertext and reads it back', async () => {
|
|
124
218
|
const { db, rows } = makeDb();
|
|
@@ -191,8 +285,6 @@ describe('DeploymentSettingsService — KB layout', () => {
|
|
|
191
285
|
pluginsDir: 'Plugins',
|
|
192
286
|
agentsFile: 'AGENTS.md',
|
|
193
287
|
});
|
|
194
|
-
// The pointer is on until someone says otherwise.
|
|
195
|
-
expect(settings.resolveAgentsFileLink()).toBe(true);
|
|
196
288
|
});
|
|
197
289
|
|
|
198
290
|
/**
|
|
@@ -225,9 +317,9 @@ describe('DeploymentSettingsService — KB layout', () => {
|
|
|
225
317
|
it('ignores the environment for the four layout names', async () => {
|
|
226
318
|
const { db } = makeDb();
|
|
227
319
|
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
228
|
-
await settings.save({ skillsDir: 'skills', pluginsDir: 'plugins'
|
|
320
|
+
await settings.save({ skillsDir: 'skills', pluginsDir: 'plugins' }, null);
|
|
229
321
|
process.env.KB_SKILLS_DIR = 'capabilities';
|
|
230
|
-
expect(settings.resolveKbLayout()).toMatchObject({ skillsDir: 'skills'
|
|
322
|
+
expect(settings.resolveKbLayout()).toMatchObject({ skillsDir: 'skills' });
|
|
231
323
|
expect(settings.sourceOf('skillsDir')).toBe('stored');
|
|
232
324
|
// Not locked: the field stays editable in the app, and a save of it is
|
|
233
325
|
// accepted rather than refused as 'set by the environment'.
|
|
@@ -284,68 +376,41 @@ describe('DeploymentSettingsService — KB layout', () => {
|
|
|
284
376
|
});
|
|
285
377
|
|
|
286
378
|
/**
|
|
287
|
-
* The guide's
|
|
288
|
-
* the
|
|
289
|
-
*
|
|
379
|
+
* The guide's name was a setting while the guide was written to disk. It is
|
|
380
|
+
* gone: the setup screen no longer offers it, a save naming it is refused
|
|
381
|
+
* as unknown, and the guide is read as `AGENTS.md` on every deployment
|
|
382
|
+
* whatever a deployment saved before.
|
|
290
383
|
*/
|
|
291
|
-
it('
|
|
292
|
-
const { db } = makeDb();
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
SettingsValidationError,
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
await expect(settings.save({ agentsFile: 'HEXIS.md' }, null)).resolves.toBeTruthy();
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
it('refuses a guide named after a root folder, from either side of the pair', async () => {
|
|
303
|
-
const { db } = makeDb();
|
|
304
|
-
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
305
|
-
// The plugins folder already in effect, named by the guide alone.
|
|
306
|
-
await settings.save({ pluginsDir: 'Guide.md' }, null);
|
|
307
|
-
await expect(settings.save({ agentsFile: 'guide.md' }, null)).rejects.toBeInstanceOf(
|
|
308
|
-
SettingsValidationError,
|
|
309
|
-
);
|
|
310
|
-
// And the other way round, in one batch.
|
|
311
|
-
await expect(
|
|
312
|
-
settings.save({ agentsFile: 'HEXIS.md', skillsDir: 'hexis.md' }, null),
|
|
313
|
-
).rejects.toBeInstanceOf(SettingsValidationError);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
it('marks the guide name and its pointer setting as restart-to-apply', async () => {
|
|
317
|
-
const { db } = makeDb();
|
|
384
|
+
it('knows no guide name any more: a save naming one is refused, and the layout always says AGENTS.md', async () => {
|
|
385
|
+
const { db, rows } = makeDb();
|
|
386
|
+
// The row a deployment saved while the setting existed is still in its
|
|
387
|
+
// database. It is loaded like any other row, and changes nothing.
|
|
388
|
+
rows.push({ key: 'agentsFile', value: 'HEXIS.md', encrypted: false });
|
|
318
389
|
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
319
|
-
|
|
320
|
-
expect(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
390
|
+
await settings.load();
|
|
391
|
+
expect(settings.resolveKbLayout().agentsFile).toBe('AGENTS.md');
|
|
392
|
+
await expect(settings.save({ agentsFile: 'HEXIS.md' }, null)).rejects.toMatchObject({
|
|
393
|
+
problems: { agentsFile: 'Unknown setting.' },
|
|
394
|
+
});
|
|
395
|
+
await expect(settings.save({ agentsFile: 'HEXIS.md' }, null, 'deployment')).rejects.toMatchObject({
|
|
396
|
+
problems: { agentsFile: 'Unknown setting.' },
|
|
397
|
+
});
|
|
398
|
+
expect(settings.resolveKbLayout().agentsFile).toBe('AGENTS.md');
|
|
399
|
+
expect(settings.describe().map((s) => s.key)).not.toContain('agentsFile');
|
|
324
400
|
});
|
|
325
401
|
|
|
326
402
|
/**
|
|
327
403
|
* A restart is owed for a CHANGE, and saving what a deployment is already
|
|
328
|
-
* running on is not one.
|
|
329
|
-
*
|
|
330
|
-
*
|
|
404
|
+
* running on is not one. A root name means something while unset — the
|
|
405
|
+
* default — so the first save of that same answer changes nothing the
|
|
406
|
+
* process would pick up at a restart.
|
|
331
407
|
*/
|
|
332
408
|
it('owes no restart for saving the value an unset setting already meant', async () => {
|
|
333
409
|
const { db } = makeDb();
|
|
334
410
|
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
335
|
-
// The checkbox arrives ticked, and ticked is what an unset one already is.
|
|
336
|
-
expect((await settings.save({ agentsFileLink: 'true' }, null)).restartKeys).not.toContain(
|
|
337
|
-
'agentsFileLink',
|
|
338
|
-
);
|
|
339
|
-
expect((await settings.save({ agentsFile: 'AGENTS.md' }, null)).restartKeys).not.toContain(
|
|
340
|
-
'agentsFile',
|
|
341
|
-
);
|
|
342
411
|
expect((await settings.save({ skillsDir: 'Skills' }, null)).restartKeys).not.toContain('skillsDir');
|
|
343
|
-
//
|
|
344
|
-
expect(settings.
|
|
345
|
-
// Turning it off from there IS a change, and still reports one.
|
|
346
|
-
expect((await settings.save({ agentsFileLink: 'false' }, null)).restartKeys).toContain(
|
|
347
|
-
'agentsFileLink',
|
|
348
|
-
);
|
|
412
|
+
// Renaming it from there IS a change, and still reports one.
|
|
413
|
+
expect((await settings.save({ skillsDir: 'Abilities' }, null)).restartKeys).toContain('skillsDir');
|
|
349
414
|
});
|
|
350
415
|
|
|
351
416
|
/**
|
|
@@ -557,3 +622,58 @@ describe('DeploymentSettingsService — an environment of its own', () => {
|
|
|
557
622
|
expect(shared.resolve('kbRepoUrl')).toBe('https://host.example/leaks-into-every-tenant.git');
|
|
558
623
|
});
|
|
559
624
|
});
|
|
625
|
+
|
|
626
|
+
describe('DeploymentSettingsService — recordIfAbsent', () => {
|
|
627
|
+
/**
|
|
628
|
+
* The claim a once-only flow rests on: the row is the lock, and the
|
|
629
|
+
* database — shared by every replica — lets exactly one insert through.
|
|
630
|
+
*/
|
|
631
|
+
it('claims a setting once, and tells the second caller it was not theirs', async () => {
|
|
632
|
+
const { db, rows } = makeDb();
|
|
633
|
+
const one = new DeploymentSettingsService(db, ENC_KEY);
|
|
634
|
+
const two = new DeploymentSettingsService(db, ENC_KEY);
|
|
635
|
+
await one.load();
|
|
636
|
+
await two.load();
|
|
637
|
+
|
|
638
|
+
expect(await one.recordIfAbsent('starterPack', 'sales', 'u-ada')).toBe(true);
|
|
639
|
+
expect(await two.recordIfAbsent('starterPack', 'none', 'u-bo')).toBe(false);
|
|
640
|
+
|
|
641
|
+
expect(rows.filter((r) => r.key === 'starterPack')).toEqual([{ key: 'starterPack', value: 'sales', encrypted: false }]);
|
|
642
|
+
expect(one.resolve('starterPack')).toBe('sales');
|
|
643
|
+
// The loser's cache was not touched: it reads the winner's row on its next `reload`.
|
|
644
|
+
expect(two.resolve('starterPack')).toBe('');
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
it('is no claim at all with a blank value, which would be a clear', async () => {
|
|
648
|
+
const { db, rows } = makeDb();
|
|
649
|
+
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
650
|
+
await settings.load();
|
|
651
|
+
expect(await settings.recordIfAbsent('starterPack', '', null)).toBe(false);
|
|
652
|
+
expect(rows).toEqual([]);
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* The conditional swap the claim flows rest on: a value is replaced, or
|
|
657
|
+
* removed, only while it still reads what the caller saw — so two
|
|
658
|
+
* replicas acting on one read cannot both succeed.
|
|
659
|
+
*/
|
|
660
|
+
it('swaps a value only while it still reads what was expected, and removes it the same way', async () => {
|
|
661
|
+
const { db, rows } = makeDb();
|
|
662
|
+
const settings = new DeploymentSettingsService(db, ENC_KEY);
|
|
663
|
+
await settings.load();
|
|
664
|
+
expect(await settings.recordIfAbsent('starterPackClaim', 'u-a 1', 'u-a')).toBe(true);
|
|
665
|
+
|
|
666
|
+
// The value moved under the second caller: refused, untouched.
|
|
667
|
+
expect(await settings.swapIfValue('starterPackClaim', 'u-z 0', 'u-b 2', 'u-b')).toBe(false);
|
|
668
|
+
expect(await settings.swapIfValue('starterPackClaim', 'u-a 1', 'u-b 2', 'u-b')).toBe(true);
|
|
669
|
+
expect(rows.find((r) => r.key === 'starterPackClaim')?.value).toBe('u-b 2');
|
|
670
|
+
expect(settings.resolve('starterPackClaim')).toBe('u-b 2');
|
|
671
|
+
|
|
672
|
+
// A release names its own claim: the holder's row stays for a stale one.
|
|
673
|
+
expect(await settings.swapIfValue('starterPackClaim', 'u-a 1', null, null)).toBe(false);
|
|
674
|
+
expect(rows.find((r) => r.key === 'starterPackClaim')?.value).toBe('u-b 2');
|
|
675
|
+
expect(await settings.swapIfValue('starterPackClaim', 'u-b 2', null, null)).toBe(true);
|
|
676
|
+
expect(rows.find((r) => r.key === 'starterPackClaim')).toBeUndefined();
|
|
677
|
+
expect(settings.resolve('starterPackClaim')).toBe('');
|
|
678
|
+
});
|
|
679
|
+
});
|
|
@@ -124,6 +124,15 @@ describe('RepositorySource: a repository reached through a GitHub App', () => {
|
|
|
124
124
|
expect(renewed).toBe(1);
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
+
it("hands the app the runner's word that the host refused the token", async () => {
|
|
128
|
+
const seen: unknown[] = [];
|
|
129
|
+
const githubApp = app({ prepare: async (opts) => void seen.push(opts) });
|
|
130
|
+
const { source: s } = source({ gitMode: 'github-app' }, { githubApp });
|
|
131
|
+
await s.credentials.prepare?.({ refused: true });
|
|
132
|
+
await s.credentials.prepare?.();
|
|
133
|
+
expect(seen).toEqual([{ refused: true }, undefined]);
|
|
134
|
+
});
|
|
135
|
+
|
|
127
136
|
it('is unanswered on a deployment that has no such app', () => {
|
|
128
137
|
const { source: s } = source({ gitMode: 'github-app' });
|
|
129
138
|
expect(s.answered()).toBe(false);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { eq, inArray } from 'drizzle-orm';
|
|
1
|
+
import { and, eq, inArray } from 'drizzle-orm';
|
|
2
2
|
import { logger } from '../../shared/logging.js';
|
|
3
3
|
|
|
4
4
|
const log = logger('settings');
|
|
@@ -7,7 +7,6 @@ import { deploymentSettings } from '../database/core-schema.js';
|
|
|
7
7
|
import {
|
|
8
8
|
DEFAULT_KB_LAYOUT,
|
|
9
9
|
type KbLayout,
|
|
10
|
-
validateAgentsFileName,
|
|
11
10
|
validateBranchModel,
|
|
12
11
|
validateKbLayout,
|
|
13
12
|
validateKbRootName,
|
|
@@ -110,6 +109,16 @@ export const validateHttpsRemote = (value: string): string | null => {
|
|
|
110
109
|
/**
|
|
111
110
|
* The core catalogue. Order is the order the setup screen renders them in.
|
|
112
111
|
*/
|
|
112
|
+
/**
|
|
113
|
+
* What the `retireMergedBranches` value in effect means: on, unless it says
|
|
114
|
+
* off. The page saves only `true` or `false`; the environment variable is
|
|
115
|
+
* typed by a person, so `0`, `off` and `no` (any case) mean off too, and
|
|
116
|
+
* anything else — unset included — leaves the cleanup on.
|
|
117
|
+
*/
|
|
118
|
+
export function retireMergedBranchesOn(raw: string): boolean {
|
|
119
|
+
return !/^(false|0|off|no)$/i.test(raw.trim());
|
|
120
|
+
}
|
|
121
|
+
|
|
113
122
|
export const CORE_SETTINGS: SettingDef[] = [
|
|
114
123
|
{
|
|
115
124
|
/**
|
|
@@ -228,14 +237,16 @@ export const CORE_SETTINGS: SettingDef[] = [
|
|
|
228
237
|
/**
|
|
229
238
|
* The KB layout: the three root folders a deployment may rename so hexis can
|
|
230
239
|
* read a repository laid out by someone else (`skills/` and `plugins/` in
|
|
231
|
-
* lowercase, say)
|
|
240
|
+
* lowercase, say). The agent guide's name is not among them any more: the
|
|
241
|
+
* guide is served by the platform as `AGENTS.md` everywhere, and a name a
|
|
242
|
+
* deployment saved for the written guide is ignored.
|
|
232
243
|
* Restart-to-apply like the branch model — the names are applied once at boot
|
|
233
244
|
* through `configureKbLayout` and served to the browser once by
|
|
234
245
|
* `/api/config`. Each has a default, so an unset field means the default, not
|
|
235
|
-
* an unconfigured deployment. Checked as a
|
|
246
|
+
* an unconfigured deployment. Checked as a TRIO in `save`: the three must
|
|
236
247
|
* differ, and one field alone cannot see the other three.
|
|
237
248
|
*
|
|
238
|
-
* NO `envVar`, on any of the
|
|
249
|
+
* NO `envVar`, on any of the three. Layout is deployment configuration that is
|
|
239
250
|
* entered once in the app; the three that used to be environment-driven are
|
|
240
251
|
* imported into their saved setting on the first boot after the upgrade
|
|
241
252
|
* ({@link DeploymentSettingsService.importLegacyLayoutEnv}) so nothing
|
|
@@ -262,37 +273,6 @@ export const CORE_SETTINGS: SettingDef[] = [
|
|
|
262
273
|
restartToApply: true,
|
|
263
274
|
unsetMeans: DEFAULT_KB_LAYOUT.pluginsDir,
|
|
264
275
|
},
|
|
265
|
-
{
|
|
266
|
-
/**
|
|
267
|
-
* The managed agent guide's file name. Its own validator says what a guide
|
|
268
|
-
* may be called; the quartet check in `plan` is what keeps it clear of the
|
|
269
|
-
* three folder names it is saved beside.
|
|
270
|
-
*/
|
|
271
|
-
key: 'agentsFile',
|
|
272
|
-
section: 'knowledge-base',
|
|
273
|
-
// Judged against the default roots here; the quartet check in `plan`
|
|
274
|
-
// judges it against the roots the same save puts in effect.
|
|
275
|
-
validate: (v) => validateAgentsFileName(v, DEFAULT_KB_LAYOUT),
|
|
276
|
-
restartToApply: true,
|
|
277
|
-
unsetMeans: DEFAULT_KB_LAYOUT.agentsFile,
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
/**
|
|
281
|
-
* Whether to keep the platform's one-sentence pointer in a customer's own
|
|
282
|
-
* `AGENTS.md` — the admin's consent to the only text the platform ever adds
|
|
283
|
-
* to a file it does not own. On unless it is explicitly turned off, because
|
|
284
|
-
* a renamed guide nothing points at is a guide no coding agent will find.
|
|
285
|
-
*
|
|
286
|
-
* Restart-to-apply like the name it belongs to: the check runs once per
|
|
287
|
-
* start, in the KB startup phase.
|
|
288
|
-
*/
|
|
289
|
-
key: 'agentsFileLink',
|
|
290
|
-
section: 'knowledge-base',
|
|
291
|
-
validate: (v) => (v === 'true' || v === 'false' ? null : 'Use "true" or "false".'),
|
|
292
|
-
restartToApply: true,
|
|
293
|
-
// On unless explicitly turned off — the reading `resolveAgentsFileLink` applies.
|
|
294
|
-
unsetMeans: 'true',
|
|
295
|
-
},
|
|
296
276
|
|
|
297
277
|
|
|
298
278
|
/**
|
|
@@ -319,6 +299,23 @@ export const CORE_SETTINGS: SettingDef[] = [
|
|
|
319
299
|
restartToApply: true,
|
|
320
300
|
},
|
|
321
301
|
|
|
302
|
+
{
|
|
303
|
+
/**
|
|
304
|
+
* Whether the server removes, on its own, the branches merged change
|
|
305
|
+
* requests left behind (`WorkflowService.retireLeftoverMergedBranches`).
|
|
306
|
+
* On unless set to `false`; a blanked field puts the default back. Read
|
|
307
|
+
* at every round, so it applies without a restart. It covers that cleanup
|
|
308
|
+
* only: the removal of a branch when its change request is merged does
|
|
309
|
+
* not ask it.
|
|
310
|
+
*/
|
|
311
|
+
key: 'retireMergedBranches',
|
|
312
|
+
envVar: 'RETIRE_MERGED_BRANCHES',
|
|
313
|
+
section: 'knowledge-base',
|
|
314
|
+
blankMeansDefault: true,
|
|
315
|
+
unsetMeans: 'true',
|
|
316
|
+
validate: (v) => (v === 'true' || v === 'false' ? null : 'Either true or false.'),
|
|
317
|
+
},
|
|
318
|
+
|
|
322
319
|
{
|
|
323
320
|
/**
|
|
324
321
|
* The credential a git host's webhook or a pipeline presents to
|
|
@@ -402,6 +399,35 @@ export const CORE_SETTINGS: SettingDef[] = [
|
|
|
402
399
|
validate: (v) =>
|
|
403
400
|
parseRetentionWindow(v) === null ? 'Enter a whole number of days, or 0 to keep events forever.' : null,
|
|
404
401
|
},
|
|
402
|
+
|
|
403
|
+
{
|
|
404
|
+
/**
|
|
405
|
+
* Which starter pack the first admin chose for a new knowledge base — a
|
|
406
|
+
* pack's id, or `none` for "I'll start from scratch" — written once, by
|
|
407
|
+
* the deployment, when the choice landed (see
|
|
408
|
+
* `modules/onboarding/starter-pack.service.ts`). Its presence is what
|
|
409
|
+
* retires the "What does your team do?" card for good; its value is what
|
|
410
|
+
* the first-page prompt and the agent's first-run note follow. Internal:
|
|
411
|
+
* a fact about what happened, not something the setup screen offers.
|
|
412
|
+
*/
|
|
413
|
+
key: 'starterPack',
|
|
414
|
+
section: 'knowledge-base',
|
|
415
|
+
internal: true,
|
|
416
|
+
validate: (v) => (/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(v) ? null : 'A starter pack id is lowercase letters, digits and hyphens.'),
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
/**
|
|
420
|
+
* The claim an admin holds while their starter-pack choice is being
|
|
421
|
+
* written: `<user id> <epoch ms>`, inserted only if absent so two replicas
|
|
422
|
+
* cannot both write, and released once the choice is recorded. A claim
|
|
423
|
+
* nobody released in time is a process that died mid-write and is taken
|
|
424
|
+
* over (see `starter-pack.service.ts`). Internal, like the choice.
|
|
425
|
+
*/
|
|
426
|
+
key: 'starterPackClaim',
|
|
427
|
+
section: 'knowledge-base',
|
|
428
|
+
internal: true,
|
|
429
|
+
validate: (v) => (/^\S+ \d+$/.test(v) ? null : 'A claim is a user id and a time.'),
|
|
430
|
+
},
|
|
405
431
|
];
|
|
406
432
|
|
|
407
433
|
/**
|
|
@@ -587,20 +613,10 @@ export class DeploymentSettingsService {
|
|
|
587
613
|
knowledgeBaseDir: this.resolve('knowledgeBaseDir') || DEFAULT_KB_LAYOUT.knowledgeBaseDir,
|
|
588
614
|
skillsDir: this.resolve('skillsDir') || DEFAULT_KB_LAYOUT.skillsDir,
|
|
589
615
|
pluginsDir: this.resolve('pluginsDir') || DEFAULT_KB_LAYOUT.pluginsDir,
|
|
590
|
-
agentsFile:
|
|
616
|
+
agentsFile: DEFAULT_KB_LAYOUT.agentsFile,
|
|
591
617
|
};
|
|
592
618
|
}
|
|
593
619
|
|
|
594
|
-
/**
|
|
595
|
-
* Whether the platform should keep its pointer sentence in a customer-owned
|
|
596
|
-
* `AGENTS.md`. On unless the admin turned it off — an unset setting is a
|
|
597
|
-
* deployment that never saw the checkbox, and the sentence is what makes a
|
|
598
|
-
* renamed guide findable at all.
|
|
599
|
-
*/
|
|
600
|
-
resolveAgentsFileLink(): boolean {
|
|
601
|
-
return this.resolve('agentsFileLink') !== 'false';
|
|
602
|
-
}
|
|
603
|
-
|
|
604
620
|
/**
|
|
605
621
|
* Import the retired layout environment variables into their saved settings,
|
|
606
622
|
* ONCE, on a deployment that still sets them.
|
|
@@ -764,6 +780,61 @@ export class DeploymentSettingsService {
|
|
|
764
780
|
await this.save(entries, updatedBy, 'deployment');
|
|
765
781
|
}
|
|
766
782
|
|
|
783
|
+
/**
|
|
784
|
+
* {@link record} one value ONLY IF NOTHING IS THERE, and say whether it was
|
|
785
|
+
* this call that put it there. The row is the claim for a flow that must
|
|
786
|
+
* happen once across every replica (the starter-pack choice): the insert
|
|
787
|
+
* yields to a row already there, so of two replicas claiming at once the
|
|
788
|
+
* database lets exactly one through. Validated as `record` is; a blank
|
|
789
|
+
* value is no claim (it would be a clear) and answers false.
|
|
790
|
+
*/
|
|
791
|
+
async recordIfAbsent(key: string, value: string, updatedBy: string | null): Promise<boolean> {
|
|
792
|
+
const write = this.plan({ [key]: value }, 'deployment').toWrite.find((w) => w.key === key);
|
|
793
|
+
if (!write) return false;
|
|
794
|
+
const encrypted = write.def.secret === true;
|
|
795
|
+
const stored = encrypted ? this.crypto!.encrypt(write.value) : write.value;
|
|
796
|
+
const inserted = await this.db
|
|
797
|
+
.insert(deploymentSettings)
|
|
798
|
+
.values({ key, value: stored, encrypted, updatedBy })
|
|
799
|
+
.onConflictDoNothing({ target: deploymentSettings.key })
|
|
800
|
+
.returning({ key: deploymentSettings.key });
|
|
801
|
+
if (inserted.length === 0) return false;
|
|
802
|
+
this.stored.set(key, write.value);
|
|
803
|
+
return true;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Replace a plain setting's value ONLY IF it still reads `expected` —
|
|
808
|
+
* with `next`, or with nothing when `next` is null — and say whether it
|
|
809
|
+
* was this call that did it. One statement, so of two replicas acting on
|
|
810
|
+
* what they both read, the database lets exactly one through: the other
|
|
811
|
+
* finds the value gone or changed and answers false. For the claim flows
|
|
812
|
+
* that {@link recordIfAbsent} opens: taking over a claim that expired, and
|
|
813
|
+
* releasing one's own without touching a successor's. Plain settings only;
|
|
814
|
+
* `next` is validated as {@link record} would.
|
|
815
|
+
*/
|
|
816
|
+
async swapIfValue(key: string, expected: string, next: string | null, updatedBy: string | null): Promise<boolean> {
|
|
817
|
+
const def = this.defs.get(key);
|
|
818
|
+
if (!def || def.secret) return false;
|
|
819
|
+
const same = and(eq(deploymentSettings.key, key), eq(deploymentSettings.value, expected));
|
|
820
|
+
if (next === null) {
|
|
821
|
+
const gone = await this.db.delete(deploymentSettings).where(same).returning({ key: deploymentSettings.key });
|
|
822
|
+
if (gone.length === 0) return false;
|
|
823
|
+
this.stored.delete(key);
|
|
824
|
+
return true;
|
|
825
|
+
}
|
|
826
|
+
const write = this.plan({ [key]: next }, 'deployment').toWrite.find((w) => w.key === key);
|
|
827
|
+
if (!write) return false;
|
|
828
|
+
const swapped = await this.db
|
|
829
|
+
.update(deploymentSettings)
|
|
830
|
+
.set({ value: write.value, updatedBy, updatedAt: new Date() })
|
|
831
|
+
.where(same)
|
|
832
|
+
.returning({ key: deploymentSettings.key });
|
|
833
|
+
if (swapped.length === 0) return false;
|
|
834
|
+
this.stored.set(key, write.value);
|
|
835
|
+
return true;
|
|
836
|
+
}
|
|
837
|
+
|
|
767
838
|
/** Validate a batch and return the writes (and the clears) it amounts to; throws on any problem. */
|
|
768
839
|
private plan(
|
|
769
840
|
entries: Record<string, string>,
|
|
@@ -832,12 +903,12 @@ export class DeploymentSettingsService {
|
|
|
832
903
|
if (problem) problems.protectedBranches = problem;
|
|
833
904
|
}
|
|
834
905
|
|
|
835
|
-
// The layout
|
|
836
|
-
//
|
|
837
|
-
//
|
|
838
|
-
//
|
|
839
|
-
//
|
|
840
|
-
const layoutKeys = ['knowledgeBaseDir', 'skillsDir', 'pluginsDir'
|
|
906
|
+
// The layout trio is the other cross-field rule: three folder names that
|
|
907
|
+
// must all differ. Judged on the layout this save WOULD produce, with the
|
|
908
|
+
// default standing in for anything neither written nor stored — so
|
|
909
|
+
// renaming one folder to what another is already called is refused
|
|
910
|
+
// whichever of the two the save names.
|
|
911
|
+
const layoutKeys = ['knowledgeBaseDir', 'skillsDir', 'pluginsDir'] as const;
|
|
841
912
|
if (toWrite.some((w) => (layoutKeys as readonly string[]).includes(w.key))) {
|
|
842
913
|
const effective = (key: (typeof layoutKeys)[number]) =>
|
|
843
914
|
toWrite.find((w) => w.key === key)?.value || this.resolve(key) || DEFAULT_KB_LAYOUT[key];
|
|
@@ -845,7 +916,6 @@ export class DeploymentSettingsService {
|
|
|
845
916
|
knowledgeBaseDir: effective('knowledgeBaseDir'),
|
|
846
917
|
skillsDir: effective('skillsDir'),
|
|
847
918
|
pluginsDir: effective('pluginsDir'),
|
|
848
|
-
agentsFile: effective('agentsFile'),
|
|
849
919
|
});
|
|
850
920
|
// Against the field being written — the first one in the batch — since
|
|
851
921
|
// any of the three could be the one that collides.
|
|
@@ -873,7 +943,7 @@ export class DeploymentSettingsService {
|
|
|
873
943
|
knowledgeBaseDir: effective('knowledgeBaseDir'),
|
|
874
944
|
skillsDir: effective('skillsDir'),
|
|
875
945
|
pluginsDir: effective('pluginsDir'),
|
|
876
|
-
agentsFile:
|
|
946
|
+
agentsFile: DEFAULT_KB_LAYOUT.agentsFile,
|
|
877
947
|
});
|
|
878
948
|
} catch (err) {
|
|
879
949
|
// Against the field this save is writing — the checkout name when that
|
|
@@ -993,6 +1063,25 @@ export class DeploymentSettingsService {
|
|
|
993
1063
|
return `${OIDC_VERIFICATION_PREFIX}${fingerprint}`;
|
|
994
1064
|
}
|
|
995
1065
|
|
|
1066
|
+
/**
|
|
1067
|
+
* One plain (never sealed) setting as the DATABASE has it now, taken into
|
|
1068
|
+
* this replica's cache on the way: for the rare setting a running
|
|
1069
|
+
* deployment writes, so a replica that did not serve the write still
|
|
1070
|
+
* answers with it. The environment still wins, as in {@link resolve}.
|
|
1071
|
+
*/
|
|
1072
|
+
async reload(key: string): Promise<string> {
|
|
1073
|
+
const def = this.defs.get(key);
|
|
1074
|
+
if (!def || def.secret) return this.resolve(key);
|
|
1075
|
+
const rows = await this.db
|
|
1076
|
+
.select({ value: deploymentSettings.value, encrypted: deploymentSettings.encrypted })
|
|
1077
|
+
.from(deploymentSettings)
|
|
1078
|
+
.where(eq(deploymentSettings.key, key));
|
|
1079
|
+
const row = rows.find((r) => !r.encrypted);
|
|
1080
|
+
if (row) this.stored.set(key, row.value);
|
|
1081
|
+
else this.stored.delete(key);
|
|
1082
|
+
return this.resolve(key);
|
|
1083
|
+
}
|
|
1084
|
+
|
|
996
1085
|
/** Remove one stored row (used by tests and by `prune`). */
|
|
997
1086
|
async clear(key: string): Promise<void> {
|
|
998
1087
|
await this.db.delete(deploymentSettings).where(eq(deploymentSettings.key, key));
|
|
@@ -34,7 +34,7 @@ export interface GitHubAppRepository {
|
|
|
34
34
|
* Make sure {@link token} answers with one that is still good. `asked`
|
|
35
35
|
* is for a caller waiting on the answer itself, who is told a failure.
|
|
36
36
|
*/
|
|
37
|
-
prepare(opts?: { asked?: boolean }): Promise<void>;
|
|
37
|
+
prepare(opts?: { asked?: boolean; refused?: boolean }): Promise<void>;
|
|
38
38
|
/** Whether the deployment may be pointed at this repository (`owner/name`). */
|
|
39
39
|
permits(repository: string, read: SettingReader): boolean;
|
|
40
40
|
/** Whether the app, its installation and a repository are all there. */
|
|
@@ -98,7 +98,7 @@ export class RepositorySource {
|
|
|
98
98
|
this.credentials = {
|
|
99
99
|
username: () => this.username(),
|
|
100
100
|
token: () => this.token(),
|
|
101
|
-
prepare: () => this.prepare(),
|
|
101
|
+
prepare: (opts) => this.prepare(opts),
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -185,8 +185,8 @@ export class RepositorySource {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
private async prepare(): Promise<void> {
|
|
189
|
-
if (this.inEffect === 'github-app') await this.opts.githubApp?.prepare();
|
|
188
|
+
private async prepare(opts?: { refused?: boolean }): Promise<void> {
|
|
189
|
+
if (this.inEffect === 'github-app') await this.opts.githubApp?.prepare(opts);
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
private tokenIn(read: SettingReader): string {
|
|
@@ -64,17 +64,14 @@ const SECRET_FOR_THAT_PROVIDER =
|
|
|
64
64
|
'Enter the application secret for that provider — the saved one is only sent to the provider it was saved for.';
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
* The knowledge-base layout as setting keys: the three renameable roots
|
|
68
|
-
* guide's file name
|
|
69
|
-
*
|
|
70
|
-
* with the names.
|
|
67
|
+
* The knowledge-base layout as setting keys: the three renameable roots. The
|
|
68
|
+
* guide's file name is not one of them — the settings layer sets none, so the
|
|
69
|
+
* layout it produces carries the default, `AGENTS.md`.
|
|
71
70
|
*/
|
|
72
71
|
const LAYOUT_KEYS: readonly string[] = [
|
|
73
72
|
'knowledgeBaseDir',
|
|
74
73
|
'skillsDir',
|
|
75
74
|
'pluginsDir',
|
|
76
|
-
'agentsFile',
|
|
77
|
-
'agentsFileLink',
|
|
78
75
|
];
|
|
79
76
|
/** The branch model, as setting keys. */
|
|
80
77
|
const BRANCH_KEYS: readonly string[] = ['defaultBranch', 'protectedBranches'];
|