@gitkraken/core-gitlens 0.5.109 → 0.5.111
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 +48 -1
- package/dist/git/cache.d.ts +111 -6
- package/dist/git/cache.d.ts.map +1 -1
- package/dist/git/cache.js +312 -43
- package/dist/git/cache.js.map +1 -1
- package/dist/git/context.d.ts +11 -0
- package/dist/git/context.d.ts.map +1 -1
- package/dist/git/context.js.map +1 -1
- package/dist/git/models/fileStatus.d.ts +1 -0
- package/dist/git/models/fileStatus.d.ts.map +1 -1
- package/dist/git/models/fileStatus.js +1 -0
- package/dist/git/models/fileStatus.js.map +1 -1
- package/dist/git/models/issue.d.ts +4 -0
- package/dist/git/models/issue.d.ts.map +1 -1
- package/dist/git/models/mergeConflicts.d.ts +2 -0
- package/dist/git/models/mergeConflicts.d.ts.map +1 -1
- package/dist/git/models/pullRequest.d.ts +119 -2
- package/dist/git/models/pullRequest.d.ts.map +1 -1
- package/dist/git/models/pullRequest.js +27 -1
- package/dist/git/models/pullRequest.js.map +1 -1
- package/dist/git/models/repository.d.ts +32 -5
- package/dist/git/models/repository.d.ts.map +1 -1
- package/dist/git/models/repository.js +58 -12
- package/dist/git/models/repository.js.map +1 -1
- package/dist/git/models/statusFile.d.ts.map +1 -1
- package/dist/git/models/statusFile.js +3 -0
- package/dist/git/models/statusFile.js.map +1 -1
- package/dist/git/providers/branches.d.ts +2 -0
- package/dist/git/providers/branches.d.ts.map +1 -1
- package/dist/git/providers/commits.d.ts +8 -0
- package/dist/git/providers/commits.d.ts.map +1 -1
- package/dist/git/providers/config.d.ts +19 -1
- package/dist/git/providers/config.d.ts.map +1 -1
- package/dist/git/providers/operations.d.ts +1 -0
- package/dist/git/providers/operations.d.ts.map +1 -1
- package/dist/git/providers/pausedOperations.d.ts +2 -0
- package/dist/git/providers/pausedOperations.d.ts.map +1 -1
- package/dist/git/providers/status.d.ts +1 -0
- package/dist/git/providers/status.d.ts.map +1 -1
- package/dist/git/utils/config.utils.d.ts +3 -0
- package/dist/git/utils/config.utils.d.ts.map +1 -0
- package/dist/git/utils/config.utils.js +8 -0
- package/dist/git/utils/config.utils.js.map +1 -0
- package/dist/git/utils/issue.utils.d.ts.map +1 -1
- package/dist/git/utils/issue.utils.js +2 -0
- package/dist/git/utils/issue.utils.js.map +1 -1
- package/dist/git/utils/pausedOperationStatus.utils.d.ts +14 -0
- package/dist/git/utils/pausedOperationStatus.utils.d.ts.map +1 -1
- package/dist/git/utils/pausedOperationStatus.utils.js +23 -0
- package/dist/git/utils/pausedOperationStatus.utils.js.map +1 -1
- package/dist/git/utils/pullRequest.utils.d.ts +24 -1
- package/dist/git/utils/pullRequest.utils.d.ts.map +1 -1
- package/dist/git/utils/pullRequest.utils.js +71 -0
- package/dist/git/utils/pullRequest.utils.js.map +1 -1
- package/dist/git/watching/changeEvent.d.ts +6 -1
- package/dist/git/watching/changeEvent.d.ts.map +1 -1
- package/dist/git/watching/classifyChange.d.ts.map +1 -1
- package/dist/git/watching/classifyChange.js +14 -1
- package/dist/git/watching/classifyChange.js.map +1 -1
- package/dist/git/watching/watchService.d.ts.map +1 -1
- package/dist/git/watching/watchService.js +18 -3
- package/dist/git/watching/watchService.js.map +1 -1
- package/dist/git/watching/watchSession.d.ts +8 -1
- package/dist/git/watching/watchSession.d.ts.map +1 -1
- package/dist/git/watching/watchSession.js +38 -6
- package/dist/git/watching/watchSession.js.map +1 -1
- package/dist/git/watching/watcherPatterns.d.ts +2 -2
- package/dist/git/watching/watcherPatterns.d.ts.map +1 -1
- package/dist/git/watching/watcherPatterns.js +1 -1
- package/dist/git/watching/watcherPatterns.js.map +1 -1
- package/dist/git-cli/exec/git.d.ts +1 -1
- package/dist/git-cli/exec/git.d.ts.map +1 -1
- package/dist/git-cli/exec/git.js +13 -3
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/providers/branches.d.ts +19 -0
- package/dist/git-cli/providers/branches.d.ts.map +1 -1
- package/dist/git-cli/providers/branches.js +282 -78
- package/dist/git-cli/providers/branches.js.map +1 -1
- package/dist/git-cli/providers/commits.d.ts +4 -0
- package/dist/git-cli/providers/commits.d.ts.map +1 -1
- package/dist/git-cli/providers/commits.js +84 -11
- package/dist/git-cli/providers/commits.js.map +1 -1
- package/dist/git-cli/providers/config.d.ts +42 -0
- package/dist/git-cli/providers/config.d.ts.map +1 -1
- package/dist/git-cli/providers/config.js +186 -5
- package/dist/git-cli/providers/config.js.map +1 -1
- package/dist/git-cli/providers/contributors.d.ts.map +1 -1
- package/dist/git-cli/providers/contributors.js +1 -1
- package/dist/git-cli/providers/contributors.js.map +1 -1
- package/dist/git-cli/providers/graph.d.ts +2 -2
- package/dist/git-cli/providers/graph.d.ts.map +1 -1
- package/dist/git-cli/providers/graph.js +27 -9
- package/dist/git-cli/providers/graph.js.map +1 -1
- package/dist/git-cli/providers/operations.d.ts.map +1 -1
- package/dist/git-cli/providers/operations.js +40 -12
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/pausedOperations.d.ts +5 -0
- package/dist/git-cli/providers/pausedOperations.d.ts.map +1 -1
- package/dist/git-cli/providers/pausedOperations.js +87 -16
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/refs.d.ts +5 -3
- package/dist/git-cli/providers/refs.d.ts.map +1 -1
- package/dist/git-cli/providers/refs.js +33 -4
- package/dist/git-cli/providers/refs.js.map +1 -1
- package/dist/git-cli/providers/status.d.ts +1 -0
- package/dist/git-cli/providers/status.d.ts.map +1 -1
- package/dist/git-cli/providers/status.js +18 -3
- package/dist/git-cli/providers/status.js.map +1 -1
- package/dist/git-cli/providers/worktrees.d.ts.map +1 -1
- package/dist/git-cli/providers/worktrees.js +4 -0
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/git-cli/service.d.ts.map +1 -1
- package/dist/git-cli/service.js.map +1 -1
- package/dist/plus/agents/providers/claudeCodeProvider.d.ts +39 -1
- package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -1
- package/dist/plus/agents/providers/claudeCodeProvider.js +978 -71
- package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -1
- package/dist/plus/agents/providers/claudeCodeTranscript.d.ts +24 -2
- package/dist/plus/agents/providers/claudeCodeTranscript.d.ts.map +1 -1
- package/dist/plus/agents/providers/claudeCodeTranscript.js +84 -9
- package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
- package/dist/plus/agents/types.d.ts +37 -2
- package/dist/plus/agents/types.d.ts.map +1 -1
- package/dist/plus/agents/types.js +2 -0
- package/dist/plus/agents/types.js.map +1 -1
- package/dist/plus/ai/errors.d.ts +10 -0
- package/dist/plus/ai/errors.d.ts.map +1 -1
- package/dist/plus/ai/errors.js +29 -0
- package/dist/plus/ai/errors.js.map +1 -1
- package/dist/plus/ai/models/model.d.ts +4 -0
- package/dist/plus/ai/models/model.d.ts.map +1 -1
- package/dist/plus/ai/models/model.js +51 -6
- package/dist/plus/ai/models/model.js.map +1 -1
- package/dist/plus/ai/models/promptTemplates.d.ts +1 -1
- package/dist/plus/ai/models/promptTemplates.d.ts.map +1 -1
- package/dist/plus/ai/models/provider.d.ts +60 -2
- package/dist/plus/ai/models/provider.d.ts.map +1 -1
- package/dist/plus/ai/prompts.d.ts +12 -0
- package/dist/plus/ai/prompts.d.ts.map +1 -1
- package/dist/plus/ai/prompts.js +177 -61
- package/dist/plus/ai/prompts.js.map +1 -1
- package/dist/plus/ai/providers/anthropicProvider.d.ts +10 -2
- package/dist/plus/ai/providers/anthropicProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/anthropicProvider.js +139 -46
- package/dist/plus/ai/providers/anthropicProvider.js.map +1 -1
- package/dist/plus/ai/providers/deepSeekProvider.d.ts +2 -0
- package/dist/plus/ai/providers/deepSeekProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/deepSeekProvider.js +10 -21
- package/dist/plus/ai/providers/deepSeekProvider.js.map +1 -1
- package/dist/plus/ai/providers/geminiProvider.d.ts +1 -0
- package/dist/plus/ai/providers/geminiProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/geminiProvider.js +19 -0
- package/dist/plus/ai/providers/geminiProvider.js.map +1 -1
- package/dist/plus/ai/providers/gitkrakenProvider.d.ts +5 -1
- package/dist/plus/ai/providers/gitkrakenProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/gitkrakenProvider.js +118 -3
- package/dist/plus/ai/providers/gitkrakenProvider.js.map +1 -1
- package/dist/plus/ai/providers/huggingFaceProvider.d.ts +1 -0
- package/dist/plus/ai/providers/huggingFaceProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/huggingFaceProvider.js +5 -0
- package/dist/plus/ai/providers/huggingFaceProvider.js.map +1 -1
- package/dist/plus/ai/providers/mistralProvider.d.ts +3 -1
- package/dist/plus/ai/providers/mistralProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/mistralProvider.js +99 -19
- package/dist/plus/ai/providers/mistralProvider.js.map +1 -1
- package/dist/plus/ai/providers/ollamaProvider.d.ts +4 -3
- package/dist/plus/ai/providers/ollamaProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/ollamaProvider.js +38 -3
- package/dist/plus/ai/providers/ollamaProvider.js.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProvider.d.ts +1 -0
- package/dist/plus/ai/providers/openAICompatibleProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProvider.js +4 -0
- package/dist/plus/ai/providers/openAICompatibleProvider.js.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts +154 -5
- package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts.map +1 -1
- package/dist/plus/ai/providers/openAICompatibleProviderBase.js +259 -10
- package/dist/plus/ai/providers/openAICompatibleProviderBase.js.map +1 -1
- package/dist/plus/ai/providers/openRouterProvider.d.ts +4 -0
- package/dist/plus/ai/providers/openRouterProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/openRouterProvider.js +9 -0
- package/dist/plus/ai/providers/openRouterProvider.js.map +1 -1
- package/dist/plus/ai/providers/openaiProvider.d.ts +1 -0
- package/dist/plus/ai/providers/openaiProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/openaiProvider.js +1 -0
- package/dist/plus/ai/providers/openaiProvider.js.map +1 -1
- package/dist/plus/ai/providers/responseFormatCache.d.ts +8 -0
- package/dist/plus/ai/providers/responseFormatCache.d.ts.map +1 -0
- package/dist/plus/ai/providers/responseFormatCache.js +25 -0
- package/dist/plus/ai/providers/responseFormatCache.js.map +1 -0
- package/dist/plus/ai/providers/xaiProvider.d.ts +1 -0
- package/dist/plus/ai/providers/xaiProvider.d.ts.map +1 -1
- package/dist/plus/ai/providers/xaiProvider.js +10 -1
- package/dist/plus/ai/providers/xaiProvider.js.map +1 -1
- package/dist/plus/ai/utils/ai.utils.d.ts +3 -0
- package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
- package/dist/plus/ai/utils/ai.utils.js +13 -0
- package/dist/plus/ai/utils/ai.utils.js.map +1 -1
- package/dist/plus/ai/utils/results.utils.d.ts +16 -2
- package/dist/plus/ai/utils/results.utils.d.ts.map +1 -1
- package/dist/plus/ai/utils/results.utils.js +204 -28
- package/dist/plus/ai/utils/results.utils.js.map +1 -1
- package/dist/plus/git-github/api/github.d.ts +92 -4
- package/dist/plus/git-github/api/github.d.ts.map +1 -1
- package/dist/plus/git-github/api/github.js +324 -20
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/git-github/api/pullRequestSearchQuery.d.ts +27 -1
- package/dist/plus/git-github/api/pullRequestSearchQuery.d.ts.map +1 -1
- package/dist/plus/git-github/api/pullRequestSearchQuery.js +73 -6
- package/dist/plus/git-github/api/pullRequestSearchQuery.js.map +1 -1
- package/dist/plus/git-github/models.d.ts +33 -5
- package/dist/plus/git-github/models.d.ts.map +1 -1
- package/dist/plus/git-github/models.js +43 -4
- package/dist/plus/git-github/models.js.map +1 -1
- package/dist/plus/git-github/providers/github/status.d.ts +1 -0
- package/dist/plus/git-github/providers/github/status.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/status.js.map +1 -1
- package/dist/plus/integrations/context.d.ts +4 -0
- package/dist/plus/integrations/context.d.ts.map +1 -1
- package/dist/plus/integrations/index.d.ts.map +1 -1
- package/dist/plus/integrations/index.js +2 -0
- package/dist/plus/integrations/index.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +16 -1
- package/dist/plus/integrations/integrationService.d.ts.map +1 -1
- package/dist/plus/integrations/integrationService.js +9 -1
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/manager.d.ts +45 -5
- package/dist/plus/integrations/manager.d.ts.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +18 -3
- package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.js +30 -2
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +4 -2
- package/dist/plus/integrations/models/integration.d.ts.map +1 -1
- package/dist/plus/integrations/models/integration.js +2 -2
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/providerFilters.d.ts +1 -1
- package/dist/plus/integrations/providerFilters.d.ts.map +1 -1
- package/dist/plus/integrations/providers/accounts.d.ts +6 -0
- package/dist/plus/integrations/providers/accounts.d.ts.map +1 -0
- package/dist/plus/integrations/providers/accounts.js +34 -0
- package/dist/plus/integrations/providers/accounts.js.map +1 -0
- package/dist/plus/integrations/providers/azure/models.d.ts.map +1 -1
- package/dist/plus/integrations/providers/azure/models.js +3 -0
- package/dist/plus/integrations/providers/azure/models.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket/models.d.ts.map +1 -1
- package/dist/plus/integrations/providers/bitbucket/models.js +1 -0
- package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -1
- package/dist/plus/integrations/providers/github.d.ts +23 -2
- package/dist/plus/integrations/providers/github.d.ts.map +1 -1
- package/dist/plus/integrations/providers/github.js +169 -138
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.d.ts +9 -0
- package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -1
- package/dist/plus/integrations/providers/gitlab.js +23 -4
- package/dist/plus/integrations/providers/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/models.d.ts +14 -32
- package/dist/plus/integrations/providers/models.d.ts.map +1 -1
- package/dist/plus/integrations/providers/models.js +66 -109
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/pullRequestReviews.d.ts +50 -0
- package/dist/plus/integrations/providers/pullRequestReviews.d.ts.map +1 -0
- package/dist/plus/integrations/providers/pullRequestReviews.js +99 -0
- package/dist/plus/integrations/providers/pullRequestReviews.js.map +1 -0
- package/dist/plus/integrations/reads/broaden.d.ts.map +1 -1
- package/dist/plus/integrations/reads/broaden.js +6 -1
- package/dist/plus/integrations/reads/broaden.js.map +1 -1
- package/dist/plus/integrations/reads/counts.d.ts +55 -0
- package/dist/plus/integrations/reads/counts.d.ts.map +1 -1
- package/dist/plus/integrations/reads/counts.js +146 -2
- package/dist/plus/integrations/reads/counts.js.map +1 -1
- package/dist/plus/integrations/reads/drains.d.ts +7 -1
- package/dist/plus/integrations/reads/drains.d.ts.map +1 -1
- package/dist/plus/integrations/reads/drains.js +20 -6
- package/dist/plus/integrations/reads/drains.js.map +1 -1
- package/dist/plus/integrations/reads/filters.d.ts.map +1 -1
- package/dist/plus/integrations/reads/filters.js +22 -0
- package/dist/plus/integrations/reads/filters.js.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.d.ts.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.js +3 -1
- package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.d.ts.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +8 -3
- package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
- package/dist/plus/integrations/reads/issues.d.ts.map +1 -1
- package/dist/plus/integrations/reads/issues.js +9 -4
- package/dist/plus/integrations/reads/issues.js.map +1 -1
- package/dist/plus/integrations/reads/pullRequests.d.ts.map +1 -1
- package/dist/plus/integrations/reads/pullRequests.js +9 -4
- package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
- package/dist/plus/integrations/reads/searchPullRequests.d.ts +4 -3
- package/dist/plus/integrations/reads/searchPullRequests.d.ts.map +1 -1
- package/dist/plus/integrations/reads/searchPullRequests.js +6 -4
- package/dist/plus/integrations/reads/searchPullRequests.js.map +1 -1
- package/dist/plus/integrations/reads/sweeps.js +1 -1
- package/dist/plus/integrations/reads/sweeps.js.map +1 -1
- package/dist/plus/integrations/reads/warnings.d.ts +2 -2
- package/dist/plus/integrations/reads/warnings.d.ts.map +1 -1
- package/dist/plus/integrations/reads/warnings.js +11 -2
- package/dist/plus/integrations/reads/warnings.js.map +1 -1
- package/dist/plus/integrations/results.d.ts +6 -1
- package/dist/plus/integrations/results.d.ts.map +1 -1
- package/dist/plus/integrations/results.js.map +1 -1
- package/dist/utils/env/browser/base64.d.ts +1 -1
- package/dist/utils/env/browser/base64.d.ts.map +1 -1
- package/dist/utils/env/node/base64.d.ts +1 -1
- package/dist/utils/env/node/base64.d.ts.map +1 -1
- package/dist/utils/env/node/base64.js +2 -0
- package/dist/utils/env/node/base64.js.map +1 -1
- package/dist/utils/keys/chord.d.ts +52 -0
- package/dist/utils/keys/chord.d.ts.map +1 -0
- package/dist/utils/keys/chord.js +135 -0
- package/dist/utils/keys/chord.js.map +1 -0
- package/dist/utils/keys/keybinding.d.ts +53 -0
- package/dist/utils/keys/keybinding.d.ts.map +1 -0
- package/dist/utils/keys/keybinding.js +58 -0
- package/dist/utils/keys/keybinding.js.map +1 -0
- package/dist/utils/path.d.ts +11 -0
- package/dist/utils/path.d.ts.map +1 -1
- package/dist/utils/path.js +13 -0
- package/dist/utils/path.js.map +1 -1
- package/docs/integrations.md +76 -10
- package/docs/kepler-read-api-parity.md +9 -0
- package/package.json +13 -5
- package/src/git/cache.ts +383 -47
- package/src/git/context.ts +11 -0
- package/src/git/models/fileStatus.ts +1 -0
- package/src/git/models/issue.ts +4 -0
- package/src/git/models/mergeConflicts.ts +3 -2
- package/src/git/models/pullRequest.ts +117 -1
- package/src/git/models/repository.ts +58 -17
- package/src/git/models/statusFile.ts +3 -0
- package/src/git/providers/branches.ts +6 -0
- package/src/git/providers/commits.ts +11 -0
- package/src/git/providers/config.ts +18 -0
- package/src/git/providers/operations.ts +1 -0
- package/src/git/providers/pausedOperations.ts +2 -0
- package/src/git/providers/status.ts +1 -0
- package/src/git/utils/config.utils.ts +8 -0
- package/src/git/utils/issue.utils.ts +2 -0
- package/src/git/utils/pausedOperationStatus.utils.ts +28 -0
- package/src/git/utils/pullRequest.utils.ts +86 -0
- package/src/git/watching/changeEvent.ts +6 -1
- package/src/git/watching/classifyChange.ts +15 -1
- package/src/git/watching/watchService.ts +20 -3
- package/src/git/watching/watchSession.ts +41 -6
- package/src/git/watching/watcherPatterns.ts +1 -1
- package/src/git-cli/exec/git.ts +13 -3
- package/src/git-cli/providers/branches.ts +384 -132
- package/src/git-cli/providers/commits.ts +106 -15
- package/src/git-cli/providers/config.ts +229 -8
- package/src/git-cli/providers/contributors.ts +5 -1
- package/src/git-cli/providers/graph.ts +26 -13
- package/src/git-cli/providers/operations.ts +45 -20
- package/src/git-cli/providers/pausedOperations.ts +109 -17
- package/src/git-cli/providers/refs.ts +33 -3
- package/src/git-cli/providers/status.ts +25 -4
- package/src/git-cli/providers/worktrees.ts +5 -0
- package/src/git-cli/service.ts +0 -1
- package/src/plus/agents/providers/claudeCodeProvider.ts +1130 -87
- package/src/plus/agents/providers/claudeCodeTranscript.ts +95 -9
- package/src/plus/agents/types.ts +46 -2
- package/src/plus/ai/errors.ts +30 -0
- package/src/plus/ai/models/model.ts +56 -6
- package/src/plus/ai/models/promptTemplates.ts +1 -1
- package/src/plus/ai/models/provider.ts +69 -2
- package/src/plus/ai/prompts.ts +186 -61
- package/src/plus/ai/providers/anthropicProvider.ts +155 -47
- package/src/plus/ai/providers/deepSeekProvider.ts +11 -21
- package/src/plus/ai/providers/geminiProvider.ts +19 -0
- package/src/plus/ai/providers/gitkrakenProvider.ts +126 -3
- package/src/plus/ai/providers/huggingFaceProvider.ts +6 -0
- package/src/plus/ai/providers/mistralProvider.ts +102 -19
- package/src/plus/ai/providers/ollamaProvider.ts +55 -4
- package/src/plus/ai/providers/openAICompatibleProvider.ts +5 -0
- package/src/plus/ai/providers/openAICompatibleProviderBase.ts +360 -17
- package/src/plus/ai/providers/openRouterProvider.ts +17 -0
- package/src/plus/ai/providers/openaiProvider.ts +1 -0
- package/src/plus/ai/providers/responseFormatCache.ts +39 -0
- package/src/plus/ai/providers/xaiProvider.ts +10 -1
- package/src/plus/ai/utils/ai.utils.ts +14 -0
- package/src/plus/ai/utils/results.utils.ts +255 -31
- package/src/plus/git-github/api/github.ts +467 -23
- package/src/plus/git-github/api/pullRequestSearchQuery.ts +81 -7
- package/src/plus/git-github/models.ts +77 -7
- package/src/plus/git-github/providers/github/status.ts +1 -0
- package/src/plus/integrations/context.ts +4 -0
- package/src/plus/integrations/index.ts +2 -0
- package/src/plus/integrations/integrationService.ts +25 -2
- package/src/plus/integrations/manager.ts +50 -5
- package/src/plus/integrations/models/gitHostIntegration.ts +54 -2
- package/src/plus/integrations/models/integration.ts +24 -13
- package/src/plus/integrations/providerFilters.ts +6 -1
- package/src/plus/integrations/providers/accounts.ts +38 -0
- package/src/plus/integrations/providers/azure/models.ts +3 -0
- package/src/plus/integrations/providers/bitbucket/models.ts +1 -0
- package/src/plus/integrations/providers/github.ts +218 -145
- package/src/plus/integrations/providers/gitlab.ts +30 -20
- package/src/plus/integrations/providers/models.ts +99 -127
- package/src/plus/integrations/providers/pullRequestReviews.ts +122 -0
- package/src/plus/integrations/reads/broaden.ts +6 -1
- package/src/plus/integrations/reads/counts.ts +273 -2
- package/src/plus/integrations/reads/drains.ts +19 -6
- package/src/plus/integrations/reads/filters.ts +22 -0
- package/src/plus/integrations/reads/hierarchy.ts +3 -1
- package/src/plus/integrations/reads/issueTracker.ts +9 -3
- package/src/plus/integrations/reads/issues.ts +9 -4
- package/src/plus/integrations/reads/pullRequests.ts +9 -4
- package/src/plus/integrations/reads/searchPullRequests.ts +12 -4
- package/src/plus/integrations/reads/sweeps.ts +1 -1
- package/src/plus/integrations/reads/warnings.ts +12 -1
- package/src/plus/integrations/results.ts +6 -1
- package/src/utils/env/browser/base64.ts +1 -1
- package/src/utils/env/node/base64.ts +3 -1
- package/src/utils/keys/chord.ts +184 -0
- package/src/utils/keys/keybinding.ts +116 -0
- package/src/utils/path.ts +14 -0
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type {
|
|
2
|
+
PullRequestSearchCriteria,
|
|
3
|
+
PullRequestSorting,
|
|
4
|
+
PullRequestStateFilter,
|
|
5
|
+
} from '../../../git/models/pullRequest.js';
|
|
6
|
+
import { defaultPullRequestSort, PullRequestFilter } from '../../../git/models/pullRequest.js';
|
|
7
|
+
import { sanitizeGitHubQualifierValue, sanitizeGitHubSearchText } from './issueSearchQuery.js';
|
|
4
8
|
|
|
5
9
|
export type GitHubPullRequestSearchFacet = {
|
|
6
10
|
/** Stable GraphQL alias and composite-cursor key. */
|
|
@@ -8,10 +12,20 @@ export type GitHubPullRequestSearchFacet = {
|
|
|
8
12
|
qualifiers: string[];
|
|
9
13
|
};
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The GitHub search qualifier each relationship translates to. Exhaustive over `PullRequestFilter` so a new
|
|
17
|
+
* member can't be silently unmapped.
|
|
18
|
+
*
|
|
19
|
+
* Exported because the account-wide read builds its own facets from the same vocabulary (see
|
|
20
|
+
* `GitHubIntegrationBase.getProviderMyPullRequestsForUser`). Kept as ONE declaration rather than a copy per
|
|
21
|
+
* caller: the exhaustive `Record` makes a missing key a compile error, but nothing would catch two copies
|
|
22
|
+
* disagreeing on a qualifier STRING, and a wrong qualifier is a read that quietly answers a different question.
|
|
23
|
+
*/
|
|
24
|
+
export const gitHubPullRequestRelationshipQualifiers: Record<PullRequestFilter, string> = {
|
|
12
25
|
[PullRequestFilter.Author]: 'author:@me',
|
|
13
26
|
[PullRequestFilter.Assignee]: 'assignee:@me',
|
|
14
27
|
[PullRequestFilter.ReviewRequested]: 'review-requested:@me',
|
|
28
|
+
[PullRequestFilter.Reviewed]: 'reviewed-by:@me',
|
|
15
29
|
[PullRequestFilter.Mention]: 'mentions:@me',
|
|
16
30
|
};
|
|
17
31
|
|
|
@@ -19,6 +33,7 @@ const relationshipAlias: Record<PullRequestFilter, string> = {
|
|
|
19
33
|
[PullRequestFilter.Author]: 'author',
|
|
20
34
|
[PullRequestFilter.Assignee]: 'assignee',
|
|
21
35
|
[PullRequestFilter.ReviewRequested]: 'reviewRequested',
|
|
36
|
+
[PullRequestFilter.Reviewed]: 'reviewed',
|
|
22
37
|
[PullRequestFilter.Mention]: 'mention',
|
|
23
38
|
};
|
|
24
39
|
|
|
@@ -29,6 +44,30 @@ const stateAlias: Record<PullRequestStateFilter, string> = {
|
|
|
29
44
|
all: 'All',
|
|
30
45
|
};
|
|
31
46
|
|
|
47
|
+
/**
|
|
48
|
+
* How each orderable key becomes a GitHub `sort:` qualifier.
|
|
49
|
+
*
|
|
50
|
+
* A literal `Record` over the union rather than a derived transform, for the same reason the relationship tables
|
|
51
|
+
* are: adding a sort field without deciding its qualifier fails the build instead of quietly emitting a search
|
|
52
|
+
* with no ordering constraint — the one failure mode the ordering contract exists to prevent, and the one a
|
|
53
|
+
* caller cannot detect from the result.
|
|
54
|
+
*
|
|
55
|
+
* `updated:desc` maps to the bare `sort:updated`, not `sort:updated-desc`. The two are the same query to GitHub,
|
|
56
|
+
* but the bare form is what this read has always emitted, so keeping it makes the default byte-identical to
|
|
57
|
+
* today's query — matching `toGitHubIssueSortQualifier`. Do not "normalize" it.
|
|
58
|
+
*/
|
|
59
|
+
export const gitHubPullRequestSortQualifiers: Partial<Record<PullRequestSorting, string>> = {
|
|
60
|
+
'created:asc': 'sort:created-asc',
|
|
61
|
+
'created:desc': 'sort:created-desc',
|
|
62
|
+
'updated:asc': 'sort:updated-asc',
|
|
63
|
+
'updated:desc': 'sort:updated',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/** The `sort:` qualifier for a key, or `undefined` when there is no key or GitHub can't express it. */
|
|
67
|
+
export function toGitHubPullRequestSortQualifier(sort: PullRequestSorting | undefined): string | undefined {
|
|
68
|
+
return sort != null ? gitHubPullRequestSortQualifiers[sort] : undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
32
71
|
function stateQualifiers(state: PullRequestStateFilter): string[] {
|
|
33
72
|
switch (state) {
|
|
34
73
|
case 'closed':
|
|
@@ -62,18 +101,53 @@ export function toGitHubPullRequestSearchFacets(
|
|
|
62
101
|
: ['open'];
|
|
63
102
|
const states: PullRequestStateFilter[] = requestedStates.includes('all') ? ['all'] : requestedStates;
|
|
64
103
|
const text = criteria?.text != null ? sanitizeGitHubSearchText(criteria.text) : '';
|
|
104
|
+
// Ordering is part of the contract, not an option: without an explicit `sort:` GitHub answers in relevance
|
|
105
|
+
// order, so which rows land inside the result ceiling would shift with its ranking even when nothing changed
|
|
106
|
+
// upstream. A key GitHub can't express is REFUSED here, not approximated with a fallback order — a silent
|
|
107
|
+
// `sort:updated` substitute would emit one order in the query while the merged-page comparator applied another
|
|
108
|
+
// (or none for an unknown field), which is exactly the "the N most recent are what you get" promise the ceiling
|
|
109
|
+
// contract cannot keep under a guessed order. Unreachable through the facade — every key is validated against
|
|
110
|
+
// `githubPullRequestSearchCapabilities.sorts` first — so this guards the direct callers of this exported builder
|
|
111
|
+
// and of `GitHubApi.searchPullRequestsPage`.
|
|
112
|
+
//
|
|
113
|
+
// Deliberately STRICTER than the issue path, which drops an inexpressible qualifier and searches on
|
|
114
|
+
// (`toGitHubIssueSearchQualifiers` pushes `toGitHubIssueSortQualifier`'s result only when it is non-null). The
|
|
115
|
+
// two reads differ in what that costs: an issue search is served by whichever facets the provider ordered, while
|
|
116
|
+
// this one hands its merged page to `getPullRequestComparator`, so a dropped qualifier here means the query and
|
|
117
|
+
// the comparator disagree about the order the ceiling was applied under. Refusing is the only answer that
|
|
118
|
+
// cannot lie about which rows were reachable.
|
|
119
|
+
const sort = criteria?.sort ?? defaultPullRequestSort;
|
|
120
|
+
const sortQualifier = toGitHubPullRequestSortQualifier(sort);
|
|
121
|
+
if (sortQualifier == null) {
|
|
122
|
+
throw new Error(`GitHub cannot order a pull request search by '${sort}'`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Facet-independent, unlike the relationship/state qualifiers below — build once and share.
|
|
126
|
+
const dateQualifiers: string[] = [];
|
|
127
|
+
const pushDate = (value: string | undefined, toQualifier: (sanitized: string) => string): void => {
|
|
128
|
+
if (value == null) return;
|
|
129
|
+
|
|
130
|
+
const sanitized = sanitizeGitHubQualifierValue(value);
|
|
131
|
+
if (sanitized.length > 0) {
|
|
132
|
+
dateQualifiers.push(toQualifier(sanitized));
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
pushDate(criteria?.updatedAfter, v => `updated:>=${v}`);
|
|
136
|
+
pushDate(criteria?.createdAfter, v => `created:>=${v}`);
|
|
65
137
|
|
|
66
138
|
return relationships.flatMap(relationship =>
|
|
67
139
|
states.map(state => ({
|
|
68
140
|
alias: `${relationship != null ? relationshipAlias[relationship] : 'scope'}${stateAlias[state]}`,
|
|
69
141
|
qualifiers: [
|
|
70
142
|
'is:pr',
|
|
71
|
-
...(relationship != null ? [
|
|
143
|
+
...(relationship != null ? [gitHubPullRequestRelationshipQualifiers[relationship]] : []),
|
|
72
144
|
...stateQualifiers(state),
|
|
145
|
+
// `!= null`, not truthy: `draft:false` narrows to ready-for-review PRs just as `draft:true` narrows to drafts.
|
|
146
|
+
...(criteria?.draft != null ? [`draft:${criteria.draft}`] : []),
|
|
73
147
|
...(criteria?.includeArchived === true ? [] : ['archived:false']),
|
|
74
148
|
...(text.length > 0 ? [text] : []),
|
|
75
|
-
|
|
76
|
-
|
|
149
|
+
...dateQualifiers,
|
|
150
|
+
sortQualifier,
|
|
77
151
|
],
|
|
78
152
|
})),
|
|
79
153
|
);
|
|
@@ -2,7 +2,7 @@ import type { Endpoints } from '@octokit/types';
|
|
|
2
2
|
import { GitFileIndexStatus } from '../../git/models/fileStatus.js';
|
|
3
3
|
import type { IssueLabel } from '../../git/models/issue.js';
|
|
4
4
|
import { Issue, RepositoryAccessLevel } from '../../git/models/issue.js';
|
|
5
|
-
import type { PullRequestMember, PullRequestState } from '../../git/models/pullRequest.js';
|
|
5
|
+
import type { PullRequestMember, PullRequestStackInfo, PullRequestState } from '../../git/models/pullRequest.js';
|
|
6
6
|
import {
|
|
7
7
|
PullRequest,
|
|
8
8
|
PullRequestMergeableState,
|
|
@@ -165,6 +165,20 @@ export interface GitHubPullRequestLite extends Omit<GitHubIssueOrPullRequest, '_
|
|
|
165
165
|
url: string;
|
|
166
166
|
viewerPermission: GitHubViewerPermission;
|
|
167
167
|
};
|
|
168
|
+
|
|
169
|
+
/** Only selected against github.com — GitHub Enterprise Server schemas lag and reject the field. */
|
|
170
|
+
stack?: GitHubPullRequestStack | null;
|
|
171
|
+
/** Only selected against github.com — see `stack`. */
|
|
172
|
+
stackEntry?: { position: number } | null;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** GitHub's stacked-pull-request object. Read-only; all stack mutations are REST-only. */
|
|
176
|
+
export interface GitHubPullRequestStack {
|
|
177
|
+
id: string;
|
|
178
|
+
number: number;
|
|
179
|
+
size: number;
|
|
180
|
+
/** The branch the bottom of the stack targets — the stack's trunk. */
|
|
181
|
+
baseRefName: string;
|
|
168
182
|
}
|
|
169
183
|
|
|
170
184
|
export interface GitHubIssue extends Omit<GitHubIssueOrPullRequest, '__typename'> {
|
|
@@ -194,21 +208,32 @@ export type GitHubPullRequestMergeableState = 'MERGEABLE' | 'CONFLICTING' | 'UNK
|
|
|
194
208
|
export type GitHubPullRequestStatusCheckRollupState = 'SUCCESS' | 'FAILURE' | 'PENDING' | 'EXPECTED' | 'ERROR';
|
|
195
209
|
export type GitHubPullRequestReviewState = 'APPROVED' | 'CHANGES_REQUESTED' | 'COMMENTED' | 'DISMISSED' | 'PENDING';
|
|
196
210
|
|
|
211
|
+
type GitHubPullRequestReview = {
|
|
212
|
+
id: string;
|
|
213
|
+
author: GitHubMember | null;
|
|
214
|
+
state: GitHubPullRequestReviewState;
|
|
215
|
+
commit?: { oid: string } | null;
|
|
216
|
+
};
|
|
217
|
+
|
|
197
218
|
export interface GitHubPullRequest extends GitHubPullRequestLite {
|
|
198
219
|
additions: number;
|
|
199
220
|
assignees: {
|
|
200
221
|
nodes: GitHubMember[];
|
|
201
222
|
};
|
|
223
|
+
changedFiles: number;
|
|
202
224
|
checksUrl: string;
|
|
203
225
|
deletions: number;
|
|
204
226
|
mergeable: GitHubPullRequestMergeableState;
|
|
205
227
|
reviewDecision: GitHubPullRequestReviewDecision;
|
|
206
228
|
latestReviews: {
|
|
207
|
-
nodes:
|
|
208
|
-
author: GitHubMember | null;
|
|
209
|
-
state: GitHubPullRequestReviewState;
|
|
210
|
-
}[];
|
|
229
|
+
nodes: GitHubPullRequestReview[];
|
|
211
230
|
};
|
|
231
|
+
/**
|
|
232
|
+
* The current user's own latest review. `latestReviews` is capped, so on a heavily-reviewed pull request
|
|
233
|
+
* the viewer's own review can fall outside that window — which is exactly the row a "needs my review"
|
|
234
|
+
* surface is asking about.
|
|
235
|
+
*/
|
|
236
|
+
viewerLatestReview: GitHubPullRequestReview | null;
|
|
212
237
|
reviewRequests: {
|
|
213
238
|
nodes: {
|
|
214
239
|
asCodeOwner: boolean;
|
|
@@ -216,6 +241,7 @@ export interface GitHubPullRequest extends GitHubPullRequestLite {
|
|
|
216
241
|
}[];
|
|
217
242
|
};
|
|
218
243
|
commits: {
|
|
244
|
+
totalCount: number;
|
|
219
245
|
nodes: {
|
|
220
246
|
commit: {
|
|
221
247
|
statusCheckRollup: {
|
|
@@ -240,7 +266,13 @@ export type GitHubViewerPermission =
|
|
|
240
266
|
function fromGitHubMemberOrGhost(member: GitHubMember | null | undefined): PullRequestMember {
|
|
241
267
|
if (member == null) return { id: 'ghost', name: 'ghost' };
|
|
242
268
|
|
|
243
|
-
return {
|
|
269
|
+
return {
|
|
270
|
+
id: member.login,
|
|
271
|
+
name: member.login,
|
|
272
|
+
username: member.login,
|
|
273
|
+
avatarUrl: member.avatarUrl,
|
|
274
|
+
url: member.url,
|
|
275
|
+
};
|
|
244
276
|
}
|
|
245
277
|
|
|
246
278
|
export function fromGitHubPullRequestLite(pr: GitHubPullRequestLite, provider: Provider): PullRequest {
|
|
@@ -289,6 +321,7 @@ export function fromGitHubPullRequestLite(pr: GitHubPullRequestLite, provider: P
|
|
|
289
321
|
isCrossRepository: pr.isCrossRepository,
|
|
290
322
|
},
|
|
291
323
|
pr.isDraft,
|
|
324
|
+
// The lite fragment selects nothing between `isDraft` and `stack`.
|
|
292
325
|
undefined, // additions
|
|
293
326
|
undefined, // deletions
|
|
294
327
|
undefined, // commentsCount
|
|
@@ -300,10 +333,26 @@ export function fromGitHubPullRequestLite(pr: GitHubPullRequestLite, provider: P
|
|
|
300
333
|
undefined, // statusCheckRollupState
|
|
301
334
|
undefined, // project
|
|
302
335
|
undefined, // version
|
|
336
|
+
undefined, // commitCount
|
|
337
|
+
fromGitHubPullRequestStack(pr),
|
|
338
|
+
undefined, // filesChanged
|
|
303
339
|
pr.body ?? undefined,
|
|
304
340
|
);
|
|
305
341
|
}
|
|
306
342
|
|
|
343
|
+
/** Both fields are absent on GitHub Enterprise Server (never selected) and `null` when unstacked. */
|
|
344
|
+
function fromGitHubPullRequestStack(pr: GitHubPullRequestLite): PullRequestStackInfo | undefined {
|
|
345
|
+
if (pr.stack == null || pr.stackEntry == null) return undefined;
|
|
346
|
+
|
|
347
|
+
return {
|
|
348
|
+
id: pr.stack.id,
|
|
349
|
+
number: pr.stack.number,
|
|
350
|
+
size: pr.stack.size,
|
|
351
|
+
position: pr.stackEntry.position,
|
|
352
|
+
baseRef: pr.stack.baseRefName,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
307
356
|
export function fromGitHubIssueOrPullRequestState(state: GitHubPullRequestState): PullRequestState {
|
|
308
357
|
return state === 'MERGED' ? 'merged' : state === 'CLOSED' ? 'closed' : 'opened';
|
|
309
358
|
}
|
|
@@ -401,6 +450,19 @@ export function fromGitHubPullRequestStatusCheckRollupState(
|
|
|
401
450
|
}
|
|
402
451
|
|
|
403
452
|
export function fromGitHubPullRequest(pr: GitHubPullRequest, provider: Provider): PullRequest {
|
|
453
|
+
// `latestReviews` is capped, so keep the viewer's own review even when it falls outside that window, deduped
|
|
454
|
+
// by review id since the two selections overlap. Unsubmitted drafts are dropped from the union rather than
|
|
455
|
+
// from the viewer's side alone: `PENDING` is in GitHub's review-state enum on both selections, and the field
|
|
456
|
+
// this feeds is documented as reviews already SUBMITTED — a draft there tells a "needs my review" consumer
|
|
457
|
+
// the review is done, and a reviewer with a submitted review plus a draft would get two conflicting rows.
|
|
458
|
+
const viewerLatestReview = pr.viewerLatestReview;
|
|
459
|
+
const latestReviews = [
|
|
460
|
+
...pr.latestReviews.nodes,
|
|
461
|
+
...(viewerLatestReview != null && !pr.latestReviews.nodes.some(r => r.id === viewerLatestReview.id)
|
|
462
|
+
? [viewerLatestReview]
|
|
463
|
+
: []),
|
|
464
|
+
].filter(review => review.state !== 'PENDING');
|
|
465
|
+
|
|
404
466
|
return new PullRequest(
|
|
405
467
|
provider,
|
|
406
468
|
fromGitHubMemberOrGhost(pr.author),
|
|
@@ -459,6 +521,7 @@ export function fromGitHubPullRequest(pr: GitHubPullRequest, provider: Provider)
|
|
|
459
521
|
reviewer: {
|
|
460
522
|
id: r.requestedReviewer.login,
|
|
461
523
|
name: r.requestedReviewer.login,
|
|
524
|
+
username: r.requestedReviewer.login,
|
|
462
525
|
avatarUrl: r.requestedReviewer.avatarUrl,
|
|
463
526
|
url: r.requestedReviewer.url,
|
|
464
527
|
},
|
|
@@ -467,19 +530,24 @@ export function fromGitHubPullRequest(pr: GitHubPullRequest, provider: Provider)
|
|
|
467
530
|
: undefined,
|
|
468
531
|
)
|
|
469
532
|
.filter(<T>(r?: T): r is T => Boolean(r)),
|
|
470
|
-
|
|
533
|
+
latestReviews.map(r => ({
|
|
471
534
|
reviewer: fromGitHubMemberOrGhost(r.author),
|
|
472
535
|
state: fromGitHubPullRequestReviewState(r.state),
|
|
536
|
+
commitOid: r.commit?.oid,
|
|
473
537
|
})),
|
|
474
538
|
pr.assignees.nodes.map(r => ({
|
|
475
539
|
id: r.login,
|
|
476
540
|
name: r.login,
|
|
541
|
+
username: r.login,
|
|
477
542
|
avatarUrl: r.avatarUrl,
|
|
478
543
|
url: r.url,
|
|
479
544
|
})),
|
|
480
545
|
fromGitHubPullRequestStatusCheckRollupState(pr.commits.nodes?.[0]?.commit.statusCheckRollup?.state),
|
|
481
546
|
undefined, // project
|
|
482
547
|
undefined, // version
|
|
548
|
+
pr.commits.totalCount,
|
|
549
|
+
fromGitHubPullRequestStack(pr),
|
|
550
|
+
pr.changedFiles,
|
|
483
551
|
pr.body ?? undefined,
|
|
484
552
|
);
|
|
485
553
|
}
|
|
@@ -505,12 +573,14 @@ export function fromGitHubIssue(value: GitHubIssue, provider: Provider): Issue {
|
|
|
505
573
|
: {
|
|
506
574
|
id: value.author.login,
|
|
507
575
|
name: value.author.login,
|
|
576
|
+
username: value.author.login,
|
|
508
577
|
avatarUrl: value.author.avatarUrl,
|
|
509
578
|
url: value.author.url,
|
|
510
579
|
},
|
|
511
580
|
value.assignees.nodes.map(assignee => ({
|
|
512
581
|
id: assignee.login,
|
|
513
582
|
name: assignee.login,
|
|
583
|
+
username: assignee.login,
|
|
514
584
|
avatarUrl: assignee.avatarUrl,
|
|
515
585
|
url: assignee.url,
|
|
516
586
|
})),
|
|
@@ -155,6 +155,10 @@ export interface IntegrationCacheProvider {
|
|
|
155
155
|
cacheable: Cacheable<Account>,
|
|
156
156
|
options?: CacheExpiryOptions & { connectionId?: string; etag?: string },
|
|
157
157
|
): CacheResult<Account>;
|
|
158
|
+
/** Evicts every cached pull request. A merge invalidates more than the merged pull request alone —
|
|
159
|
+
* a stacked merge lands every layer below it and retargets every layer above — and no caller can
|
|
160
|
+
* name that full set. */
|
|
161
|
+
deletePullRequests(): void;
|
|
158
162
|
}
|
|
159
163
|
|
|
160
164
|
/**
|
|
@@ -73,6 +73,8 @@ const uncachedIntegrationCacheProvider: IntegrationCacheProvider = {
|
|
|
73
73
|
getIssueOrPullRequest: (_id, _type, _resource, _integration, loader) => loadUncached(loader),
|
|
74
74
|
getIssue: (_id, _resource, _integration, loader) => loadUncached(loader),
|
|
75
75
|
getCurrentAccount: (_integration, loader) => loadUncached(loader),
|
|
76
|
+
// Nothing is cached, so there is nothing to evict.
|
|
77
|
+
deletePullRequests: () => {},
|
|
76
78
|
};
|
|
77
79
|
|
|
78
80
|
function toIntegrationCacheProvider(cache: IntegrationManagerCacheProvider | undefined): IntegrationCacheProvider {
|
|
@@ -77,8 +77,13 @@ import { providersMetadata } from './providers/models.js';
|
|
|
77
77
|
import type { ProvidersApi } from './providers/providersApi.js';
|
|
78
78
|
import { broadenIssues } from './reads/broaden.js';
|
|
79
79
|
import type { RepositoryResolutionContext } from './reads/context.js';
|
|
80
|
-
import type {
|
|
81
|
-
|
|
80
|
+
import type {
|
|
81
|
+
IssueCountResult,
|
|
82
|
+
IssueCountScope,
|
|
83
|
+
PullRequestCountResult,
|
|
84
|
+
PullRequestCountScope,
|
|
85
|
+
} from './reads/counts.js';
|
|
86
|
+
import { countIssues, countPullRequests } from './reads/counts.js';
|
|
82
87
|
import type { SupportedFilters } from './reads/filters.js';
|
|
83
88
|
import { getSupportedFilters } from './reads/filters.js';
|
|
84
89
|
import { listOrgs, listProjects, listRepos } from './reads/hierarchy.js';
|
|
@@ -1147,6 +1152,24 @@ export class IntegrationService implements Disposable, RepositoryResolutionConte
|
|
|
1147
1152
|
return countIssues(this, options);
|
|
1148
1153
|
}
|
|
1149
1154
|
|
|
1155
|
+
/**
|
|
1156
|
+
* How many pull requests match each scope, without fetching any — the PR twin of {@link countIssues}. See
|
|
1157
|
+
* {@link IntegrationManager.countPullRequests} for the cost model, the per-scope isolation rules, and why
|
|
1158
|
+
* `count: undefined` must not be rendered as zero.
|
|
1159
|
+
*/
|
|
1160
|
+
async countPullRequests(options: {
|
|
1161
|
+
providerId: IntegrationIds;
|
|
1162
|
+
scopes: readonly PullRequestCountScope[];
|
|
1163
|
+
connectionId?: string;
|
|
1164
|
+
/**
|
|
1165
|
+
* Explicit self-managed host domain. Used only when the requested connection has no configured domain;
|
|
1166
|
+
* it must come from the trusted authentication configuration, not repository or remote data.
|
|
1167
|
+
*/
|
|
1168
|
+
domain?: string;
|
|
1169
|
+
}): Promise<ProviderResult<PullRequestCountResult>> {
|
|
1170
|
+
return countPullRequests(this, options);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1150
1173
|
/**
|
|
1151
1174
|
* Reads the user's issues from an issue-tracker provider (Jira/Linear/Trello), whose issues live under
|
|
1152
1175
|
* resource → project (not repos), so they can't go through {@link listIssuesPage} (git-host, repo-scoped).
|
|
@@ -9,7 +9,12 @@ import type { ConfiguredIntegrationsChangeEvent } from './authentication/configu
|
|
|
9
9
|
import type { ConfiguredIntegrationDescriptor } from './authentication/models.js';
|
|
10
10
|
import type { IntegrationIds } from './constants.js';
|
|
11
11
|
import type { IssueFilter, IssueSorting, PullRequestFilter } from './providerFilters.js';
|
|
12
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
IssueCountResult,
|
|
14
|
+
IssueCountScope,
|
|
15
|
+
PullRequestCountResult,
|
|
16
|
+
PullRequestCountScope,
|
|
17
|
+
} from './reads/counts.js';
|
|
13
18
|
import type { SupportedFilters } from './reads/filters.js';
|
|
14
19
|
import type {
|
|
15
20
|
ConnectionStateChangeEvent,
|
|
@@ -156,6 +161,22 @@ type PullRequestSweepCommonOptions = {
|
|
|
156
161
|
* This extends the provider-native result; it is not a narrowing filter.
|
|
157
162
|
*/
|
|
158
163
|
includeReviewRequested?: boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Account-wide only: fetch the full PR projection (review decision, review requests, latest reviews)
|
|
166
|
+
* instead of the default summary/lite one. Opt-in because it enlarges every account-wide page; callers
|
|
167
|
+
* that classify by review state (e.g. a "needs my review" surface) set it, others keep the lean read.
|
|
168
|
+
*
|
|
169
|
+
* GitHub/GHE only today — no other provider's account-wide read has a projection switch, so they return
|
|
170
|
+
* their native shape regardless. A cross-provider sweep therefore gets reviews from GitHub targets and
|
|
171
|
+
* whatever the others natively carry; it is a breadth request, not a guarantee, so it does not refuse
|
|
172
|
+
* (unlike `filters`, where dropping a member would change the requested set).
|
|
173
|
+
*
|
|
174
|
+
* Projection only: it cannot change which pull requests come back. Every GitHub account-wide read goes through
|
|
175
|
+
* the same search whether or not it is set, so the Launchpad ignored-repository and organization qualifiers
|
|
176
|
+
* (and the per-facet result ceiling) apply the same either way. What it costs is the reduced page size, and a
|
|
177
|
+
* document whose weight scales with the number of relationship × state facets in flight.
|
|
178
|
+
*/
|
|
179
|
+
includeReviews?: boolean;
|
|
159
180
|
forceSync?: boolean;
|
|
160
181
|
maxPages?: number;
|
|
161
182
|
/**
|
|
@@ -355,10 +376,17 @@ export interface IntegrationManager {
|
|
|
355
376
|
* GitHub's mismatched `involves:@me`. Omit relationships only with a repository/organization scope to search
|
|
356
377
|
* every PR there.
|
|
357
378
|
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
379
|
+
* **Ordering is `criteria.sort`**, most-recently-updated-first when omitted. It is validated like every other
|
|
380
|
+
* criterion — a key not in `getSupportedFilters().pullRequestSearch.sorts` refuses the whole read rather than
|
|
381
|
+
* falling back, because at a bounded result window another order reaches another subset. The page is a union of
|
|
382
|
+
* the provider's relationship × state facets, so it is re-ordered as a whole rather than served as concatenated
|
|
383
|
+
* per-facet runs. Changing the sort invalidates a threaded cursor (it is part of the cursor's fingerprint,
|
|
384
|
+
* alongside the text and the scope); drop the cursor when you change the order.
|
|
385
|
+
*
|
|
386
|
+
* If the provider's result ceiling is reached, the request still succeeds and carries a warning omission with
|
|
387
|
+
* `totalCount`, `limit`, `sort`, and `recovery: 'none'`. `totalCount` is the largest provider-reported
|
|
388
|
+
* pre-ceiling facet count, not the reachable or returned row count; this mirrors the per-search ceiling's own
|
|
389
|
+
* unit.
|
|
362
390
|
*
|
|
363
391
|
* Check `getSupportedFilters().pullRequestSearch` before calling. A provider that reports no relationships
|
|
364
392
|
* refuses the read rather than returning a page that never honored the criteria or scope.
|
|
@@ -518,6 +546,23 @@ export interface IntegrationManager {
|
|
|
518
546
|
/** Self-managed host domain fallback; see {@link ProviderSweepTarget.domain}. */
|
|
519
547
|
domain?: string;
|
|
520
548
|
}): Promise<ProviderResult<IssueCountResult>>;
|
|
549
|
+
/**
|
|
550
|
+
* How many pull requests match each scope, fetching none of them — the PR twin of {@link countIssues}, behind a
|
|
551
|
+
* "this will fetch ~N pull requests" preview and a live count next to an unapplied filter. Same cost model,
|
|
552
|
+
* per-scope isolation, `key`-echo, and `count: undefined` ≠ zero rule as the issue count; GitHub/GHE only.
|
|
553
|
+
*
|
|
554
|
+
* The one PR-specific difference: a scope's `states` are counted as independent searches, so the reported count
|
|
555
|
+
* is the LARGEST of them (the same total {@link searchPullRequestsPage} surfaces), not their sum. Several states
|
|
556
|
+
* in one scope are therefore fine; only several relationships are refused — one relationship per scope, see
|
|
557
|
+
* {@link PullRequestCountScope}.
|
|
558
|
+
*/
|
|
559
|
+
countPullRequests(options: {
|
|
560
|
+
providerId: IntegrationIds;
|
|
561
|
+
scopes: readonly PullRequestCountScope[];
|
|
562
|
+
connectionId?: string;
|
|
563
|
+
/** Self-managed host domain fallback; see {@link ProviderSweepTarget.domain}. */
|
|
564
|
+
domain?: string;
|
|
565
|
+
}): Promise<ProviderResult<PullRequestCountResult>>;
|
|
521
566
|
/** Issue trackers are cloud-only, so this read takes no `domain`. */
|
|
522
567
|
listIssueTrackerIssuesPage(options: {
|
|
523
568
|
providerId: IntegrationIds;
|
|
@@ -7,11 +7,13 @@ import type {
|
|
|
7
7
|
PullRequest,
|
|
8
8
|
PullRequestMergeMethod,
|
|
9
9
|
PullRequestSearchCriteria,
|
|
10
|
+
PullRequestStackInfo,
|
|
10
11
|
PullRequestStateFilter,
|
|
11
12
|
} from '../../../git/models/pullRequest.js';
|
|
12
13
|
import type { RepositoryMetadata } from '../../../git/models/repositoryMetadata.js';
|
|
13
14
|
import type { ResourceDescriptor } from '../../../git/models/resourceDescriptor.js';
|
|
14
15
|
import type { PullRequestUrlIdentity } from '../../../git/utils/pullRequest.utils.js';
|
|
16
|
+
import { isCancellationError } from '../../../utils/cancellation.js';
|
|
15
17
|
import { gate } from '../../../utils/decorators/gate.js';
|
|
16
18
|
import { trace } from '../../../utils/decorators/log.js';
|
|
17
19
|
import { first } from '../../../utils/iterable.js';
|
|
@@ -267,6 +269,14 @@ export abstract class GitHostIntegration<
|
|
|
267
269
|
connectionId?: string;
|
|
268
270
|
}): Promise<ProviderRepository | undefined>;
|
|
269
271
|
|
|
272
|
+
/** Stack membership for every stacked pull request in the repository, keyed by pull request number.
|
|
273
|
+
* Only hosts with a stacks concept implement this (currently GitHub). */
|
|
274
|
+
getStacksByPullRequestNumber?(
|
|
275
|
+
owner: string,
|
|
276
|
+
repo: string,
|
|
277
|
+
cancellation?: AbortSignal,
|
|
278
|
+
): Promise<Map<number, PullRequestStackInfo> | undefined>;
|
|
279
|
+
|
|
270
280
|
protected abstract getProviderDefaultBranch(
|
|
271
281
|
{ accessToken }: ProviderAuthenticationSession,
|
|
272
282
|
repo: T,
|
|
@@ -514,7 +524,11 @@ export abstract class GitHostIntegration<
|
|
|
514
524
|
options?: { cursor?: string },
|
|
515
525
|
): Promise<ProviderHierarchyResult<ProviderRepository> | undefined>;
|
|
516
526
|
|
|
517
|
-
async mergePullRequest(
|
|
527
|
+
async mergePullRequest(
|
|
528
|
+
pr: PullRequest,
|
|
529
|
+
options?: { mergeMethod?: PullRequestMergeMethod },
|
|
530
|
+
cancellation?: AbortSignal,
|
|
531
|
+
): Promise<boolean> {
|
|
518
532
|
const scope = getScopedLogger();
|
|
519
533
|
|
|
520
534
|
const connected = this.maybeConnected ?? (await this.isConnected());
|
|
@@ -523,12 +537,20 @@ export abstract class GitHostIntegration<
|
|
|
523
537
|
await this.refreshSessionIfExpired(scope);
|
|
524
538
|
|
|
525
539
|
try {
|
|
526
|
-
const result = await this.mergeProviderPullRequest(this._session!, pr, options);
|
|
540
|
+
const result = await this.mergeProviderPullRequest(this._session!, pr, options, cancellation);
|
|
527
541
|
this.resetRequestExceptionCount('mergePullRequest');
|
|
528
542
|
return result;
|
|
529
543
|
} catch (ex) {
|
|
544
|
+
if (isCancellationError(ex)) return false;
|
|
545
|
+
|
|
530
546
|
this.handleProviderException('mergePullRequest', ex, { scope: scope });
|
|
531
547
|
return false;
|
|
548
|
+
} finally {
|
|
549
|
+
// A merge attempt just changed the state of more than this pull request on the server (a
|
|
550
|
+
// stacked merge lands every layer below and retargets every layer above) whether it succeeded
|
|
551
|
+
// or failed partway through — so cached pull requests can't be trusted either way. Without
|
|
552
|
+
// this, ref pills and branch enrichment keep serving the pre-merge object until its expiry.
|
|
553
|
+
this.ctx.cache.deletePullRequests();
|
|
532
554
|
}
|
|
533
555
|
}
|
|
534
556
|
|
|
@@ -536,6 +558,7 @@ export abstract class GitHostIntegration<
|
|
|
536
558
|
session: ProviderAuthenticationSession,
|
|
537
559
|
pr: PullRequest,
|
|
538
560
|
options?: { mergeMethod?: PullRequestMergeMethod },
|
|
561
|
+
cancellation?: AbortSignal,
|
|
539
562
|
): Promise<boolean>;
|
|
540
563
|
|
|
541
564
|
@trace()
|
|
@@ -1755,6 +1778,35 @@ export abstract class GitHostIntegration<
|
|
|
1755
1778
|
cancellation?: AbortSignal,
|
|
1756
1779
|
): Promise<(number | undefined)[] | undefined>;
|
|
1757
1780
|
|
|
1781
|
+
/** The PR twin of {@link countIssuesResult}: counts each scope's pull requests, transferring none. */
|
|
1782
|
+
async countPullRequestsResult(
|
|
1783
|
+
scopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],
|
|
1784
|
+
cancellation?: AbortSignal,
|
|
1785
|
+
connectionId?: string,
|
|
1786
|
+
): Promise<IntegrationResult<(number | undefined)[] | undefined>> {
|
|
1787
|
+
const scope = getScopedLogger();
|
|
1788
|
+
// `connectionId` targets a specific account (multi-account); omitted reads the primary.
|
|
1789
|
+
const session = await this.resolveReadSession(connectionId, scope);
|
|
1790
|
+
if (session == null) return undefined;
|
|
1791
|
+
|
|
1792
|
+
const start = performance.now();
|
|
1793
|
+
try {
|
|
1794
|
+
const counts = await this.countProviderPullRequests?.(session, scopes, cancellation);
|
|
1795
|
+
this.resetRequestExceptionCount('countPullRequests');
|
|
1796
|
+
return { value: counts, duration: performance.now() - start };
|
|
1797
|
+
} catch (ex) {
|
|
1798
|
+
this.handleProviderException('countPullRequests', ex, { scope: scope, connectionId: connectionId });
|
|
1799
|
+
return { error: toError(ex), duration: performance.now() - start };
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
/** OPTIONAL, like {@link countProviderIssues}: only a provider that can count without fetching implements it. */
|
|
1804
|
+
protected countProviderPullRequests?(
|
|
1805
|
+
session: ProviderAuthenticationSession,
|
|
1806
|
+
scopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],
|
|
1807
|
+
cancellation?: AbortSignal,
|
|
1808
|
+
): Promise<(number | undefined)[] | undefined>;
|
|
1809
|
+
|
|
1758
1810
|
getPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {
|
|
1759
1811
|
return this.getProviderPullRequestIdentityFromMaybeUrl?.(search);
|
|
1760
1812
|
}
|
|
@@ -81,6 +81,7 @@ type SyncReqUsecase = Exclude<
|
|
|
81
81
|
| 'getResourcesForUser'
|
|
82
82
|
| 'getSshSigningKeysForEmails'
|
|
83
83
|
| 'countIssues'
|
|
84
|
+
| 'countPullRequests'
|
|
84
85
|
| 'mergePullRequest'
|
|
85
86
|
| 'searchIssuesPage'
|
|
86
87
|
| 'searchPullRequestsPage'
|
|
@@ -928,7 +929,11 @@ export abstract class IntegrationBase<
|
|
|
928
929
|
}
|
|
929
930
|
|
|
930
931
|
@trace()
|
|
931
|
-
async getPullRequest(
|
|
932
|
+
async getPullRequest(
|
|
933
|
+
resource: T,
|
|
934
|
+
id: string,
|
|
935
|
+
options?: { expiryOverride?: boolean | number },
|
|
936
|
+
): Promise<PullRequest | undefined> {
|
|
932
937
|
const scope = getScopedLogger();
|
|
933
938
|
|
|
934
939
|
const connected = this.maybeConnected ?? (await this.isConnected());
|
|
@@ -936,18 +941,24 @@ export abstract class IntegrationBase<
|
|
|
936
941
|
|
|
937
942
|
await this.refreshSessionIfExpired(scope);
|
|
938
943
|
|
|
939
|
-
const pr = await this.ctx.cache.getPullRequest(
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
944
|
+
const pr = await this.ctx.cache.getPullRequest(
|
|
945
|
+
id,
|
|
946
|
+
resource,
|
|
947
|
+
this,
|
|
948
|
+
() => ({
|
|
949
|
+
value: (async () => {
|
|
950
|
+
try {
|
|
951
|
+
const result = await this.getProviderPullRequest?.(this._session!, resource, id);
|
|
952
|
+
this.resetRequestExceptionCount('getPullRequest');
|
|
953
|
+
return result;
|
|
954
|
+
} catch (ex) {
|
|
955
|
+
this.handleProviderException('getPullRequest', ex, { scope: scope });
|
|
956
|
+
return undefined;
|
|
957
|
+
}
|
|
958
|
+
})(),
|
|
959
|
+
}),
|
|
960
|
+
{ expiryOverride: options?.expiryOverride },
|
|
961
|
+
);
|
|
951
962
|
return pr;
|
|
952
963
|
}
|
|
953
964
|
|
|
@@ -28,4 +28,9 @@ export type {
|
|
|
28
28
|
* same dependency-direction reason as the issue-search model above: provider API clients translate them below
|
|
29
29
|
* this package and cannot import this facade.
|
|
30
30
|
*/
|
|
31
|
-
export type {
|
|
31
|
+
export type {
|
|
32
|
+
PullRequestSearchCapabilities,
|
|
33
|
+
PullRequestSearchCriteria,
|
|
34
|
+
PullRequestSortField,
|
|
35
|
+
PullRequestSorting,
|
|
36
|
+
} from '../../git/models/pullRequest.js';
|