@bevel-software/platform-core-backend 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-guide/access-control.md +17 -0
- package/agent-guide/conventions.md +8 -0
- package/agent-guide/html-views.md +83 -0
- package/agent-guide/new-knowledge-base.md +24 -0
- package/agent-guide/tool-manuals.md +10 -0
- package/dist/assets.d.ts +19 -0
- package/dist/assets.d.ts.map +1 -1
- package/dist/assets.js +26 -2
- package/dist/assets.js.map +1 -1
- package/dist/core/catalog-revision.d.ts +19 -1
- package/dist/core/catalog-revision.d.ts.map +1 -1
- package/dist/core/catalog-revision.js +14 -3
- package/dist/core/catalog-revision.js.map +1 -1
- package/dist/core/create-core-server.d.ts +5 -0
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +54 -3
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +26 -0
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +100 -8
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core/lifecycle.d.ts +16 -1
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/core/lifecycle.js +18 -1
- package/dist/core/lifecycle.js.map +1 -1
- package/dist/core-config.d.ts +21 -0
- package/dist/core-config.d.ts.map +1 -1
- package/dist/core-config.js +22 -1
- package/dist/core-config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +8 -0
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +1 -0
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +11 -0
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/directory-sync-bot.js +1 -1
- package/dist/modules/access/directory-sync-bot.js.map +1 -1
- package/dist/modules/agent-guide/agent-guide.d.ts +6 -0
- package/dist/modules/agent-guide/agent-guide.d.ts.map +1 -1
- package/dist/modules/agent-guide/agent-guide.js +8 -0
- package/dist/modules/agent-guide/agent-guide.js.map +1 -1
- package/dist/modules/agent-guide/index.d.ts +1 -1
- package/dist/modules/agent-guide/index.d.ts.map +1 -1
- package/dist/modules/agent-guide/index.js +1 -1
- package/dist/modules/agent-guide/index.js.map +1 -1
- package/dist/modules/agent-instructions/compose.d.ts +5 -0
- package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
- package/dist/modules/agent-instructions/compose.js +19 -2
- package/dist/modules/agent-instructions/compose.js.map +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.js +19 -19
- package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
- package/dist/modules/audit/agent-audit.service.d.ts +21 -2
- package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
- package/dist/modules/audit/agent-audit.service.js +43 -2
- package/dist/modules/audit/agent-audit.service.js.map +1 -1
- package/dist/modules/audit/agent-connection.routes.d.ts +34 -0
- package/dist/modules/audit/agent-connection.routes.d.ts.map +1 -0
- package/dist/modules/audit/agent-connection.routes.js +38 -0
- package/dist/modules/audit/agent-connection.routes.js.map +1 -0
- package/dist/modules/audit/audit.contract.d.ts +24 -0
- package/dist/modules/audit/audit.contract.d.ts.map +1 -1
- package/dist/modules/audit/audit.contract.js.map +1 -1
- package/dist/modules/audit/index.d.ts +1 -0
- package/dist/modules/audit/index.d.ts.map +1 -1
- package/dist/modules/audit/index.js +1 -0
- package/dist/modules/audit/index.js.map +1 -1
- package/dist/modules/auth/account.routes.d.ts.map +1 -1
- package/dist/modules/auth/account.routes.js +10 -3
- package/dist/modules/auth/account.routes.js.map +1 -1
- package/dist/modules/auth/auth.middleware.d.ts +7 -0
- package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
- package/dist/modules/auth/auth.middleware.js +1 -1
- package/dist/modules/auth/auth.middleware.js.map +1 -1
- package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -1
- package/dist/modules/code-mode/code-mode.tool.js +11 -3
- package/dist/modules/code-mode/code-mode.tool.js.map +1 -1
- package/dist/modules/database/core-schema.d.ts +96 -0
- package/dist/modules/database/core-schema.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +32 -3
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/embed/account-link.service.d.ts +42 -0
- package/dist/modules/embed/account-link.service.d.ts.map +1 -0
- package/dist/modules/embed/account-link.service.js +50 -0
- package/dist/modules/embed/account-link.service.js.map +1 -0
- package/dist/modules/embed/embed-link.d.ts +58 -0
- package/dist/modules/embed/embed-link.d.ts.map +1 -0
- package/dist/modules/embed/embed-link.js +160 -0
- package/dist/modules/embed/embed-link.js.map +1 -0
- package/dist/modules/embed/embed.errors.d.ts +30 -0
- package/dist/modules/embed/embed.errors.d.ts.map +1 -0
- package/dist/modules/embed/embed.errors.js +42 -0
- package/dist/modules/embed/embed.errors.js.map +1 -0
- package/dist/modules/embed/embed.interface.d.ts +204 -0
- package/dist/modules/embed/embed.interface.d.ts.map +1 -0
- package/dist/modules/embed/embed.interface.js +2 -0
- package/dist/modules/embed/embed.interface.js.map +1 -0
- package/dist/modules/embed/embed.routes.d.ts +59 -0
- package/dist/modules/embed/embed.routes.d.ts.map +1 -0
- package/dist/modules/embed/embed.routes.js +343 -0
- package/dist/modules/embed/embed.routes.js.map +1 -0
- package/dist/modules/embed/embed.service.d.ts +169 -0
- package/dist/modules/embed/embed.service.d.ts.map +1 -0
- package/dist/modules/embed/embed.service.js +627 -0
- package/dist/modules/embed/embed.service.js.map +1 -0
- package/dist/modules/embed/embed.tools.d.ts +51 -0
- package/dist/modules/embed/embed.tools.d.ts.map +1 -0
- package/dist/modules/embed/embed.tools.js +170 -0
- package/dist/modules/embed/embed.tools.js.map +1 -0
- package/dist/modules/embed/mcp-app.d.ts +64 -0
- package/dist/modules/embed/mcp-app.d.ts.map +1 -0
- package/dist/modules/embed/mcp-app.js +147 -0
- package/dist/modules/embed/mcp-app.js.map +1 -0
- package/dist/modules/embed/mcp-app.routes.d.ts +21 -0
- package/dist/modules/embed/mcp-app.routes.d.ts.map +1 -0
- package/dist/modules/embed/mcp-app.routes.js +36 -0
- package/dist/modules/embed/mcp-app.routes.js.map +1 -0
- package/dist/modules/github-app/github-app.connection.d.ts +15 -0
- package/dist/modules/github-app/github-app.connection.d.ts.map +1 -1
- package/dist/modules/github-app/github-app.connection.js +34 -3
- package/dist/modules/github-app/github-app.connection.js.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.d.ts +65 -0
- package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.js +300 -0
- package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
- package/dist/modules/kb-sync/kb-sync.interface.d.ts +5 -0
- package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.service.js +6 -0
- package/dist/modules/kb-sync/kb-sync.service.js.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.js +2 -1
- package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
- package/dist/modules/mcp/mcp.service.d.ts +28 -1
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.service.js +64 -8
- package/dist/modules/mcp/mcp.service.js.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +24 -0
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js +32 -4
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
- package/dist/modules/onboarding/onboarding.contract.d.ts +80 -0
- package/dist/modules/onboarding/onboarding.contract.d.ts.map +1 -0
- package/dist/modules/onboarding/onboarding.contract.js +7 -0
- package/dist/modules/onboarding/onboarding.contract.js.map +1 -0
- package/dist/modules/onboarding/onboarding.routes.d.ts +18 -0
- package/dist/modules/onboarding/onboarding.routes.d.ts.map +1 -0
- package/dist/modules/onboarding/onboarding.routes.js +81 -0
- package/dist/modules/onboarding/onboarding.routes.js.map +1 -0
- package/dist/modules/onboarding/starter-pack.service.d.ts +213 -0
- package/dist/modules/onboarding/starter-pack.service.d.ts.map +1 -0
- package/dist/modules/onboarding/starter-pack.service.js +492 -0
- package/dist/modules/onboarding/starter-pack.service.js.map +1 -0
- package/dist/modules/onboarding/starter-packs.d.ts +78 -0
- package/dist/modules/onboarding/starter-packs.d.ts.map +1 -0
- package/dist/modules/onboarding/starter-packs.js +156 -0
- package/dist/modules/onboarding/starter-packs.js.map +1 -0
- package/dist/modules/plugins/index.d.ts +1 -1
- package/dist/modules/plugins/index.d.ts.map +1 -1
- package/dist/modules/plugins/index.js +1 -1
- package/dist/modules/plugins/index.js.map +1 -1
- package/dist/modules/plugins/plugin-provision.service.d.ts +19 -0
- package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-provision.service.js +18 -1
- package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
- package/dist/modules/plugins/plugins.routes.d.ts +0 -36
- package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.js +31 -0
- package/dist/modules/plugins/plugins.routes.js.map +1 -1
- package/dist/modules/settings/deployment-settings.service.d.ts +34 -0
- package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
- package/dist/modules/settings/deployment-settings.service.js +134 -1
- package/dist/modules/settings/deployment-settings.service.js.map +1 -1
- package/dist/modules/settings/repository-source.d.ts +1 -0
- package/dist/modules/settings/repository-source.d.ts.map +1 -1
- package/dist/modules/settings/repository-source.js +3 -3
- package/dist/modules/settings/repository-source.js.map +1 -1
- package/dist/modules/skills/skills.tools.d.ts.map +1 -1
- package/dist/modules/skills/skills.tools.js +50 -32
- package/dist/modules/skills/skills.tools.js.map +1 -1
- package/dist/modules/tool-auth/connection-key-rejection.d.ts +10 -1
- package/dist/modules/tool-auth/connection-key-rejection.d.ts.map +1 -1
- package/dist/modules/tool-auth/connection-key-rejection.js +11 -3
- package/dist/modules/tool-auth/connection-key-rejection.js.map +1 -1
- package/dist/modules/tool-auth/external-api-key.interface.d.ts +8 -0
- package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.d.ts +24 -2
- package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.js +59 -2
- package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.js +9 -4
- package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
- package/dist/modules/tool-helpers/index.d.ts +28 -1
- package/dist/modules/tool-helpers/index.d.ts.map +1 -1
- package/dist/modules/tool-helpers/index.js +28 -1
- package/dist/modules/tool-helpers/index.js.map +1 -1
- package/dist/modules/tool-helpers/route-argument-check.d.ts +10 -0
- package/dist/modules/tool-helpers/route-argument-check.d.ts.map +1 -0
- package/dist/modules/tool-helpers/route-argument-check.js +132 -0
- package/dist/modules/tool-helpers/route-argument-check.js.map +1 -0
- package/dist/modules/tool-helpers/route-tool-schemas.d.ts +89 -0
- package/dist/modules/tool-helpers/route-tool-schemas.d.ts.map +1 -0
- package/dist/modules/tool-helpers/route-tool-schemas.js +113 -0
- package/dist/modules/tool-helpers/route-tool-schemas.js.map +1 -0
- package/dist/modules/tool-helpers/tool-def.d.ts +71 -0
- package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-def.js +70 -6
- package/dist/modules/tool-helpers/tool-def.js.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.d.ts +46 -6
- package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.js +157 -8
- package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.d.ts +9 -0
- package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.js +14 -5
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
- package/dist/modules/tool-registry/description-length.d.ts +6 -2
- package/dist/modules/tool-registry/description-length.d.ts.map +1 -1
- package/dist/modules/tool-registry/description-length.js +27 -5
- package/dist/modules/tool-registry/description-length.js.map +1 -1
- package/dist/modules/tool-registry/guide-first.d.ts +4 -0
- package/dist/modules/tool-registry/guide-first.d.ts.map +1 -1
- package/dist/modules/tool-registry/guide-first.js +9 -1
- package/dist/modules/tool-registry/guide-first.js.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts +53 -0
- package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-read.tools.js +97 -68
- package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +8 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js +124 -37
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
- package/dist/modules/workflow/file-lock.service.d.ts +29 -5
- package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
- package/dist/modules/workflow/file-lock.service.js +62 -5
- package/dist/modules/workflow/file-lock.service.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +72 -1
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +172 -36
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/git/node-git-runner.d.ts +15 -0
- package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
- package/dist/modules/workflow/git/node-git-runner.js +78 -6
- package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
- package/dist/modules/workflow/pending-commits.service.d.ts +15 -0
- package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
- package/dist/modules/workflow/pending-commits.service.js +25 -1
- package/dist/modules/workflow/pending-commits.service.js.map +1 -1
- package/dist/modules/workflow/pending-commits.worker.d.ts +6 -1
- package/dist/modules/workflow/pending-commits.worker.d.ts.map +1 -1
- package/dist/modules/workflow/pending-commits.worker.js +23 -6
- package/dist/modules/workflow/pending-commits.worker.js.map +1 -1
- package/dist/modules/workflow/recovery-bot.js +1 -1
- package/dist/modules/workflow/recovery-bot.js.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.js +2 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
- package/dist/modules/workflow/sanitize-error.d.ts +16 -0
- package/dist/modules/workflow/sanitize-error.d.ts.map +1 -1
- package/dist/modules/workflow/sanitize-error.js +45 -0
- package/dist/modules/workflow/sanitize-error.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +183 -15
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +805 -106
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/agent-download.builder.d.ts +105 -0
- package/dist/modules/workspace/agent-download.builder.d.ts.map +1 -0
- package/dist/modules/workspace/agent-download.builder.js +238 -0
- package/dist/modules/workspace/agent-download.builder.js.map +1 -0
- package/dist/modules/workspace/agent-download.routes.d.ts +77 -0
- package/dist/modules/workspace/agent-download.routes.d.ts.map +1 -0
- package/dist/modules/workspace/agent-download.routes.js +156 -0
- package/dist/modules/workspace/agent-download.routes.js.map +1 -0
- package/dist/modules/workspace/agent-download.store.d.ts +225 -0
- package/dist/modules/workspace/agent-download.store.d.ts.map +1 -0
- package/dist/modules/workspace/agent-download.store.js +423 -0
- package/dist/modules/workspace/agent-download.store.js.map +1 -0
- package/dist/modules/workspace/agent-upload.store.d.ts +10 -1
- package/dist/modules/workspace/agent-upload.store.d.ts.map +1 -1
- package/dist/modules/workspace/agent-upload.store.js +16 -6
- package/dist/modules/workspace/agent-upload.store.js.map +1 -1
- package/dist/modules/workspace/file-readers/raw-mime.d.ts +6 -0
- package/dist/modules/workspace/file-readers/raw-mime.d.ts.map +1 -0
- package/dist/modules/workspace/file-readers/raw-mime.js +38 -0
- package/dist/modules/workspace/file-readers/raw-mime.js.map +1 -0
- package/dist/modules/workspace/file-readers/text-reader.d.ts +5 -5
- package/dist/modules/workspace/file-readers/text-reader.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/text-reader.js +5 -8
- package/dist/modules/workspace/file-readers/text-reader.js.map +1 -1
- package/dist/modules/workspace/first-run.d.ts +111 -0
- package/dist/modules/workspace/first-run.d.ts.map +1 -0
- package/dist/modules/workspace/first-run.js +181 -0
- package/dist/modules/workspace/first-run.js.map +1 -0
- package/dist/modules/workspace/move-links.d.ts +92 -0
- package/dist/modules/workspace/move-links.d.ts.map +1 -0
- package/dist/modules/workspace/move-links.js +173 -0
- package/dist/modules/workspace/move-links.js.map +1 -0
- package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.js +3 -13
- package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +63 -22
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +75 -2
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +197 -24
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.d.ts +59 -1
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +443 -65
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/modules/write-access/write-access.d.ts.map +1 -1
- package/dist/modules/write-access/write-access.js +9 -0
- package/dist/modules/write-access/write-access.js.map +1 -1
- package/dist/shared/domain-errors.d.ts +73 -1
- package/dist/shared/domain-errors.d.ts.map +1 -1
- package/dist/shared/domain-errors.js +86 -12
- package/dist/shared/domain-errors.js.map +1 -1
- package/dist/shared/git.contract.d.ts +10 -1
- package/dist/shared/git.contract.d.ts.map +1 -1
- package/dist/shared/git.contract.js.map +1 -1
- package/dist/shared/utf8-text.d.ts +15 -0
- package/dist/shared/utf8-text.d.ts.map +1 -0
- package/dist/shared/utf8-text.js +20 -0
- package/dist/shared/utf8-text.js.map +1 -0
- package/dist/tenancy/static-tenant-source.d.ts +2 -1
- package/dist/tenancy/static-tenant-source.d.ts.map +1 -1
- package/dist/tenancy/static-tenant-source.js +9 -2
- package/dist/tenancy/static-tenant-source.js.map +1 -1
- package/mcp-app/page.html +349 -0
- package/migrations/0017_atlassian_account_links.sql +37 -0
- package/migrations/meta/0017_snapshot.json +2396 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +5 -3
- package/src/__tests__/packaged-assets-ship.test.ts +16 -4
- package/src/assets.ts +28 -2
- package/src/core/__tests__/catalog-revision.test.ts +40 -0
- package/src/core/__tests__/gated-boot.test.ts +1 -0
- package/src/core/__tests__/lifecycle.test.ts +14 -0
- package/src/core/catalog-revision.ts +15 -2
- package/src/core/create-core-server.ts +67 -3
- package/src/core/create-core-services.ts +140 -6
- package/src/core/lifecycle.ts +28 -2
- package/src/core-config.ts +24 -1
- package/src/index.ts +2 -2
- package/src/modules/access/__tests__/access-control.service.test.ts +19 -0
- package/src/modules/access/access-control.interface.ts +13 -0
- package/src/modules/access/access-control.service.ts +16 -0
- package/src/modules/access/directory-sync-bot.ts +1 -1
- package/src/modules/agent-guide/__tests__/agent-guide.test.ts +58 -0
- package/src/modules/agent-guide/__tests__/agent-guide.tools.test.ts +19 -1
- package/src/modules/agent-guide/agent-guide.ts +9 -0
- package/src/modules/agent-guide/index.ts +1 -0
- package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +14 -0
- package/src/modules/agent-instructions/compose.ts +17 -2
- package/src/modules/agent-instructions/shared-file-rules.ts +19 -19
- package/src/modules/audit/__tests__/agent-audit.service.test.ts +64 -4
- package/src/modules/audit/__tests__/agent-connection.routes.test.ts +102 -0
- package/src/modules/audit/agent-audit.service.ts +58 -3
- package/src/modules/audit/agent-connection.routes.ts +56 -0
- package/src/modules/audit/audit.contract.ts +26 -0
- package/src/modules/audit/index.ts +1 -0
- package/src/modules/auth/__tests__/account.routes.test.ts +5 -3
- package/src/modules/auth/account.routes.ts +10 -3
- package/src/modules/auth/auth.middleware.ts +1 -1
- package/src/modules/code-mode/__tests__/code-mode.tool.test.ts +18 -2
- package/src/modules/code-mode/code-mode.tool.ts +13 -2
- package/src/modules/database/core-schema.ts +33 -3
- package/src/modules/embed/__tests__/account-links.migration.test.ts +98 -0
- package/src/modules/embed/__tests__/embed-link.test.ts +122 -0
- package/src/modules/embed/__tests__/embed.routes.test.ts +362 -0
- package/src/modules/embed/__tests__/embed.service.lock.test.ts +193 -0
- package/src/modules/embed/__tests__/embed.service.test.ts +805 -0
- package/src/modules/embed/__tests__/embed.tools.test.ts +304 -0
- package/src/modules/embed/__tests__/mcp-app.test.ts +207 -0
- package/src/modules/embed/account-link.service.ts +76 -0
- package/src/modules/embed/embed-link.ts +180 -0
- package/src/modules/embed/embed.errors.ts +43 -0
- package/src/modules/embed/embed.interface.ts +203 -0
- package/src/modules/embed/embed.routes.ts +363 -0
- package/src/modules/embed/embed.service.ts +705 -0
- package/src/modules/embed/embed.tools.ts +206 -0
- package/src/modules/embed/mcp-app.routes.ts +41 -0
- package/src/modules/embed/mcp-app.ts +173 -0
- package/src/modules/github-app/__tests__/github-app.test.ts +76 -0
- package/src/modules/github-app/github-app.connection.ts +38 -4
- package/src/modules/kb-fs/__tests__/move-with-edits.test.ts +304 -0
- package/src/modules/kb-fs/locking-filesystem.ts +287 -0
- package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +35 -0
- package/src/modules/kb-sync/kb-sync.interface.ts +2 -0
- package/src/modules/kb-sync/kb-sync.service.ts +6 -0
- package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +68 -11
- package/src/modules/mcp/__tests__/mcp-proxy-helpers.test.ts +37 -2
- package/src/modules/mcp/__tests__/mcp.app.e2e.test.ts +200 -0
- package/src/modules/mcp/__tests__/mcp.e2e.test.ts +3 -1
- package/src/modules/mcp/__tests__/mcp.service.test.ts +23 -13
- package/src/modules/mcp/__tests__/tool-call-interface.e2e.test.ts +499 -0
- package/src/modules/mcp/mcp-auth.middleware.ts +2 -1
- package/src/modules/mcp/mcp.service.ts +81 -12
- package/src/modules/mcp/oauth/bevel-oauth-provider.ts +42 -4
- package/src/modules/onboarding/__tests__/onboarding.routes.test.ts +163 -0
- package/src/modules/onboarding/__tests__/starter-pack.service.test.ts +635 -0
- package/src/modules/onboarding/__tests__/starter-packs.test.ts +169 -0
- package/src/modules/onboarding/onboarding.contract.ts +85 -0
- package/src/modules/onboarding/onboarding.routes.ts +85 -0
- package/src/modules/onboarding/starter-pack.service.ts +580 -0
- package/src/modules/onboarding/starter-packs.ts +182 -0
- package/src/modules/plugins/__tests__/plugins.tools.test.ts +25 -2
- package/src/modules/plugins/index.ts +1 -0
- package/src/modules/plugins/plugin-provision.service.ts +22 -1
- package/src/modules/plugins/plugins.routes.ts +29 -0
- package/src/modules/settings/__tests__/deployment-settings.service.test.ts +150 -1
- package/src/modules/settings/__tests__/repository-source.test.ts +9 -0
- package/src/modules/settings/deployment-settings.service.ts +131 -1
- package/src/modules/settings/repository-source.ts +4 -4
- package/src/modules/skills/__tests__/skills.tools.description.test.ts +5 -1
- package/src/modules/skills/skills.tools.ts +55 -35
- package/src/modules/tool-auth/__tests__/connection-key-rejection.test.ts +32 -0
- package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +65 -0
- package/src/modules/tool-auth/connection-key-rejection.ts +13 -3
- package/src/modules/tool-auth/external-api-key.interface.ts +9 -0
- package/src/modules/tool-auth/external-api-key.service.ts +61 -4
- package/src/modules/tool-auth/tool-auth.middleware.ts +13 -4
- package/src/modules/tool-helpers/__tests__/branch-declaration.test.ts +502 -0
- package/src/modules/tool-helpers/__tests__/route-argument-check.test.ts +337 -0
- package/src/modules/tool-helpers/index.ts +34 -1
- package/src/modules/tool-helpers/route-argument-check.ts +149 -0
- package/src/modules/tool-helpers/route-tool-schemas.ts +171 -0
- package/src/modules/tool-helpers/tool-def.ts +132 -7
- package/src/modules/tool-helpers/tool-handler.ts +196 -8
- package/src/modules/tool-helpers/tool.contract.ts +9 -0
- package/src/modules/tool-manuals/tool-manuals.tools.ts +15 -5
- package/src/modules/tool-registry/__tests__/own-tool-schemas.test.ts +14 -1
- package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +23 -10
- package/src/modules/tool-registry/description-length.ts +34 -7
- package/src/modules/tool-registry/guide-first.ts +8 -1
- package/src/modules/workflow/__tests__/file-lock.service.deletion-gate.test.ts +104 -0
- package/src/modules/workflow/__tests__/pending-commits.repository-replaced.test.ts +66 -0
- package/src/modules/workflow/__tests__/pending-commits.worker.test.ts +31 -2
- package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +110 -6
- package/src/modules/workflow/__tests__/sanitize-error.test.ts +89 -1
- package/src/modules/workflow/__tests__/workflow.routes.push-refused.test.ts +202 -0
- package/src/modules/workflow/__tests__/workflow.service.branch-in-use.test.ts +6 -6
- package/src/modules/workflow/__tests__/workflow.service.delete-branch.test.ts +1026 -0
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +468 -10
- package/src/modules/workflow/__tests__/workflow.service.folder-proposals.test.ts +4 -0
- package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +5 -4
- package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +54 -2
- package/src/modules/workflow/agent-tools/__tests__/change-request-read.tools.test.ts +41 -5
- package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +127 -2
- package/src/modules/workflow/agent-tools/change-request-read.tools.ts +157 -122
- package/src/modules/workflow/agent-tools/workflow.tools.ts +129 -35
- package/src/modules/workflow/file-lock.service.ts +67 -5
- package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +164 -0
- package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +48 -1
- package/src/modules/workflow/git/__tests__/node-git-runner.test.ts +231 -2
- package/src/modules/workflow/git/git.service.ts +176 -38
- package/src/modules/workflow/git/node-git-runner.ts +82 -7
- package/src/modules/workflow/pending-commits.service.ts +29 -1
- package/src/modules/workflow/pending-commits.worker.ts +24 -6
- package/src/modules/workflow/recovery-bot.ts +1 -1
- package/src/modules/workflow/review-workflow/review-workflow.service.ts +2 -1
- package/src/modules/workflow/sanitize-error.ts +50 -0
- package/src/modules/workflow/workflow.service.ts +879 -112
- package/src/modules/workspace/__tests__/agent-downloads.test.ts +823 -0
- package/src/modules/workspace/__tests__/first-run.test.ts +234 -0
- package/src/modules/workspace/__tests__/git-internals.security.test.ts +5 -2
- package/src/modules/workspace/__tests__/md-links.test.ts +353 -0
- package/src/modules/workspace/__tests__/move-links.test.ts +261 -0
- package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +219 -0
- package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -0
- package/src/modules/workspace/__tests__/workspace.routes.delete.test.ts +102 -0
- package/src/modules/workspace/__tests__/workspace.routes.download.test.ts +52 -5
- package/src/modules/workspace/__tests__/workspace.routes.folder-zip-access.test.ts +190 -0
- package/src/modules/workspace/__tests__/workspace.service.forget-clone-races.test.ts +8 -4
- package/src/modules/workspace/__tests__/workspace.service.test.ts +50 -8
- package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +44 -1
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +409 -12
- package/src/modules/workspace/agent-download.builder.ts +308 -0
- package/src/modules/workspace/agent-download.routes.ts +183 -0
- package/src/modules/workspace/agent-download.store.ts +533 -0
- package/src/modules/workspace/agent-upload.store.ts +23 -7
- package/src/modules/workspace/file-readers/raw-mime.ts +40 -0
- package/src/modules/workspace/file-readers/text-reader.ts +5 -8
- package/src/modules/workspace/first-run.ts +222 -0
- package/src/modules/workspace/move-links.ts +237 -0
- package/src/modules/workspace/startup/steps/seed-tree.ts +3 -12
- package/src/modules/workspace/workspace.routes.ts +64 -22
- package/src/modules/workspace/workspace.service.ts +202 -25
- package/src/modules/workspace/workspace.tools.ts +492 -63
- package/src/modules/write-access/__tests__/write-access.test.ts +13 -0
- package/src/modules/write-access/write-access.ts +9 -0
- package/src/shared/domain-errors.ts +108 -11
- package/src/shared/git.contract.ts +8 -1
- package/src/shared/utf8-text.ts +21 -0
- package/src/tenancy/__tests__/static-tenant-source.test.ts +1 -0
- package/src/tenancy/static-tenant-source.ts +10 -2
- package/starter-packs/README.md +103 -0
- package/starter-packs/engineering/KnowledgeBase/About us.md +9 -0
- package/starter-packs/engineering/KnowledgeBase/Architecture.md +9 -0
- package/starter-packs/engineering/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/engineering/KnowledgeBase/How we ship.md +9 -0
- package/starter-packs/engineering/Plugins/engineering-starter/LICENSE +21 -0
- package/starter-packs/engineering/Plugins/engineering-starter/SOURCE.md +20 -0
- package/starter-packs/engineering/Plugins/engineering-starter/access.md +19 -0
- package/starter-packs/engineering/Plugins/engineering-starter/plugin.json +10 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/SKILL.md +171 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2a-startup-diagnostic.md +157 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/office-hours/sections/phase-2b-builder-brainstorm.md +39 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-ceo-review/SKILL.md +144 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/plan-eng-review/SKILL.md +144 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/review/SKILL.md +80 -0
- package/starter-packs/engineering/Plugins/engineering-starter/skills/review/checklist.md +184 -0
- package/starter-packs/engineering/pack.yaml +11 -0
- package/starter-packs/general/KnowledgeBase/About us.md +9 -0
- package/starter-packs/general/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/general/KnowledgeBase/How we work.md +9 -0
- package/starter-packs/general/Plugins/general-starter/LICENSE +202 -0
- package/starter-packs/general/Plugins/general-starter/SOURCE.md +10 -0
- package/starter-packs/general/Plugins/general-starter/access.md +19 -0
- package/starter-packs/general/Plugins/general-starter/plugin.json +10 -0
- package/starter-packs/general/Plugins/general-starter/skills/memory-management/SKILL.md +332 -0
- package/starter-packs/general/Plugins/general-starter/skills/productivity-start/SKILL.md +163 -0
- package/starter-packs/general/Plugins/general-starter/skills/productivity-update/SKILL.md +167 -0
- package/starter-packs/general/Plugins/general-starter/skills/task-management/SKILL.md +83 -0
- package/starter-packs/general/pack.yaml +10 -0
- package/starter-packs/operations/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/operations/KnowledgeBase/How we work.md +9 -0
- package/starter-packs/operations/KnowledgeBase/Processes.md +9 -0
- package/starter-packs/operations/KnowledgeBase/Tools we use.md +9 -0
- package/starter-packs/operations/KnowledgeBase/Vendors.md +9 -0
- package/starter-packs/operations/Plugins/operations-starter/LICENSE +202 -0
- package/starter-packs/operations/Plugins/operations-starter/SOURCE.md +10 -0
- package/starter-packs/operations/Plugins/operations-starter/access.md +19 -0
- package/starter-packs/operations/Plugins/operations-starter/plugin.json +10 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/capacity-plan/SKILL.md +111 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/change-request/SKILL.md +119 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/compliance-tracking/SKILL.md +44 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/process-doc/SKILL.md +80 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/process-optimization/SKILL.md +39 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/risk-assessment/SKILL.md +40 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/runbook/SKILL.md +85 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/status-report/SKILL.md +75 -0
- package/starter-packs/operations/Plugins/operations-starter/skills/vendor-review/SKILL.md +102 -0
- package/starter-packs/operations/pack.yaml +12 -0
- package/starter-packs/sales/KnowledgeBase/About us.md +9 -0
- package/starter-packs/sales/KnowledgeBase/Customers.md +9 -0
- package/starter-packs/sales/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/sales/KnowledgeBase/How we sell.md +9 -0
- package/starter-packs/sales/KnowledgeBase/Objections.md +9 -0
- package/starter-packs/sales/KnowledgeBase/Pricing.md +9 -0
- package/starter-packs/sales/Plugins/sales-starter/LICENSE +202 -0
- package/starter-packs/sales/Plugins/sales-starter/SOURCE.md +10 -0
- package/starter-packs/sales/Plugins/sales-starter/access.md +19 -0
- package/starter-packs/sales/Plugins/sales-starter/plugin.json +10 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/account-context/SKILL.md +94 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/account-plan/SKILL.md +95 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/account-research/SKILL.md +99 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/account-tiering/SKILL.md +101 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/call-prep/SKILL.md +111 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/call-summary/SKILL.md +111 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/close-plan/SKILL.md +106 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/competitive-intelligence/SKILL.md +102 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/create-an-asset/SKILL.md +105 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/crm-hygiene-check/SKILL.md +103 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/customer-health/SKILL.md +108 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/customer-voice/SKILL.md +94 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/daily-briefing/SKILL.md +61 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/deal-advance-gap/SKILL.md +102 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/deal-review/SKILL.md +105 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/deal-signals/SKILL.md +96 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/deal-slip-scenario/SKILL.md +104 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/draft-outreach/SKILL.md +116 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/end-of-day/SKILL.md +114 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/expansion-whitespace/SKILL.md +97 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/forecast/SKILL.md +100 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/handle-objection/SKILL.md +93 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/inbox-sweep/SKILL.md +114 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/lead-triage/SKILL.md +106 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/log-activity/SKILL.md +111 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/pipeline-review/SKILL.md +97 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/renewal-radar/SKILL.md +95 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/rep-context/SKILL.md +90 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/route-lead/SKILL.md +111 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/sales-setup/SKILL.md +200 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/schedule-meeting/SKILL.md +99 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/stakeholder-map/SKILL.md +107 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/team-pipeline/SKILL.md +105 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/update-opportunity/SKILL.md +112 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/weekly-wrap/SKILL.md +90 -0
- package/starter-packs/sales/Plugins/sales-starter/skills/win-loss-review/SKILL.md +88 -0
- package/starter-packs/sales/pack.yaml +13 -0
- package/starter-packs/support/KnowledgeBase/Escalations.md +9 -0
- package/starter-packs/support/KnowledgeBase/Glossary.md +9 -0
- package/starter-packs/support/KnowledgeBase/Known issues.md +9 -0
- package/starter-packs/support/KnowledgeBase/Products.md +9 -0
- package/starter-packs/support/KnowledgeBase/Tone of voice.md +9 -0
- package/starter-packs/support/Plugins/support-starter/LICENSE +202 -0
- package/starter-packs/support/Plugins/support-starter/SOURCE.md +10 -0
- package/starter-packs/support/Plugins/support-starter/access.md +19 -0
- package/starter-packs/support/Plugins/support-starter/plugin.json +10 -0
- package/starter-packs/support/Plugins/support-starter/skills/customer-escalation/SKILL.md +246 -0
- package/starter-packs/support/Plugins/support-starter/skills/customer-research/SKILL.md +250 -0
- package/starter-packs/support/Plugins/support-starter/skills/draft-response/SKILL.md +416 -0
- package/starter-packs/support/Plugins/support-starter/skills/kb-article/SKILL.md +350 -0
- package/starter-packs/support/Plugins/support-starter/skills/ticket-triage/SKILL.md +273 -0
- package/starter-packs/support/pack.yaml +12 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The link half of `move_file`: which pages a move edits, and what it reports.
|
|
3
|
+
*
|
|
4
|
+
* A move breaks two sets of links — those inside the moved files that point
|
|
5
|
+
* elsewhere, and those elsewhere that point at the moved files. The plan reads
|
|
6
|
+
* both through the shared grammar (`md-links` in platform-shared) and answers
|
|
7
|
+
* the edits to make plus the report the agent gets, the same for a dry run and
|
|
8
|
+
* for the move itself.
|
|
9
|
+
*
|
|
10
|
+
* Who sees what:
|
|
11
|
+
* - a file the caller cannot read is never opened; the report then carries
|
|
12
|
+
* one sentence saying such files may still point at the old path, with no
|
|
13
|
+
* name and no count;
|
|
14
|
+
* - a file the caller can read but may not change (a protected branch's
|
|
15
|
+
* write rules, or the write hook's refusal) is named with its links, and
|
|
16
|
+
* left;
|
|
17
|
+
* - a file the read hook refuses counts as one the caller cannot read: not
|
|
18
|
+
* named, only covered by the same sentence — the hook is asked for every
|
|
19
|
+
* file the answer would name, before it is named, and for no other;
|
|
20
|
+
* - an HTML page is named with its links, and left — and so is a markdown
|
|
21
|
+
* page for the raw HTML it carries (`<a href>`, `<img src>`), which the
|
|
22
|
+
* grammar reads but never rewrites.
|
|
23
|
+
*/
|
|
24
|
+
import { type MdLinkEdit } from '@bevel-software/platform-shared';
|
|
25
|
+
/** More edited files than this and the move is refused. */
|
|
26
|
+
export declare const MOVE_LINK_EDIT_CAP = 200;
|
|
27
|
+
/** How many edits the report lists. */
|
|
28
|
+
export declare const MOVE_LINK_REPORT_EDITS = 100;
|
|
29
|
+
/** The sentence about files the caller cannot read. */
|
|
30
|
+
export declare const UNSEARCHED_SENTENCE = "Links in files you cannot read were not searched, and may still point at the old path.";
|
|
31
|
+
export interface MoveLinksReport {
|
|
32
|
+
filesEdited: number;
|
|
33
|
+
linksRewritten: number;
|
|
34
|
+
/** The first {@link MOVE_LINK_REPORT_EDITS} edits; `path` is where the file sits after the move. */
|
|
35
|
+
edits: {
|
|
36
|
+
path: string;
|
|
37
|
+
from: string;
|
|
38
|
+
to: string;
|
|
39
|
+
}[];
|
|
40
|
+
notRewritten: {
|
|
41
|
+
path: string;
|
|
42
|
+
reason: string;
|
|
43
|
+
links: string[];
|
|
44
|
+
}[];
|
|
45
|
+
unsearched?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface PlannedEdit {
|
|
48
|
+
/** Where the file sits after the move. */
|
|
49
|
+
path: string;
|
|
50
|
+
/** Where it sits now. */
|
|
51
|
+
lockAt: string;
|
|
52
|
+
/** The bytes the edit was computed from — compared again under the lock. */
|
|
53
|
+
original: string;
|
|
54
|
+
content: string;
|
|
55
|
+
links: MdLinkEdit[];
|
|
56
|
+
}
|
|
57
|
+
export interface MoveLinksPlan {
|
|
58
|
+
edits: PlannedEdit[];
|
|
59
|
+
report: MoveLinksReport;
|
|
60
|
+
/** Set when the move would edit more than the cap; the move is refused with it. */
|
|
61
|
+
overCap?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface MoveLinksInput {
|
|
64
|
+
src: string;
|
|
65
|
+
dest: string;
|
|
66
|
+
branch: string;
|
|
67
|
+
kbDirName: string;
|
|
68
|
+
/** Every file on the branch inside the clone folder, workspace-relative. */
|
|
69
|
+
allFiles: string[];
|
|
70
|
+
/** Read verdicts for workspace-relative paths. */
|
|
71
|
+
canRead: (paths: string[]) => Promise<Map<string, boolean>>;
|
|
72
|
+
/** The paths among these the caller may not change (protected-branch rules). */
|
|
73
|
+
writeBlocked: (paths: string[]) => Promise<string[]>;
|
|
74
|
+
readText: (path: string) => Promise<string>;
|
|
75
|
+
/**
|
|
76
|
+
* The deployment's read hook on one page, at its current path: true when
|
|
77
|
+
* it refuses. Asked for every page the answer would NAME — edited, or left
|
|
78
|
+
* with its links listed — and for no page merely searched: naming is the
|
|
79
|
+
* disclosure. A refused page is one the caller cannot read, covered by the
|
|
80
|
+
* one sentence and never named.
|
|
81
|
+
*/
|
|
82
|
+
readRefused: (path: string) => Promise<boolean>;
|
|
83
|
+
/**
|
|
84
|
+
* The deployment's write hook on a page the move would edit, at its
|
|
85
|
+
* post-move path: why it may not be, or null. Asked for edited pages only.
|
|
86
|
+
*/
|
|
87
|
+
writeRefusal: (lockAt: string, path: string) => Promise<string | null>;
|
|
88
|
+
}
|
|
89
|
+
/** Whether `path` lies in a `transcripts/` or `probes/` folder. */
|
|
90
|
+
export declare function isUnsearchedRecord(path: string): boolean;
|
|
91
|
+
export declare function planMoveLinks(input: MoveLinksInput): Promise<MoveLinksPlan>;
|
|
92
|
+
//# sourceMappingURL=move-links.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-links.d.ts","sourceRoot":"","sources":["../../../src/modules/workspace/move-links.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,iCAAiC,CAAC;AAEzC,2DAA2D;AAC3D,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,uCAAuC;AACvC,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,2FAC0D,CAAC;AAK3F,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,oGAAoG;IACpG,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpD,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kDAAkD;IAClD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5D,gFAAgF;IAChF,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C;;;;;;OAMG;IACH,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACxE;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAuBD,wBAAsB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAkGjF"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The link half of `move_file`: which pages a move edits, and what it reports.
|
|
3
|
+
*
|
|
4
|
+
* A move breaks two sets of links — those inside the moved files that point
|
|
5
|
+
* elsewhere, and those elsewhere that point at the moved files. The plan reads
|
|
6
|
+
* both through the shared grammar (`md-links` in platform-shared) and answers
|
|
7
|
+
* the edits to make plus the report the agent gets, the same for a dry run and
|
|
8
|
+
* for the move itself.
|
|
9
|
+
*
|
|
10
|
+
* Who sees what:
|
|
11
|
+
* - a file the caller cannot read is never opened; the report then carries
|
|
12
|
+
* one sentence saying such files may still point at the old path, with no
|
|
13
|
+
* name and no count;
|
|
14
|
+
* - a file the caller can read but may not change (a protected branch's
|
|
15
|
+
* write rules, or the write hook's refusal) is named with its links, and
|
|
16
|
+
* left;
|
|
17
|
+
* - a file the read hook refuses counts as one the caller cannot read: not
|
|
18
|
+
* named, only covered by the same sentence — the hook is asked for every
|
|
19
|
+
* file the answer would name, before it is named, and for no other;
|
|
20
|
+
* - an HTML page is named with its links, and left — and so is a markdown
|
|
21
|
+
* page for the raw HTML it carries (`<a href>`, `<img src>`), which the
|
|
22
|
+
* grammar reads but never rewrites.
|
|
23
|
+
*/
|
|
24
|
+
import { htmlLinksAffectedByMove, rewriteMdLinks, scanMarkdownHtmlLinks, } from '@bevel-software/platform-shared';
|
|
25
|
+
/** More edited files than this and the move is refused. */
|
|
26
|
+
export const MOVE_LINK_EDIT_CAP = 200;
|
|
27
|
+
/** How many edits the report lists. */
|
|
28
|
+
export const MOVE_LINK_REPORT_EDITS = 100;
|
|
29
|
+
/** The sentence about files the caller cannot read. */
|
|
30
|
+
export const UNSEARCHED_SENTENCE = 'Links in files you cannot read were not searched, and may still point at the old path.';
|
|
31
|
+
/** A folder segment whose files are records of the past, never searched or rewritten. */
|
|
32
|
+
const UNSEARCHED_SEGMENTS = new Set(['transcripts', 'probes']);
|
|
33
|
+
/** Whether `path` lies in a `transcripts/` or `probes/` folder. */
|
|
34
|
+
export function isUnsearchedRecord(path) {
|
|
35
|
+
return path.split('/').slice(0, -1).some((s) => UNSEARCHED_SEGMENTS.has(s));
|
|
36
|
+
}
|
|
37
|
+
const isMarkdown = (p) => /\.md$/i.test(p);
|
|
38
|
+
const isHtml = (p) => /\.html?$/i.test(p);
|
|
39
|
+
/**
|
|
40
|
+
* The search's cheap first cut: a file linking at `name` names it — raw, or
|
|
41
|
+
* spelled with markdown escapes or percent-encoding, which are undone here
|
|
42
|
+
* the way the resolver undoes them (any case, any subset of characters).
|
|
43
|
+
*/
|
|
44
|
+
function mayMention(text, name) {
|
|
45
|
+
if (text.includes(name))
|
|
46
|
+
return true;
|
|
47
|
+
const unescaped = text.replace(/\\([!-/:-@[-`{-~])/g, '$1');
|
|
48
|
+
const decoded = unescaped.replace(/(?:%[0-9a-f]{2})+/gi, (run) => {
|
|
49
|
+
try {
|
|
50
|
+
return decodeURIComponent(run);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return run;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return decoded.includes(name);
|
|
57
|
+
}
|
|
58
|
+
export async function planMoveLinks(input) {
|
|
59
|
+
const { src, dest, branch, kbDirName } = input;
|
|
60
|
+
const mapPath = (p) => p === src ? dest : p.startsWith(`${src}/`) ? dest + p.slice(src.length) : null;
|
|
61
|
+
const srcName = src.slice(src.lastIndexOf('/') + 1);
|
|
62
|
+
const candidates = input.allFiles.filter((p) => (isMarkdown(p) || isHtml(p)) && !isUnsearchedRecord(p)).sort();
|
|
63
|
+
const readable = await input.canRead(candidates);
|
|
64
|
+
let unsearched = candidates.some((p) => readable.get(p) !== true);
|
|
65
|
+
const edits = [];
|
|
66
|
+
/** Pages the answer would name for raw HTML, held back until the read hook allows the page. */
|
|
67
|
+
const htmlReports = [];
|
|
68
|
+
for (const oldPath of candidates) {
|
|
69
|
+
if (readable.get(oldPath) !== true)
|
|
70
|
+
continue;
|
|
71
|
+
const newPath = mapPath(oldPath) ?? oldPath;
|
|
72
|
+
// The sidebar moves and deletes without this tool's locks, so a page can
|
|
73
|
+
// go between the listing and this read. A page gone has no links to fix;
|
|
74
|
+
// one that cannot be opened is one more the search did not cover. Gone is
|
|
75
|
+
// the disk's own definition of absence: ENOENT, and ENOTDIR for a page
|
|
76
|
+
// whose folder became a file in the meantime.
|
|
77
|
+
let text;
|
|
78
|
+
try {
|
|
79
|
+
text = await input.readText(oldPath);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
const code = err?.code;
|
|
83
|
+
if (code !== 'ENOENT' && code !== 'ENOTDIR')
|
|
84
|
+
unsearched = true;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
// A file that stays put is only touched by a link that names the moved
|
|
88
|
+
// path, so a page that does not mention it is skipped unparsed.
|
|
89
|
+
if (newPath === oldPath && !mayMention(text, srcName))
|
|
90
|
+
continue;
|
|
91
|
+
const opts = { oldPath, newPath, mapPath, kbDirName, branch };
|
|
92
|
+
if (isHtml(oldPath)) {
|
|
93
|
+
const links = htmlLinksAffectedByMove(text, opts);
|
|
94
|
+
if (links.length > 0)
|
|
95
|
+
htmlReports.push({ lockAt: oldPath, entry: { path: newPath, reason: 'html page', links } });
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// Raw HTML inside a markdown page (`<img src>`, `<a href>`) renders like
|
|
99
|
+
// a link but is not one the grammar rewrites: named with those links and
|
|
100
|
+
// left, as an HTML page is, so a stale target is never silent. Only a
|
|
101
|
+
// live tag: one inside code or behind a `\<` escape is an example.
|
|
102
|
+
const html = htmlLinksAffectedByMove(text, opts, scanMarkdownHtmlLinks(text));
|
|
103
|
+
if (html.length > 0) {
|
|
104
|
+
htmlReports.push({ lockAt: oldPath, entry: { path: newPath, reason: 'html in markdown', links: html } });
|
|
105
|
+
}
|
|
106
|
+
const rewritten = rewriteMdLinks(text, opts);
|
|
107
|
+
if (rewritten.edits.length === 0)
|
|
108
|
+
continue;
|
|
109
|
+
edits.push({ path: newPath, lockAt: oldPath, original: text, content: rewritten.text, links: rewritten.edits });
|
|
110
|
+
}
|
|
111
|
+
// ONE gate before anything is named: the read hook, asked once per page the
|
|
112
|
+
// answer would name, whether as an edit or as a page left with its links
|
|
113
|
+
// listed. A page it refuses is one the caller cannot read — covered by the
|
|
114
|
+
// one sentence, named nowhere, its links quoted nowhere. A page merely
|
|
115
|
+
// searched is never asked about: nothing of it reaches the answer.
|
|
116
|
+
const readAllowed = new Map();
|
|
117
|
+
const mayName = async (lockAt) => {
|
|
118
|
+
let allowed = readAllowed.get(lockAt);
|
|
119
|
+
if (allowed === undefined) {
|
|
120
|
+
allowed = !(await input.readRefused(lockAt));
|
|
121
|
+
readAllowed.set(lockAt, allowed);
|
|
122
|
+
if (!allowed)
|
|
123
|
+
unsearched = true;
|
|
124
|
+
}
|
|
125
|
+
return allowed;
|
|
126
|
+
};
|
|
127
|
+
const notRewritten = [];
|
|
128
|
+
for (const r of htmlReports)
|
|
129
|
+
if (await mayName(r.lockAt))
|
|
130
|
+
notRewritten.push(r.entry);
|
|
131
|
+
const named = [];
|
|
132
|
+
for (const e of edits)
|
|
133
|
+
if (await mayName(e.lockAt))
|
|
134
|
+
named.push(e);
|
|
135
|
+
// Only a file that stays put can be one the caller may not change: every
|
|
136
|
+
// moved file was already judged writable at both ends by the move itself.
|
|
137
|
+
const blocked = new Set(await input.writeBlocked(named.filter((e) => e.path === e.lockAt).map((e) => e.path)));
|
|
138
|
+
const kept = named.filter((e) => {
|
|
139
|
+
if (!blocked.has(e.path))
|
|
140
|
+
return true;
|
|
141
|
+
notRewritten.push({ path: e.path, reason: 'no write access', links: e.links.map((l) => l.from) });
|
|
142
|
+
return false;
|
|
143
|
+
});
|
|
144
|
+
if (kept.length > MOVE_LINK_EDIT_CAP) {
|
|
145
|
+
return {
|
|
146
|
+
edits: [],
|
|
147
|
+
report: reportOf([], notRewritten, unsearched),
|
|
148
|
+
overCap: `This move would edit links in ${kept.length} files, more than the ${MOVE_LINK_EDIT_CAP} one move may edit, so nothing was moved. ` +
|
|
149
|
+
'Move fewer files at a time (a subfolder, then the rest), or pass `rewriteLinks: false` to move without rewriting links.',
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// The write hook hears about edited files only.
|
|
153
|
+
const allowed = [];
|
|
154
|
+
for (const e of kept) {
|
|
155
|
+
const refusal = await input.writeRefusal(e.lockAt, e.path);
|
|
156
|
+
if (refusal === null)
|
|
157
|
+
allowed.push(e);
|
|
158
|
+
else
|
|
159
|
+
notRewritten.push({ path: e.path, reason: refusal, links: e.links.map((l) => l.from) });
|
|
160
|
+
}
|
|
161
|
+
return { edits: allowed, report: reportOf(allowed, notRewritten, unsearched) };
|
|
162
|
+
}
|
|
163
|
+
function reportOf(edits, notRewritten, unsearched) {
|
|
164
|
+
const flat = edits.flatMap((e) => e.links.map((l) => ({ path: e.path, from: l.from, to: l.to })));
|
|
165
|
+
return {
|
|
166
|
+
filesEdited: edits.length,
|
|
167
|
+
linksRewritten: flat.length,
|
|
168
|
+
edits: flat.slice(0, MOVE_LINK_REPORT_EDITS),
|
|
169
|
+
notRewritten,
|
|
170
|
+
...(unsearched ? { unsearched: UNSEARCHED_SENTENCE } : {}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=move-links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-links.js","sourceRoot":"","sources":["../../../src/modules/workspace/move-links.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-tree.d.ts","sourceRoot":"","sources":["../../../../../src/modules/workspace/startup/steps/seed-tree.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"seed-tree.d.ts","sourceRoot":"","sources":["../../../../../src/modules/workspace/startup/steps/seed-tree.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AASlE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,QAAQ,GAAG,WAAW,EAC5B,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,eAAe,EAAE,SAAS,MAAM,EAAE;AAClC,qHAAqH;AACrH,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,GAC5B,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAKpC"}
|
|
@@ -6,6 +6,7 @@ import { TEMPLATE_SOURCE_FALLBACKS, TemplateSource, renderTemplateText } from '.
|
|
|
6
6
|
import { assertNotGitInternals, hasGitInternalsSegment } from '../../../../shared/git-internals.js';
|
|
7
7
|
import { GitInternalsError } from '../../../../shared/domain-errors.js';
|
|
8
8
|
import { isManagedGuide } from '../../../agent-guide/agent-guide.js';
|
|
9
|
+
import { utf8Text } from '../../../../shared/utf8-text.js';
|
|
9
10
|
/**
|
|
10
11
|
* The empty-remote seed builder the runner takes as `buildSeedTree`: the full
|
|
11
12
|
* template tree, every reserved root, and a generated roles.yaml. DIRECT fs
|
|
@@ -148,7 +149,7 @@ class KbSeedTree {
|
|
|
148
149
|
// Judged the way the copy below judges: a binary under the name is
|
|
149
150
|
// spotted from its first bytes and never read whole.
|
|
150
151
|
const source = await this.templates.pathOf(name);
|
|
151
|
-
const text = (await headHasNul(source)) ? null :
|
|
152
|
+
const text = (await headHasNul(source)) ? null : utf8Text(await fs.readFile(source));
|
|
152
153
|
if (text !== null && isManagedGuide(text))
|
|
153
154
|
return;
|
|
154
155
|
}
|
|
@@ -172,7 +173,7 @@ class KbSeedTree {
|
|
|
172
173
|
// A binary is spotted from its first bytes (a NUL turns up early in any
|
|
173
174
|
// real one) and streamed across without ever being read whole; only what
|
|
174
175
|
// may be text is read in full, and the full decode is still the judge.
|
|
175
|
-
const text = (await headHasNul(from)) ? null :
|
|
176
|
+
const text = (await headHasNul(from)) ? null : utf8Text(await fs.readFile(from));
|
|
176
177
|
if (text === null) {
|
|
177
178
|
await fs.copyFile(from, to);
|
|
178
179
|
}
|
|
@@ -196,17 +197,6 @@ async function headHasNul(file) {
|
|
|
196
197
|
await handle.close();
|
|
197
198
|
}
|
|
198
199
|
}
|
|
199
|
-
/** The bytes as text when they ARE text — strict UTF-8, BOM kept, no NUL — else null. */
|
|
200
|
-
function asText(bytes) {
|
|
201
|
-
if (bytes.includes(0))
|
|
202
|
-
return null;
|
|
203
|
-
try {
|
|
204
|
-
return new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
205
|
-
}
|
|
206
|
-
catch {
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
200
|
/**
|
|
211
201
|
* Whether `rel` under `templateRoot` resolves inside a git folder — the
|
|
212
202
|
* template entry is a link, and following it would read the repository's own
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-tree.js","sourceRoot":"","sources":["../../../../../src/modules/workspace/startup/steps/seed-tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrG,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AACpG,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"seed-tree.js","sourceRoot":"","sources":["../../../../../src/modules/workspace/startup/steps/seed-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.routes.d.ts","sourceRoot":"","sources":["../../../src/modules/workspace/workspace.routes.ts"],"names":[],"mappings":"AAKA,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE3F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAY,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace.routes.d.ts","sourceRoot":"","sources":["../../../src/modules/workspace/workspace.routes.ts"],"names":[],"mappings":"AAKA,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE3F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAY,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAiBlF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAoB,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAQjE,OAAO,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAwB3D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,WAAW,EACxB,eAAe,EAAE,gBAAgB,EACjC,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,EAAE,cAAc,EAC7B,EAAE,EAAE,SAAS,EACb,aAAa,EAAE,cAAc,EAC7B,WAAW,EAAE,mBAAmB,EAChC,IAAI,EAAE,WAAW;AACjB,4GAA4G;AAC5G,cAAc,CAAC,EAAE,cAAc;AAC/B;;;;;GAKG;AACH,UAAU,CAAC,EAAE,eAAe,GAC3B,OAAO,CAAC,MAAM,CAwgDhB"}
|
|
@@ -5,7 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import { IGNORE_FILENAME, isAbsence } from '../../shared/fs.contract.js';
|
|
6
6
|
import { printable } from '../../shared/printable.js';
|
|
7
7
|
import express from 'express';
|
|
8
|
-
import { KNOWLEDGE_DIR, canonicalRelativePath, folderPlaceholderPath, isPlatformFile, isPlatformRestoreShape, platformFileCreationRefusal, platformFileRefusal, reservedRootDirNames, } from '@bevel-software/platform-shared';
|
|
8
|
+
import { KNOWLEDGE_DIR, canonicalRelativePath, folderPlaceholderPath, isPlatformFile, isPlatformFolder, isPlatformRestoreShape, isRepositoryOwnFile, repositoryOwnFileDeleteRefusal, platformFileCreationRefusal, platformFileRefusal, platformFolderRefusal, reservedRootDirNames, } from '@bevel-software/platform-shared';
|
|
9
9
|
import { FolderTooLargeError } from './workspace.service.js';
|
|
10
10
|
import { branchForWorkspaceId } from '../../shared/workspace-id.js';
|
|
11
11
|
import { EntryExistsError } from './workspace.service.js';
|
|
@@ -20,6 +20,7 @@ import { createGitInternalsRouteGuard } from './git-internals.middleware.js';
|
|
|
20
20
|
import { removeEmptyDirs } from './empty-dirs.js';
|
|
21
21
|
import '../auth/auth.middleware.js'; // Express Request augmentation
|
|
22
22
|
import { MAX_UPLOAD_BYTES } from './upload-limits.js';
|
|
23
|
+
import { OCTET_STREAM, rawExtensionOf, rawMimeFor } from './file-readers/raw-mime.js';
|
|
23
24
|
/**
|
|
24
25
|
* One file identity from one request field, or `null` when the caller sent
|
|
25
26
|
* nothing usable.
|
|
@@ -500,8 +501,11 @@ changeGate) {
|
|
|
500
501
|
* `accessConfigErrors`) surfaces to the caller — same shape the
|
|
501
502
|
* `/access/has-role` endpoint returns.
|
|
502
503
|
*/
|
|
503
|
-
async function requireDownloadPermission(req, res, workspaceId, relativePath
|
|
504
|
-
|
|
504
|
+
async function requireDownloadPermission(req, res, workspaceId, relativePath,
|
|
505
|
+
// A caller that has already resolved the user hands it over, so one
|
|
506
|
+
// request is not looked up twice.
|
|
507
|
+
resolvedUser) {
|
|
508
|
+
const user = resolvedUser ?? (await requireUser(req, res));
|
|
505
509
|
if (!user)
|
|
506
510
|
return false;
|
|
507
511
|
let allowed;
|
|
@@ -767,25 +771,15 @@ changeGate) {
|
|
|
767
771
|
// its own weak ETag and answers a matching If-None-Match with a 304.
|
|
768
772
|
res.setHeader('ETag', `"${at.blobId}"`);
|
|
769
773
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
'.jpeg': 'image/jpeg',
|
|
775
|
-
'.gif': 'image/gif',
|
|
776
|
-
'.webp': 'image/webp',
|
|
777
|
-
'.svg': 'image/svg+xml',
|
|
778
|
-
'.bmp': 'image/bmp',
|
|
779
|
-
'.ico': 'image/x-icon',
|
|
780
|
-
'.pdf': 'application/pdf',
|
|
781
|
-
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
782
|
-
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
783
|
-
};
|
|
774
|
+
// The type from the extension, the one table the embed's raw route
|
|
775
|
+
// serves from as well (`file-readers/raw-mime.ts`).
|
|
776
|
+
const ext = rawExtensionOf(filePath);
|
|
777
|
+
const inlineMime = rawMimeFor(filePath);
|
|
784
778
|
// SVG is active web content (it can carry <script>), and it is active in
|
|
785
779
|
// BOTH directions: a saved-to-disk SVG re-opened later runs its scripts
|
|
786
780
|
// under the file:// origin, so a download is forced to octet-stream.
|
|
787
|
-
const downloadMime = ext === '.svg' ?
|
|
788
|
-
res.setHeader('Content-Type', wantsDownload ? downloadMime :
|
|
781
|
+
const downloadMime = ext === '.svg' ? OCTET_STREAM : inlineMime;
|
|
782
|
+
res.setHeader('Content-Type', wantsDownload ? downloadMime : inlineMime);
|
|
789
783
|
// Block MIME-sniffing so a misdeclared file can't be promoted to
|
|
790
784
|
// active content by the browser.
|
|
791
785
|
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
@@ -886,10 +880,35 @@ changeGate) {
|
|
|
886
880
|
res.status(400).json({ error: 'download=1 is required for folder zip downloads' });
|
|
887
881
|
return;
|
|
888
882
|
}
|
|
889
|
-
|
|
883
|
+
const user = await requireUser(req, res);
|
|
884
|
+
if (!user)
|
|
885
|
+
return;
|
|
886
|
+
if (!(await requireDownloadPermission(req, res, id, folderPath, user)))
|
|
890
887
|
return;
|
|
888
|
+
// `download` on the folder lets the caller ASK for the zip. What goes in
|
|
889
|
+
// it is judged file by file, through the two gates the per-file route
|
|
890
|
+
// runs in the same order: a file the caller may not read is left out, and
|
|
891
|
+
// so is one they may read but not download. Nothing in the answer names a
|
|
892
|
+
// left-out file; the count below covers only files the caller could
|
|
893
|
+
// already see in the tree, so it discloses nothing the tree does not.
|
|
894
|
+
let withheld = 0;
|
|
895
|
+
const include = async (paths) => {
|
|
896
|
+
const readable = await accessControl.canReadBatch(id, user.email, paths);
|
|
897
|
+
const visible = paths.filter((p) => readable.get(p) === true);
|
|
898
|
+
const downloadable = await accessControl.canDownloadBatch(id, user.email, visible);
|
|
899
|
+
const kept = new Set(visible.filter((p) => downloadable.get(p) === true));
|
|
900
|
+
withheld = visible.length - kept.size;
|
|
901
|
+
return kept;
|
|
902
|
+
};
|
|
891
903
|
try {
|
|
892
|
-
const buffer = await workspaceService.createFolderZip(id, folderPath);
|
|
904
|
+
const buffer = await workspaceService.createFolderZip(id, folderPath, include);
|
|
905
|
+
res.setHeader('X-Withheld-Files', String(withheld));
|
|
906
|
+
// One caller's archive: which files it holds, and the count beside it,
|
|
907
|
+
// are that caller's verdicts. `private` keeps a shared cache from
|
|
908
|
+
// handing it to the next caller; `no-store` because, unlike the single
|
|
909
|
+
// file, nothing here can be revalidated (no ETag), so a copy is never
|
|
910
|
+
// worth keeping.
|
|
911
|
+
res.setHeader('Cache-Control', 'private, no-store');
|
|
893
912
|
// `|| 'folder'` covers the edge case where `folderPath` itself was
|
|
894
913
|
// a single bare slash (`/`) that survived the trim — the service
|
|
895
914
|
// would still reject it as path traversal, but the basename
|
|
@@ -906,7 +925,11 @@ changeGate) {
|
|
|
906
925
|
res.status(413).json({ error: error.message });
|
|
907
926
|
return;
|
|
908
927
|
}
|
|
909
|
-
|
|
928
|
+
// A traversal refusal (`PathTraversalError`), or the access tree failing
|
|
929
|
+
// to load while the entries were judged (`AccessConfigError`): both are
|
|
930
|
+
// domain errors carrying their own status and payload, the same ones
|
|
931
|
+
// the single-file gate answers with.
|
|
932
|
+
if (error instanceof WorkflowDomainError) {
|
|
910
933
|
sendError(res, error);
|
|
911
934
|
return;
|
|
912
935
|
}
|
|
@@ -1011,6 +1034,16 @@ changeGate) {
|
|
|
1011
1034
|
// Not on disk — let workspaceService.deleteFile return its own 404.
|
|
1012
1035
|
}
|
|
1013
1036
|
if (stat?.isDirectory()) {
|
|
1037
|
+
// A platform folder — the repository root, whose sweep would take the
|
|
1038
|
+
// root's `access.md` and `roles.yaml` with it, or one of the reserved
|
|
1039
|
+
// top-level folders that hold a whole section of the knowledge base —
|
|
1040
|
+
// is refused here as `delete_folder` refuses it, by the same rule.
|
|
1041
|
+
const trimmedFolder = filePath.replace(/\/+$/, '');
|
|
1042
|
+
const folderRel = trimmedFolder === kbDirName ? '' : toKbRelative(trimmedFolder, kbDirName);
|
|
1043
|
+
if (folderRel !== null && isPlatformFolder(folderRel, kb.layout)) {
|
|
1044
|
+
res.status(409).json({ error: platformFolderRefusal(folderRel) });
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1014
1047
|
const branch = branchForWorkspaceId(id);
|
|
1015
1048
|
// In the folder's turn: keeping a folder under this one (a file delete
|
|
1016
1049
|
// racing this one) waits until the sweep is done, and then finds the
|
|
@@ -1075,6 +1108,14 @@ changeGate) {
|
|
|
1075
1108
|
res.json({ status: 'deleted', count: filesInDir.length });
|
|
1076
1109
|
return;
|
|
1077
1110
|
}
|
|
1111
|
+
// The root's `access.md` and `roles.yaml` govern the whole repository:
|
|
1112
|
+
// nobody deletes them, here or through the agent tools. A nested
|
|
1113
|
+
// `access.md` is deleted like any file its caller may write.
|
|
1114
|
+
const rel = toKbRelative(filePath, kbDirName);
|
|
1115
|
+
if (rel !== null && isRepositoryOwnFile(rel, kb.layout)) {
|
|
1116
|
+
res.status(409).json({ error: repositoryOwnFileDeleteRefusal(rel) });
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1078
1119
|
await withLock(id, user, filePath, () => workspaceService.deleteFile(id, filePath));
|
|
1079
1120
|
// Deleting content is not deleting structure: an emptied folder stays.
|
|
1080
1121
|
await keepFolderOf(id, user, filePath);
|