@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,145 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { execFile } from 'node:child_process';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import os from 'node:os';
|
|
7
|
+
import type { AuthUser } from '@bevel-software/platform-shared';
|
|
8
|
+
import type { WorkspaceService } from '../../../workspace/workspace.service.js';
|
|
9
|
+
import { WorkflowHooks } from '../../workflow-hooks.js';
|
|
10
|
+
import { GitService } from '../git.service.js';
|
|
11
|
+
|
|
12
|
+
const execFileAsync = promisify(execFile);
|
|
13
|
+
const BASE = 'current-company-state';
|
|
14
|
+
const USER: AuthUser = { id: 'u1', email: 'alice@example.com', name: 'Alice' };
|
|
15
|
+
|
|
16
|
+
async function runGit(cwd: string, args: string[]): Promise<void> {
|
|
17
|
+
await execFileAsync('git', args, {
|
|
18
|
+
cwd,
|
|
19
|
+
env: {
|
|
20
|
+
...process.env,
|
|
21
|
+
GIT_AUTHOR_NAME: 'Seed', GIT_AUTHOR_EMAIL: 's@x.com',
|
|
22
|
+
GIT_COMMITTER_NAME: 'Seed', GIT_COMMITTER_EMAIL: 's@x.com',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async function gitOut(cwd: string, args: string[]): Promise<string> {
|
|
27
|
+
const { stdout } = await execFileAsync('git', args, { cwd });
|
|
28
|
+
return stdout.toString();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function stubWorkspaceService(baseWsId: string, baseRepo: string): WorkspaceService {
|
|
32
|
+
return {
|
|
33
|
+
getWorkspacePath: async (id: string) => {
|
|
34
|
+
if (id !== baseWsId) throw new Error(`unexpected workspace ${id}`);
|
|
35
|
+
return path.dirname(baseRepo);
|
|
36
|
+
},
|
|
37
|
+
} as unknown as WorkspaceService;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Bare upstream seeded on BASE with `files`, plus a base-branch workspace clone
|
|
42
|
+
* laid out like prod (`<root>/<wsId>/knowledge-base`). Returns handles for
|
|
43
|
+
* building feature branches and inspecting the merged remote.
|
|
44
|
+
*/
|
|
45
|
+
async function seed(root: string, baseFiles: Record<string, string>) {
|
|
46
|
+
const upstream = path.join(root, 'upstream.git');
|
|
47
|
+
await runGit(root, ['init', '--bare', '-b', BASE, upstream]);
|
|
48
|
+
const seedDir = path.join(root, '.seed');
|
|
49
|
+
await fs.mkdir(seedDir);
|
|
50
|
+
await runGit(seedDir, ['init', '-b', BASE]);
|
|
51
|
+
await runGit(seedDir, ['remote', 'add', 'origin', upstream]);
|
|
52
|
+
for (const [name, content] of Object.entries(baseFiles)) {
|
|
53
|
+
await fs.writeFile(path.join(seedDir, name), content);
|
|
54
|
+
}
|
|
55
|
+
await runGit(seedDir, ['add', '-A']);
|
|
56
|
+
await runGit(seedDir, ['commit', '-m', 'base']);
|
|
57
|
+
await runGit(seedDir, ['push', 'origin', BASE]);
|
|
58
|
+
|
|
59
|
+
const baseWsId = BASE;
|
|
60
|
+
const baseRepo = path.join(root, baseWsId, 'knowledge-base');
|
|
61
|
+
await fs.mkdir(path.join(root, baseWsId), { recursive: true });
|
|
62
|
+
await runGit(root, ['clone', '-b', BASE, upstream, baseRepo]);
|
|
63
|
+
return { upstream, seedDir, baseWsId, baseRepo };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Branch `name` off origin/BASE in a throwaway clone, apply `mutate`, push. */
|
|
67
|
+
async function pushFeatureBranch(
|
|
68
|
+
root: string,
|
|
69
|
+
upstream: string,
|
|
70
|
+
name: string,
|
|
71
|
+
mutate: (dir: string) => Promise<void>,
|
|
72
|
+
) {
|
|
73
|
+
const dir = path.join(root, `feat-${name.replace(/\W/g, '_')}`);
|
|
74
|
+
await runGit(root, ['clone', '-b', BASE, upstream, dir]);
|
|
75
|
+
await runGit(dir, ['checkout', '-b', name]);
|
|
76
|
+
await mutate(dir);
|
|
77
|
+
await runGit(dir, ['add', '-A']);
|
|
78
|
+
await runGit(dir, ['commit', '-m', `work on ${name}`]);
|
|
79
|
+
await runGit(dir, ['push', '-u', 'origin', name]);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
describe('GitService.mergeChangeRequest', () => {
|
|
83
|
+
let root: string;
|
|
84
|
+
beforeEach(async () => {
|
|
85
|
+
root = await fs.mkdtemp(path.join(os.tmpdir(), 'bevel-merge-cr-'));
|
|
86
|
+
});
|
|
87
|
+
afterEach(async () => {
|
|
88
|
+
await fs.rm(root, { recursive: true, force: true }).catch(() => {});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('merges a feature branch into base and pushes the merge commit', async () => {
|
|
92
|
+
const { upstream, baseWsId, baseRepo } = await seed(root, { 'base.md': 'base\n' });
|
|
93
|
+
await pushFeatureBranch(root, upstream, 'alice/add', async (dir) => {
|
|
94
|
+
await fs.writeFile(path.join(dir, 'feature.md'), 'new content\n');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const git = new GitService(stubWorkspaceService(baseWsId, baseRepo), new WorkflowHooks(), 'knowledge-base');
|
|
98
|
+
const result = await git.mergeChangeRequest(
|
|
99
|
+
baseWsId, 'alice/add', BASE, { subject: 'Add feature (#1)', body: 'Merged via Bevel' }, USER,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
expect(result.kind).toBe('merged');
|
|
103
|
+
if (result.kind !== 'merged') return;
|
|
104
|
+
expect(result.sha).toMatch(/^[0-9a-f]{40}$/);
|
|
105
|
+
|
|
106
|
+
// The merge landed on origin/BASE: a fresh clone sees the feature file and a
|
|
107
|
+
// merge commit authored by the human triggerer.
|
|
108
|
+
const verify = path.join(root, 'verify');
|
|
109
|
+
await runGit(root, ['clone', '-b', BASE, upstream, verify]);
|
|
110
|
+
const merged = await fs.readFile(path.join(verify, 'feature.md'), 'utf8');
|
|
111
|
+
expect(merged.replace(/\r\n/g, '\n')).toBe('new content\n');
|
|
112
|
+
const log = await gitOut(verify, ['log', '-1', '--format=%an <%ae>%n%s']);
|
|
113
|
+
expect(log).toContain('Alice <alice@example.com>');
|
|
114
|
+
expect(log).toContain('Add feature (#1)');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('returns the conflicting paths when base and source both changed a file', async () => {
|
|
118
|
+
const { upstream, baseWsId, baseRepo } = await seed(root, { 'shared.md': 'original\n' });
|
|
119
|
+
// Source edits shared.md one way…
|
|
120
|
+
await pushFeatureBranch(root, upstream, 'alice/edit', async (dir) => {
|
|
121
|
+
await fs.writeFile(path.join(dir, 'shared.md'), 'source version\n');
|
|
122
|
+
});
|
|
123
|
+
// …and BASE advances with a conflicting edit to the same file.
|
|
124
|
+
await pushFeatureBranch(root, upstream, 'tmp-base-advance', async (dir) => {
|
|
125
|
+
await fs.writeFile(path.join(dir, 'shared.md'), 'base advanced\n');
|
|
126
|
+
});
|
|
127
|
+
// Fast-forward BASE to that commit so origin/BASE conflicts with the source.
|
|
128
|
+
const advancer = path.join(root, 'advancer');
|
|
129
|
+
await runGit(root, ['clone', '-b', 'tmp-base-advance', upstream, advancer]);
|
|
130
|
+
await runGit(advancer, ['push', 'origin', 'tmp-base-advance:' + BASE]);
|
|
131
|
+
|
|
132
|
+
const git = new GitService(stubWorkspaceService(baseWsId, baseRepo), new WorkflowHooks(), 'knowledge-base');
|
|
133
|
+
const result = await git.mergeChangeRequest(
|
|
134
|
+
baseWsId, 'alice/edit', BASE, { subject: 'Edit (#2)', body: 'x' }, USER,
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
expect(result.kind).toBe('conflicts');
|
|
138
|
+
if (result.kind !== 'conflicts') return;
|
|
139
|
+
expect(result.paths).toContain('shared.md');
|
|
140
|
+
|
|
141
|
+
// The base workspace must be left clean (merge aborted) — not stuck mid-merge.
|
|
142
|
+
const status = await gitOut(baseRepo, ['status', '--porcelain=v1']);
|
|
143
|
+
expect(status.trim()).toBe('');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { execFile } from 'node:child_process';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import os from 'node:os';
|
|
7
|
+
import type { WorkspaceService } from '../../../workspace/workspace.service.js';
|
|
8
|
+
import { WorkflowHooks } from '../../workflow-hooks.js';
|
|
9
|
+
import { GitService } from '../git.service.js';
|
|
10
|
+
import { parsePorcelainZ } from '../git.service.js';
|
|
11
|
+
|
|
12
|
+
const execFileAsync = promisify(execFile);
|
|
13
|
+
const PROCESS_MAP_DIR = 'knowledge-base';
|
|
14
|
+
|
|
15
|
+
async function mkTmpRoot(): Promise<string> {
|
|
16
|
+
return fs.mkdtemp(path.join(os.tmpdir(), 'bevel-pending-changes-'));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function runGit(cwd: string, args: string[]): Promise<void> {
|
|
20
|
+
await execFileAsync('git', args, {
|
|
21
|
+
cwd,
|
|
22
|
+
env: {
|
|
23
|
+
...process.env,
|
|
24
|
+
GIT_AUTHOR_NAME: 'Test',
|
|
25
|
+
GIT_AUTHOR_EMAIL: 't@x.com',
|
|
26
|
+
GIT_COMMITTER_NAME: 'Test',
|
|
27
|
+
GIT_COMMITTER_EMAIL: 't@x.com',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function seedWorkspace(
|
|
33
|
+
root: string,
|
|
34
|
+
workspaceId: string,
|
|
35
|
+
): Promise<{ workspaceDir: string; repo: string }> {
|
|
36
|
+
const workspaceDir = path.join(root, workspaceId);
|
|
37
|
+
const repo = path.join(workspaceDir, PROCESS_MAP_DIR);
|
|
38
|
+
await fs.mkdir(repo, { recursive: true });
|
|
39
|
+
await runGit(repo, ['init', '-b', 'current-company-state']);
|
|
40
|
+
return { workspaceDir, repo };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function writeFile(repo: string, relativePath: string, contents: string): Promise<void> {
|
|
44
|
+
const absolutePath = path.join(repo, relativePath);
|
|
45
|
+
await fs.mkdir(path.dirname(absolutePath), { recursive: true });
|
|
46
|
+
await fs.writeFile(absolutePath, contents);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function commitFile(
|
|
50
|
+
repo: string,
|
|
51
|
+
relativePath: string,
|
|
52
|
+
contents: string,
|
|
53
|
+
subject: string,
|
|
54
|
+
): Promise<void> {
|
|
55
|
+
await writeFile(repo, relativePath, contents);
|
|
56
|
+
await runGit(repo, ['add', relativePath]);
|
|
57
|
+
await runGit(repo, ['commit', '-m', subject]);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
function stubWorkspaceService(workspaceId: string, workspaceDir: string): WorkspaceService {
|
|
62
|
+
return {
|
|
63
|
+
getWorkspacePath: async (id: string) => {
|
|
64
|
+
if (id !== workspaceId) throw new Error(`unexpected workspace ${id}`);
|
|
65
|
+
return workspaceDir;
|
|
66
|
+
},
|
|
67
|
+
} as unknown as WorkspaceService;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function makeSvc(root: string, workspaceId: string) {
|
|
71
|
+
const { workspaceDir, repo } = await seedWorkspace(root, workspaceId);
|
|
72
|
+
const svc = new GitService(
|
|
73
|
+
stubWorkspaceService(workspaceId, workspaceDir),
|
|
74
|
+
new WorkflowHooks(),
|
|
75
|
+
'knowledge-base',
|
|
76
|
+
);
|
|
77
|
+
return { svc, repo };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
describe('GitService.pendingChanges', () => {
|
|
81
|
+
let root: string;
|
|
82
|
+
const workspaceId = 'ws-pending-1';
|
|
83
|
+
|
|
84
|
+
beforeEach(async () => {
|
|
85
|
+
root = await mkTmpRoot();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
afterEach(async () => {
|
|
89
|
+
await fs.rm(root, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('lists an untracked file that has never been added', async () => {
|
|
93
|
+
const { svc, repo } = await makeSvc(root, workspaceId);
|
|
94
|
+
await commitFile(repo, 'Knowledge/Seed.md', 'seed\n', 'seed');
|
|
95
|
+
await runGit(repo, ['checkout', '-b', 'ali/demo']);
|
|
96
|
+
await writeFile(repo, 'juan.md', 'hello\n');
|
|
97
|
+
|
|
98
|
+
expect(await svc.pendingChanges(workspaceId)).toEqual(['juan.md']);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('lists a modified tracked file once', async () => {
|
|
102
|
+
const { svc, repo } = await makeSvc(root, workspaceId);
|
|
103
|
+
await commitFile(repo, 'Knowledge/Foo.md', 'one\n', 'add foo');
|
|
104
|
+
await runGit(repo, ['checkout', '-b', 'ali/demo']);
|
|
105
|
+
await writeFile(repo, 'Knowledge/Foo.md', 'two\n');
|
|
106
|
+
|
|
107
|
+
expect(await svc.pendingChanges(workspaceId)).toEqual(['Knowledge/Foo.md']);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('lists a deleted tracked file', async () => {
|
|
111
|
+
const { svc, repo } = await makeSvc(root, workspaceId);
|
|
112
|
+
await commitFile(repo, 'Knowledge/Foo.md', 'one\n', 'add foo');
|
|
113
|
+
await runGit(repo, ['checkout', '-b', 'ali/demo']);
|
|
114
|
+
await fs.rm(path.join(repo, 'Knowledge/Foo.md'));
|
|
115
|
+
|
|
116
|
+
expect(await svc.pendingChanges(workspaceId)).toEqual(['Knowledge/Foo.md']);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('lists a staged-but-uncommitted new file exactly once', async () => {
|
|
120
|
+
const { svc, repo } = await makeSvc(root, workspaceId);
|
|
121
|
+
await commitFile(repo, 'Knowledge/Seed.md', 'seed\n', 'seed');
|
|
122
|
+
await runGit(repo, ['checkout', '-b', 'ali/demo']);
|
|
123
|
+
await writeFile(repo, 'Knowledge/Foo.md', 'new\n');
|
|
124
|
+
await runGit(repo, ['add', 'Knowledge/Foo.md']);
|
|
125
|
+
|
|
126
|
+
expect(await svc.pendingChanges(workspaceId)).toEqual(['Knowledge/Foo.md']);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('lists the new path only for a rename, not the old one', async () => {
|
|
130
|
+
const { svc, repo } = await makeSvc(root, workspaceId);
|
|
131
|
+
await commitFile(repo, 'Knowledge/Old.md', 'one\n', 'add old');
|
|
132
|
+
await runGit(repo, ['checkout', '-b', 'ali/demo']);
|
|
133
|
+
await runGit(repo, ['mv', 'Knowledge/Old.md', 'Knowledge/New.md']);
|
|
134
|
+
|
|
135
|
+
expect(await svc.pendingChanges(workspaceId)).toEqual(['Knowledge/New.md']);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('honours .gitignore — ignored untracked files are excluded', async () => {
|
|
139
|
+
const { svc, repo } = await makeSvc(root, workspaceId);
|
|
140
|
+
await commitFile(repo, 'Knowledge/Seed.md', 'seed\n', 'seed');
|
|
141
|
+
await runGit(repo, ['checkout', '-b', 'ali/demo']);
|
|
142
|
+
await writeFile(repo, '.gitignore', 'secret.txt\n');
|
|
143
|
+
await writeFile(repo, 'secret.txt', 'shh\n');
|
|
144
|
+
await writeFile(repo, 'visible.md', 'ok\n');
|
|
145
|
+
|
|
146
|
+
const paths = await svc.pendingChanges(workspaceId);
|
|
147
|
+
expect(paths).toContain('.gitignore');
|
|
148
|
+
expect(paths).toContain('visible.md');
|
|
149
|
+
expect(paths).not.toContain('secret.txt');
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('preserves filenames with spaces verbatim', async () => {
|
|
153
|
+
const { svc, repo } = await makeSvc(root, workspaceId);
|
|
154
|
+
await commitFile(repo, 'Knowledge/Seed.md', 'seed\n', 'seed');
|
|
155
|
+
await runGit(repo, ['checkout', '-b', 'ali/demo']);
|
|
156
|
+
await writeFile(repo, 'hello world.md', 'ok\n');
|
|
157
|
+
|
|
158
|
+
expect(await svc.pendingChanges(workspaceId)).toEqual(['hello world.md']);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('returns an empty list when the tree is clean', async () => {
|
|
162
|
+
const { svc, repo } = await makeSvc(root, workspaceId);
|
|
163
|
+
await commitFile(repo, 'Knowledge/Seed.md', 'seed\n', 'seed');
|
|
164
|
+
await runGit(repo, ['checkout', '-b', 'ali/demo']);
|
|
165
|
+
|
|
166
|
+
expect(await svc.pendingChanges(workspaceId)).toEqual([]);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('combines modified + deleted + staged + untracked without duplicates', async () => {
|
|
170
|
+
const { svc, repo } = await makeSvc(root, workspaceId);
|
|
171
|
+
await commitFile(repo, 'Knowledge/Mod.md', 'one\n', 'seed mod');
|
|
172
|
+
await commitFile(repo, 'Knowledge/Del.md', 'gone\n', 'seed del');
|
|
173
|
+
await runGit(repo, ['checkout', '-b', 'ali/demo']);
|
|
174
|
+
|
|
175
|
+
// Modified tracked.
|
|
176
|
+
await writeFile(repo, 'Knowledge/Mod.md', 'two\n');
|
|
177
|
+
// Deleted tracked (on disk only, not staged).
|
|
178
|
+
await fs.rm(path.join(repo, 'Knowledge/Del.md'));
|
|
179
|
+
// Staged new file.
|
|
180
|
+
await writeFile(repo, 'Knowledge/Staged.md', 'staged\n');
|
|
181
|
+
await runGit(repo, ['add', 'Knowledge/Staged.md']);
|
|
182
|
+
// Plain untracked.
|
|
183
|
+
await writeFile(repo, 'juan.md', 'hi\n');
|
|
184
|
+
|
|
185
|
+
const paths = await svc.pendingChanges(workspaceId);
|
|
186
|
+
expect(paths.sort()).toEqual([
|
|
187
|
+
'Knowledge/Del.md',
|
|
188
|
+
'Knowledge/Mod.md',
|
|
189
|
+
'Knowledge/Staged.md',
|
|
190
|
+
'juan.md',
|
|
191
|
+
]);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
describe('parsePorcelainZ', () => {
|
|
196
|
+
it('returns empty for empty input', () => {
|
|
197
|
+
expect(parsePorcelainZ('')).toEqual([]);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('parses an untracked entry', () => {
|
|
201
|
+
expect(parsePorcelainZ('?? juan.md\0')).toEqual(['juan.md']);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('parses a modified entry', () => {
|
|
205
|
+
expect(parsePorcelainZ(' M Knowledge/Foo.md\0')).toEqual(['Knowledge/Foo.md']);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('parses a rename by keeping the new path and dropping the old one', () => {
|
|
209
|
+
expect(parsePorcelainZ('R Knowledge/New.md\0Knowledge/Old.md\0'))
|
|
210
|
+
.toEqual(['Knowledge/New.md']);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('parses a copy the same way as a rename', () => {
|
|
214
|
+
expect(parsePorcelainZ('C b.md\0a.md\0')).toEqual(['b.md']);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('dedupes multiple entries pointing at the same path', () => {
|
|
218
|
+
expect(parsePorcelainZ('MM foo.md\0')).toEqual(['foo.md']);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('preserves spaces in filenames', () => {
|
|
222
|
+
expect(parsePorcelainZ('?? hello world.md\0')).toEqual(['hello world.md']);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('parses a mix of entries in one buffer', () => {
|
|
226
|
+
const buf =
|
|
227
|
+
' M Knowledge/Mod.md\0' +
|
|
228
|
+
' D Knowledge/Del.md\0' +
|
|
229
|
+
'A Knowledge/Staged.md\0' +
|
|
230
|
+
'?? juan.md\0' +
|
|
231
|
+
'R Knowledge/New.md\0Knowledge/Old.md\0';
|
|
232
|
+
expect(parsePorcelainZ(buf).sort()).toEqual([
|
|
233
|
+
'Knowledge/Del.md',
|
|
234
|
+
'Knowledge/Mod.md',
|
|
235
|
+
'Knowledge/New.md',
|
|
236
|
+
'Knowledge/Staged.md',
|
|
237
|
+
'juan.md',
|
|
238
|
+
]);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { execFile } from 'node:child_process';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import os from 'node:os';
|
|
7
|
+
import type { AuthUser } from '@bevel-software/platform-shared';
|
|
8
|
+
import { GitService } from '../git.service.js';
|
|
9
|
+
import { runGit, gitOut, stubWorkflowHooks, stubWorkspaceService } from './git-test-helpers.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The post-merge refresh path: `WorkflowService.mergeChangeRequest` merges a
|
|
13
|
+
* change request onto `origin/<base>` and then pulls the BASE branch's own
|
|
14
|
+
* workspace so its working tree (what every file read serves) isn't left behind
|
|
15
|
+
* the remote.
|
|
16
|
+
*
|
|
17
|
+
* The bug this covers: that pull ran against a clone whose git config had
|
|
18
|
+
* drifted — a duplicated `remote.origin.fetch` refspec and/or a multi-valued
|
|
19
|
+
* `branch.<base>.merge` — so git refused to refresh it with "Cannot rebase onto
|
|
20
|
+
* multiple branches", and the merge was followed by a
|
|
21
|
+
* `[merge] post-merge pull … failed` warning with the workspace stuck on the
|
|
22
|
+
* pre-merge tree.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const execFileAsync = promisify(execFile);
|
|
26
|
+
const BASE = 'current-company-state';
|
|
27
|
+
const SOURCE = 'alice/add-feature';
|
|
28
|
+
const KB_DIR = 'knowledge-base';
|
|
29
|
+
const USER: AuthUser = { id: 'u1', email: 'alice@example.com', name: 'Alice' };
|
|
30
|
+
|
|
31
|
+
/** Clone `branch` into `<root>/<wsId>/knowledge-base`, like prod's layout. */
|
|
32
|
+
async function cloneWorkspace(root: string, upstream: string, branch: string): Promise<string> {
|
|
33
|
+
const wsDir = path.join(root, encodeURIComponent(branch));
|
|
34
|
+
const repo = path.join(wsDir, KB_DIR);
|
|
35
|
+
await fs.mkdir(wsDir, { recursive: true });
|
|
36
|
+
await runGit(root, ['clone', '-b', branch, upstream, repo]);
|
|
37
|
+
await runGit(repo, ['config', 'user.email', 'workspace@bevel.test']);
|
|
38
|
+
await runGit(repo, ['config', 'user.name', 'bevel Workspace']);
|
|
39
|
+
return repo;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Bare upstream carrying BASE and a SOURCE branch with one new file, plus the
|
|
44
|
+
* two workspaces prod would have: the source draft's (where the merge runs) and
|
|
45
|
+
* the base branch's own (the one the post-merge pull refreshes).
|
|
46
|
+
*/
|
|
47
|
+
async function seed(root: string) {
|
|
48
|
+
const upstream = path.join(root, 'upstream.git');
|
|
49
|
+
await runGit(root, ['init', '--bare', '-b', BASE, upstream]);
|
|
50
|
+
|
|
51
|
+
const seedDir = path.join(root, '.seed');
|
|
52
|
+
await fs.mkdir(seedDir);
|
|
53
|
+
await runGit(seedDir, ['init', '-b', BASE]);
|
|
54
|
+
await runGit(seedDir, ['remote', 'add', 'origin', upstream]);
|
|
55
|
+
await fs.writeFile(path.join(seedDir, 'base.md'), 'base\n');
|
|
56
|
+
await runGit(seedDir, ['add', '-A']);
|
|
57
|
+
await runGit(seedDir, ['commit', '-m', 'base']);
|
|
58
|
+
await runGit(seedDir, ['push', 'origin', BASE]);
|
|
59
|
+
await runGit(seedDir, ['checkout', '-b', SOURCE]);
|
|
60
|
+
await fs.writeFile(path.join(seedDir, 'feature.md'), 'from the change request\n');
|
|
61
|
+
await runGit(seedDir, ['add', '-A']);
|
|
62
|
+
await runGit(seedDir, ['commit', '-m', 'add feature']);
|
|
63
|
+
await runGit(seedDir, ['push', 'origin', SOURCE]);
|
|
64
|
+
|
|
65
|
+
const sourceRepo = await cloneWorkspace(root, upstream, SOURCE);
|
|
66
|
+
const baseRepo = await cloneWorkspace(root, upstream, BASE);
|
|
67
|
+
return { upstream, sourceRepo, baseRepo };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
describe('post-merge refresh of the target branch workspace', () => {
|
|
71
|
+
let root: string;
|
|
72
|
+
const sourceWsId = encodeURIComponent(SOURCE);
|
|
73
|
+
const baseWsId = encodeURIComponent(BASE);
|
|
74
|
+
|
|
75
|
+
beforeEach(async () => {
|
|
76
|
+
root = await fs.mkdtemp(path.join(os.tmpdir(), 'bevel-post-merge-pull-'));
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
afterEach(async () => {
|
|
80
|
+
await fs.rm(root, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 }).catch(() => {});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('pulls the target workspace up to origin after a merge, even with a drifted clone config', async () => {
|
|
84
|
+
const { sourceRepo, baseRepo } = await seed(root);
|
|
85
|
+
|
|
86
|
+
// The target branch's workspace has drifted into the state that strands the
|
|
87
|
+
// refresh: the branch tracks two merge refs and origin is fetched through
|
|
88
|
+
// three refspecs.
|
|
89
|
+
await runGit(baseRepo, ['config', '--add', `branch.${BASE}.merge`, `refs/heads/${SOURCE}`]);
|
|
90
|
+
await runGit(baseRepo, ['config', '--add', 'remote.origin.fetch', '+refs/heads/*:refs/remotes/origin/*']);
|
|
91
|
+
await runGit(baseRepo, [
|
|
92
|
+
'config', '--add', 'remote.origin.fetch', `+refs/heads/${BASE}:refs/remotes/origin/${BASE}`,
|
|
93
|
+
]);
|
|
94
|
+
// Guard: in this state git really does refuse to rebase — without the fix
|
|
95
|
+
// this is exactly what the post-merge pull hit. `LC_ALL`/`LANG` pinned to
|
|
96
|
+
// `C` for the same reason `GitService.git` pins them: the assertion below
|
|
97
|
+
// matches git's English text, and a non-English runner would otherwise
|
|
98
|
+
// report a false regression.
|
|
99
|
+
await expect(
|
|
100
|
+
execFileAsync('git', ['pull', '--rebase'], {
|
|
101
|
+
cwd: baseRepo,
|
|
102
|
+
env: { ...process.env, LC_ALL: 'C', LANG: 'C' },
|
|
103
|
+
}),
|
|
104
|
+
).rejects.toThrow(/multiple branches/i);
|
|
105
|
+
|
|
106
|
+
const git = new GitService(
|
|
107
|
+
stubWorkspaceService({
|
|
108
|
+
[sourceWsId]: path.dirname(sourceRepo),
|
|
109
|
+
[baseWsId]: path.dirname(baseRepo),
|
|
110
|
+
}),
|
|
111
|
+
stubWorkflowHooks(),
|
|
112
|
+
KB_DIR,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// 1. The merge lands on origin/BASE (run from the caller's workspace).
|
|
116
|
+
const merged = await git.mergeChangeRequest(
|
|
117
|
+
sourceWsId, SOURCE, BASE, { subject: 'Add feature (#1)', body: 'Merged via Bevel' }, USER,
|
|
118
|
+
);
|
|
119
|
+
expect(merged.kind).toBe('merged');
|
|
120
|
+
|
|
121
|
+
// 2. The post-merge refresh of the TARGET branch's own workspace succeeds.
|
|
122
|
+
await expect(git.pull(baseWsId)).resolves.toBeUndefined();
|
|
123
|
+
|
|
124
|
+
// The workspace is at origin's head, and serves the merged file.
|
|
125
|
+
const originHead = await gitOut(baseRepo, ['rev-parse', `origin/${BASE}`]);
|
|
126
|
+
expect(await gitOut(baseRepo, ['rev-parse', 'HEAD'])).toBe(originHead);
|
|
127
|
+
if (merged.kind === 'merged') expect(originHead).toBe(merged.sha);
|
|
128
|
+
const feature = await fs.readFile(path.join(baseRepo, 'feature.md'), 'utf8');
|
|
129
|
+
expect(feature.replace(/\r\n/g, '\n')).toBe('from the change request\n');
|
|
130
|
+
|
|
131
|
+
// The clone was repaired rather than merely worked around, so the next
|
|
132
|
+
// refresh starts from a healthy config.
|
|
133
|
+
const mergeRefs = (await gitOut(baseRepo, ['config', '--get-all', `branch.${BASE}.merge`]))
|
|
134
|
+
.split('\n').filter(Boolean);
|
|
135
|
+
expect(mergeRefs).toEqual([`refs/heads/${BASE}`]);
|
|
136
|
+
const refspecs = (await gitOut(baseRepo, ['config', '--get-all', 'remote.origin.fetch']))
|
|
137
|
+
.split('\n').filter(Boolean);
|
|
138
|
+
expect(refspecs).toEqual(['+refs/heads/*:refs/remotes/origin/*']);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// The reported failure, reproduced. `git pull` reads its rebase target from
|
|
142
|
+
// `.git/FETCH_HEAD`, and the app fetches into the same clone from paths that
|
|
143
|
+
// don't share the workspace mutex (`GitService.fetchOriginIfStale`,
|
|
144
|
+
// `WorkspaceService.ensureRemotesFetched` — both driven by the polling the UI
|
|
145
|
+
// does around a merge). On a clone whose `branch.<base>.merge` has drifted to
|
|
146
|
+
// two values, one of those bare fetches writes TWO for-merge FETCH_HEAD
|
|
147
|
+
// entries; landing inside the pull's fetch→read window makes it die with
|
|
148
|
+
// "Cannot rebase onto multiple branches".
|
|
149
|
+
//
|
|
150
|
+
// Reproduced deterministically below: the drift is applied, ONE real bare
|
|
151
|
+
// fetch is run to capture the exact FETCH_HEAD bytes it produces (asserted to
|
|
152
|
+
// carry two for-merge entries — the loaded gun), and a second process then
|
|
153
|
+
// replays those real bytes in a tight loop while the refresh runs. Replaying
|
|
154
|
+
// is the concurrent fetch's last step; looping it removes the timing luck
|
|
155
|
+
// that a `git fetch` loop leaves to chance. Against the pre-fix
|
|
156
|
+
// `git pull --rebase --autostash origin <base>` this dies with the reported
|
|
157
|
+
// fatal; the refresh now touches no shared state, so it cannot.
|
|
158
|
+
it('refreshes the target workspace while a concurrent fetch rewrites FETCH_HEAD', async () => {
|
|
159
|
+
const { sourceRepo, baseRepo } = await seed(root);
|
|
160
|
+
const git = new GitService(
|
|
161
|
+
stubWorkspaceService({
|
|
162
|
+
[sourceWsId]: path.dirname(sourceRepo),
|
|
163
|
+
[baseWsId]: path.dirname(baseRepo),
|
|
164
|
+
}),
|
|
165
|
+
stubWorkflowHooks(),
|
|
166
|
+
KB_DIR,
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
const merged = await git.mergeChangeRequest(
|
|
170
|
+
sourceWsId, SOURCE, BASE, { subject: 'Add feature (#1)', body: 'Merged via Bevel' }, USER,
|
|
171
|
+
);
|
|
172
|
+
expect(merged.kind).toBe('merged');
|
|
173
|
+
|
|
174
|
+
// The drift, then one real bare fetch — exactly what
|
|
175
|
+
// `fetchOriginIfStale` / `ensureRemotesFetched` run outside the mutex.
|
|
176
|
+
await runGit(baseRepo, ['config', '--add', `branch.${BASE}.merge`, `refs/heads/${SOURCE}`]);
|
|
177
|
+
await runGit(baseRepo, ['fetch', '--prune', 'origin']);
|
|
178
|
+
const fetchHeadPath = path.join(baseRepo, '.git', 'FETCH_HEAD');
|
|
179
|
+
const concurrentFetchWrote = await fs.readFile(fetchHeadPath, 'utf8');
|
|
180
|
+
const forMerge = concurrentFetchWrote
|
|
181
|
+
.split('\n').filter((l) => l && !l.includes('not-for-merge'));
|
|
182
|
+
expect(forMerge.length).toBe(2);
|
|
183
|
+
|
|
184
|
+
// Now run that same bare fetch in a loop alongside the refresh. It re-adds
|
|
185
|
+
// the drift each round the way whatever added it in production kept doing
|
|
186
|
+
// — the refresh's own self-heal would otherwise disarm the reproduction
|
|
187
|
+
// after round one. A real `git fetch` (rather than a tight write loop) also
|
|
188
|
+
// keeps the competitor self-throttling instead of starving the box.
|
|
189
|
+
//
|
|
190
|
+
// Driven from Node rather than `sh -c` so the suite stays runnable on
|
|
191
|
+
// Windows: each round still spawns real, genuinely concurrent git
|
|
192
|
+
// processes — `git.pull` is awaiting its own child while these run.
|
|
193
|
+
let stop = false;
|
|
194
|
+
const noise = (async () => {
|
|
195
|
+
while (!stop) {
|
|
196
|
+
await runGit(baseRepo, [
|
|
197
|
+
'config', '--add', `branch.${BASE}.merge`, `refs/heads/${SOURCE}`,
|
|
198
|
+
]).catch(() => undefined);
|
|
199
|
+
await runGit(baseRepo, ['fetch', '--prune', 'origin']).catch(() => undefined);
|
|
200
|
+
}
|
|
201
|
+
})();
|
|
202
|
+
try {
|
|
203
|
+
// ~40% of rounds hit the fatal pre-fix (measured), so 20 rounds makes a
|
|
204
|
+
// pre-fix regression a practical certainty while staying quick.
|
|
205
|
+
for (let round = 0; round < 20; round += 1) {
|
|
206
|
+
await expect(git.pull(baseWsId)).resolves.toBeUndefined();
|
|
207
|
+
}
|
|
208
|
+
} finally {
|
|
209
|
+
stop = true;
|
|
210
|
+
await noise;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Still exactly where the merge left origin, with the merged file served.
|
|
214
|
+
expect(await gitOut(baseRepo, ['rev-parse', 'HEAD']))
|
|
215
|
+
.toBe(await gitOut(baseRepo, ['rev-parse', `origin/${BASE}`]));
|
|
216
|
+
const feature = await fs.readFile(path.join(baseRepo, 'feature.md'), 'utf8');
|
|
217
|
+
expect(feature.replace(/\r\n/g, '\n')).toBe('from the change request\n');
|
|
218
|
+
}, 60_000);
|
|
219
|
+
|
|
220
|
+
// The same config drift, one step earlier in the flow. `git fetch origin
|
|
221
|
+
// <branch>` updates `refs/remotes/origin/<branch>` only *opportunistically* —
|
|
222
|
+
// git consults `remote.origin.fetch` to decide — so a refspec narrowed to
|
|
223
|
+
// some other branch leaves `origin/<source>` frozen at whatever the clone
|
|
224
|
+
// last saw. The merge then lands a stale source tip on the base and the CR's
|
|
225
|
+
// latest revision silently goes missing (and every push attempt burns against
|
|
226
|
+
// the same stale ref). Naming the destination refspecs explicitly is what
|
|
227
|
+
// makes the fetch independent of that config.
|
|
228
|
+
it('merges the latest source tip even when remote.origin.fetch no longer covers it', async () => {
|
|
229
|
+
const { upstream, sourceRepo, baseRepo } = await seed(root);
|
|
230
|
+
|
|
231
|
+
// Drift: the clone the merge runs in now fetches ONLY the base branch, so
|
|
232
|
+
// nothing refreshes `origin/<SOURCE>` through ambient config any more.
|
|
233
|
+
await runGit(sourceRepo, [
|
|
234
|
+
'config', '--replace-all', 'remote.origin.fetch',
|
|
235
|
+
`+refs/heads/${BASE}:refs/remotes/origin/${BASE}`,
|
|
236
|
+
]);
|
|
237
|
+
|
|
238
|
+
// The change request gets another revision pushed after that clone's last
|
|
239
|
+
// sight of it — the commit the merge must not miss.
|
|
240
|
+
const author = path.join(root, '.author');
|
|
241
|
+
await runGit(root, ['clone', '-b', SOURCE, upstream, author]);
|
|
242
|
+
await fs.writeFile(path.join(author, 'revision.md'), 'second revision\n');
|
|
243
|
+
await runGit(author, ['add', '-A']);
|
|
244
|
+
await runGit(author, ['commit', '-m', 'address review feedback']);
|
|
245
|
+
await runGit(author, ['push', 'origin', SOURCE]);
|
|
246
|
+
const latestSource = await gitOut(author, ['rev-parse', 'HEAD']);
|
|
247
|
+
|
|
248
|
+
const git = new GitService(
|
|
249
|
+
stubWorkspaceService({
|
|
250
|
+
[sourceWsId]: path.dirname(sourceRepo),
|
|
251
|
+
[baseWsId]: path.dirname(baseRepo),
|
|
252
|
+
}),
|
|
253
|
+
stubWorkflowHooks(),
|
|
254
|
+
KB_DIR,
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
const merged = await git.mergeChangeRequest(
|
|
258
|
+
sourceWsId, SOURCE, BASE, { subject: 'Add feature (#1)', body: 'Merged via Bevel' }, USER,
|
|
259
|
+
);
|
|
260
|
+
expect(merged.kind).toBe('merged');
|
|
261
|
+
|
|
262
|
+
// Origin's base carries the LATEST source commit, not the tip the drifted
|
|
263
|
+
// refspec would have left behind.
|
|
264
|
+
const upstreamLog = await gitOut(upstream, ['log', '--format=%H', BASE]);
|
|
265
|
+
expect(upstreamLog.split('\n')).toContain(latestSource);
|
|
266
|
+
|
|
267
|
+
// ...and the post-merge refresh of the base workspace serves that revision.
|
|
268
|
+
await expect(git.pull(baseWsId)).resolves.toBeUndefined();
|
|
269
|
+
const revision = await fs.readFile(path.join(baseRepo, 'revision.md'), 'utf8');
|
|
270
|
+
expect(revision.replace(/\r\n/g, '\n')).toBe('second revision\n');
|
|
271
|
+
});
|
|
272
|
+
});
|