@bevel-software/platform-core-backend 0.1.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/LICENSE +202 -0
- package/dist/assets.d.ts +5 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +23 -0
- package/dist/assets.js.map +1 -0
- package/dist/core/core-ports.d.ts +83 -0
- package/dist/core/core-ports.d.ts.map +1 -0
- package/dist/core/core-ports.js +12 -0
- package/dist/core/core-ports.js.map +1 -0
- package/dist/core/create-core-server.d.ts +62 -0
- package/dist/core/create-core-server.d.ts.map +1 -0
- package/dist/core/create-core-server.js +204 -0
- package/dist/core/create-core-server.js.map +1 -0
- package/dist/core/create-core-services.d.ts +95 -0
- package/dist/core/create-core-services.d.ts.map +1 -0
- package/dist/core/create-core-services.js +352 -0
- package/dist/core/create-core-services.js.map +1 -0
- package/dist/core-config.d.ts +119 -0
- package/dist/core-config.d.ts.map +1 -0
- package/dist/core-config.js +240 -0
- package/dist/core-config.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/access/access-control.interface.d.ts +348 -0
- package/dist/modules/access/access-control.interface.d.ts.map +1 -0
- package/dist/modules/access/access-control.interface.js +2 -0
- package/dist/modules/access/access-control.interface.js.map +1 -0
- package/dist/modules/access/access-control.service.d.ts +323 -0
- package/dist/modules/access/access-control.service.d.ts.map +1 -0
- package/dist/modules/access/access-control.service.js +1431 -0
- package/dist/modules/access/access-control.service.js.map +1 -0
- package/dist/modules/access/access-errors.d.ts +34 -0
- package/dist/modules/access/access-errors.d.ts.map +1 -0
- package/dist/modules/access/access-errors.js +40 -0
- package/dist/modules/access/access-errors.js.map +1 -0
- package/dist/modules/access/access-mutation.service.d.ts +176 -0
- package/dist/modules/access/access-mutation.service.d.ts.map +1 -0
- package/dist/modules/access/access-mutation.service.js +307 -0
- package/dist/modules/access/access-mutation.service.js.map +1 -0
- package/dist/modules/access/access-splice.d.ts +98 -0
- package/dist/modules/access/access-splice.d.ts.map +1 -0
- package/dist/modules/access/access-splice.js +346 -0
- package/dist/modules/access/access-splice.js.map +1 -0
- package/dist/modules/access/access.routes.d.ts +10 -0
- package/dist/modules/access/access.routes.d.ts.map +1 -0
- package/dist/modules/access/access.routes.js +757 -0
- package/dist/modules/access/access.routes.js.map +1 -0
- package/dist/modules/access/creator-access.d.ts +113 -0
- package/dist/modules/access/creator-access.d.ts.map +1 -0
- package/dist/modules/access/creator-access.js +212 -0
- package/dist/modules/access/creator-access.js.map +1 -0
- package/dist/modules/access/kb-read-filter.d.ts +41 -0
- package/dist/modules/access/kb-read-filter.d.ts.map +1 -0
- package/dist/modules/access/kb-read-filter.js +60 -0
- package/dist/modules/access/kb-read-filter.js.map +1 -0
- package/dist/modules/access/roles-admin.service.d.ts +240 -0
- package/dist/modules/access/roles-admin.service.d.ts.map +1 -0
- package/dist/modules/access/roles-admin.service.js +630 -0
- package/dist/modules/access/roles-admin.service.js.map +1 -0
- package/dist/modules/access/roles-edit.d.ts +91 -0
- package/dist/modules/access/roles-edit.d.ts.map +1 -0
- package/dist/modules/access/roles-edit.js +232 -0
- package/dist/modules/access/roles-edit.js.map +1 -0
- package/dist/modules/access/roles-yaml-guard.d.ts +56 -0
- package/dist/modules/access/roles-yaml-guard.d.ts.map +1 -0
- package/dist/modules/access/roles-yaml-guard.js +79 -0
- package/dist/modules/access/roles-yaml-guard.js.map +1 -0
- package/dist/modules/admin/admin-access.routes.d.ts +18 -0
- package/dist/modules/admin/admin-access.routes.d.ts.map +1 -0
- package/dist/modules/admin/admin-access.routes.js +26 -0
- package/dist/modules/admin/admin-access.routes.js.map +1 -0
- package/dist/modules/admin/admin-access.service.d.ts +24 -0
- package/dist/modules/admin/admin-access.service.d.ts.map +1 -0
- package/dist/modules/admin/admin-access.service.js +41 -0
- package/dist/modules/admin/admin-access.service.js.map +1 -0
- package/dist/modules/admin/admin.interface.d.ts +11 -0
- package/dist/modules/admin/admin.interface.d.ts.map +1 -0
- package/dist/modules/admin/admin.interface.js +2 -0
- package/dist/modules/admin/admin.interface.js.map +1 -0
- package/dist/modules/auth/account-erasure.service.d.ts +80 -0
- package/dist/modules/auth/account-erasure.service.d.ts.map +1 -0
- package/dist/modules/auth/account-erasure.service.js +91 -0
- package/dist/modules/auth/account-erasure.service.js.map +1 -0
- package/dist/modules/auth/auth.middleware.d.ts +23 -0
- package/dist/modules/auth/auth.middleware.d.ts.map +1 -0
- package/dist/modules/auth/auth.middleware.js +68 -0
- package/dist/modules/auth/auth.middleware.js.map +1 -0
- package/dist/modules/auth/auth.routes.d.ts +25 -0
- package/dist/modules/auth/auth.routes.d.ts.map +1 -0
- package/dist/modules/auth/auth.routes.js +72 -0
- package/dist/modules/auth/auth.routes.js.map +1 -0
- package/dist/modules/auth/auth.service.d.ts +76 -0
- package/dist/modules/auth/auth.service.d.ts.map +1 -0
- package/dist/modules/auth/auth.service.js +168 -0
- package/dist/modules/auth/auth.service.js.map +1 -0
- package/dist/modules/code-mode/code-mode-names.d.ts +16 -0
- package/dist/modules/code-mode/code-mode-names.d.ts.map +1 -0
- package/dist/modules/code-mode/code-mode-names.js +30 -0
- package/dist/modules/code-mode/code-mode-names.js.map +1 -0
- package/dist/modules/code-mode/code-mode.tool.d.ts +13 -0
- package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -0
- package/dist/modules/code-mode/code-mode.tool.js +112 -0
- package/dist/modules/code-mode/code-mode.tool.js.map +1 -0
- package/dist/modules/code-mode/index.d.ts +3 -0
- package/dist/modules/code-mode/index.d.ts.map +1 -0
- package/dist/modules/code-mode/index.js +3 -0
- package/dist/modules/code-mode/index.js.map +1 -0
- package/dist/modules/database/connection.d.ts +6 -0
- package/dist/modules/database/connection.d.ts.map +1 -0
- package/dist/modules/database/connection.js +12 -0
- package/dist/modules/database/connection.js.map +1 -0
- package/dist/modules/database/core-schema.d.ts +2273 -0
- package/dist/modules/database/core-schema.d.ts.map +1 -0
- package/dist/modules/database/core-schema.js +413 -0
- package/dist/modules/database/core-schema.js.map +1 -0
- package/dist/modules/database/migrate.d.ts +10 -0
- package/dist/modules/database/migrate.d.ts.map +1 -0
- package/dist/modules/database/migrate.js +40 -0
- package/dist/modules/database/migrate.js.map +1 -0
- package/dist/modules/database/schema.d.ts +12 -0
- package/dist/modules/database/schema.d.ts.map +1 -0
- package/dist/modules/database/schema.js +12 -0
- package/dist/modules/database/schema.js.map +1 -0
- package/dist/modules/diff/diff-paths.d.ts +2 -0
- package/dist/modules/diff/diff-paths.d.ts.map +1 -0
- package/dist/modules/diff/diff-paths.js +9 -0
- package/dist/modules/diff/diff-paths.js.map +1 -0
- package/dist/modules/diff/diff.config.d.ts +8 -0
- package/dist/modules/diff/diff.config.d.ts.map +1 -0
- package/dist/modules/diff/diff.config.js +13 -0
- package/dist/modules/diff/diff.config.js.map +1 -0
- package/dist/modules/diff/diff.interface.d.ts +73 -0
- package/dist/modules/diff/diff.interface.d.ts.map +1 -0
- package/dist/modules/diff/diff.interface.js +2 -0
- package/dist/modules/diff/diff.interface.js.map +1 -0
- package/dist/modules/diff/diff.routes.d.ts +35 -0
- package/dist/modules/diff/diff.routes.d.ts.map +1 -0
- package/dist/modules/diff/diff.routes.js +228 -0
- package/dist/modules/diff/diff.routes.js.map +1 -0
- package/dist/modules/diff/diff.service.d.ts +51 -0
- package/dist/modules/diff/diff.service.d.ts.map +1 -0
- package/dist/modules/diff/diff.service.js +489 -0
- package/dist/modules/diff/diff.service.js.map +1 -0
- package/dist/modules/diff/line-diff.d.ts +16 -0
- package/dist/modules/diff/line-diff.d.ts.map +1 -0
- package/dist/modules/diff/line-diff.js +67 -0
- package/dist/modules/diff/line-diff.js.map +1 -0
- package/dist/modules/mcp/mcp-auth.middleware.d.ts +27 -0
- package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -0
- package/dist/modules/mcp/mcp-auth.middleware.js +116 -0
- package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -0
- package/dist/modules/mcp/mcp-session-store.d.ts +74 -0
- package/dist/modules/mcp/mcp-session-store.d.ts.map +1 -0
- package/dist/modules/mcp/mcp-session-store.js +131 -0
- package/dist/modules/mcp/mcp-session-store.js.map +1 -0
- package/dist/modules/mcp/mcp.routes.d.ts +24 -0
- package/dist/modules/mcp/mcp.routes.d.ts.map +1 -0
- package/dist/modules/mcp/mcp.routes.js +229 -0
- package/dist/modules/mcp/mcp.routes.js.map +1 -0
- package/dist/modules/mcp/mcp.service.d.ts +198 -0
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -0
- package/dist/modules/mcp/mcp.service.js +840 -0
- package/dist/modules/mcp/mcp.service.js.map +1 -0
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +76 -0
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -0
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js +291 -0
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -0
- package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +18 -0
- package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -0
- package/dist/modules/mcp/oauth/oauth-consent.routes.js +52 -0
- package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -0
- package/dist/modules/mcp/oauth/oauth-state.d.ts +32 -0
- package/dist/modules/mcp/oauth/oauth-state.d.ts.map +1 -0
- package/dist/modules/mcp/oauth/oauth-state.js +34 -0
- package/dist/modules/mcp/oauth/oauth-state.js.map +1 -0
- package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +92 -0
- package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -0
- package/dist/modules/secrets-vault/db-secrets-vault.service.js +728 -0
- package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -0
- package/dist/modules/secrets-vault/index.d.ts +7 -0
- package/dist/modules/secrets-vault/index.d.ts.map +1 -0
- package/dist/modules/secrets-vault/index.js +6 -0
- package/dist/modules/secrets-vault/index.js.map +1 -0
- package/dist/modules/secrets-vault/mcp-oauth-discovery.service.d.ts +63 -0
- package/dist/modules/secrets-vault/mcp-oauth-discovery.service.d.ts.map +1 -0
- package/dist/modules/secrets-vault/mcp-oauth-discovery.service.js +269 -0
- package/dist/modules/secrets-vault/mcp-oauth-discovery.service.js.map +1 -0
- package/dist/modules/secrets-vault/secrets-variable-loader.d.ts +46 -0
- package/dist/modules/secrets-vault/secrets-variable-loader.d.ts.map +1 -0
- package/dist/modules/secrets-vault/secrets-variable-loader.js +87 -0
- package/dist/modules/secrets-vault/secrets-variable-loader.js.map +1 -0
- package/dist/modules/secrets-vault/secrets-vault.contract.d.ts +210 -0
- package/dist/modules/secrets-vault/secrets-vault.contract.d.ts.map +1 -0
- package/dist/modules/secrets-vault/secrets-vault.contract.js +90 -0
- package/dist/modules/secrets-vault/secrets-vault.contract.js.map +1 -0
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +30 -0
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -0
- package/dist/modules/secrets-vault/secrets-vault.routes.js +490 -0
- package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -0
- package/dist/modules/skills/index.d.ts +5 -0
- package/dist/modules/skills/index.d.ts.map +1 -0
- package/dist/modules/skills/index.js +4 -0
- package/dist/modules/skills/index.js.map +1 -0
- package/dist/modules/skills/skills.contract.d.ts +58 -0
- package/dist/modules/skills/skills.contract.d.ts.map +1 -0
- package/dist/modules/skills/skills.contract.js +10 -0
- package/dist/modules/skills/skills.contract.js.map +1 -0
- package/dist/modules/skills/skills.routes.d.ts +15 -0
- package/dist/modules/skills/skills.routes.d.ts.map +1 -0
- package/dist/modules/skills/skills.routes.js +34 -0
- package/dist/modules/skills/skills.routes.js.map +1 -0
- package/dist/modules/skills/skills.service.d.ts +21 -0
- package/dist/modules/skills/skills.service.d.ts.map +1 -0
- package/dist/modules/skills/skills.service.js +202 -0
- package/dist/modules/skills/skills.service.js.map +1 -0
- package/dist/modules/skills/skills.tools.d.ts +15 -0
- package/dist/modules/skills/skills.tools.d.ts.map +1 -0
- package/dist/modules/skills/skills.tools.js +96 -0
- package/dist/modules/skills/skills.tools.js.map +1 -0
- package/dist/modules/tool-auth/external-api-key.errors.d.ts +14 -0
- package/dist/modules/tool-auth/external-api-key.errors.d.ts.map +1 -0
- package/dist/modules/tool-auth/external-api-key.errors.js +23 -0
- package/dist/modules/tool-auth/external-api-key.errors.js.map +1 -0
- package/dist/modules/tool-auth/external-api-key.interface.d.ts +90 -0
- package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -0
- package/dist/modules/tool-auth/external-api-key.interface.js +2 -0
- package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -0
- package/dist/modules/tool-auth/external-api-key.service.d.ts +25 -0
- package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -0
- package/dist/modules/tool-auth/external-api-key.service.js +164 -0
- package/dist/modules/tool-auth/external-api-key.service.js.map +1 -0
- package/dist/modules/tool-auth/internal-token.service.d.ts +62 -0
- package/dist/modules/tool-auth/internal-token.service.d.ts.map +1 -0
- package/dist/modules/tool-auth/internal-token.service.js +85 -0
- package/dist/modules/tool-auth/internal-token.service.js.map +1 -0
- package/dist/modules/tool-auth/llm-usage-meter.d.ts +16 -0
- package/dist/modules/tool-auth/llm-usage-meter.d.ts.map +1 -0
- package/dist/modules/tool-auth/llm-usage-meter.js +6 -0
- package/dist/modules/tool-auth/llm-usage-meter.js.map +1 -0
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts +101 -0
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -0
- package/dist/modules/tool-auth/tool-auth.middleware.js +166 -0
- package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -0
- package/dist/modules/tool-helpers/index.d.ts +19 -0
- package/dist/modules/tool-helpers/index.d.ts.map +1 -0
- package/dist/modules/tool-helpers/index.js +18 -0
- package/dist/modules/tool-helpers/index.js.map +1 -0
- package/dist/modules/tool-helpers/tool-context.d.ts +35 -0
- package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -0
- package/dist/modules/tool-helpers/tool-context.js +66 -0
- package/dist/modules/tool-helpers/tool-context.js.map +1 -0
- package/dist/modules/tool-helpers/tool-def.d.ts +33 -0
- package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -0
- package/dist/modules/tool-helpers/tool-def.js +57 -0
- package/dist/modules/tool-helpers/tool-def.js.map +1 -0
- package/dist/modules/tool-helpers/tool-handler.d.ts +19 -0
- package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -0
- package/dist/modules/tool-helpers/tool-handler.js +84 -0
- package/dist/modules/tool-helpers/tool-handler.js.map +1 -0
- package/dist/modules/tool-helpers/tool.contract.d.ts +64 -0
- package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -0
- package/dist/modules/tool-helpers/tool.contract.js +24 -0
- package/dist/modules/tool-helpers/tool.contract.js.map +1 -0
- package/dist/modules/tool-helpers/validate-token.d.ts +31 -0
- package/dist/modules/tool-helpers/validate-token.d.ts.map +1 -0
- package/dist/modules/tool-helpers/validate-token.js +20 -0
- package/dist/modules/tool-helpers/validate-token.js.map +1 -0
- package/dist/modules/tool-manuals/index.d.ts +5 -0
- package/dist/modules/tool-manuals/index.d.ts.map +1 -0
- package/dist/modules/tool-manuals/index.js +5 -0
- package/dist/modules/tool-manuals/index.js.map +1 -0
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +182 -0
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -0
- package/dist/modules/tool-manuals/tool-manuals.contract.js +19 -0
- package/dist/modules/tool-manuals/tool-manuals.contract.js.map +1 -0
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +24 -0
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -0
- package/dist/modules/tool-manuals/tool-manuals.routes.js +102 -0
- package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -0
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts +108 -0
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -0
- package/dist/modules/tool-manuals/tool-manuals.service.js +710 -0
- package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -0
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +35 -0
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -0
- package/dist/modules/tool-manuals/tool-manuals.tools.js +157 -0
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -0
- package/dist/modules/tool-registry/manual.routes.d.ts +6 -0
- package/dist/modules/tool-registry/manual.routes.d.ts.map +1 -0
- package/dist/modules/tool-registry/manual.routes.js +76 -0
- package/dist/modules/tool-registry/manual.routes.js.map +1 -0
- package/dist/modules/tool-registry/tool-registry.d.ts +23 -0
- package/dist/modules/tool-registry/tool-registry.d.ts.map +1 -0
- package/dist/modules/tool-registry/tool-registry.js +46 -0
- package/dist/modules/tool-registry/tool-registry.js.map +1 -0
- package/dist/modules/tool-registry/tool.contract.d.ts +48 -0
- package/dist/modules/tool-registry/tool.contract.d.ts.map +1 -0
- package/dist/modules/tool-registry/tool.contract.js +2 -0
- package/dist/modules/tool-registry/tool.contract.js.map +1 -0
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +14 -0
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -0
- package/dist/modules/workflow/agent-tools/workflow.tools.js +437 -0
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -0
- package/dist/modules/workflow/event-bus.d.ts +107 -0
- package/dist/modules/workflow/event-bus.d.ts.map +1 -0
- package/dist/modules/workflow/event-bus.js +224 -0
- package/dist/modules/workflow/event-bus.js.map +1 -0
- package/dist/modules/workflow/events.routes.d.ts +80 -0
- package/dist/modules/workflow/events.routes.d.ts.map +1 -0
- package/dist/modules/workflow/events.routes.js +216 -0
- package/dist/modules/workflow/events.routes.js.map +1 -0
- package/dist/modules/workflow/file-change-notifier.d.ts +38 -0
- package/dist/modules/workflow/file-change-notifier.d.ts.map +1 -0
- package/dist/modules/workflow/file-change-notifier.js +22 -0
- package/dist/modules/workflow/file-change-notifier.js.map +1 -0
- package/dist/modules/workflow/file-lock.service.d.ts +57 -0
- package/dist/modules/workflow/file-lock.service.d.ts.map +1 -0
- package/dist/modules/workflow/file-lock.service.js +202 -0
- package/dist/modules/workflow/file-lock.service.js.map +1 -0
- package/dist/modules/workflow/git/branch-name.d.ts +10 -0
- package/dist/modules/workflow/git/branch-name.d.ts.map +1 -0
- package/dist/modules/workflow/git/branch-name.js +76 -0
- package/dist/modules/workflow/git/branch-name.js.map +1 -0
- package/dist/modules/workflow/git/clone-config.d.ts +61 -0
- package/dist/modules/workflow/git/clone-config.d.ts.map +1 -0
- package/dist/modules/workflow/git/clone-config.js +69 -0
- package/dist/modules/workflow/git/clone-config.js.map +1 -0
- package/dist/modules/workflow/git/git-version.d.ts +34 -0
- package/dist/modules/workflow/git/git-version.d.ts.map +1 -0
- package/dist/modules/workflow/git/git-version.js +63 -0
- package/dist/modules/workflow/git/git-version.js.map +1 -0
- package/dist/modules/workflow/git/git.service.d.ts +427 -0
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -0
- package/dist/modules/workflow/git/git.service.js +1987 -0
- package/dist/modules/workflow/git/git.service.js.map +1 -0
- package/dist/modules/workflow/git/mutex.d.ts +11 -0
- package/dist/modules/workflow/git/mutex.d.ts.map +1 -0
- package/dist/modules/workflow/git/mutex.js +23 -0
- package/dist/modules/workflow/git/mutex.js.map +1 -0
- package/dist/modules/workflow/git/pull-request.service.d.ts +124 -0
- package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -0
- package/dist/modules/workflow/git/pull-request.service.js +328 -0
- package/dist/modules/workflow/git/pull-request.service.js.map +1 -0
- package/dist/modules/workflow/locking-filesystem.d.ts +133 -0
- package/dist/modules/workflow/locking-filesystem.d.ts.map +1 -0
- package/dist/modules/workflow/locking-filesystem.js +400 -0
- package/dist/modules/workflow/locking-filesystem.js.map +1 -0
- package/dist/modules/workflow/pending-commits.service.d.ts +221 -0
- package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -0
- package/dist/modules/workflow/pending-commits.service.js +364 -0
- package/dist/modules/workflow/pending-commits.service.js.map +1 -0
- package/dist/modules/workflow/pending-commits.worker.d.ts +148 -0
- package/dist/modules/workflow/pending-commits.worker.d.ts.map +1 -0
- package/dist/modules/workflow/pending-commits.worker.js +245 -0
- package/dist/modules/workflow/pending-commits.worker.js.map +1 -0
- package/dist/modules/workflow/read-only-filesystem.d.ts +24 -0
- package/dist/modules/workflow/read-only-filesystem.d.ts.map +1 -0
- package/dist/modules/workflow/read-only-filesystem.js +39 -0
- package/dist/modules/workflow/read-only-filesystem.js.map +1 -0
- package/dist/modules/workflow/recovery-bot.d.ts +31 -0
- package/dist/modules/workflow/recovery-bot.d.ts.map +1 -0
- package/dist/modules/workflow/recovery-bot.js +64 -0
- package/dist/modules/workflow/recovery-bot.js.map +1 -0
- package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts +137 -0
- package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts.map +1 -0
- package/dist/modules/workflow/review-workflow/review-workflow.interface.js +2 -0
- package/dist/modules/workflow/review-workflow/review-workflow.interface.js.map +1 -0
- package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts +26 -0
- package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -0
- package/dist/modules/workflow/review-workflow/review-workflow.service.js +636 -0
- package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -0
- package/dist/modules/workflow/sanitize-error.d.ts +29 -0
- package/dist/modules/workflow/sanitize-error.d.ts.map +1 -0
- package/dist/modules/workflow/sanitize-error.js +60 -0
- package/dist/modules/workflow/sanitize-error.js.map +1 -0
- package/dist/modules/workflow/session-ontology.policy.d.ts +52 -0
- package/dist/modules/workflow/session-ontology.policy.d.ts.map +1 -0
- package/dist/modules/workflow/session-ontology.policy.js +62 -0
- package/dist/modules/workflow/session-ontology.policy.js.map +1 -0
- package/dist/modules/workflow/session-ontology.service.d.ts +100 -0
- package/dist/modules/workflow/session-ontology.service.d.ts.map +1 -0
- package/dist/modules/workflow/session-ontology.service.js +143 -0
- package/dist/modules/workflow/session-ontology.service.js.map +1 -0
- package/dist/modules/workflow/workflow-hooks.d.ts +87 -0
- package/dist/modules/workflow/workflow-hooks.d.ts.map +1 -0
- package/dist/modules/workflow/workflow-hooks.js +35 -0
- package/dist/modules/workflow/workflow-hooks.js.map +1 -0
- package/dist/modules/workflow/workflow.errors.d.ts +171 -0
- package/dist/modules/workflow/workflow.errors.d.ts.map +1 -0
- package/dist/modules/workflow/workflow.errors.js +260 -0
- package/dist/modules/workflow/workflow.errors.js.map +1 -0
- package/dist/modules/workflow/workflow.routes.d.ts +26 -0
- package/dist/modules/workflow/workflow.routes.d.ts.map +1 -0
- package/dist/modules/workflow/workflow.routes.js +804 -0
- package/dist/modules/workflow/workflow.routes.js.map +1 -0
- package/dist/modules/workflow/workflow.service.d.ts +385 -0
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -0
- package/dist/modules/workflow/workflow.service.js +1155 -0
- package/dist/modules/workflow/workflow.service.js.map +1 -0
- package/dist/modules/workspace/bevel-ignore.d.ts +25 -0
- package/dist/modules/workspace/bevel-ignore.d.ts.map +1 -0
- package/dist/modules/workspace/bevel-ignore.js +57 -0
- package/dist/modules/workspace/bevel-ignore.js.map +1 -0
- package/dist/modules/workspace/kb-seed.interface.d.ts +36 -0
- package/dist/modules/workspace/kb-seed.interface.d.ts.map +1 -0
- package/dist/modules/workspace/kb-seed.interface.js +2 -0
- package/dist/modules/workspace/kb-seed.interface.js.map +1 -0
- package/dist/modules/workspace/kb-seed.service.d.ts +70 -0
- package/dist/modules/workspace/kb-seed.service.d.ts.map +1 -0
- package/dist/modules/workspace/kb-seed.service.js +325 -0
- package/dist/modules/workspace/kb-seed.service.js.map +1 -0
- package/dist/modules/workspace/routine-write-policy.d.ts +49 -0
- package/dist/modules/workspace/routine-write-policy.d.ts.map +1 -0
- package/dist/modules/workspace/routine-write-policy.js +46 -0
- package/dist/modules/workspace/routine-write-policy.js.map +1 -0
- package/dist/modules/workspace/session-ontology.gate.d.ts +112 -0
- package/dist/modules/workspace/session-ontology.gate.d.ts.map +1 -0
- package/dist/modules/workspace/session-ontology.gate.js +161 -0
- package/dist/modules/workspace/session-ontology.gate.js.map +1 -0
- package/dist/modules/workspace/session-sink.d.ts +25 -0
- package/dist/modules/workspace/session-sink.d.ts.map +1 -0
- package/dist/modules/workspace/session-sink.js +8 -0
- package/dist/modules/workspace/session-sink.js.map +1 -0
- package/dist/modules/workspace/spill-store.d.ts +24 -0
- package/dist/modules/workspace/spill-store.d.ts.map +1 -0
- package/dist/modules/workspace/spill-store.js +87 -0
- package/dist/modules/workspace/spill-store.js.map +1 -0
- package/dist/modules/workspace/workspace.routes.d.ts +25 -0
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -0
- package/dist/modules/workspace/workspace.routes.js +1046 -0
- package/dist/modules/workspace/workspace.routes.js.map +1 -0
- package/dist/modules/workspace/workspace.service.d.ts +339 -0
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -0
- package/dist/modules/workspace/workspace.service.js +1221 -0
- package/dist/modules/workspace/workspace.service.js.map +1 -0
- package/dist/modules/workspace/workspace.tools.d.ts +19 -0
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -0
- package/dist/modules/workspace/workspace.tools.js +767 -0
- package/dist/modules/workspace/workspace.tools.js.map +1 -0
- package/dist/shared/frontmatter-id.d.ts +35 -0
- package/dist/shared/frontmatter-id.d.ts.map +1 -0
- package/dist/shared/frontmatter-id.js +68 -0
- package/dist/shared/frontmatter-id.js.map +1 -0
- package/dist/shared/fs-walk.d.ts +9 -0
- package/dist/shared/fs-walk.d.ts.map +1 -0
- package/dist/shared/fs-walk.js +34 -0
- package/dist/shared/fs-walk.js.map +1 -0
- package/dist/shared/hash-email.d.ts +11 -0
- package/dist/shared/hash-email.d.ts.map +1 -0
- package/dist/shared/hash-email.js +14 -0
- package/dist/shared/hash-email.js.map +1 -0
- package/dist/shared/kb-layout.d.ts +38 -0
- package/dist/shared/kb-layout.d.ts.map +1 -0
- package/dist/shared/kb-layout.js +102 -0
- package/dist/shared/kb-layout.js.map +1 -0
- package/dist/shared/kb-layout.test.d.ts +2 -0
- package/dist/shared/kb-layout.test.d.ts.map +1 -0
- package/dist/shared/kb-layout.test.js +67 -0
- package/dist/shared/kb-layout.test.js.map +1 -0
- package/dist/shared/ssrf.d.ts +20 -0
- package/dist/shared/ssrf.d.ts.map +1 -0
- package/dist/shared/ssrf.js +89 -0
- package/dist/shared/ssrf.js.map +1 -0
- package/dist/shared/token-crypto.d.ts +16 -0
- package/dist/shared/token-crypto.d.ts.map +1 -0
- package/dist/shared/token-crypto.js +49 -0
- package/dist/shared/token-crypto.js.map +1 -0
- package/dist/shared/ttl-cache.d.ts +16 -0
- package/dist/shared/ttl-cache.d.ts.map +1 -0
- package/dist/shared/ttl-cache.js +27 -0
- package/dist/shared/ttl-cache.js.map +1 -0
- package/dist/shared/utcp-namespace.d.ts +46 -0
- package/dist/shared/utcp-namespace.d.ts.map +1 -0
- package/dist/shared/utcp-namespace.js +82 -0
- package/dist/shared/utcp-namespace.js.map +1 -0
- package/dist/version.d.ts +17 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +19 -0
- package/dist/version.js.map +1 -0
- package/kb-template/.bevelignore +21 -0
- package/kb-template/Agents/.gitkeep +0 -0
- package/kb-template/Agents/README.md +38 -0
- package/kb-template/CLAUDE.md +419 -0
- package/kb-template/Data/.gitkeep +0 -0
- package/kb-template/Data/README.md +39 -0
- package/kb-template/KnowledgeBase/.gitkeep +0 -0
- package/kb-template/KnowledgeBase/README.md +37 -0
- package/kb-template/Pipelines/.gitkeep +0 -0
- package/kb-template/Pipelines/README.md +38 -0
- package/kb-template/Skills/.gitkeep +0 -0
- package/kb-template/Skills/README.md +32 -0
- package/kb-template/Tools/.gitkeep +0 -0
- package/kb-template/Tools/README.md +42 -0
- package/kb-template/access.md +36 -0
- package/migrations/0000_core_init.sql +243 -0
- package/migrations/meta/0000_snapshot.json +1480 -0
- package/migrations/meta/_journal.json +13 -0
- package/package.json +80 -0
- package/src/assets.ts +25 -0
- package/src/core/core-ports.ts +91 -0
- package/src/core/create-core-server.ts +338 -0
- package/src/core/create-core-services.ts +501 -0
- package/src/core-config.ts +257 -0
- package/src/index.ts +69 -0
- package/src/modules/access/__tests__/access-control.atref-batch.test.ts +98 -0
- package/src/modules/access/__tests__/access-control.read-batch.test.ts +132 -0
- package/src/modules/access/__tests__/access-control.service.test.ts +1011 -0
- package/src/modules/access/__tests__/access-mutation.service.test.ts +439 -0
- package/src/modules/access/__tests__/access-splice.test.ts +247 -0
- package/src/modules/access/__tests__/access.routes.revoke.test.ts +407 -0
- package/src/modules/access/__tests__/creator-access.test.ts +217 -0
- package/src/modules/access/__tests__/grant-sources.test.ts +204 -0
- package/src/modules/access/__tests__/kb-read-filter.test.ts +70 -0
- package/src/modules/access/__tests__/roles-admin.service.test.ts +469 -0
- package/src/modules/access/__tests__/roles-edit.test.ts +138 -0
- package/src/modules/access/__tests__/roles-yaml-guard.test.ts +70 -0
- package/src/modules/access/__tests__/roles.routes.test.ts +234 -0
- package/src/modules/access/access-control.interface.ts +383 -0
- package/src/modules/access/access-control.service.ts +1794 -0
- package/src/modules/access/access-errors.ts +60 -0
- package/src/modules/access/access-mutation.service.ts +369 -0
- package/src/modules/access/access-splice.ts +413 -0
- package/src/modules/access/access.routes.ts +894 -0
- package/src/modules/access/creator-access.ts +270 -0
- package/src/modules/access/kb-read-filter.ts +76 -0
- package/src/modules/access/roles-admin.service.ts +741 -0
- package/src/modules/access/roles-edit.ts +248 -0
- package/src/modules/access/roles-yaml-guard.ts +89 -0
- package/src/modules/admin/admin-access.routes.ts +29 -0
- package/src/modules/admin/admin-access.service.ts +38 -0
- package/src/modules/admin/admin.interface.ts +10 -0
- package/src/modules/auth/account-erasure.service.ts +183 -0
- package/src/modules/auth/auth.middleware.ts +78 -0
- package/src/modules/auth/auth.routes.ts +97 -0
- package/src/modules/auth/auth.service.ts +199 -0
- package/src/modules/code-mode/code-mode-names.ts +38 -0
- package/src/modules/code-mode/code-mode.tool.ts +117 -0
- package/src/modules/code-mode/index.ts +6 -0
- package/src/modules/database/connection.ts +15 -0
- package/src/modules/database/core-schema.ts +431 -0
- package/src/modules/database/migrate.ts +43 -0
- package/src/modules/database/schema.ts +11 -0
- package/src/modules/diff/__tests__/diff.routes.read-gate.test.ts +87 -0
- package/src/modules/diff/__tests__/diff.routes.rejectPathsLocked.test.ts +150 -0
- package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +184 -0
- package/src/modules/diff/__tests__/diff.service.test.ts +202 -0
- package/src/modules/diff/diff-paths.ts +9 -0
- package/src/modules/diff/diff.config.ts +12 -0
- package/src/modules/diff/diff.interface.ts +78 -0
- package/src/modules/diff/diff.routes.ts +277 -0
- package/src/modules/diff/diff.service.ts +508 -0
- package/src/modules/diff/line-diff.ts +79 -0
- package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +287 -0
- package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +249 -0
- package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +253 -0
- package/src/modules/mcp/__tests__/mcp-session-store.test.ts +151 -0
- package/src/modules/mcp/__tests__/mcp.e2e.test.ts +150 -0
- package/src/modules/mcp/__tests__/mcp.routes.delete.test.ts +92 -0
- package/src/modules/mcp/__tests__/mcp.service.test.ts +414 -0
- package/src/modules/mcp/mcp-auth.middleware.ts +126 -0
- package/src/modules/mcp/mcp-session-store.ts +162 -0
- package/src/modules/mcp/mcp.routes.ts +263 -0
- package/src/modules/mcp/mcp.service.ts +973 -0
- package/src/modules/mcp/oauth/bevel-oauth-provider.ts +401 -0
- package/src/modules/mcp/oauth/oauth-consent.routes.ts +60 -0
- package/src/modules/mcp/oauth/oauth-state.ts +61 -0
- package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +277 -0
- package/src/modules/secrets-vault/__tests__/db-secrets-vault.oauth.test.ts +206 -0
- package/src/modules/secrets-vault/__tests__/mcp-oauth-discovery.service.test.ts +178 -0
- package/src/modules/secrets-vault/__tests__/scopes-covered.test.ts +101 -0
- package/src/modules/secrets-vault/__tests__/secrets-variable-loader.test.ts +54 -0
- package/src/modules/secrets-vault/__tests__/tool-owner-gate.route.test.ts +143 -0
- package/src/modules/secrets-vault/db-secrets-vault.service.ts +792 -0
- package/src/modules/secrets-vault/index.ts +25 -0
- package/src/modules/secrets-vault/mcp-oauth-discovery.service.ts +289 -0
- package/src/modules/secrets-vault/secrets-variable-loader.ts +104 -0
- package/src/modules/secrets-vault/secrets-vault.contract.ts +270 -0
- package/src/modules/secrets-vault/secrets-vault.routes.ts +526 -0
- package/src/modules/skills/__tests__/skills.service.test.ts +176 -0
- package/src/modules/skills/index.ts +10 -0
- package/src/modules/skills/skills.contract.ts +54 -0
- package/src/modules/skills/skills.routes.ts +38 -0
- package/src/modules/skills/skills.service.ts +245 -0
- package/src/modules/skills/skills.tools.ts +121 -0
- package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +358 -0
- package/src/modules/tool-auth/__tests__/internal-token.service.test.ts +79 -0
- package/src/modules/tool-auth/__tests__/manual-auth.middleware.test.ts +88 -0
- package/src/modules/tool-auth/external-api-key.errors.ts +25 -0
- package/src/modules/tool-auth/external-api-key.interface.ts +99 -0
- package/src/modules/tool-auth/external-api-key.service.ts +209 -0
- package/src/modules/tool-auth/internal-token.service.ts +124 -0
- package/src/modules/tool-auth/llm-usage-meter.ts +19 -0
- package/src/modules/tool-auth/tool-auth.middleware.ts +220 -0
- package/src/modules/tool-helpers/__tests__/phase0-loopback-spike.test.ts +129 -0
- package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +95 -0
- package/src/modules/tool-helpers/__tests__/tools-surface.test.ts +146 -0
- package/src/modules/tool-helpers/__tests__/validate-token.test.ts +75 -0
- package/src/modules/tool-helpers/index.ts +18 -0
- package/src/modules/tool-helpers/tool-context.ts +98 -0
- package/src/modules/tool-helpers/tool-def.ts +73 -0
- package/src/modules/tool-helpers/tool-handler.ts +91 -0
- package/src/modules/tool-helpers/tool.contract.ts +85 -0
- package/src/modules/tool-helpers/validate-token.ts +50 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.mcp-oauth.test.ts +200 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +499 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +156 -0
- package/src/modules/tool-manuals/index.ts +12 -0
- package/src/modules/tool-manuals/tool-manuals.contract.ts +183 -0
- package/src/modules/tool-manuals/tool-manuals.routes.ts +110 -0
- package/src/modules/tool-manuals/tool-manuals.service.ts +781 -0
- package/src/modules/tool-manuals/tool-manuals.tools.ts +202 -0
- package/src/modules/tool-registry/__tests__/tool-registry.test.ts +64 -0
- package/src/modules/tool-registry/manual.routes.ts +87 -0
- package/src/modules/tool-registry/tool-registry.ts +55 -0
- package/src/modules/tool-registry/tool.contract.ts +52 -0
- package/src/modules/workflow/__tests__/event-bus.test.ts +322 -0
- package/src/modules/workflow/__tests__/file-change-notifier.test.ts +51 -0
- package/src/modules/workflow/__tests__/format-affected-owners.test.ts +67 -0
- package/src/modules/workflow/__tests__/locking-filesystem.test.ts +445 -0
- package/src/modules/workflow/__tests__/pending-commits.canonical.test.ts +36 -0
- package/src/modules/workflow/__tests__/pending-commits.worker.test.ts +243 -0
- package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +308 -0
- package/src/modules/workflow/__tests__/sanitize-error.test.ts +67 -0
- package/src/modules/workflow/__tests__/session-ontology.policy.test.ts +62 -0
- package/src/modules/workflow/__tests__/session-ontology.service.test.ts +200 -0
- package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +232 -0
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +380 -0
- package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +340 -0
- package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +192 -0
- package/src/modules/workflow/agent-tools/workflow.tools.ts +502 -0
- package/src/modules/workflow/event-bus.ts +262 -0
- package/src/modules/workflow/events.routes.ts +266 -0
- package/src/modules/workflow/file-change-notifier.ts +54 -0
- package/src/modules/workflow/file-lock.service.ts +269 -0
- package/src/modules/workflow/git/__tests__/branch-name.test.ts +86 -0
- package/src/modules/workflow/git/__tests__/branchAuthor.test.ts +80 -0
- package/src/modules/workflow/git/__tests__/clone-config.test.ts +15 -0
- package/src/modules/workflow/git/__tests__/git-test-helpers.ts +47 -0
- package/src/modules/workflow/git/__tests__/git-version.failure.test.ts +24 -0
- package/src/modules/workflow/git/__tests__/git-version.test.ts +49 -0
- package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +389 -0
- package/src/modules/workflow/git/__tests__/git.service.changedFilesForPr.test.ts +124 -0
- package/src/modules/workflow/git/__tests__/git.service.commitChanges.test.ts +105 -0
- package/src/modules/workflow/git/__tests__/git.service.commitFile.test.ts +211 -0
- package/src/modules/workflow/git/__tests__/git.service.createBranch.test.ts +154 -0
- package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +320 -0
- package/src/modules/workflow/git/__tests__/git.service.diffFileAtCommit.test.ts +202 -0
- package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +453 -0
- package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +198 -0
- package/src/modules/workflow/git/__tests__/git.service.listTrackedFiles.test.ts +125 -0
- package/src/modules/workflow/git/__tests__/git.service.logForFile.test.ts +219 -0
- package/src/modules/workflow/git/__tests__/git.service.mergeChangeRequest.test.ts +145 -0
- package/src/modules/workflow/git/__tests__/git.service.pendingChanges.test.ts +240 -0
- package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +272 -0
- package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +232 -0
- package/src/modules/workflow/git/__tests__/git.service.readFileAtRef.test.ts +101 -0
- package/src/modules/workflow/git/__tests__/git.service.status.test.ts +127 -0
- package/src/modules/workflow/git/__tests__/mutex.test.ts +78 -0
- package/src/modules/workflow/git/__tests__/pull-request.service.test.ts +225 -0
- package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-cancel.test.ts +101 -0
- package/src/modules/workflow/git/branch-name.ts +70 -0
- package/src/modules/workflow/git/clone-config.ts +71 -0
- package/src/modules/workflow/git/git-version.ts +70 -0
- package/src/modules/workflow/git/git.service.ts +2248 -0
- package/src/modules/workflow/git/mutex.ts +22 -0
- package/src/modules/workflow/git/pull-request.service.ts +447 -0
- package/src/modules/workflow/locking-filesystem.ts +489 -0
- package/src/modules/workflow/pending-commits.service.ts +444 -0
- package/src/modules/workflow/pending-commits.worker.ts +361 -0
- package/src/modules/workflow/read-only-filesystem.ts +54 -0
- package/src/modules/workflow/recovery-bot.ts +73 -0
- package/src/modules/workflow/review-workflow/__tests__/approval-states.test.ts +560 -0
- package/src/modules/workflow/review-workflow/__tests__/cancel-pr.test.ts +176 -0
- package/src/modules/workflow/review-workflow/__tests__/merge-gate.test.ts +258 -0
- package/src/modules/workflow/review-workflow/review-workflow.interface.ts +199 -0
- package/src/modules/workflow/review-workflow/review-workflow.service.ts +806 -0
- package/src/modules/workflow/sanitize-error.ts +62 -0
- package/src/modules/workflow/session-ontology.policy.ts +70 -0
- package/src/modules/workflow/session-ontology.service.ts +178 -0
- package/src/modules/workflow/workflow-hooks.ts +101 -0
- package/src/modules/workflow/workflow.errors.ts +285 -0
- package/src/modules/workflow/workflow.routes.ts +858 -0
- package/src/modules/workflow/workflow.service.ts +1555 -0
- package/src/modules/workspace/__tests__/kb-seed.service.test.ts +213 -0
- package/src/modules/workspace/__tests__/routine-write-policy.test.ts +68 -0
- package/src/modules/workspace/__tests__/session-ontology.gate.test.ts +237 -0
- package/src/modules/workspace/__tests__/spill-store.test.ts +43 -0
- package/src/modules/workspace/__tests__/workspace.routes.create-grant.test.ts +233 -0
- package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +176 -0
- package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +303 -0
- package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +276 -0
- package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +120 -0
- package/src/modules/workspace/__tests__/workspace.service.test.ts +565 -0
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +504 -0
- package/src/modules/workspace/bevel-ignore.ts +62 -0
- package/src/modules/workspace/kb-seed.interface.ts +36 -0
- package/src/modules/workspace/kb-seed.service.ts +361 -0
- package/src/modules/workspace/routine-write-policy.ts +79 -0
- package/src/modules/workspace/session-ontology.gate.ts +189 -0
- package/src/modules/workspace/session-sink.ts +25 -0
- package/src/modules/workspace/spill-store.ts +87 -0
- package/src/modules/workspace/workspace.routes.ts +1114 -0
- package/src/modules/workspace/workspace.service.ts +1343 -0
- package/src/modules/workspace/workspace.tools.ts +885 -0
- package/src/shared/__tests__/frontmatter-id.test.ts +88 -0
- package/src/shared/__tests__/fs-walk.test.ts +42 -0
- package/src/shared/__tests__/ssrf.test.ts +53 -0
- package/src/shared/__tests__/utcp-namespace.test.ts +19 -0
- package/src/shared/frontmatter-id.ts +72 -0
- package/src/shared/fs-walk.ts +30 -0
- package/src/shared/hash-email.ts +14 -0
- package/src/shared/kb-layout.test.ts +88 -0
- package/src/shared/kb-layout.ts +101 -0
- package/src/shared/ssrf.ts +78 -0
- package/src/shared/token-crypto.ts +54 -0
- package/src/shared/ttl-cache.ts +27 -0
- package/src/shared/utcp-namespace.ts +88 -0
- package/src/version.ts +19 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { Server as HttpServer } from 'node:http';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
4
|
+
import '@utcp/http'; // registers the http CallTemplate serializer + protocol
|
|
5
|
+
import { HttpCallTemplateSerializer } from '@utcp/http';
|
|
6
|
+
import { CodeModeUtcpClient } from '../../code-mode/index.js';
|
|
7
|
+
|
|
8
|
+
const httpTemplate = new HttpCallTemplateSerializer();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* PHASE 0 SPIKE (gates the unified-registry plan): prove the agent's INTERNAL
|
|
12
|
+
* execution model works — a real `CodeModeUtcpClient` discovers an HTTP UTCP
|
|
13
|
+
* manual over loopback and calls its tools from inside `call_tool_chain`, with a
|
|
14
|
+
* bearer token resolved from per-client config. Also benchmark per-op loopback
|
|
15
|
+
* latency (R1). This mirrors what each agent turn will do against the internal
|
|
16
|
+
* manual endpoint. Throwaway once the real registry e2e lands.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const MANUAL = 'bevel';
|
|
20
|
+
|
|
21
|
+
// The internal UTCP manual a module-hosted endpoint would serve. Tools use the
|
|
22
|
+
// `{body}` wrapper (body_field:'body') so multi-field args ride the JSON body —
|
|
23
|
+
// the only standard-http way to do that (verified in @utcp/http callTool).
|
|
24
|
+
function manual(): unknown {
|
|
25
|
+
const httpTool = (name: string, bodyProps: Record<string, unknown>) => ({
|
|
26
|
+
name,
|
|
27
|
+
description: `the ${name} tool`,
|
|
28
|
+
inputs: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: { body: { type: 'object', properties: bodyProps } },
|
|
31
|
+
required: ['body'],
|
|
32
|
+
},
|
|
33
|
+
outputs: { type: 'object', properties: {} },
|
|
34
|
+
tags: [],
|
|
35
|
+
tool_call_template: {
|
|
36
|
+
call_template_type: 'http',
|
|
37
|
+
http_method: 'POST',
|
|
38
|
+
url: `\${API_URL}/api/agent/tools/${name}`,
|
|
39
|
+
content_type: 'application/json',
|
|
40
|
+
headers: { Authorization: 'Bearer ${CONNECTION_KEY}' },
|
|
41
|
+
body_field: 'body',
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
utcp_version: '1.1.0',
|
|
46
|
+
manual_version: '1.0.0',
|
|
47
|
+
tools: [httpTool('list_branches', {}), httpTool('echo', { msg: { type: 'string' } })],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let httpServer: HttpServer | undefined;
|
|
52
|
+
let seenAuth: string | undefined;
|
|
53
|
+
|
|
54
|
+
async function startApp(): Promise<string> {
|
|
55
|
+
const app = express();
|
|
56
|
+
app.use(express.json());
|
|
57
|
+
app.get('/api/agent/internal/utcp', (_req, res) => res.json(manual()));
|
|
58
|
+
app.post('/api/agent/tools/list_branches', (req, res) => {
|
|
59
|
+
seenAuth = req.headers.authorization;
|
|
60
|
+
res.json({ branches: ['current-company-state', 'target-company-state'] });
|
|
61
|
+
});
|
|
62
|
+
app.post('/api/agent/tools/echo', (req, res) => {
|
|
63
|
+
res.json({ echoed: (req.body as { msg?: string })?.msg ?? null });
|
|
64
|
+
});
|
|
65
|
+
httpServer = await new Promise<HttpServer>((resolve) => {
|
|
66
|
+
const s = app.listen(0, () => resolve(s));
|
|
67
|
+
});
|
|
68
|
+
const port = (httpServer.address() as { port: number }).port;
|
|
69
|
+
return `http://127.0.0.1:${port}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function buildClient(baseUrl: string, token: string): Promise<CodeModeUtcpClient> {
|
|
73
|
+
// Per-client config carries the loopback base URL + the scoped token under the
|
|
74
|
+
// manual namespace (`<MANUAL>_API_URL` / `<MANUAL>_CONNECTION_KEY`).
|
|
75
|
+
const client = await CodeModeUtcpClient.create(process.cwd(), {
|
|
76
|
+
variables: { [`${MANUAL}_API_URL`]: baseUrl, [`${MANUAL}_CONNECTION_KEY`]: token },
|
|
77
|
+
} as never);
|
|
78
|
+
await client.registerManual(
|
|
79
|
+
httpTemplate.validateDict({
|
|
80
|
+
name: MANUAL,
|
|
81
|
+
call_template_type: 'http',
|
|
82
|
+
http_method: 'GET',
|
|
83
|
+
url: '${API_URL}/api/agent/internal/utcp',
|
|
84
|
+
content_type: 'application/json',
|
|
85
|
+
headers: { Authorization: 'Bearer ${CONNECTION_KEY}' },
|
|
86
|
+
}),
|
|
87
|
+
);
|
|
88
|
+
return client;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
afterEach(async () => {
|
|
92
|
+
if (httpServer) await new Promise<void>((r) => httpServer!.close(() => r()));
|
|
93
|
+
httpServer = undefined;
|
|
94
|
+
seenAuth = undefined;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('Phase 0 — internal loopback execution', () => {
|
|
98
|
+
it('discovers an http manual and calls its tools from inside call_tool_chain', async () => {
|
|
99
|
+
const base = await startApp();
|
|
100
|
+
const client = await buildClient(base, 'internal-token-abc');
|
|
101
|
+
|
|
102
|
+
const tools = await client.getTools();
|
|
103
|
+
expect(tools.map((t) => t.name).sort()).toEqual([`${MANUAL}.echo`, `${MANUAL}.list_branches`]);
|
|
104
|
+
|
|
105
|
+
const { result } = await client.callToolChain(
|
|
106
|
+
`return { a: ${MANUAL}.list_branches({ body: {} }), b: ${MANUAL}.echo({ body: { msg: 'hi' } }) };`,
|
|
107
|
+
20_000,
|
|
108
|
+
);
|
|
109
|
+
expect(result.a).toEqual({ branches: ['current-company-state', 'target-company-state'] });
|
|
110
|
+
expect(result.b).toEqual({ echoed: 'hi' });
|
|
111
|
+
// The per-client token reached the loopback endpoint.
|
|
112
|
+
expect(seenAuth).toBe('Bearer internal-token-abc');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('benchmark: per-op loopback latency inside a code-mode loop', async () => {
|
|
116
|
+
const base = await startApp();
|
|
117
|
+
const client = await buildClient(base, 'tok');
|
|
118
|
+
const N = 30;
|
|
119
|
+
const t0 = performance.now();
|
|
120
|
+
const { result } = await client.callToolChain(
|
|
121
|
+
`let n = 0; for (let i = 0; i < ${N}; i++) { ${MANUAL}.echo({ body: { msg: 'x' } }); n++; } return n;`,
|
|
122
|
+
30_000,
|
|
123
|
+
);
|
|
124
|
+
const ms = performance.now() - t0;
|
|
125
|
+
expect(result).toBe(N);
|
|
126
|
+
// eslint-disable-next-line no-console
|
|
127
|
+
console.log(`[phase0] ${N} loopback tool calls in one code-mode chain: ${ms.toFixed(0)}ms total, ${(ms / N).toFixed(1)}ms/op`);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { Server as HttpServer } from 'node:http';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
4
|
+
import { ToolRegistry } from '../../tool-registry/tool-registry.js';
|
|
5
|
+
import { InternalTokenService } from '../../tool-auth/internal-token.service.js';
|
|
6
|
+
import { createToolAuthMiddleware } from '../../tool-auth/tool-auth.middleware.js';
|
|
7
|
+
import { createToolContextResolver } from '../tool-context.js';
|
|
8
|
+
import { createToolHandlerFactory } from '../tool-handler.js';
|
|
9
|
+
import { createManualRoutes } from '../../tool-registry/manual.routes.js';
|
|
10
|
+
import { registerWorkspaceTools } from '../../workspace/workspace.tools.js';
|
|
11
|
+
import { RoutineWritePolicyService } from '../../workspace/routine-write-policy.js';
|
|
12
|
+
import { WorkflowHooks } from '../../workflow/workflow-hooks.js';
|
|
13
|
+
import { SpillStore } from '../../workspace/spill-store.js';
|
|
14
|
+
|
|
15
|
+
const WS = 'target-company-state';
|
|
16
|
+
let recorded: unknown[][] = [];
|
|
17
|
+
|
|
18
|
+
const externalApiKeyService = { verifyAndLoadToken: async () => null } as never;
|
|
19
|
+
const authService = { getUserById: async (id: string) => ({ id, email: 'e@x', name: 'N' }) } as never;
|
|
20
|
+
const workspaceService = {
|
|
21
|
+
getOrCreateForUser: async () => ({ id: WS }),
|
|
22
|
+
getWorkspacePath: async () => '/tmp/ws',
|
|
23
|
+
unzipFile: async (ws: string, p: string, d?: string) => {
|
|
24
|
+
recorded.push(['unzip', ws, p, d]);
|
|
25
|
+
return { extracted: [p], skipped: [] };
|
|
26
|
+
},
|
|
27
|
+
readFile: async () => {
|
|
28
|
+
throw new Error('no such file');
|
|
29
|
+
},
|
|
30
|
+
} as never;
|
|
31
|
+
const workflowService = {} as never;
|
|
32
|
+
const events = {} as never;
|
|
33
|
+
const accessControl = {
|
|
34
|
+
canRead: async () => true,
|
|
35
|
+
canReadBatch: async (_w: string, _u: string, paths: string[]) => new Map(paths.map((p) => [p, true])),
|
|
36
|
+
} as never;
|
|
37
|
+
|
|
38
|
+
const internalToken = new InternalTokenService({ secret: 's' });
|
|
39
|
+
let httpServer: HttpServer | undefined;
|
|
40
|
+
|
|
41
|
+
async function start(): Promise<string> {
|
|
42
|
+
const registry = new ToolRegistry();
|
|
43
|
+
const toolAuth = createToolAuthMiddleware(externalApiKeyService, internalToken);
|
|
44
|
+
const resolve = createToolContextResolver({ authService, workspaceService, workflowService, events, kbDirName: 'knowledge-base', creatorAccess: { planForCreate: async () => null, grantInExtractedFile: async () => null, noteAccessFileWritten: () => {} } });
|
|
45
|
+
const th = createToolHandlerFactory(resolve);
|
|
46
|
+
const router = express.Router();
|
|
47
|
+
// NOTE (core split): this suite used to register the search, feedback and
|
|
48
|
+
// kb (citation) tools alongside the workspace tools. Those registrations —
|
|
49
|
+
// and their web_search / submit_feedback / cite_kb_node cases — moved to
|
|
50
|
+
// the enterprise repo with their modules; core registers only core tools.
|
|
51
|
+
registerWorkspaceTools(registry, router, toolAuth, th, new SpillStore('/tmp/bevel-test-spills'), accessControl, 'knowledge-base', {
|
|
52
|
+
service: {} as never,
|
|
53
|
+
enabled: false, // ontology boundary not under test here
|
|
54
|
+
kbDirName: 'knowledge-base',
|
|
55
|
+
recoveryBotEmail: 'recovery-bot@bevel.local',
|
|
56
|
+
hooks: new WorkflowHooks(),
|
|
57
|
+
}, new RoutineWritePolicyService(), {} as never /* sessionSink — start_session not exercised here */);
|
|
58
|
+
router.use(createManualRoutes(registry, toolAuth));
|
|
59
|
+
|
|
60
|
+
const app = express();
|
|
61
|
+
app.use(express.json());
|
|
62
|
+
app.use('/api', router);
|
|
63
|
+
httpServer = await new Promise<HttpServer>((r) => {
|
|
64
|
+
const s = app.listen(0, () => r(s));
|
|
65
|
+
});
|
|
66
|
+
return `http://127.0.0.1:${(httpServer.address() as { port: number }).port}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const tok = () => internalToken.mint({ userId: 'user-A' });
|
|
70
|
+
const post = (url: string, body: unknown = {}) =>
|
|
71
|
+
fetch(url, { method: 'POST', headers: { 'content-type': 'application/json', authorization: `Bearer ${tok()}` }, body: JSON.stringify(body) });
|
|
72
|
+
|
|
73
|
+
beforeEach(() => {
|
|
74
|
+
recorded = [];
|
|
75
|
+
});
|
|
76
|
+
afterEach(async () => {
|
|
77
|
+
if (httpServer) await new Promise<void>((r) => httpServer!.close(() => r()));
|
|
78
|
+
httpServer = undefined;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('Phase 4 tools (core subset)', () => {
|
|
82
|
+
it('unzip calls workspaceService.unzipFile with the context workspace', async () => {
|
|
83
|
+
const base = await start();
|
|
84
|
+
const res = await post(`${base}/api/agent/tools/unzip`, { path: 'a.zip', branch: WS });
|
|
85
|
+
expect(res.status).toBe(200);
|
|
86
|
+
expect(recorded).toContainEqual(['unzip', WS, 'a.zip', undefined]);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('the registered core tool appears in the internal manual', async () => {
|
|
90
|
+
const base = await start();
|
|
91
|
+
const m = (await (await fetch(`${base}/api/agent/internal/utcp`, { headers: { authorization: `Bearer ${tok()}` } })).json()) as { tools: { name: string }[] };
|
|
92
|
+
const names = m.tools.map((t) => t.name);
|
|
93
|
+
expect(names).toContain('unzip');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { Server as HttpServer } from 'node:http';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
4
|
+
import { ToolRegistry } from '../../tool-registry/tool-registry.js';
|
|
5
|
+
import { toolDef } from '../tool-def.js';
|
|
6
|
+
import { InternalTokenService } from '../../tool-auth/internal-token.service.js';
|
|
7
|
+
import { createToolAuthMiddleware, requireInternalSource } from '../../tool-auth/tool-auth.middleware.js';
|
|
8
|
+
import { createToolContextResolver } from '../tool-context.js';
|
|
9
|
+
import { createToolHandlerFactory } from '../tool-handler.js';
|
|
10
|
+
import { createManualRoutes } from '../../tool-registry/manual.routes.js';
|
|
11
|
+
import type { ToolContext } from '../tool.contract.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Integration test for the Phase 1 machinery: the ONE mechanism (host endpoint +
|
|
15
|
+
* register def), the dual `toolAuth` (connection key OR internal token resolving
|
|
16
|
+
* to a normalized context), write-scope enforcement, and the two manual
|
|
17
|
+
* endpoints — over a real express app.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const WS = 'target-company-state';
|
|
21
|
+
|
|
22
|
+
// Minimal service stubs (list_branches/touch don't touch the filesystem, so the
|
|
23
|
+
// lazy LockingFilesystem is never built).
|
|
24
|
+
const externalApiKeyService = {
|
|
25
|
+
looksLikeExternalApiKey: (t: string) => typeof t === 'string' && t.startsWith('bevel_'),
|
|
26
|
+
verifyAndLoadToken: async (t: string) =>
|
|
27
|
+
t === 'bevel_good' ? { user: { id: 'user-A', email: 'e@x', name: 'N' }, tokenId: 'tok-1' } : null,
|
|
28
|
+
} as never;
|
|
29
|
+
const authService = { getUserById: async (id: string) => ({ id, email: 'e@x', name: 'N' }) } as never;
|
|
30
|
+
const workspaceService = {
|
|
31
|
+
getOrCreateForUser: async () => ({ id: WS }),
|
|
32
|
+
getWorkspacePath: async () => '/tmp/ws',
|
|
33
|
+
} as never;
|
|
34
|
+
const workflowService = { listBranches: async () => [{ name: 'main', isProtected: true }] } as never;
|
|
35
|
+
const events = {} as never;
|
|
36
|
+
|
|
37
|
+
let httpServer: HttpServer | undefined;
|
|
38
|
+
const internalToken = new InternalTokenService({ secret: 'test-secret' });
|
|
39
|
+
|
|
40
|
+
async function start(): Promise<string> {
|
|
41
|
+
const registry = new ToolRegistry();
|
|
42
|
+
const toolAuth = createToolAuthMiddleware(externalApiKeyService, internalToken);
|
|
43
|
+
const resolve = createToolContextResolver({ authService, workspaceService, workflowService, events, kbDirName: 'knowledge-base', creatorAccess: { planForCreate: async () => null, grantInExtractedFile: async () => null, noteAccessFileWritten: () => {} } });
|
|
44
|
+
const toolHandler = createToolHandlerFactory(resolve);
|
|
45
|
+
|
|
46
|
+
registry.registerExternalTool(
|
|
47
|
+
toolDef({ name: 'list_branches', description: 'list', path: '/api/agent/tools/list_branches', inputs: { type: 'object', properties: {} } }),
|
|
48
|
+
);
|
|
49
|
+
registry.registerInternalTool(
|
|
50
|
+
toolDef({ name: 'list_branches', description: 'list', path: '/api/agent/tools/list_branches', inputs: { type: 'object', properties: {} } }),
|
|
51
|
+
);
|
|
52
|
+
registry.registerInternalTool(
|
|
53
|
+
toolDef({ name: 'touch', description: 'write', path: '/api/agent/tools/touch', inputs: { type: 'object', properties: {} }, tags: ['write'] }),
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const app = express();
|
|
57
|
+
app.use(express.json());
|
|
58
|
+
app.post(
|
|
59
|
+
'/api/agent/tools/list_branches',
|
|
60
|
+
toolAuth,
|
|
61
|
+
toolHandler(async (_a: Record<string, unknown>, ctx: ToolContext) => ({
|
|
62
|
+
branches: await ctx.workflowService.listBranches('ws'),
|
|
63
|
+
ranAs: ctx.user.id,
|
|
64
|
+
source: ctx.source,
|
|
65
|
+
})),
|
|
66
|
+
);
|
|
67
|
+
// `touch` is internal-only (registered only via registerInternalTool) AND
|
|
68
|
+
// write-tagged — so its route carries the internal-source gate, mirroring the
|
|
69
|
+
// production mount helpers.
|
|
70
|
+
app.post(
|
|
71
|
+
'/api/agent/tools/touch',
|
|
72
|
+
toolAuth,
|
|
73
|
+
requireInternalSource,
|
|
74
|
+
toolHandler(async () => ({ ok: true }), { write: true }),
|
|
75
|
+
);
|
|
76
|
+
// Internal-only route: mounted (our agent reaches it over loopback) but gated.
|
|
77
|
+
app.post(
|
|
78
|
+
'/api/agent/tools/secret_internal',
|
|
79
|
+
toolAuth,
|
|
80
|
+
requireInternalSource,
|
|
81
|
+
toolHandler(async () => ({ ok: true })),
|
|
82
|
+
);
|
|
83
|
+
app.use('/api', createManualRoutes(registry, toolAuth));
|
|
84
|
+
|
|
85
|
+
httpServer = await new Promise<HttpServer>((resolve2) => {
|
|
86
|
+
const s = app.listen(0, () => resolve2(s));
|
|
87
|
+
});
|
|
88
|
+
const port = (httpServer.address() as { port: number }).port;
|
|
89
|
+
return `http://127.0.0.1:${port}`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
afterEach(async () => {
|
|
93
|
+
if (httpServer) await new Promise<void>((r) => httpServer!.close(() => r()));
|
|
94
|
+
httpServer = undefined;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const post = (url: string, bearer: string, body: unknown = {}) =>
|
|
98
|
+
fetch(url, { method: 'POST', headers: { 'content-type': 'application/json', authorization: `Bearer ${bearer}` }, body: JSON.stringify(body) });
|
|
99
|
+
|
|
100
|
+
const get = (url: string, bearer: string) => fetch(url, { headers: { authorization: `Bearer ${bearer}` } });
|
|
101
|
+
|
|
102
|
+
describe('tools surface — dual auth + scope + manuals', () => {
|
|
103
|
+
it('dispatches the same tool under BOTH a connection key and an internal token', async () => {
|
|
104
|
+
const base = await start();
|
|
105
|
+
const keyRes = await post(`${base}/api/agent/tools/list_branches`, 'bevel_good');
|
|
106
|
+
expect(keyRes.status).toBe(200);
|
|
107
|
+
expect(await keyRes.json()).toMatchObject({ branches: [{ name: 'main' }], ranAs: 'user-A', source: 'external' });
|
|
108
|
+
|
|
109
|
+
const intTok = internalToken.mint({ userId: 'user-A' });
|
|
110
|
+
const intRes = await post(`${base}/api/agent/tools/list_branches`, intTok);
|
|
111
|
+
expect(intRes.status).toBe(200);
|
|
112
|
+
expect(await intRes.json()).toMatchObject({ source: 'internal', ranAs: 'user-A' });
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('rejects a bad/absent bearer (401)', async () => {
|
|
116
|
+
const base = await start();
|
|
117
|
+
expect((await post(`${base}/api/agent/tools/list_branches`, 'nonsense')).status).toBe(401);
|
|
118
|
+
expect((await fetch(`${base}/api/agent/tools/list_branches`, { method: 'POST' })).status).toBe(401);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('serves filtered manuals: internal has list_branches+touch, external only list_branches', async () => {
|
|
122
|
+
const base = await start();
|
|
123
|
+
const intTok = internalToken.mint({ userId: 'user-A' });
|
|
124
|
+
const internal = (await (await get(`${base}/api/agent/internal/utcp`, intTok)).json()) as { tools: { name: string }[] };
|
|
125
|
+
const external = (await (await get(`${base}/api/agent/utcp`, 'bevel_good')).json()) as { tools: { name: string }[] };
|
|
126
|
+
expect(internal.tools.map((t) => t.name).sort()).toEqual(['list_branches', 'touch']);
|
|
127
|
+
expect(external.tools.map((t) => t.name)).toEqual(['list_branches']);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('refuses internal-only surfaces to an external connection key (403), but admits an internal token', async () => {
|
|
131
|
+
const base = await start();
|
|
132
|
+
const intTok = internalToken.mint({ userId: 'user-A' });
|
|
133
|
+
|
|
134
|
+
// The internal tool catalog: external key authenticates but is not internal.
|
|
135
|
+
expect((await get(`${base}/api/agent/internal/utcp`, 'bevel_good')).status).toBe(403);
|
|
136
|
+
expect((await get(`${base}/api/agent/internal/utcp`, intTok)).status).toBe(200);
|
|
137
|
+
|
|
138
|
+
// Internal-only tool routes, reached directly by name, are gated the same
|
|
139
|
+
// way — an external write-scope key can't bypass the catalog filtering by
|
|
140
|
+
// POSTing the route directly. (`touch` is also write-tagged.)
|
|
141
|
+
expect((await post(`${base}/api/agent/tools/secret_internal`, 'bevel_good')).status).toBe(403);
|
|
142
|
+
expect((await post(`${base}/api/agent/tools/secret_internal`, intTok)).status).toBe(200);
|
|
143
|
+
expect((await post(`${base}/api/agent/tools/touch`, 'bevel_good')).status).toBe(403);
|
|
144
|
+
expect((await post(`${base}/api/agent/tools/touch`, intTok)).status).toBe(200);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { InternalTokenService } from '../../tool-auth/internal-token.service.js';
|
|
6
|
+
import { createToolValidator } from '../validate-token.js';
|
|
7
|
+
import { hasHttpStatus } from '../tool.contract.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `validateToken` is the framework-agnostic SDK entry: bearer token → full
|
|
11
|
+
* `ToolContext`, fusing the shared verify core with the context resolver. These
|
|
12
|
+
* tests pin that contract (the same one a marketplace plugin will code against).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const internalToken = new InternalTokenService({ secret: 'test-secret' });
|
|
16
|
+
const externalApiKeyService = {
|
|
17
|
+
looksLikeExternalApiKey: (t: string) => typeof t === 'string' && t.startsWith('bevel_'),
|
|
18
|
+
verifyAndLoadToken: async (t: string) =>
|
|
19
|
+
t === 'bevel_ok' ? { user: { id: 'u-ext', email: 'e@x', name: 'Ext' }, tokenId: 'tk-1' } : null,
|
|
20
|
+
} as never;
|
|
21
|
+
const authService = { getUserById: async (id: string) => ({ id, email: 'e@x', name: 'N' }) } as never;
|
|
22
|
+
|
|
23
|
+
let tempDir = '';
|
|
24
|
+
const workspaceService = {
|
|
25
|
+
getWorkspacePath: async () => tempDir,
|
|
26
|
+
getOrCreateForUser: async () => ({ id: 'ext-ws' }),
|
|
27
|
+
} as never;
|
|
28
|
+
|
|
29
|
+
const validateToken = createToolValidator({
|
|
30
|
+
externalApiKeyService,
|
|
31
|
+
internalTokenService: internalToken,
|
|
32
|
+
authService,
|
|
33
|
+
workspaceService,
|
|
34
|
+
workflowService: {} as never,
|
|
35
|
+
events: {} as never,
|
|
36
|
+
kbDirName: 'knowledge-base',
|
|
37
|
+
creatorAccess: { planForCreate: async () => null, grantInExtractedFile: async () => null, noteAccessFileWritten: () => {} },
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
beforeEach(async () => {
|
|
41
|
+
tempDir = await mkdtemp(join(tmpdir(), 'validate-token-'));
|
|
42
|
+
await writeFile(join(tempDir, 'a.md'), 'hi');
|
|
43
|
+
});
|
|
44
|
+
afterEach(async () => {
|
|
45
|
+
if (tempDir) await rm(tempDir, { recursive: true, force: true });
|
|
46
|
+
tempDir = '';
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('validateToken (tool-author SDK entry)', () => {
|
|
50
|
+
it('resolves an internal token to a write-scoped identity context (no workspace bound)', async () => {
|
|
51
|
+
const tok = internalToken.mint({ userId: 'u1' });
|
|
52
|
+
const ctx = await validateToken(tok);
|
|
53
|
+
expect(ctx).toMatchObject({ source: 'internal', scope: 'write' });
|
|
54
|
+
expect(ctx.user.id).toBe('u1');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('resolves an external connection key to a write-scoped identity context', async () => {
|
|
58
|
+
const ctx = await validateToken('bevel_ok');
|
|
59
|
+
expect(ctx).toMatchObject({ source: 'external', scope: 'write' });
|
|
60
|
+
expect(ctx.user.id).toBe('u-ext');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('getFilesystem(branch) builds the filesystem for that branch\'s workspace', async () => {
|
|
64
|
+
const tok = internalToken.mint({ userId: 'u1' });
|
|
65
|
+
const fs = await (await validateToken(tok)).getFilesystem('some/draft');
|
|
66
|
+
expect((await fs.readFile('a.md')).toString()).toBe('hi');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('throws a 401 ToolError on a bad token and an empty token', async () => {
|
|
70
|
+
for (const bad of ['garbage', 'bevel_nope', '', undefined]) {
|
|
71
|
+
const err = await validateToken(bad as string).catch((e) => e);
|
|
72
|
+
expect(hasHttpStatus(err) && err.status).toBe(401);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tool-author SDK — everything needed to build a tool, in ONE import.
|
|
3
|
+
* Internal tools use it today; it is the surface a third-party marketplace
|
|
4
|
+
* plugin will code against (eventually shipped as a standalone `@bevel-software/tool-sdk`
|
|
5
|
+
* package). A tool author never needs the registry internals, the Express
|
|
6
|
+
* middleware, or the internal-token service — only what is re-exported here.
|
|
7
|
+
*
|
|
8
|
+
* import { validateToken, toolDef, ToolError } from '<tool-sdk>';
|
|
9
|
+
*
|
|
10
|
+
* // in your endpoint:
|
|
11
|
+
* const ctx = await validateToken(bearerToken, body); // verify + resolve, throws ToolError
|
|
12
|
+
* const fs = await ctx.getFilesystem(); // lock-aware (write) / read-only (read)
|
|
13
|
+
* const def = toolDef({ name, description, inputs, path }); // self-describing UTCP Tool to register
|
|
14
|
+
*/
|
|
15
|
+
export { createToolValidator, type ValidateToken, type ToolValidatorDeps } from './validate-token.js';
|
|
16
|
+
export { toolDef, type ToolDefSpec } from './tool-def.js';
|
|
17
|
+
export { ToolError, hasHttpStatus, type ToolContext, type ToolHandler } from './tool.contract.js';
|
|
18
|
+
export type { JsonSchema, UtcpTool } from '../tool-registry/tool.contract.js';
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { LocalFilesystem } from '@mastra/core/workspace';
|
|
2
|
+
import type { IWorkflowService } from '@bevel-software/platform-shared';
|
|
3
|
+
import { LockingFilesystem } from '../workflow/locking-filesystem.js';
|
|
4
|
+
import { ReadOnlyFilesystem } from '../workflow/read-only-filesystem.js';
|
|
5
|
+
import { makeRolesYamlWriteValidator } from '../access/roles-yaml-guard.js';
|
|
6
|
+
import type { ICreatorAccess } from '../access/creator-access.js';
|
|
7
|
+
import { branchForWorkspaceId, type WorkspaceService } from '../workspace/workspace.service.js';
|
|
8
|
+
import type { WorkflowEventBus } from '../workflow/event-bus.js';
|
|
9
|
+
import type { AuthService } from '../auth/auth.service.js';
|
|
10
|
+
import { ToolError, type ToolContext } from './tool.contract.js';
|
|
11
|
+
import type { ToolAuth } from '../tool-auth/tool-auth.middleware.js';
|
|
12
|
+
|
|
13
|
+
export interface ToolContextDeps {
|
|
14
|
+
authService: AuthService;
|
|
15
|
+
workspaceService: WorkspaceService;
|
|
16
|
+
workflowService: IWorkflowService;
|
|
17
|
+
events: WorkflowEventBus;
|
|
18
|
+
/** KB dir name — used to recognise (and validate) writes to `roles.yaml`. */
|
|
19
|
+
kbDirName: string;
|
|
20
|
+
/**
|
|
21
|
+
* Creator read-grant planner, threaded into the LockingFilesystem so agent
|
|
22
|
+
* creations in unreadable spots stay visible to the driving user (see
|
|
23
|
+
* `modules/access/creator-access`).
|
|
24
|
+
*/
|
|
25
|
+
creatorAccess: ICreatorAccess;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type ResolveToolContext = (
|
|
29
|
+
auth: ToolAuth,
|
|
30
|
+
abortSignal: AbortSignal,
|
|
31
|
+
sessionId?: string,
|
|
32
|
+
) => Promise<ToolContext>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Build the per-call `ToolContext` from a verified `ToolAuth`. Identity (user,
|
|
36
|
+
* scope, source) is resolved up front; the WORKSPACE is resolved on demand by
|
|
37
|
+
* `getFilesystem(branch)` and cached per branch. Internal and external callers
|
|
38
|
+
* are identical — the credential is identity-only, so the workspace always comes
|
|
39
|
+
* from the `branch` the tool passes (`getOrCreateForUser` clones the per-branch
|
|
40
|
+
* workspace if needed). A tool that never touches the KB never calls
|
|
41
|
+
* `getFilesystem`, so it resolves no workspace. Writes through the
|
|
42
|
+
* LockingFilesystem auto-commit+push as `user`. Framework-agnostic — never reads
|
|
43
|
+
* a request body; `branch` arrives as an explicit argument from the tool.
|
|
44
|
+
*/
|
|
45
|
+
export function createToolContextResolver(deps: ToolContextDeps): ResolveToolContext {
|
|
46
|
+
// Reject an agent write that would leave roles.yaml unparseable (app-wide
|
|
47
|
+
// admin lockout) before it reaches disk — the agent gets a tool error and the
|
|
48
|
+
// file is untouched, mirroring the human editor's save-time gate.
|
|
49
|
+
const validateRolesWrite = makeRolesYamlWriteValidator(deps.kbDirName);
|
|
50
|
+
|
|
51
|
+
return async function resolveToolContext(auth, abortSignal, sessionId) {
|
|
52
|
+
const user = await deps.authService.getUserById(auth.userId);
|
|
53
|
+
if (!user) throw new ToolError('Your account is no longer available.', 401);
|
|
54
|
+
|
|
55
|
+
const fsCache = new Map<string, LocalFilesystem>();
|
|
56
|
+
const getFilesystem = async (branch: string): Promise<LocalFilesystem> => {
|
|
57
|
+
const cached = fsCache.get(branch);
|
|
58
|
+
if (cached) return cached;
|
|
59
|
+
const ws = await deps.workspaceService.getOrCreateForUser(user, branch);
|
|
60
|
+
const workspaceId = ws.id;
|
|
61
|
+
const basePath = await deps.workspaceService.getWorkspacePath(workspaceId);
|
|
62
|
+
const fs =
|
|
63
|
+
auth.scope === 'write'
|
|
64
|
+
? new LockingFilesystem(
|
|
65
|
+
{ basePath, contained: true },
|
|
66
|
+
{
|
|
67
|
+
workflow: deps.workflowService,
|
|
68
|
+
workspaceId,
|
|
69
|
+
branch: branchForWorkspaceId(workspaceId),
|
|
70
|
+
user,
|
|
71
|
+
validateWrite: validateRolesWrite,
|
|
72
|
+
creatorAccess: deps.creatorAccess,
|
|
73
|
+
},
|
|
74
|
+
)
|
|
75
|
+
: new ReadOnlyFilesystem({ basePath, contained: true });
|
|
76
|
+
fsCache.set(branch, fs);
|
|
77
|
+
return fs;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
user,
|
|
82
|
+
scope: auth.scope,
|
|
83
|
+
source: auth.source,
|
|
84
|
+
tokenId: auth.tokenId,
|
|
85
|
+
// For `internal` callers the signed token claim is the ONLY trustworthy
|
|
86
|
+
// session: honoring a body value would let one per-run token switch to a
|
|
87
|
+
// fresh `sessionId` and shed its accumulated touched-set. The body path is
|
|
88
|
+
// only for `external`/`session` callers, whose token carries no claim and
|
|
89
|
+
// whose `sessionId` is injected by the MCP proxy's continuity convention.
|
|
90
|
+
sessionId: auth.source === 'internal' ? auth.sessionId : sessionId ?? auth.sessionId,
|
|
91
|
+
abortSignal,
|
|
92
|
+
workspaceService: deps.workspaceService,
|
|
93
|
+
workflowService: deps.workflowService,
|
|
94
|
+
events: deps.events,
|
|
95
|
+
getFilesystem,
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import '@utcp/http';
|
|
2
|
+
import { HttpCallTemplateSerializer } from '@utcp/http';
|
|
3
|
+
import { ToolSerializer } from '@utcp/sdk';
|
|
4
|
+
import type { JsonSchema, UtcpTool } from '../tool-registry/tool.contract.js';
|
|
5
|
+
|
|
6
|
+
const httpTemplate = new HttpCallTemplateSerializer();
|
|
7
|
+
const toolSerializer = new ToolSerializer();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The required `branch` input every KB tool declares — the model names the
|
|
11
|
+
* workspace (draft) the call acts on. Since the credential is identity-only
|
|
12
|
+
* (internal token == connection key), the workspace is never implied; it always
|
|
13
|
+
* comes from this argument.
|
|
14
|
+
*/
|
|
15
|
+
export const BRANCH_INPUT: JsonSchema = {
|
|
16
|
+
type: 'string',
|
|
17
|
+
minLength: 1,
|
|
18
|
+
description: 'The branch (draft) whose workspace this operates on — pass the branch you are currently working on.',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** Add a required `branch` property to an object input schema (KB tools). */
|
|
22
|
+
export function withBranchInput(inputs: JsonSchema): JsonSchema {
|
|
23
|
+
const o = inputs as { properties?: Record<string, JsonSchema>; required?: string[] };
|
|
24
|
+
return {
|
|
25
|
+
...inputs,
|
|
26
|
+
properties: { ...(o.properties ?? {}), branch: BRANCH_INPUT },
|
|
27
|
+
required: [...new Set([...(o.required ?? []), 'branch'])],
|
|
28
|
+
} as JsonSchema;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ToolDefSpec {
|
|
32
|
+
/** Unique within its surface; also the namespace member the agent calls (`Bevel.<name>`). */
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
/** The LOGICAL (flat) input schema — what the handler receives and the agent passes. */
|
|
36
|
+
inputs: JsonSchema;
|
|
37
|
+
outputs?: JsonSchema;
|
|
38
|
+
tags?: string[];
|
|
39
|
+
/** The route the owning module hosts, e.g. `/agent/tools/list_branches`. */
|
|
40
|
+
path: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Build a self-describing UTCP `Tool` def for a module-hosted endpoint. The flat
|
|
45
|
+
* `inputs` are wrapped under a single `body` property (`body_field: 'body'`) —
|
|
46
|
+
* the only standard-http way to ride multiple fields in the JSON body — so the
|
|
47
|
+
* agent calls `Bevel.<name>({ body: { ... } })` and the endpoint reads `req.body`
|
|
48
|
+
* as the flat args. The URL + bearer are `${API_URL}` / `${CONNECTION_KEY}`
|
|
49
|
+
* placeholders the consumer resolves (public URL + key for external; loopback +
|
|
50
|
+
* internal token for our agent), so one def serves both surfaces.
|
|
51
|
+
*/
|
|
52
|
+
export function toolDef(spec: ToolDefSpec): UtcpTool {
|
|
53
|
+
return toolSerializer.validateDict({
|
|
54
|
+
name: spec.name,
|
|
55
|
+
description: spec.description,
|
|
56
|
+
inputs: {
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: { body: spec.inputs },
|
|
59
|
+
required: ['body'],
|
|
60
|
+
additionalProperties: false,
|
|
61
|
+
},
|
|
62
|
+
outputs: spec.outputs ?? { type: 'object', properties: {} },
|
|
63
|
+
tags: spec.tags ?? [],
|
|
64
|
+
tool_call_template: httpTemplate.validateDict({
|
|
65
|
+
call_template_type: 'http',
|
|
66
|
+
http_method: 'POST',
|
|
67
|
+
url: `\${API_URL}${spec.path}`,
|
|
68
|
+
content_type: 'application/json',
|
|
69
|
+
headers: { Authorization: 'Bearer ${CONNECTION_KEY}' },
|
|
70
|
+
body_field: 'body',
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
}
|