@bevel-software/platform-core-backend 0.33.0 → 0.34.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 +19 -8
- package/agent-guide/html-views.md +231 -5
- package/agent-guide/tool-manuals.md +1 -1
- package/dist/core/catalog-revision.d.ts +12 -1
- package/dist/core/catalog-revision.d.ts.map +1 -1
- package/dist/core/catalog-revision.js +23 -3
- package/dist/core/catalog-revision.js.map +1 -1
- package/dist/core/core-ports.d.ts +41 -0
- package/dist/core/core-ports.d.ts.map +1 -1
- package/dist/core/core-ports.js.map +1 -1
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +14 -7
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +16 -5
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +37 -12
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core/lifecycle.d.ts +16 -0
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/core/lifecycle.js +12 -2
- package/dist/core/lifecycle.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +17 -9
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +12 -2
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +164 -75
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access-mutation.service.d.ts +22 -24
- package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
- package/dist/modules/access/access-mutation.service.js +48 -51
- package/dist/modules/access/access-mutation.service.js.map +1 -1
- package/dist/modules/access/access-view.d.ts.map +1 -1
- package/dist/modules/access/access-view.js +12 -11
- package/dist/modules/access/access-view.js.map +1 -1
- package/dist/modules/access/access.routes.d.ts +3 -0
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +35 -29
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access/groups-admin.routes.d.ts.map +1 -1
- package/dist/modules/access/groups-admin.routes.js +4 -2
- package/dist/modules/access/groups-admin.routes.js.map +1 -1
- package/dist/modules/access/groups-admin.service.d.ts +44 -13
- package/dist/modules/access/groups-admin.service.d.ts.map +1 -1
- package/dist/modules/access/groups-admin.service.js +80 -38
- package/dist/modules/access/groups-admin.service.js.map +1 -1
- package/dist/modules/access/groups-edit.d.ts +1 -1
- package/dist/modules/access/groups-edit.d.ts.map +1 -1
- package/dist/modules/access/groups-edit.js +1 -1
- package/dist/modules/access/groups-edit.js.map +1 -1
- package/dist/modules/access/reference-scan.d.ts +116 -24
- package/dist/modules/access/reference-scan.d.ts.map +1 -1
- package/dist/modules/access/reference-scan.js +305 -44
- package/dist/modules/access/reference-scan.js.map +1 -1
- package/dist/modules/access/roles-admin.service.d.ts +17 -8
- package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
- package/dist/modules/access/roles-admin.service.js +32 -23
- package/dist/modules/access/roles-admin.service.js.map +1 -1
- package/dist/modules/access-model/access-grammar.d.ts +35 -10
- package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
- package/dist/modules/access-model/access-grammar.js +60 -20
- package/dist/modules/access-model/access-grammar.js.map +1 -1
- package/dist/modules/access-model/access-splice.d.ts +22 -18
- package/dist/modules/access-model/access-splice.d.ts.map +1 -1
- package/dist/modules/access-model/access-splice.js +20 -14
- package/dist/modules/access-model/access-splice.js.map +1 -1
- package/dist/modules/access-model/group-files.d.ts +1 -0
- package/dist/modules/access-model/group-files.d.ts.map +1 -1
- package/dist/modules/access-model/group-files.js +5 -1
- package/dist/modules/access-model/group-files.js.map +1 -1
- package/dist/modules/agent-guide/agent-guide.tools.d.ts.map +1 -1
- package/dist/modules/agent-guide/agent-guide.tools.js +13 -3
- package/dist/modules/agent-guide/agent-guide.tools.js.map +1 -1
- package/dist/modules/agent-instructions/compose.d.ts +3 -1
- package/dist/modules/agent-instructions/compose.d.ts.map +1 -1
- package/dist/modules/agent-instructions/compose.js +3 -1
- package/dist/modules/agent-instructions/compose.js.map +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.d.ts +5 -1
- package/dist/modules/agent-instructions/shared-file-rules.d.ts.map +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.js +16 -1
- package/dist/modules/agent-instructions/shared-file-rules.js.map +1 -1
- package/dist/modules/agent-scope/agent-scope.contract.d.ts +67 -0
- package/dist/modules/agent-scope/agent-scope.contract.d.ts.map +1 -0
- package/dist/modules/agent-scope/agent-scope.contract.js +27 -0
- package/dist/modules/agent-scope/agent-scope.contract.js.map +1 -0
- package/dist/modules/agent-scope/connection-scope.d.ts +111 -0
- package/dist/modules/agent-scope/connection-scope.d.ts.map +1 -0
- package/dist/modules/agent-scope/connection-scope.js +165 -0
- package/dist/modules/agent-scope/connection-scope.js.map +1 -0
- package/dist/modules/agent-scope/index.d.ts +3 -0
- package/dist/modules/agent-scope/index.d.ts.map +1 -0
- package/dist/modules/agent-scope/index.js +3 -0
- package/dist/modules/agent-scope/index.js.map +1 -0
- package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
- package/dist/modules/audit/agent-audit.service.js +2 -0
- package/dist/modules/audit/agent-audit.service.js.map +1 -1
- package/dist/modules/audit/audit.contract.d.ts +6 -0
- package/dist/modules/audit/audit.contract.d.ts.map +1 -1
- package/dist/modules/audit/audit.contract.js.map +1 -1
- package/dist/modules/auth/account-admission.d.ts +12 -0
- package/dist/modules/auth/account-admission.d.ts.map +1 -1
- package/dist/modules/auth/account-admission.js +15 -0
- package/dist/modules/auth/account-admission.js.map +1 -1
- package/dist/modules/auth/auth.middleware.d.ts +27 -1
- package/dist/modules/auth/auth.middleware.d.ts.map +1 -1
- package/dist/modules/auth/auth.middleware.js +42 -4
- package/dist/modules/auth/auth.middleware.js.map +1 -1
- package/dist/modules/auth/auth.routes.d.ts +13 -9
- package/dist/modules/auth/auth.routes.d.ts.map +1 -1
- package/dist/modules/auth/auth.routes.js +35 -29
- package/dist/modules/auth/auth.routes.js.map +1 -1
- package/dist/modules/auth/auth.service.d.ts +55 -6
- package/dist/modules/auth/auth.service.d.ts.map +1 -1
- package/dist/modules/auth/auth.service.js +128 -34
- package/dist/modules/auth/auth.service.js.map +1 -1
- package/dist/modules/auth/index.d.ts +1 -1
- package/dist/modules/auth/index.d.ts.map +1 -1
- package/dist/modules/auth/index.js +1 -1
- package/dist/modules/auth/index.js.map +1 -1
- package/dist/modules/auth/oidc-auth-provider.d.ts.map +1 -1
- package/dist/modules/auth/oidc-auth-provider.js +2 -9
- package/dist/modules/auth/oidc-auth-provider.js.map +1 -1
- package/dist/modules/database/core-schema.d.ts +68 -0
- package/dist/modules/database/core-schema.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +33 -0
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/declared-variables/declared-variables.routes.d.ts +8 -1
- package/dist/modules/declared-variables/declared-variables.routes.d.ts.map +1 -1
- package/dist/modules/declared-variables/declared-variables.routes.js +13 -2
- package/dist/modules/declared-variables/declared-variables.routes.js.map +1 -1
- package/dist/modules/embed/embed.tools.d.ts.map +1 -1
- package/dist/modules/embed/embed.tools.js +5 -0
- package/dist/modules/embed/embed.tools.js.map +1 -1
- package/dist/modules/kb-fs/index.d.ts +2 -0
- package/dist/modules/kb-fs/index.d.ts.map +1 -1
- package/dist/modules/kb-fs/index.js +1 -0
- package/dist/modules/kb-fs/index.js.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.js +7 -1
- package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
- package/dist/modules/kb-fs/repo-path.d.ts +26 -6
- package/dist/modules/kb-fs/repo-path.d.ts.map +1 -1
- package/dist/modules/kb-fs/repo-path.js +22 -7
- package/dist/modules/kb-fs/repo-path.js.map +1 -1
- package/dist/modules/kb-fs/tmp-ref.d.ts +36 -0
- package/dist/modules/kb-fs/tmp-ref.d.ts.map +1 -0
- package/dist/modules/kb-fs/tmp-ref.js +76 -0
- package/dist/modules/kb-fs/tmp-ref.js.map +1 -0
- package/dist/modules/mcp/mcp-auth.middleware.d.ts +7 -0
- package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.js +14 -1
- package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
- package/dist/modules/mcp/mcp.routes.d.ts +7 -1
- package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.routes.js +39 -4
- package/dist/modules/mcp/mcp.routes.js.map +1 -1
- package/dist/modules/mcp/mcp.service.d.ts +11 -0
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.service.js +68 -13
- package/dist/modules/mcp/mcp.service.js.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts +24 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js +45 -10
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +9 -0
- package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.js +34 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -1
- package/dist/modules/plugins/index.d.ts +1 -1
- package/dist/modules/plugins/index.d.ts.map +1 -1
- package/dist/modules/plugins/index.js.map +1 -1
- package/dist/modules/plugins/plugin-links.d.ts +18 -2
- package/dist/modules/plugins/plugin-links.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-links.js.map +1 -1
- package/dist/modules/plugins/plugins.routes.d.ts +5 -1
- package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.js +32 -5
- package/dist/modules/plugins/plugins.routes.js.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts +9 -0
- package/dist/modules/secrets-vault/secrets-vault.routes.d.ts.map +1 -1
- package/dist/modules/secrets-vault/secrets-vault.routes.js +15 -3
- package/dist/modules/secrets-vault/secrets-vault.routes.js.map +1 -1
- package/dist/modules/skills/index.d.ts +3 -3
- package/dist/modules/skills/index.d.ts.map +1 -1
- package/dist/modules/skills/index.js +0 -2
- package/dist/modules/skills/index.js.map +1 -1
- package/dist/modules/skills/skills.contract.d.ts +16 -0
- package/dist/modules/skills/skills.contract.d.ts.map +1 -1
- package/dist/modules/skills/skills.service.d.ts.map +1 -1
- package/dist/modules/skills/skills.service.js +6 -1
- package/dist/modules/skills/skills.service.js.map +1 -1
- package/dist/modules/skills/skills.tools.d.ts.map +1 -1
- package/dist/modules/skills/skills.tools.js +24 -12
- package/dist/modules/skills/skills.tools.js.map +1 -1
- package/dist/modules/tool-auth/external-api-key.interface.d.ts +11 -0
- package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.interface.js.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.d.ts +1 -0
- package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.js +4 -1
- package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
- package/dist/modules/tool-auth/index.d.ts +1 -1
- package/dist/modules/tool-auth/index.d.ts.map +1 -1
- package/dist/modules/tool-auth/internal-token.service.d.ts +9 -0
- package/dist/modules/tool-auth/internal-token.service.d.ts.map +1 -1
- package/dist/modules/tool-auth/internal-token.service.js +1 -0
- package/dist/modules/tool-auth/internal-token.service.js.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts +27 -3
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.js +32 -6
- package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
- package/dist/modules/tool-helpers/tool-context.d.ts +7 -0
- package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-context.js +3 -0
- package/dist/modules/tool-helpers/tool-context.js.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.d.ts +15 -0
- package/dist/modules/tool-helpers/tool-handler.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.js +19 -0
- package/dist/modules/tool-helpers/tool-handler.js.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.d.ts +10 -0
- package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
- package/dist/modules/tool-helpers/validate-token.d.ts +3 -1
- 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 +3 -3
- package/dist/modules/tool-manuals/index.d.ts.map +1 -1
- package/dist/modules/tool-manuals/index.js +0 -2
- package/dist/modules/tool-manuals/index.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts +19 -6
- package/dist/modules/tool-manuals/tool-manuals.contract.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts +7 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.routes.js +41 -4
- package/dist/modules/tool-manuals/tool-manuals.routes.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts +13 -6
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.js +23 -15
- package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.tools.js +25 -10
- package/dist/modules/tool-manuals/tool-manuals.tools.js.map +1 -1
- package/dist/modules/tool-registry/manual.routes.d.ts +8 -1
- package/dist/modules/tool-registry/manual.routes.d.ts.map +1 -1
- package/dist/modules/tool-registry/manual.routes.js +27 -7
- package/dist/modules/tool-registry/manual.routes.js.map +1 -1
- package/dist/modules/tool-registry/tool.contract.d.ts +7 -0
- package/dist/modules/tool-registry/tool.contract.d.ts.map +1 -1
- package/dist/modules/tool-registry/tool.contract.js.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js +14 -9
- package/dist/modules/workflow/agent-tools/workflow.tools.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 +20 -35
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +2 -1
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +3 -0
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/file-readers/doc-extract.service.d.ts +28 -4
- package/dist/modules/workspace/file-readers/doc-extract.service.d.ts.map +1 -1
- package/dist/modules/workspace/file-readers/doc-extract.service.js +61 -40
- package/dist/modules/workspace/file-readers/doc-extract.service.js.map +1 -1
- package/dist/modules/workspace/index.d.ts +8 -0
- package/dist/modules/workspace/index.d.ts.map +1 -1
- package/dist/modules/workspace/index.js +8 -0
- package/dist/modules/workspace/index.js.map +1 -1
- package/dist/modules/workspace/nul-scan.d.ts +19 -0
- package/dist/modules/workspace/nul-scan.d.ts.map +1 -0
- package/dist/modules/workspace/nul-scan.js +55 -0
- package/dist/modules/workspace/nul-scan.js.map +1 -0
- package/dist/modules/workspace/pattern-matcher.contract.d.ts +110 -27
- package/dist/modules/workspace/pattern-matcher.contract.d.ts.map +1 -1
- package/dist/modules/workspace/pattern-matcher.contract.js +30 -13
- package/dist/modules/workspace/pattern-matcher.contract.js.map +1 -1
- package/dist/modules/workspace/ripgrep-search.d.ts +54 -0
- package/dist/modules/workspace/ripgrep-search.d.ts.map +1 -0
- package/dist/modules/workspace/ripgrep-search.js +657 -0
- package/dist/modules/workspace/ripgrep-search.js.map +1 -0
- package/dist/modules/workspace/ripgrep-version.d.ts +15 -0
- package/dist/modules/workspace/ripgrep-version.d.ts.map +1 -0
- package/dist/modules/workspace/ripgrep-version.js +31 -0
- package/dist/modules/workspace/ripgrep-version.js.map +1 -0
- package/dist/modules/workspace/startup/beside-checkout.d.ts +8 -5
- package/dist/modules/workspace/startup/beside-checkout.d.ts.map +1 -1
- package/dist/modules/workspace/startup/beside-checkout.js +14 -5
- package/dist/modules/workspace/startup/beside-checkout.js.map +1 -1
- package/dist/modules/workspace/worker-pool.d.ts +3 -4
- package/dist/modules/workspace/worker-pool.d.ts.map +1 -1
- package/dist/modules/workspace/worker-pool.js.map +1 -1
- package/dist/modules/workspace/workspace-tmp.d.ts +146 -0
- package/dist/modules/workspace/workspace-tmp.d.ts.map +1 -0
- package/dist/modules/workspace/workspace-tmp.js +435 -0
- package/dist/modules/workspace/workspace-tmp.js.map +1 -0
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +5 -26
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +47 -6
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +86 -6
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +460 -116
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/shared/path-order.d.ts +28 -8
- package/dist/shared/path-order.d.ts.map +1 -1
- package/dist/shared/path-order.js +37 -8
- package/dist/shared/path-order.js.map +1 -1
- package/migrations/0022_session_version.sql +6 -0
- package/migrations/0023_agent_path.sql +3 -0
- package/migrations/meta/0022_snapshot.json +2360 -0
- package/migrations/meta/0023_snapshot.json +2378 -0
- package/migrations/meta/_journal.json +14 -0
- package/package.json +3 -3
- package/src/__tests__/pg-scratch.test.ts +69 -0
- package/src/__tests__/pg-scratch.ts +31 -0
- package/src/__tests__/slow-ripgrep.ts +65 -0
- package/src/core/__tests__/boot-without-ripgrep.test.ts +34 -0
- package/src/core/__tests__/catalog-revision.test.ts +89 -0
- package/src/core/__tests__/damaged-document.tools.test.ts +2 -2
- package/src/core/__tests__/gated-boot.test.ts +8 -1
- package/src/core/__tests__/lifecycle.test.ts +46 -13
- package/src/core/catalog-revision.ts +24 -2
- package/src/core/core-ports.ts +42 -0
- package/src/core/create-core-server.ts +13 -0
- package/src/core/create-core-services.ts +49 -12
- package/src/core/lifecycle.ts +26 -2
- package/src/index.ts +1 -1
- package/src/modules/access/__tests__/access-control.admin-root-floor.test.ts +12 -0
- package/src/modules/access/__tests__/access-control.colliding-name-cases.test.ts +113 -0
- package/src/modules/access/__tests__/access-control.frontmatter-head.test.ts +117 -0
- package/src/modules/access/__tests__/access-control.group-named-admin.test.ts +122 -0
- package/src/modules/access/__tests__/access-control.preview-relocation.test.ts +50 -0
- package/src/modules/access/__tests__/access-declarations.test.ts +19 -0
- package/src/modules/access/__tests__/access-groups.test.ts +55 -22
- package/src/modules/access/__tests__/access-mutation.service.test.ts +85 -59
- package/src/modules/access/__tests__/access-restrict-here.test.ts +7 -5
- package/src/modules/access/__tests__/access.routes.admins.test.ts +1 -0
- package/src/modules/access/__tests__/access.routes.batch.test.ts +2 -0
- package/src/modules/access/__tests__/access.routes.folder-governs.test.ts +2 -0
- package/src/modules/access/__tests__/access.routes.group-grant.test.ts +50 -14
- package/src/modules/access/__tests__/access.routes.overrides.test.ts +2 -1
- package/src/modules/access/__tests__/access.routes.proposal-branch.test.ts +1 -0
- package/src/modules/access/__tests__/access.routes.prospective.test.ts +2 -0
- package/src/modules/access/__tests__/access.routes.revoke.test.ts +18 -13
- package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -0
- package/src/modules/access/__tests__/grant-sources.test.ts +20 -15
- package/src/modules/access/__tests__/groups-admin.routes.test.ts +61 -0
- package/src/modules/access/__tests__/groups-admin.service.test.ts +211 -18
- package/src/modules/access/__tests__/reference-scan.test.ts +366 -14
- package/src/modules/access/__tests__/roles-admin.security.test.ts +1 -1
- package/src/modules/access/__tests__/roles-admin.service.test.ts +43 -22
- package/src/modules/access/__tests__/roles-capabilities.test.ts +6 -2
- package/src/modules/access/__tests__/roles.routes.test.ts +1 -1
- package/src/modules/access/access-control.interface.ts +17 -10
- package/src/modules/access/access-control.service.ts +158 -72
- package/src/modules/access/access-mutation.service.ts +48 -53
- package/src/modules/access/access-view.ts +12 -10
- package/src/modules/access/access.routes.ts +43 -33
- package/src/modules/access/groups-admin.routes.ts +4 -2
- package/src/modules/access/groups-admin.service.ts +114 -44
- package/src/modules/access/groups-edit.ts +1 -1
- package/src/modules/access/reference-scan.ts +319 -46
- package/src/modules/access/roles-admin.service.ts +43 -26
- package/src/modules/access/synced-groups-writer.ts +1 -1
- package/src/modules/access-model/__tests__/access-grammar.test.ts +38 -1
- package/src/modules/access-model/__tests__/access-splice.test.ts +50 -8
- package/src/modules/access-model/access-grammar.ts +65 -20
- package/src/modules/access-model/access-splice.ts +31 -23
- package/src/modules/access-model/group-files.ts +5 -0
- package/src/modules/agent-guide/__tests__/agent-guide.test.ts +31 -0
- package/src/modules/agent-guide/agent-guide.tools.ts +13 -2
- package/src/modules/agent-instructions/__tests__/shared-file-rules.test.ts +1 -0
- package/src/modules/agent-instructions/compose.ts +3 -1
- package/src/modules/agent-instructions/shared-file-rules.ts +17 -1
- package/src/modules/agent-scope/__tests__/agent-surfaces.connect-as.test.ts +421 -0
- package/src/modules/agent-scope/__tests__/connection-scope.test.ts +46 -0
- package/src/modules/agent-scope/__tests__/in-memory-kb.ts +148 -0
- package/src/modules/agent-scope/agent-scope.contract.ts +83 -0
- package/src/modules/agent-scope/connection-scope.ts +199 -0
- package/src/modules/agent-scope/index.ts +15 -0
- package/src/modules/audit/agent-audit.service.ts +2 -0
- package/src/modules/audit/audit.contract.ts +6 -0
- package/src/modules/auth/__tests__/auth.middleware.test.ts +30 -2
- package/src/modules/auth/__tests__/auth.routes.test.ts +71 -5
- package/src/modules/auth/__tests__/auth.service.test.ts +90 -9
- package/src/modules/auth/__tests__/password-change-sessions.pg.test.ts +269 -0
- package/src/modules/auth/account-admission.ts +19 -0
- package/src/modules/auth/auth.middleware.ts +45 -4
- package/src/modules/auth/auth.routes.ts +46 -29
- package/src/modules/auth/auth.service.ts +135 -34
- package/src/modules/auth/index.ts +2 -0
- package/src/modules/auth/oidc-auth-provider.ts +2 -9
- package/src/modules/database/__tests__/session-version-migration.pg.test.ts +133 -0
- package/src/modules/database/core-schema.ts +33 -0
- package/src/modules/declared-variables/__tests__/declared-variables.route.test.ts +44 -1
- package/src/modules/declared-variables/declared-variables.routes.ts +12 -1
- package/src/modules/embed/__tests__/embed.tools.test.ts +12 -0
- package/src/modules/embed/embed.tools.ts +5 -0
- package/src/modules/kb-fs/__tests__/locking-filesystem.test.ts +25 -0
- package/src/modules/kb-fs/__tests__/repo-path.test.ts +53 -8
- package/src/modules/kb-fs/index.ts +2 -0
- package/src/modules/kb-fs/locking-filesystem.ts +7 -1
- package/src/modules/kb-fs/repo-path.ts +33 -7
- package/src/modules/kb-fs/tmp-ref.ts +81 -0
- package/src/modules/mcp/__tests__/connect-as.pg.test.ts +137 -0
- package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +29 -5
- package/src/modules/mcp/__tests__/mcp-routes-harness.ts +8 -0
- package/src/modules/mcp/__tests__/mcp.connect-as.test.ts +195 -0
- package/src/modules/mcp/__tests__/mcp.routes.connect-as.test.ts +192 -0
- package/src/modules/mcp/__tests__/oauth-consent.connect-as.test.ts +146 -0
- package/src/modules/mcp/mcp-auth.middleware.ts +19 -2
- package/src/modules/mcp/mcp.routes.ts +39 -3
- package/src/modules/mcp/mcp.service.ts +107 -17
- package/src/modules/mcp/oauth/bevel-oauth-provider.ts +46 -8
- package/src/modules/mcp/oauth/oauth-consent.routes.ts +41 -1
- package/src/modules/plugins/__tests__/plugins.tools.test.ts +38 -2
- package/src/modules/plugins/index.ts +1 -1
- package/src/modules/plugins/plugin-links.ts +19 -2
- package/src/modules/plugins/plugins.routes.ts +35 -4
- package/src/modules/secrets-vault/__tests__/connect-pending.route.test.ts +113 -0
- package/src/modules/secrets-vault/secrets-vault.routes.ts +23 -3
- package/src/modules/skills/__tests__/skills.service.test.ts +34 -0
- package/src/modules/skills/index.ts +7 -2
- package/src/modules/skills/skills.contract.ts +17 -0
- package/src/modules/skills/skills.service.ts +5 -1
- package/src/modules/skills/skills.tools.ts +44 -13
- package/src/modules/tool-auth/__tests__/external-api-key.service.test.ts +4 -0
- package/src/modules/tool-auth/external-api-key.interface.ts +11 -1
- package/src/modules/tool-auth/external-api-key.service.ts +5 -2
- package/src/modules/tool-auth/index.ts +1 -1
- package/src/modules/tool-auth/internal-token.service.ts +10 -0
- package/src/modules/tool-auth/tool-auth.middleware.ts +45 -3
- package/src/modules/tool-helpers/__tests__/can-write.tools.test.ts +3 -1
- package/src/modules/tool-helpers/tool-context.ts +10 -0
- package/src/modules/tool-helpers/tool-handler.ts +34 -0
- package/src/modules/tool-helpers/tool.contract.ts +10 -0
- package/src/modules/tool-helpers/validate-token.ts +4 -2
- package/src/modules/tool-manuals/__tests__/tool-manuals.archive.route.test.ts +80 -4
- package/src/modules/tool-manuals/__tests__/tool-manuals.service.test.ts +42 -0
- package/src/modules/tool-manuals/__tests__/tool-manuals.tools.test.ts +3 -3
- package/src/modules/tool-manuals/index.ts +6 -2
- package/src/modules/tool-manuals/tool-manuals.contract.ts +18 -6
- package/src/modules/tool-manuals/tool-manuals.routes.ts +40 -3
- package/src/modules/tool-manuals/tool-manuals.service.ts +31 -15
- package/src/modules/tool-manuals/tool-manuals.tools.ts +28 -11
- package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +2 -2
- package/src/modules/tool-registry/manual.routes.ts +26 -5
- package/src/modules/tool-registry/tool.contract.ts +7 -0
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +1 -1
- package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +1 -1
- package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +54 -3
- package/src/modules/workflow/agent-tools/workflow.tools.ts +14 -9
- package/src/modules/workflow/git/__tests__/git.service.list-branches.test.ts +130 -3
- package/src/modules/workflow/git/git.service.ts +29 -48
- package/src/modules/workflow/workflow.service.ts +5 -0
- package/src/modules/workspace/__tests__/git-internals.security.test.ts +2 -2
- package/src/modules/workspace/__tests__/holds-nul.test.ts +66 -0
- package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +3 -3
- package/src/modules/workspace/__tests__/ripgrep-search.test.ts +570 -0
- package/src/modules/workspace/__tests__/ripgrep-version.test.ts +29 -0
- package/src/modules/workspace/__tests__/workspace-tmp.tools.test.ts +928 -0
- package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +17 -37
- package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +20 -8
- package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +22 -10
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +393 -113
- package/src/modules/workspace/file-readers/__tests__/doc-extract.service.test.ts +10 -0
- package/src/modules/workspace/file-readers/doc-extract.service.ts +71 -38
- package/src/modules/workspace/index.ts +20 -0
- package/src/modules/workspace/nul-scan.ts +50 -0
- package/src/modules/workspace/pattern-matcher.contract.ts +123 -32
- package/src/modules/workspace/ripgrep-search.ts +715 -0
- package/src/modules/workspace/ripgrep-version.ts +35 -0
- package/src/modules/workspace/startup/__tests__/beside-checkout.test.ts +11 -0
- package/src/modules/workspace/startup/beside-checkout.ts +13 -5
- package/src/modules/workspace/worker-pool.ts +3 -4
- package/src/modules/workspace/workspace-tmp.ts +457 -0
- package/src/modules/workspace/workspace.routes.ts +6 -27
- package/src/modules/workspace/workspace.service.ts +92 -15
- package/src/modules/workspace/workspace.tools.ts +500 -155
- package/src/shared/path-order.ts +37 -8
- package/starter-packs/engineering/Plugins/engineering-starter/access.md +1 -1
- package/starter-packs/general/Plugins/general-starter/access.md +1 -1
- package/starter-packs/operations/Plugins/operations-starter/access.md +1 -1
- package/starter-packs/sales/Plugins/sales-starter/access.md +1 -1
- package/starter-packs/support/Plugins/support-starter/access.md +1 -1
- package/dist/modules/workspace/bounded-matcher.d.ts +0 -73
- package/dist/modules/workspace/bounded-matcher.d.ts.map +0 -1
- package/dist/modules/workspace/bounded-matcher.js +0 -200
- package/dist/modules/workspace/bounded-matcher.js.map +0 -1
- package/src/modules/workspace/__tests__/bounded-matcher.test.ts +0 -213
- package/src/modules/workspace/bounded-matcher.ts +0 -271
|
@@ -9,7 +9,7 @@ Access to any path — reading it as much as writing it — is governed by
|
|
|
9
9
|
role to a group* below). Role names are
|
|
10
10
|
case- and whitespace-insensitive (`Admin` = `admin` = `ADMIN`; `Product Team`
|
|
11
11
|
= `product team`). The reserved names `deny` and `everyone` cannot be used, and neither can
|
|
12
|
-
names starting with `role/` or `plugin/` — those spellings are tokens in
|
|
12
|
+
names starting with `role/`, `group/` or `plugin/` — those spellings are tokens in
|
|
13
13
|
access entries (below). One exception to the file's authority: the
|
|
14
14
|
**deployment admin** — the address the server configuration sets as
|
|
15
15
|
`ADMIN_EMAIL` — is **always an Admin**, whether or not `roles.yaml` lists
|
|
@@ -35,8 +35,11 @@ Access to any path — reading it as much as writing it — is governed by
|
|
|
35
35
|
denials (the lowercase word `deny`, a space, then the principal).
|
|
36
36
|
Capitalised forms like `Deny` are *not* triggers; they are treated as part
|
|
37
37
|
of a name.
|
|
38
|
-
- **Principals** are a role
|
|
39
|
-
`
|
|
38
|
+
- **Principals** are a role (`role/<Name>`, from `roles.yaml`), a group
|
|
39
|
+
(`group/<Name>`, from the active group source — `groups.yaml`, or
|
|
40
|
+
`synced-groups.yaml` when groups sync from an identity provider), a person
|
|
41
|
+
as `Name <email>`, a plugin
|
|
42
|
+
token (above), or
|
|
40
43
|
**`everyone`** — the built-in org-wide principal: every signed-in person and
|
|
41
44
|
their agents. `read: everyone` in a folder's BODY opens that folder to the
|
|
42
45
|
whole organisation; it is how an organisation-wide skill or plugin is
|
|
@@ -46,8 +49,17 @@ Access to any path — reading it as much as writing it — is governed by
|
|
|
46
49
|
to the plugin itself. A person's personal plugin
|
|
47
50
|
(`{{pluginsDir}}/personal-<id>/`) grants its owner access and denies
|
|
48
51
|
`everyone` outright, so opening a parent folder never opens it.
|
|
49
|
-
|
|
50
|
-
`
|
|
52
|
+
**Write roles as `role/<Name>` and groups as `group/<Name>`** — for
|
|
53
|
+
example `read: group/Platform Team` or `deny role/Reviewer`; the Manage
|
|
54
|
+
access dialog writes them that way too. A bare name (`read: Reviewer`)
|
|
55
|
+
still works and means the ROLE when a role of that name exists, and the
|
|
56
|
+
group otherwise. So a group that shares a role's name is reached only as
|
|
57
|
+
`group/<Name>`: a bare `read: Admin` reaches the `Admin` role, never the
|
|
58
|
+
members of a group named `Admin` (unless `roles.yaml` itself lists that
|
|
59
|
+
group under the role). The same holds for a denial: a bare
|
|
60
|
+
`deny Admin` denies the role, so denying a same-named group needs
|
|
61
|
+
`deny group/Admin`. `role/<Name>` always means the role,
|
|
62
|
+
`group/<Name>` always the group.
|
|
51
63
|
- **Keep an `access.md` body pure YAML**, with any explanation in `#` comments.
|
|
52
64
|
A body that does not parse as YAML naming at least one verb is read in the
|
|
53
65
|
older format instead, where the FRONTMATTER carried the folder's rules — so a
|
|
@@ -171,9 +183,8 @@ roles:
|
|
|
171
183
|
- **With denials.** Group members hold the role's grants exactly as if they
|
|
172
184
|
were listed by email. A denial of the role in an `access.md`
|
|
173
185
|
(`deny role/Reviewer`) therefore removes the role's contribution for
|
|
174
|
-
everyone in the group, as it does for the emails.
|
|
175
|
-
|
|
176
|
-
exists. The nearest `access.md` that says
|
|
186
|
+
everyone in the group, as it does for the emails. To deny the group
|
|
187
|
+
instead, write `deny group/Platform Team`. The nearest `access.md` that says
|
|
177
188
|
anything about the person decides: a person granted by name
|
|
178
189
|
(`Name <email>`) in the SAME `access.md` as the denial keeps that access,
|
|
179
190
|
because within one file a person's own entry beats a role entry. A grant by
|
|
@@ -28,11 +28,17 @@ than by a markdown document.
|
|
|
28
28
|
|
|
29
29
|
### `window.bevel`
|
|
30
30
|
|
|
31
|
-
Core puts
|
|
31
|
+
Core puts five members on it:
|
|
32
32
|
|
|
33
33
|
- `window.bevel.openNode(href)` — follow `href` as if the reader had clicked a
|
|
34
34
|
link to it.
|
|
35
35
|
- `window.bevel.navigate(href)` — the same function under a second name.
|
|
36
|
+
- `window.bevel.branch` — the branch the page is viewed on, as a string: a
|
|
37
|
+
page that reads its data through the tools and links to what they name
|
|
38
|
+
does both there, so the same page shows a draft's data on the draft and the
|
|
39
|
+
released data on the default branch. `null` where the host has no branch
|
|
40
|
+
for the page (a page embedded on another site); read it as `window.bevel?.branch
|
|
41
|
+
?? '<default branch>'` so the page still works there.
|
|
36
42
|
- `window.bevel.tools` — the viewer's tools, or `null` where there are none
|
|
37
43
|
(next section).
|
|
38
44
|
- `window.bevel.requireTools()` — ask for the tools when the page cannot work
|
|
@@ -147,11 +153,214 @@ if (await window.bevel?.requireTools?.()) {
|
|
|
147
153
|
}
|
|
148
154
|
```
|
|
149
155
|
|
|
156
|
+
### Live data: a page that stays still while it loads
|
|
157
|
+
|
|
158
|
+
A page that reads its data through `window.bevel.tools` waits on several
|
|
159
|
+
calls before it has anything to show. Write it so the reader never sees the
|
|
160
|
+
page change shape, never sees a half-loaded board as if it were the answer,
|
|
161
|
+
and never loses the board they were reading:
|
|
162
|
+
|
|
163
|
+
- **Render the final page shell in the markup, before any data.** Headings,
|
|
164
|
+
columns, panels and the controls are in the HTML itself, with their size
|
|
165
|
+
reserved in CSS (a grid, a `min-height` per region). The loading treatment —
|
|
166
|
+
placeholder rows, `aria-busy="true"` — sits **inside** the data regions.
|
|
167
|
+
Never start with one "Loading…" line that the script later swaps for the
|
|
168
|
+
whole page: that swap is a full-page layout change, and the first thing the
|
|
169
|
+
reader sees looks broken.
|
|
170
|
+
- **Publish one consistent dataset at a time.** Collect every read into local
|
|
171
|
+
variables first; when ALL of them have succeeded, update every data region
|
|
172
|
+
from that one dataset in one synchronous step. Until then show no counts,
|
|
173
|
+
no cards and no empty columns: "0" or "None" is an answer only a finished
|
|
174
|
+
dataset may give.
|
|
175
|
+
- **Refresh keeps the current board.** A refresh leaves the last published
|
|
176
|
+
dataset on screen, shows a small refreshing state (a status line, the
|
|
177
|
+
Refresh button disabled) and publishes the replacement only when it is
|
|
178
|
+
complete. Never return to the loading placeholders.
|
|
179
|
+
- **A failed read fails the whole load, visibly.** If any read the page needs
|
|
180
|
+
rejects, publish nothing from that load: keep the shell (first load) or the
|
|
181
|
+
last good dataset (refresh), say what failed — the rejection carries the
|
|
182
|
+
tool's own message — and offer a Retry button that runs the same load
|
|
183
|
+
again. Never show the reads that did succeed as if they were the whole
|
|
184
|
+
board.
|
|
185
|
+
- **Read in bounded parallel once the paths are known.** List first
|
|
186
|
+
(`list_files`, `grep`), then read the files it named with a small fixed
|
|
187
|
+
number of `callTool` reads in flight at a time — four is plenty — rather
|
|
188
|
+
than one after another or all at once. Read tools run at once with no
|
|
189
|
+
prompt.
|
|
190
|
+
- **Load with `callTool`, not `callToolChain`.** A chain may write, so the app
|
|
191
|
+
asks the viewer before it runs: a page that loads through `callToolChain`
|
|
192
|
+
shows its reader a "wants to write" card for a read.
|
|
193
|
+
- **The reads are the viewer's own.** Every call answers with exactly what
|
|
194
|
+
the person viewing the page may read: `list_files` and `grep` leave out
|
|
195
|
+
what they may not, and `read_file` of such a file rejects. Build the board
|
|
196
|
+
from what the calls return; never try to widen it (another identity, a
|
|
197
|
+
copied dataset) — the same page shows each reader their own board.
|
|
198
|
+
- **Link to what the tools named by the path they answered.** A path a tool
|
|
199
|
+
answers (`read_file`'s `path`, a listing's `path`) starts with the checkout
|
|
200
|
+
folder, `{{kbDirName}}/Data/Tickets/A.md`, and knows nothing of where the
|
|
201
|
+
page sits. Link to it on the branch the page read it from, each segment of
|
|
202
|
+
the path encoded on its own — `'/workspace/' + encodeURIComponent(BRANCH)
|
|
203
|
+
+ '/' + path.split('/').map(encodeURIComponent).join('/')` — so a card and
|
|
204
|
+
its data come from one branch and a name carrying `#`, `?` or `%` stays
|
|
205
|
+
in the path rather than ending the URL at it; a root-relative `'/' +
|
|
206
|
+
path.split('/').map(encodeURIComponent).join('/')` opens it on the branch
|
|
207
|
+
the page is viewed on instead (see *How a link resolves*). Never put the
|
|
208
|
+
checkout folder in front of a path a tool answered: it is already there.
|
|
209
|
+
|
|
210
|
+
A complete page that follows these rules — plain HTML and one inline script,
|
|
211
|
+
no build step and no framework:
|
|
212
|
+
|
|
213
|
+
```html
|
|
214
|
+
<!doctype html>
|
|
215
|
+
<html>
|
|
216
|
+
<head>
|
|
217
|
+
<style>
|
|
218
|
+
body { font: 14px system-ui, sans-serif; margin: 16px; }
|
|
219
|
+
header { display: flex; align-items: center; gap: 12px; min-height: 40px; }
|
|
220
|
+
#status { color: #555; }
|
|
221
|
+
#status.error { color: #b00020; }
|
|
222
|
+
.board { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
|
|
223
|
+
.column { min-height: 320px; border: 1px solid #ddd; border-radius: 6px; padding: 8px; }
|
|
224
|
+
.column ul { list-style: none; margin: 0; padding: 0; }
|
|
225
|
+
.column li { min-height: 20px; padding: 6px; margin-bottom: 6px; border-radius: 4px; background: #f4f4f4; }
|
|
226
|
+
.column li.placeholder { background: #ececec; }
|
|
227
|
+
.count { color: #777; font-weight: normal; }
|
|
228
|
+
</style>
|
|
229
|
+
</head>
|
|
230
|
+
<body>
|
|
231
|
+
<header>
|
|
232
|
+
<h1>Tickets</h1>
|
|
233
|
+
<button id="refresh" type="button" disabled>Refresh</button>
|
|
234
|
+
<span id="status" role="status">Loading…</span>
|
|
235
|
+
<button id="retry" type="button" hidden>Retry</button>
|
|
236
|
+
</header>
|
|
237
|
+
<main id="board" class="board" aria-busy="true">
|
|
238
|
+
<section class="column" data-status="todo"><h2>To do <span class="count"></span></h2><ul><li class="placeholder"></li><li class="placeholder"></li></ul></section>
|
|
239
|
+
<section class="column" data-status="doing"><h2>Doing <span class="count"></span></h2><ul><li class="placeholder"></li><li class="placeholder"></li></ul></section>
|
|
240
|
+
<section class="column" data-status="done"><h2>Done <span class="count"></span></h2><ul><li class="placeholder"></li><li class="placeholder"></li></ul></section>
|
|
241
|
+
</main>
|
|
242
|
+
<script>
|
|
243
|
+
// The branch the page is viewed on: its data and its links both come from
|
|
244
|
+
// there, so the page on a draft shows the draft's tickets. Outside the app
|
|
245
|
+
// (no bridge) it reads the default branch.
|
|
246
|
+
const BRANCH = window.bevel?.branch ?? 'main';
|
|
247
|
+
const FOLDER = 'Data/Tickets';
|
|
248
|
+
const READS_IN_FLIGHT = 4;
|
|
249
|
+
const tools = window.bevel?.tools;
|
|
250
|
+
const board = document.getElementById('board');
|
|
251
|
+
const statusLine = document.getElementById('status');
|
|
252
|
+
const refreshButton = document.getElementById('refresh');
|
|
253
|
+
const retryButton = document.getElementById('retry');
|
|
254
|
+
let published = false;
|
|
255
|
+
|
|
256
|
+
/** The text under `# <heading>` in a node's markdown, whatever its line endings. */
|
|
257
|
+
function field(markdown, heading) {
|
|
258
|
+
const lines = markdown.split(/\r?\n/);
|
|
259
|
+
const at = lines.indexOf('# ' + heading);
|
|
260
|
+
if (at < 0) return '';
|
|
261
|
+
const end = lines.findIndex((line, i) => i > at && line.startsWith('# '));
|
|
262
|
+
return lines.slice(at + 1, end < 0 ? undefined : end).join('\n').trim();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* `fn` over `items`, at most `limit` at a time. After a failure no new item
|
|
267
|
+
* starts; it rejects with the first failure once the calls in flight have
|
|
268
|
+
* settled, so a Retry never overlaps the load that failed.
|
|
269
|
+
*/
|
|
270
|
+
async function mapBounded(items, limit, fn) {
|
|
271
|
+
const results = new Array(items.length);
|
|
272
|
+
let next = 0;
|
|
273
|
+
let failure = null;
|
|
274
|
+
async function worker() {
|
|
275
|
+
while (!failure && next < items.length) {
|
|
276
|
+
const i = next++;
|
|
277
|
+
try {
|
|
278
|
+
results[i] = await fn(items[i]);
|
|
279
|
+
} catch (error) {
|
|
280
|
+
failure ??= { error };
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
|
|
285
|
+
if (failure) throw failure.error;
|
|
286
|
+
return results;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** The whole dataset, or a rejection. Touches no element. */
|
|
290
|
+
async function readTickets() {
|
|
291
|
+
const listing = await tools.callTool('list_files', { body: { branch: BRANCH, path: FOLDER } });
|
|
292
|
+
const paths = listing.entries
|
|
293
|
+
.filter((entry) => entry.type === 'file' && entry.name.endsWith('.md'))
|
|
294
|
+
.map((entry) => `${FOLDER}/${entry.name}`);
|
|
295
|
+
return mapBounded(paths, READS_IN_FLIGHT, async (path) => {
|
|
296
|
+
const file = await tools.callTool('read_file', { body: { branch: BRANCH, path } });
|
|
297
|
+
// `file.path` is the path as the tool names it, checkout folder first.
|
|
298
|
+
return { path: file.path, name: field(file.content, 'Name') || path, status: field(file.content, 'Status').toLowerCase() };
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/** Every data region from one dataset, in one synchronous step. */
|
|
303
|
+
function publish(tickets) {
|
|
304
|
+
for (const column of board.querySelectorAll('.column')) {
|
|
305
|
+
const mine = tickets.filter((ticket) => ticket.status === column.dataset.status);
|
|
306
|
+
column.querySelector('.count').textContent = `(${mine.length})`;
|
|
307
|
+
const items = mine.map((ticket) => {
|
|
308
|
+
const link = document.createElement('a');
|
|
309
|
+
// Each segment encoded on its own: a name with `#` in it stays a name.
|
|
310
|
+
link.href = '/workspace/' + encodeURIComponent(BRANCH) + '/' + ticket.path.split('/').map(encodeURIComponent).join('/');
|
|
311
|
+
link.textContent = ticket.name;
|
|
312
|
+
const item = document.createElement('li');
|
|
313
|
+
item.append(link);
|
|
314
|
+
return item;
|
|
315
|
+
});
|
|
316
|
+
if (items.length === 0) {
|
|
317
|
+
const none = document.createElement('li');
|
|
318
|
+
none.textContent = 'None';
|
|
319
|
+
items.push(none);
|
|
320
|
+
}
|
|
321
|
+
column.querySelector('ul').replaceChildren(...items);
|
|
322
|
+
}
|
|
323
|
+
published = true;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function load() {
|
|
327
|
+
refreshButton.disabled = true;
|
|
328
|
+
retryButton.hidden = true;
|
|
329
|
+
board.setAttribute('aria-busy', 'true');
|
|
330
|
+
statusLine.className = '';
|
|
331
|
+
statusLine.textContent = published ? 'Refreshing…' : 'Loading…';
|
|
332
|
+
try {
|
|
333
|
+
publish(await readTickets());
|
|
334
|
+
statusLine.textContent = `Updated ${new Date().toLocaleTimeString()}`;
|
|
335
|
+
} catch (error) {
|
|
336
|
+
statusLine.className = 'error';
|
|
337
|
+
statusLine.textContent = (published ? 'Could not refresh; showing the last loaded board. ' : 'Could not load the tickets. ') + error.message;
|
|
338
|
+
retryButton.hidden = false;
|
|
339
|
+
} finally {
|
|
340
|
+
board.setAttribute('aria-busy', 'false');
|
|
341
|
+
refreshButton.disabled = false;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
refreshButton.addEventListener('click', load);
|
|
346
|
+
retryButton.addEventListener('click', load);
|
|
347
|
+
if (tools) {
|
|
348
|
+
load();
|
|
349
|
+
} else {
|
|
350
|
+
board.setAttribute('aria-busy', 'false');
|
|
351
|
+
statusLine.textContent = 'Open this page in Bevel to load the tickets.';
|
|
352
|
+
}
|
|
353
|
+
</script>
|
|
354
|
+
</body>
|
|
355
|
+
</html>
|
|
356
|
+
```
|
|
357
|
+
|
|
150
358
|
### Links written in the markup
|
|
151
359
|
|
|
152
360
|
An `<a href>` in the page keeps its address only when it is one of these:
|
|
153
361
|
|
|
154
362
|
- a document of the knowledge base, `.md`, `.html` or `.htm`, with or without a heading — `../Knowledge/Alice.md#goal`, `Q3-Report.html`, `Notes.htm`
|
|
363
|
+
- a root-relative path to such a document, from the checkout folder — `/{{kbDirName}}/Data/Tickets/A.md`
|
|
155
364
|
- an absolute workspace URL — `/workspace/main/{{knowledgeBaseDir}}/Alice.md`
|
|
156
365
|
- an external address — `https://example.com/docs`, `http://example.com`, `mailto:team@example.com`
|
|
157
366
|
- a bare fragment, a place in this page — `#totals`, `#`
|
|
@@ -177,10 +386,22 @@ or `window.bevel.navigate(href)`:
|
|
|
177
386
|
top" link. The page's own address does not change, so `hashchange` never
|
|
178
387
|
fires: a page that routes by hash handles its own clicks.
|
|
179
388
|
- **A relative path** resolves against the folder of the page's own file and
|
|
180
|
-
opens that file in the app
|
|
181
|
-
|
|
182
|
-
at its `goal` heading.
|
|
183
|
-
|
|
389
|
+
opens that file in the app, in a new tab, leaving the page where it is:
|
|
390
|
+
from `{{knowledgeBaseDir}}/Reports/Q3.html`, `../Knowledge/Alice.md#goal`
|
|
391
|
+
opens `{{knowledgeBaseDir}}/Knowledge/Alice.md` at its `goal` heading. A
|
|
392
|
+
path that names the page's own file with a fragment (`Q3.html#totals`
|
|
393
|
+
from `Q3.html`) scrolls the page, as `#totals` does.
|
|
394
|
+
- **A root-relative path**, `/{{kbDirName}}/<path>`, opens that file on the
|
|
395
|
+
page's own branch, in a new tab, from a page in any folder. A path a tool
|
|
396
|
+
answered (`read_file`'s `path`, a listing's `path`) already starts with the
|
|
397
|
+
checkout folder, so it is linked as `'/' +
|
|
398
|
+
path.split('/').map(encodeURIComponent).join('/')` — each segment encoded
|
|
399
|
+
on its own, so a name carrying `#`, `?` or `%` stays a name — never with
|
|
400
|
+
the folder put in front of it again; a path the page composed itself,
|
|
401
|
+
without that prefix, gets `'/{{kbDirName}}/'` in front. A link the page's
|
|
402
|
+
script creates after load is kept as written.
|
|
403
|
+
- **`/workspace/<branch>/<path>`** opens that file on that branch, in a new
|
|
404
|
+
tab.
|
|
184
405
|
- **An external address** (`http:`, `https:`, `mailto:`) opens in a new tab.
|
|
185
406
|
A call from a script may also open `tel:`, `sms:`, `geo:` and a
|
|
186
407
|
protocol-relative `//host/path` address in a new tab, though a link
|
|
@@ -191,3 +412,8 @@ or `window.bevel.navigate(href)`:
|
|
|
191
412
|
A click that a handler of the page has already cancelled with
|
|
192
413
|
`event.preventDefault()` is left to that handler: the bridge neither scrolls
|
|
193
414
|
nor opens anything for it.
|
|
415
|
+
|
|
416
|
+
A click on a link with Ctrl, Cmd or Shift held, or with the middle button,
|
|
417
|
+
opens its destination in a new tab, as a browser does with a link: a bare
|
|
418
|
+
fragment opens the page's own file at that section in a new tab, and the
|
|
419
|
+
page stays where it is.
|
|
@@ -2,6 +2,7 @@ import express, { type RequestHandler } from 'express';
|
|
|
2
2
|
import type { ISkillService, SkillSummary } from '../modules/skills/skills.contract.js';
|
|
3
3
|
import type { IToolManualService } from '../modules/tool-manuals/tool-manuals.contract.js';
|
|
4
4
|
import '../modules/tool-auth/tool-auth.middleware.js';
|
|
5
|
+
import { type IAgentScopeResolver } from '../modules/agent-scope/index.js';
|
|
5
6
|
/**
|
|
6
7
|
* The revision of a caller's catalog: a hex digest over the two lists.
|
|
7
8
|
*
|
|
@@ -27,7 +28,15 @@ export declare function catalogRevision(manuals: readonly string[], skills: read
|
|
|
27
28
|
views?: readonly {
|
|
28
29
|
uri: string;
|
|
29
30
|
text: string;
|
|
30
|
-
}[]
|
|
31
|
+
}[],
|
|
32
|
+
/**
|
|
33
|
+
* The connection's agent configuration — its path and the digest of its bytes, or
|
|
34
|
+
* why it cannot be used (`ConnectionScope.fingerprint`) — so an edit of
|
|
35
|
+
* the file is a new revision even when it changes nothing listed (a new
|
|
36
|
+
* skill entry that names nothing yet still moves it). Absent for
|
|
37
|
+
* Everything, whose revision is exactly what it was before agents existed.
|
|
38
|
+
*/
|
|
39
|
+
agent?: string | null): string;
|
|
31
40
|
/**
|
|
32
41
|
* `GET /agent/catalog-revision` — the caller's catalog fingerprint, plus the
|
|
33
42
|
* two counts behind it so an operator reading a log can tell a shrinking
|
|
@@ -42,6 +51,8 @@ export declare function createCatalogRevisionRoutes(deps: {
|
|
|
42
51
|
toolManuals: Pick<IToolManualService, 'catalogFingerprints'>;
|
|
43
52
|
skills: Pick<ISkillService, 'listSkills'>;
|
|
44
53
|
manualAuth: RequestHandler;
|
|
54
|
+
/** Resolves the scope of a connection made as an agent configuration (`modules/agent-scope`). */
|
|
55
|
+
agentScope?: Pick<IAgentScopeResolver, 'resolve'>;
|
|
45
56
|
/** Connection-key/internal-token user id → email, for the per-caller ACL. */
|
|
46
57
|
resolveUserEmail: (userId: string) => Promise<string | undefined>;
|
|
47
58
|
/** The MCP App views served; absent on a deployment that serves none. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-revision.d.ts","sourceRoot":"","sources":["../../src/core/catalog-revision.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,EAAE,EAAgB,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAErE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kDAAkD,CAAC;AAC3F,OAAO,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog-revision.d.ts","sourceRoot":"","sources":["../../src/core/catalog-revision.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,EAAE,EAAgB,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAErE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACxF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kDAAkD,CAAC;AAC3F,OAAO,8CAA8C,CAAC;AACtD,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAqCnG;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,MAAM,EAAE,SAAS,YAAY,EAAE;AAC/B;;;;GAIG;AACH,KAAK,GAAE,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAO;AACpD;;;;;;GAMG;AACH,KAAK,GAAE,MAAM,GAAG,IAAW,GAC1B,MAAM,CAUR;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,WAAW,EAAE,IAAI,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;IAC7D,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC1C,UAAU,EAAE,cAAc,CAAC;IAC3B,iGAAiG;IACjG,UAAU,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;IAClD,6EAA6E;IAC7E,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClE,yEAAyE;IACzE,OAAO,CAAC,EAAE;QAAE,QAAQ,IAAI,OAAO,CAAC;YAAE,SAAS,EAAE,SAAS;gBAAE,GAAG,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAA;aAAE,EAAE,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CAC5F,GAAG,OAAO,CAAC,MAAM,CAsCjB"}
|
|
@@ -2,6 +2,7 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import { logger } from '../shared/logging.js';
|
|
4
4
|
import '../modules/tool-auth/tool-auth.middleware.js'; // Express Request augmentation (req.toolAuth)
|
|
5
|
+
import { resolveConnectionScope } from '../modules/agent-scope/index.js';
|
|
5
6
|
const log = logger('catalog-revision');
|
|
6
7
|
/**
|
|
7
8
|
* A fingerprint of ONE caller's released catalog — every tool manual and every
|
|
@@ -56,13 +57,22 @@ export function catalogRevision(manuals, skills,
|
|
|
56
57
|
* changes a view and nothing else must still move the revision, or a local
|
|
57
58
|
* server already running keeps serving the view it read at startup.
|
|
58
59
|
*/
|
|
59
|
-
views = []
|
|
60
|
+
views = [],
|
|
61
|
+
/**
|
|
62
|
+
* The connection's agent configuration — its path and the digest of its bytes, or
|
|
63
|
+
* why it cannot be used (`ConnectionScope.fingerprint`) — so an edit of
|
|
64
|
+
* the file is a new revision even when it changes nothing listed (a new
|
|
65
|
+
* skill entry that names nothing yet still moves it). Absent for
|
|
66
|
+
* Everything, whose revision is exactly what it was before agents existed.
|
|
67
|
+
*/
|
|
68
|
+
agent = null) {
|
|
60
69
|
const lines = [
|
|
61
70
|
...[...manuals].sort(),
|
|
62
71
|
'\u0001', // separates the lists, so a line can never migrate between them
|
|
63
72
|
...skills.map(skillFingerprint).sort(),
|
|
64
73
|
'\u0001',
|
|
65
74
|
...views.map((v) => `${v.uri}\u0000${createHash('sha256').update(v.text).digest('hex')}`).sort(),
|
|
75
|
+
...(agent !== null ? ['\u0001', agent] : []),
|
|
66
76
|
];
|
|
67
77
|
return createHash('sha256').update(lines.join('\n')).digest('hex').slice(0, 32);
|
|
68
78
|
}
|
|
@@ -85,16 +95,26 @@ export function createCatalogRevisionRoutes(deps) {
|
|
|
85
95
|
// No resolvable caller is an EMPTY catalog, not a failure: that is what
|
|
86
96
|
// both list surfaces answer such a caller, so the fingerprint agrees
|
|
87
97
|
// with them rather than inventing a third verdict.
|
|
98
|
+
// A connection made as an agent configuration is fingerprinted over what IT
|
|
99
|
+
// loads, plus the file itself; Everything asks exactly what it always did.
|
|
100
|
+
const scope = await resolveConnectionScope(deps.agentScope, email, req.toolAuth?.agentPath);
|
|
101
|
+
const connectors = scope.connectorFilter();
|
|
102
|
+
const within = scope.skillFilter();
|
|
88
103
|
const [manuals, skills] = email
|
|
89
|
-
? await Promise.all([
|
|
104
|
+
? await Promise.all([
|
|
105
|
+
connectors ? deps.toolManuals.catalogFingerprints(email, connectors) : deps.toolManuals.catalogFingerprints(email),
|
|
106
|
+
within ? deps.skills.listSkills(email, { within }) : deps.skills.listSkills(email),
|
|
107
|
+
])
|
|
90
108
|
: [[], []];
|
|
91
109
|
// A manifest that cannot be read counts as no views, which is also what
|
|
92
110
|
// the MCP endpoint serves in that state.
|
|
93
111
|
const views = deps.mcpApps ? ((await deps.mcpApps.manifest().catch(() => null))?.resources ?? []) : [];
|
|
112
|
+
const connection = scope.toWire();
|
|
94
113
|
res.json({
|
|
95
|
-
revision: catalogRevision(manuals, skills, views),
|
|
114
|
+
revision: catalogRevision(manuals, skills, views, scope.fingerprint()),
|
|
96
115
|
tools: manuals.length,
|
|
97
116
|
skills: skills.length,
|
|
117
|
+
...(connection ? { connection } : {}),
|
|
98
118
|
});
|
|
99
119
|
}
|
|
100
120
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-revision.js","sourceRoot":"","sources":["../../src/core/catalog-revision.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,OAA8C,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG9C,OAAO,8CAA8C,CAAC,CAAC,8CAA8C;
|
|
1
|
+
{"version":3,"file":"catalog-revision.js","sourceRoot":"","sources":["../../src/core/catalog-revision.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,OAA8C,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG9C,OAAO,8CAA8C,CAAC,CAAC,8CAA8C;AACrG,OAAO,EAAE,sBAAsB,EAA4B,MAAM,iCAAiC,CAAC;AAEnG,MAAM,GAAG,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;;;GAOG;AACH,SAAS,gBAAgB,CAAC,CAAe;IACvC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACzE,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAC7B,OAA0B,EAC1B,MAA+B;AAC/B;;;;GAIG;AACH,QAAkD,EAAE;AACpD;;;;;;GAMG;AACH,QAAuB,IAAI;IAE3B,MAAM,KAAK,GAAG;QACZ,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE;QACtB,QAAQ,EAAE,gEAAgE;QAC1E,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE;QACtC,QAAQ;QACR,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE;QAChG,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC;IACF,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAU3C;IACC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,GAAY,EAAE,GAAG,EAAE,EAAE;QACjF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC;YACpC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC9F,wEAAwE;YACxE,qEAAqE;YACrE,mDAAmD;YACnD,4EAA4E;YAC5E,2EAA2E;YAC3E,MAAM,KAAK,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YAC5F,MAAM,UAAU,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YACnC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,KAAK;gBAC7B,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC;oBAChB,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,KAAK,CAAC;oBAClH,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;iBACnF,CAAC;gBACJ,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACb,wEAAwE;YACxE,yCAAyC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACvG,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC;gBACP,QAAQ,EAAE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtE,KAAK,EAAE,OAAO,CAAC,MAAM;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YAC/C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -7,7 +7,33 @@ import type { IAccountAdmission } from '../modules/auth/account-admission.js';
|
|
|
7
7
|
import type { IWriteAccess } from '../modules/write-access/write-access.js';
|
|
8
8
|
import type { OnServerStart } from '../modules/workspace/startup/on-server-start.js';
|
|
9
9
|
import type { AgentGuideHook } from '../modules/agent-guide/agent-guide.js';
|
|
10
|
+
import type { IAgentScopeResolver } from '../modules/agent-scope/index.js';
|
|
10
11
|
import type { EmbedNodeIdResolver } from '../modules/embed/embed.interface.js';
|
|
12
|
+
import type { IWorkspaceService } from '@bevel-software/platform-shared';
|
|
13
|
+
import type { IAccessControl } from '../modules/access/index.js';
|
|
14
|
+
import type { KbContext } from '../shared/kb-context.js';
|
|
15
|
+
import type { ITreeWalker } from '../shared/fs.contract.js';
|
|
16
|
+
import type { IPluginLinkIndex } from '../modules/plugins/index.js';
|
|
17
|
+
/**
|
|
18
|
+
* The core services a distribution's agent-scope resolver reads through,
|
|
19
|
+
* handed to `CorePorts.agentScope` when core makes it: the clones of the
|
|
20
|
+
* branches, the person's read gate, the branch model and knowledge-base
|
|
21
|
+
* layout, the disk walk that finds its configurations, and the plugin link
|
|
22
|
+
* index that says which plugins a `plugins:`-style entry stands for.
|
|
23
|
+
*
|
|
24
|
+
* Each is the service's CONTRACT, not its class: a resolver written against
|
|
25
|
+
* these runs on any implementation of them — core's own services in a
|
|
26
|
+
* deployment, a stand-in in a distribution's tests — and a resolver that
|
|
27
|
+
* needs more than a contract offers asks for the contract to grow, not for
|
|
28
|
+
* the class.
|
|
29
|
+
*/
|
|
30
|
+
export interface AgentScopeCollaborators {
|
|
31
|
+
workspaceService: IWorkspaceService;
|
|
32
|
+
accessControl: IAccessControl;
|
|
33
|
+
kb: KbContext;
|
|
34
|
+
disk: ITreeWalker;
|
|
35
|
+
pluginLinkIndex: IPluginLinkIndex;
|
|
36
|
+
}
|
|
11
37
|
/**
|
|
12
38
|
* Every seam the enterprise overlay can fill in the CORE composition
|
|
13
39
|
* (`createCoreServices`). All fields are optional; each has a safe core-only
|
|
@@ -108,6 +134,21 @@ export interface CorePorts {
|
|
|
108
134
|
* `modules/agent-guide`.
|
|
109
135
|
*/
|
|
110
136
|
agentGuide?: AgentGuideHook;
|
|
137
|
+
/**
|
|
138
|
+
* THIS distribution's agent configurations: what "Connect as" offers beside
|
|
139
|
+
* Everything, and what a connection made as one of them loads (see
|
|
140
|
+
* `modules/agent-scope`). Core owns the mechanism and no configuration —
|
|
141
|
+
* the file kind, where it lives and what its definition says are the
|
|
142
|
+
* distribution's, as the file kinds registered for access verbs are. A
|
|
143
|
+
* factory, since a resolver reads through core services that exist only
|
|
144
|
+
* once core is built: called ONCE, during construction, with those
|
|
145
|
+
* services (`AgentScopeCollaborators`), and its answer is the one resolver
|
|
146
|
+
* every surface consults from then on — the tool contexts, which capture it
|
|
147
|
+
* at construction, as much as the routes the server mounts later. Core
|
|
148
|
+
* default: `noAgentConfigurations()` — nothing is offered, and a connection
|
|
149
|
+
* recorded as some path loads nothing, never Everything.
|
|
150
|
+
*/
|
|
151
|
+
agentScope?: (core: AgentScopeCollaborators) => IAgentScopeResolver;
|
|
111
152
|
/**
|
|
112
153
|
* Mirror this composition's branch model and knowledge-base layout onto the
|
|
113
154
|
* shared package's PROCESS-WIDE live bindings (`DEFAULT_BRANCH`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core-ports.d.ts","sourceRoot":"","sources":["../../src/core/core-ports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iDAAiD,CAAC;AACrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"core-ports.d.ts","sourceRoot":"","sources":["../../src/core/core-ports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iDAAiD,CAAC;AACrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEpE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,EAAE,iBAAiB,CAAC;IACpC,aAAa,EAAE,cAAc,CAAC;IAC9B,EAAE,EAAE,SAAS,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,eAAe,EAAE,gBAAgB,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACrC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC5C;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;OAIG;IACH,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,mBAAmB,CAAC;IACpE;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IACrC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,mBAI/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core-ports.js","sourceRoot":"","sources":["../../src/core/core-ports.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"core-ports.js","sourceRoot":"","sources":["../../src/core/core-ports.ts"],"names":[],"mappings":"AAkMA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAwB;IACpD,KAAK,CAAC,GAAG;QACP,yCAAyC;IAC3C,CAAC;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-core-server.d.ts","sourceRoot":"","sources":["../../src/core/create-core-server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"create-core-server.d.ts","sourceRoot":"","sources":["../../src/core/create-core-server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAkDtD,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAmCvG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAO9D,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAE7C;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;IAChD,kEAAkE;IAClE,eAAe,EAAE,eAAe,CAAC;IACjC,IAAI,EAAE,YAAY,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;;OAYG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC;;;;OAIG;IACH,MAAM,CAAC,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClD,mFAAmF;IACnF,OAAO,CAAC,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACpD;;;;OAIG;IACH,KAAK,CAAC,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAAC;IAClC;;;;OAIG;IACH,SAAS,CAAC,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IACtD,2EAA2E;IAC3E,MAAM,CAAC,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;CACpD;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,YAAY,EAClB,GAAG,GAAE,gBAAqB,EAC1B,IAAI,GAAE;IACJ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAC;CACX,GACL,OAAO,CAAC,UAAU,CAAC,CA0xBrB"}
|
|
@@ -2,6 +2,7 @@ import express from 'express';
|
|
|
2
2
|
import cors from 'cors';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { createAuthRoutes } from '../modules/auth/auth.routes.js';
|
|
5
|
+
import { authCookieSecure } from '../modules/auth/auth.middleware.js';
|
|
5
6
|
import { createWorkspaceRoutes } from '../modules/workspace/workspace.routes.js';
|
|
6
7
|
import { createAgentUploadRoutes, isAgentUploadRawBodyPath, } from '../modules/workspace/agent-upload.routes.js';
|
|
7
8
|
import { createAgentDownloadRoutes } from '../modules/workspace/agent-download.routes.js';
|
|
@@ -228,7 +229,10 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
228
229
|
if (opts.boot ?? true)
|
|
229
230
|
await startCore(core, ext);
|
|
230
231
|
// Auth routes (unprotected — login endpoint must be accessible)
|
|
231
|
-
app.use('/api', createAuthRoutes(core.authService, core.authMiddleware, core.authProviders, core.config.loginPasswordEnabled
|
|
232
|
+
app.use('/api', createAuthRoutes(core.authService, core.authMiddleware, core.authProviders, core.config.loginPasswordEnabled,
|
|
233
|
+
// The cookie's Secure flag follows the scheme the deployment is reached
|
|
234
|
+
// on, as the SSO providers' does: one rule for every sign-in path.
|
|
235
|
+
{ cookieSecure: authCookieSecure(core.config.publicBackendUrl) }));
|
|
232
236
|
// MCP routes must mount BEFORE every `app.use('/api', authMiddleware, …)`
|
|
233
237
|
// below: Express 5 fires the outer JWT middleware before deciding whether
|
|
234
238
|
// its router has a matching route, so a request to `POST /api/mcp` carrying
|
|
@@ -237,7 +241,7 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
237
241
|
app.use('/api', createMcpRoutes(core.mcpService, core.externalApiKeyService, core.mcpAuthMiddleware, core.authMiddleware, core.usageMeter,
|
|
238
242
|
// The local-token exchange: verifies an MCP OAuth access token and mints
|
|
239
243
|
// the loopback internal token the local MCP server uses for its REST reads.
|
|
240
|
-
core.internalTokenService, core.mcpOAuthProvider, core.mcpResourceMetadataUrl));
|
|
244
|
+
core.internalTokenService, core.mcpOAuthProvider, core.mcpResourceMetadataUrl, core.agentScopeService));
|
|
241
245
|
// Remote sync — `POST /api/sync`, called by a git host's webhook or a
|
|
242
246
|
// pipeline with the deployment's sync secret (or by an admin's session).
|
|
243
247
|
// Same reason as MCP for mounting here: a non-JWT bearer must not meet a
|
|
@@ -273,6 +277,7 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
273
277
|
toolManualService: core.toolManualService,
|
|
274
278
|
accessControl: core.accessControl,
|
|
275
279
|
connectionProbe: core.connectionProbeService,
|
|
280
|
+
agents: core.agentScopeService,
|
|
276
281
|
stateSecret: core.config.jwtSecret,
|
|
277
282
|
publicBackendUrl: core.config.publicBackendUrl,
|
|
278
283
|
publicFrontendUrl: core.config.publicFrontendUrl,
|
|
@@ -394,7 +399,7 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
394
399
|
// What MCP clients are told about each platform tool's effect: read by the
|
|
395
400
|
// agent manual (the hosted endpoint) and by `/agent/tool-hints` (hexis-mcp).
|
|
396
401
|
const { readOnlyHints } = core;
|
|
397
|
-
toolsRouter.use(createManualRoutes(core.toolRegistry, core.manualAuthMiddleware, async (userId) => (await core.authService.getUserById(userId))?.email, readOnlyHints));
|
|
402
|
+
toolsRouter.use(createManualRoutes(core.toolRegistry, core.manualAuthMiddleware, async (userId) => (await core.authService.getUserById(userId))?.email, readOnlyHints, core.agentScopeService));
|
|
398
403
|
toolsRouter.use(createToolHintsAgentRoutes(readOnlyHints, core.manualAuthMiddleware));
|
|
399
404
|
// The aggregated manual list (KB + the caller's accessible `.tool`s) + inline
|
|
400
405
|
// `.tool` sub-manuals. Mounted on the tools router so they share `manualAuth`
|
|
@@ -405,7 +410,7 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
405
410
|
kb: core.kb,
|
|
406
411
|
disk: core.disk,
|
|
407
412
|
pluginIndex: core.pluginIndexService,
|
|
408
|
-
}));
|
|
413
|
+
}, core.agentScopeService));
|
|
409
414
|
// What every connected agent is told at session start, as the hosted proxy
|
|
410
415
|
// composes it: read by the local `hexis-mcp` bridge at startup and by the
|
|
411
416
|
// External agent access card. Same `manualAuth`, same router, as `all-tools`.
|
|
@@ -419,6 +424,7 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
419
424
|
skills: core.skillService,
|
|
420
425
|
manualAuth: core.manualAuthMiddleware,
|
|
421
426
|
resolveUserEmail: async (userId) => (await core.authService.getUserById(userId))?.email,
|
|
427
|
+
agentScope: core.agentScopeService,
|
|
422
428
|
// The views move the revision too: a release that changes a view and no
|
|
423
429
|
// manual would otherwise leave a running local server on the old one.
|
|
424
430
|
mcpApps: core.mcpAppService,
|
|
@@ -428,7 +434,7 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
428
434
|
// declaring knowledge-base file server-side, so the file is the allowlist and
|
|
429
435
|
// the caller cannot widen it. Same `manualAuth` as the rest of the agent
|
|
430
436
|
// surface.
|
|
431
|
-
toolsRouter.use(createDeclaredVariableRoutes(core.toolManualService, core.secretsVaultService, core.manualAuthMiddleware, async (userId) => (await core.authService.getUserById(userId))?.email));
|
|
437
|
+
toolsRouter.use(createDeclaredVariableRoutes(core.toolManualService, core.secretsVaultService, core.manualAuthMiddleware, async (userId) => (await core.authService.getUserById(userId))?.email, core.agentScopeService));
|
|
432
438
|
app.use('/api', toolsRouter);
|
|
433
439
|
// The same guard on the PARSED body, for the WHOLE `/workspace/:id` prefix
|
|
434
440
|
// and ahead of EVERY router under it — the file routes, the review, workflow
|
|
@@ -459,7 +465,7 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
459
465
|
toolAuth: core.toolAuthMiddleware,
|
|
460
466
|
isToolCredential: (token) => core.internalTokenService.looksLikeInternalToken(token) ||
|
|
461
467
|
core.externalApiKeyService.looksLikeExternalApiKey(token),
|
|
462
|
-
}), createPluginCreationRoutes(core.pluginProvisionService, async (req) => (req.userId ? ((await core.authService.getUserById(req.userId)) ?? null) : null)));
|
|
468
|
+
}), createPluginCreationRoutes(core.pluginProvisionService, async (req) => (req.userId ? ((await core.authService.getUserById(req.userId)) ?? null) : null), core.agentScopeService));
|
|
463
469
|
// Protected routes
|
|
464
470
|
// The same guard again, now BEHIND the JWT check, so an authenticated
|
|
465
471
|
// request also gets the resolved form judged — a link in the repository that
|
|
@@ -490,7 +496,7 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
490
496
|
}));
|
|
491
497
|
app.use('/api', createEventsRoutes(core.eventBus, core.authMiddleware, eventDelivery));
|
|
492
498
|
app.use('/api', core.authMiddleware, createDiffRoutes(core.diffService, core.authService, core.workflowService, core.accessControl, core.kbDirName));
|
|
493
|
-
app.use('/api', core.authMiddleware, createAccessRoutes(core.accessControl, core.workspaceService, core.authService, core.authService, core.workflowService, core.eventBus, core.db, core.kb, [core.config.adminEmail]));
|
|
499
|
+
app.use('/api', core.authMiddleware, createAccessRoutes(core.accessControl, core.workspaceService, core.authService, core.authService, core.workflowService, core.eventBus, core.db, core.kb, core.disk, [core.config.adminEmail]));
|
|
494
500
|
// Asking for Can edit or Owner on an item from its Manage access dialog, and
|
|
495
501
|
// the editors' Accept / Decline. Mounted beside the access routes it shares
|
|
496
502
|
// its gate with: the request is refused by the same canWrite it would
|
|
@@ -617,6 +623,7 @@ export async function createCoreServer(core, ext = {}, opts = {}) {
|
|
|
617
623
|
clientNameFor: (st) => core.githubFacade.clientNameFor(st),
|
|
618
624
|
completeConsent: (userId, st) => core.githubFacade.completeConsent(userId, st),
|
|
619
625
|
},
|
|
626
|
+
agents: core.agentScopeService,
|
|
620
627
|
}));
|
|
621
628
|
// What an Owner pastes into Claude's admin settings to register this
|
|
622
629
|
// deployment as a GitHub Enterprise Server — admins only — plus whether it
|