@bevel-software/platform-core-backend 0.14.0 → 0.15.1
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/THIRD-PARTY-NOTICES.md +6 -6
- package/dist/core/catalog-cache-invalidation.d.ts +29 -0
- package/dist/core/catalog-cache-invalidation.d.ts.map +1 -0
- package/dist/core/catalog-cache-invalidation.js +71 -0
- package/dist/core/catalog-cache-invalidation.js.map +1 -0
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +99 -8
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +18 -1
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +96 -43
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +18 -6
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +26 -1
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +213 -71
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +59 -7
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access-model/access-grammar.d.ts +51 -1
- package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
- package/dist/modules/access-model/access-grammar.js +95 -1
- package/dist/modules/access-model/access-grammar.js.map +1 -1
- package/dist/modules/access-model/group-files.d.ts.map +1 -1
- package/dist/modules/access-model/group-files.js +4 -1
- package/dist/modules/access-model/group-files.js.map +1 -1
- package/dist/modules/access-model/plugin-principals.d.ts +49 -0
- package/dist/modules/access-model/plugin-principals.d.ts.map +1 -0
- package/dist/modules/access-model/plugin-principals.js +125 -0
- package/dist/modules/access-model/plugin-principals.js.map +1 -0
- package/dist/modules/database/core-schema.d.ts +326 -0
- package/dist/modules/database/core-schema.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +52 -0
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/kb-sync/index.d.ts +6 -0
- package/dist/modules/kb-sync/index.d.ts.map +1 -0
- package/dist/modules/kb-sync/index.js +5 -0
- package/dist/modules/kb-sync/index.js.map +1 -0
- package/dist/modules/kb-sync/kb-sync.interface.d.ts +77 -0
- package/dist/modules/kb-sync/kb-sync.interface.d.ts.map +1 -0
- package/dist/modules/kb-sync/kb-sync.interface.js +2 -0
- package/dist/modules/kb-sync/kb-sync.interface.js.map +1 -0
- package/dist/modules/kb-sync/kb-sync.routes.d.ts +70 -0
- package/dist/modules/kb-sync/kb-sync.routes.d.ts.map +1 -0
- package/dist/modules/kb-sync/kb-sync.routes.js +135 -0
- package/dist/modules/kb-sync/kb-sync.routes.js.map +1 -0
- package/dist/modules/kb-sync/kb-sync.service.d.ts +45 -0
- package/dist/modules/kb-sync/kb-sync.service.d.ts.map +1 -0
- package/dist/modules/kb-sync/kb-sync.service.js +183 -0
- package/dist/modules/kb-sync/kb-sync.service.js.map +1 -0
- package/dist/modules/kb-sync/sync-auth.d.ts +59 -0
- package/dist/modules/kb-sync/sync-auth.d.ts.map +1 -0
- package/dist/modules/kb-sync/sync-auth.js +62 -0
- package/dist/modules/kb-sync/sync-auth.js.map +1 -0
- package/dist/modules/kb-sync/sync-payload.d.ts +32 -0
- package/dist/modules/kb-sync/sync-payload.d.ts.map +1 -0
- package/dist/modules/kb-sync/sync-payload.js +105 -0
- package/dist/modules/kb-sync/sync-payload.js.map +1 -0
- package/dist/modules/marketplace/git-http.routes.d.ts +42 -0
- package/dist/modules/marketplace/git-http.routes.d.ts.map +1 -0
- package/dist/modules/marketplace/git-http.routes.js +190 -0
- package/dist/modules/marketplace/git-http.routes.js.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts +23 -0
- package/dist/modules/marketplace/github-facade/github-facade-admin.routes.d.ts.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js +59 -0
- package/dist/modules/marketplace/github-facade/github-facade-admin.routes.js.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts +59 -0
- package/dist/modules/marketplace/github-facade/github-facade-codes.store.d.ts.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade-codes.store.js +96 -0
- package/dist/modules/marketplace/github-facade/github-facade-codes.store.js.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts +99 -0
- package/dist/modules/marketplace/github-facade/github-facade-credentials.service.d.ts.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js +147 -0
- package/dist/modules/marketplace/github-facade/github-facade-credentials.service.js.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts +47 -0
- package/dist/modules/marketplace/github-facade/github-facade.routes.d.ts.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade.routes.js +228 -0
- package/dist/modules/marketplace/github-facade/github-facade.routes.js.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade.service.d.ts +109 -0
- package/dist/modules/marketplace/github-facade/github-facade.service.d.ts.map +1 -0
- package/dist/modules/marketplace/github-facade/github-facade.service.js +172 -0
- package/dist/modules/marketplace/github-facade/github-facade.service.js.map +1 -0
- package/dist/modules/marketplace/github-facade/index.d.ts +6 -0
- package/dist/modules/marketplace/github-facade/index.d.ts.map +1 -0
- package/dist/modules/marketplace/github-facade/index.js +6 -0
- package/dist/modules/marketplace/github-facade/index.js.map +1 -0
- package/dist/modules/marketplace/index.d.ts +4 -0
- package/dist/modules/marketplace/index.d.ts.map +1 -0
- package/dist/modules/marketplace/index.js +4 -0
- package/dist/modules/marketplace/index.js.map +1 -0
- package/dist/modules/marketplace/marketplace-repo.service.d.ts +122 -0
- package/dist/modules/marketplace/marketplace-repo.service.d.ts.map +1 -0
- package/dist/modules/marketplace/marketplace-repo.service.js +300 -0
- package/dist/modules/marketplace/marketplace-repo.service.js.map +1 -0
- package/dist/modules/mcp/oauth/bevel-oauth-provider.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js +4 -0
- package/dist/modules/mcp/oauth/bevel-oauth-provider.js.map +1 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts +14 -8
- package/dist/modules/mcp/oauth/oauth-consent.routes.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.js +13 -1
- package/dist/modules/mcp/oauth/oauth-consent.routes.js.map +1 -1
- package/dist/modules/mcp/oauth/oauth-state.d.ts +13 -2
- package/dist/modules/mcp/oauth/oauth-state.d.ts.map +1 -1
- package/dist/modules/mcp/oauth/oauth-state.js +3 -1
- package/dist/modules/mcp/oauth/oauth-state.js.map +1 -1
- package/dist/modules/plugins/compile/compile-marketplace.d.ts +97 -0
- package/dist/modules/plugins/compile/compile-marketplace.d.ts.map +1 -0
- package/dist/modules/plugins/compile/compile-marketplace.js +240 -0
- package/dist/modules/plugins/compile/compile-marketplace.js.map +1 -0
- package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts +66 -0
- package/dist/modules/plugins/compile/marketplace-compiler.service.d.ts.map +1 -0
- package/dist/modules/plugins/compile/marketplace-compiler.service.js +132 -0
- package/dist/modules/plugins/compile/marketplace-compiler.service.js.map +1 -0
- package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts +37 -0
- package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.d.ts.map +1 -0
- package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js +135 -0
- package/dist/modules/plugins/discovery/bundle-dialect/bundle.source.js.map +1 -0
- package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts +45 -0
- package/dist/modules/plugins/discovery/bundle-dialect/registry.d.ts.map +1 -0
- package/dist/modules/plugins/discovery/bundle-dialect/registry.js +147 -0
- package/dist/modules/plugins/discovery/bundle-dialect/registry.js.map +1 -0
- package/dist/modules/plugins/discovery/kb-plugin-source.d.ts +37 -0
- package/dist/modules/plugins/discovery/kb-plugin-source.d.ts.map +1 -0
- package/dist/modules/plugins/discovery/kb-plugin-source.js +107 -0
- package/dist/modules/plugins/discovery/kb-plugin-source.js.map +1 -0
- package/dist/modules/plugins/discovery/native.source.d.ts +15 -0
- package/dist/modules/plugins/discovery/native.source.d.ts.map +1 -0
- package/dist/modules/plugins/discovery/native.source.js +102 -0
- package/dist/modules/plugins/discovery/native.source.js.map +1 -0
- package/dist/modules/plugins/discovery/plugin-source.d.ts +96 -0
- package/dist/modules/plugins/discovery/plugin-source.d.ts.map +1 -0
- package/dist/modules/plugins/discovery/plugin-source.js +2 -0
- package/dist/modules/plugins/discovery/plugin-source.js.map +1 -0
- package/dist/modules/plugins/index.d.ts +10 -1
- package/dist/modules/plugins/index.d.ts.map +1 -1
- package/dist/modules/plugins/index.js +8 -0
- package/dist/modules/plugins/index.js.map +1 -1
- package/dist/modules/plugins/plugin-links.d.ts +66 -0
- package/dist/modules/plugins/plugin-links.d.ts.map +1 -0
- package/dist/modules/plugins/plugin-links.js +160 -0
- package/dist/modules/plugins/plugin-links.js.map +1 -0
- package/dist/modules/plugins/plugin-links.service.d.ts +114 -0
- package/dist/modules/plugins/plugin-links.service.d.ts.map +1 -0
- package/dist/modules/plugins/plugin-links.service.js +304 -0
- package/dist/modules/plugins/plugin-links.service.js.map +1 -0
- package/dist/modules/plugins/plugin-provision.service.d.ts +39 -3
- package/dist/modules/plugins/plugin-provision.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugin-provision.service.js +152 -52
- package/dist/modules/plugins/plugin-provision.service.js.map +1 -1
- package/dist/modules/plugins/plugin-rename.service.d.ts +69 -0
- package/dist/modules/plugins/plugin-rename.service.d.ts.map +1 -0
- package/dist/modules/plugins/plugin-rename.service.js +245 -0
- package/dist/modules/plugins/plugin-rename.service.js.map +1 -0
- package/dist/modules/plugins/plugins.contract.d.ts +27 -1
- package/dist/modules/plugins/plugins.contract.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.d.ts +7 -1
- package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.routes.js +120 -12
- package/dist/modules/plugins/plugins.routes.js.map +1 -1
- package/dist/modules/plugins/plugins.service.d.ts +50 -3
- package/dist/modules/plugins/plugins.service.d.ts.map +1 -1
- package/dist/modules/plugins/plugins.service.js +108 -47
- package/dist/modules/plugins/plugins.service.js.map +1 -1
- package/dist/modules/settings/deployment-settings.service.d.ts +9 -0
- package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
- package/dist/modules/settings/deployment-settings.service.js +82 -2
- package/dist/modules/settings/deployment-settings.service.js.map +1 -1
- package/dist/modules/settings/setup.routes.d.ts +26 -0
- package/dist/modules/settings/setup.routes.d.ts.map +1 -1
- package/dist/modules/settings/setup.routes.js +9 -1
- package/dist/modules/settings/setup.routes.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/index.js +1 -0
- package/dist/modules/skills/index.js.map +1 -1
- package/dist/modules/skills/pending-skills.service.d.ts.map +1 -1
- package/dist/modules/skills/pending-skills.service.js +9 -4
- package/dist/modules/skills/pending-skills.service.js.map +1 -1
- package/dist/modules/skills/skill-access-requests.routes.d.ts +38 -0
- package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -0
- package/dist/modules/skills/skill-access-requests.routes.js +168 -0
- package/dist/modules/skills/skill-access-requests.routes.js.map +1 -0
- package/dist/modules/skills/skills.contract.d.ts +31 -0
- package/dist/modules/skills/skills.contract.d.ts.map +1 -1
- package/dist/modules/skills/skills.routes.d.ts +28 -3
- package/dist/modules/skills/skills.routes.d.ts.map +1 -1
- package/dist/modules/skills/skills.routes.js +42 -3
- package/dist/modules/skills/skills.routes.js.map +1 -1
- package/dist/modules/skills/skills.service.d.ts +4 -0
- package/dist/modules/skills/skills.service.d.ts.map +1 -1
- package/dist/modules/skills/skills.service.js +83 -22
- package/dist/modules/skills/skills.service.js.map +1 -1
- package/dist/modules/tool-auth/external-api-key.interface.d.ts +18 -1
- package/dist/modules/tool-auth/external-api-key.interface.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.interface.js +2 -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 +13 -4
- package/dist/modules/tool-auth/external-api-key.service.d.ts.map +1 -1
- package/dist/modules/tool-auth/external-api-key.service.js +26 -9
- package/dist/modules/tool-auth/external-api-key.service.js.map +1 -1
- package/dist/modules/tool-manuals/mcp-json-discovery.d.ts +36 -0
- package/dist/modules/tool-manuals/mcp-json-discovery.d.ts.map +1 -1
- package/dist/modules/tool-manuals/mcp-json-discovery.js +130 -92
- package/dist/modules/tool-manuals/mcp-json-discovery.js.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts +6 -1
- package/dist/modules/tool-manuals/tool-manuals.service.d.ts.map +1 -1
- package/dist/modules/tool-manuals/tool-manuals.service.js +18 -25
- package/dist/modules/tool-manuals/tool-manuals.service.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +40 -2
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +227 -54
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.d.ts +6 -0
- package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/pull-request.service.js +8 -0
- package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +52 -1
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +242 -9
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts +35 -0
- package/dist/modules/workspace/startup/steps/plugin-manifests.step.d.ts.map +1 -0
- package/dist/modules/workspace/startup/steps/plugin-manifests.step.js +121 -0
- package/dist/modules/workspace/startup/steps/plugin-manifests.step.js.map +1 -0
- package/dist/modules/workspace/startup/steps/seed-tree.d.ts.map +1 -1
- package/dist/modules/workspace/startup/steps/seed-tree.js +46 -2
- package/dist/modules/workspace/startup/steps/seed-tree.js.map +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 +112 -25
- package/dist/modules/workspace/startup/steps/template-files.step.js.map +1 -1
- package/dist/modules/workspace/workspace.routes.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.routes.js +9 -9
- package/dist/modules/workspace/workspace.routes.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +33 -0
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +110 -16
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/shared/domain-errors.d.ts +20 -0
- package/dist/shared/domain-errors.d.ts.map +1 -1
- package/dist/shared/domain-errors.js +29 -0
- package/dist/shared/domain-errors.js.map +1 -1
- package/dist/shared/fs-errors.d.ts +8 -0
- package/dist/shared/fs-errors.d.ts.map +1 -0
- package/dist/shared/fs-errors.js +11 -0
- package/dist/shared/fs-errors.js.map +1 -0
- package/dist/shared/fs-walk.d.ts +20 -6
- package/dist/shared/fs-walk.d.ts.map +1 -1
- package/dist/shared/fs-walk.js +35 -27
- package/dist/shared/fs-walk.js.map +1 -1
- package/dist/shared/kb-walk.d.ts +52 -0
- package/dist/shared/kb-walk.d.ts.map +1 -0
- package/dist/shared/kb-walk.js +76 -0
- package/dist/shared/kb-walk.js.map +1 -0
- package/dist/shared/path-order.d.ts +18 -0
- package/dist/shared/path-order.d.ts.map +1 -0
- package/dist/shared/path-order.js +35 -0
- package/dist/shared/path-order.js.map +1 -0
- package/dist/shared/ttl-cache.d.ts +28 -1
- package/dist/shared/ttl-cache.d.ts.map +1 -1
- package/dist/shared/ttl-cache.js +33 -1
- package/dist/shared/ttl-cache.js.map +1 -1
- package/kb-template/.bevelignore +1 -1
- package/kb-template/AGENTS.md +95 -30
- package/kb-template/Skills/.gitkeep +0 -0
- package/migrations/0005_github_facade.sql +25 -0
- package/migrations/meta/0005_snapshot.json +1717 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +6 -6
- package/src/__tests__/kb-layout-config.test.ts +110 -0
- package/src/core/__tests__/catalog-cache-invalidation.test.ts +146 -0
- package/src/core/catalog-cache-invalidation.ts +92 -0
- package/src/core/create-core-server.ts +123 -7
- package/src/core/create-core-services.ts +162 -41
- package/src/modules/access/__tests__/access-control.invalidate-race.test.ts +86 -0
- package/src/modules/access/__tests__/access-control.service.test.ts +19 -3
- package/src/modules/access/__tests__/access-plugin-principals.test.ts +368 -0
- package/src/modules/access/__tests__/groups-admin.service.test.ts +8 -0
- package/src/modules/access/access-control.interface.ts +20 -9
- package/src/modules/access/access-control.service.ts +240 -78
- package/src/modules/access/access.routes.ts +96 -14
- package/src/modules/access-model/__tests__/access-grammar.test.ts +18 -0
- package/src/modules/access-model/__tests__/plugin-token-canonical.test.ts +40 -0
- package/src/modules/access-model/access-grammar.ts +114 -2
- package/src/modules/access-model/group-files.ts +4 -0
- package/src/modules/access-model/plugin-principals.ts +137 -0
- package/src/modules/database/core-schema.ts +54 -0
- package/src/modules/kb-sync/__tests__/kb-sync.routes.test.ts +297 -0
- package/src/modules/kb-sync/__tests__/kb-sync.service.test.ts +295 -0
- package/src/modules/kb-sync/__tests__/sync-auth.test.ts +118 -0
- package/src/modules/kb-sync/__tests__/sync-payload.test.ts +148 -0
- package/src/modules/kb-sync/index.ts +19 -0
- package/src/modules/kb-sync/kb-sync.interface.ts +79 -0
- package/src/modules/kb-sync/kb-sync.routes.ts +197 -0
- package/src/modules/kb-sync/kb-sync.service.ts +201 -0
- package/src/modules/kb-sync/sync-auth.ts +118 -0
- package/src/modules/kb-sync/sync-payload.ts +143 -0
- package/src/modules/marketplace/__tests__/github-facade.test.ts +443 -0
- package/src/modules/marketplace/__tests__/marketplace-git.test.ts +179 -0
- package/src/modules/marketplace/git-http.routes.ts +193 -0
- package/src/modules/marketplace/github-facade/github-facade-admin.routes.ts +78 -0
- package/src/modules/marketplace/github-facade/github-facade-codes.store.ts +145 -0
- package/src/modules/marketplace/github-facade/github-facade-credentials.service.ts +208 -0
- package/src/modules/marketplace/github-facade/github-facade.routes.ts +268 -0
- package/src/modules/marketplace/github-facade/github-facade.service.ts +221 -0
- package/src/modules/marketplace/github-facade/index.ts +25 -0
- package/src/modules/marketplace/index.ts +3 -0
- package/src/modules/marketplace/marketplace-repo.service.ts +337 -0
- package/src/modules/mcp/oauth/bevel-oauth-provider.ts +3 -0
- package/src/modules/mcp/oauth/oauth-consent.routes.ts +24 -2
- package/src/modules/mcp/oauth/oauth-state.ts +15 -3
- package/src/modules/plugins/__tests__/bundle-dialect.e2e.test.ts +163 -0
- package/src/modules/plugins/__tests__/compile-marketplace.test.ts +294 -0
- package/src/modules/plugins/__tests__/plugin-index.service.test.ts +56 -12
- package/src/modules/plugins/__tests__/plugin-links.service.test.ts +287 -0
- package/src/modules/plugins/__tests__/plugin-provision.service.test.ts +205 -5
- package/src/modules/plugins/__tests__/plugin-rename.service.test.ts +394 -0
- package/src/modules/plugins/__tests__/plugins.routes.test.ts +80 -33
- package/src/modules/plugins/compile/compile-marketplace.ts +403 -0
- package/src/modules/plugins/compile/marketplace-compiler.service.ts +150 -0
- package/src/modules/plugins/discovery/__tests__/kb-plugin-source.test.ts +329 -0
- package/src/modules/plugins/discovery/bundle-dialect/bundle.source.ts +140 -0
- package/src/modules/plugins/discovery/bundle-dialect/registry.ts +175 -0
- package/src/modules/plugins/discovery/kb-plugin-source.ts +114 -0
- package/src/modules/plugins/discovery/native.source.ts +122 -0
- package/src/modules/plugins/discovery/plugin-source.ts +99 -0
- package/src/modules/plugins/index.ts +10 -0
- package/src/modules/plugins/plugin-links.service.ts +363 -0
- package/src/modules/plugins/plugin-links.ts +184 -0
- package/src/modules/plugins/plugin-provision.service.ts +160 -54
- package/src/modules/plugins/plugin-rename.service.ts +298 -0
- package/src/modules/plugins/plugins.contract.ts +28 -1
- package/src/modules/plugins/plugins.routes.ts +128 -11
- package/src/modules/plugins/plugins.service.ts +106 -53
- package/src/modules/settings/__tests__/deployment-settings.service.test.ts +57 -0
- package/src/modules/settings/__tests__/setup.routes.sync-status.test.ts +77 -0
- package/src/modules/settings/deployment-settings.service.ts +95 -2
- package/src/modules/settings/setup.routes.ts +24 -0
- package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +128 -0
- package/src/modules/skills/__tests__/skills.service.test.ts +85 -0
- package/src/modules/skills/index.ts +1 -0
- package/src/modules/skills/pending-skills.service.ts +7 -5
- package/src/modules/skills/skill-access-requests.routes.ts +199 -0
- package/src/modules/skills/skills.contract.ts +32 -0
- package/src/modules/skills/skills.routes.ts +59 -3
- package/src/modules/skills/skills.service.ts +84 -22
- package/src/modules/tool-auth/external-api-key.interface.ts +20 -1
- package/src/modules/tool-auth/external-api-key.service.ts +31 -13
- package/src/modules/tool-manuals/__tests__/mcp-json-discovery.test.ts +24 -1
- package/src/modules/tool-manuals/__tests__/tool-manuals.cli.test.ts +2 -0
- package/src/modules/tool-manuals/mcp-json-discovery.ts +154 -88
- package/src/modules/tool-manuals/tool-manuals.service.ts +14 -23
- package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +1 -1
- package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +1 -0
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +2 -2
- package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +119 -2
- package/src/modules/workflow/__tests__/workflow.service.sync.test.ts +437 -0
- package/src/modules/workflow/git/__tests__/git.service.postMergePull.test.ts +3 -3
- package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +47 -4
- package/src/modules/workflow/git/__tests__/git.service.syncFromRemote.test.ts +253 -0
- package/src/modules/workflow/git/git.service.ts +239 -56
- package/src/modules/workflow/git/pull-request.service.ts +9 -0
- package/src/modules/workflow/workflow.service.ts +260 -9
- package/src/modules/workspace/__tests__/workspace.routes.read-gate.test.ts +6 -7
- package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +93 -0
- package/src/modules/workspace/__tests__/workspace.service.missing-branch.test.ts +28 -0
- package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +42 -12
- package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +219 -4
- package/src/modules/workspace/startup/steps/plugin-manifests.step.ts +129 -0
- package/src/modules/workspace/startup/steps/seed-tree.ts +44 -2
- package/src/modules/workspace/startup/steps/template-files.step.ts +131 -27
- package/src/modules/workspace/workspace.routes.ts +9 -17
- package/src/modules/workspace/workspace.service.ts +107 -16
- package/src/shared/__tests__/filename.test.ts +0 -0
- package/src/shared/__tests__/fs-walk.test.ts +22 -1
- package/src/shared/__tests__/kb-walk.test.ts +107 -0
- package/src/shared/__tests__/path-order.test.ts +24 -0
- package/src/shared/__tests__/ttl-cache.test.ts +55 -0
- package/src/shared/domain-errors.ts +29 -0
- package/src/shared/fs-errors.ts +10 -0
- package/src/shared/fs-walk.ts +38 -23
- package/src/shared/kb-walk.ts +95 -0
- package/src/shared/path-order.ts +33 -0
- package/src/shared/ttl-cache.ts +33 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuthUser, BranchInfo, CommitAttribution, IGitService, PrFileStatus, PullRequestFile, ShareChangesRequest, WorkingTreeStatus } from '@bevel-software/platform-shared';
|
|
1
|
+
import type { AuthUser, BranchInfo, CommitAttribution, IGitService, RemoteSyncPullResult, PrFileStatus, PullRequestFile, ShareChangesRequest, WorkingTreeStatus } from '@bevel-software/platform-shared';
|
|
2
2
|
import type { WorkspaceService } from '../../workspace/workspace.service.js';
|
|
3
3
|
import type { WorkflowHooks } from '../workflow-hooks.js';
|
|
4
4
|
import type { IAccessControl } from '../../access/access-control.interface.js';
|
|
@@ -299,7 +299,45 @@ export declare class GitService implements IGitService {
|
|
|
299
299
|
* drift apart — which is precisely the failure class this guards against.
|
|
300
300
|
*/
|
|
301
301
|
private refreshRemoteBranchRef;
|
|
302
|
-
|
|
302
|
+
/** A commit-free tree, for diffing against a HEAD that did not exist yet. */
|
|
303
|
+
private static readonly EMPTY_TREE_SHA;
|
|
304
|
+
/**
|
|
305
|
+
* The checked-out branch by its symbolic ref, which an UNBORN HEAD (a clone
|
|
306
|
+
* of an empty upstream) still has — `rev-parse --abbrev-ref HEAD` does not
|
|
307
|
+
* resolve there, so the tolerant tree reads below would never be reached.
|
|
308
|
+
*/
|
|
309
|
+
private checkedOutBranch;
|
|
310
|
+
/**
|
|
311
|
+
* Whether origin still has `branch`. `ls-remote --exit-code` answers with
|
|
312
|
+
* exit status 2 for "no such ref" — the one failure that is a fact about the
|
|
313
|
+
* branch rather than about reaching the host, which propagates.
|
|
314
|
+
*/
|
|
315
|
+
remoteBranchExists(workspaceId: string, branch: string): Promise<boolean>;
|
|
316
|
+
/** Whether origin has ANY branch — an empty repository has none. */
|
|
317
|
+
private remoteHasAnyBranch;
|
|
318
|
+
/** `git rev-parse --verify` that answers null for a rev that does not resolve (an unborn HEAD). */
|
|
319
|
+
private revParseOrNull;
|
|
320
|
+
/**
|
|
321
|
+
* Refresh `refs/remotes/origin/<branch>` for a sync, naming the one failure
|
|
322
|
+
* that is not "origin unreachable": the branch no longer exists there.
|
|
323
|
+
*/
|
|
324
|
+
private refreshRemoteBranchRefForSync;
|
|
325
|
+
/**
|
|
326
|
+
* Rebase the checked-out branch onto `remoteRef`, turning a content
|
|
327
|
+
* conflict into the typed error the workflow layer queues recovery for.
|
|
328
|
+
* Shared by `pull` and `syncFromRemote` so the two cannot drift.
|
|
329
|
+
*/
|
|
330
|
+
private rebaseOntoRemote;
|
|
331
|
+
/**
|
|
332
|
+
* Repo-relative paths whose content differs between two commits. Rename-
|
|
333
|
+
* aware: a renamed file reports both its old and new path, so a viewer
|
|
334
|
+
* holding the OLD path learns it is gone. Caller holds the mutex.
|
|
335
|
+
*/
|
|
336
|
+
private changedPathsBetween;
|
|
337
|
+
syncFromRemote(workspaceId: string): Promise<RemoteSyncPullResult>;
|
|
338
|
+
pull(workspaceId: string): Promise<{
|
|
339
|
+
treeChanged: boolean;
|
|
340
|
+
}>;
|
|
303
341
|
/**
|
|
304
342
|
* Does the checked-out branch carry commits its remote-tracking ref
|
|
305
343
|
* doesn't reach? Purely local (`rev-list` against
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.service.d.ts","sourceRoot":"","sources":["../../../../src/modules/workflow/git/git.service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAA2B,MAAM,sBAAsB,CAAC;AACnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAE/E,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAML,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"git.service.d.ts","sourceRoot":"","sources":["../../../../src/modules/workflow/git/git.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import { WorkspaceMutex } from '../../kb-fs/mutex.js';
|
|
|
7
7
|
import { assertInsideRepo } from '../../kb-fs/repo-path.js';
|
|
8
8
|
import { cloneTrackingConfigArgs, SAFE_IMPLICIT_FETCH_ARGS } from '../../kb-fs/clone-config.js';
|
|
9
9
|
import { assertValidBranchName, assertValidRelativePath, isBranchAuthoredBy, isOwnSuggestionsBranch, isProtectedBranch, PROTECTED_BRANCHES, } from '../../kb-fs/branch-name.js';
|
|
10
|
-
import { BranchAuthorshipError, WorkflowValidationError, ProtectedBranchError, PullRebaseConflictError, } from '../../../shared/domain-errors.js';
|
|
10
|
+
import { BranchAuthorshipError, WorkflowValidationError, ProtectedBranchError, PullRebaseConflictError, RemoteBranchGoneError, isMissingRemoteBranchFailure, } from '../../../shared/domain-errors.js';
|
|
11
11
|
const execFileAsync = promisify(execFile);
|
|
12
12
|
function redact(msg) {
|
|
13
13
|
const token = process.env.GITHUB_TOKEN;
|
|
@@ -1369,68 +1369,241 @@ export class GitService {
|
|
|
1369
1369
|
]);
|
|
1370
1370
|
return `refs/remotes/origin/${branch}`;
|
|
1371
1371
|
}
|
|
1372
|
-
|
|
1372
|
+
/** A commit-free tree, for diffing against a HEAD that did not exist yet. */
|
|
1373
|
+
static EMPTY_TREE_SHA = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
|
|
1374
|
+
/**
|
|
1375
|
+
* The checked-out branch by its symbolic ref, which an UNBORN HEAD (a clone
|
|
1376
|
+
* of an empty upstream) still has — `rev-parse --abbrev-ref HEAD` does not
|
|
1377
|
+
* resolve there, so the tolerant tree reads below would never be reached.
|
|
1378
|
+
*/
|
|
1379
|
+
async checkedOutBranch(cwd) {
|
|
1380
|
+
const { stdout } = await this.git(cwd, ['symbolic-ref', '--short', 'HEAD']);
|
|
1381
|
+
return stdout.trim();
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Whether origin still has `branch`. `ls-remote --exit-code` answers with
|
|
1385
|
+
* exit status 2 for "no such ref" — the one failure that is a fact about the
|
|
1386
|
+
* branch rather than about reaching the host, which propagates.
|
|
1387
|
+
*/
|
|
1388
|
+
async remoteBranchExists(workspaceId, branch) {
|
|
1389
|
+
assertValidBranchName(branch);
|
|
1390
|
+
const cwd = await this.repoDir(workspaceId);
|
|
1391
|
+
try {
|
|
1392
|
+
await this.git(cwd, ['ls-remote', '--exit-code', '--heads', 'origin', `refs/heads/${branch}`]);
|
|
1393
|
+
return true;
|
|
1394
|
+
}
|
|
1395
|
+
catch (err) {
|
|
1396
|
+
if (err.exitCode === 2)
|
|
1397
|
+
return false;
|
|
1398
|
+
throw err;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
/** Whether origin has ANY branch — an empty repository has none. */
|
|
1402
|
+
async remoteHasAnyBranch(cwd) {
|
|
1403
|
+
const { stdout } = await this.git(cwd, ['ls-remote', '--heads', 'origin']);
|
|
1404
|
+
return stdout.trim().length > 0;
|
|
1405
|
+
}
|
|
1406
|
+
/** `git rev-parse --verify` that answers null for a rev that does not resolve (an unborn HEAD). */
|
|
1407
|
+
async revParseOrNull(cwd, rev) {
|
|
1408
|
+
try {
|
|
1409
|
+
const { stdout } = await this.git(cwd, ['rev-parse', '--verify', '--quiet', rev]);
|
|
1410
|
+
return stdout.trim() || null;
|
|
1411
|
+
}
|
|
1412
|
+
catch {
|
|
1413
|
+
return null;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Refresh `refs/remotes/origin/<branch>` for a sync, naming the one failure
|
|
1418
|
+
* that is not "origin unreachable": the branch no longer exists there.
|
|
1419
|
+
*/
|
|
1420
|
+
async refreshRemoteBranchRefForSync(cwd, branch) {
|
|
1421
|
+
try {
|
|
1422
|
+
return await this.refreshRemoteBranchRef(cwd, branch);
|
|
1423
|
+
}
|
|
1424
|
+
catch (err) {
|
|
1425
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1426
|
+
if (isMissingRemoteBranchFailure(msg))
|
|
1427
|
+
throw new RemoteBranchGoneError(branch);
|
|
1428
|
+
throw err;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Rebase the checked-out branch onto `remoteRef`, turning a content
|
|
1433
|
+
* conflict into the typed error the workflow layer queues recovery for.
|
|
1434
|
+
* Shared by `pull` and `syncFromRemote` so the two cannot drift.
|
|
1435
|
+
*/
|
|
1436
|
+
async rebaseOntoRemote(cwd, branch, remoteRef) {
|
|
1437
|
+
// An UNBORN HEAD (a clone of an upstream that was empty when cloned) has
|
|
1438
|
+
// no commit to replay and `git rebase` refuses to start from it, so the
|
|
1439
|
+
// branch is moved to the remote commit instead. That is only safe while
|
|
1440
|
+
// the index is EMPTY: files staged in an unborn clone are tracked, and a
|
|
1441
|
+
// hard reset would destroy them where the normal path autostashes — and
|
|
1442
|
+
// `git stash` cannot run without an initial commit. So a non-empty index
|
|
1443
|
+
// is refused as a conflict, naming the staged paths, and takes the same
|
|
1444
|
+
// recovery path a rebase conflict does; nothing on disk is touched.
|
|
1445
|
+
if ((await this.revParseOrNull(cwd, 'HEAD')) === null) {
|
|
1446
|
+
// `-z`: NUL-delimited and unquoted. Line output quotes a path with a
|
|
1447
|
+
// non-ASCII or control character ("Entw\303\274rfe.md"), and that
|
|
1448
|
+
// spelling would name a file that does not exist to whoever recovers.
|
|
1449
|
+
const { stdout: stagedOut } = await this.git(cwd, ['ls-files', '--cached', '-z']);
|
|
1450
|
+
const staged = stagedOut.split('\0').filter(Boolean);
|
|
1451
|
+
if (staged.length > 0) {
|
|
1452
|
+
throw new PullRebaseConflictError(branch, staged, 'The clone has files staged before its first commit; they cannot be replayed onto the remote branch automatically.');
|
|
1453
|
+
}
|
|
1454
|
+
await this.git(cwd, ['reset', '--hard', remoteRef]);
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
try {
|
|
1458
|
+
// `--autostash` is load-bearing for the cooperative push recovery.
|
|
1459
|
+
// Under save=share the working tree is *supposed* to stay clean, but
|
|
1460
|
+
// in practice it can carry modified tracked artifacts (e.g. the
|
|
1461
|
+
// validator regenerates a dashboard HTML on every commit) that the
|
|
1462
|
+
// single-file commit didn't pick up. A rebase without it aborts
|
|
1463
|
+
// outright on those — "cannot rebase: You have unstaged
|
|
1464
|
+
// changes" — which is exactly the failure that strands a diverged
|
|
1465
|
+
// branch in an unrecoverable loop (the retry push stays non-fast-
|
|
1466
|
+
// forward forever). Autostash stashes those modifications, rebases
|
|
1467
|
+
// the local commits onto origin, then reapplies them, so the retry
|
|
1468
|
+
// push can fast-forward. Untracked files don't block rebase and are
|
|
1469
|
+
// left untouched.
|
|
1470
|
+
await this.git(cwd, ['rebase', '--autostash', remoteRef]);
|
|
1471
|
+
}
|
|
1472
|
+
catch (err) {
|
|
1473
|
+
// Capture the contested paths BEFORE the abort wipes the rebase
|
|
1474
|
+
// state — `--diff-filter=U` lists exactly the files whose replay
|
|
1475
|
+
// conflicted. Best-effort: an empty list just means this wasn't a
|
|
1476
|
+
// content conflict (or the probe itself failed) and the raw error
|
|
1477
|
+
// is surfaced unchanged.
|
|
1478
|
+
let conflictedPaths = [];
|
|
1479
|
+
try {
|
|
1480
|
+
const { stdout } = await this.git(cwd, ['diff', '--name-only', '--diff-filter=U']);
|
|
1481
|
+
conflictedPaths = stdout.split('\n').map((s) => s.trim()).filter(Boolean);
|
|
1482
|
+
}
|
|
1483
|
+
catch {
|
|
1484
|
+
// fall through with an empty list
|
|
1485
|
+
}
|
|
1486
|
+
// A failed rebase leaves the repo in a "REBASE_HEAD" / detached-apply state,
|
|
1487
|
+
// which makes every subsequent git command behave unexpectedly. Return the
|
|
1488
|
+
// working tree to a clean state before surfacing the original error.
|
|
1489
|
+
let abortSucceeded = true;
|
|
1490
|
+
await this.git(cwd, ['rebase', '--abort']).catch(() => {
|
|
1491
|
+
abortSucceeded = false;
|
|
1492
|
+
});
|
|
1493
|
+
if (abortSucceeded && conflictedPaths.length > 0) {
|
|
1494
|
+
// Typed so the workflow layer can queue background recovery — this
|
|
1495
|
+
// divergence never resolves on its own (every retry pull hits the
|
|
1496
|
+
// same conflict) and the unpushed local commits are someone's saved
|
|
1497
|
+
// content stuck violating save=share.
|
|
1498
|
+
//
|
|
1499
|
+
// Gated on the abort succeeding: a failed abort means either no
|
|
1500
|
+
// rebase was ever active (the unmerged paths pre-date this pull —
|
|
1501
|
+
// some earlier operation left the index broken) or the clone is in
|
|
1502
|
+
// a state git itself can't unwind. Queueing recovery there would
|
|
1503
|
+
// point the worker's commitFile at a repo mid-conflict, risking a
|
|
1504
|
+
// commit full of conflict markers — surface the raw error instead
|
|
1505
|
+
// and leave diagnosis to a human.
|
|
1506
|
+
throw new PullRebaseConflictError(branch, conflictedPaths, err instanceof Error ? err.message : String(err));
|
|
1507
|
+
}
|
|
1508
|
+
throw err;
|
|
1509
|
+
}
|
|
1510
|
+
// `--autostash` reapplies the stashed edits AFTER the rebase, and when that
|
|
1511
|
+
// reapply conflicts git exits 0: the clone is left with an unmerged index,
|
|
1512
|
+
// the edits kept in `stash@{0}`, and nothing above has thrown. Read the
|
|
1513
|
+
// index rather than the exit status. The rebase itself landed, so the
|
|
1514
|
+
// branch is at the remote commit; resetting to it drops only the
|
|
1515
|
+
// half-applied stash (still in the stash list) and lets the conflict
|
|
1516
|
+
// travel the same typed path a rebase conflict does.
|
|
1517
|
+
const { stdout: unmergedOut } = await this.git(cwd, ['diff', '--name-only', '--diff-filter=U']);
|
|
1518
|
+
const unmerged = unmergedOut.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
1519
|
+
if (unmerged.length > 0) {
|
|
1520
|
+
await this.git(cwd, ['reset', '--hard', 'HEAD']);
|
|
1521
|
+
throw new PullRebaseConflictError(branch, unmerged, 'Reapplying the autostashed working-tree edits conflicted; the edits are kept in git stash.');
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Repo-relative paths whose content differs between two commits. Rename-
|
|
1526
|
+
* aware: a renamed file reports both its old and new path, so a viewer
|
|
1527
|
+
* holding the OLD path learns it is gone. Caller holds the mutex.
|
|
1528
|
+
*/
|
|
1529
|
+
async changedPathsBetween(cwd, fromSha, toSha) {
|
|
1530
|
+
const { stdout } = await this.git(cwd, [
|
|
1531
|
+
'diff', '--name-status', '-M', '--no-color', '-z', fromSha, toSha,
|
|
1532
|
+
]);
|
|
1533
|
+
const fields = stdout.split('\0');
|
|
1534
|
+
const paths = new Set();
|
|
1535
|
+
for (let i = 0; i < fields.length;) {
|
|
1536
|
+
const status = fields[i];
|
|
1537
|
+
if (!status)
|
|
1538
|
+
break;
|
|
1539
|
+
if (status.startsWith('R') || status.startsWith('C')) {
|
|
1540
|
+
if (fields[i + 1])
|
|
1541
|
+
paths.add(fields[i + 1]);
|
|
1542
|
+
if (fields[i + 2])
|
|
1543
|
+
paths.add(fields[i + 2]);
|
|
1544
|
+
i += 3;
|
|
1545
|
+
}
|
|
1546
|
+
else {
|
|
1547
|
+
if (fields[i + 1])
|
|
1548
|
+
paths.add(fields[i + 1]);
|
|
1549
|
+
i += 2;
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
return [...paths];
|
|
1553
|
+
}
|
|
1554
|
+
async syncFromRemote(workspaceId) {
|
|
1555
|
+
// ONE mutex section for everything the sync reports about this clone.
|
|
1556
|
+
// Bracketing `pull` with separate HEAD reads and a diff took the hold
|
|
1557
|
+
// four times, and a save landing between any two of them was announced
|
|
1558
|
+
// back to its author as a "Git sync" change with the wrong sha.
|
|
1373
1559
|
return this.mutex.run(workspaceId, async () => {
|
|
1374
1560
|
const cwd = await this.repoDir(workspaceId);
|
|
1375
|
-
const branch = await this.
|
|
1561
|
+
const branch = await this.checkedOutBranch(cwd);
|
|
1562
|
+
const before = await this.revParseOrNull(cwd, 'HEAD');
|
|
1563
|
+
const treeBefore = (await this.revParseOrNull(cwd, 'HEAD^{tree}')) ?? '';
|
|
1564
|
+
let remoteRef;
|
|
1376
1565
|
try {
|
|
1377
|
-
|
|
1378
|
-
// `refreshRemoteBranchRef` for why both halves are load-bearing.
|
|
1379
|
-
//
|
|
1380
|
-
// `--autostash` is load-bearing for the cooperative push recovery.
|
|
1381
|
-
// Under save=share the working tree is *supposed* to stay clean, but
|
|
1382
|
-
// in practice it can carry modified tracked artifacts (e.g. the
|
|
1383
|
-
// validator regenerates a dashboard HTML on every commit) that the
|
|
1384
|
-
// single-file commit didn't pick up. A rebase without it aborts
|
|
1385
|
-
// outright on those — "cannot rebase: You have unstaged
|
|
1386
|
-
// changes" — which is exactly the failure that strands a diverged
|
|
1387
|
-
// branch in an unrecoverable loop (the retry push stays non-fast-
|
|
1388
|
-
// forward forever). Autostash stashes those modifications, rebases
|
|
1389
|
-
// the local commits onto origin, then reapplies them, so the retry
|
|
1390
|
-
// push can fast-forward. Untracked files don't block rebase and are
|
|
1391
|
-
// left untouched.
|
|
1392
|
-
const remoteRef = await this.refreshRemoteBranchRef(cwd, branch);
|
|
1393
|
-
await this.git(cwd, ['rebase', '--autostash', remoteRef]);
|
|
1566
|
+
remoteRef = await this.refreshRemoteBranchRefForSync(cwd, branch);
|
|
1394
1567
|
}
|
|
1395
1568
|
catch (err) {
|
|
1396
|
-
//
|
|
1397
|
-
//
|
|
1398
|
-
//
|
|
1399
|
-
//
|
|
1400
|
-
// is
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
const { stdout } = await this.git(cwd, ['diff', '--name-only', '--diff-filter=U']);
|
|
1404
|
-
conflictedPaths = stdout.split('\n').map((s) => s.trim()).filter(Boolean);
|
|
1405
|
-
}
|
|
1406
|
-
catch {
|
|
1407
|
-
// fall through with an empty list
|
|
1408
|
-
}
|
|
1409
|
-
// A failed rebase leaves the repo in a "REBASE_HEAD" / detached-apply state,
|
|
1410
|
-
// which makes every subsequent git command behave unexpectedly. Return the
|
|
1411
|
-
// working tree to a clean state before surfacing the original error.
|
|
1412
|
-
let abortSucceeded = true;
|
|
1413
|
-
await this.git(cwd, ['rebase', '--abort']).catch(() => {
|
|
1414
|
-
abortSucceeded = false;
|
|
1415
|
-
});
|
|
1416
|
-
if (abortSucceeded && conflictedPaths.length > 0) {
|
|
1417
|
-
// Typed so the workflow layer can queue background recovery — this
|
|
1418
|
-
// divergence never resolves on its own (every retry pull hits the
|
|
1419
|
-
// same conflict) and the unpushed local commits are someone's saved
|
|
1420
|
-
// content stuck violating save=share.
|
|
1421
|
-
//
|
|
1422
|
-
// Gated on the abort succeeding: a failed abort means either no
|
|
1423
|
-
// rebase was ever active (the unmerged paths pre-date this pull —
|
|
1424
|
-
// some earlier operation left the index broken) or the clone is in
|
|
1425
|
-
// a state git itself can't unwind. Queueing recovery there would
|
|
1426
|
-
// point the worker's commitFile at a repo mid-conflict, risking a
|
|
1427
|
-
// commit full of conflict markers — surface the raw error instead
|
|
1428
|
-
// and leave diagnosis to a human.
|
|
1429
|
-
throw new PullRebaseConflictError(branch, conflictedPaths, err instanceof Error ? err.message : String(err));
|
|
1569
|
+
// An unborn clone whose branch origin does not have either: on a FRESH
|
|
1570
|
+
// deployment (origin has no branch at all) nobody has pushed yet —
|
|
1571
|
+
// nothing to sync, nothing to retire. But an origin that does have
|
|
1572
|
+
// branches and lacks this one has had this branch created and deleted
|
|
1573
|
+
// since the clone was made, and the clone is as stale as any other.
|
|
1574
|
+
if (err instanceof RemoteBranchGoneError && before === null && !(await this.remoteHasAnyBranch(cwd))) {
|
|
1575
|
+
return { before: null, after: null, treeChanged: false, changedPaths: [] };
|
|
1430
1576
|
}
|
|
1431
1577
|
throw err;
|
|
1432
1578
|
}
|
|
1579
|
+
await this.rebaseOntoRemote(cwd, branch, remoteRef);
|
|
1580
|
+
this.accessControl?.invalidate(workspaceId);
|
|
1581
|
+
const after = await this.revParseOrNull(cwd, 'HEAD');
|
|
1582
|
+
const treeAfter = (await this.revParseOrNull(cwd, 'HEAD^{tree}')) ?? '';
|
|
1583
|
+
const treeChanged = treeAfter !== treeBefore;
|
|
1584
|
+
const changedPaths = treeChanged && after
|
|
1585
|
+
? await this.changedPathsBetween(cwd, before ?? GitService.EMPTY_TREE_SHA, after)
|
|
1586
|
+
: [];
|
|
1587
|
+
return { before, after, treeChanged, changedPaths };
|
|
1588
|
+
});
|
|
1589
|
+
}
|
|
1590
|
+
async pull(workspaceId) {
|
|
1591
|
+
return this.mutex.run(workspaceId, async () => {
|
|
1592
|
+
const cwd = await this.repoDir(workspaceId);
|
|
1593
|
+
const branch = await this.checkedOutBranch(cwd);
|
|
1594
|
+
// For `treeChanged` (see IGitService.pull): TREE ids, not commit ids —
|
|
1595
|
+
// a pull that lands only content-identical commits (an empty commit)
|
|
1596
|
+
// must not read as a content change. Tolerant of an unborn HEAD (a
|
|
1597
|
+
// clone of an empty upstream): "" before + a tree after correctly
|
|
1598
|
+
// reads as changed, "" both sides as not.
|
|
1599
|
+
const treeBefore = (await this.revParseOrNull(cwd, 'HEAD^{tree}')) ?? '';
|
|
1600
|
+
// Refresh WITHOUT `git pull`, and without touching `FETCH_HEAD` — see
|
|
1601
|
+
// `refreshRemoteBranchRef` for why both halves are load-bearing.
|
|
1602
|
+
const remoteRef = await this.refreshRemoteBranchRef(cwd, branch);
|
|
1603
|
+
await this.rebaseOntoRemote(cwd, branch, remoteRef);
|
|
1433
1604
|
this.accessControl?.invalidate(workspaceId);
|
|
1605
|
+
const treeAfter = (await this.revParseOrNull(cwd, 'HEAD^{tree}')) ?? '';
|
|
1606
|
+
return { treeChanged: treeAfter !== treeBefore };
|
|
1434
1607
|
});
|
|
1435
1608
|
}
|
|
1436
1609
|
/**
|