@bevel-software/platform-core-backend 0.31.0 → 0.33.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 +5 -0
- package/agent-guide/html-views.md +46 -10
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +29 -4
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +14 -2
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +34 -7
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core/lifecycle.d.ts +8 -0
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/core/lifecycle.js +4 -0
- package/dist/core/lifecycle.js.map +1 -1
- package/dist/core/public-config.d.ts +10 -0
- package/dist/core/public-config.d.ts.map +1 -1
- package/dist/core/public-config.js +10 -0
- package/dist/core/public-config.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +3 -3
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +4 -5
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access-declarations.d.ts +1 -1
- package/dist/modules/access/access-declarations.d.ts.map +1 -1
- package/dist/modules/access/access-declarations.js +1 -1
- package/dist/modules/access/access-declarations.js.map +1 -1
- package/dist/modules/access/access-mutation.service.d.ts +8 -3
- package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
- package/dist/modules/access/access-mutation.service.js +3 -3
- package/dist/modules/access/access-mutation.service.js.map +1 -1
- package/dist/modules/access/access-requests.contract.d.ts +1 -1
- package/dist/modules/access/access-requests.contract.d.ts.map +1 -1
- package/dist/modules/access/access-requests.routes.d.ts +3 -3
- package/dist/modules/access/access-requests.routes.d.ts.map +1 -1
- package/dist/modules/access/access-requests.routes.js +7 -7
- package/dist/modules/access/access-requests.routes.js.map +1 -1
- package/dist/modules/access/access-requests.service.d.ts +21 -20
- package/dist/modules/access/access-requests.service.d.ts.map +1 -1
- package/dist/modules/access/access-requests.service.js +22 -68
- package/dist/modules/access/access-requests.service.js.map +1 -1
- package/dist/modules/access/access-view.d.ts +1 -1
- package/dist/modules/access/access-view.d.ts.map +1 -1
- package/dist/modules/access/access-view.js +1 -1
- package/dist/modules/access/access-view.js.map +1 -1
- package/dist/modules/access/access.routes.d.ts +5 -7
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +4 -4
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access/admin-locked-commit.d.ts +2 -2
- package/dist/modules/access/admin-locked-commit.d.ts.map +1 -1
- package/dist/modules/access/admin-locked-commit.js +1 -1
- package/dist/modules/access/admin-locked-commit.js.map +1 -1
- package/dist/modules/access/capability-registry.js +1 -1
- package/dist/modules/access/capability-registry.js.map +1 -1
- package/dist/modules/access/change-read-gate.d.ts +2 -2
- package/dist/modules/access/change-read-gate.d.ts.map +1 -1
- package/dist/modules/access/change-read-gate.js +1 -3
- package/dist/modules/access/change-read-gate.js.map +1 -1
- package/dist/modules/access/creator-access.d.ts +2 -2
- package/dist/modules/access/creator-access.d.ts.map +1 -1
- package/dist/modules/access/creator-access.js +2 -4
- package/dist/modules/access/creator-access.js.map +1 -1
- package/dist/modules/access/directory-sync-bot.d.ts +1 -1
- package/dist/modules/access/directory-sync-bot.d.ts.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/access/groups-admin.routes.d.ts +2 -2
- package/dist/modules/access/groups-admin.routes.d.ts.map +1 -1
- package/dist/modules/access/groups-admin.routes.js +2 -2
- package/dist/modules/access/groups-admin.routes.js.map +1 -1
- package/dist/modules/access/groups-admin.service.d.ts +1 -1
- package/dist/modules/access/groups-admin.service.d.ts.map +1 -1
- package/dist/modules/access/groups-admin.service.js +2 -3
- package/dist/modules/access/groups-admin.service.js.map +1 -1
- package/dist/modules/access/groups-edit.js +2 -2
- package/dist/modules/access/groups-edit.js.map +1 -1
- package/dist/modules/access/index.d.ts +17 -0
- package/dist/modules/access/index.d.ts.map +1 -0
- package/dist/modules/access/index.js +6 -0
- package/dist/modules/access/index.js.map +1 -0
- package/dist/modules/access/reference-scan.js +1 -1
- package/dist/modules/access/reference-scan.js.map +1 -1
- package/dist/modules/access/roles-admin.service.d.ts +1 -1
- package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
- package/dist/modules/access/roles-admin.service.js +2 -5
- package/dist/modules/access/roles-admin.service.js.map +1 -1
- package/dist/modules/access/roles-edit.js +1 -1
- package/dist/modules/access/roles-edit.js.map +1 -1
- package/dist/modules/access/synced-groups-committer.d.ts +2 -2
- package/dist/modules/access/synced-groups-committer.d.ts.map +1 -1
- package/dist/modules/access/synced-groups-committer.js +2 -2
- package/dist/modules/access/synced-groups-committer.js.map +1 -1
- package/dist/modules/access/synced-groups-writer.js +2 -2
- package/dist/modules/access/synced-groups-writer.js.map +1 -1
- package/dist/modules/access/user-access-removal.service.d.ts +1 -1
- package/dist/modules/access/user-access-removal.service.d.ts.map +1 -1
- package/dist/modules/access/user-access-removal.service.js +2 -5
- package/dist/modules/access/user-access-removal.service.js.map +1 -1
- package/dist/modules/access-model/index.d.ts +29 -0
- package/dist/modules/access-model/index.d.ts.map +1 -0
- package/dist/modules/access-model/index.js +26 -0
- package/dist/modules/access-model/index.js.map +1 -0
- package/dist/modules/access-model/roles-yaml-guard.d.ts +1 -1
- package/dist/modules/access-model/roles-yaml-guard.d.ts.map +1 -1
- package/dist/modules/admin/admin-access.routes.d.ts +1 -1
- package/dist/modules/admin/admin-access.routes.d.ts.map +1 -1
- package/dist/modules/admin/admin-access.routes.js +1 -1
- package/dist/modules/admin/admin-access.routes.js.map +1 -1
- package/dist/modules/admin/admin-access.service.d.ts +2 -2
- package/dist/modules/admin/admin-access.service.d.ts.map +1 -1
- package/dist/modules/admin/index.d.ts +8 -0
- package/dist/modules/admin/index.d.ts.map +1 -0
- package/dist/modules/admin/index.js +2 -0
- package/dist/modules/admin/index.js.map +1 -0
- package/dist/modules/agent-guide/agent-guide.js +1 -1
- package/dist/modules/agent-guide/agent-guide.js.map +1 -1
- package/dist/modules/agent-guide/agent-guide.tools.d.ts +3 -3
- package/dist/modules/agent-guide/agent-guide.tools.d.ts.map +1 -1
- package/dist/modules/agent-guide/agent-guide.tools.js +2 -4
- package/dist/modules/agent-guide/agent-guide.tools.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/read-preamble.d.ts +1 -1
- package/dist/modules/agent-instructions/read-preamble.d.ts.map +1 -1
- package/dist/modules/audit/agent-audit.service.d.ts +2 -2
- package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
- package/dist/modules/audit/agent-audit.service.js +1 -1
- package/dist/modules/audit/agent-audit.service.js.map +1 -1
- package/dist/modules/audit/agent-connection.routes.d.ts +1 -1
- package/dist/modules/audit/agent-connection.routes.d.ts.map +1 -1
- package/dist/modules/audit/agent-connection.routes.js +1 -1
- package/dist/modules/audit/agent-connection.routes.js.map +1 -1
- package/dist/modules/audit/agent-rest-audit.middleware.d.ts +1 -1
- package/dist/modules/audit/agent-rest-audit.middleware.d.ts.map +1 -1
- package/dist/modules/audit/agent-rest-audit.middleware.js +1 -1
- package/dist/modules/audit/agent-rest-audit.middleware.js.map +1 -1
- package/dist/modules/audit/audit.routes.d.ts +3 -3
- package/dist/modules/audit/audit.routes.d.ts.map +1 -1
- package/dist/modules/audit/audit.routes.js +2 -2
- package/dist/modules/audit/audit.routes.js.map +1 -1
- package/dist/modules/auth/account-erasure.service.d.ts +3 -3
- package/dist/modules/auth/account-erasure.service.d.ts.map +1 -1
- package/dist/modules/auth/account-erasure.service.js +1 -5
- package/dist/modules/auth/account-erasure.service.js.map +1 -1
- package/dist/modules/auth/account-hooks.d.ts +4 -6
- package/dist/modules/auth/account-hooks.d.ts.map +1 -1
- package/dist/modules/auth/account-hooks.js +7 -17
- package/dist/modules/auth/account-hooks.js.map +1 -1
- package/dist/modules/auth/account-switch-lock.d.ts +1 -1
- package/dist/modules/auth/account-switch-lock.d.ts.map +1 -1
- package/dist/modules/auth/account-switch-lock.js +1 -1
- package/dist/modules/auth/account-switch-lock.js.map +1 -1
- package/dist/modules/auth/account.routes.d.ts +2 -2
- package/dist/modules/auth/account.routes.d.ts.map +1 -1
- package/dist/modules/auth/account.routes.js +1 -1
- package/dist/modules/auth/account.routes.js.map +1 -1
- package/dist/modules/auth/auth.service.d.ts +10 -9
- package/dist/modules/auth/auth.service.d.ts.map +1 -1
- package/dist/modules/auth/auth.service.js +22 -21
- package/dist/modules/auth/auth.service.js.map +1 -1
- package/dist/modules/auth/index.d.ts +2 -0
- package/dist/modules/auth/index.d.ts.map +1 -1
- package/dist/modules/auth/oidc-auth-provider.js +1 -1
- package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
- package/dist/modules/code-mode/code-mode.tool.d.ts +1 -1
- package/dist/modules/code-mode/code-mode.tool.d.ts.map +1 -1
- package/dist/modules/connection-probe/connection-probe.service.d.ts +2 -2
- package/dist/modules/connection-probe/connection-probe.service.d.ts.map +1 -1
- package/dist/modules/connection-probe/connection-probe.service.js +1 -4
- package/dist/modules/connection-probe/connection-probe.service.js.map +1 -1
- package/dist/modules/database/core-schema.d.ts +128 -235
- package/dist/modules/database/core-schema.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +55 -36
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/database/index.d.ts +10 -0
- package/dist/modules/database/index.d.ts.map +1 -0
- package/dist/modules/database/index.js +4 -0
- package/dist/modules/database/index.js.map +1 -0
- package/dist/modules/database/migrate.d.ts.map +1 -1
- package/dist/modules/database/migrate.js +78 -3
- package/dist/modules/database/migrate.js.map +1 -1
- package/dist/modules/declared-variables/declared-variables.routes.d.ts +2 -2
- package/dist/modules/declared-variables/declared-variables.routes.d.ts.map +1 -1
- package/dist/modules/diff/diff.routes.d.ts +3 -3
- package/dist/modules/diff/diff.routes.d.ts.map +1 -1
- package/dist/modules/diff/diff.routes.js +3 -3
- package/dist/modules/diff/diff.routes.js.map +1 -1
- package/dist/modules/diff/diff.service.d.ts +2 -2
- package/dist/modules/diff/diff.service.d.ts.map +1 -1
- package/dist/modules/diff/index.d.ts +7 -0
- package/dist/modules/diff/index.d.ts.map +1 -0
- package/dist/modules/diff/index.js +2 -0
- package/dist/modules/diff/index.js.map +1 -0
- package/dist/modules/embed/account-link.service.d.ts +1 -1
- package/dist/modules/embed/account-link.service.d.ts.map +1 -1
- package/dist/modules/embed/account-link.service.js +1 -1
- package/dist/modules/embed/account-link.service.js.map +1 -1
- package/dist/modules/embed/embed.routes.d.ts +1 -1
- package/dist/modules/embed/embed.routes.d.ts.map +1 -1
- package/dist/modules/embed/embed.routes.js +2 -2
- package/dist/modules/embed/embed.routes.js.map +1 -1
- package/dist/modules/embed/embed.service.d.ts +1 -1
- package/dist/modules/embed/embed.service.d.ts.map +1 -1
- package/dist/modules/embed/embed.tools.d.ts +4 -4
- package/dist/modules/embed/embed.tools.d.ts.map +1 -1
- package/dist/modules/embed/embed.tools.js +3 -5
- package/dist/modules/embed/embed.tools.js.map +1 -1
- package/dist/modules/github-app/github-app.connection.d.ts +1 -1
- package/dist/modules/github-app/github-app.connection.d.ts.map +1 -1
- package/dist/modules/github-app/github-app.routes.d.ts +3 -3
- package/dist/modules/github-app/github-app.routes.d.ts.map +1 -1
- package/dist/modules/github-app/github-app.routes.js +1 -1
- package/dist/modules/github-app/github-app.routes.js.map +1 -1
- package/dist/modules/kb-fs/index.d.ts +10 -0
- package/dist/modules/kb-fs/index.d.ts.map +1 -1
- package/dist/modules/kb-fs/index.js +10 -0
- package/dist/modules/kb-fs/index.js.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.d.ts +1 -1
- package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.routes.d.ts +1 -1
- package/dist/modules/kb-sync/kb-sync.routes.d.ts.map +1 -1
- package/dist/modules/kb-sync/kb-sync.routes.js +2 -2
- package/dist/modules/kb-sync/kb-sync.routes.js.map +1 -1
- package/dist/modules/kb-sync/kb-sync.service.js +1 -1
- package/dist/modules/kb-sync/kb-sync.service.js.map +1 -1
- package/dist/modules/kb-sync/sync-auth.js +1 -1
- package/dist/modules/kb-sync/sync-auth.js.map +1 -1
- package/dist/modules/kb-sync/sync-payload.js +1 -1
- package/dist/modules/kb-sync/sync-payload.js.map +1 -1
- package/dist/modules/marketplace/git-http.routes.d.ts +1 -1
- package/dist/modules/marketplace/git-http.routes.d.ts.map +1 -1
- package/dist/modules/marketplace/git-http.routes.js +1 -1
- package/dist/modules/marketplace/git-http.routes.js.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-codes.store.js +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-codes.store.js.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js +1 -1
- package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts +2 -2
- package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade.routes.js +2 -2
- package/dist/modules/marketplace/github-facade/github-facade.routes.js.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade.service.d.ts +2 -2
- package/dist/modules/marketplace/github-facade/github-facade.service.d.ts.map +1 -1
- package/dist/modules/marketplace/github-facade/github-facade.service.js +1 -1
- package/dist/modules/marketplace/github-facade/github-facade.service.js.map +1 -1
- package/dist/modules/marketplace/marketplace-repo.service.d.ts +1 -1
- package/dist/modules/marketplace/marketplace-repo.service.d.ts.map +1 -1
- package/dist/modules/marketplace/marketplace-repo.service.js +1 -1
- package/dist/modules/mcp/index.d.ts +8 -0
- package/dist/modules/mcp/index.d.ts.map +1 -0
- package/dist/modules/mcp/index.js +7 -0
- package/dist/modules/mcp/index.js.map +1 -0
- package/dist/modules/mcp/mcp-auth.middleware.d.ts +4 -5
- package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.js +4 -4
- package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
- package/dist/modules/mcp/mcp.routes.d.ts +2 -4
- package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.routes.js +2 -2
- package/dist/modules/mcp/mcp.routes.js.map +1 -1
- package/dist/modules/mcp/mcp.service.d.ts +14 -4
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.service.js +17 -7
- package/dist/modules/mcp/mcp.service.js.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +29 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js +167 -40
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +1 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.js +1 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -1
- package/dist/modules/onboarding/onboarding.routes.d.ts +1 -1
- package/dist/modules/onboarding/onboarding.routes.d.ts.map +1 -1
- package/dist/modules/onboarding/onboarding.routes.js +1 -1
- package/dist/modules/onboarding/onboarding.routes.js.map +1 -1
- package/dist/modules/onboarding/starter-pack.service.d.ts +4 -5
- package/dist/modules/onboarding/starter-pack.service.d.ts.map +1 -1
- package/dist/modules/onboarding/starter-pack.service.js +2 -2
- package/dist/modules/onboarding/starter-pack.service.js.map +1 -1
- package/dist/modules/plugins/compile/compile-marketplace.d.ts +1 -1
- package/dist/modules/plugins/compile/compile-marketplace.d.ts.map +1 -1
- package/dist/modules/plugins/compile/compile-marketplace.js +1 -1
- package/dist/modules/plugins/compile/compile-marketplace.js.map +1 -1
- package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +3 -3
- package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -1
- package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts +1 -1
- package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts.map +1 -1
- package/dist/modules/plugins/discovery/bundle-dialect/registry.js +1 -1
- package/dist/modules/plugins/discovery/bundle-dialect/registry.js.map +1 -1
- package/dist/modules/plugins/index.d.ts +1 -0
- package/dist/modules/plugins/index.d.ts.map +1 -1
- package/dist/modules/plugins/index.js +2 -0
- package/dist/modules/plugins/index.js.map +1 -1
- package/dist/modules/plugins/join-proposals.d.ts +2 -2
- package/dist/modules/plugins/join-proposals.d.ts.map +1 -1
- package/dist/modules/plugins/join-proposals.js +1 -1
- package/dist/modules/plugins/join-proposals.js.map +1 -1
- package/dist/modules/plugins/join-request-jobs.service.d.ts +1 -1
- package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
- package/dist/modules/plugins/join-request-jobs.service.js +2 -2
- package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
- package/dist/modules/plugins/join-request-records.store.d.ts +1 -1
- package/dist/modules/plugins/join-request-records.store.d.ts.map +1 -1
- package/dist/modules/plugins/join-request-records.store.js +1 -1
- package/dist/modules/plugins/join-request-records.store.js.map +1 -1
- package/dist/modules/plugins/join-requests.service.d.ts +3 -3
- package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
- package/dist/modules/plugins/join-requests.service.js +1 -1
- package/dist/modules/plugins/join-requests.service.js.map +1 -1
- package/dist/modules/plugins/plugin-links.d.ts +3 -3
- package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-links.js +1 -1
- package/dist/modules/plugins/plugin-links.js.map +1 -1
- package/dist/modules/plugins/plugin-links.service.d.ts +8 -5
- package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-links.service.js +8 -6
- package/dist/modules/plugins/plugin-links.service.js.map +1 -1
- package/dist/modules/plugins/plugin-provision.service.d.ts +2 -2
- package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-provision.service.js +2 -3
- package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
- package/dist/modules/plugins/plugin-rename.service.d.ts +2 -2
- package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-rename.service.js +1 -1
- package/dist/modules/plugins/plugin-rename.service.js.map +1 -1
- package/dist/modules/plugins/plugins.contract.d.ts +1 -1
- package/dist/modules/plugins/plugins.contract.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.d.ts +2 -2
- package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.js +3 -3
- package/dist/modules/plugins/plugins.routes.js.map +1 -1
- package/dist/modules/plugins/plugins.service.d.ts +4 -4
- package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.service.js +1 -1
- package/dist/modules/plugins/plugins.service.js.map +1 -1
- package/dist/modules/plugins/plugins.tools.d.ts +1 -1
- package/dist/modules/plugins/plugins.tools.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.tools.js +3 -3
- package/dist/modules/plugins/plugins.tools.js.map +1 -1
- package/dist/modules/plugins/teams.routes.d.ts +3 -3
- package/dist/modules/plugins/teams.routes.d.ts.map +1 -1
- package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts +1 -1
- package/dist/modules/secrets-vault/db-secrets-vault.service.d.ts.map +1 -1
- package/dist/modules/secrets-vault/db-secrets-vault.service.js +1 -1
- package/dist/modules/secrets-vault/db-secrets-vault.service.js.map +1 -1
- package/dist/modules/secrets-vault/index.d.ts +1 -0
- package/dist/modules/secrets-vault/index.d.ts.map +1 -1
- package/dist/modules/secrets-vault/index.js +2 -0
- package/dist/modules/secrets-vault/index.js.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +4 -4
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.js +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
- package/dist/modules/settings/connection-check.js +1 -1
- package/dist/modules/settings/connection-check.js.map +1 -1
- package/dist/modules/settings/deployment-settings.service.d.ts +7 -1
- package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
- package/dist/modules/settings/deployment-settings.service.js +45 -3
- package/dist/modules/settings/deployment-settings.service.js.map +1 -1
- package/dist/modules/settings/git-root-folders.js +1 -1
- package/dist/modules/settings/git-root-folders.js.map +1 -1
- package/dist/modules/settings/index.d.ts +13 -0
- package/dist/modules/settings/index.d.ts.map +1 -0
- package/dist/modules/settings/index.js +3 -0
- package/dist/modules/settings/index.js.map +1 -0
- package/dist/modules/settings/setup.routes.d.ts +3 -3
- package/dist/modules/settings/setup.routes.d.ts.map +1 -1
- package/dist/modules/settings/setup.routes.js +2 -2
- package/dist/modules/settings/setup.routes.js.map +1 -1
- package/dist/modules/skills/allowed-tools-check.d.ts +2 -2
- package/dist/modules/skills/allowed-tools-check.d.ts.map +1 -1
- package/dist/modules/skills/allowed-tools-check.js +1 -1
- package/dist/modules/skills/allowed-tools-check.js.map +1 -1
- package/dist/modules/skills/index.d.ts +1 -0
- package/dist/modules/skills/index.d.ts.map +1 -1
- package/dist/modules/skills/pending-skills.service.d.ts +3 -3
- package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
- package/dist/modules/skills/pending-skills.service.js.map +1 -1
- package/dist/modules/skills/skill-access-requests.routes.d.ts +5 -5
- package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
- package/dist/modules/skills/skill-access-requests.routes.js +6 -13
- package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
- package/dist/modules/skills/skills.routes.d.ts +1 -1
- package/dist/modules/skills/skills.routes.d.ts.map +1 -1
- package/dist/modules/skills/skills.routes.js +1 -1
- package/dist/modules/skills/skills.routes.js.map +1 -1
- package/dist/modules/skills/skills.service.d.ts +2 -2
- package/dist/modules/skills/skills.service.d.ts.map +1 -1
- package/dist/modules/skills/skills.tools.d.ts +3 -3
- package/dist/modules/skills/skills.tools.d.ts.map +1 -1
- package/dist/modules/skills/skills.tools.js +3 -7
- package/dist/modules/skills/skills.tools.js.map +1 -1
- package/dist/modules/tool-auth/connection-key-rejection.js +1 -1
- package/dist/modules/tool-auth/connection-key-rejection.js.map +1 -1
- package/dist/modules/tool-auth/connection-keys-admin.routes.d.ts +2 -2
- package/dist/modules/tool-auth/connection-keys-admin.routes.d.ts.map +1 -1
- package/dist/modules/tool-auth/connection-keys-admin.routes.js +1 -1
- package/dist/modules/tool-auth/connection-keys-admin.routes.js.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.d.ts +1 -1
- package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.js +1 -1
- package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
- package/dist/modules/tool-auth/index.d.ts +15 -0
- package/dist/modules/tool-auth/index.d.ts.map +1 -0
- package/dist/modules/tool-auth/index.js +11 -0
- package/dist/modules/tool-auth/index.js.map +1 -0
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts +2 -2
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.js +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
- package/dist/modules/tool-helpers/default-branch-write.d.ts +1 -1
- package/dist/modules/tool-helpers/default-branch-write.d.ts.map +1 -1
- package/dist/modules/tool-helpers/index.d.ts +4 -1
- package/dist/modules/tool-helpers/index.d.ts.map +1 -1
- package/dist/modules/tool-helpers/index.js +3 -0
- package/dist/modules/tool-helpers/index.js.map +1 -1
- package/dist/modules/tool-helpers/route-argument-check.js +1 -1
- package/dist/modules/tool-helpers/route-argument-check.js.map +1 -1
- package/dist/modules/tool-helpers/route-tool-schemas.d.ts +1 -1
- package/dist/modules/tool-helpers/route-tool-schemas.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-context.d.ts +5 -6
- package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-context.js +2 -3
- package/dist/modules/tool-helpers/tool-context.js.map +1 -1
- package/dist/modules/tool-helpers/tool-def.d.ts +4 -2
- package/dist/modules/tool-helpers/tool-def.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-def.js +3 -1
- package/dist/modules/tool-helpers/tool-def.js.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.d.ts +2 -2
- package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.js +2 -2
- package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.d.ts +2 -2
- package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
- package/dist/modules/tool-helpers/validate-token.d.ts +1 -2
- package/dist/modules/tool-helpers/validate-token.d.ts.map +1 -1
- package/dist/modules/tool-helpers/validate-token.js +1 -1
- package/dist/modules/tool-helpers/validate-token.js.map +1 -1
- package/dist/modules/tool-manuals/index.d.ts +5 -0
- package/dist/modules/tool-manuals/index.d.ts.map +1 -1
- package/dist/modules/tool-manuals/index.js +4 -0
- package/dist/modules/tool-manuals/index.js.map +1 -1
- package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts +2 -2
- package/dist/modules/tool-manuals/mcp-server-edit.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/pending-tools.service.d.ts +2 -2
- package/dist/modules/tool-manuals/pending-tools.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-delete.service.d.ts +5 -6
- package/dist/modules/tool-manuals/tool-delete.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-delete.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +5 -5
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.js +2 -2
- package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts +3 -3
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts +3 -3
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.js +1 -2
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
- package/dist/modules/tool-registry/description-length.js +2 -2
- package/dist/modules/tool-registry/description-length.js.map +1 -1
- package/dist/modules/tool-registry/index.d.ts +8 -0
- package/dist/modules/tool-registry/index.d.ts.map +1 -0
- package/dist/modules/tool-registry/index.js +8 -0
- package/dist/modules/tool-registry/index.js.map +1 -0
- package/dist/modules/tool-registry/manual.routes.d.ts +37 -2
- package/dist/modules/tool-registry/manual.routes.d.ts.map +1 -1
- package/dist/modules/tool-registry/manual.routes.js +14 -7
- package/dist/modules/tool-registry/manual.routes.js.map +1 -1
- package/dist/modules/tool-registry/read-only-hints.contract.d.ts +52 -0
- package/dist/modules/tool-registry/read-only-hints.contract.d.ts.map +1 -0
- package/dist/modules/tool-registry/read-only-hints.contract.js +2 -0
- package/dist/modules/tool-registry/read-only-hints.contract.js.map +1 -0
- package/dist/modules/tool-registry/read-only-hints.d.ts +89 -0
- package/dist/modules/tool-registry/read-only-hints.d.ts.map +1 -0
- package/dist/modules/tool-registry/read-only-hints.js +212 -0
- package/dist/modules/tool-registry/read-only-hints.js.map +1 -0
- package/dist/modules/tool-registry/tool.contract.d.ts +8 -0
- package/dist/modules/tool-registry/tool.contract.d.ts.map +1 -1
- package/dist/modules/tool-registry/tool.contract.js +10 -1
- package/dist/modules/tool-registry/tool.contract.js.map +1 -1
- package/dist/modules/update-check/update-check.routes.d.ts +2 -2
- package/dist/modules/update-check/update-check.routes.d.ts.map +1 -1
- package/dist/modules/update-check/update-check.routes.js +1 -1
- package/dist/modules/update-check/update-check.routes.js.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts +9 -104
- package/dist/modules/workflow/agent-tools/change-request-read-shape.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-read-shape.js +8 -118
- package/dist/modules/workflow/agent-tools/change-request-read-shape.js.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts +16 -17
- 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 +19 -86
- package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-summary.d.ts +15 -2
- package/dist/modules/workflow/agent-tools/change-request-summary.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-summary.js +12 -1
- package/dist/modules/workflow/agent-tools/change-request-summary.js.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +7 -5
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js +51 -68
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
- package/dist/modules/workflow/change-request-hooks.d.ts +78 -0
- package/dist/modules/workflow/change-request-hooks.d.ts.map +1 -0
- package/dist/modules/workflow/change-request-hooks.js +15 -0
- package/dist/modules/workflow/change-request-hooks.js.map +1 -0
- package/dist/modules/workflow/event-bus.d.ts.map +1 -1
- package/dist/modules/workflow/event-bus.js +3 -1
- package/dist/modules/workflow/event-bus.js.map +1 -1
- package/dist/modules/workflow/events-delivery.d.ts +120 -0
- package/dist/modules/workflow/events-delivery.d.ts.map +1 -0
- package/dist/modules/workflow/events-delivery.js +202 -0
- package/dist/modules/workflow/events-delivery.js.map +1 -0
- package/dist/modules/workflow/events.routes.d.ts +16 -7
- package/dist/modules/workflow/events.routes.d.ts.map +1 -1
- package/dist/modules/workflow/events.routes.js +23 -4
- package/dist/modules/workflow/events.routes.js.map +1 -1
- package/dist/modules/workflow/file-lock.service.d.ts +1 -1
- package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
- package/dist/modules/workflow/file-lock.service.js +1 -1
- package/dist/modules/workflow/file-lock.service.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +2 -2
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +3 -6
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/git/node-git-runner.js +1 -1
- package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.d.ts +16 -7
- package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.js +49 -33
- package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
- package/dist/modules/workflow/index.d.ts +14 -2
- package/dist/modules/workflow/index.d.ts.map +1 -1
- package/dist/modules/workflow/index.js +11 -2
- package/dist/modules/workflow/index.js.map +1 -1
- package/dist/modules/workflow/pending-commits.service.d.ts +1 -1
- package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
- package/dist/modules/workflow/pending-commits.service.js +1 -1
- package/dist/modules/workflow/pending-commits.service.js.map +1 -1
- package/dist/modules/workflow/read-on-branch.d.ts +1 -1
- package/dist/modules/workflow/read-on-branch.d.ts.map +1 -1
- package/dist/modules/workflow/recovery-bot.d.ts +1 -1
- package/dist/modules/workflow/recovery-bot.d.ts.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/approval-lock.d.ts +1 -1
- package/dist/modules/workflow/review-workflow/approval-lock.d.ts.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts +4 -20
- package/dist/modules/workflow/review-workflow/review-workflow.interface.d.ts.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts +4 -8
- package/dist/modules/workflow/review-workflow/review-workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/review-workflow/review-workflow.service.js +3 -138
- package/dist/modules/workflow/review-workflow/review-workflow.service.js.map +1 -1
- package/dist/modules/workflow/workflow.routes.d.ts +5 -5
- package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.routes.js +42 -94
- package/dist/modules/workflow/workflow.routes.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +112 -62
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +367 -172
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/agent-access.gate.d.ts +3 -3
- package/dist/modules/workspace/agent-access.gate.d.ts.map +1 -1
- package/dist/modules/workspace/agent-download.builder.d.ts +1 -1
- package/dist/modules/workspace/agent-download.builder.d.ts.map +1 -1
- package/dist/modules/workspace/agent-download.builder.js +1 -1
- package/dist/modules/workspace/agent-download.builder.js.map +1 -1
- package/dist/modules/workspace/agent-upload.routes.d.ts.map +1 -1
- package/dist/modules/workspace/agent-upload.routes.js +19 -0
- package/dist/modules/workspace/agent-upload.routes.js.map +1 -1
- package/dist/modules/workspace/agent-upload.store.d.ts +11 -0
- package/dist/modules/workspace/agent-upload.store.d.ts.map +1 -1
- package/dist/modules/workspace/agent-upload.store.js +18 -0
- package/dist/modules/workspace/agent-upload.store.js.map +1 -1
- package/dist/modules/workspace/bounded-matcher.d.ts +5 -11
- package/dist/modules/workspace/bounded-matcher.d.ts.map +1 -1
- package/dist/modules/workspace/bounded-matcher.js +26 -87
- package/dist/modules/workspace/bounded-matcher.js.map +1 -1
- package/dist/modules/workspace/file-readers/doc-extract.service.d.ts +54 -10
- package/dist/modules/workspace/file-readers/doc-extract.service.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/doc-extract.service.js +69 -17
- package/dist/modules/workspace/file-readers/doc-extract.service.js.map +1 -1
- package/dist/modules/workspace/file-readers/doc-extract.types.d.ts +9 -2
- package/dist/modules/workspace/file-readers/doc-extract.types.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/doc-extract.types.js.map +1 -1
- package/dist/modules/workspace/file-readers/document-extractor.contract.d.ts +41 -0
- package/dist/modules/workspace/file-readers/document-extractor.contract.d.ts.map +1 -0
- package/dist/modules/workspace/file-readers/document-extractor.contract.js +5 -0
- package/dist/modules/workspace/file-readers/document-extractor.contract.js.map +1 -0
- package/dist/modules/workspace/file-readers/document-extractors.d.ts +9 -0
- package/dist/modules/workspace/file-readers/document-extractors.d.ts.map +1 -0
- package/dist/modules/workspace/file-readers/document-extractors.js +26 -0
- package/dist/modules/workspace/file-readers/document-extractors.js.map +1 -0
- package/dist/modules/workspace/file-readers/document-formats.d.ts +12 -0
- package/dist/modules/workspace/file-readers/document-formats.d.ts.map +1 -0
- package/dist/modules/workspace/file-readers/document-formats.js +11 -0
- package/dist/modules/workspace/file-readers/document-formats.js.map +1 -0
- package/dist/modules/workspace/file-readers/document-reader.d.ts +21 -17
- package/dist/modules/workspace/file-readers/document-reader.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/document-reader.js +38 -34
- package/dist/modules/workspace/file-readers/document-reader.js.map +1 -1
- package/dist/modules/workspace/file-readers/extract-in-worker.d.ts +60 -0
- package/dist/modules/workspace/file-readers/extract-in-worker.d.ts.map +1 -0
- package/dist/modules/workspace/file-readers/extract-in-worker.js +140 -0
- package/dist/modules/workspace/file-readers/extract-in-worker.js.map +1 -0
- package/dist/modules/workspace/file-readers/extract-pdf.d.ts +2 -0
- package/dist/modules/workspace/file-readers/extract-pdf.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/extract-pdf.js +20 -3
- package/dist/modules/workspace/file-readers/extract-pdf.js.map +1 -1
- package/dist/modules/workspace/file-readers/extract.worker.d.ts +2 -0
- package/dist/modules/workspace/file-readers/extract.worker.d.ts.map +1 -0
- package/dist/modules/workspace/file-readers/extract.worker.js +5 -0
- package/dist/modules/workspace/file-readers/extract.worker.js.map +1 -0
- package/dist/modules/workspace/file-readers/extraction-cache.d.ts +21 -5
- package/dist/modules/workspace/file-readers/extraction-cache.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/extraction-cache.js +24 -10
- package/dist/modules/workspace/file-readers/extraction-cache.js.map +1 -1
- package/dist/modules/workspace/file-readers/extraction-worker.d.ts +42 -0
- package/dist/modules/workspace/file-readers/extraction-worker.d.ts.map +1 -0
- package/dist/modules/workspace/file-readers/extraction-worker.js +69 -0
- package/dist/modules/workspace/file-readers/extraction-worker.js.map +1 -0
- package/dist/modules/workspace/file-readers/file-reader.d.ts +13 -4
- package/dist/modules/workspace/file-readers/file-reader.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/file-reader.js.map +1 -1
- package/dist/modules/workspace/file-readers/file-reader.registry.d.ts +3 -2
- package/dist/modules/workspace/file-readers/file-reader.registry.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/file-reader.registry.js +6 -20
- package/dist/modules/workspace/file-readers/file-reader.registry.js.map +1 -1
- package/dist/modules/workspace/first-run.js +1 -1
- package/dist/modules/workspace/first-run.js.map +1 -1
- package/dist/modules/workspace/git-internals.middleware.d.ts +1 -1
- package/dist/modules/workspace/git-internals.middleware.d.ts.map +1 -1
- package/dist/modules/workspace/git-internals.middleware.js +1 -1
- package/dist/modules/workspace/git-internals.middleware.js.map +1 -1
- package/dist/modules/workspace/index.d.ts +16 -0
- package/dist/modules/workspace/index.d.ts.map +1 -1
- package/dist/modules/workspace/index.js +13 -0
- package/dist/modules/workspace/index.js.map +1 -1
- package/dist/modules/workspace/kb-repository.d.ts.map +1 -1
- package/dist/modules/workspace/kb-repository.js +1 -1
- package/dist/modules/workspace/kb-repository.js.map +1 -1
- package/dist/modules/workspace/not-found.d.ts +1 -1
- package/dist/modules/workspace/not-found.d.ts.map +1 -1
- package/dist/modules/workspace/not-found.js +1 -1
- package/dist/modules/workspace/not-found.js.map +1 -1
- package/dist/modules/workspace/pattern-matcher.contract.d.ts +1 -1
- package/dist/modules/workspace/pattern-matcher.contract.d.ts.map +1 -1
- package/dist/modules/workspace/pattern-matcher.contract.js +1 -1
- package/dist/modules/workspace/pattern-matcher.contract.js.map +1 -1
- package/dist/modules/workspace/routine-write-policy.js +1 -1
- package/dist/modules/workspace/routine-write-policy.js.map +1 -1
- package/dist/modules/workspace/startup/kb-git.js +1 -1
- package/dist/modules/workspace/startup/kb-git.js.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.js +1 -2
- package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js +2 -2
- package/dist/modules/workspace/startup/steps/groups-to-plugins.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/personal-spaces.step.js +2 -2
- package/dist/modules/workspace/startup/steps/personal-spaces.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/plugin-layout.js +1 -1
- package/dist/modules/workspace/startup/steps/plugin-layout.js.map +1 -1
- package/dist/modules/workspace/startup/steps/roles-yaml.step.js +1 -1
- package/dist/modules/workspace/startup/steps/roles-yaml.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.js +2 -2
- package/dist/modules/workspace/startup/steps/seed-tree.js.map +1 -1
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts +1 -1
- package/dist/modules/workspace/startup/steps/template-files.step.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/template-files.step.js +2 -2
- package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
- package/dist/modules/workspace/startup/steps/template-source.js +2 -2
- package/dist/modules/workspace/startup/steps/template-source.js.map +1 -1
- package/dist/modules/workspace/worker-pool.d.ts +100 -0
- package/dist/modules/workspace/worker-pool.d.ts.map +1 -0
- package/dist/modules/workspace/worker-pool.js +156 -0
- package/dist/modules/workspace/worker-pool.js.map +1 -0
- package/dist/modules/workspace/workspace.routes.d.ts +7 -8
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +4 -6
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +1 -1
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +3 -6
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.d.ts +7 -7
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +45 -27
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/modules/workspace/write-denial.d.ts +4 -4
- package/dist/modules/workspace/write-denial.d.ts.map +1 -1
- package/dist/modules/workspace/write-denial.js +2 -3
- package/dist/modules/workspace/write-denial.js.map +1 -1
- package/dist/modules/write-access/index.d.ts +8 -0
- package/dist/modules/write-access/index.d.ts.map +1 -0
- package/dist/modules/write-access/index.js +7 -0
- package/dist/modules/write-access/index.js.map +1 -0
- package/dist/shared/listener-seam.d.ts +34 -0
- package/dist/shared/listener-seam.d.ts.map +1 -0
- package/dist/shared/listener-seam.js +42 -0
- package/dist/shared/listener-seam.js.map +1 -0
- package/migrations/0019_oauth_token_rotated_at.sql +7 -0
- package/migrations/0020_change_request_body_is_the_description.sql +20 -0
- package/migrations/0021_data_migrations_ledger.sql +11 -0
- package/migrations/meta/0019_snapshot.json +2435 -0
- package/migrations/meta/0020_snapshot.json +2321 -0
- package/migrations/meta/0021_snapshot.json +2353 -0
- package/migrations/meta/_journal.json +21 -0
- package/package.json +3 -3
- package/src/core/__tests__/damaged-document.tools.test.ts +374 -0
- package/src/core/__tests__/public-config.test.ts +5 -0
- package/src/core/create-core-server.ts +32 -3
- package/src/core/create-core-services.ts +49 -5
- package/src/core/lifecycle.ts +10 -0
- package/src/core/public-config.ts +10 -0
- package/src/index.ts +7 -0
- package/src/modules/access/__tests__/access-requests.routes.test.ts +29 -15
- package/src/modules/access/access-control.service.ts +5 -6
- package/src/modules/access/access-declarations.ts +1 -1
- package/src/modules/access/access-mutation.service.ts +10 -4
- package/src/modules/access/access-requests.contract.ts +1 -1
- package/src/modules/access/access-requests.routes.ts +10 -15
- package/src/modules/access/access-requests.service.ts +29 -71
- package/src/modules/access/access-view.ts +1 -1
- package/src/modules/access/access.routes.ts +9 -11
- package/src/modules/access/admin-locked-commit.ts +3 -2
- package/src/modules/access/capability-registry.ts +1 -1
- package/src/modules/access/change-read-gate.ts +3 -5
- package/src/modules/access/creator-access.ts +3 -5
- package/src/modules/access/directory-sync-bot.ts +2 -2
- package/src/modules/access/groups-admin.routes.ts +3 -3
- package/src/modules/access/groups-admin.service.ts +3 -4
- package/src/modules/access/groups-edit.ts +2 -2
- package/src/modules/access/index.ts +17 -0
- package/src/modules/access/reference-scan.ts +1 -1
- package/src/modules/access/roles-admin.service.ts +3 -6
- package/src/modules/access/roles-edit.ts +1 -1
- package/src/modules/access/synced-groups-committer.ts +4 -4
- package/src/modules/access/synced-groups-writer.ts +2 -2
- package/src/modules/access/user-access-removal.service.ts +3 -6
- package/src/modules/access-model/index.ts +29 -0
- package/src/modules/access-model/roles-yaml-guard.ts +1 -1
- package/src/modules/admin/admin-access.routes.ts +1 -1
- package/src/modules/admin/admin-access.service.ts +2 -2
- package/src/modules/admin/index.ts +7 -0
- package/src/modules/agent-guide/__tests__/agent-guide.test.ts +5 -0
- package/src/modules/agent-guide/agent-guide.tools.ts +4 -6
- package/src/modules/agent-guide/agent-guide.ts +1 -1
- package/src/modules/agent-guide/index.ts +1 -1
- package/src/modules/agent-instructions/read-preamble.ts +1 -1
- package/src/modules/audit/agent-audit.service.ts +3 -3
- package/src/modules/audit/agent-connection.routes.ts +1 -1
- package/src/modules/audit/agent-rest-audit.middleware.ts +1 -1
- package/src/modules/audit/audit.routes.ts +4 -4
- package/src/modules/auth/__tests__/account-deactivation.test.ts +38 -2
- package/src/modules/auth/account-erasure.service.ts +4 -9
- package/src/modules/auth/account-hooks.ts +13 -21
- package/src/modules/auth/account-switch-lock.ts +2 -2
- package/src/modules/auth/account.routes.ts +3 -3
- package/src/modules/auth/auth.service.ts +23 -22
- package/src/modules/auth/index.ts +3 -0
- package/src/modules/auth/oidc-auth-provider.ts +1 -1
- package/src/modules/code-mode/code-mode.tool.ts +1 -1
- package/src/modules/connection-probe/connection-probe.service.ts +3 -6
- package/src/modules/database/__tests__/legacy-change-request-body.test.ts +118 -0
- package/src/modules/database/__tests__/legacy-request-bodies.pg.test.ts +258 -0
- package/src/modules/database/__tests__/pii-backfill.pg.test.ts +15 -18
- package/src/modules/database/core-schema.ts +59 -37
- package/src/modules/database/index.ts +9 -0
- package/src/modules/database/migrate.ts +79 -3
- package/src/modules/declared-variables/declared-variables.routes.ts +2 -2
- package/src/modules/diff/diff.routes.ts +5 -5
- package/src/modules/diff/diff.service.ts +2 -2
- package/src/modules/diff/index.ts +6 -0
- package/src/modules/embed/account-link.service.ts +2 -2
- package/src/modules/embed/embed.routes.ts +2 -2
- package/src/modules/embed/embed.service.ts +1 -1
- package/src/modules/embed/embed.tools.ts +6 -9
- package/src/modules/github-app/github-app.connection.ts +1 -1
- package/src/modules/github-app/github-app.routes.ts +3 -3
- package/src/modules/kb-fs/index.ts +11 -0
- package/src/modules/kb-fs/locking-filesystem.ts +1 -1
- package/src/modules/kb-sync/kb-sync.routes.ts +3 -3
- package/src/modules/kb-sync/kb-sync.service.ts +1 -1
- package/src/modules/kb-sync/sync-auth.ts +1 -1
- package/src/modules/kb-sync/sync-payload.ts +1 -1
- package/src/modules/marketplace/git-http.routes.ts +1 -1
- package/src/modules/marketplace/github-facade/github-facade-admin.routes.ts +1 -1
- package/src/modules/marketplace/github-facade/github-facade-codes.store.ts +2 -2
- package/src/modules/marketplace/github-facade/github-facade-credentials.service.ts +2 -2
- package/src/modules/marketplace/github-facade/github-facade.routes.ts +2 -2
- package/src/modules/marketplace/github-facade/github-facade.service.ts +2 -2
- package/src/modules/marketplace/marketplace-repo.service.ts +2 -2
- package/src/modules/mcp/__tests__/bevel-oauth-provider.pg.test.ts +279 -0
- package/src/modules/mcp/__tests__/bevel-oauth-provider.test.ts +190 -15
- package/src/modules/mcp/__tests__/read-only-hint.e2e.test.ts +213 -0
- package/src/modules/mcp/index.ts +7 -0
- package/src/modules/mcp/mcp-auth.middleware.ts +6 -7
- package/src/modules/mcp/mcp.routes.ts +3 -5
- package/src/modules/mcp/mcp.service.ts +30 -13
- package/src/modules/mcp/oauth/bevel-oauth-provider.ts +216 -50
- package/src/modules/mcp/oauth/oauth-consent.routes.ts +1 -1
- package/src/modules/onboarding/onboarding.routes.ts +1 -1
- package/src/modules/onboarding/starter-pack.service.ts +5 -6
- package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +2 -1
- package/src/modules/plugins/__tests__/plugin-links.service.test.ts +2 -1
- package/src/modules/plugins/compile/compile-marketplace.ts +2 -2
- package/src/modules/plugins/compile/marketplace-compiler.service.ts +3 -3
- package/src/modules/plugins/discovery/bundle-dialect/registry.ts +1 -1
- package/src/modules/plugins/index.ts +2 -0
- package/src/modules/plugins/join-proposals.ts +2 -2
- package/src/modules/plugins/join-request-jobs.service.ts +3 -3
- package/src/modules/plugins/join-request-records.store.ts +2 -2
- package/src/modules/plugins/join-requests.service.ts +4 -4
- package/src/modules/plugins/plugin-links.service.ts +10 -11
- package/src/modules/plugins/plugin-links.ts +4 -4
- package/src/modules/plugins/plugin-provision.service.ts +4 -5
- package/src/modules/plugins/plugin-rename.service.ts +3 -3
- package/src/modules/plugins/plugins.contract.ts +1 -1
- package/src/modules/plugins/plugins.routes.ts +4 -4
- package/src/modules/plugins/plugins.service.ts +5 -5
- package/src/modules/plugins/plugins.tools.ts +4 -4
- package/src/modules/plugins/teams.routes.ts +3 -3
- package/src/modules/secrets-vault/db-secrets-vault.service.ts +2 -2
- package/src/modules/secrets-vault/index.ts +2 -0
- package/src/modules/secrets-vault/secrets-vault.routes.ts +4 -4
- package/src/modules/settings/__tests__/deployment-settings.service.test.ts +88 -1
- package/src/modules/settings/connection-check.ts +1 -1
- package/src/modules/settings/deployment-settings.service.ts +44 -4
- package/src/modules/settings/git-root-folders.ts +1 -1
- package/src/modules/settings/index.ts +12 -0
- package/src/modules/settings/setup.routes.ts +5 -4
- package/src/modules/skills/__tests__/allowed-tools-warn.tools.test.ts +2 -2
- package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +6 -3
- package/src/modules/skills/allowed-tools-check.ts +2 -6
- package/src/modules/skills/index.ts +2 -0
- package/src/modules/skills/pending-skills.service.ts +3 -4
- package/src/modules/skills/skill-access-requests.routes.ts +10 -17
- package/src/modules/skills/skills.routes.ts +1 -1
- package/src/modules/skills/skills.service.ts +2 -2
- package/src/modules/skills/skills.tools.ts +5 -9
- package/src/modules/tool-auth/connection-key-rejection.ts +1 -1
- package/src/modules/tool-auth/connection-keys-admin.routes.ts +2 -2
- package/src/modules/tool-auth/external-api-key.service.ts +2 -2
- package/src/modules/tool-auth/index.ts +14 -0
- package/src/modules/tool-auth/tool-auth.middleware.ts +3 -3
- package/src/modules/tool-helpers/__tests__/agent-roles-write.test.ts +2 -2
- package/src/modules/tool-helpers/__tests__/can-write.tools.test.ts +2 -2
- package/src/modules/tool-helpers/__tests__/phase4-tools.test.ts +2 -2
- package/src/modules/tool-helpers/default-branch-write.ts +1 -1
- package/src/modules/tool-helpers/index.ts +5 -1
- package/src/modules/tool-helpers/route-argument-check.ts +1 -1
- package/src/modules/tool-helpers/route-tool-schemas.ts +1 -1
- package/src/modules/tool-helpers/tool-context.ts +8 -10
- package/src/modules/tool-helpers/tool-def.ts +7 -3
- package/src/modules/tool-helpers/tool-handler.ts +2 -2
- package/src/modules/tool-helpers/tool.contract.ts +2 -2
- package/src/modules/tool-helpers/validate-token.ts +2 -3
- package/src/modules/tool-manuals/index.ts +6 -0
- package/src/modules/tool-manuals/mcp-server-edit.service.ts +2 -2
- package/src/modules/tool-manuals/pending-tools.service.ts +2 -2
- package/src/modules/tool-manuals/tool-delete.service.ts +5 -6
- package/src/modules/tool-manuals/tool-manuals.routes.ts +5 -5
- package/src/modules/tool-manuals/tool-manuals.service.ts +3 -3
- package/src/modules/tool-manuals/tool-manuals.tools.ts +4 -6
- package/src/modules/tool-registry/__tests__/read-only-hints.test.ts +439 -0
- package/src/modules/tool-registry/__tests__/tool-registry.test.ts +9 -2
- package/src/modules/tool-registry/description-length.ts +2 -2
- package/src/modules/tool-registry/index.ts +22 -0
- package/src/modules/tool-registry/manual.routes.ts +14 -8
- package/src/modules/tool-registry/read-only-hints.contract.ts +54 -0
- package/src/modules/tool-registry/read-only-hints.ts +225 -0
- package/src/modules/tool-registry/tool.contract.ts +11 -0
- package/src/modules/update-check/update-check.routes.ts +2 -2
- package/src/modules/workflow/__tests__/change-request-hooks.test.ts +62 -0
- package/src/modules/workflow/__tests__/event-bus.test.ts +14 -2
- package/src/modules/workflow/__tests__/events-delivery.test.ts +778 -0
- package/src/modules/workflow/__tests__/workflow.routes.open-change-request.test.ts +79 -0
- package/src/modules/workflow/__tests__/workflow.service.delete-branch.test.ts +9 -1
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +342 -22
- package/src/modules/workflow/__tests__/workflow.service.update-change-request.pg.test.ts +120 -0
- package/src/modules/workflow/__tests__/workflow.service.update-change-request.test.ts +346 -0
- package/src/modules/workflow/agent-tools/__tests__/change-request-read-shape.test.ts +32 -209
- package/src/modules/workflow/agent-tools/__tests__/change-request-read.tools.test.ts +16 -245
- package/src/modules/workflow/agent-tools/__tests__/update-change-request.parity.test.ts +306 -0
- package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +43 -57
- package/src/modules/workflow/agent-tools/change-request-read-shape.ts +18 -153
- package/src/modules/workflow/agent-tools/change-request-read.tools.ts +24 -96
- package/src/modules/workflow/agent-tools/change-request-summary.ts +26 -3
- package/src/modules/workflow/agent-tools/workflow.tools.ts +55 -75
- package/src/modules/workflow/change-request-hooks.ts +96 -0
- package/src/modules/workflow/event-bus.ts +3 -1
- package/src/modules/workflow/events-delivery.ts +278 -0
- package/src/modules/workflow/events.routes.ts +30 -9
- package/src/modules/workflow/file-lock.service.ts +2 -2
- package/src/modules/workflow/git/__tests__/pull-request.service.getPrDetail.test.ts +24 -9
- package/src/modules/workflow/git/git.service.ts +5 -8
- package/src/modules/workflow/git/node-git-runner.ts +1 -1
- package/src/modules/workflow/git/pull-request.service.ts +44 -29
- package/src/modules/workflow/index.ts +15 -2
- package/src/modules/workflow/pending-commits.service.ts +2 -2
- package/src/modules/workflow/read-on-branch.ts +1 -1
- package/src/modules/workflow/recovery-bot.ts +2 -2
- package/src/modules/workflow/review-workflow/approval-lock.ts +1 -1
- package/src/modules/workflow/review-workflow/review-workflow.interface.ts +3 -35
- package/src/modules/workflow/review-workflow/review-workflow.service.ts +6 -165
- package/src/modules/workflow/workflow.routes.ts +46 -100
- package/src/modules/workflow/workflow.service.ts +444 -215
- package/src/modules/workspace/__tests__/agent-downloads.test.ts +2 -1
- package/src/modules/workspace/__tests__/agent-uploads.test.ts +87 -1
- package/src/modules/workspace/__tests__/escape-sequences.routes.test.ts +2 -1
- package/src/modules/workspace/__tests__/file-stat-access.test.ts +2 -1
- package/src/modules/workspace/__tests__/git-internals.security.test.ts +2 -1
- package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +2 -1
- package/src/modules/workspace/__tests__/worker-pool.test.ts +118 -0
- package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +3 -2
- package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +30 -0
- package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +30 -4
- package/src/modules/workspace/agent-access.gate.ts +3 -3
- package/src/modules/workspace/agent-download.builder.ts +1 -1
- package/src/modules/workspace/agent-upload.routes.ts +19 -0
- package/src/modules/workspace/agent-upload.store.ts +18 -0
- package/src/modules/workspace/bounded-matcher.ts +32 -89
- package/src/modules/workspace/file-readers/README.md +9 -0
- package/src/modules/workspace/file-readers/__tests__/doc-extract.service.test.ts +165 -0
- package/src/modules/workspace/file-readers/__tests__/doc-extract.test.ts +21 -16
- package/src/modules/workspace/file-readers/__tests__/extract-in-worker.test.ts +229 -0
- package/src/modules/workspace/file-readers/__tests__/file-reader.registry.test.ts +2 -1
- package/src/modules/workspace/file-readers/__tests__/fixtures/damaged-pdf.ts +34 -0
- package/src/modules/workspace/file-readers/__tests__/fixtures/misbehaving-extract.worker.ts +57 -0
- package/src/modules/workspace/file-readers/__tests__/fixtures/pdf-in-trouble.worker.ts +20 -0
- package/src/modules/workspace/file-readers/__tests__/fixtures/unloadable-extract.worker.ts +2 -0
- package/src/modules/workspace/file-readers/doc-extract.service.ts +95 -20
- package/src/modules/workspace/file-readers/doc-extract.types.ts +13 -3
- package/src/modules/workspace/file-readers/document-extractor.contract.ts +42 -0
- package/src/modules/workspace/file-readers/document-extractors.ts +28 -0
- package/src/modules/workspace/file-readers/document-formats.ts +13 -0
- package/src/modules/workspace/file-readers/document-reader.ts +40 -36
- package/src/modules/workspace/file-readers/extract-in-worker.ts +183 -0
- package/src/modules/workspace/file-readers/extract-pdf.ts +23 -4
- package/src/modules/workspace/file-readers/extract.worker.ts +5 -0
- package/src/modules/workspace/file-readers/extraction-cache.ts +33 -12
- package/src/modules/workspace/file-readers/extraction-worker.ts +86 -0
- package/src/modules/workspace/file-readers/file-reader.registry.ts +6 -20
- package/src/modules/workspace/file-readers/file-reader.ts +14 -4
- package/src/modules/workspace/first-run.ts +1 -1
- package/src/modules/workspace/git-internals.middleware.ts +1 -1
- package/src/modules/workspace/index.ts +17 -0
- package/src/modules/workspace/kb-repository.ts +3 -2
- package/src/modules/workspace/not-found.ts +1 -1
- package/src/modules/workspace/pattern-matcher.contract.ts +1 -1
- package/src/modules/workspace/routine-write-policy.ts +1 -1
- package/src/modules/workspace/startup/kb-git.ts +1 -1
- package/src/modules/workspace/startup/kb-startup-runner.ts +1 -2
- package/src/modules/workspace/startup/steps/groups-to-plugins.step.ts +3 -3
- package/src/modules/workspace/startup/steps/personal-spaces.step.ts +2 -2
- package/src/modules/workspace/startup/steps/plugin-layout.ts +1 -1
- package/src/modules/workspace/startup/steps/roles-yaml.step.ts +1 -1
- package/src/modules/workspace/startup/steps/seed-tree.ts +2 -2
- package/src/modules/workspace/startup/steps/template-files.step.ts +2 -2
- package/src/modules/workspace/startup/steps/template-source.ts +2 -2
- package/src/modules/workspace/worker-pool.ts +193 -0
- package/src/modules/workspace/workspace.routes.ts +9 -12
- package/src/modules/workspace/workspace.service.ts +4 -7
- package/src/modules/workspace/workspace.tools.ts +53 -34
- package/src/modules/workspace/write-denial.ts +4 -5
- package/src/modules/write-access/index.ts +7 -0
- package/src/shared/__tests__/module-boundaries.lint.test.ts +301 -0
- package/src/shared/listener-seam.ts +52 -0
- package/src/modules/workflow/__tests__/format-affected-owners.test.ts +0 -85
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
3
|
+
import { extractionTimeoutNotice } from '../document-extractor.contract.js';
|
|
4
|
+
import { extractDocx } from '../extract-docx.js';
|
|
5
|
+
import { EXTRACTION_BUDGET_MS, EXTRACTION_WORKER_FAILED, WorkerDocumentExtractor, type ExtractionWorkerEntry } from '../extract-in-worker.js';
|
|
6
|
+
import { extractPdf } from '../extract-pdf.js';
|
|
7
|
+
import { xrefPdf } from './fixtures/damaged-pdf.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The extraction worker kind: every document's extractor runs in a pooled
|
|
11
|
+
* worker thread under a budget, and nothing a parser does — an error, a
|
|
12
|
+
* rejection it never hands back, a loop, a crash — reaches this process.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** A worker module from this suite's fixtures, loaded as the suites are (TypeScript, through tsx). */
|
|
16
|
+
function fixtureEntry(name: string): ExtractionWorkerEntry {
|
|
17
|
+
return { url: new URL(`./fixtures/${name}`, import.meta.url), execArgv: ['--import', 'tsx'] };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Every unhandled rejection and uncaught exception THIS process sees while a test runs. */
|
|
21
|
+
let processSaw: unknown[] = [];
|
|
22
|
+
const onRejection = (reason: unknown) => processSaw.push(reason);
|
|
23
|
+
const onException = (err: unknown) => processSaw.push(err);
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
processSaw = [];
|
|
26
|
+
process.on('unhandledRejection', onRejection);
|
|
27
|
+
process.on('uncaughtException', onException);
|
|
28
|
+
});
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
process.off('unhandledRejection', onRejection);
|
|
31
|
+
process.off('uncaughtException', onException);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('WorkerDocumentExtractor — the real document extractors', () => {
|
|
35
|
+
let extractor: WorkerDocumentExtractor;
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
extractor = new WorkerDocumentExtractor();
|
|
38
|
+
});
|
|
39
|
+
afterEach(() => extractor.close());
|
|
40
|
+
|
|
41
|
+
it('budgets ten seconds per file by default, and words a timeout as the ticket does', () => {
|
|
42
|
+
expect(EXTRACTION_BUDGET_MS).toBe(10_000);
|
|
43
|
+
expect(extractionTimeoutNotice(EXTRACTION_BUDGET_MS)).toBe(
|
|
44
|
+
'could not be read: extracting its text took longer than 10 seconds',
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('answers a PDF with a damaged cross-reference table with pdf.js’s own message, as a parser failure', async () => {
|
|
49
|
+
const res = await extractor.extract('.pdf', xrefPdf('Hello', { damage: true }));
|
|
50
|
+
expect(res).toEqual({
|
|
51
|
+
ok: false,
|
|
52
|
+
failure: 'parser',
|
|
53
|
+
message: "could not extract the PDF's text (Bad (uncompressed) XRef entry: 4R)",
|
|
54
|
+
});
|
|
55
|
+
// Long enough for any rejection pdf.js left behind to have surfaced.
|
|
56
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
57
|
+
expect(processSaw).toEqual([]);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('extracts a sound document exactly as the extractor does on its own — same text, same summary', async () => {
|
|
61
|
+
const pdf = xrefPdf('Hello PDF world', { damage: false });
|
|
62
|
+
const docx = await readFile(new URL('./fixtures/tab.docx', import.meta.url));
|
|
63
|
+
const inProcess = [await extractPdf(pdf), await extractDocx(docx)];
|
|
64
|
+
const inWorker = [await extractor.extract('.pdf', pdf), await extractor.extract('.docx', docx)];
|
|
65
|
+
expect(inWorker).toEqual(inProcess);
|
|
66
|
+
expect(inWorker[0]).toMatchObject({ ok: true, text: '[page 1]\nHello PDF world' });
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('leaves the caller’s buffer as it was — the worker gets a copy', async () => {
|
|
70
|
+
const pdf = xrefPdf('Keep me', { damage: false });
|
|
71
|
+
const before = Buffer.from(pdf);
|
|
72
|
+
await extractor.extract('.pdf', pdf);
|
|
73
|
+
expect(pdf.byteLength).toBe(before.byteLength);
|
|
74
|
+
expect(pdf.equals(before)).toBe(true);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('WorkerDocumentExtractor — a parser that misbehaves', () => {
|
|
79
|
+
let extractor: WorkerDocumentExtractor;
|
|
80
|
+
afterEach(() => extractor.close());
|
|
81
|
+
|
|
82
|
+
it('turns a rejection the parser never hands back into the job’s failure — this process sees none', async () => {
|
|
83
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts') });
|
|
84
|
+
const res = await extractor.extract('.dangling', Buffer.from('x'));
|
|
85
|
+
expect(res).toEqual({
|
|
86
|
+
ok: false,
|
|
87
|
+
failure: 'parser',
|
|
88
|
+
message: 'could not be extracted (XRefEntryException: Bad (uncompressed) XRef entry)',
|
|
89
|
+
});
|
|
90
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
91
|
+
expect(processSaw).toEqual([]);
|
|
92
|
+
// The worker it happened in is retired; the next job gets a sound one.
|
|
93
|
+
expect(await extractor.extract('.echo', Buffer.from('after'))).toMatchObject({ ok: true, text: 'after' });
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('keeps a rejection left behind AFTER an answer out of this process and out of the next job', async () => {
|
|
97
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts'), poolMax: 1 });
|
|
98
|
+
expect(await extractor.extract('.straggler', Buffer.from('x'))).toMatchObject({ ok: true, text: 'answered first' });
|
|
99
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
100
|
+
expect(await extractor.extract('.echo', Buffer.from('next'))).toMatchObject({ ok: true, text: 'next' });
|
|
101
|
+
expect(processSaw).toEqual([]);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('never pins an earlier job’s late rejection on the job the worker runs next — reused at once', async () => {
|
|
105
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts'), poolMax: 1 });
|
|
106
|
+
expect(await extractor.extract('.straggler', Buffer.from('x'))).toMatchObject({ ok: true, text: 'answered first' });
|
|
107
|
+
// No pause: the one worker gets this job straight away, and the straggler lands while it runs.
|
|
108
|
+
expect(await extractor.extract('.slow-echo', Buffer.from('mine'))).toEqual({ ok: true, summary: 'echo', text: 'mine' });
|
|
109
|
+
expect(processSaw).toEqual([]);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('never answers the next job as crashed when the worker ends itself over a straggler between jobs', async () => {
|
|
113
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts'), poolMax: 1 });
|
|
114
|
+
expect(await extractor.extract('.straggler-between-jobs', Buffer.from('x'))).toMatchObject({ ok: true });
|
|
115
|
+
// The one worker is handed this job at once, and exits (code 0) before taking it up:
|
|
116
|
+
// the job runs again in a fresh worker and is answered as its own.
|
|
117
|
+
expect(await extractor.extract('.echo', Buffer.from('mine'))).toEqual({ ok: true, summary: 'echo', text: 'mine' });
|
|
118
|
+
expect(processSaw).toEqual([]);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('gives a job rerun over another file’s straggler the whole budget again, not what was left', async () => {
|
|
122
|
+
// Budget 1500 ms. The straggler lands 600 ms into the next job, which
|
|
123
|
+
// needs 1100 ms: the 900 ms the budget had left would not do, the whole
|
|
124
|
+
// budget does. A rerun on the leftover would time out a sound document
|
|
125
|
+
// and remember that timeout for an hour.
|
|
126
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts'), poolMax: 1, budgetMs: 1500 });
|
|
127
|
+
expect(await extractor.extract('.straggler-late', Buffer.from('x'))).toMatchObject({ ok: true, text: 'answered first' });
|
|
128
|
+
// No pause: the one worker gets this job straight away, and the straggler lands while it runs.
|
|
129
|
+
expect(await extractor.extract('.slow-echo-long', Buffer.from('mine'))).toEqual({ ok: true, summary: 'echo', text: 'mine' });
|
|
130
|
+
expect(processSaw).toEqual([]);
|
|
131
|
+
}, 10_000);
|
|
132
|
+
|
|
133
|
+
it('still pins a rejection on its own job when the worker had served another first', async () => {
|
|
134
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts'), poolMax: 1 });
|
|
135
|
+
expect(await extractor.extract('.echo', Buffer.from('warm'))).toMatchObject({ ok: true });
|
|
136
|
+
expect(await extractor.extract('.dangling', Buffer.from('x'))).toEqual({
|
|
137
|
+
ok: false,
|
|
138
|
+
failure: 'parser',
|
|
139
|
+
message: 'could not be extracted (XRefEntryException: Bad (uncompressed) XRef entry)',
|
|
140
|
+
});
|
|
141
|
+
expect(await extractor.extract('.echo', Buffer.from('after'))).toMatchObject({ ok: true, text: 'after' });
|
|
142
|
+
expect(processSaw).toEqual([]);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('answers a parser that throws with its message', async () => {
|
|
146
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts') });
|
|
147
|
+
expect(await extractor.extract('.throw', Buffer.from('x'))).toEqual({
|
|
148
|
+
ok: false,
|
|
149
|
+
failure: 'parser',
|
|
150
|
+
message: 'could not be extracted (boom)',
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('terminates a parser past its budget and answers the timeout notice — while this thread stays free', async () => {
|
|
155
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts'), budgetMs: 300 });
|
|
156
|
+
// Warm the worker so its start-up is not part of the budget measured below.
|
|
157
|
+
await extractor.extract('.echo', Buffer.from('warm'));
|
|
158
|
+
const started = Date.now();
|
|
159
|
+
let ticks = 0;
|
|
160
|
+
const ticker = setInterval(() => ticks++, 20);
|
|
161
|
+
const res = await extractor.extract('.hang', Buffer.from('x'));
|
|
162
|
+
clearInterval(ticker);
|
|
163
|
+
expect(res).toEqual({
|
|
164
|
+
ok: false,
|
|
165
|
+
failure: 'timeout',
|
|
166
|
+
message: 'could not be read: extracting its text took longer than 0.3 seconds',
|
|
167
|
+
});
|
|
168
|
+
expect(Date.now() - started).toBeLessThan(2_000);
|
|
169
|
+
// The loop ran on the worker's thread: this one kept turning the whole time.
|
|
170
|
+
expect(ticks).toBeGreaterThan(5);
|
|
171
|
+
expect(await extractor.extract('.echo', Buffer.from('again'))).toMatchObject({ ok: true, text: 'again' });
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('gives three documents at once a worker and a budget each', async () => {
|
|
175
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts'), budgetMs: 500 });
|
|
176
|
+
await Promise.all([1, 2, 3].map(() => extractor.extract('.echo', Buffer.from('warm'))));
|
|
177
|
+
const started = Date.now();
|
|
178
|
+
const results = await Promise.all([1, 2, 3].map(() => extractor.extract('.hang', Buffer.from('x'))));
|
|
179
|
+
expect(results.map((r) => !r.ok && r.failure)).toEqual(['timeout', 'timeout', 'timeout']);
|
|
180
|
+
// Side by side, not one after another: none waited a budget for a worker.
|
|
181
|
+
expect(Date.now() - started).toBeLessThan(1_000);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('answers a worker that dies under the job as crashed, and one that cannot load the same way', async () => {
|
|
185
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts') });
|
|
186
|
+
expect(await extractor.extract('.exit', Buffer.from('x'))).toEqual({
|
|
187
|
+
ok: false,
|
|
188
|
+
failure: 'crashed',
|
|
189
|
+
message: 'could not be read: its extraction stopped unexpectedly (exit code 3)',
|
|
190
|
+
});
|
|
191
|
+
await extractor.close();
|
|
192
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('unloadable-extract.worker.ts') });
|
|
193
|
+
const res = await extractor.extract('.pdf', Buffer.from('x'));
|
|
194
|
+
expect(res.ok).toBe(false);
|
|
195
|
+
expect(!res.ok && res.failure).toBe('crashed');
|
|
196
|
+
expect(!res.ok && res.message).toBe(EXTRACTION_WORKER_FAILED);
|
|
197
|
+
expect(processSaw).toEqual([]);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('answers a parser that did not load as crashed — remembered for the hour, not for good', async () => {
|
|
201
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts') });
|
|
202
|
+
expect(await extractor.extract('.transient', Buffer.from('x'))).toEqual({
|
|
203
|
+
ok: false,
|
|
204
|
+
failure: 'crashed',
|
|
205
|
+
message: 'could not be read: the PDF reader did not load on the server; try again later',
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('answers busy — nothing learned about the file — when every worker is taken and no one may wait', async () => {
|
|
210
|
+
extractor = new WorkerDocumentExtractor({
|
|
211
|
+
entry: fixtureEntry('misbehaving-extract.worker.ts'),
|
|
212
|
+
budgetMs: 500,
|
|
213
|
+
poolMax: 1,
|
|
214
|
+
maxWaiting: 0,
|
|
215
|
+
});
|
|
216
|
+
const hanging = extractor.extract('.hang', Buffer.from('x'));
|
|
217
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
218
|
+
expect(await extractor.extract('.echo', Buffer.from('y'))).toMatchObject({ ok: false, failure: 'busy' });
|
|
219
|
+
expect(await hanging).toMatchObject({ failure: 'timeout' });
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('answers busy for an extraction running when the graph stops', async () => {
|
|
223
|
+
extractor = new WorkerDocumentExtractor({ entry: fixtureEntry('misbehaving-extract.worker.ts'), budgetMs: 5_000 });
|
|
224
|
+
const hanging = extractor.extract('.hang', Buffer.from('x'));
|
|
225
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
226
|
+
await extractor.close();
|
|
227
|
+
expect(await hanging).toMatchObject({ ok: false, failure: 'busy' });
|
|
228
|
+
});
|
|
229
|
+
});
|
|
@@ -2,6 +2,7 @@ import { tmpdir } from 'node:os';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { describe, expect, it } from 'vitest';
|
|
4
4
|
import { DocExtractService } from '../doc-extract.service.js';
|
|
5
|
+
import { WorkerDocumentExtractor } from '../extract-in-worker.js';
|
|
5
6
|
import { DocumentReader } from '../document-reader.js';
|
|
6
7
|
import { EmailReader } from '../email-reader.js';
|
|
7
8
|
import { FileReaderRegistry, type FileReader, type ReadResult } from '../file-reader.js';
|
|
@@ -21,7 +22,7 @@ import { accessFrontmatterExtensionList } from '../../../access-model/access-gra
|
|
|
21
22
|
*/
|
|
22
23
|
|
|
23
24
|
const registry = createFileReaderRegistry(
|
|
24
|
-
new DocExtractService(join(tmpdir(), 'bevel-test-file-reader-registry')),
|
|
25
|
+
new DocExtractService(join(tmpdir(), 'bevel-test-file-reader-registry'), new WorkerDocumentExtractor()),
|
|
25
26
|
);
|
|
26
27
|
|
|
27
28
|
describe('file-reader registry routing', () => {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A SYNTHETIC PDF whose cross-reference table is damaged — never a tenant's
|
|
3
|
+
* file. One page, one content stream; the xref entry for the content stream
|
|
4
|
+
* (object 4) points two bytes past where the object starts, and the object's
|
|
5
|
+
* own header is defaced so pdf.js's recovery scan cannot find it either.
|
|
6
|
+
* pdf.js answers it with the exception of the 2026-10-15 incident:
|
|
7
|
+
* `Bad (uncompressed) XRef entry: 4R`.
|
|
8
|
+
*
|
|
9
|
+
* `damage: false` builds the same file intact, which reads as `text`.
|
|
10
|
+
*/
|
|
11
|
+
export function xrefPdf(text: string, { damage }: { damage: boolean }): Buffer {
|
|
12
|
+
const stream = `BT /F1 12 Tf 72 720 Td (${text}) Tj ET`;
|
|
13
|
+
const objects = [
|
|
14
|
+
'<< /Type /Catalog /Pages 2 0 R >>',
|
|
15
|
+
'<< /Type /Pages /Kids [3 0 R] /Count 1 >>',
|
|
16
|
+
'<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >>',
|
|
17
|
+
`<< /Length ${stream.length} >>\nstream\n${stream}\nendstream`,
|
|
18
|
+
'<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>',
|
|
19
|
+
];
|
|
20
|
+
let pdf = '%PDF-1.4\n';
|
|
21
|
+
const offsets: number[] = [];
|
|
22
|
+
for (let i = 0; i < objects.length; i++) {
|
|
23
|
+
offsets.push(pdf.length);
|
|
24
|
+
const header = damage && i === 3 ? `${i + 1} 0 xbj` : `${i + 1} 0 obj`;
|
|
25
|
+
pdf += `${header}\n${objects[i]}\nendobj\n`;
|
|
26
|
+
}
|
|
27
|
+
const xrefStart = pdf.length;
|
|
28
|
+
pdf += `xref\n0 ${objects.length + 1}\n0000000000 65535 f \n`;
|
|
29
|
+
offsets.forEach((off, i) => {
|
|
30
|
+
pdf += `${String(damage && i === 3 ? off + 2 : off).padStart(10, '0')} 00000 n \n`;
|
|
31
|
+
});
|
|
32
|
+
pdf += `trailer\n<< /Size ${objects.length + 1} /Root 1 0 R >>\nstartxref\n${xrefStart}\n%%EOF\n`;
|
|
33
|
+
return Buffer.from(pdf, 'latin1');
|
|
34
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { serveExtractions } from '../../extraction-worker.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An extraction worker serving parsers that misbehave in each of the ways a
|
|
5
|
+
* real one can, by extension — for `extract-in-worker.test.ts`.
|
|
6
|
+
*/
|
|
7
|
+
serveExtractions({
|
|
8
|
+
// The incident's shape: a rejection nothing awaits, and a promise that never settles.
|
|
9
|
+
'.dangling': () => {
|
|
10
|
+
void Promise.reject(new Error('XRefEntryException: Bad (uncompressed) XRef entry'));
|
|
11
|
+
return new Promise(() => {});
|
|
12
|
+
},
|
|
13
|
+
// Answers, then leaves a rejection behind after the answer.
|
|
14
|
+
'.straggler': () => {
|
|
15
|
+
setTimeout(() => void Promise.reject(new Error('late')), 20);
|
|
16
|
+
return { ok: true, summary: 'straggler', text: 'answered first' };
|
|
17
|
+
},
|
|
18
|
+
// Answers, then — once the host has had time to hand the worker its next
|
|
19
|
+
// job — leaves a rejection behind before that job's message is taken up:
|
|
20
|
+
// the worker sees it BETWEEN jobs, and ends itself.
|
|
21
|
+
'.straggler-between-jobs': () => {
|
|
22
|
+
setImmediate(() => {
|
|
23
|
+
const until = Date.now() + 200;
|
|
24
|
+
while (Date.now() < until) {
|
|
25
|
+
/* the host answers, releases this worker and posts the next job meanwhile */
|
|
26
|
+
}
|
|
27
|
+
void Promise.reject(new Error('late, between jobs'));
|
|
28
|
+
});
|
|
29
|
+
return { ok: true, summary: 'straggler', text: 'answered first' };
|
|
30
|
+
},
|
|
31
|
+
'.throw': () => {
|
|
32
|
+
throw new Error('boom');
|
|
33
|
+
},
|
|
34
|
+
// Spins on the worker's thread: only terminating the worker stops it.
|
|
35
|
+
'.hang': () => {
|
|
36
|
+
for (;;) {
|
|
37
|
+
/* a parser in a loop */
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
// The parser itself did not load: the reader's fault, not the file's.
|
|
41
|
+
'.transient': () => ({ ok: false, transient: true, message: 'could not be read: the PDF reader did not load on the server; try again later' }),
|
|
42
|
+
'.exit': () => process.exit(3),
|
|
43
|
+
'.echo': (bytes) => ({ ok: true, summary: 'echo', text: bytes.toString('utf8') }),
|
|
44
|
+
// Answers after a while: long enough for an earlier job's straggler to land during it.
|
|
45
|
+
'.slow-echo': (bytes) =>
|
|
46
|
+
new Promise((resolve) => setTimeout(() => resolve({ ok: true, summary: 'echo', text: bytes.toString('utf8') }), 150)),
|
|
47
|
+
// Answers, then leaves a rejection behind well into the next job — late
|
|
48
|
+
// enough that the budget the next job has left is less than that job needs.
|
|
49
|
+
'.straggler-late': () => {
|
|
50
|
+
setTimeout(() => void Promise.reject(new Error('late')), 600);
|
|
51
|
+
return { ok: true, summary: 'straggler', text: 'answered first' };
|
|
52
|
+
},
|
|
53
|
+
// A sound document that takes most of a budget: more than what is left
|
|
54
|
+
// after `.straggler-late` lands, less than the budget whole.
|
|
55
|
+
'.slow-echo-long': (bytes) =>
|
|
56
|
+
new Promise((resolve) => setTimeout(() => resolve({ ok: true, summary: 'echo', text: bytes.toString('utf8') }), 1100)),
|
|
57
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { extractPdf } from '../../extract-pdf.js';
|
|
2
|
+
import { serveExtractions } from '../../extraction-worker.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The real PDF extractor, except for a PDF whose bytes say otherwise: `HANG`
|
|
6
|
+
* spins forever, `SLOW` spins for 1.5 s before extracting — both on the
|
|
7
|
+
* worker's thread, as a parser stuck on crafted input would. For the tool
|
|
8
|
+
* suites that time `/api/health` while a document is being extracted.
|
|
9
|
+
*/
|
|
10
|
+
serveExtractions({
|
|
11
|
+
'.pdf': (bytes) => {
|
|
12
|
+
const text = bytes.toString('latin1');
|
|
13
|
+
if (text.includes('HANG')) for (;;) { /* stuck */ }
|
|
14
|
+
if (text.includes('SLOW')) {
|
|
15
|
+
const until = Date.now() + 1_500;
|
|
16
|
+
while (Date.now() < until) { /* busy */ }
|
|
17
|
+
}
|
|
18
|
+
return extractPdf(bytes);
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { IDocumentExtractor, IsolatedExtraction } from './document-extractor.contract.js';
|
|
2
|
+
import { extractionMarker, fileExtension } from './doc-extract.types.js';
|
|
2
3
|
import { DocExtractionCache, gitBlobSha } from './extraction-cache.js';
|
|
4
|
+
import type { ReadOrigin } from './file-reader.js';
|
|
3
5
|
|
|
4
6
|
/** An extraction ready for a consumer: the honest marker header + the text. */
|
|
5
7
|
export interface DocExtraction {
|
|
@@ -13,6 +15,34 @@ export type DocExtractOutcome =
|
|
|
13
15
|
| ({ ok: true } & DocExtraction)
|
|
14
16
|
| { ok: false; message: string };
|
|
15
17
|
|
|
18
|
+
/** A document whose extraction just failed, as the people looking at it are told. */
|
|
19
|
+
export interface UnreadableDocument {
|
|
20
|
+
workspaceId: string;
|
|
21
|
+
path: string;
|
|
22
|
+
/** What went wrong, worded to follow "Could not be read:". */
|
|
23
|
+
reason: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface DocExtractServiceOptions {
|
|
27
|
+
/** The clock a remembered timeout is judged by (epoch ms). Default `Date.now`. */
|
|
28
|
+
now?: () => number;
|
|
29
|
+
/**
|
|
30
|
+
* Told once per FRESH failure of an extraction a read with an origin
|
|
31
|
+
* started — never for a failure answered from memory. The composition root
|
|
32
|
+
* turns it into the `document-unreadable` event.
|
|
33
|
+
*/
|
|
34
|
+
onUnreadable?: (doc: UnreadableDocument) => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* How long an extraction stopped over its budget, or whose worker died under
|
|
39
|
+
* it, is remembered: an overrun is a property of the moment (a busy server, a
|
|
40
|
+
* large file), not of the bytes, so it is tried again after this. A parser's
|
|
41
|
+
* refusal is a property of the bytes and is remembered like a success
|
|
42
|
+
* (decided 2026-10-15/19).
|
|
43
|
+
*/
|
|
44
|
+
export const TIMEOUT_MEMORY_MS = 60 * 60 * 1000;
|
|
45
|
+
|
|
16
46
|
/**
|
|
17
47
|
* The content-hash CACHE wrap around document text extraction. The per-format
|
|
18
48
|
* `DocumentReader`s in the file-reader registry stay pure (each pairs one
|
|
@@ -28,7 +58,15 @@ export type DocExtractOutcome =
|
|
|
28
58
|
* extract DIFFERENTLY per format: a `.odt` renamed `.ods` must run the ods
|
|
29
59
|
* extractor, not return the odt extraction. Extraction is deterministic
|
|
30
60
|
* (stable slide/sheet/page ordering), which is what makes a content-keyed
|
|
31
|
-
* cache correct.
|
|
61
|
+
* cache correct.
|
|
62
|
+
*
|
|
63
|
+
* Extraction itself runs in a worker, under a budget (`IDocumentExtractor`),
|
|
64
|
+
* and its FAILURES are remembered under the same key: a parser's refusal for
|
|
65
|
+
* good, so damaged bytes cost the server once for as long as the entry is
|
|
66
|
+
* kept (the cache evicts by size, as it does successes), and a timeout or a
|
|
67
|
+
* crash for {@link TIMEOUT_MEMORY_MS}. A re-saved file is new content and is
|
|
68
|
+
* extracted again. Only "no worker was free" is not remembered: it says
|
|
69
|
+
* nothing about the file. The key also carries
|
|
32
70
|
* `EXTRACTION_SCHEMA`, so an upgrade that changes what an extractor emits does
|
|
33
71
|
* not keep serving the previous release's text for unchanged bytes.
|
|
34
72
|
*/
|
|
@@ -53,55 +91,92 @@ export const EXTRACTION_SCHEMA = 'v3';
|
|
|
53
91
|
|
|
54
92
|
export class DocExtractService {
|
|
55
93
|
private readonly cache: DocExtractionCache;
|
|
94
|
+
private readonly now: () => number;
|
|
95
|
+
private readonly onUnreadable: ((doc: UnreadableDocument) => void) | undefined;
|
|
56
96
|
/**
|
|
57
97
|
* Cold extractions currently running, by cache key. Two reads of the same
|
|
58
98
|
* document arriving together would otherwise BOTH parse it — the expensive
|
|
59
99
|
* half of this service, run twice for one answer — because neither had
|
|
60
100
|
* written the cache entry yet when the other looked.
|
|
61
101
|
*/
|
|
62
|
-
private readonly inFlight = new Map<string, Promise<
|
|
102
|
+
private readonly inFlight = new Map<string, Promise<IsolatedExtraction>>();
|
|
63
103
|
|
|
64
|
-
constructor(
|
|
104
|
+
constructor(
|
|
105
|
+
cacheRoot: string,
|
|
106
|
+
private readonly extractor: IDocumentExtractor,
|
|
107
|
+
opts: DocExtractServiceOptions = {},
|
|
108
|
+
) {
|
|
65
109
|
this.cache = new DocExtractionCache(cacheRoot);
|
|
110
|
+
this.now = opts.now ?? Date.now;
|
|
111
|
+
this.onUnreadable = opts.onUnreadable;
|
|
66
112
|
}
|
|
67
113
|
|
|
68
114
|
/**
|
|
69
|
-
*
|
|
70
|
-
* never extracts. `grep` uses this
|
|
71
|
-
* search already-extracted documents
|
|
72
|
-
*
|
|
115
|
+
* What the cache REMEMBERS for these bytes — the extraction, or the notice
|
|
116
|
+
* of a failed one — or undefined on a miss; never extracts. `grep` uses this
|
|
117
|
+
* (via `DocumentReader.cachedRead`) to search already-extracted documents
|
|
118
|
+
* for free, skip remembered failures for free, and apply its per-walk budget
|
|
119
|
+
* only to cold ones; `file_stat` uses it to report a remembered failure.
|
|
73
120
|
*/
|
|
74
|
-
async getCached(path: string, bytes: Buffer): Promise<
|
|
75
|
-
const hit = await this.cache.get(this.cacheKey(path, bytes));
|
|
76
|
-
|
|
121
|
+
async getCached(path: string, bytes: Buffer): Promise<DocExtractOutcome | undefined> {
|
|
122
|
+
const hit = await this.cache.get(this.cacheKey(path, bytes), this.now());
|
|
123
|
+
if (!hit) return undefined;
|
|
124
|
+
return hit.failed
|
|
125
|
+
? { ok: false, message: hit.message }
|
|
126
|
+
: { ok: true, marker: extractionMarker(path, hit.summary), text: hit.text };
|
|
77
127
|
}
|
|
78
128
|
|
|
79
|
-
/**
|
|
80
|
-
|
|
129
|
+
/**
|
|
130
|
+
* The extraction of `bytes` (remembered, or run in the extractor's worker
|
|
131
|
+
* and remembered). `path` supplies the marker AND the key's format part;
|
|
132
|
+
* `origin`, when given, is where a fresh failure is reported.
|
|
133
|
+
*/
|
|
134
|
+
async extract(path: string, bytes: Buffer, origin?: ReadOrigin): Promise<DocExtractOutcome> {
|
|
81
135
|
const key = this.cacheKey(path, bytes);
|
|
82
|
-
const
|
|
83
|
-
if (
|
|
136
|
+
const remembered = await this.getCached(path, bytes);
|
|
137
|
+
if (remembered) return remembered;
|
|
84
138
|
const running = this.inFlight.get(key);
|
|
85
139
|
const result = await (running ??
|
|
86
140
|
(() => {
|
|
87
141
|
// The cache write stays INSIDE the shared promise: were the entry
|
|
88
142
|
// dropped as soon as parsing settled, a read arriving during the
|
|
89
143
|
// write would miss both the cache and the in-flight map — and parse
|
|
90
|
-
// the same document again.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
144
|
+
// the same document again. The bytes are hashed (above) BEFORE the
|
|
145
|
+
// extractor takes its copy of them.
|
|
146
|
+
const started = (async (): Promise<IsolatedExtraction> => {
|
|
147
|
+
const res = await this.extractor.extract(fileExtension(path), bytes);
|
|
148
|
+
if (res.ok) {
|
|
149
|
+
await this.cache.put(key, { summary: res.summary, text: res.text });
|
|
150
|
+
} else if (res.failure !== 'busy') {
|
|
151
|
+
const until = res.failure === 'parser' ? undefined : this.now() + TIMEOUT_MEMORY_MS;
|
|
152
|
+
await this.cache.put(key, { failed: true, message: res.message, ...(until === undefined ? {} : { until }) });
|
|
153
|
+
if (origin) this.notifyUnreadable({ workspaceId: origin.workspaceId, path, reason: reasonOf(res.message) });
|
|
154
|
+
}
|
|
94
155
|
return res;
|
|
95
156
|
})().finally(() => this.inFlight.delete(key));
|
|
96
157
|
this.inFlight.set(key, started);
|
|
97
158
|
return started;
|
|
98
159
|
})());
|
|
99
|
-
if (!result.ok) return result;
|
|
160
|
+
if (!result.ok) return { ok: false, message: result.message };
|
|
100
161
|
return { ok: true, marker: extractionMarker(path, result.summary), text: result.text };
|
|
101
162
|
}
|
|
102
163
|
|
|
164
|
+
/** Best-effort, like every event: a listener that throws never fails the read. */
|
|
165
|
+
private notifyUnreadable(doc: UnreadableDocument): void {
|
|
166
|
+
try {
|
|
167
|
+
this.onUnreadable?.(doc);
|
|
168
|
+
} catch {
|
|
169
|
+
// the read still answers its notice
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
103
173
|
/** Content hash + lowercased extension — e.g. `…sha….odt` (see the class doc). */
|
|
104
174
|
private cacheKey(path: string, bytes: Buffer): string {
|
|
105
175
|
return `${gitBlobSha(bytes)}${fileExtension(path)}.${EXTRACTION_SCHEMA}`;
|
|
106
176
|
}
|
|
107
177
|
}
|
|
178
|
+
|
|
179
|
+
/** A failure's notice, worded to follow "Could not be read:" (the explorer's copy) without saying it twice. */
|
|
180
|
+
function reasonOf(message: string): string {
|
|
181
|
+
return message.replace(/^could not be read: /, '');
|
|
182
|
+
}
|
|
@@ -34,13 +34,23 @@ export interface ExtractedDoc {
|
|
|
34
34
|
*/
|
|
35
35
|
export type ExtractResult =
|
|
36
36
|
| ({ ok: true } & ExtractedDoc)
|
|
37
|
-
| {
|
|
37
|
+
| {
|
|
38
|
+
ok: false;
|
|
39
|
+
message: string;
|
|
40
|
+
/**
|
|
41
|
+
* Set when the failure is the reader's, not the file's — the parser
|
|
42
|
+
* itself did not load — so it is not remembered as the file's answer
|
|
43
|
+
* the way a refusal of its bytes is.
|
|
44
|
+
*/
|
|
45
|
+
transient?: true;
|
|
46
|
+
};
|
|
38
47
|
|
|
39
48
|
/**
|
|
40
49
|
* A format's PURE extract function — bytes in, `ExtractResult` out (async for
|
|
41
50
|
* pdf.js). One per supported format (extract-docx.ts and friends); each is
|
|
42
|
-
* paired with its extension
|
|
43
|
-
*
|
|
51
|
+
* paired with its extension in the extraction worker's table
|
|
52
|
+
* (`document-extractors.ts`), run there under a budget, and cache-wrapped by
|
|
53
|
+
* `DocExtractService`.
|
|
44
54
|
*/
|
|
45
55
|
export type ExtractFn = (bytes: Buffer) => ExtractResult | Promise<ExtractResult>;
|
|
46
56
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ExtractedDoc } from './doc-extract.types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The contract for running a document's extractor: what `DocExtractService`
|
|
5
|
+
* depends on, so it never holds a concrete engine. The one implementation is
|
|
6
|
+
* `WorkerDocumentExtractor` (`extract-in-worker.ts`), owned by the
|
|
7
|
+
* composition root and closed with the graph.
|
|
8
|
+
*
|
|
9
|
+
* A parser can hang on crafted input and can reject promises it never hands
|
|
10
|
+
* back, so an implementation must never run one on the request thread, must
|
|
11
|
+
* stop an extraction that outlives its budget, and must answer every failure
|
|
12
|
+
* — a parser error, a dangling rejection, a crash — as an outcome, never as a
|
|
13
|
+
* rejection of `extract` and never as an event on the server's process.
|
|
14
|
+
*/
|
|
15
|
+
export interface IDocumentExtractor {
|
|
16
|
+
/** Extract `bytes` as a file of `extension` (lowercased, with its dot). The caller's buffer is left as it was. */
|
|
17
|
+
extract(extension: string, bytes: Buffer): Promise<IsolatedExtraction>;
|
|
18
|
+
/** Ends the workers; an extraction after this is answered `busy`. */
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Why an extraction failed, which is what decides how long the failure is
|
|
24
|
+
* remembered (see `DocExtractService`):
|
|
25
|
+
* - `parser`: the parser refused the bytes, threw, or left a rejection behind
|
|
26
|
+
* it — a property of the content;
|
|
27
|
+
* - `timeout`: the extraction outlived its budget and was stopped;
|
|
28
|
+
* - `crashed`: the worker failed or died under the job without answering
|
|
29
|
+
* (out of memory, a script that would not load), or the parser itself did
|
|
30
|
+
* not load — a fault of the moment;
|
|
31
|
+
* - `busy`: no worker could take the job — nothing was learned about the file.
|
|
32
|
+
*/
|
|
33
|
+
export type ExtractionFailure = 'parser' | 'timeout' | 'crashed' | 'busy';
|
|
34
|
+
|
|
35
|
+
export type IsolatedExtraction =
|
|
36
|
+
| ({ ok: true } & ExtractedDoc)
|
|
37
|
+
| { ok: false; message: string; failure: ExtractionFailure };
|
|
38
|
+
|
|
39
|
+
/** The notice an extraction stopped over its budget answers with. */
|
|
40
|
+
export function extractionTimeoutNotice(budgetMs: number): string {
|
|
41
|
+
return `could not be read: extracting its text took longer than ${budgetMs / 1000} seconds`;
|
|
42
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DocumentExtension } from './document-formats.js';
|
|
2
|
+
import type { ExtractFn } from './doc-extract.types.js';
|
|
3
|
+
import { extractDocx } from './extract-docx.js';
|
|
4
|
+
import { extractEml } from './extract-eml.js';
|
|
5
|
+
import { extractMsg } from './extract-msg.js';
|
|
6
|
+
import { extractOdp } from './extract-odp.js';
|
|
7
|
+
import { extractOds } from './extract-ods.js';
|
|
8
|
+
import { extractOdt } from './extract-odt.js';
|
|
9
|
+
import { extractPdf } from './extract-pdf.js';
|
|
10
|
+
import { extractPptx } from './extract-pptx.js';
|
|
11
|
+
import { extractXlsx } from './extract-xlsx.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Which pure extract function owns which document format. Loaded by the
|
|
15
|
+
* extraction worker only (`extract.worker.ts`): no parser runs on the
|
|
16
|
+
* server's request thread.
|
|
17
|
+
*/
|
|
18
|
+
export const DOCUMENT_EXTRACTORS: Readonly<Record<DocumentExtension, ExtractFn>> = {
|
|
19
|
+
'.docx': extractDocx,
|
|
20
|
+
'.pptx': extractPptx,
|
|
21
|
+
'.xlsx': extractXlsx,
|
|
22
|
+
'.pdf': extractPdf,
|
|
23
|
+
'.odt': extractOdt,
|
|
24
|
+
'.odp': extractOdp,
|
|
25
|
+
'.ods': extractOds,
|
|
26
|
+
'.eml': extractEml,
|
|
27
|
+
'.msg': extractMsg,
|
|
28
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The document formats whose text is EXTRACTED rather than read: the one list
|
|
3
|
+
* both sides of the extraction worker agree on. The file-reader registry
|
|
4
|
+
* builds a reader for each, on the request thread, without loading a single
|
|
5
|
+
* parser; the worker's table (`document-extractors.ts`) is typed by these
|
|
6
|
+
* lists, so a format added here and not there fails to compile.
|
|
7
|
+
*/
|
|
8
|
+
export const OFFICE_DOCUMENT_EXTENSIONS = ['.docx', '.pptx', '.xlsx', '.pdf', '.odt', '.odp', '.ods'] as const;
|
|
9
|
+
|
|
10
|
+
/** Email files: extracted the same way, refused for writing with an email-honest message (see `EmailReader`). */
|
|
11
|
+
export const EMAIL_EXTENSIONS = ['.eml', '.msg'] as const;
|
|
12
|
+
|
|
13
|
+
export type DocumentExtension = (typeof OFFICE_DOCUMENT_EXTENSIONS)[number] | (typeof EMAIL_EXTENSIONS)[number];
|