@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
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import type { Server as HttpServer } from 'node:http';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { createToolHandlerFactory } from '../tool-handler.js';
|
|
5
|
+
import { declareRouteTool, routeToolName, routeToolSchemas } from '../route-tool-schemas.js';
|
|
6
|
+
import { toolDef } from '../tool-def.js';
|
|
7
|
+
import type { ToolContext } from '../tool.contract.js';
|
|
8
|
+
import type { ToolAuth } from '../../tool-auth/tool-auth.middleware.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The route's argument check at the level of the helper that runs it: what it
|
|
12
|
+
* does with a tool nothing declared, what it leaves to the tool's own refusals,
|
|
13
|
+
* and that it never touches the arguments of a call that matches.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
let server: HttpServer | undefined;
|
|
17
|
+
const calls: Array<Record<string, unknown>> = [];
|
|
18
|
+
|
|
19
|
+
afterEach(async () => {
|
|
20
|
+
// A spy on `console.warn` is restored here, not at the end of its test, so
|
|
21
|
+
// a failing assertion cannot leave warnings silenced for the rest of the file.
|
|
22
|
+
vi.restoreAllMocks();
|
|
23
|
+
if (server) await new Promise<void>((r) => server!.close(() => r()));
|
|
24
|
+
server = undefined;
|
|
25
|
+
calls.length = 0;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/** One route per tool name, mounted exactly as a module (or a deployment) mounts it. */
|
|
29
|
+
async function mount(...tools: string[]): Promise<string> {
|
|
30
|
+
const toolHandler = createToolHandlerFactory(
|
|
31
|
+
async (auth: ToolAuth, abortSignal: AbortSignal): Promise<ToolContext> =>
|
|
32
|
+
({ user: { id: 'u', email: 'e@x.io', name: 'N' }, scope: auth.scope, source: auth.source, abortSignal }) as unknown as ToolContext,
|
|
33
|
+
);
|
|
34
|
+
const app = express();
|
|
35
|
+
app.use(express.json());
|
|
36
|
+
for (const tool of tools) {
|
|
37
|
+
app.post(
|
|
38
|
+
`/api/agent/tools/${tool}`,
|
|
39
|
+
(req, _res, next) => {
|
|
40
|
+
req.toolAuth = { source: 'external', userId: 'u', scope: 'write' };
|
|
41
|
+
next();
|
|
42
|
+
},
|
|
43
|
+
toolHandler(async (args) => {
|
|
44
|
+
calls.push(args);
|
|
45
|
+
return { ran: tool, args };
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
server = await new Promise<HttpServer>((r) => {
|
|
50
|
+
const s = app.listen(0, '127.0.0.1', () => r(s));
|
|
51
|
+
});
|
|
52
|
+
return `http://127.0.0.1:${(server.address() as { port: number }).port}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const post = (base: string, tool: string, body: unknown) =>
|
|
56
|
+
fetch(`${base}/api/agent/tools/${tool}`, {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: { 'content-type': 'application/json', authorization: 'Bearer k' },
|
|
59
|
+
body: JSON.stringify(body),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('routeToolName', () => {
|
|
63
|
+
it('is the last segment of the route, query and trailing slash aside', () => {
|
|
64
|
+
expect(routeToolName('/api/agent/tools/write_file')).toBe('write_file');
|
|
65
|
+
expect(routeToolName('/agent/tools/grep/')).toBe('grep');
|
|
66
|
+
expect(routeToolName('/api/agent/tools/grep?x=1')).toBe('grep');
|
|
67
|
+
expect(routeToolName('/')).toBe('');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('a tool declared with `toolDef`', () => {
|
|
72
|
+
it('is checked by its route without the module saying so', async () => {
|
|
73
|
+
toolDef({
|
|
74
|
+
name: 'declared_by_tooldef',
|
|
75
|
+
description: 'A tool a deployment adds.',
|
|
76
|
+
path: '/api/agent/tools/declared_by_tooldef',
|
|
77
|
+
inputs: {
|
|
78
|
+
type: 'object',
|
|
79
|
+
properties: { q: { type: 'string', description: 'What to look for.' } },
|
|
80
|
+
required: ['q'],
|
|
81
|
+
additionalProperties: false,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
const base = await mount('declared_by_tooldef');
|
|
85
|
+
const res = await post(base, 'declared_by_tooldef', {});
|
|
86
|
+
expect(res.status).toBe(400);
|
|
87
|
+
const body = (await res.json()) as { error: string; kind: string };
|
|
88
|
+
expect(body.kind).toBe('arguments-do-not-match');
|
|
89
|
+
expect(body.error).toContain('"q" is required, and was not given.');
|
|
90
|
+
expect(body.error).toContain('q (string, required) — What to look for.');
|
|
91
|
+
expect(body.error.split('\n').pop()).toBe('Call: KNOWLEDGE_BASE.declared_by_tooldef({ body: { q: "..." } })');
|
|
92
|
+
expect(calls).toEqual([]);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('receives a matching call with exactly the arguments that were sent', async () => {
|
|
96
|
+
toolDef({
|
|
97
|
+
name: 'untouched_arguments',
|
|
98
|
+
description: 'A tool that reports what it was given.',
|
|
99
|
+
path: '/api/agent/tools/untouched_arguments',
|
|
100
|
+
inputs: {
|
|
101
|
+
type: 'object',
|
|
102
|
+
properties: { q: { type: 'string' }, limit: { type: 'integer' }, deep: { type: 'object', properties: {} } },
|
|
103
|
+
required: ['q'],
|
|
104
|
+
additionalProperties: false,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
const base = await mount('untouched_arguments');
|
|
108
|
+
const sent = { q: 'hello', limit: 3, deep: { a: 1 } };
|
|
109
|
+
const res = await post(base, 'untouched_arguments', sent);
|
|
110
|
+
expect(res.status).toBe(200);
|
|
111
|
+
expect(calls).toEqual([sent]);
|
|
112
|
+
expect(Object.keys(calls[0])).toEqual(['q', 'limit', 'deep']);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('a tool with nothing to check against', () => {
|
|
117
|
+
it('is called unchecked, and the reason is logged once for that tool', async () => {
|
|
118
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
119
|
+
const base = await mount('nobody_declared_me');
|
|
120
|
+
expect((await post(base, 'nobody_declared_me', { whatever: 1 })).status).toBe(200);
|
|
121
|
+
expect((await post(base, 'nobody_declared_me', { whatever: 1 })).status).toBe(200);
|
|
122
|
+
expect(calls).toHaveLength(2);
|
|
123
|
+
const mine = warn.mock.calls.filter((c) => c.join(' ').includes('nobody_declared_me'));
|
|
124
|
+
expect(mine).toHaveLength(1);
|
|
125
|
+
expect(mine[0].join(' ')).toContain('no input schema is declared for its route');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('is called unchecked when the schema uses a keyword the check cannot reason about', async () => {
|
|
129
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
130
|
+
declareRouteTool('uncheckable_schema', { anyOf: [{ type: 'object' }, { type: 'string' }] } as never);
|
|
131
|
+
const base = await mount('uncheckable_schema');
|
|
132
|
+
expect((await post(base, 'uncheckable_schema', { anything: true })).status).toBe(200);
|
|
133
|
+
const mine = warn.mock.calls.filter((c) => c.join(' ').includes('uncheckable_schema'));
|
|
134
|
+
expect(mine).toHaveLength(1);
|
|
135
|
+
expect(mine[0].join(' ')).toContain('anyOf');
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
describe('a call made in the wrong shape', () => {
|
|
140
|
+
it('refuses a flat call to a tool whose arguments are all optional, instead of running it on defaults', async () => {
|
|
141
|
+
// Over the http protocol a flat call's arguments ride the query string
|
|
142
|
+
// and the body is empty — which matches an all-optional tool as `{}`.
|
|
143
|
+
declareRouteTool('all_optional', {
|
|
144
|
+
type: 'object',
|
|
145
|
+
properties: { branch: { type: 'string' }, limit: { type: 'integer' } },
|
|
146
|
+
additionalProperties: false,
|
|
147
|
+
} as never);
|
|
148
|
+
const base = await mount('all_optional');
|
|
149
|
+
const res = await fetch(`${base}/api/agent/tools/all_optional?branch=main`, {
|
|
150
|
+
method: 'POST',
|
|
151
|
+
headers: { 'content-type': 'application/json', authorization: 'Bearer k' },
|
|
152
|
+
body: '{}',
|
|
153
|
+
});
|
|
154
|
+
expect(res.status).toBe(400);
|
|
155
|
+
const body = (await res.json()) as { kind: string; error: string };
|
|
156
|
+
expect(body.kind).toBe('arguments-do-not-match');
|
|
157
|
+
expect(body.error).toContain('This tool takes its arguments under "body", not at the top level.');
|
|
158
|
+
expect(calls).toHaveLength(0);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('refuses a flat call to a tool that requires a branch the same way, rather than as a missing branch', async () => {
|
|
162
|
+
declareRouteTool('flat_with_branch', {
|
|
163
|
+
type: 'object',
|
|
164
|
+
properties: { branch: { type: 'string' }, path: { type: 'string' } },
|
|
165
|
+
required: ['branch', 'path'],
|
|
166
|
+
additionalProperties: false,
|
|
167
|
+
} as never);
|
|
168
|
+
const base = await mount('flat_with_branch');
|
|
169
|
+
const res = await fetch(`${base}/api/agent/tools/flat_with_branch?branch=main&path=a.md`, {
|
|
170
|
+
method: 'POST',
|
|
171
|
+
headers: { 'content-type': 'application/json', authorization: 'Bearer k' },
|
|
172
|
+
body: '{}',
|
|
173
|
+
});
|
|
174
|
+
expect(res.status).toBe(400);
|
|
175
|
+
expect(((await res.json()) as { error: string }).error.split('\n')[1]).toBe(
|
|
176
|
+
'This tool takes its arguments under "body", not at the top level.',
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe('a call whose URL also carries a query string', () => {
|
|
182
|
+
it('runs when the body supplies the argument the query string repeats', async () => {
|
|
183
|
+
declareRouteTool('query_echo', {
|
|
184
|
+
type: 'object',
|
|
185
|
+
properties: { branch: { type: 'string' }, limit: { type: 'integer' } },
|
|
186
|
+
additionalProperties: false,
|
|
187
|
+
} as never);
|
|
188
|
+
const base = await mount('query_echo');
|
|
189
|
+
const res = await fetch(`${base}/api/agent/tools/query_echo?branch=main`, {
|
|
190
|
+
method: 'POST',
|
|
191
|
+
headers: { 'content-type': 'application/json', authorization: 'Bearer k' },
|
|
192
|
+
body: JSON.stringify({ branch: 'main', limit: 2 }),
|
|
193
|
+
});
|
|
194
|
+
expect(res.status).toBe(200);
|
|
195
|
+
expect(calls).toEqual([{ branch: 'main', limit: 2 }]);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe('routes that overlap', () => {
|
|
200
|
+
it('check a request against the route that fits it best, not the one declared first', async () => {
|
|
201
|
+
toolDef({
|
|
202
|
+
name: 'short_overlap',
|
|
203
|
+
description: 'Declared at the shorter route, first.',
|
|
204
|
+
path: '/overlap_tool',
|
|
205
|
+
inputs: { type: 'object', properties: { a: { type: 'string' } }, required: ['a'], additionalProperties: false },
|
|
206
|
+
});
|
|
207
|
+
toolDef({
|
|
208
|
+
name: 'overlap_tool',
|
|
209
|
+
description: 'Declared at the longer route, second.',
|
|
210
|
+
path: '/api/agent/tools/overlap_tool',
|
|
211
|
+
inputs: { type: 'object', properties: { b: { type: 'string' } }, required: ['b'], additionalProperties: false },
|
|
212
|
+
});
|
|
213
|
+
const base = await mount('overlap_tool');
|
|
214
|
+
expect((await post(base, 'overlap_tool', { b: 'x' })).status).toBe(200);
|
|
215
|
+
const res = await post(base, 'overlap_tool', { a: 'x' });
|
|
216
|
+
expect(res.status).toBe(400);
|
|
217
|
+
expect(((await res.json()) as { error: string }).error).toContain('The arguments do not match the "overlap_tool" tool.');
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
describe('a tool whose route does not end in its name', () => {
|
|
222
|
+
it('is found by its route and checked under its own name', async () => {
|
|
223
|
+
toolDef({
|
|
224
|
+
name: 'named_apart',
|
|
225
|
+
description: 'A tool hosted at a route of another name.',
|
|
226
|
+
path: '/api/things/personal',
|
|
227
|
+
inputs: { type: 'object', properties: {}, additionalProperties: false },
|
|
228
|
+
});
|
|
229
|
+
const toolHandler = createToolHandlerFactory(
|
|
230
|
+
async (auth: ToolAuth, abortSignal: AbortSignal): Promise<ToolContext> =>
|
|
231
|
+
({ user: { id: 'u' }, scope: auth.scope, source: auth.source, abortSignal }) as unknown as ToolContext,
|
|
232
|
+
);
|
|
233
|
+
const app = express();
|
|
234
|
+
app.use(express.json());
|
|
235
|
+
// Mounted on a router, as the modules mount theirs: the handler sees only
|
|
236
|
+
// the part of the path below `/api`, and must still find the tool.
|
|
237
|
+
const router = express.Router();
|
|
238
|
+
router.post(
|
|
239
|
+
'/things/personal',
|
|
240
|
+
(req, _res, next) => {
|
|
241
|
+
req.toolAuth = { source: 'external', userId: 'u', scope: 'write' };
|
|
242
|
+
next();
|
|
243
|
+
},
|
|
244
|
+
toolHandler(async (args) => {
|
|
245
|
+
calls.push(args);
|
|
246
|
+
return { ok: true };
|
|
247
|
+
}),
|
|
248
|
+
);
|
|
249
|
+
app.use('/api', router);
|
|
250
|
+
server = await new Promise<HttpServer>((r) => {
|
|
251
|
+
const s = app.listen(0, '127.0.0.1', () => r(s));
|
|
252
|
+
});
|
|
253
|
+
const base = `http://127.0.0.1:${(server.address() as { port: number }).port}`;
|
|
254
|
+
const res = await fetch(`${base}/api/things/personal`, {
|
|
255
|
+
method: 'POST',
|
|
256
|
+
headers: { 'content-type': 'application/json' },
|
|
257
|
+
body: JSON.stringify({ stray: 1 }),
|
|
258
|
+
});
|
|
259
|
+
expect(res.status).toBe(400);
|
|
260
|
+
const body = (await res.json()) as { error: string };
|
|
261
|
+
expect(body.error).toContain('The arguments do not match the "named_apart" tool.');
|
|
262
|
+
expect(body.error).toContain('"stray" is not an argument of this tool.');
|
|
263
|
+
expect(calls).toHaveLength(0);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
describe('what the check says nothing about', () => {
|
|
268
|
+
it('leaves `branch` to the one refusal that names it — absent, empty or a stringified nothing', async () => {
|
|
269
|
+
declareRouteTool('needs_a_branch', {
|
|
270
|
+
type: 'object',
|
|
271
|
+
properties: { branch: { type: 'string' }, path: { type: 'string' } },
|
|
272
|
+
required: ['branch', 'path'],
|
|
273
|
+
additionalProperties: false,
|
|
274
|
+
} as never);
|
|
275
|
+
const base = await mount('needs_a_branch');
|
|
276
|
+
for (const branch of [undefined, '', null, 42, ['main'], 'undefined', 'null']) {
|
|
277
|
+
const res = await post(base, 'needs_a_branch', { path: 'a.md', ...(branch === undefined ? {} : { branch }) });
|
|
278
|
+
// Forwarded, so the handler's own `branch-required` answers — and with a
|
|
279
|
+
// valid branch the same call would be checked like any other.
|
|
280
|
+
expect(res.status, String(branch)).toBe(200);
|
|
281
|
+
}
|
|
282
|
+
expect(calls).toHaveLength(7);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('leaves an argument the tool refuses by name to the tool', async () => {
|
|
286
|
+
toolDef({
|
|
287
|
+
name: 'refuses_its_own_name',
|
|
288
|
+
description: 'A tool with a refusal of its own.',
|
|
289
|
+
path: '/api/agent/tools/refuses_its_own_name',
|
|
290
|
+
inputs: {
|
|
291
|
+
type: 'object',
|
|
292
|
+
properties: { name: { type: 'string' }, other: { type: 'string' } },
|
|
293
|
+
required: ['name', 'other'],
|
|
294
|
+
additionalProperties: false,
|
|
295
|
+
},
|
|
296
|
+
refusesItself: ['name'],
|
|
297
|
+
});
|
|
298
|
+
expect(routeToolSchemas('refuses_its_own_name')?.refusesItself.has('name')).toBe(true);
|
|
299
|
+
const base = await mount('refuses_its_own_name');
|
|
300
|
+
// Only `name` is missing: forwarded, so the tool's own message answers.
|
|
301
|
+
expect((await post(base, 'refuses_its_own_name', { other: 'o' })).status).toBe(200);
|
|
302
|
+
// `other` is missing too, and that one IS reported.
|
|
303
|
+
const res = await post(base, 'refuses_its_own_name', { name: 'n' });
|
|
304
|
+
expect(res.status).toBe(400);
|
|
305
|
+
const body = (await res.json()) as { error: string };
|
|
306
|
+
expect(body.error).toContain('"other" is required, and was not given.');
|
|
307
|
+
expect(body.error).not.toContain('"name" is required');
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('filters by the whole quoted name: a dotted argument is not its first segment, and a nested line is kept', async () => {
|
|
311
|
+
toolDef({
|
|
312
|
+
name: 'refuses_by_whole_name',
|
|
313
|
+
description: 'A tool whose refused argument is the first segment of another, and the name of a nested object.',
|
|
314
|
+
path: '/api/agent/tools/refuses_by_whole_name',
|
|
315
|
+
inputs: {
|
|
316
|
+
type: 'object',
|
|
317
|
+
properties: {
|
|
318
|
+
a: { type: 'string' },
|
|
319
|
+
'a.b': { type: 'string' },
|
|
320
|
+
body: { type: 'object', properties: { path: { type: 'string' } }, required: ['path'] },
|
|
321
|
+
},
|
|
322
|
+
required: ['a', 'a.b', 'body'],
|
|
323
|
+
additionalProperties: false,
|
|
324
|
+
},
|
|
325
|
+
refusesItself: ['a', 'body'],
|
|
326
|
+
});
|
|
327
|
+
const base = await mount('refuses_by_whole_name');
|
|
328
|
+
const res = await post(base, 'refuses_by_whole_name', { body: {} });
|
|
329
|
+
expect(res.status).toBe(400);
|
|
330
|
+
const body = (await res.json()) as { error: string };
|
|
331
|
+
// `a` is the tool's own; `a.b` is another argument and IS reported…
|
|
332
|
+
expect(body.error).not.toContain('"a" is required');
|
|
333
|
+
expect(body.error).toContain('"a.b" is required, and was not given.');
|
|
334
|
+
// …and a line about `body.path` is about `body.path`, not about `body`.
|
|
335
|
+
expect(body.error).toContain('"body.path" is required, and was not given.');
|
|
336
|
+
});
|
|
337
|
+
});
|
|
@@ -11,8 +11,41 @@
|
|
|
11
11
|
* const ctx = await validateToken(bearerToken, body); // verify + resolve, throws ToolError
|
|
12
12
|
* const fs = await ctx.getFilesystem(); // lock-aware (write) / read-only (read)
|
|
13
13
|
* const def = toolDef({ name, description, inputs, path }); // self-describing UTCP Tool to register
|
|
14
|
+
*
|
|
15
|
+
* ## The branch
|
|
16
|
+
*
|
|
17
|
+
* A tool that works on a knowledge-base branch declares how, and the tool
|
|
18
|
+
* handler resolves the branch before the tool runs — the tool itself carries
|
|
19
|
+
* no guard and reads the result from `ctx.branch`:
|
|
20
|
+
*
|
|
21
|
+
* toolDef({ name, description, inputs, path, branch: 'required' });
|
|
22
|
+
* toolDef({ name, description, inputs, path, branch: 'defaults-to-default-branch' });
|
|
23
|
+
*
|
|
24
|
+
* - `required` (what a tool whose `inputs` require `branch` gets without
|
|
25
|
+
* saying so): a call without a branch, or with an empty or non-string one,
|
|
26
|
+
* is answered 400 `branch-required` and the tool does not run.
|
|
27
|
+
* - `defaults-to-default-branch`, for a READ-ONLY tool: a call without a
|
|
28
|
+
* branch runs on the deployment's default branch, the input schema shows
|
|
29
|
+
* `branch` as optional and says so, and an object answer without a
|
|
30
|
+
* `branch` field gets one naming the branch used. A deployment with no
|
|
31
|
+
* default branch configured answers such a call 503
|
|
32
|
+
* `default-branch-unset`. A writing tool (`write: true`, or a `write`
|
|
33
|
+
* tag) that declares it makes `toolDef` throw at startup, naming the tool.
|
|
34
|
+
* - neither, with no `branch` in `inputs`: the tool takes no branch. A stray
|
|
35
|
+
* `branch` in a call is refused by the argument check when the schema
|
|
36
|
+
* forbids extra arguments (every platform tool's does), and dropped before
|
|
37
|
+
* the tool runs when the schema leaves extras open.
|
|
38
|
+
*
|
|
39
|
+
* Under either branch declaration, a given branch that does not exist is
|
|
40
|
+
* answered 404 `branch-not-found`, naming it, before the tool runs.
|
|
14
41
|
*/
|
|
15
42
|
export { createToolValidator, type ValidateToken, type ToolValidatorDeps } from './validate-token.js';
|
|
16
|
-
export {
|
|
43
|
+
export {
|
|
44
|
+
toolDef,
|
|
45
|
+
BRANCH_INPUT,
|
|
46
|
+
DEFAULTED_BRANCH_INPUT,
|
|
47
|
+
type ToolDefSpec,
|
|
48
|
+
type BranchDeclaration,
|
|
49
|
+
} from './tool-def.js';
|
|
17
50
|
export { ToolError, hasHttpStatus, type ToolContext, type ToolHandler } from './tool.contract.js';
|
|
18
51
|
export type { JsonSchema, UtcpTool } from '../tool-registry/tool.contract.js';
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ARGS_UNDER_BODY_LINE,
|
|
3
|
+
ARGUMENTS_DO_NOT_MATCH_KIND,
|
|
4
|
+
argumentsDoNotMatchMessage,
|
|
5
|
+
checkFor,
|
|
6
|
+
} from '@bevel-software/platform-mcp-core';
|
|
7
|
+
import { EXTERNAL_KB_MANUAL_NAME } from '../tool-manuals/tool-manuals.contract.js';
|
|
8
|
+
import { branchProvided } from '../../shared/domain-errors.js';
|
|
9
|
+
import { logger } from '../../shared/logging.js';
|
|
10
|
+
import { ToolError } from './tool.contract.js';
|
|
11
|
+
import { routeToolName, routeToolSchemasForRequest } from './route-tool-schemas.js';
|
|
12
|
+
import { DEFAULTED_BRANCH_INPUT } from './tool-def.js';
|
|
13
|
+
|
|
14
|
+
const log = logger('tools');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The argument check of a tool THIS SERVER HOSTS AS A ROUTE, run in that
|
|
18
|
+
* route's handler.
|
|
19
|
+
*
|
|
20
|
+
* It lives here, and not in the MCP layer, because the route is the one place
|
|
21
|
+
* every caller of such a tool arrives at: an agent over MCP, a `call_tool_chain`
|
|
22
|
+
* chain, the in-process agent over loopback, and a runner or script calling
|
|
23
|
+
* `POST /api/agent/tools/<name>` with a connection key. A check one layer up
|
|
24
|
+
* covered the first two and left the last answering a 500 for a missing
|
|
25
|
+
* argument, or — worse — running: `grep` without a `pattern` matched every file
|
|
26
|
+
* in the knowledge base.
|
|
27
|
+
*
|
|
28
|
+
* The arguments are checked FLAT, which is what the handler receives and what a
|
|
29
|
+
* script sends. The call example at the end of the refusal is generated from the
|
|
30
|
+
* wire schema instead, so the line an agent is invited to copy is the line it
|
|
31
|
+
* would really type.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/** Tools called without a check, so the reason is logged once each (never per call). */
|
|
35
|
+
const unchecked = new Set<string>();
|
|
36
|
+
|
|
37
|
+
function noteUnchecked(toolName: string, reason: string): null {
|
|
38
|
+
if (!unchecked.has(toolName)) {
|
|
39
|
+
unchecked.add(toolName);
|
|
40
|
+
log.warn(
|
|
41
|
+
`calling "${toolName}" without checking its arguments — ${reason}. Its calls are passed through as they are.`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The names the tool declares at its top level. Used only to recognise the
|
|
49
|
+
* mirror-image wrong shape below; nothing is checked against it.
|
|
50
|
+
*/
|
|
51
|
+
function declaredNames(flat: unknown): string[] {
|
|
52
|
+
const properties = (flat as { properties?: unknown }).properties;
|
|
53
|
+
return typeof properties === 'object' && properties !== null ? Object.keys(properties) : [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Does this tool require a `branch`? Read off its own declaration, never assumed. */
|
|
57
|
+
function requiresBranch(flat: unknown): boolean {
|
|
58
|
+
const required = (flat as { required?: unknown }).required;
|
|
59
|
+
return Array.isArray(required) && required.includes('branch');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Does this tool declare `defaults-to-default-branch`? Its `branch` is then the defaulted input. */
|
|
63
|
+
function defaultsBranch(flat: unknown): boolean {
|
|
64
|
+
return (flat as { properties?: Record<string, unknown> }).properties?.branch === DEFAULTED_BRANCH_INPUT;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Did this call pass the tool's arguments at the top level, to a tool that takes
|
|
69
|
+
* them under `body`?
|
|
70
|
+
*
|
|
71
|
+
* The http protocol sends the argument named by the template's `body_field`
|
|
72
|
+
* (`body`, for every tool `toolDef` declares) as the request body and EVERY
|
|
73
|
+
* OTHER argument as a query parameter. So a flat call to one of these tools
|
|
74
|
+
* arrives with an empty body and the arguments in the query string — which is
|
|
75
|
+
* what this recognises, so the refusal can name the mistake instead of listing
|
|
76
|
+
* every argument as missing and leaving the agent to guess why.
|
|
77
|
+
*/
|
|
78
|
+
function argumentsCameAsQuery(flat: unknown, query: unknown, args: Record<string, unknown>): boolean {
|
|
79
|
+
if (typeof query !== 'object' || query === null) return false;
|
|
80
|
+
const sent = Object.keys(query as Record<string, unknown>);
|
|
81
|
+
if (sent.length === 0) return false;
|
|
82
|
+
const names = new Set(declaredNames(flat));
|
|
83
|
+
// An argument the body DOES carry was not misplaced, whatever else the URL
|
|
84
|
+
// holds: only one that reached the route by the query string alone was.
|
|
85
|
+
// An OWN property of the body: `?toString=` would otherwise read as carried
|
|
86
|
+
// by an empty `{}` through its prototype, and the tool would run without it.
|
|
87
|
+
return sent.some((name) => names.has(name) && !Object.prototype.hasOwnProperty.call(args, name));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The refusal this call deserves, or `null` when the arguments match the tool
|
|
92
|
+
* (or when it has nothing to check them against, which is logged once).
|
|
93
|
+
*
|
|
94
|
+
* Never changes the call: a checker that repaired arguments would hide the
|
|
95
|
+
* mistake it exists to report.
|
|
96
|
+
*/
|
|
97
|
+
export function argumentsRefusal(
|
|
98
|
+
requestPath: string,
|
|
99
|
+
args: Record<string, unknown>,
|
|
100
|
+
query?: unknown,
|
|
101
|
+
): ToolError | null {
|
|
102
|
+
const schemas = routeToolSchemasForRequest(requestPath);
|
|
103
|
+
if (!schemas) return noteUnchecked(routeToolName(requestPath), 'no input schema is declared for its route');
|
|
104
|
+
const toolName = schemas.name;
|
|
105
|
+
const check = checkFor(schemas.flat);
|
|
106
|
+
if (!check.checkable) return noteUnchecked(toolName, check.reason);
|
|
107
|
+
// The shape first, before anything may wave the call through: arguments
|
|
108
|
+
// passed flat reach this route as query parameters and leave the body
|
|
109
|
+
// empty, so a call whose arguments are all optional would otherwise MATCH —
|
|
110
|
+
// as `{}` — and run on defaults, silently dropping what was passed.
|
|
111
|
+
const cameAsQuery = argumentsCameAsQuery(schemas.flat, query, args);
|
|
112
|
+
// A call that names no branch is answered by the refusal that NAMES it, and
|
|
113
|
+
// that refusal comes first, exactly as it does today. It says what a branch
|
|
114
|
+
// is and what to pass, and it is one message rather than a list; putting a
|
|
115
|
+
// second fault ahead of it would replace an answer the caller can act on
|
|
116
|
+
// with one it has to read twice. Whatever else is wrong with such a call is
|
|
117
|
+
// reported on the next one, which at least names its workspace.
|
|
118
|
+
// A tool that defaults its branch is defaulted only when the branch is
|
|
119
|
+
// ABSENT; an empty or non-string one gets the same refusal by name.
|
|
120
|
+
if (!cameAsQuery && !branchProvided(args.branch)) {
|
|
121
|
+
if (requiresBranch(schemas.flat)) return null;
|
|
122
|
+
if (args.branch !== undefined && defaultsBranch(schemas.flat)) return null;
|
|
123
|
+
}
|
|
124
|
+
// A mismatch about an argument the tool refuses itself is dropped, so the
|
|
125
|
+
// tool's own message — which says what that argument is FOR — is the one the
|
|
126
|
+
// caller reads. Every mismatch line opens with the argument it is about.
|
|
127
|
+
const mismatches = check
|
|
128
|
+
.check(args)
|
|
129
|
+
// The whole quoted name: an argument may carry a dot of its own, and a
|
|
130
|
+
// nested line (`"body.path"`) names nothing in `refusesItself` anyway.
|
|
131
|
+
.filter((line) => !schemas.refusesItself.has(/^"([^"]+)"/.exec(line)?.[1] ?? ''));
|
|
132
|
+
// The shape first, when that is what went wrong: the lines below (every
|
|
133
|
+
// required argument missing) are its symptoms, not the mistake.
|
|
134
|
+
if (cameAsQuery) mismatches.unshift(ARGS_UNDER_BODY_LINE);
|
|
135
|
+
if (mismatches.length === 0) return null;
|
|
136
|
+
// The namespace of the example is the one manual the whole catalog is served
|
|
137
|
+
// as, so the line matches the `Call:` line at the top of this tool's own
|
|
138
|
+
// description. A connection that renames the manual (the local stdio server
|
|
139
|
+
// names it after the deployment) reads a different namespace there; the
|
|
140
|
+
// arguments, which are what the refusal is about, are the same either way.
|
|
141
|
+
const message = argumentsDoNotMatchMessage(
|
|
142
|
+
toolName,
|
|
143
|
+
`${EXTERNAL_KB_MANUAL_NAME}.${toolName}`,
|
|
144
|
+
schemas.flat,
|
|
145
|
+
mismatches,
|
|
146
|
+
{ exampleInputs: schemas.wire },
|
|
147
|
+
);
|
|
148
|
+
return new ToolError(message, 400, { kind: ARGUMENTS_DO_NOT_MATCH_KIND });
|
|
149
|
+
}
|