@gitkraken/core-gitlens 0.3.0 → 0.4.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/CHANGELOG.md +20 -1
- package/README.md +13 -10
- package/dist/git/cache.d.ts +12 -6
- package/dist/git/cache.d.ts.map +1 -1
- package/dist/git/cache.js +40 -39
- package/dist/git/cache.js.map +1 -1
- package/dist/git/context.d.ts +23 -3
- package/dist/git/context.d.ts.map +1 -1
- package/dist/git/context.js.map +1 -1
- package/dist/git/features.d.ts +1 -1
- package/dist/git/features.d.ts.map +1 -1
- package/dist/git/features.js +1 -0
- package/dist/git/features.js.map +1 -1
- package/dist/git/models/graph.d.ts +96 -0
- package/dist/git/models/graph.d.ts.map +1 -1
- package/dist/git/models/graph.js +24 -1
- package/dist/git/models/graph.js.map +1 -1
- package/dist/git/models/remoteProvider.d.ts +1 -0
- package/dist/git/models/remoteProvider.d.ts.map +1 -1
- package/dist/git/models/remoteProvider.js.map +1 -1
- package/dist/git/models/repository.d.ts +21 -12
- package/dist/git/models/repository.d.ts.map +1 -1
- package/dist/git/models/repository.js +70 -84
- package/dist/git/models/repository.js.map +1 -1
- package/dist/git/models/statusFile.d.ts +9 -0
- package/dist/git/models/statusFile.d.ts.map +1 -1
- package/dist/git/models/statusFile.js +11 -0
- package/dist/git/models/statusFile.js.map +1 -1
- package/dist/git/providers/commits.d.ts +4 -0
- package/dist/git/providers/commits.d.ts.map +1 -1
- package/dist/git/providers/config.d.ts +1 -3
- package/dist/git/providers/config.d.ts.map +1 -1
- package/dist/git/providers/operations.d.ts +40 -13
- package/dist/git/providers/operations.d.ts.map +1 -1
- package/dist/git/providers/worktrees.d.ts +2 -0
- package/dist/git/providers/worktrees.d.ts.map +1 -1
- package/dist/git/remotes/custom.d.ts +2 -0
- package/dist/git/remotes/custom.d.ts.map +1 -1
- package/dist/git/remotes/custom.js +20 -0
- package/dist/git/remotes/custom.js.map +1 -1
- package/dist/git/utils/conflictResolution.utils.d.ts +32 -0
- package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -1
- package/dist/git/utils/conflictResolution.utils.js +95 -0
- package/dist/git/utils/conflictResolution.utils.js.map +1 -1
- package/dist/git/utils/contributor.utils.d.ts +3 -0
- package/dist/git/utils/contributor.utils.d.ts.map +1 -1
- package/dist/git/utils/contributor.utils.js +22 -0
- package/dist/git/utils/contributor.utils.js.map +1 -1
- package/dist/git/utils/reachability.utils.d.ts +37 -0
- package/dist/git/utils/reachability.utils.d.ts.map +1 -0
- package/dist/git/utils/reachability.utils.js +96 -0
- package/dist/git/utils/reachability.utils.js.map +1 -0
- package/dist/git/watching/watchService.d.ts +4 -2
- package/dist/git/watching/watchService.d.ts.map +1 -1
- package/dist/git/watching/watchService.js +8 -3
- package/dist/git/watching/watchService.js.map +1 -1
- package/dist/git/watching/watchSession.d.ts +14 -12
- package/dist/git/watching/watchSession.d.ts.map +1 -1
- package/dist/git/watching/watchSession.js +56 -55
- package/dist/git/watching/watchSession.js.map +1 -1
- package/dist/git-cli/providers/branches.d.ts.map +1 -1
- package/dist/git-cli/providers/branches.js +1 -0
- package/dist/git-cli/providers/branches.js.map +1 -1
- package/dist/git-cli/providers/commits.d.ts +1 -0
- package/dist/git-cli/providers/commits.d.ts.map +1 -1
- package/dist/git-cli/providers/commits.js +12 -0
- package/dist/git-cli/providers/commits.js.map +1 -1
- package/dist/git-cli/providers/config.d.ts +8 -4
- package/dist/git-cli/providers/config.d.ts.map +1 -1
- package/dist/git-cli/providers/config.js +62 -39
- package/dist/git-cli/providers/config.js.map +1 -1
- package/dist/git-cli/providers/diff.d.ts.map +1 -1
- package/dist/git-cli/providers/diff.js +1 -1
- package/dist/git-cli/providers/diff.js.map +1 -1
- package/dist/git-cli/providers/graph.d.ts.map +1 -1
- package/dist/git-cli/providers/graph.js +132 -14
- package/dist/git-cli/providers/graph.js.map +1 -1
- package/dist/git-cli/providers/operations.d.ts +7 -5
- package/dist/git-cli/providers/operations.d.ts.map +1 -1
- package/dist/git-cli/providers/operations.js +118 -95
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/stash.d.ts.map +1 -1
- package/dist/git-cli/providers/stash.js +20 -2
- package/dist/git-cli/providers/stash.js.map +1 -1
- package/dist/git-cli/providers/status.d.ts.map +1 -1
- package/dist/git-cli/providers/status.js +5 -2
- package/dist/git-cli/providers/status.js.map +1 -1
- package/dist/git-cli/providers/worktrees.d.ts +2 -0
- package/dist/git-cli/providers/worktrees.d.ts.map +1 -1
- package/dist/git-cli/providers/worktrees.js +3 -0
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/ipc/discovery.d.ts +22 -0
- package/dist/ipc/discovery.d.ts.map +1 -1
- package/dist/ipc/discovery.js +111 -2
- package/dist/ipc/discovery.js.map +1 -1
- package/dist/plus/agents/providers/claudeCodeProvider.d.ts +73 -20
- package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -1
- package/dist/plus/agents/providers/claudeCodeProvider.js +394 -88
- package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -1
- package/dist/plus/agents/types.d.ts +62 -11
- package/dist/plus/agents/types.d.ts.map +1 -1
- package/dist/plus/ai/models/model.d.ts +1 -1
- package/dist/plus/ai/models/model.d.ts.map +1 -1
- package/dist/plus/ai/models/model.js.map +1 -1
- package/dist/plus/ai/models/provider.d.ts +3 -0
- package/dist/plus/ai/models/provider.d.ts.map +1 -1
- package/dist/plus/ai/providers/gitkrakenProvider.d.ts +1 -1
- package/dist/plus/ai/providers/gitkrakenProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/gitkrakenProvider.js +4 -1
- package/dist/plus/ai/providers/gitkrakenProvider.js.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts +4 -3
- package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProviderBase.js +9 -6
- package/dist/plus/ai/providers/openAICompatibleProviderBase.js.map +1 -1
- package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
- package/dist/plus/ai/utils/ai.utils.js +6 -4
- package/dist/plus/ai/utils/ai.utils.js.map +1 -1
- package/dist/plus/git-github/api/github.d.ts +8 -13
- package/dist/plus/git-github/api/github.d.ts.map +1 -1
- package/dist/plus/git-github/api/github.js +96 -14
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/git-github/providers/github/refs.js +1 -1
- package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts +11 -0
- package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/cloudIntegrationService.js +90 -0
- package/dist/plus/integrations/authentication/cloudIntegrationService.js.map +1 -0
- package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts +67 -0
- package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/configuredIntegrationService.js +295 -0
- package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts +92 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +185 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js.map +1 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts +62 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationService.js +122 -0
- package/dist/plus/integrations/authentication/integrationAuthenticationService.js.map +1 -0
- package/dist/plus/integrations/authentication/manualTokenProvider.d.ts +15 -0
- package/dist/plus/integrations/authentication/manualTokenProvider.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/manualTokenProvider.js +49 -0
- package/dist/plus/integrations/authentication/manualTokenProvider.js.map +1 -0
- package/dist/plus/integrations/authentication/models.d.ts +87 -0
- package/dist/plus/integrations/authentication/models.d.ts.map +1 -0
- package/dist/plus/integrations/authentication/models.js +64 -0
- package/dist/plus/integrations/authentication/models.js.map +1 -0
- package/dist/plus/integrations/constants.d.ts +47 -0
- package/dist/plus/integrations/constants.d.ts.map +1 -0
- package/dist/plus/integrations/constants.js +128 -0
- package/dist/plus/integrations/constants.js.map +1 -0
- package/dist/plus/integrations/context.d.ts +354 -0
- package/dist/plus/integrations/context.d.ts.map +1 -0
- package/dist/plus/integrations/context.js +2 -0
- package/dist/plus/integrations/context.js.map +1 -0
- package/dist/plus/integrations/errors.d.ts +14 -0
- package/dist/plus/integrations/errors.d.ts.map +1 -0
- package/dist/plus/integrations/errors.js +19 -0
- package/dist/plus/integrations/errors.js.map +1 -0
- package/dist/plus/integrations/index.d.ts +32 -0
- package/dist/plus/integrations/index.d.ts.map +1 -0
- package/dist/plus/integrations/index.js +62 -0
- package/dist/plus/integrations/index.js.map +1 -0
- package/dist/plus/integrations/integrationService.d.ts +98 -0
- package/dist/plus/integrations/integrationService.d.ts.map +1 -0
- package/dist/plus/integrations/integrationService.js +627 -0
- package/dist/plus/integrations/integrationService.js.map +1 -0
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +82 -0
- package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -0
- package/dist/plus/integrations/models/gitHostIntegration.js +522 -0
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -0
- package/dist/plus/integrations/models/integration.d.ts +127 -0
- package/dist/plus/integrations/models/integration.d.ts.map +1 -0
- package/dist/plus/integrations/models/integration.js +456 -0
- package/dist/plus/integrations/models/integration.js.map +1 -0
- package/dist/plus/integrations/models/issuesIntegration.d.ts +28 -0
- package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -0
- package/dist/plus/integrations/models/issuesIntegration.js +101 -0
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -0
- package/dist/plus/integrations/providers/apiClients.d.ts +25 -0
- package/dist/plus/integrations/providers/apiClients.d.ts.map +1 -0
- package/dist/plus/integrations/providers/apiClients.js +39 -0
- package/dist/plus/integrations/providers/apiClients.js.map +1 -0
- package/dist/plus/integrations/providers/azure/azure.d.ts +47 -0
- package/dist/plus/integrations/providers/azure/azure.d.ts.map +1 -0
- package/dist/plus/integrations/providers/azure/azure.js +444 -0
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -0
- package/dist/plus/integrations/providers/azure/models.d.ts +286 -0
- package/dist/plus/integrations/providers/azure/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/azure/models.js +203 -0
- package/dist/plus/integrations/providers/azure/models.js.map +1 -0
- package/dist/plus/integrations/providers/azureDevOps.d.ts +95 -0
- package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -0
- package/dist/plus/integrations/providers/azureDevOps.js +432 -0
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +42 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js +513 -0
- package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket/models.d.ts +222 -0
- package/dist/plus/integrations/providers/bitbucket/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket/models.js +158 -0
- package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +120 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.js +111 -0
- package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +60 -0
- package/dist/plus/integrations/providers/bitbucket-server.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket-server.js +138 -0
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -0
- package/dist/plus/integrations/providers/bitbucket.d.ts +50 -0
- package/dist/plus/integrations/providers/bitbucket.d.ts.map +1 -0
- package/dist/plus/integrations/providers/bitbucket.js +181 -0
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -0
- package/dist/plus/integrations/providers/github/github.d.ts +5 -0
- package/dist/plus/integrations/providers/github/github.d.ts.map +1 -0
- package/dist/plus/integrations/providers/github/github.js +47 -0
- package/dist/plus/integrations/providers/github/github.js.map +1 -0
- package/dist/plus/integrations/providers/github/github.utils.d.ts +11 -0
- package/dist/plus/integrations/providers/github/github.utils.d.ts.map +1 -0
- package/dist/plus/integrations/providers/github/github.utils.js +6 -0
- package/dist/plus/integrations/providers/github/github.utils.js.map +1 -0
- package/dist/plus/integrations/providers/github/models.d.ts +3 -0
- package/dist/plus/integrations/providers/github/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/github/models.js +2 -0
- package/dist/plus/integrations/providers/github/models.js.map +1 -0
- package/dist/plus/integrations/providers/github.d.ts +73 -0
- package/dist/plus/integrations/providers/github.d.ts.map +1 -0
- package/dist/plus/integrations/providers/github.js +160 -0
- package/dist/plus/integrations/providers/github.js.map +1 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +63 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.d.ts.map +1 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.js +828 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts +21 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts.map +1 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.utils.js +45 -0
- package/dist/plus/integrations/providers/gitlab/gitlab.utils.js.map +1 -0
- package/dist/plus/integrations/providers/gitlab/models.d.ts +128 -0
- package/dist/plus/integrations/providers/gitlab/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/gitlab/models.js +96 -0
- package/dist/plus/integrations/providers/gitlab/models.js.map +1 -0
- package/dist/plus/integrations/providers/gitlab.d.ts +79 -0
- package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -0
- package/dist/plus/integrations/providers/gitlab.js +253 -0
- package/dist/plus/integrations/providers/gitlab.js.map +1 -0
- package/dist/plus/integrations/providers/jira.d.ts +46 -0
- package/dist/plus/integrations/providers/jira.d.ts.map +1 -0
- package/dist/plus/integrations/providers/jira.js +255 -0
- package/dist/plus/integrations/providers/jira.js.map +1 -0
- package/dist/plus/integrations/providers/linear.d.ts +47 -0
- package/dist/plus/integrations/providers/linear.d.ts.map +1 -0
- package/dist/plus/integrations/providers/linear.js +198 -0
- package/dist/plus/integrations/providers/linear.js.map +1 -0
- package/dist/plus/integrations/providers/models.d.ts +433 -0
- package/dist/plus/integrations/providers/models.d.ts.map +1 -0
- package/dist/plus/integrations/providers/models.js +602 -0
- package/dist/plus/integrations/providers/models.js.map +1 -0
- package/dist/plus/integrations/providers/providersApi.d.ts +129 -0
- package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -0
- package/dist/plus/integrations/providers/providersApi.js +602 -0
- package/dist/plus/integrations/providers/providersApi.js.map +1 -0
- package/dist/plus/integrations/providers/utils.d.ts +54 -0
- package/dist/plus/integrations/providers/utils.d.ts.map +1 -0
- package/dist/plus/integrations/providers/utils.js +262 -0
- package/dist/plus/integrations/providers/utils.js.map +1 -0
- package/dist/plus/integrations/telemetry.d.ts +26 -0
- package/dist/plus/integrations/telemetry.d.ts.map +1 -0
- package/dist/plus/integrations/telemetry.js +11 -0
- package/dist/plus/integrations/telemetry.js.map +1 -0
- package/dist/plus/integrations/utils/integration.utils.d.ts +14 -0
- package/dist/plus/integrations/utils/integration.utils.d.ts.map +1 -0
- package/dist/plus/integrations/utils/integration.utils.js +111 -0
- package/dist/plus/integrations/utils/integration.utils.js.map +1 -0
- package/dist/utils/date.d.ts.map +1 -1
- package/dist/utils/date.js +6 -0
- package/dist/utils/date.js.map +1 -1
- package/dist/utils/debounce.js +1 -1
- package/dist/utils/disposable.d.ts +15 -2
- package/dist/utils/disposable.d.ts.map +1 -1
- package/dist/utils/disposable.js.map +1 -1
- package/dist/utils/iterable.d.ts +7 -1
- package/dist/utils/iterable.d.ts.map +1 -1
- package/dist/utils/iterable.js +12 -4
- package/dist/utils/iterable.js.map +1 -1
- package/dist/utils/object.d.ts +22 -1
- package/dist/utils/object.d.ts.map +1 -1
- package/dist/utils/object.js +56 -3
- package/dist/utils/object.js.map +1 -1
- package/dist/utils/paging.js +14 -15
- package/dist/utils/paging.js.map +1 -1
- package/dist/utils/promiseCache.d.ts.map +1 -1
- package/dist/utils/promiseCache.js +12 -4
- package/dist/utils/promiseCache.js.map +1 -1
- package/dist/utils/string.js +1 -1
- package/package.json +43 -2
- package/src/git/cache.ts +58 -70
- package/src/git/context.ts +25 -3
- package/src/git/features.ts +2 -0
- package/src/git/models/graph.ts +97 -0
- package/src/git/models/remoteProvider.ts +1 -0
- package/src/git/models/repository.ts +84 -93
- package/src/git/models/statusFile.ts +12 -0
- package/src/git/providers/commits.ts +4 -0
- package/src/git/providers/config.ts +1 -5
- package/src/git/providers/operations.ts +42 -22
- package/src/git/providers/worktrees.ts +14 -2
- package/src/git/remotes/custom.ts +23 -0
- package/src/git/utils/conflictResolution.utils.ts +126 -0
- package/src/git/utils/contributor.utils.ts +24 -0
- package/src/git/utils/reachability.utils.ts +109 -0
- package/src/git/watching/watchService.ts +9 -4
- package/src/git/watching/watchSession.ts +61 -55
- package/src/git-cli/providers/branches.ts +1 -0
- package/src/git-cli/providers/commits.ts +24 -0
- package/src/git-cli/providers/config.ts +63 -49
- package/src/git-cli/providers/diff.ts +2 -1
- package/src/git-cli/providers/graph.ts +145 -14
- package/src/git-cli/providers/operations.ts +138 -130
- package/src/git-cli/providers/stash.ts +20 -2
- package/src/git-cli/providers/status.ts +11 -3
- package/src/git-cli/providers/worktrees.ts +17 -2
- package/src/ipc/discovery.ts +132 -2
- package/src/plus/agents/providers/claudeCodeProvider.ts +430 -90
- package/src/plus/agents/types.ts +59 -11
- package/src/plus/ai/models/model.ts +1 -0
- package/src/plus/ai/models/provider.ts +7 -1
- package/src/plus/ai/providers/gitkrakenProvider.ts +4 -0
- package/src/plus/ai/providers/openAICompatibleProviderBase.ts +21 -4
- package/src/plus/ai/utils/ai.utils.ts +6 -4
- package/src/plus/git-github/api/github.ts +131 -31
- package/src/plus/git-github/providers/github/refs.ts +1 -1
- package/src/plus/integrations/authentication/cloudIntegrationService.ts +120 -0
- package/src/plus/integrations/authentication/configuredIntegrationService.ts +414 -0
- package/src/plus/integrations/authentication/integrationAuthenticationProvider.ts +289 -0
- package/src/plus/integrations/authentication/integrationAuthenticationService.ts +144 -0
- package/src/plus/integrations/authentication/manualTokenProvider.ts +72 -0
- package/src/plus/integrations/authentication/models.ts +168 -0
- package/src/plus/integrations/constants.ts +169 -0
- package/src/plus/integrations/context.ts +383 -0
- package/src/plus/integrations/errors.ts +35 -0
- package/src/plus/integrations/index.ts +119 -0
- package/src/plus/integrations/integrationService.ts +924 -0
- package/src/plus/integrations/models/gitHostIntegration.ts +738 -0
- package/src/plus/integrations/models/integration.ts +657 -0
- package/src/plus/integrations/models/issuesIntegration.ts +124 -0
- package/src/plus/integrations/providers/apiClients.ts +72 -0
- package/src/plus/integrations/providers/azure/azure.ts +691 -0
- package/src/plus/integrations/providers/azure/models.ts +605 -0
- package/src/plus/integrations/providers/azureDevOps.ts +677 -0
- package/src/plus/integrations/providers/bitbucket/bitbucket.ts +774 -0
- package/src/plus/integrations/providers/bitbucket/models.ts +445 -0
- package/src/plus/integrations/providers/bitbucket-server/models.ts +252 -0
- package/src/plus/integrations/providers/bitbucket-server.ts +282 -0
- package/src/plus/integrations/providers/bitbucket.ts +350 -0
- package/src/plus/integrations/providers/github/github.ts +64 -0
- package/src/plus/integrations/providers/github/github.utils.ts +23 -0
- package/src/plus/integrations/providers/github/models.ts +29 -0
- package/src/plus/integrations/providers/github.ts +366 -0
- package/src/plus/integrations/providers/gitlab/gitlab.ts +1210 -0
- package/src/plus/integrations/providers/gitlab/gitlab.utils.ts +71 -0
- package/src/plus/integrations/providers/gitlab/models.ts +257 -0
- package/src/plus/integrations/providers/gitlab.ts +473 -0
- package/src/plus/integrations/providers/jira.ts +359 -0
- package/src/plus/integrations/providers/linear.ts +275 -0
- package/src/plus/integrations/providers/models.ts +1114 -0
- package/src/plus/integrations/providers/providersApi.ts +1126 -0
- package/src/plus/integrations/providers/utils.ts +359 -0
- package/src/plus/integrations/telemetry.ts +29 -0
- package/src/plus/integrations/utils/integration.utils.ts +138 -0
- package/src/utils/date.ts +5 -0
- package/src/utils/debounce.ts +1 -1
- package/src/utils/disposable.ts +15 -2
- package/src/utils/iterable.ts +14 -3
- package/src/utils/object.ts +55 -4
- package/src/utils/paging.ts +14 -14
- package/src/utils/promiseCache.ts +24 -16
- package/src/utils/string.ts +1 -1
|
@@ -7,7 +7,6 @@ import type { UnifiedDisposable } from '../../utils/disposable.js';
|
|
|
7
7
|
import { createDisposable } from '../../utils/disposable.js';
|
|
8
8
|
import type { Event } from '../../utils/event.js';
|
|
9
9
|
import { Emitter } from '../../utils/event.js';
|
|
10
|
-
import { getScopedLogger } from '../../utils/logger.scoped.js';
|
|
11
10
|
import { basename, normalizePath } from '../../utils/path.js';
|
|
12
11
|
import type { Uri } from '../../utils/uri.js';
|
|
13
12
|
import { fileUri } from '../../utils/uri.js';
|
|
@@ -84,8 +83,6 @@ export interface RepositoryInit {
|
|
|
84
83
|
readonly gitDir: GitDir | undefined;
|
|
85
84
|
readonly index: number;
|
|
86
85
|
readonly root: boolean;
|
|
87
|
-
readonly closed?: boolean;
|
|
88
|
-
readonly suspended?: boolean;
|
|
89
86
|
readonly watchService: RepositoryWatchService;
|
|
90
87
|
}
|
|
91
88
|
|
|
@@ -118,19 +115,21 @@ export class Repository {
|
|
|
118
115
|
readonly root: boolean;
|
|
119
116
|
|
|
120
117
|
protected readonly _gitDir: GitDir | undefined;
|
|
121
|
-
protected _pendingResumeTimer: ReturnType<typeof setTimeout> | undefined;
|
|
122
118
|
protected _repoSubscription: RepositorySubscription | undefined;
|
|
123
|
-
protected _suspended: boolean;
|
|
124
119
|
protected _watchHandle: WatchHandle | undefined;
|
|
125
120
|
protected readonly _watchService: RepositoryWatchService;
|
|
126
121
|
|
|
127
122
|
private _pendingWorkingTreeChange?: RepositoryWorkingTreeChangeEvent;
|
|
128
123
|
private _pendingWorkingTreeFlush = false;
|
|
129
124
|
private _repoChangeListener: UnifiedDisposable | undefined;
|
|
125
|
+
/** Outstanding leases on the shared {@link _watchHandle} across `watch()` + `watchWorkingTree()`. */
|
|
126
|
+
private _watchHandleRefs = 0;
|
|
127
|
+
/** Outstanding `watch()` (repo-change) leases; drives the single shared bridge subscription. */
|
|
128
|
+
private _watchRefs = 0;
|
|
129
|
+
private _disposed = false;
|
|
130
130
|
|
|
131
131
|
constructor(init: RepositoryInit) {
|
|
132
132
|
({
|
|
133
|
-
closed: this._closed = init.closed ?? false,
|
|
134
133
|
id: this.id,
|
|
135
134
|
index: this.index,
|
|
136
135
|
gitDir: this._gitDir,
|
|
@@ -138,7 +137,6 @@ export class Repository {
|
|
|
138
137
|
path: this.path,
|
|
139
138
|
provider: this.provider,
|
|
140
139
|
root: this.root,
|
|
141
|
-
suspended: this._suspended = init.suspended ?? false,
|
|
142
140
|
uri: this.uri,
|
|
143
141
|
watchService: this._watchService,
|
|
144
142
|
} = init);
|
|
@@ -156,45 +154,25 @@ export class Repository {
|
|
|
156
154
|
this._name = `${prefix}${this._name}`;
|
|
157
155
|
}
|
|
158
156
|
}
|
|
159
|
-
|
|
160
|
-
this.setupWatching();
|
|
161
157
|
}
|
|
162
158
|
|
|
163
159
|
dispose(): void {
|
|
164
|
-
|
|
160
|
+
this._disposed = true;
|
|
165
161
|
this._repoChangeListener?.dispose();
|
|
166
162
|
this._repoChangeListener = undefined;
|
|
167
163
|
this._repoSubscription?.dispose();
|
|
168
164
|
this._repoSubscription = undefined;
|
|
169
165
|
this._watchHandle?.dispose();
|
|
170
166
|
this._watchHandle = undefined;
|
|
167
|
+
this._watchHandleRefs = 0;
|
|
168
|
+
this._watchRefs = 0;
|
|
171
169
|
this._onDidChange.dispose();
|
|
172
170
|
this._onDidChangeWorkingTree.dispose();
|
|
173
171
|
}
|
|
174
172
|
|
|
175
|
-
|
|
176
|
-
get
|
|
177
|
-
return this.
|
|
178
|
-
}
|
|
179
|
-
set closed(value: boolean) {
|
|
180
|
-
const changed = this._closed !== value;
|
|
181
|
-
this._closed = value;
|
|
182
|
-
if (changed) {
|
|
183
|
-
if (this._closed) {
|
|
184
|
-
// When closing, fire immediately even if suspended
|
|
185
|
-
this.fireChange('closed', true);
|
|
186
|
-
|
|
187
|
-
this._repoChangeListener?.dispose();
|
|
188
|
-
this._repoChangeListener = undefined;
|
|
189
|
-
this._repoSubscription?.dispose();
|
|
190
|
-
this._repoSubscription = undefined;
|
|
191
|
-
} else {
|
|
192
|
-
this.setupWatching();
|
|
193
|
-
this.fireChange('opened');
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
this.onClosedChanged(value);
|
|
197
|
-
}
|
|
173
|
+
/** Indicates whether this repository currently has an active `watch()` (repo-change) lease. */
|
|
174
|
+
get watching(): boolean {
|
|
175
|
+
return this._watchRefs > 0;
|
|
198
176
|
}
|
|
199
177
|
|
|
200
178
|
get etag(): number {
|
|
@@ -249,41 +227,6 @@ export class Repository {
|
|
|
249
227
|
return this.provider.virtual;
|
|
250
228
|
}
|
|
251
229
|
|
|
252
|
-
@trace({ onlyExit: true })
|
|
253
|
-
suspend(): void {
|
|
254
|
-
this._suspended = true;
|
|
255
|
-
this._watchHandle?.session.suspend();
|
|
256
|
-
|
|
257
|
-
if (this._pendingResumeTimer != null) {
|
|
258
|
-
clearTimeout(this._pendingResumeTimer);
|
|
259
|
-
this._pendingResumeTimer = undefined;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
@trace({ onlyExit: true })
|
|
264
|
-
resume(delayMs?: number): void {
|
|
265
|
-
if (delayMs) {
|
|
266
|
-
if (this._pendingResumeTimer != null) {
|
|
267
|
-
clearTimeout(this._pendingResumeTimer);
|
|
268
|
-
}
|
|
269
|
-
this._pendingResumeTimer = setTimeout(() => {
|
|
270
|
-
this._pendingResumeTimer = undefined;
|
|
271
|
-
this.resume();
|
|
272
|
-
}, delayMs);
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const scope = getScopedLogger();
|
|
277
|
-
|
|
278
|
-
if (!this._suspended) {
|
|
279
|
-
scope?.addExitInfo('ignored; not suspended');
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
this._suspended = false;
|
|
284
|
-
this._watchHandle?.session.resume();
|
|
285
|
-
}
|
|
286
|
-
|
|
287
230
|
waitForRepoChange(timeoutMs: number): Promise<boolean> {
|
|
288
231
|
let timeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
289
232
|
let listener: UnifiedDisposable | undefined;
|
|
@@ -313,17 +256,57 @@ export class Repository {
|
|
|
313
256
|
]);
|
|
314
257
|
}
|
|
315
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Starts watching this repository's `.git` directory for repo-change events (delivered via
|
|
261
|
+
* {@link onDidChange}) and returns a lease. Ref-counted: the underlying watch handle is acquired
|
|
262
|
+
* on the first lease (across `watch()` and {@link watchWorkingTree}) and released when the last
|
|
263
|
+
* is disposed. The model is inert until watched. No-ops (returns a disposable that does nothing)
|
|
264
|
+
* for repositories without a git directory (e.g. virtual repos).
|
|
265
|
+
*/
|
|
266
|
+
@trace({ onlyExit: true })
|
|
267
|
+
watch(): UnifiedDisposable {
|
|
268
|
+
const acquired = this.acquireWatchHandle();
|
|
269
|
+
if (acquired == null) return createDisposable(() => {});
|
|
270
|
+
|
|
271
|
+
if (this._watchRefs++ === 0) {
|
|
272
|
+
const sub = acquired.handle.session.subscribe();
|
|
273
|
+
this._repoSubscription = sub;
|
|
274
|
+
this._repoChangeListener = sub.onDidChange(e => this.onSessionRepoChange(e));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return createDisposable(
|
|
278
|
+
() => {
|
|
279
|
+
// Repo already torn down — its handle/subscriptions are gone; skip to avoid a negative refcount
|
|
280
|
+
if (this._disposed) return;
|
|
281
|
+
|
|
282
|
+
if (--this._watchRefs === 0) {
|
|
283
|
+
this._repoChangeListener?.dispose();
|
|
284
|
+
this._repoChangeListener = undefined;
|
|
285
|
+
this._repoSubscription?.dispose();
|
|
286
|
+
this._repoSubscription = undefined;
|
|
287
|
+
}
|
|
288
|
+
acquired.lease.dispose();
|
|
289
|
+
},
|
|
290
|
+
{ once: true },
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
|
|
316
294
|
@trace({ onlyExit: true })
|
|
317
295
|
watchWorkingTree(delay: number = 2500): UnifiedDisposable {
|
|
318
|
-
const
|
|
319
|
-
if (
|
|
296
|
+
const acquired = this.acquireWatchHandle();
|
|
297
|
+
if (acquired == null) return createDisposable(() => {});
|
|
320
298
|
|
|
299
|
+
const sub = acquired.handle.session.subscribeToWorkingTree({ delayMs: delay });
|
|
321
300
|
const listener = sub.onDidChangeWorkingTree(e => this.onWorkingTreeChanged(e.paths));
|
|
322
301
|
|
|
323
|
-
return createDisposable(
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
302
|
+
return createDisposable(
|
|
303
|
+
() => {
|
|
304
|
+
listener.dispose();
|
|
305
|
+
sub.dispose();
|
|
306
|
+
acquired.lease.dispose();
|
|
307
|
+
},
|
|
308
|
+
{ once: true },
|
|
309
|
+
);
|
|
327
310
|
}
|
|
328
311
|
|
|
329
312
|
/**
|
|
@@ -338,7 +321,7 @@ export class Repository {
|
|
|
338
321
|
protected fireChange(change: RepositoryChange, force: boolean): void;
|
|
339
322
|
@trace()
|
|
340
323
|
protected fireChange(...args: RepositoryChange[] | [RepositoryChange, boolean]): void {
|
|
341
|
-
const lastArg = args
|
|
324
|
+
const lastArg = args.at(-1);
|
|
342
325
|
const force = typeof lastArg === 'boolean' ? lastArg : false;
|
|
343
326
|
const changes = (force ? args.slice(0, -1) : args) as RepositoryChange[];
|
|
344
327
|
|
|
@@ -353,9 +336,6 @@ export class Repository {
|
|
|
353
336
|
this._watchHandle?.session.fireChange(...changes);
|
|
354
337
|
}
|
|
355
338
|
|
|
356
|
-
/** Called when the closed state changes. Override to add behavior (e.g., branch access tracking). */
|
|
357
|
-
protected onClosedChanged(_closed: boolean): void {}
|
|
358
|
-
|
|
359
339
|
/** Called when the watch service notifies of FETCH_HEAD changes. */
|
|
360
340
|
protected onFetchHeadChanged(): void {
|
|
361
341
|
// Don't reset `_lastFetched` here: the FS watcher can fire even when the on-disk mtime
|
|
@@ -414,39 +394,50 @@ export class Repository {
|
|
|
414
394
|
(this._pendingWorkingTreeChange.uris as Set<Uri>).add(fileUri(p));
|
|
415
395
|
}
|
|
416
396
|
|
|
417
|
-
if (this._suspended) return;
|
|
418
397
|
if (this._pendingWorkingTreeFlush) return;
|
|
419
398
|
|
|
420
399
|
this._pendingWorkingTreeFlush = true;
|
|
421
400
|
queueMicrotask(() => {
|
|
422
401
|
this._pendingWorkingTreeFlush = false;
|
|
423
402
|
const e = this._pendingWorkingTreeChange;
|
|
424
|
-
if (e == null
|
|
403
|
+
if (e == null) return;
|
|
425
404
|
|
|
426
405
|
this._pendingWorkingTreeChange = undefined;
|
|
427
406
|
this._onDidChangeWorkingTree.fire(e);
|
|
428
407
|
});
|
|
429
408
|
}
|
|
430
409
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
410
|
+
/**
|
|
411
|
+
* Lazily acquires (and ref-counts) the shared {@link _watchHandle} for this repository, returning
|
|
412
|
+
* the handle plus a one-shot lease whose disposal decrements the ref count (releasing the handle
|
|
413
|
+
* when the last lease is gone). Returns `undefined` for repositories without a git directory.
|
|
414
|
+
*/
|
|
415
|
+
private acquireWatchHandle(): { handle: WatchHandle; lease: UnifiedDisposable } | undefined {
|
|
416
|
+
if (this._gitDir == null || this._disposed) return undefined;
|
|
437
417
|
|
|
438
418
|
this._watchHandle ??= this._watchService.watch(this.path, this._gitDir, {
|
|
439
419
|
onFetchHeadChanged: () => this.onFetchHeadChanged(),
|
|
440
420
|
onGitIgnoreChanged: () => this.onGitIgnoreChanged(),
|
|
441
421
|
onIgnoresChanged: () => this.onIgnoresChanged(),
|
|
442
422
|
} satisfies WatchHooks);
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
this.
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
423
|
+
const handle = this._watchHandle;
|
|
424
|
+
if (handle == null) return undefined;
|
|
425
|
+
|
|
426
|
+
this._watchHandleRefs++;
|
|
427
|
+
const lease = createDisposable(
|
|
428
|
+
() => {
|
|
429
|
+
// Repo already torn down — the handle is gone; skip to avoid a negative refcount
|
|
430
|
+
if (this._disposed) return;
|
|
431
|
+
|
|
432
|
+
if (--this._watchHandleRefs === 0) {
|
|
433
|
+
this._watchHandle?.dispose();
|
|
434
|
+
this._watchHandle = undefined;
|
|
435
|
+
}
|
|
436
|
+
},
|
|
437
|
+
{ once: true },
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
return { handle: handle, lease: lease };
|
|
450
441
|
}
|
|
451
442
|
|
|
452
443
|
static is(repository: unknown): repository is Repository {
|
|
@@ -94,6 +94,18 @@ export class GitStatusFile implements GitFile {
|
|
|
94
94
|
return this.conflictStatus != null;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* True when the file has both staged (index) and unstaged (working-tree) changes and is not
|
|
99
|
+
* conflicted. Used by the host-side discard flows to apply partial-discard semantics — drop the
|
|
100
|
+
* working-tree delta while preserving the staged portion. Centralized here so those host paths
|
|
101
|
+
* agree on what "mixed" means. (The webview button predicate can't consume this getter — it
|
|
102
|
+
* runs against the wire `GitFileChangeShape` and infers the same state from the duplicate
|
|
103
|
+
* staged/unstaged rows the WIP feed emits per mixed path.)
|
|
104
|
+
*/
|
|
105
|
+
get mixed(): boolean {
|
|
106
|
+
return this.indexStatus != null && this.workingTreeStatus != null && this.conflictStatus == null;
|
|
107
|
+
}
|
|
108
|
+
|
|
97
109
|
get staged(): boolean {
|
|
98
110
|
return this.indexStatus != null;
|
|
99
111
|
}
|
|
@@ -78,6 +78,10 @@ export interface GitCommitReachability {
|
|
|
78
78
|
export interface GitCommitsSubProvider {
|
|
79
79
|
getCommit(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<GitCommit | undefined>;
|
|
80
80
|
getCommitCount(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<number | undefined>;
|
|
81
|
+
/** Whether `rev` has any commits not reachable from any remote-tracking ref (i.e. unpushed/unpublished).
|
|
82
|
+
* Cheap early-exit probe (`rev-list --not --remotes <rev> -n 1`) — it does NOT count them. Returns
|
|
83
|
+
* `undefined` when it can't be determined. */
|
|
84
|
+
hasUnpublishedCommits?(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<boolean | undefined>;
|
|
81
85
|
/** Cheap author/committer date lookup for a single revision. Skips the full commit parse (no files, parents, or message) — use when only the dates are needed. Pass a full SHA so caching stays correct (commits are immutable; refs are not). */
|
|
82
86
|
getCommitDates?(
|
|
83
87
|
repoPath: string,
|
|
@@ -88,11 +88,7 @@ export interface GitConfigSubProvider {
|
|
|
88
88
|
| []
|
|
89
89
|
>;
|
|
90
90
|
|
|
91
|
-
getGkConfig?(
|
|
92
|
-
repoPath: string,
|
|
93
|
-
key: GkConfigKeys | DeprecatedGkConfigKeys,
|
|
94
|
-
options?: { type?: GitConfigType },
|
|
95
|
-
): Promise<string | undefined>;
|
|
91
|
+
getGkConfig?(repoPath: string, key: GkConfigKeys | DeprecatedGkConfigKeys): Promise<string | undefined>;
|
|
96
92
|
getGkConfigRegex?(repoPath: string, pattern: string): Promise<Map<string, string>>;
|
|
97
93
|
setGkConfig?(
|
|
98
94
|
repoPath: string,
|
|
@@ -21,31 +21,14 @@ export interface GitOperationResult {
|
|
|
21
21
|
export type GitOperationRunOptions = Pick<GitRunOptions, 'env' | 'cancellation' | 'timeout'>;
|
|
22
22
|
|
|
23
23
|
export interface GitOperationsSubProvider {
|
|
24
|
-
checkout(
|
|
25
|
-
repoPath: string,
|
|
26
|
-
ref: string,
|
|
27
|
-
options?: { createBranch?: string | undefined } | { path?: string | undefined },
|
|
28
|
-
runOptions?: GitOperationRunOptions,
|
|
29
|
-
): Promise<void>;
|
|
30
24
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
25
|
+
* Switches the repository to a branch or ref. Pure branch/ref switching — does not accept
|
|
26
|
+
* a path. For path-level operations use {@link restore}.
|
|
33
27
|
*/
|
|
34
|
-
|
|
35
|
-
repoPath: string,
|
|
36
|
-
path: string,
|
|
37
|
-
side: 'ours' | 'theirs',
|
|
38
|
-
runOptions?: GitOperationRunOptions,
|
|
39
|
-
): Promise<void>;
|
|
40
|
-
/**
|
|
41
|
-
* Checks out one side for multiple conflicted paths during a paused merge/rebase/cherry-pick.
|
|
42
|
-
* Batches paths into `git checkout --ours|--theirs -- <paths...>`, chunked to stay under the
|
|
43
|
-
* CLI length limit. Leaves files unstaged.
|
|
44
|
-
*/
|
|
45
|
-
checkoutConflictedPaths(
|
|
28
|
+
checkout(
|
|
46
29
|
repoPath: string,
|
|
47
|
-
|
|
48
|
-
|
|
30
|
+
ref: string,
|
|
31
|
+
options?: { createBranch?: string | undefined; noTracking?: boolean },
|
|
49
32
|
runOptions?: GitOperationRunOptions,
|
|
50
33
|
): Promise<void>;
|
|
51
34
|
cherryPick(
|
|
@@ -110,8 +93,24 @@ export interface GitOperationsSubProvider {
|
|
|
110
93
|
options?: {
|
|
111
94
|
autoStash?: boolean;
|
|
112
95
|
branch?: string;
|
|
96
|
+
/** Command set as `sequence.editor` — edits the interactive rebase todo list. */
|
|
113
97
|
editor?: string;
|
|
114
98
|
interactive?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Set when the `editor` is a script that rewrites the todo by command word + SHA (e.g. the
|
|
101
|
+
* Commit Graph's headless squash/drop/reword) rather than a human. Forces git to emit a plain,
|
|
102
|
+
* natural-order todo by disabling `rebase.autosquash` (which would reorder commits and rewrite
|
|
103
|
+
* `pick`→`fixup` for `fixup!`/`squash!` commits) and `rebase.abbreviateCommands` (which would
|
|
104
|
+
* emit `p` instead of `pick`). Both honor the user's git config otherwise.
|
|
105
|
+
*/
|
|
106
|
+
programmaticEditor?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Command git uses to edit per-commit messages (the combined message a `squash` produces, or a
|
|
109
|
+
* `reword`). Applied as `GIT_EDITOR` — which git's interactive-rebase `reword`/`squash` step honors,
|
|
110
|
+
* unlike `core.editor` — with `core.editor` also set as a fallback. When omitted, git falls back to
|
|
111
|
+
* the user's configured editor.
|
|
112
|
+
*/
|
|
113
|
+
messageEditor?: string;
|
|
115
114
|
onto?: string;
|
|
116
115
|
updateRefs?: boolean;
|
|
117
116
|
source?: unknown;
|
|
@@ -124,6 +123,27 @@ export interface GitOperationsSubProvider {
|
|
|
124
123
|
options?: { mode?: 'hard' | 'keep' | 'merge' | 'mixed' | 'soft' },
|
|
125
124
|
runOptions?: GitOperationRunOptions,
|
|
126
125
|
): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Restores the working-tree copy of one or more paths. Single path or array; arrays are
|
|
128
|
+
* chunked under the CLI length limit and dispatched as one git invocation per chunk
|
|
129
|
+
* (typically one for normal-sized batches).
|
|
130
|
+
*
|
|
131
|
+
* Source selection — `options` is mutually exclusive (`side` wins if both are supplied):
|
|
132
|
+
*
|
|
133
|
+
* - **No options** (`git checkout -- <paths>`): copies the index to the working tree, leaving
|
|
134
|
+
* the index untouched. Use to drop unstaged changes (mixed-file partial discard preserves
|
|
135
|
+
* the staged portion this way).
|
|
136
|
+
* - **`{ ref }`** (`git checkout <ref> -- <paths>`): resets BOTH the index and the working
|
|
137
|
+
* tree of the path(s) to `<ref>`. Use to fully revert files to HEAD, a specific commit, etc.
|
|
138
|
+
* - **`{ side }`** (`git checkout --ours|--theirs -- <paths>`): conflict-resolution
|
|
139
|
+
* shortcut, valid only during a paused merge/rebase/cherry-pick. Leaves files unstaged.
|
|
140
|
+
*/
|
|
141
|
+
restore(
|
|
142
|
+
repoPath: string,
|
|
143
|
+
path: string | string[],
|
|
144
|
+
options?: { ref?: string; side?: 'ours' | 'theirs' },
|
|
145
|
+
runOptions?: GitOperationRunOptions,
|
|
146
|
+
): Promise<void>;
|
|
127
147
|
revert(
|
|
128
148
|
repoPath: string,
|
|
129
149
|
refs: string[],
|
|
@@ -5,12 +5,24 @@ export interface GitWorktreesSubProvider {
|
|
|
5
5
|
createWorktree(
|
|
6
6
|
repoPath: string,
|
|
7
7
|
path: string,
|
|
8
|
-
options?: {
|
|
8
|
+
options?: {
|
|
9
|
+
commitish?: string;
|
|
10
|
+
createBranch?: string;
|
|
11
|
+
detach?: boolean;
|
|
12
|
+
force?: boolean;
|
|
13
|
+
noTracking?: boolean;
|
|
14
|
+
},
|
|
9
15
|
): Promise<void>;
|
|
10
16
|
createWorktreeWithResult(
|
|
11
17
|
repoPath: string,
|
|
12
18
|
path: string,
|
|
13
|
-
options?: {
|
|
19
|
+
options?: {
|
|
20
|
+
commitish?: string;
|
|
21
|
+
createBranch?: string;
|
|
22
|
+
detach?: boolean;
|
|
23
|
+
force?: boolean;
|
|
24
|
+
noTracking?: boolean;
|
|
25
|
+
},
|
|
14
26
|
): Promise<GitWorktree | undefined>;
|
|
15
27
|
getWorktree(
|
|
16
28
|
repoPath: string,
|
|
@@ -35,6 +35,29 @@ export class CustomRemoteProvider extends RemoteProvider {
|
|
|
35
35
|
return [];
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
get avatarUrlTemplate(): string | undefined {
|
|
39
|
+
return this.urls.avatar;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getUrlForAvatar(email: string, size: number): string | undefined {
|
|
43
|
+
if (this.urls.avatar == null) return undefined;
|
|
44
|
+
|
|
45
|
+
// Split on the last `@` so local-parts that contain `@` are preserved (per RFC 5322)
|
|
46
|
+
const at = email.lastIndexOf('@');
|
|
47
|
+
const emailName = at === -1 ? email : email.slice(0, at);
|
|
48
|
+
const domain = at === -1 ? '' : email.slice(at + 1);
|
|
49
|
+
|
|
50
|
+
// Component-encode identity values — commit emails are attacker-controllable and
|
|
51
|
+
// must never be able to inject URL-structural characters (`/`, `?`, `#`, ...) into the
|
|
52
|
+
// resulting URL
|
|
53
|
+
return interpolate(this.urls.avatar, {
|
|
54
|
+
email: encodeURIComponent(email),
|
|
55
|
+
emailName: encodeURIComponent(emailName),
|
|
56
|
+
domain: encodeURIComponent(domain),
|
|
57
|
+
size: String(size),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
38
61
|
protected override getUrlForRepository(): string {
|
|
39
62
|
return this.getUrl(this.urls.repository, this.getContext());
|
|
40
63
|
}
|
|
@@ -2,6 +2,71 @@ import type { GitFileConflictStatus } from '../models/fileStatus.js';
|
|
|
2
2
|
|
|
3
3
|
export type ConflictResolutionAction = 'take-ours' | 'take-theirs' | 'delete' | 'unsupported';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* A richer description of a conflict than the raw XY status code — used to label conflicts the
|
|
7
|
+
* AI text resolver can't parse (binary, symlink, submodule, mode-only, add/add) and to surface
|
|
8
|
+
* rename conflicts. Derived by {@link classifyConflictKind} from the XY status plus, when
|
|
9
|
+
* available, the per-stage file modes/oids and rename/binary hints the caller computes.
|
|
10
|
+
*/
|
|
11
|
+
export type ConflictKind =
|
|
12
|
+
| 'text'
|
|
13
|
+
| 'binary'
|
|
14
|
+
| 'symlink'
|
|
15
|
+
| 'submodule'
|
|
16
|
+
| 'mode-only'
|
|
17
|
+
| 'add-add'
|
|
18
|
+
| 'delete-modify'
|
|
19
|
+
| 'both-deleted'
|
|
20
|
+
| 'rename-rename'
|
|
21
|
+
| 'rename-delete'
|
|
22
|
+
| 'rename-modify'
|
|
23
|
+
| 'unknown';
|
|
24
|
+
|
|
25
|
+
export type ConflictRenameKind = 'rename-rename' | 'rename-delete' | 'rename-modify';
|
|
26
|
+
|
|
27
|
+
const symlinkMode = '120000';
|
|
28
|
+
const submoduleMode = '160000';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Classifies a conflict into a {@link ConflictKind}. Pure — all detection that needs git/IO
|
|
32
|
+
* (rename correlation, binary sniffing) is computed by the caller and passed via `hints`. When
|
|
33
|
+
* `modes`/`oids` are omitted (e.g. a webview caller that only has the XY status), it still returns
|
|
34
|
+
* a useful coarse kind; pass the per-stage data for the fine-grained symlink/submodule/mode-only split.
|
|
35
|
+
*/
|
|
36
|
+
export function classifyConflictKind(
|
|
37
|
+
status: GitFileConflictStatus,
|
|
38
|
+
modes?: { base?: string; current?: string; incoming?: string },
|
|
39
|
+
oids?: { base?: string; current?: string; incoming?: string },
|
|
40
|
+
hints?: { binary?: boolean; rename?: ConflictRenameKind },
|
|
41
|
+
): ConflictKind {
|
|
42
|
+
if (hints?.rename != null) return hints.rename;
|
|
43
|
+
|
|
44
|
+
if (status === 'DD') return 'both-deleted';
|
|
45
|
+
if (status === 'UD' || status === 'DU') return 'delete-modify';
|
|
46
|
+
|
|
47
|
+
const presentModes = [modes?.current, modes?.incoming, modes?.base].filter((m): m is string => m != null);
|
|
48
|
+
if (presentModes.includes(submoduleMode)) return 'submodule';
|
|
49
|
+
if (presentModes.includes(symlinkMode)) return 'symlink';
|
|
50
|
+
|
|
51
|
+
if (hints?.binary) return 'binary';
|
|
52
|
+
|
|
53
|
+
// Both sides present with identical content (same oid) but different mode → only the file mode
|
|
54
|
+
// conflicts (e.g. one side flipped the executable bit).
|
|
55
|
+
if (
|
|
56
|
+
modes?.current != null &&
|
|
57
|
+
modes?.incoming != null &&
|
|
58
|
+
modes.current !== modes.incoming &&
|
|
59
|
+
oids?.current != null &&
|
|
60
|
+
oids.current === oids?.incoming
|
|
61
|
+
) {
|
|
62
|
+
return 'mode-only';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (status === 'AA' || status === 'AU' || status === 'UA') return 'add-add';
|
|
66
|
+
|
|
67
|
+
return 'text';
|
|
68
|
+
}
|
|
69
|
+
|
|
5
70
|
export function classifyConflictAction(
|
|
6
71
|
status: GitFileConflictStatus,
|
|
7
72
|
resolution: 'current' | 'incoming',
|
|
@@ -29,3 +94,64 @@ export function canStageCurrent(status: GitFileConflictStatus): boolean {
|
|
|
29
94
|
export function canStageIncoming(status: GitFileConflictStatus): boolean {
|
|
30
95
|
return status !== 'AU' && status !== 'DD';
|
|
31
96
|
}
|
|
97
|
+
|
|
98
|
+
/** A short label + one-line description for a {@link ConflictKind}, used to explain conflicts the AI
|
|
99
|
+
* resolver can't auto-merge (and rename conflicts) wherever they're surfaced. */
|
|
100
|
+
export function getConflictKindLabel(kind: ConflictKind, renameOf?: string): { label: string; description: string } {
|
|
101
|
+
const named = renameOf ? `"${renameOf}"` : 'The file';
|
|
102
|
+
switch (kind) {
|
|
103
|
+
case 'binary':
|
|
104
|
+
return {
|
|
105
|
+
label: 'Binary conflict',
|
|
106
|
+
description: 'Binary file changed on both sides — choose a side to keep',
|
|
107
|
+
};
|
|
108
|
+
case 'symlink':
|
|
109
|
+
return {
|
|
110
|
+
label: 'Symlink conflict',
|
|
111
|
+
description: 'Symbolic link changed on both sides — choose a side to keep',
|
|
112
|
+
};
|
|
113
|
+
case 'submodule':
|
|
114
|
+
return {
|
|
115
|
+
label: 'Submodule conflict',
|
|
116
|
+
description: 'Submodule reference changed on both sides — choose a side to keep',
|
|
117
|
+
};
|
|
118
|
+
case 'mode-only':
|
|
119
|
+
return {
|
|
120
|
+
label: 'File mode conflict',
|
|
121
|
+
description: 'Only the file mode differs (e.g. the executable bit) — choose a side to keep',
|
|
122
|
+
};
|
|
123
|
+
case 'add-add':
|
|
124
|
+
// Covers AA (added on both sides) as well as AU/UA (added on one side) — keep the wording
|
|
125
|
+
// accurate for all three rather than asserting "both sides".
|
|
126
|
+
return {
|
|
127
|
+
label: 'Add conflict',
|
|
128
|
+
description: 'Conflicting file additions — choose a side to keep',
|
|
129
|
+
};
|
|
130
|
+
case 'delete-modify':
|
|
131
|
+
return {
|
|
132
|
+
label: 'Modified and deleted',
|
|
133
|
+
description: 'Deleted on one side and modified on the other — keep the file or delete it',
|
|
134
|
+
};
|
|
135
|
+
case 'both-deleted':
|
|
136
|
+
return { label: 'Deleted on both sides', description: 'Deleted on both sides — confirm the deletion' };
|
|
137
|
+
case 'rename-rename':
|
|
138
|
+
return {
|
|
139
|
+
label: 'Renamed differently',
|
|
140
|
+
description: `${named} was renamed differently on each side — choose which name to keep`,
|
|
141
|
+
};
|
|
142
|
+
case 'rename-delete':
|
|
143
|
+
return {
|
|
144
|
+
label: 'Renamed and deleted',
|
|
145
|
+
description: `${named} was renamed on one side and deleted on the other — keep the file or delete it`,
|
|
146
|
+
};
|
|
147
|
+
case 'rename-modify':
|
|
148
|
+
return {
|
|
149
|
+
label: 'Renamed and modified',
|
|
150
|
+
description: `${named} was renamed on one side and modified on the other`,
|
|
151
|
+
};
|
|
152
|
+
case 'text':
|
|
153
|
+
return { label: 'Text conflict', description: 'Conflicting changes on both sides' };
|
|
154
|
+
default:
|
|
155
|
+
return { label: 'Conflict', description: 'Resolve this conflict manually' };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -79,3 +79,27 @@ export function calculateDistribution<T extends string>(
|
|
|
79
79
|
export function matchContributor(c: GitContributor, user: GitUser): boolean {
|
|
80
80
|
return c.name === user.name && c.email === user.email && c.username === user.username;
|
|
81
81
|
}
|
|
82
|
+
|
|
83
|
+
/** Appends `Co-authored-by:` trailers for the given coauthors to a commit message, replacing
|
|
84
|
+
* any existing trailer block. Each coauthor is the `Name <email>` form (GitContributor.coauthor). */
|
|
85
|
+
export function appendCoauthorsToMessage(message: string, coauthors: Iterable<string>): string {
|
|
86
|
+
const index = message.indexOf('Co-authored-by: ');
|
|
87
|
+
if (index !== -1) {
|
|
88
|
+
message = message.substring(0, index - 1).trimEnd();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
for (const coauthor of coauthors) {
|
|
92
|
+
let newlines;
|
|
93
|
+
if (message.includes('Co-authored-by: ')) {
|
|
94
|
+
newlines = '\n';
|
|
95
|
+
} else if (message.length !== 0 && message.endsWith('\n')) {
|
|
96
|
+
newlines = '\n\n';
|
|
97
|
+
} else {
|
|
98
|
+
newlines = '\n\n\n';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
message += `${newlines}Co-authored-by: ${coauthor}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return message;
|
|
105
|
+
}
|