@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,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure parse → edit → re-emit editor for `roles.yaml`.
|
|
3
|
+
*
|
|
4
|
+
* WHY re-emit and not a line-splice (cf. `access-splice.ts`): `access-splice.ts`
|
|
5
|
+
* splices `access.md` line-by-line specifically because those files carry a
|
|
6
|
+
* markdown BODY below the frontmatter (the repo-root one is a whole README)
|
|
7
|
+
* that a parse→emit round-trip would silently delete. `roles.yaml` has no body
|
|
8
|
+
* and no frontmatter fence — it is a plain `roles:` mapping of display-name →
|
|
9
|
+
* email list — and no real `roles.yaml` in the repo carries comments. So we
|
|
10
|
+
* parse the file into a model, apply the edit, and re-emit a canonical,
|
|
11
|
+
* deterministic file. Re-emit is idempotent (re-emitting an unchanged model
|
|
12
|
+
* yields byte-identical text), so a single edit moves only the lines it
|
|
13
|
+
* actually changes. The trade-off — hand-written comments are not preserved —
|
|
14
|
+
* is a documented non-goal.
|
|
15
|
+
*
|
|
16
|
+
* roles: (always the top-level key)
|
|
17
|
+
* Admin: (role display name, indent 2)
|
|
18
|
+
* - a@x.eu (member email, indent 4)
|
|
19
|
+
* - b@x.eu
|
|
20
|
+
* Empty Role: [] (the only empty-list form the subset parser
|
|
21
|
+
* reads back — a bare `Empty Role:` parses to
|
|
22
|
+
* null and fails parseRolesYaml's list check)
|
|
23
|
+
*
|
|
24
|
+
* Every mutation returns `{ text, changed }`; `changed: false` means the edit
|
|
25
|
+
* was a no-op (e.g. adding a member who already exists) and the caller should
|
|
26
|
+
* skip the commit. Role ORDER is preserved as parsed; a newly created role is
|
|
27
|
+
* appended last. Member emails within a role are canonicalised + de-duplicated.
|
|
28
|
+
*
|
|
29
|
+
* This module does NOT enforce the Admin-must-exist / no-self-lockout
|
|
30
|
+
* invariants — those are policy and live in `roles-admin.service.ts`. It only
|
|
31
|
+
* guarantees the emitted text is structurally well-formed YAML the resolver can
|
|
32
|
+
* load (the service additionally runs `validateRolesYaml` as a backstop gate).
|
|
33
|
+
*/
|
|
34
|
+
/** Bad-input failure when editing roles.yaml (invalid name/email, unknown role). */
|
|
35
|
+
export declare class RolesEditError extends Error {
|
|
36
|
+
readonly status: number;
|
|
37
|
+
constructor(message: string, status?: number);
|
|
38
|
+
}
|
|
39
|
+
/** One role in parse order: display name + its de-duplicated member emails. */
|
|
40
|
+
export interface RoleModel {
|
|
41
|
+
displayName: string;
|
|
42
|
+
/** canonicalised, de-duplicated, in first-seen order */
|
|
43
|
+
members: string[];
|
|
44
|
+
}
|
|
45
|
+
export type RolesModel = RoleModel[];
|
|
46
|
+
export interface EditResult {
|
|
47
|
+
text: string;
|
|
48
|
+
changed: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reject role display names whose characters would corrupt the emitted YAML.
|
|
52
|
+
* `canonicalRoleName` only trims/lowercases/collapses spaces — it does NOT
|
|
53
|
+
* reject structural characters, so a name like `Sales: West` or `#temp` would
|
|
54
|
+
* round-trip into a broken file. This guard is the structural complement to the
|
|
55
|
+
* reserved/duplicate checks the service layer applies.
|
|
56
|
+
*
|
|
57
|
+
* `:` mis-tokenises as a nested mapping key
|
|
58
|
+
* `#` truncated as a comment by the subset parser's stripComment
|
|
59
|
+
* `<` / `>` collide with the `Name <email>` user-reference shape
|
|
60
|
+
* leading - tokenises as a list item
|
|
61
|
+
* \x00-\x1f control chars / newlines break line structure outright
|
|
62
|
+
*/
|
|
63
|
+
export declare function assertSafeRoleDisplayName(displayName: string): void;
|
|
64
|
+
/**
|
|
65
|
+
* Parse `roles.yaml` text into the ordered model. Tolerant of an empty/missing
|
|
66
|
+
* file (yields `[]`). Throws RolesEditError on structurally-broken YAML — the
|
|
67
|
+
* caller reads under the lock, so a broken on-disk file is an operator problem
|
|
68
|
+
* surfaced as a 422, not a silent reset.
|
|
69
|
+
*/
|
|
70
|
+
export declare function parseRolesModel(text: string): RolesModel;
|
|
71
|
+
/**
|
|
72
|
+
* Re-emit the model as canonical `roles.yaml` text. Deterministic: same model →
|
|
73
|
+
* same bytes. An empty role is emitted as `Name: []` (round-trippable); a role
|
|
74
|
+
* with members is emitted as a block list. Always ends with a trailing newline.
|
|
75
|
+
*/
|
|
76
|
+
export declare function emitRolesModel(model: RolesModel): string;
|
|
77
|
+
/** Create a new empty role. 422 on reserved/duplicate/structurally-unsafe name. */
|
|
78
|
+
export declare function createRole(text: string, displayName: string): EditResult;
|
|
79
|
+
/** Delete a role by canonical name. 404 if absent. */
|
|
80
|
+
export declare function deleteRole(text: string, canonical: string): EditResult;
|
|
81
|
+
/** Add a member email to a role. Idempotent. 422 bad email; 404 unknown role. */
|
|
82
|
+
export declare function addMember(text: string, canonical: string, rawEmail: string): EditResult;
|
|
83
|
+
/** Remove a member email from a role. 404 unknown role; no-op if not a member. */
|
|
84
|
+
export declare function removeMember(text: string, canonical: string, rawEmail: string): EditResult;
|
|
85
|
+
/**
|
|
86
|
+
* Rename a role's display name. The canonical name MAY change (the service
|
|
87
|
+
* layer is responsible for the reference rewrite + Admin guard when it does).
|
|
88
|
+
* 404 unknown source; 422 reserved/duplicate/unsafe target.
|
|
89
|
+
*/
|
|
90
|
+
export declare function renameRoleDisplay(text: string, canonical: string, newDisplayName: string): EditResult;
|
|
91
|
+
//# sourceMappingURL=roles-edit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles-edit.d.ts","sourceRoot":"","sources":["../../../src/modules/access/roles-edit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAUH,oFAAoF;AACpF,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,MAAM,SAAM;CAK1C;AAED,+EAA+E;AAC/E,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,EAAE,CAAC;AAErC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAanE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAyCxD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAWxD;AAqBD,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU,CAYxE;AAED,sDAAsD;AACtD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CAMtE;AAED,iFAAiF;AACjF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CASvF;AAED,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAS1F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,UAAU,CAcrG"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure parse → edit → re-emit editor for `roles.yaml`.
|
|
3
|
+
*
|
|
4
|
+
* WHY re-emit and not a line-splice (cf. `access-splice.ts`): `access-splice.ts`
|
|
5
|
+
* splices `access.md` line-by-line specifically because those files carry a
|
|
6
|
+
* markdown BODY below the frontmatter (the repo-root one is a whole README)
|
|
7
|
+
* that a parse→emit round-trip would silently delete. `roles.yaml` has no body
|
|
8
|
+
* and no frontmatter fence — it is a plain `roles:` mapping of display-name →
|
|
9
|
+
* email list — and no real `roles.yaml` in the repo carries comments. So we
|
|
10
|
+
* parse the file into a model, apply the edit, and re-emit a canonical,
|
|
11
|
+
* deterministic file. Re-emit is idempotent (re-emitting an unchanged model
|
|
12
|
+
* yields byte-identical text), so a single edit moves only the lines it
|
|
13
|
+
* actually changes. The trade-off — hand-written comments are not preserved —
|
|
14
|
+
* is a documented non-goal.
|
|
15
|
+
*
|
|
16
|
+
* roles: (always the top-level key)
|
|
17
|
+
* Admin: (role display name, indent 2)
|
|
18
|
+
* - a@x.eu (member email, indent 4)
|
|
19
|
+
* - b@x.eu
|
|
20
|
+
* Empty Role: [] (the only empty-list form the subset parser
|
|
21
|
+
* reads back — a bare `Empty Role:` parses to
|
|
22
|
+
* null and fails parseRolesYaml's list check)
|
|
23
|
+
*
|
|
24
|
+
* Every mutation returns `{ text, changed }`; `changed: false` means the edit
|
|
25
|
+
* was a no-op (e.g. adding a member who already exists) and the caller should
|
|
26
|
+
* skip the commit. Role ORDER is preserved as parsed; a newly created role is
|
|
27
|
+
* appended last. Member emails within a role are canonicalised + de-duplicated.
|
|
28
|
+
*
|
|
29
|
+
* This module does NOT enforce the Admin-must-exist / no-self-lockout
|
|
30
|
+
* invariants — those are policy and live in `roles-admin.service.ts`. It only
|
|
31
|
+
* guarantees the emitted text is structurally well-formed YAML the resolver can
|
|
32
|
+
* load (the service additionally runs `validateRolesYaml` as a backstop gate).
|
|
33
|
+
*/
|
|
34
|
+
import { parseYamlSubset, canonicalRoleName, canonicalEmail, EMAIL_REGEX, RESERVED_ROLE_NAMES, } from './access-control.service.js';
|
|
35
|
+
/** Bad-input failure when editing roles.yaml (invalid name/email, unknown role). */
|
|
36
|
+
export class RolesEditError extends Error {
|
|
37
|
+
status;
|
|
38
|
+
constructor(message, status = 422) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = 'RolesEditError';
|
|
41
|
+
this.status = status;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Reject role display names whose characters would corrupt the emitted YAML.
|
|
46
|
+
* `canonicalRoleName` only trims/lowercases/collapses spaces — it does NOT
|
|
47
|
+
* reject structural characters, so a name like `Sales: West` or `#temp` would
|
|
48
|
+
* round-trip into a broken file. This guard is the structural complement to the
|
|
49
|
+
* reserved/duplicate checks the service layer applies.
|
|
50
|
+
*
|
|
51
|
+
* `:` mis-tokenises as a nested mapping key
|
|
52
|
+
* `#` truncated as a comment by the subset parser's stripComment
|
|
53
|
+
* `<` / `>` collide with the `Name <email>` user-reference shape
|
|
54
|
+
* leading - tokenises as a list item
|
|
55
|
+
* \x00-\x1f control chars / newlines break line structure outright
|
|
56
|
+
*/
|
|
57
|
+
export function assertSafeRoleDisplayName(displayName) {
|
|
58
|
+
const trimmed = displayName.trim();
|
|
59
|
+
if (!trimmed)
|
|
60
|
+
throw new RolesEditError('role name must not be empty');
|
|
61
|
+
if (/[:#<>]/.test(trimmed)) {
|
|
62
|
+
throw new RolesEditError(`role name must not contain ':', '#', '<', or '>': ${JSON.stringify(displayName)}`);
|
|
63
|
+
}
|
|
64
|
+
// eslint-disable-next-line no-control-regex
|
|
65
|
+
if (/[\x00-\x1f]/.test(trimmed)) {
|
|
66
|
+
throw new RolesEditError(`role name must not contain control characters: ${JSON.stringify(displayName)}`);
|
|
67
|
+
}
|
|
68
|
+
if (trimmed.startsWith('-')) {
|
|
69
|
+
throw new RolesEditError(`role name must not start with '-': ${JSON.stringify(displayName)}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Parse `roles.yaml` text into the ordered model. Tolerant of an empty/missing
|
|
74
|
+
* file (yields `[]`). Throws RolesEditError on structurally-broken YAML — the
|
|
75
|
+
* caller reads under the lock, so a broken on-disk file is an operator problem
|
|
76
|
+
* surfaced as a 422, not a silent reset.
|
|
77
|
+
*/
|
|
78
|
+
export function parseRolesModel(text) {
|
|
79
|
+
const trimmed = text.trim();
|
|
80
|
+
if (!trimmed)
|
|
81
|
+
return [];
|
|
82
|
+
const parsed = parseYamlSubset(text);
|
|
83
|
+
if (!parsed.ok)
|
|
84
|
+
throw new RolesEditError(`roles.yaml: ${parsed.error}`);
|
|
85
|
+
const root = parsed.value;
|
|
86
|
+
if (root == null || typeof root !== 'object' || Array.isArray(root)) {
|
|
87
|
+
throw new RolesEditError('roles.yaml: must be a top-level mapping');
|
|
88
|
+
}
|
|
89
|
+
const rolesNode = root.roles;
|
|
90
|
+
if (rolesNode == null)
|
|
91
|
+
return [];
|
|
92
|
+
if (typeof rolesNode !== 'object' || Array.isArray(rolesNode)) {
|
|
93
|
+
throw new RolesEditError("roles.yaml: 'roles' must be a mapping");
|
|
94
|
+
}
|
|
95
|
+
const model = [];
|
|
96
|
+
for (const [displayName, value] of Object.entries(rolesNode)) {
|
|
97
|
+
const members = [];
|
|
98
|
+
// A role value must be a list of emails, an empty list (`[]`), or null
|
|
99
|
+
// (`Role:` with no members). Any OTHER shape (a scalar string, a nested
|
|
100
|
+
// mapping) is a malformed file — surface it as the documented 422 rather
|
|
101
|
+
// than silently coercing it to an empty role (CodeRabbit: a coerce would
|
|
102
|
+
// let an unrelated edit rewrite a broken roles.yaml).
|
|
103
|
+
if (value !== null && !Array.isArray(value)) {
|
|
104
|
+
throw new RolesEditError(`roles.yaml: role '${displayName.trim()}' must be a list of emails`);
|
|
105
|
+
}
|
|
106
|
+
if (Array.isArray(value)) {
|
|
107
|
+
const seen = new Set();
|
|
108
|
+
for (const raw of value) {
|
|
109
|
+
// A non-string member entry is malformed — reject, don't drop.
|
|
110
|
+
if (typeof raw !== 'string') {
|
|
111
|
+
throw new RolesEditError(`roles.yaml: role '${displayName.trim()}' has a non-string member`);
|
|
112
|
+
}
|
|
113
|
+
const email = canonicalEmail(raw);
|
|
114
|
+
if (!email || seen.has(email))
|
|
115
|
+
continue;
|
|
116
|
+
seen.add(email);
|
|
117
|
+
members.push(email);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
model.push({ displayName: displayName.trim(), members });
|
|
121
|
+
}
|
|
122
|
+
return model;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Re-emit the model as canonical `roles.yaml` text. Deterministic: same model →
|
|
126
|
+
* same bytes. An empty role is emitted as `Name: []` (round-trippable); a role
|
|
127
|
+
* with members is emitted as a block list. Always ends with a trailing newline.
|
|
128
|
+
*/
|
|
129
|
+
export function emitRolesModel(model) {
|
|
130
|
+
const lines = ['roles:'];
|
|
131
|
+
for (const role of model) {
|
|
132
|
+
if (role.members.length === 0) {
|
|
133
|
+
lines.push(` ${role.displayName}: []`);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
lines.push(` ${role.displayName}:`);
|
|
137
|
+
for (const email of role.members)
|
|
138
|
+
lines.push(` - ${email}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return lines.join('\n') + '\n';
|
|
142
|
+
}
|
|
143
|
+
function findRole(model, canonical) {
|
|
144
|
+
return model.find((r) => canonicalRoleName(r.displayName) === canonical);
|
|
145
|
+
}
|
|
146
|
+
function reemit(original, model) {
|
|
147
|
+
const text = emitRolesModel(model);
|
|
148
|
+
// Compare against a re-emit of the ORIGINAL so a pure formatting difference
|
|
149
|
+
// (e.g. legacy spacing) doesn't masquerade as a content change — `changed`
|
|
150
|
+
// tracks whether the canonical model moved, which is what the commit cares
|
|
151
|
+
// about.
|
|
152
|
+
let originalCanonical;
|
|
153
|
+
try {
|
|
154
|
+
originalCanonical = emitRolesModel(parseRolesModel(original));
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
originalCanonical = original;
|
|
158
|
+
}
|
|
159
|
+
return { text, changed: text !== originalCanonical };
|
|
160
|
+
}
|
|
161
|
+
/** Create a new empty role. 422 on reserved/duplicate/structurally-unsafe name. */
|
|
162
|
+
export function createRole(text, displayName) {
|
|
163
|
+
assertSafeRoleDisplayName(displayName);
|
|
164
|
+
const canonical = canonicalRoleName(displayName);
|
|
165
|
+
if (RESERVED_ROLE_NAMES.has(canonical)) {
|
|
166
|
+
throw new RolesEditError(`'${displayName.trim()}' is a reserved name and cannot be a role`);
|
|
167
|
+
}
|
|
168
|
+
const model = parseRolesModel(text);
|
|
169
|
+
if (findRole(model, canonical)) {
|
|
170
|
+
throw new RolesEditError(`a role named '${displayName.trim()}' already exists`);
|
|
171
|
+
}
|
|
172
|
+
model.push({ displayName: displayName.trim(), members: [] });
|
|
173
|
+
return reemit(text, model);
|
|
174
|
+
}
|
|
175
|
+
/** Delete a role by canonical name. 404 if absent. */
|
|
176
|
+
export function deleteRole(text, canonical) {
|
|
177
|
+
const model = parseRolesModel(text);
|
|
178
|
+
const idx = model.findIndex((r) => canonicalRoleName(r.displayName) === canonical);
|
|
179
|
+
if (idx < 0)
|
|
180
|
+
throw new RolesEditError(`role not found: ${canonical}`, 404);
|
|
181
|
+
model.splice(idx, 1);
|
|
182
|
+
return reemit(text, model);
|
|
183
|
+
}
|
|
184
|
+
/** Add a member email to a role. Idempotent. 422 bad email; 404 unknown role. */
|
|
185
|
+
export function addMember(text, canonical, rawEmail) {
|
|
186
|
+
const email = canonicalEmail(rawEmail);
|
|
187
|
+
if (!EMAIL_REGEX.test(email))
|
|
188
|
+
throw new RolesEditError(`malformed email: ${JSON.stringify(rawEmail)}`);
|
|
189
|
+
const model = parseRolesModel(text);
|
|
190
|
+
const role = findRole(model, canonical);
|
|
191
|
+
if (!role)
|
|
192
|
+
throw new RolesEditError(`role not found: ${canonical}`, 404);
|
|
193
|
+
if (role.members.includes(email))
|
|
194
|
+
return { text: emitRolesModel(model), changed: false };
|
|
195
|
+
role.members.push(email);
|
|
196
|
+
return reemit(text, model);
|
|
197
|
+
}
|
|
198
|
+
/** Remove a member email from a role. 404 unknown role; no-op if not a member. */
|
|
199
|
+
export function removeMember(text, canonical, rawEmail) {
|
|
200
|
+
const email = canonicalEmail(rawEmail);
|
|
201
|
+
const model = parseRolesModel(text);
|
|
202
|
+
const role = findRole(model, canonical);
|
|
203
|
+
if (!role)
|
|
204
|
+
throw new RolesEditError(`role not found: ${canonical}`, 404);
|
|
205
|
+
const idx = role.members.indexOf(email);
|
|
206
|
+
if (idx < 0)
|
|
207
|
+
return { text: emitRolesModel(model), changed: false };
|
|
208
|
+
role.members.splice(idx, 1);
|
|
209
|
+
return reemit(text, model);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Rename a role's display name. The canonical name MAY change (the service
|
|
213
|
+
* layer is responsible for the reference rewrite + Admin guard when it does).
|
|
214
|
+
* 404 unknown source; 422 reserved/duplicate/unsafe target.
|
|
215
|
+
*/
|
|
216
|
+
export function renameRoleDisplay(text, canonical, newDisplayName) {
|
|
217
|
+
assertSafeRoleDisplayName(newDisplayName);
|
|
218
|
+
const newCanonical = canonicalRoleName(newDisplayName);
|
|
219
|
+
if (RESERVED_ROLE_NAMES.has(newCanonical)) {
|
|
220
|
+
throw new RolesEditError(`'${newDisplayName.trim()}' is a reserved name and cannot be a role`);
|
|
221
|
+
}
|
|
222
|
+
const model = parseRolesModel(text);
|
|
223
|
+
const role = findRole(model, canonical);
|
|
224
|
+
if (!role)
|
|
225
|
+
throw new RolesEditError(`role not found: ${canonical}`, 404);
|
|
226
|
+
if (newCanonical !== canonical && findRole(model, newCanonical)) {
|
|
227
|
+
throw new RolesEditError(`a role named '${newDisplayName.trim()}' already exists`);
|
|
228
|
+
}
|
|
229
|
+
role.displayName = newDisplayName.trim();
|
|
230
|
+
return reemit(text, model);
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=roles-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles-edit.js","sourceRoot":"","sources":["../../../src/modules/access/roles-edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-disk validity gate for `roles.yaml`.
|
|
3
|
+
*
|
|
4
|
+
* WHY this exists: `roles.yaml` is the single point of failure for the whole
|
|
5
|
+
* app. The runtime resolver's `loadModel` HARD-THROWS `AccessConfigError` on a
|
|
6
|
+
* parse failure, and `isAdmin` swallows that into `false` for EVERYONE — so a
|
|
7
|
+
* single malformed `roles.yaml` is an app-wide, in-app-unrecoverable admin
|
|
8
|
+
* lockout. The dedicated Roles & Members service already validates every
|
|
9
|
+
* candidate before writing (`assertLoadable`), but the two RAW write paths do
|
|
10
|
+
* not:
|
|
11
|
+
* - the human editor save (`PUT /workspace/:id/file`)
|
|
12
|
+
* - the agent's file tools (`LockingFilesystem.writeFile` / `writeFiles`)
|
|
13
|
+
*
|
|
14
|
+
* Both of those let an admin (or an admin-driven agent) commit a broken file.
|
|
15
|
+
* This guard plugs them: it runs the resolver's OWN parser on the candidate
|
|
16
|
+
* BEFORE a byte hits disk, and refuses the write with a 422 on any error. A
|
|
17
|
+
* write that passes here is loadable by `loadModel`, so the lockout becomes
|
|
18
|
+
* structurally unreachable through normal edits.
|
|
19
|
+
*
|
|
20
|
+
* The break-glass recovery path (for a file that got broken some OTHER way —
|
|
21
|
+
* a direct git push, a pre-guard commit) lives in `roles-admin.service.ts`.
|
|
22
|
+
*/
|
|
23
|
+
import type { FileContent } from '@mastra/core/workspace';
|
|
24
|
+
import { WorkflowDomainError } from '../workflow/workflow.errors.js';
|
|
25
|
+
/** Repo-relative basename of the roles file (it lives at the KB repo root). */
|
|
26
|
+
export declare const ROLES_YAML_BASENAME = "roles.yaml";
|
|
27
|
+
/**
|
|
28
|
+
* A raw write whose candidate `roles.yaml` would not parse. 422 (bad input) —
|
|
29
|
+
* the edit is refused and nothing is written. Carries the parser errors so the
|
|
30
|
+
* editor / agent can show exactly what's wrong.
|
|
31
|
+
*/
|
|
32
|
+
export declare class RolesYamlInvalidError extends WorkflowDomainError {
|
|
33
|
+
readonly errors: string[];
|
|
34
|
+
constructor(errors: string[]);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* True iff `workspaceRelPath` targets the KB's `roles.yaml` (the file at
|
|
38
|
+
* `<kbDirName>/roles.yaml`). Both the human save route and the agent's
|
|
39
|
+
* `LockingFilesystem` speak workspace-relative paths, so this is the form we
|
|
40
|
+
* key on. A bare `roles.yaml` (no KB prefix) is also accepted defensively.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isRolesYamlPath(workspaceRelPath: string, kbDirName: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Throw {@link RolesYamlInvalidError} if `content` does not parse as a valid
|
|
45
|
+
* `roles.yaml` per the resolver's own parser. No-op on valid content.
|
|
46
|
+
*/
|
|
47
|
+
export declare function assertRolesYamlParsable(content: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* A `LockingFilesystem` write-validator scoped to a KB dir: refuses a raw write
|
|
50
|
+
* that would leave `roles.yaml` unparseable. Pass the returned closure as the
|
|
51
|
+
* filesystem's `validateWrite` hook. Only string writes are checked — every
|
|
52
|
+
* code path that writes `roles.yaml` writes it as text; a binary write to that
|
|
53
|
+
* path is nonsensical and left alone.
|
|
54
|
+
*/
|
|
55
|
+
export declare function makeRolesYamlWriteValidator(kbDirName: string): (path: string, content: FileContent) => void;
|
|
56
|
+
//# sourceMappingURL=roles-yaml-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles-yaml-guard.d.ts","sourceRoot":"","sources":["../../../src/modules/access/roles-yaml-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,mBAAmB;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBACd,MAAM,EAAE,MAAM,EAAE;CAS7B;AAOD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAGpF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG7D;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,GAChB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,IAAI,CAM9C"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-disk validity gate for `roles.yaml`.
|
|
3
|
+
*
|
|
4
|
+
* WHY this exists: `roles.yaml` is the single point of failure for the whole
|
|
5
|
+
* app. The runtime resolver's `loadModel` HARD-THROWS `AccessConfigError` on a
|
|
6
|
+
* parse failure, and `isAdmin` swallows that into `false` for EVERYONE — so a
|
|
7
|
+
* single malformed `roles.yaml` is an app-wide, in-app-unrecoverable admin
|
|
8
|
+
* lockout. The dedicated Roles & Members service already validates every
|
|
9
|
+
* candidate before writing (`assertLoadable`), but the two RAW write paths do
|
|
10
|
+
* not:
|
|
11
|
+
* - the human editor save (`PUT /workspace/:id/file`)
|
|
12
|
+
* - the agent's file tools (`LockingFilesystem.writeFile` / `writeFiles`)
|
|
13
|
+
*
|
|
14
|
+
* Both of those let an admin (or an admin-driven agent) commit a broken file.
|
|
15
|
+
* This guard plugs them: it runs the resolver's OWN parser on the candidate
|
|
16
|
+
* BEFORE a byte hits disk, and refuses the write with a 422 on any error. A
|
|
17
|
+
* write that passes here is loadable by `loadModel`, so the lockout becomes
|
|
18
|
+
* structurally unreachable through normal edits.
|
|
19
|
+
*
|
|
20
|
+
* The break-glass recovery path (for a file that got broken some OTHER way —
|
|
21
|
+
* a direct git push, a pre-guard commit) lives in `roles-admin.service.ts`.
|
|
22
|
+
*/
|
|
23
|
+
import { parseRolesYaml } from './access-control.service.js';
|
|
24
|
+
import { WorkflowDomainError } from '../workflow/workflow.errors.js';
|
|
25
|
+
/** Repo-relative basename of the roles file (it lives at the KB repo root). */
|
|
26
|
+
export const ROLES_YAML_BASENAME = 'roles.yaml';
|
|
27
|
+
/**
|
|
28
|
+
* A raw write whose candidate `roles.yaml` would not parse. 422 (bad input) —
|
|
29
|
+
* the edit is refused and nothing is written. Carries the parser errors so the
|
|
30
|
+
* editor / agent can show exactly what's wrong.
|
|
31
|
+
*/
|
|
32
|
+
export class RolesYamlInvalidError extends WorkflowDomainError {
|
|
33
|
+
errors;
|
|
34
|
+
constructor(errors) {
|
|
35
|
+
super(`roles.yaml would be invalid and was not saved: ${errors.join('; ')}`, 422, { kind: 'roles-yaml-invalid', rolesYamlErrors: errors });
|
|
36
|
+
this.name = 'RolesYamlInvalidError';
|
|
37
|
+
this.errors = errors;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Normalise a workspace-relative path: backslashes → `/`, strip a leading `./`. */
|
|
41
|
+
function normalizeWsPath(p) {
|
|
42
|
+
return p.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* True iff `workspaceRelPath` targets the KB's `roles.yaml` (the file at
|
|
46
|
+
* `<kbDirName>/roles.yaml`). Both the human save route and the agent's
|
|
47
|
+
* `LockingFilesystem` speak workspace-relative paths, so this is the form we
|
|
48
|
+
* key on. A bare `roles.yaml` (no KB prefix) is also accepted defensively.
|
|
49
|
+
*/
|
|
50
|
+
export function isRolesYamlPath(workspaceRelPath, kbDirName) {
|
|
51
|
+
const norm = normalizeWsPath(workspaceRelPath);
|
|
52
|
+
return norm === `${kbDirName}/${ROLES_YAML_BASENAME}` || norm === ROLES_YAML_BASENAME;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Throw {@link RolesYamlInvalidError} if `content` does not parse as a valid
|
|
56
|
+
* `roles.yaml` per the resolver's own parser. No-op on valid content.
|
|
57
|
+
*/
|
|
58
|
+
export function assertRolesYamlParsable(content) {
|
|
59
|
+
const parsed = parseRolesYaml(content);
|
|
60
|
+
if (!parsed.ok)
|
|
61
|
+
throw new RolesYamlInvalidError(parsed.errors);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A `LockingFilesystem` write-validator scoped to a KB dir: refuses a raw write
|
|
65
|
+
* that would leave `roles.yaml` unparseable. Pass the returned closure as the
|
|
66
|
+
* filesystem's `validateWrite` hook. Only string writes are checked — every
|
|
67
|
+
* code path that writes `roles.yaml` writes it as text; a binary write to that
|
|
68
|
+
* path is nonsensical and left alone.
|
|
69
|
+
*/
|
|
70
|
+
export function makeRolesYamlWriteValidator(kbDirName) {
|
|
71
|
+
return (path, content) => {
|
|
72
|
+
if (typeof content !== 'string')
|
|
73
|
+
return;
|
|
74
|
+
if (!isRolesYamlPath(path, kbDirName))
|
|
75
|
+
return;
|
|
76
|
+
assertRolesYamlParsable(content);
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=roles-yaml-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles-yaml-guard.js","sourceRoot":"","sources":["../../../src/modules/access/roles-yaml-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAEhD;;;;GAIG;AACH,MAAM,OAAO,qBAAsB,SAAQ,mBAAmB;IACnD,MAAM,CAAW;IAC1B,YAAY,MAAgB;QAC1B,KAAK,CACH,kDAAkD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACrE,GAAG,EACH,EAAE,IAAI,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,EAAE,CACxD,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,oFAAoF;AACpF,SAAS,eAAe,CAAC,CAAS;IAChC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,gBAAwB,EAAE,SAAiB;IACzE,MAAM,IAAI,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAC/C,OAAO,IAAI,KAAK,GAAG,SAAS,IAAI,mBAAmB,EAAE,IAAI,IAAI,KAAK,mBAAmB,CAAC;AACxF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CACzC,SAAiB;IAEjB,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;QACvB,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO;QACxC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC;YAAE,OAAO;QAC9C,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import type { IAdminAccessService } from './admin.interface.js';
|
|
3
|
+
import '../auth/auth.middleware.js';
|
|
4
|
+
/**
|
|
5
|
+
* The CORE slice of the admin surface: just the admin-status resolver the
|
|
6
|
+
* frontend branches on (AdminMenu's "Admin only" section, the roles-recovery
|
|
7
|
+
* banner). The full admin router (feedback inbox, user administration /
|
|
8
|
+
* GDPR erasure) is an enterprise extension mounted via
|
|
9
|
+
* `ServerExtensions.authed`.
|
|
10
|
+
*
|
|
11
|
+
* NOTE (core split): in bevel-platform this endpoint lives in the enterprise
|
|
12
|
+
* `admin.routes.ts`; core serves it itself so a core-only deployment can
|
|
13
|
+
* resolve admin status. Express keeps first-match-wins, so an enterprise
|
|
14
|
+
* overlay's own `/admin/access` (mounted later) never shadows this one —
|
|
15
|
+
* both resolve through the same {@link IAdminAccessService}.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createAdminAccessRoutes(adminAccess: IAdminAccessService): express.Router;
|
|
18
|
+
//# sourceMappingURL=admin-access.routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-access.routes.d.ts","sourceRoot":"","sources":["../../../src/modules/admin/admin-access.routes.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,4BAA4B,CAAC;AAEpC;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAWxF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import '../auth/auth.middleware.js'; // Express Request augmentation
|
|
3
|
+
/**
|
|
4
|
+
* The CORE slice of the admin surface: just the admin-status resolver the
|
|
5
|
+
* frontend branches on (AdminMenu's "Admin only" section, the roles-recovery
|
|
6
|
+
* banner). The full admin router (feedback inbox, user administration /
|
|
7
|
+
* GDPR erasure) is an enterprise extension mounted via
|
|
8
|
+
* `ServerExtensions.authed`.
|
|
9
|
+
*
|
|
10
|
+
* NOTE (core split): in bevel-platform this endpoint lives in the enterprise
|
|
11
|
+
* `admin.routes.ts`; core serves it itself so a core-only deployment can
|
|
12
|
+
* resolve admin status. Express keeps first-match-wins, so an enterprise
|
|
13
|
+
* overlay's own `/admin/access` (mounted later) never shadows this one —
|
|
14
|
+
* both resolve through the same {@link IAdminAccessService}.
|
|
15
|
+
*/
|
|
16
|
+
export function createAdminAccessRoutes(adminAccess) {
|
|
17
|
+
const router = express.Router();
|
|
18
|
+
// Open to any authenticated user — returns `false` for non-admins instead of
|
|
19
|
+
// 403 so the frontend can branch on the answer without treating a normal
|
|
20
|
+
// user as an error case.
|
|
21
|
+
router.get('/admin/access', async (req, res) => {
|
|
22
|
+
res.json({ isAdmin: await adminAccess.isAdmin(req.userEmail) });
|
|
23
|
+
});
|
|
24
|
+
return router;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=admin-access.routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-access.routes.js","sourceRoot":"","sources":["../../../src/modules/admin/admin-access.routes.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,4BAA4B,CAAC,CAAC,+BAA+B;AAEpE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAgC;IACtE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,6EAA6E;IAC7E,yEAAyE;IACzE,yBAAyB;IACzB,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7C,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { IAccessControl } from '../access/access-control.interface.js';
|
|
2
|
+
import { type WorkspaceService } from '../workspace/workspace.service.js';
|
|
3
|
+
import type { IAdminAccessService } from './admin.interface.js';
|
|
4
|
+
/**
|
|
5
|
+
* Admin = holder of the `Admin` role in `roles.yaml`. We resolve it through the
|
|
6
|
+
* access model exactly as the rest of the app does — `canWrite('roles.yaml')` is
|
|
7
|
+
* the existing source of truth for Admin-role membership (only admins may write
|
|
8
|
+
* `roles.yaml`). Read from the default-branch workspace so admin status doesn't
|
|
9
|
+
* depend on whichever branch the caller happens to be on.
|
|
10
|
+
*
|
|
11
|
+
* There is no env allow-list (`ADMIN_EMAILS` is gone) — `roles.yaml` is the
|
|
12
|
+
* single source of truth.
|
|
13
|
+
*/
|
|
14
|
+
export declare class AdminAccessService implements IAdminAccessService {
|
|
15
|
+
private readonly accessControl;
|
|
16
|
+
private readonly workspaceService;
|
|
17
|
+
/** Branch whose `roles.yaml` defines admins (the authoritative default branch). */
|
|
18
|
+
private readonly branch;
|
|
19
|
+
constructor(accessControl: IAccessControl, workspaceService: WorkspaceService,
|
|
20
|
+
/** Branch whose `roles.yaml` defines admins (the authoritative default branch). */
|
|
21
|
+
branch: string);
|
|
22
|
+
isAdmin(email: string | undefined): Promise<boolean>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=admin-access.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-access.service.d.ts","sourceRoot":"","sources":["../../../src/modules/admin/admin-access.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,KAAK,gBAAgB,EAAwB,MAAM,mCAAmC,CAAC;AAChG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;IAE1D,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAHN,aAAa,EAAE,cAAc,EAC7B,gBAAgB,EAAE,gBAAgB;IACnD,mFAAmF;IAClE,MAAM,EAAE,MAAM;IAG3B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;CAe3D"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { workspaceIdForBranch } from '../workspace/workspace.service.js';
|
|
2
|
+
/**
|
|
3
|
+
* Admin = holder of the `Admin` role in `roles.yaml`. We resolve it through the
|
|
4
|
+
* access model exactly as the rest of the app does — `canWrite('roles.yaml')` is
|
|
5
|
+
* the existing source of truth for Admin-role membership (only admins may write
|
|
6
|
+
* `roles.yaml`). Read from the default-branch workspace so admin status doesn't
|
|
7
|
+
* depend on whichever branch the caller happens to be on.
|
|
8
|
+
*
|
|
9
|
+
* There is no env allow-list (`ADMIN_EMAILS` is gone) — `roles.yaml` is the
|
|
10
|
+
* single source of truth.
|
|
11
|
+
*/
|
|
12
|
+
export class AdminAccessService {
|
|
13
|
+
accessControl;
|
|
14
|
+
workspaceService;
|
|
15
|
+
branch;
|
|
16
|
+
constructor(accessControl, workspaceService,
|
|
17
|
+
/** Branch whose `roles.yaml` defines admins (the authoritative default branch). */
|
|
18
|
+
branch) {
|
|
19
|
+
this.accessControl = accessControl;
|
|
20
|
+
this.workspaceService = workspaceService;
|
|
21
|
+
this.branch = branch;
|
|
22
|
+
}
|
|
23
|
+
async isAdmin(email) {
|
|
24
|
+
if (!email)
|
|
25
|
+
return false;
|
|
26
|
+
try {
|
|
27
|
+
// Ensure the authoritative clone is on disk, then resolve Admin-role
|
|
28
|
+
// membership via the access model. Any failure (missing/invalid
|
|
29
|
+
// roles.yaml, clone error) resolves to "not admin" — the safe default.
|
|
30
|
+
await this.workspaceService.getOrCreateForBranch(this.branch);
|
|
31
|
+
return await this.accessControl.canWrite(workspaceIdForBranch(this.branch), email, 'roles.yaml');
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
// Log so an admin lockout caused by a clone / roles.yaml failure is
|
|
35
|
+
// diagnosable rather than a silent denial.
|
|
36
|
+
console.warn('[admin] isAdmin resolution failed:', err instanceof Error ? err.message : String(err));
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=admin-access.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-access.service.js","sourceRoot":"","sources":["../../../src/modules/admin/admin-access.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAGhG;;;;;;;;;GASG;AACH,MAAM,OAAO,kBAAkB;IAEV;IACA;IAEA;IAJnB,YACmB,aAA6B,EAC7B,gBAAkC;IACnD,mFAAmF;IAClE,MAAc;QAHd,kBAAa,GAAb,aAAa,CAAgB;QAC7B,qBAAgB,GAAhB,gBAAgB,CAAkB;QAElC,WAAM,GAAN,MAAM,CAAQ;IAC9B,CAAC;IAEJ,KAAK,CAAC,OAAO,CAAC,KAAyB;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,IAAI,CAAC;YACH,qEAAqE;YACrE,gEAAgE;YAChE,uEAAuE;YACvE,MAAM,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9D,OAAO,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QACnG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,oEAAoE;YACpE,2CAA2C;YAC3C,OAAO,CAAC,IAAI,CAAC,oCAAoC,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACrG,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract for the deployment admin check. A user is an admin iff they hold the
|
|
3
|
+
* `Admin` role in the KB's `roles.yaml` — the same source of truth the access
|
|
4
|
+
* model uses for `canWrite('roles.yaml')`. Async because resolving it reads the
|
|
5
|
+
* access model from the default-branch workspace. Kept as an interface so tests
|
|
6
|
+
* can swap a static stub without loading the access tree.
|
|
7
|
+
*/
|
|
8
|
+
export interface IAdminAccessService {
|
|
9
|
+
isAdmin(email: string | undefined): Promise<boolean>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=admin.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.interface.d.ts","sourceRoot":"","sources":["../../../src/modules/admin/admin.interface.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.interface.js","sourceRoot":"","sources":["../../../src/modules/admin/admin.interface.ts"],"names":[],"mappings":""}
|