@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
|
@@ -22,10 +22,32 @@ function updated(branch: string): BranchSyncOutcome {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
describe('KbSyncService', () => {
|
|
25
|
+
it('answers the sync without waiting for the tidy-up after it', async () => {
|
|
26
|
+
let finish = (): void => undefined;
|
|
27
|
+
const workflow: SyncWorkflowPort = {
|
|
28
|
+
syncWorkspaceFromRemote: vi.fn(async (id: string) => updated(decodeURIComponent(id))),
|
|
29
|
+
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
|
|
30
|
+
// A tidy-up that never ends unless told to — and one that fails.
|
|
31
|
+
tidyAfterSweep: vi
|
|
32
|
+
.fn()
|
|
33
|
+
.mockImplementationOnce(
|
|
34
|
+
() => new Promise((resolve) => (finish = () => resolve({ closedEmpty: 0, removedLeftovers: 0 }))),
|
|
35
|
+
)
|
|
36
|
+
.mockRejectedValueOnce(new Error('boom')),
|
|
37
|
+
retireRemoteGoneClone: vi.fn(async () => true),
|
|
38
|
+
};
|
|
39
|
+
const svc = new KbSyncService(workflow, workspaces(['main']));
|
|
40
|
+
await expect(svc.sync({ branches: 'all' })).resolves.toMatchObject({ status: 'synced' });
|
|
41
|
+
expect(workflow.tidyAfterSweep).toHaveBeenCalledTimes(1);
|
|
42
|
+
await expect(svc.sync({ branches: 'all' })).resolves.toMatchObject({ status: 'synced' });
|
|
43
|
+
finish();
|
|
44
|
+
});
|
|
45
|
+
|
|
25
46
|
it('syncs every known clone for an "all" request and reports unknown branches as not cloned', async () => {
|
|
26
47
|
const workflow: SyncWorkflowPort = {
|
|
27
48
|
syncWorkspaceFromRemote: vi.fn(async (id: string) => updated(decodeURIComponent(id))),
|
|
28
49
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 1),
|
|
50
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
29
51
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
30
52
|
};
|
|
31
53
|
const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x']));
|
|
@@ -34,6 +56,8 @@ describe('KbSyncService', () => {
|
|
|
34
56
|
expect(all.status).toBe('synced');
|
|
35
57
|
expect(all.results.map((r) => r.branch)).toEqual(['main', 'ali/x']);
|
|
36
58
|
expect(all.changeRequests.closedDeletedBranch).toBe(1);
|
|
59
|
+
// Every sweep for deleted branches is followed by the leftover cleanup.
|
|
60
|
+
expect(workflow.tidyAfterSweep).toHaveBeenCalledTimes(1);
|
|
37
61
|
expect(workflow.syncWorkspaceFromRemote).toHaveBeenCalledWith('ali%2Fx');
|
|
38
62
|
|
|
39
63
|
const some = await svc.sync({ branches: ['ali/x', 'juan/other'] });
|
|
@@ -48,6 +72,7 @@ describe('KbSyncService', () => {
|
|
|
48
72
|
: updated(decodeURIComponent(id)),
|
|
49
73
|
),
|
|
50
74
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
|
|
75
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
51
76
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
52
77
|
};
|
|
53
78
|
const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x']));
|
|
@@ -62,6 +87,7 @@ describe('KbSyncService', () => {
|
|
|
62
87
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => {
|
|
63
88
|
throw new Error('origin down');
|
|
64
89
|
}),
|
|
90
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
65
91
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
66
92
|
};
|
|
67
93
|
const svc = new KbSyncService(workflow, workspaces(['main']));
|
|
@@ -91,6 +117,7 @@ describe('KbSyncService', () => {
|
|
|
91
117
|
return updated(branch);
|
|
92
118
|
}),
|
|
93
119
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
|
|
120
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
94
121
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
95
122
|
};
|
|
96
123
|
const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x', 'juan/y']));
|
|
@@ -121,6 +148,7 @@ describe('KbSyncService', () => {
|
|
|
121
148
|
return updated(decodeURIComponent(id));
|
|
122
149
|
}),
|
|
123
150
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
|
|
151
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
124
152
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
125
153
|
};
|
|
126
154
|
const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x', 'juan/y']));
|
|
@@ -141,6 +169,7 @@ describe('KbSyncService.lastSync', () => {
|
|
|
141
169
|
const workflow: SyncWorkflowPort = {
|
|
142
170
|
syncWorkspaceFromRemote: vi.fn(async (id: string) => updated(decodeURIComponent(id))),
|
|
143
171
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
|
|
172
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
144
173
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
145
174
|
};
|
|
146
175
|
let clock = 1_000;
|
|
@@ -168,6 +197,7 @@ describe('KbSyncService.lastSync', () => {
|
|
|
168
197
|
return updated(decodeURIComponent(id));
|
|
169
198
|
}),
|
|
170
199
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
|
|
200
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
171
201
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
172
202
|
};
|
|
173
203
|
const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x']));
|
|
@@ -188,6 +218,7 @@ describe('KbSyncService — a throwing branch step', () => {
|
|
|
188
218
|
return updated(decodeURIComponent(id));
|
|
189
219
|
}),
|
|
190
220
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 1),
|
|
221
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
191
222
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
192
223
|
};
|
|
193
224
|
const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x']));
|
|
@@ -208,6 +239,7 @@ describe('KbSyncService — clones the host no longer has, and clones that canno
|
|
|
208
239
|
id === 'ali%2Fx' ? { branch: 'ali/x', outcome: 'remote-gone' } : updated(decodeURIComponent(id)),
|
|
209
240
|
),
|
|
210
241
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 1),
|
|
242
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
211
243
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
212
244
|
};
|
|
213
245
|
const svc = new KbSyncService(workflow, workspaces(['ali/x', 'main']));
|
|
@@ -222,6 +254,7 @@ describe('KbSyncService — clones the host no longer has, and clones that canno
|
|
|
222
254
|
const workflow: SyncWorkflowPort = {
|
|
223
255
|
syncWorkspaceFromRemote: vi.fn(async (id: string) => updated(decodeURIComponent(id))),
|
|
224
256
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
|
|
257
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
225
258
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
226
259
|
};
|
|
227
260
|
const port: SyncWorkspacePort = {
|
|
@@ -251,6 +284,7 @@ describe('KbSyncService — a coalesced caller is judged by its own branches', (
|
|
|
251
284
|
return updated(decodeURIComponent(id));
|
|
252
285
|
}),
|
|
253
286
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
|
|
287
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
254
288
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
255
289
|
};
|
|
256
290
|
const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x', 'juan/y']));
|
|
@@ -278,6 +312,7 @@ describe('KbSyncService — a waiter keeps the branches it asked for', () => {
|
|
|
278
312
|
return updated(decodeURIComponent(id));
|
|
279
313
|
}),
|
|
280
314
|
closeChangeRequestsWithDeletedBranches: vi.fn(async () => 0),
|
|
315
|
+
tidyAfterSweep: vi.fn(async () => ({ closedEmpty: 0, removedLeftovers: 0 })),
|
|
281
316
|
retireRemoteGoneClone: vi.fn(async () => true),
|
|
282
317
|
};
|
|
283
318
|
const svc = new KbSyncService(workflow, workspaces(['main', 'ali/x', 'juan/y']));
|
|
@@ -61,6 +61,8 @@ export interface SyncWorkflowPort {
|
|
|
61
61
|
retireRemoteGoneClone(workspaceId: string): Promise<boolean>;
|
|
62
62
|
/** The existing sweep; returns how many requests it closed. */
|
|
63
63
|
closeChangeRequestsWithDeletedBranches(): Promise<number>;
|
|
64
|
+
/** The tidy-up after the sweep — empty open requests closed, leftover branches removed; never throws. */
|
|
65
|
+
tidyAfterSweep(): Promise<{ closedEmpty: number; removedLeftovers: number }>;
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
/**
|
|
@@ -187,6 +187,12 @@ export class KbSyncService implements IKbSyncService {
|
|
|
187
187
|
} catch (err) {
|
|
188
188
|
log.warn('deleted-branch sweep failed:', { err });
|
|
189
189
|
}
|
|
190
|
+
// Then the tidy-up boot runs too: empty open requests closed, leftover
|
|
191
|
+
// branches of merged requests removed. Detached: it can take a while on a
|
|
192
|
+
// large repository, and the sync (often a webhook with a short timeout)
|
|
193
|
+
// must not wait on it. It never throws; the catch is for a mock or a
|
|
194
|
+
// future change that does.
|
|
195
|
+
void this.workflow.tidyAfterSweep().catch((err: unknown) => log.warn('post-sync tidy-up failed:', { err }));
|
|
190
196
|
|
|
191
197
|
const result: SyncResult = {
|
|
192
198
|
status: KbSyncService.statusOf(results),
|
|
@@ -70,15 +70,19 @@ function render(fragment: SQL): { sql: string; params: unknown[] } {
|
|
|
70
70
|
return { sql: q.sql, params: q.params };
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
function
|
|
74
|
-
|
|
75
|
-
const provider = new BevelOAuthProvider({
|
|
73
|
+
function providerDeps(db: Database) {
|
|
74
|
+
return {
|
|
76
75
|
db,
|
|
77
76
|
crypto: null,
|
|
78
77
|
stateSecret: STATE_SECRET,
|
|
79
78
|
publicFrontendUrl: FRONTEND,
|
|
80
79
|
tokenPrefix: PREFIX,
|
|
81
|
-
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function makeProvider(queue: unknown[] = []) {
|
|
84
|
+
const { db, captured } = makeFakeDb(queue);
|
|
85
|
+
const provider = new BevelOAuthProvider(providerDeps(db));
|
|
82
86
|
return { provider, captured, db };
|
|
83
87
|
}
|
|
84
88
|
|
|
@@ -292,9 +296,10 @@ describe('BevelOAuthProvider', () => {
|
|
|
292
296
|
const { provider, captured, db } = makeProvider([
|
|
293
297
|
[oldRow] /* revoke.returning */,
|
|
294
298
|
[{ id: 'conn-1' }] /* the token's connection, still live */,
|
|
295
|
-
|
|
299
|
+
[] /* the (throttled) use stamp's first-use claim: stamped before */,
|
|
296
300
|
undefined, undefined, /* prunes */
|
|
297
301
|
undefined /* token insert */,
|
|
302
|
+
undefined /* the ordinary use stamp */,
|
|
298
303
|
]);
|
|
299
304
|
const tokens = await provider.exchangeRefreshToken(CLIENT, 'bevel-mcp_r_old', ['mcp']);
|
|
300
305
|
expect(tokens.scope).toBe('mcp');
|
|
@@ -307,8 +312,10 @@ describe('BevelOAuthProvider', () => {
|
|
|
307
312
|
expect((db as any).select).toHaveBeenCalledTimes(1);
|
|
308
313
|
expect(render(captured.where[1])).toMatchObject({ params: ['conn-1'] });
|
|
309
314
|
expect(render(captured.where[1]).sql).toMatch(/"agent_connections"."revoked_at" is null/);
|
|
310
|
-
// …and the use is stamped separately, off the refresh's own path
|
|
311
|
-
|
|
315
|
+
// …and the use is stamped separately, off the refresh's own path: the
|
|
316
|
+
// first-use claim, then (stamped before) the ordinary stamp.
|
|
317
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
318
|
+
expect(captured.updateTargets).toEqual([oauthTokens, agentConnections, agentConnections]);
|
|
312
319
|
expect(Object.keys(captured.set[1])).toEqual(['lastUsedAt']);
|
|
313
320
|
|
|
314
321
|
// Widening is refused.
|
|
@@ -363,6 +370,7 @@ describe('BevelOAuthProvider', () => {
|
|
|
363
370
|
const { provider, captured } = makeProvider([
|
|
364
371
|
[row] /* select */,
|
|
365
372
|
undefined /* token lastUsedAt touch */,
|
|
373
|
+
[] /* the connection's first-use claim: stamped before */,
|
|
366
374
|
undefined /* connection lastUsedAt touch */,
|
|
367
375
|
[row] /* a second verify a moment later */,
|
|
368
376
|
undefined /* its token touch — and NO second connection touch */,
|
|
@@ -381,16 +389,65 @@ describe('BevelOAuthProvider', () => {
|
|
|
381
389
|
// Both "last used" marks are touched: the token's row, and THIS token's
|
|
382
390
|
// agent connection.
|
|
383
391
|
await new Promise((r) => setTimeout(r, 0));
|
|
384
|
-
|
|
385
|
-
|
|
392
|
+
// The connection's stamp is two statements: the first-use claim (its
|
|
393
|
+
// id, and never stamped), then — stamped before — the ordinary stamp.
|
|
394
|
+
expect(captured.updateTargets).toEqual([oauthTokens, agentConnections, agentConnections]);
|
|
395
|
+
expect(captured.set.map((s) => Object.keys(s))).toEqual([['lastUsedAt'], ['lastUsedAt'], ['lastUsedAt']]);
|
|
386
396
|
expect(render(captured.where[1])).toMatchObject({ params: ['tok-row-1'] });
|
|
387
397
|
expect(render(captured.where[2])).toMatchObject({ params: ['conn-1'] });
|
|
388
|
-
expect(render(captured.where[2]).sql).toMatch(/"agent_connections"."id" = \$1/);
|
|
398
|
+
expect(render(captured.where[2]).sql).toMatch(/"agent_connections"."id" = \$1 and "agent_connections"."last_used_at" is null/);
|
|
399
|
+
expect(render(captured.where[3])).toMatchObject({ params: ['conn-1'] });
|
|
400
|
+
expect(render(captured.where[3]).sql).toMatch(/"agent_connections"."id" = \$1/);
|
|
389
401
|
// The connection's stamp is throttled: a verify a moment later touches
|
|
390
402
|
// the token row again but not the connection — a minute has not passed.
|
|
391
403
|
await provider.verifyAccessToken('bevel-mcp_live');
|
|
392
404
|
await new Promise((r) => setTimeout(r, 0));
|
|
393
|
-
expect(captured.updateTargets).toEqual([oauthTokens, agentConnections, oauthTokens]);
|
|
405
|
+
expect(captured.updateTargets).toEqual([oauthTokens, agentConnections, agentConnections, oauthTokens]);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* The FIRST stamp of a connection is the agent arriving — what the
|
|
410
|
+
* onboarding waits for — so the owner is told, once: the claim that took
|
|
411
|
+
* the row from never-used to now is the one that announces, and it is
|
|
412
|
+
* the only statement that run makes. A connection stamped before loses
|
|
413
|
+
* the claim, is stamped the ordinary way, and nobody is told.
|
|
414
|
+
*/
|
|
415
|
+
it('announces an agent connection to its owner on its first use, and never again', async () => {
|
|
416
|
+
const row = {
|
|
417
|
+
id: 'tok-row-1', clientId: 'client-1', connectionId: 'conn-1', scope: 'mcp', resource: null,
|
|
418
|
+
expiresAt: new Date(Date.now() + 60_000), userId: 'user-1', userEmail: 'alice@example.com',
|
|
419
|
+
};
|
|
420
|
+
const events = { emit: vi.fn() };
|
|
421
|
+
const fresh = makeProvider([
|
|
422
|
+
[row],
|
|
423
|
+
undefined /* token touch */,
|
|
424
|
+
[{ userId: 'user-1', client: 'Claude' }] /* the claim: this request took the first stamp */,
|
|
425
|
+
]);
|
|
426
|
+
const freshProvider = new BevelOAuthProvider({ ...providerDeps(fresh.db), events });
|
|
427
|
+
await freshProvider.verifyAccessToken('bevel-mcp_live');
|
|
428
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
429
|
+
expect(events.emit).toHaveBeenCalledTimes(1);
|
|
430
|
+
expect(events.emit).toHaveBeenCalledWith({
|
|
431
|
+
kind: 'agent-connected',
|
|
432
|
+
forUserId: 'user-1',
|
|
433
|
+
client: 'Claude',
|
|
434
|
+
agentKind: 'agent',
|
|
435
|
+
at: expect.stringMatching(/^\d{4}-\d{2}-\d{2}T/),
|
|
436
|
+
});
|
|
437
|
+
// The claim WAS the stamp: no second write for the winner.
|
|
438
|
+
expect(fresh.captured.updateTargets).toEqual([oauthTokens, agentConnections]);
|
|
439
|
+
|
|
440
|
+
const used = makeProvider([
|
|
441
|
+
[row],
|
|
442
|
+
undefined,
|
|
443
|
+
[] /* the claim lost: stamped before (or by a racing request) */,
|
|
444
|
+
undefined /* the ordinary stamp */,
|
|
445
|
+
]);
|
|
446
|
+
const usedEvents = { emit: vi.fn() };
|
|
447
|
+
await new BevelOAuthProvider({ ...providerDeps(used.db), events: usedEvents }).verifyAccessToken('bevel-mcp_live');
|
|
448
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
449
|
+
expect(usedEvents.emit).not.toHaveBeenCalled();
|
|
450
|
+
expect(used.captured.updateTargets).toEqual([oauthTokens, agentConnections, agentConnections]);
|
|
394
451
|
});
|
|
395
452
|
|
|
396
453
|
it('revokeToken (RFC 7009) ends the agent connection once no live token remains on it, as the owner\'s doing', async () => {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ListToolsRequestSchema,
|
|
9
9
|
isInitializeRequest,
|
|
10
10
|
type CallToolResult,
|
|
11
|
+
type ListToolsResult,
|
|
11
12
|
} from '@modelcontextprotocol/sdk/types.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -44,6 +45,13 @@ export interface FakeDownstreamOptions {
|
|
|
44
45
|
* revoked or expired token with.
|
|
45
46
|
*/
|
|
46
47
|
acceptsToken?: (token: string) => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* What `tools/list` answers, in place of the single `echo` tool. A FUNCTION,
|
|
50
|
+
* read per request, so a test can have the server correct a schema between
|
|
51
|
+
* two discoveries the way a vendor's fix reaches us — through the next load,
|
|
52
|
+
* with nothing restarted here.
|
|
53
|
+
*/
|
|
54
|
+
tools?: () => Array<{ name: string; description?: string; inputSchema: unknown }>;
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
export async function startFakeDownstreamMcpServer(opts: FakeDownstreamOptions = {}): Promise<FakeDownstreamMcpServer> {
|
|
@@ -55,13 +63,16 @@ export async function startFakeDownstreamMcpServer(opts: FakeDownstreamOptions =
|
|
|
55
63
|
function buildServer(): Server {
|
|
56
64
|
const server = new Server({ name: 'downstream', version: '0.0.0' }, { capabilities: { tools: {} } });
|
|
57
65
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
58
|
-
|
|
66
|
+
// Cast because a test may deliberately advertise a schema that is NOT
|
|
67
|
+
// valid JSON Schema, which is precisely what the SDK's type forbids and
|
|
68
|
+
// what a real server is free to send.
|
|
69
|
+
tools: (opts.tools?.() ?? [
|
|
59
70
|
{
|
|
60
71
|
name: 'echo',
|
|
61
72
|
description: 'Return the text it was given.',
|
|
62
|
-
inputSchema: { type: 'object'
|
|
73
|
+
inputSchema: { type: 'object', properties: { text: { type: 'string' } } },
|
|
63
74
|
},
|
|
64
|
-
],
|
|
75
|
+
]) as unknown as ListToolsResult['tools'],
|
|
65
76
|
}));
|
|
66
77
|
server.setRequestHandler(CallToolRequestSchema, async (request): Promise<CallToolResult> => {
|
|
67
78
|
executions += 1;
|
|
@@ -68,15 +68,50 @@ describe('toListedTool', () => {
|
|
|
68
68
|
...over,
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
it('passes a conforming tool through', () => {
|
|
71
|
+
it('passes a conforming tool through, its call example first', () => {
|
|
72
72
|
const listed = toListedTool(proxied({ mcpName: 'gmail_send_email' }));
|
|
73
73
|
expect(listed).toEqual({
|
|
74
74
|
name: 'gmail_send_email',
|
|
75
|
-
description: '
|
|
75
|
+
description: 'Call: m.t({})\n\na tool',
|
|
76
76
|
inputSchema: { type: 'object', properties: {} },
|
|
77
77
|
});
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
+
it('generates the example from the tool\'s own schema, in the shape it really takes', () => {
|
|
81
|
+
const platform = toListedTool(
|
|
82
|
+
proxied({
|
|
83
|
+
utcpName: 'KNOWLEDGE_BASE.read_file',
|
|
84
|
+
mcpName: 'read_file',
|
|
85
|
+
inputSchema: {
|
|
86
|
+
type: 'object',
|
|
87
|
+
properties: {
|
|
88
|
+
body: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: { branch: { type: 'string' }, path: { type: 'string' }, limit: { type: 'integer' } },
|
|
91
|
+
required: ['branch', 'path'],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
required: ['body'],
|
|
95
|
+
} as never,
|
|
96
|
+
}),
|
|
97
|
+
)!;
|
|
98
|
+
expect(platform.description.split('\n')[0]).toBe(
|
|
99
|
+
'Call: KNOWLEDGE_BASE.read_file({ body: { branch: "...", path: "..." } })',
|
|
100
|
+
);
|
|
101
|
+
const flat = toListedTool(
|
|
102
|
+
proxied({
|
|
103
|
+
utcpName: 'NS.search',
|
|
104
|
+
mcpName: 'NS_search',
|
|
105
|
+
inputSchema: {
|
|
106
|
+
type: 'object',
|
|
107
|
+
properties: { query: { type: 'string' }, limit: { type: 'integer' } },
|
|
108
|
+
required: ['query'],
|
|
109
|
+
} as never,
|
|
110
|
+
}),
|
|
111
|
+
)!;
|
|
112
|
+
expect(flat.description.split('\n')[0]).toBe('Call: NS.search({ query: "..." })');
|
|
113
|
+
});
|
|
114
|
+
|
|
80
115
|
it('drops a tool whose name is too long or has illegal chars (so it cannot blank the whole list)', () => {
|
|
81
116
|
expect(toListedTool(proxied({ mcpName: 'has spaces' }))).toBeNull();
|
|
82
117
|
expect(toListedTool(proxied({ mcpName: 'a'.repeat(129) }))).toBeNull();
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import type { Server as HttpServer } from 'node:http';
|
|
2
|
+
import type { AddressInfo } from 'node:net';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import express, { type RequestHandler } from 'express';
|
|
6
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
7
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
8
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
9
|
+
import { MCP_APP_MIME_TYPE, MCP_APP_UI_META_KEY } from '@bevel-software/platform-mcp-core';
|
|
10
|
+
import { createMcpRoutes } from '../mcp.routes.js';
|
|
11
|
+
import { McpService } from '../mcp.service.js';
|
|
12
|
+
import { SpillStore } from '../../workspace/spill-store.js';
|
|
13
|
+
import { createManualRoutes } from '../../tool-registry/manual.routes.js';
|
|
14
|
+
import { ToolRegistry } from '../../tool-registry/tool-registry.js';
|
|
15
|
+
import { toolDef } from '../../tool-helpers/tool-def.js';
|
|
16
|
+
import { McpAppService, OPEN_PAGE_VIEW_URI_PREFIX } from '../../embed/mcp-app.js';
|
|
17
|
+
import { OPEN_PAGE_TOOL } from '../../embed/embed.tools.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The MCP App, over the REAL Streamable-HTTP transport with the official SDK
|
|
21
|
+
* client — the criterion as a host actually observes it: `tools/list` carries
|
|
22
|
+
* the view on `open_page`, `resources/list` offers it under the MCP App media
|
|
23
|
+
* type, and `resources/read` hands back the view with the framing metadata.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const KEY = 'bevel_key_user_a';
|
|
27
|
+
const PUBLIC = 'https://hexis.example';
|
|
28
|
+
|
|
29
|
+
const bearerOf = (req: express.Request) => (req.headers.authorization ?? '').replace(/^Bearer\s+/i, '');
|
|
30
|
+
const fakeAuth: RequestHandler = (req, res, next) => {
|
|
31
|
+
if (bearerOf(req) !== KEY) {
|
|
32
|
+
res.status(401).json({ error: 'unauthorized' });
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
req.userId = 'user-A';
|
|
36
|
+
req.externalApiKeyId = 'tok-A';
|
|
37
|
+
next();
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let httpServer: HttpServer | null = null;
|
|
41
|
+
let client: Client | null = null;
|
|
42
|
+
|
|
43
|
+
afterEach(async () => {
|
|
44
|
+
await client?.close().catch(() => undefined);
|
|
45
|
+
client = null;
|
|
46
|
+
if (httpServer) {
|
|
47
|
+
httpServer.closeAllConnections();
|
|
48
|
+
await new Promise<void>((r) => httpServer!.close(() => r()));
|
|
49
|
+
}
|
|
50
|
+
httpServer = null;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
/** The platform: the real proxy, the real routes, and `open_page` in the catalog. */
|
|
54
|
+
async function connect(opts: { serveApps?: boolean } = {}) {
|
|
55
|
+
const app = express();
|
|
56
|
+
app.use(express.json());
|
|
57
|
+
|
|
58
|
+
const registry = new ToolRegistry();
|
|
59
|
+
for (const name of [OPEN_PAGE_TOOL, 'read_file']) {
|
|
60
|
+
registry.registerExternalTool(
|
|
61
|
+
toolDef({
|
|
62
|
+
name,
|
|
63
|
+
description: `the ${name} tool`,
|
|
64
|
+
path: `/api/agent/tools/${name}`,
|
|
65
|
+
inputs: { type: 'object', properties: { path: { type: 'string' } }, required: ['path'], additionalProperties: false },
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const toolRoutes = express.Router();
|
|
70
|
+
toolRoutes.use(createManualRoutes(registry, fakeAuth, async () => 'a@x.io'));
|
|
71
|
+
toolRoutes.post('/agent/tools/:name', (req, res) =>
|
|
72
|
+
res.json(
|
|
73
|
+
req.params.name === OPEN_PAGE_TOOL
|
|
74
|
+
? { path: 'Data/Thing.md', content: '# Thing', embedUrl: `${PUBLIC}/embed?token=t`, appUrl: PUBLIC, branch: 'main' }
|
|
75
|
+
: { ok: true },
|
|
76
|
+
),
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
httpServer = app.listen(0);
|
|
80
|
+
await new Promise<void>((r) => httpServer!.once('listening', () => r()));
|
|
81
|
+
const port = (httpServer.address() as AddressInfo).port;
|
|
82
|
+
const baseUrl = `http://127.0.0.1:${port}`;
|
|
83
|
+
|
|
84
|
+
const service = new McpService(
|
|
85
|
+
{
|
|
86
|
+
loopbackBaseUrl: baseUrl,
|
|
87
|
+
manualName: 'KNOWLEDGE_BASE',
|
|
88
|
+
spillStore: new SpillStore(join(tmpdir(), 'bevel-test-spills')),
|
|
89
|
+
publicFrontendUrl: PUBLIC,
|
|
90
|
+
},
|
|
91
|
+
undefined,
|
|
92
|
+
undefined,
|
|
93
|
+
undefined,
|
|
94
|
+
undefined,
|
|
95
|
+
undefined,
|
|
96
|
+
// A deployment with no apps is the degraded shape: no capability, no view.
|
|
97
|
+
opts.serveApps === false ? undefined : new McpAppService({ publicFrontendUrl: PUBLIC }),
|
|
98
|
+
);
|
|
99
|
+
const stub = {} as never;
|
|
100
|
+
app.use('/api', createMcpRoutes(service, stub, fakeAuth, fakeAuth, stub, stub, stub, ''));
|
|
101
|
+
app.use('/api', toolRoutes);
|
|
102
|
+
|
|
103
|
+
client = new Client({ name: 'test-host', version: '1.0.0' });
|
|
104
|
+
await client.connect(
|
|
105
|
+
new StreamableHTTPClientTransport(new URL(`${baseUrl}/api/mcp`), {
|
|
106
|
+
requestInit: { headers: { Authorization: `Bearer ${KEY}` } },
|
|
107
|
+
}),
|
|
108
|
+
);
|
|
109
|
+
return client;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** The URI the packaged view is served under — named by its content, so read off the service. */
|
|
113
|
+
async function viewUri(): Promise<string> {
|
|
114
|
+
return (await new McpAppService({ publicFrontendUrl: PUBLIC }).manifest()).resources[0].uri;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
describe('the hosted MCP endpoint serves the open_page view', () => {
|
|
118
|
+
it('lists open_page carrying UI metadata that names a ui:// resource', async () => {
|
|
119
|
+
const host = await connect();
|
|
120
|
+
const { tools } = await host.listTools();
|
|
121
|
+
const openPage = tools.find((t) => t.name === OPEN_PAGE_TOOL);
|
|
122
|
+
expect(openPage).toBeDefined();
|
|
123
|
+
expect(openPage!._meta).toEqual({ [MCP_APP_UI_META_KEY]: { resourceUri: await viewUri() } });
|
|
124
|
+
expect((await viewUri()).startsWith(OPEN_PAGE_VIEW_URI_PREFIX)).toBe(true);
|
|
125
|
+
// And only that tool: `read_file` is deliberately untouched.
|
|
126
|
+
expect(tools.find((t) => t.name === 'read_file')!._meta).toBeUndefined();
|
|
127
|
+
}, 30_000);
|
|
128
|
+
|
|
129
|
+
it('lists the view with the MCP App media type', async () => {
|
|
130
|
+
const host = await connect();
|
|
131
|
+
const { resources } = await host.listResources();
|
|
132
|
+
const uri = await viewUri();
|
|
133
|
+
const view = resources.find((r) => r.uri === uri);
|
|
134
|
+
expect(view).toBeDefined();
|
|
135
|
+
expect(view!.mimeType).toBe(MCP_APP_MIME_TYPE);
|
|
136
|
+
expect(view!._meta).toMatchObject({
|
|
137
|
+
[MCP_APP_UI_META_KEY]: { csp: { connectDomains: [PUBLIC], resourceDomains: [PUBLIC] } },
|
|
138
|
+
});
|
|
139
|
+
}, 30_000);
|
|
140
|
+
|
|
141
|
+
it('reads the view, reaching exactly the deployment own origin and asking for no sandbox domain', async () => {
|
|
142
|
+
const host = await connect();
|
|
143
|
+
const read = await host.readResource({ uri: await viewUri() });
|
|
144
|
+
expect(read.contents).toHaveLength(1);
|
|
145
|
+
const [content] = read.contents as Array<{ mimeType: string; text: string; _meta: Record<string, unknown> }>;
|
|
146
|
+
expect(content.mimeType).toBe(MCP_APP_MIME_TYPE);
|
|
147
|
+
expect(content.text).toContain('ui/initialize');
|
|
148
|
+
expect(content._meta[MCP_APP_UI_META_KEY]).toMatchObject({
|
|
149
|
+
csp: { connectDomains: [PUBLIC], resourceDomains: [PUBLIC] },
|
|
150
|
+
prefersBorder: false,
|
|
151
|
+
});
|
|
152
|
+
// No frames: a chat host's sandbox blocks them, so the view does not ask.
|
|
153
|
+
expect((content._meta[MCP_APP_UI_META_KEY] as { csp: Record<string, unknown> }).csp).not.toHaveProperty(
|
|
154
|
+
'frameDomains',
|
|
155
|
+
);
|
|
156
|
+
// The host's default sandbox: the field's format is each host's own, and
|
|
157
|
+
// a value a host rejects is a view that never renders.
|
|
158
|
+
expect(content._meta[MCP_APP_UI_META_KEY]).not.toHaveProperty('domain');
|
|
159
|
+
}, 30_000);
|
|
160
|
+
|
|
161
|
+
it('refuses a resource it does not serve, naming the ones it does', async () => {
|
|
162
|
+
const host = await connect();
|
|
163
|
+
await expect(host.readResource({ uri: 'ui://hexis/not-a-view.html' })).rejects.toThrow(
|
|
164
|
+
/No resource at ui:\/\/hexis\/not-a-view\.html/,
|
|
165
|
+
);
|
|
166
|
+
}, 30_000);
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* A deployment that serves no view must not declare the capability: a
|
|
170
|
+
* client would list resources and be told the method does not exist, which
|
|
171
|
+
* reads as a broken endpoint rather than as "this one has no apps".
|
|
172
|
+
*/
|
|
173
|
+
it('declares no resources capability when the deployment serves no app', async () => {
|
|
174
|
+
const host = await connect({ serveApps: false });
|
|
175
|
+
expect(host.getServerCapabilities()?.resources).toBeUndefined();
|
|
176
|
+
const { tools } = await host.listTools();
|
|
177
|
+
// Every tool is still listed, and still carries no view.
|
|
178
|
+
expect(tools.find((t) => t.name === OPEN_PAGE_TOOL)).toBeDefined();
|
|
179
|
+
expect(tools.find((t) => t.name === OPEN_PAGE_TOOL)!._meta).toBeUndefined();
|
|
180
|
+
}, 30_000);
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The view frames `structuredContent.embedUrl` — it has nowhere else to
|
|
184
|
+
* read it — so a tool with a view must answer structured content as well
|
|
185
|
+
* as the text the model reads. A tool without one answers text alone.
|
|
186
|
+
*/
|
|
187
|
+
it('answers open_page with structured content the view can read, and read_file without', async () => {
|
|
188
|
+
const host = await connect();
|
|
189
|
+
const opened = await host.callTool({ name: OPEN_PAGE_TOOL, arguments: { path: 'Data/Thing.md' } });
|
|
190
|
+
expect(opened.structuredContent).toMatchObject({ embedUrl: `${PUBLIC}/embed?token=t`, branch: 'main' });
|
|
191
|
+
expect((opened.content as Array<{ type: string; text: string }>)[0].text).toContain('embedUrl');
|
|
192
|
+
const read = await host.callTool({ name: 'read_file', arguments: { path: 'Data/Thing.md' } });
|
|
193
|
+
expect(read.structuredContent).toBeUndefined();
|
|
194
|
+
}, 30_000);
|
|
195
|
+
|
|
196
|
+
it('declares the resources capability when it does', async () => {
|
|
197
|
+
const host = await connect();
|
|
198
|
+
expect(host.getServerCapabilities()?.resources).toBeDefined();
|
|
199
|
+
}, 30_000);
|
|
200
|
+
});
|