@gitkraken/core-gitlens 0.1.0 → 0.3.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 +25 -1
- package/dist/git/cache.d.ts +49 -9
- package/dist/git/cache.d.ts.map +1 -1
- package/dist/git/cache.js +174 -14
- package/dist/git/cache.js.map +1 -1
- package/dist/git/context.d.ts +11 -2
- package/dist/git/context.d.ts.map +1 -1
- package/dist/git/context.js.map +1 -1
- package/dist/git/models/branch.d.ts +1 -0
- package/dist/git/models/branch.d.ts.map +1 -1
- package/dist/git/models/branch.js.map +1 -1
- package/dist/git/models/commit.d.ts +1 -9
- package/dist/git/models/commit.d.ts.map +1 -1
- package/dist/git/models/commit.js +4 -9
- package/dist/git/models/commit.js.map +1 -1
- package/dist/git/models/graph.d.ts +2 -4
- package/dist/git/models/graph.d.ts.map +1 -1
- package/dist/git/models/reference.d.ts +31 -0
- package/dist/git/models/reference.d.ts.map +1 -1
- package/dist/git/models/remote.d.ts.map +1 -1
- package/dist/git/models/remote.js.map +1 -1
- package/dist/git/models/repository.d.ts +20 -3
- package/dist/git/models/repository.d.ts.map +1 -1
- package/dist/git/models/repository.js +42 -5
- package/dist/git/models/repository.js.map +1 -1
- package/dist/git/models/search.d.ts +2 -2
- package/dist/git/models/search.d.ts.map +1 -1
- package/dist/git/models/worktree.d.ts +4 -1
- package/dist/git/models/worktree.d.ts.map +1 -1
- package/dist/git/models/worktree.js +2 -2
- package/dist/git/models/worktree.js.map +1 -1
- package/dist/git/parsers/diffParser.d.ts +0 -1
- package/dist/git/parsers/diffParser.d.ts.map +1 -1
- package/dist/git/parsers/diffParser.js +22 -61
- package/dist/git/parsers/diffParser.js.map +1 -1
- package/dist/git/providers/branches.d.ts +18 -4
- package/dist/git/providers/branches.d.ts.map +1 -1
- package/dist/git/providers/commits.d.ts +6 -0
- package/dist/git/providers/commits.d.ts.map +1 -1
- package/dist/git/providers/config.d.ts +6 -1
- package/dist/git/providers/config.d.ts.map +1 -1
- package/dist/git/providers/diff.d.ts +2 -0
- package/dist/git/providers/diff.d.ts.map +1 -1
- package/dist/git/providers/operations.d.ts +39 -10
- package/dist/git/providers/operations.d.ts.map +1 -1
- package/dist/git/providers/pausedOperations.d.ts +3 -1
- package/dist/git/providers/pausedOperations.d.ts.map +1 -1
- package/dist/git/providers/refs.d.ts +23 -2
- package/dist/git/providers/refs.d.ts.map +1 -1
- package/dist/git/providers/revision.d.ts +1 -1
- package/dist/git/providers/revision.d.ts.map +1 -1
- package/dist/git/providers/staging.d.ts +18 -0
- package/dist/git/providers/staging.d.ts.map +1 -1
- package/dist/git/providers/status.d.ts +4 -1
- package/dist/git/providers/status.d.ts.map +1 -1
- package/dist/git/remotes/azure-devops.d.ts.map +1 -1
- package/dist/git/remotes/azure-devops.js.map +1 -1
- package/dist/git/{exec.types.d.ts → run.types.d.ts} +22 -3
- package/dist/git/run.types.d.ts.map +1 -0
- package/dist/git/run.types.js +2 -0
- package/dist/git/run.types.js.map +1 -0
- package/dist/git/service.d.ts.map +1 -1
- package/dist/git/service.js.map +1 -1
- package/dist/git/utils/autolink.utils.d.ts.map +1 -1
- package/dist/git/utils/autolink.utils.js.map +1 -1
- package/dist/git/utils/blame.utils.d.ts.map +1 -1
- package/dist/git/utils/blame.utils.js.map +1 -1
- package/dist/git/utils/conflictResolution.utils.d.ts +6 -0
- package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -0
- package/dist/git/utils/conflictResolution.utils.js +25 -0
- package/dist/git/utils/conflictResolution.utils.js.map +1 -0
- package/dist/git/utils/fileStatus.utils.d.ts +2 -1
- package/dist/git/utils/fileStatus.utils.d.ts.map +1 -1
- package/dist/git/utils/fileStatus.utils.js +4 -0
- package/dist/git/utils/fileStatus.utils.js.map +1 -1
- package/dist/git/utils/search.utils.d.ts.map +1 -1
- package/dist/git/utils/search.utils.js +3 -0
- package/dist/git/utils/search.utils.js.map +1 -1
- package/dist/git/utils/sorting.d.ts +14 -0
- package/dist/git/utils/sorting.d.ts.map +1 -1
- package/dist/git/utils/sorting.js +34 -0
- package/dist/git/utils/sorting.js.map +1 -1
- package/dist/git/utils/status.utils.d.ts.map +1 -1
- package/dist/git/utils/status.utils.js.map +1 -1
- package/dist/git/watching/classifyChange.d.ts.map +1 -1
- package/dist/git/watching/classifyChange.js +8 -0
- package/dist/git/watching/classifyChange.js.map +1 -1
- package/dist/git/watching/gitIgnoreFilter.js +1 -1
- package/dist/git/watching/gitIgnoreFilter.js.map +1 -1
- package/dist/git/watching/initWatcher.d.ts.map +1 -1
- package/dist/git/watching/initWatcher.js.map +1 -1
- package/dist/git/watching/watchGroup.d.ts.map +1 -1
- package/dist/git/watching/watchGroup.js.map +1 -1
- package/dist/git/watching/watchService.d.ts.map +1 -1
- package/dist/git/watching/watchService.js +24 -4
- package/dist/git/watching/watchService.js.map +1 -1
- package/dist/git/watching/watchSession.d.ts.map +1 -1
- package/dist/git/watching/watchSession.js.map +1 -1
- package/dist/git-cli/cliGitProvider.js +1 -1
- package/dist/git-cli/cliGitProvider.js.map +1 -1
- package/dist/git-cli/exec/exec.types.d.ts +1 -1
- package/dist/git-cli/exec/exec.types.d.ts.map +1 -1
- package/dist/git-cli/exec/git.d.ts +31 -6
- package/dist/git-cli/exec/git.d.ts.map +1 -1
- package/dist/git-cli/exec/git.js +70 -9
- package/dist/git-cli/exec/git.js.map +1 -1
- package/dist/git-cli/exec/gitQueue.d.ts +22 -6
- package/dist/git-cli/exec/gitQueue.d.ts.map +1 -1
- package/dist/git-cli/exec/gitQueue.js +88 -24
- package/dist/git-cli/exec/gitQueue.js.map +1 -1
- package/dist/git-cli/parsers/blameParser.d.ts.map +1 -1
- package/dist/git-cli/parsers/blameParser.js.map +1 -1
- package/dist/git-cli/parsers/logParser.d.ts +1 -0
- package/dist/git-cli/parsers/logParser.d.ts.map +1 -1
- package/dist/git-cli/parsers/logParser.js +4 -0
- package/dist/git-cli/parsers/logParser.js.map +1 -1
- package/dist/git-cli/parsers/refParser.d.ts +3 -30
- package/dist/git-cli/parsers/refParser.d.ts.map +1 -1
- package/dist/git-cli/parsers/refParser.js +30 -30
- package/dist/git-cli/parsers/refParser.js.map +1 -1
- package/dist/git-cli/providers/blame.d.ts.map +1 -1
- package/dist/git-cli/providers/blame.js +1 -1
- package/dist/git-cli/providers/blame.js.map +1 -1
- package/dist/git-cli/providers/branches.d.ts +17 -5
- package/dist/git-cli/providers/branches.d.ts.map +1 -1
- package/dist/git-cli/providers/branches.js +245 -162
- 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 +120 -35
- package/dist/git-cli/providers/commits.js.map +1 -1
- package/dist/git-cli/providers/config.d.ts +11 -2
- package/dist/git-cli/providers/config.d.ts.map +1 -1
- package/dist/git-cli/providers/config.js +36 -11
- 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 +7 -4
- package/dist/git-cli/providers/contributors.js.map +1 -1
- package/dist/git-cli/providers/diff.d.ts +2 -0
- package/dist/git-cli/providers/diff.d.ts.map +1 -1
- package/dist/git-cli/providers/diff.js +92 -20
- 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 +49 -28
- package/dist/git-cli/providers/graph.js.map +1 -1
- package/dist/git-cli/providers/operations.d.ts +30 -11
- package/dist/git-cli/providers/operations.d.ts.map +1 -1
- package/dist/git-cli/providers/operations.js +146 -43
- package/dist/git-cli/providers/operations.js.map +1 -1
- package/dist/git-cli/providers/patch.d.ts.map +1 -1
- package/dist/git-cli/providers/patch.js +15 -30
- package/dist/git-cli/providers/patch.js.map +1 -1
- package/dist/git-cli/providers/pausedOperations.d.ts +3 -1
- package/dist/git-cli/providers/pausedOperations.d.ts.map +1 -1
- package/dist/git-cli/providers/pausedOperations.js +13 -7
- package/dist/git-cli/providers/pausedOperations.js.map +1 -1
- package/dist/git-cli/providers/refs.d.ts +19 -2
- package/dist/git-cli/providers/refs.d.ts.map +1 -1
- package/dist/git-cli/providers/refs.js +312 -9
- package/dist/git-cli/providers/refs.js.map +1 -1
- package/dist/git-cli/providers/remotes.js +4 -4
- package/dist/git-cli/providers/remotes.js.map +1 -1
- package/dist/git-cli/providers/revision.d.ts +1 -1
- package/dist/git-cli/providers/revision.d.ts.map +1 -1
- package/dist/git-cli/providers/revision.js +15 -11
- package/dist/git-cli/providers/revision.js.map +1 -1
- package/dist/git-cli/providers/staging.d.ts +8 -0
- package/dist/git-cli/providers/staging.d.ts.map +1 -1
- package/dist/git-cli/providers/staging.js +52 -8
- package/dist/git-cli/providers/staging.js.map +1 -1
- package/dist/git-cli/providers/stash.d.ts +0 -8
- package/dist/git-cli/providers/stash.d.ts.map +1 -1
- package/dist/git-cli/providers/stash.js +63 -119
- package/dist/git-cli/providers/stash.js.map +1 -1
- package/dist/git-cli/providers/status.d.ts +4 -1
- package/dist/git-cli/providers/status.d.ts.map +1 -1
- package/dist/git-cli/providers/status.js +10 -9
- package/dist/git-cli/providers/status.js.map +1 -1
- package/dist/git-cli/providers/tags.d.ts.map +1 -1
- package/dist/git-cli/providers/tags.js +13 -9
- package/dist/git-cli/providers/tags.js.map +1 -1
- package/dist/git-cli/providers/worktrees.js +3 -3
- package/dist/git-cli/providers/worktrees.js.map +1 -1
- package/dist/ipc/discovery.d.ts +27 -0
- package/dist/ipc/discovery.d.ts.map +1 -0
- package/dist/ipc/discovery.js +38 -0
- package/dist/ipc/discovery.js.map +1 -0
- package/dist/ipc/ipcServer.d.ts +20 -0
- package/dist/ipc/ipcServer.d.ts.map +1 -0
- package/dist/ipc/ipcServer.js +162 -0
- package/dist/ipc/ipcServer.js.map +1 -0
- package/dist/plus/agents/providers/claudeCodeProvider.d.ts +114 -0
- package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -0
- package/dist/plus/agents/providers/claudeCodeProvider.js +1480 -0
- package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -0
- package/dist/plus/agents/providers/claudeCodeTranscript.d.ts +36 -0
- package/dist/plus/agents/providers/claudeCodeTranscript.d.ts.map +1 -0
- package/dist/plus/agents/providers/claudeCodeTranscript.js +171 -0
- package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -0
- package/dist/plus/agents/sanitizePrompt.d.ts +15 -0
- package/dist/plus/agents/sanitizePrompt.d.ts.map +1 -0
- package/dist/plus/agents/sanitizePrompt.js +103 -0
- package/dist/plus/agents/sanitizePrompt.js.map +1 -0
- package/dist/plus/agents/stateMachine.d.ts +32 -0
- package/dist/plus/agents/stateMachine.d.ts.map +1 -0
- package/dist/plus/agents/stateMachine.js +180 -0
- package/dist/plus/agents/stateMachine.js.map +1 -0
- package/dist/plus/agents/types.d.ts +203 -0
- package/dist/plus/agents/types.d.ts.map +1 -0
- package/dist/plus/agents/types.js +49 -0
- package/dist/plus/agents/types.js.map +1 -0
- package/dist/plus/ai/constants.d.ts +2 -1
- package/dist/plus/ai/constants.d.ts.map +1 -1
- package/dist/plus/ai/constants.js +7 -0
- package/dist/plus/ai/constants.js.map +1 -1
- package/dist/plus/ai/errors.d.ts +4 -1
- package/dist/plus/ai/errors.d.ts.map +1 -1
- package/dist/plus/ai/errors.js +38 -0
- package/dist/plus/ai/errors.js.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/promptTemplates.d.ts +28 -2
- package/dist/plus/ai/models/promptTemplates.d.ts.map +1 -1
- package/dist/plus/ai/models/results.d.ts +28 -0
- package/dist/plus/ai/models/results.d.ts.map +1 -1
- package/dist/plus/ai/prompts.d.ts +4 -0
- package/dist/plus/ai/prompts.d.ts.map +1 -1
- package/dist/plus/ai/prompts.js +167 -1
- package/dist/plus/ai/prompts.js.map +1 -1
- package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
- package/dist/plus/ai/utils/ai.utils.js +2 -0
- package/dist/plus/ai/utils/ai.utils.js.map +1 -1
- package/dist/plus/ai/utils/results.utils.d.ts +3 -0
- package/dist/plus/ai/utils/results.utils.d.ts.map +1 -1
- package/dist/plus/ai/utils/results.utils.js +75 -0
- package/dist/plus/ai/utils/results.utils.js.map +1 -1
- package/dist/plus/ai/utils/truncation.utils.d.ts +1 -1
- package/dist/plus/ai/utils/truncation.utils.d.ts.map +1 -1
- package/dist/plus/ai/utils/truncation.utils.js.map +1 -1
- package/dist/plus/git-github/api/github.d.ts +10 -1
- package/dist/plus/git-github/api/github.d.ts.map +1 -1
- package/dist/plus/git-github/api/github.js +156 -49
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/git-github/api/types.d.ts +8 -0
- package/dist/plus/git-github/api/types.d.ts.map +1 -1
- package/dist/plus/git-github/models.d.ts +1 -1
- package/dist/plus/git-github/models.d.ts.map +1 -1
- package/dist/plus/git-github/models.js.map +1 -1
- package/dist/plus/git-github/providers/github/blame.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/blame.js.map +1 -1
- package/dist/plus/git-github/providers/github/branches.d.ts +5 -1
- package/dist/plus/git-github/providers/github/branches.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/branches.js +60 -22
- package/dist/plus/git-github/providers/github/branches.js.map +1 -1
- package/dist/plus/git-github/providers/github/commits.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/commits.js +144 -92
- package/dist/plus/git-github/providers/github/commits.js.map +1 -1
- package/dist/plus/git-github/providers/github/diff.d.ts +3 -1
- package/dist/plus/git-github/providers/github/diff.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/diff.js +23 -9
- package/dist/plus/git-github/providers/github/diff.js.map +1 -1
- package/dist/plus/git-github/providers/github/refs.d.ts +9 -1
- package/dist/plus/git-github/providers/github/refs.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/refs.js +38 -13
- package/dist/plus/git-github/providers/github/refs.js.map +1 -1
- package/dist/plus/git-github/providers/github/revision.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/revision.js +1 -2
- package/dist/plus/git-github/providers/github/revision.js.map +1 -1
- package/dist/plus/git-github/providers/github/status.d.ts +4 -1
- package/dist/plus/git-github/providers/github/status.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/status.js +1 -1
- package/dist/plus/git-github/providers/github/status.js.map +1 -1
- package/dist/plus/git-github/providers/github/tags.d.ts.map +1 -1
- package/dist/plus/git-github/providers/github/tags.js +35 -36
- package/dist/plus/git-github/providers/github/tags.js.map +1 -1
- package/dist/plus/git-github/providers/githubGitProvider.d.ts.map +1 -1
- package/dist/plus/git-github/providers/githubGitProvider.js.map +1 -1
- package/dist/utils/color.d.ts.map +1 -1
- package/dist/utils/color.js.map +1 -1
- package/dist/utils/decorators/log.js +1 -1
- package/dist/utils/decorators/log.js.map +1 -1
- package/dist/utils/decorators/sequentialize.d.ts.map +1 -1
- package/dist/utils/decorators/sequentialize.js +4 -2
- package/dist/utils/decorators/sequentialize.js.map +1 -1
- package/dist/utils/decorators/serializable.d.ts.map +1 -1
- package/dist/utils/decorators/serializable.js.map +1 -1
- package/dist/utils/dedupedAsyncCache.d.ts +37 -0
- package/dist/utils/dedupedAsyncCache.d.ts.map +1 -0
- package/dist/utils/dedupedAsyncCache.js +68 -0
- package/dist/utils/dedupedAsyncCache.js.map +1 -0
- package/dist/utils/diff.d.ts +2 -0
- package/dist/utils/diff.d.ts.map +1 -0
- package/dist/utils/diff.js +53 -0
- package/dist/utils/diff.js.map +1 -0
- package/dist/utils/disposable.d.ts.map +1 -1
- package/dist/utils/disposable.js.map +1 -1
- package/dist/utils/env/node/base64.js.map +1 -1
- package/dist/utils/env/node/exec.d.ts.map +1 -1
- package/dist/utils/env/node/exec.js.map +1 -1
- package/dist/utils/error.d.ts.map +1 -1
- package/dist/utils/error.js.map +1 -1
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +4 -10
- package/dist/utils/formatter.js.map +1 -1
- package/dist/utils/iterable.d.ts.map +1 -1
- package/dist/utils/iterable.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/lruMap.d.ts +49 -0
- package/dist/utils/lruMap.d.ts.map +1 -0
- package/dist/utils/lruMap.js +103 -0
- package/dist/utils/lruMap.js.map +1 -0
- package/dist/utils/markdown.d.ts.map +1 -1
- package/dist/utils/markdown.js.map +1 -1
- package/dist/utils/mru.d.ts.map +1 -1
- package/dist/utils/mru.js.map +1 -1
- package/dist/utils/path.d.ts.map +1 -1
- package/dist/utils/path.js.map +1 -1
- package/dist/utils/promise.d.ts +1 -0
- package/dist/utils/promise.d.ts.map +1 -1
- package/dist/utils/promise.js +17 -0
- package/dist/utils/promise.js.map +1 -1
- package/dist/utils/promiseCache.d.ts +10 -0
- package/dist/utils/promiseCache.d.ts.map +1 -1
- package/dist/utils/promiseCache.js +22 -0
- package/dist/utils/promiseCache.js.map +1 -1
- package/dist/utils/string.d.ts.map +1 -1
- package/dist/utils/string.js.map +1 -1
- package/dist/utils/uri.d.ts.map +1 -1
- package/dist/utils/uri.js.map +1 -1
- package/dist/utils/version.d.ts +14 -0
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +48 -0
- package/dist/utils/version.js.map +1 -1
- package/package.json +13 -1
- package/src/git/cache.ts +309 -29
- package/src/git/context.ts +11 -2
- package/src/git/models/branch.ts +1 -0
- package/src/git/models/commit.ts +2 -17
- package/src/git/models/graph.ts +2 -4
- package/src/git/models/reference.ts +33 -0
- package/src/git/models/remote.ts +1 -0
- package/src/git/models/repository.ts +44 -6
- package/src/git/models/search.ts +2 -2
- package/src/git/models/worktree.ts +10 -2
- package/src/git/parsers/diffParser.ts +9 -44
- package/src/git/providers/branches.ts +25 -4
- package/src/git/providers/commits.ts +7 -0
- package/src/git/providers/config.ts +4 -0
- package/src/git/providers/diff.ts +8 -2
- package/src/git/providers/operations.ts +54 -3
- package/src/git/providers/pausedOperations.ts +1 -0
- package/src/git/providers/refs.ts +32 -3
- package/src/git/providers/revision.ts +5 -1
- package/src/git/providers/staging.ts +14 -0
- package/src/git/providers/status.ts +6 -1
- package/src/git/remotes/azure-devops.ts +2 -0
- package/src/git/{exec.types.ts → run.types.ts} +22 -2
- package/src/git/service.ts +1 -0
- package/src/git/utils/autolink.utils.ts +1 -0
- package/src/git/utils/blame.utils.ts +2 -0
- package/src/git/utils/conflictResolution.utils.ts +31 -0
- package/src/git/utils/fileStatus.utils.ts +7 -1
- package/src/git/utils/search.utils.ts +2 -0
- package/src/git/utils/sorting.ts +38 -0
- package/src/git/utils/status.utils.ts +1 -0
- package/src/git/watching/classifyChange.ts +9 -0
- package/src/git/watching/gitIgnoreFilter.ts +2 -2
- package/src/git/watching/initWatcher.ts +2 -0
- package/src/git/watching/watchGroup.ts +3 -0
- package/src/git/watching/watchService.ts +38 -5
- package/src/git/watching/watchSession.ts +10 -0
- package/src/git-cli/cliGitProvider.ts +1 -1
- package/src/git-cli/exec/exec.types.ts +2 -2
- package/src/git-cli/exec/git.ts +76 -23
- package/src/git-cli/exec/gitQueue.ts +98 -25
- package/src/git-cli/parsers/blameParser.ts +1 -0
- package/src/git-cli/parsers/logParser.ts +6 -1
- package/src/git-cli/parsers/refParser.ts +33 -34
- package/src/git-cli/providers/blame.ts +2 -1
- package/src/git-cli/providers/branches.ts +341 -196
- package/src/git-cli/providers/commits.ts +145 -46
- package/src/git-cli/providers/config.ts +50 -16
- package/src/git-cli/providers/contributors.ts +7 -12
- package/src/git-cli/providers/diff.ts +107 -20
- package/src/git-cli/providers/graph.ts +58 -29
- package/src/git-cli/providers/operations.ts +253 -57
- package/src/git-cli/providers/patch.ts +16 -37
- package/src/git-cli/providers/pausedOperations.ts +14 -6
- package/src/git-cli/providers/refs.ts +274 -11
- package/src/git-cli/providers/remotes.ts +4 -4
- package/src/git-cli/providers/revision.ts +22 -15
- package/src/git-cli/providers/staging.ts +51 -8
- package/src/git-cli/providers/stash.ts +67 -134
- package/src/git-cli/providers/status.ts +21 -10
- package/src/git-cli/providers/tags.ts +18 -19
- package/src/git-cli/providers/worktrees.ts +3 -3
- package/src/ipc/discovery.ts +56 -0
- package/src/ipc/ipcServer.ts +171 -0
- package/src/plus/agents/providers/claudeCodeProvider.ts +1782 -0
- package/src/plus/agents/providers/claudeCodeTranscript.ts +214 -0
- package/src/plus/agents/sanitizePrompt.ts +109 -0
- package/src/plus/agents/stateMachine.ts +197 -0
- package/src/plus/agents/types.ts +277 -0
- package/src/plus/ai/constants.ts +8 -0
- package/src/plus/ai/errors.ts +40 -0
- package/src/plus/ai/models/model.ts +1 -0
- package/src/plus/ai/models/promptTemplates.ts +42 -0
- package/src/plus/ai/models/results.ts +30 -0
- package/src/plus/ai/prompts.ts +171 -1
- package/src/plus/ai/utils/ai.utils.ts +2 -0
- package/src/plus/ai/utils/results.utils.ts +101 -0
- package/src/plus/ai/utils/truncation.utils.ts +3 -1
- package/src/plus/git-github/api/github.ts +199 -53
- package/src/plus/git-github/api/types.ts +15 -0
- package/src/plus/git-github/models.ts +1 -1
- package/src/plus/git-github/providers/github/blame.ts +2 -0
- package/src/plus/git-github/providers/github/branches.ts +75 -33
- package/src/plus/git-github/providers/github/commits.ts +231 -160
- package/src/plus/git-github/providers/github/diff.ts +35 -21
- package/src/plus/git-github/providers/github/refs.ts +57 -22
- package/src/plus/git-github/providers/github/revision.ts +1 -2
- package/src/plus/git-github/providers/github/status.ts +6 -1
- package/src/plus/git-github/providers/github/tags.ts +61 -62
- package/src/plus/git-github/providers/githubGitProvider.ts +1 -0
- package/src/utils/color.ts +2 -0
- package/src/utils/decorators/log.ts +1 -1
- package/src/utils/decorators/sequentialize.ts +8 -6
- package/src/utils/decorators/serializable.ts +1 -0
- package/src/utils/dedupedAsyncCache.ts +74 -0
- package/src/utils/diff.ts +61 -0
- package/src/utils/disposable.ts +2 -0
- package/src/utils/env/node/base64.ts +1 -1
- package/src/utils/env/node/exec.ts +4 -2
- package/src/utils/error.ts +1 -0
- package/src/utils/formatter.ts +4 -11
- package/src/utils/iterable.ts +4 -1
- package/src/utils/logger.ts +1 -0
- package/src/utils/lruMap.ts +112 -0
- package/src/utils/markdown.ts +1 -0
- package/src/utils/mru.ts +2 -0
- package/src/utils/path.ts +1 -0
- package/src/utils/promise.ts +22 -0
- package/src/utils/promiseCache.ts +24 -0
- package/src/utils/string.ts +2 -0
- package/src/utils/uri.ts +1 -0
- package/src/utils/version.ts +49 -0
- package/dist/git/exec.types.d.ts.map +0 -1
- package/dist/git/exec.types.js +0 -2
- package/dist/git/exec.types.js.map +0 -1
|
@@ -97,6 +97,7 @@ export class RepositoryWatchSession implements UnifiedDisposable {
|
|
|
97
97
|
|
|
98
98
|
dispose(): void {
|
|
99
99
|
if (this._disposed) return;
|
|
100
|
+
|
|
100
101
|
this._disposed = true;
|
|
101
102
|
|
|
102
103
|
this.cancelRepoTimer();
|
|
@@ -175,6 +176,7 @@ export class RepositoryWatchSession implements UnifiedDisposable {
|
|
|
175
176
|
return Object.assign(
|
|
176
177
|
createDisposable(() => {
|
|
177
178
|
if (subDisposed) return;
|
|
179
|
+
|
|
178
180
|
subDisposed = true;
|
|
179
181
|
|
|
180
182
|
this.repoDelays.delete(id);
|
|
@@ -221,6 +223,7 @@ export class RepositoryWatchSession implements UnifiedDisposable {
|
|
|
221
223
|
return Object.assign(
|
|
222
224
|
createDisposable(() => {
|
|
223
225
|
if (subDisposed) return;
|
|
226
|
+
|
|
224
227
|
subDisposed = true;
|
|
225
228
|
|
|
226
229
|
this.wtDelays.delete(id);
|
|
@@ -245,6 +248,7 @@ export class RepositoryWatchSession implements UnifiedDisposable {
|
|
|
245
248
|
|
|
246
249
|
resume(delayMs?: number): void {
|
|
247
250
|
if (!this._suspended) return;
|
|
251
|
+
|
|
248
252
|
this._suspended = false;
|
|
249
253
|
|
|
250
254
|
// Flush accumulated changes
|
|
@@ -259,30 +263,35 @@ export class RepositoryWatchSession implements UnifiedDisposable {
|
|
|
259
263
|
/** Inject changes (e.g., after a git operation the caller performed). Goes through debounce + suspend. */
|
|
260
264
|
fireChange(...changes: RepositoryChange[]): void {
|
|
261
265
|
if (this._disposed || changes.length === 0) return;
|
|
266
|
+
|
|
262
267
|
this.coalesceRepo(changes);
|
|
263
268
|
}
|
|
264
269
|
|
|
265
270
|
/** Immediate fire, bypassing debounce + suspend (for Closed/Opened). */
|
|
266
271
|
fireChangeImmediate(...changes: RepositoryChange[]): void {
|
|
267
272
|
if (this._disposed || changes.length === 0) return;
|
|
273
|
+
|
|
268
274
|
this.repoEmitter.fire(new WatcherRepoChangeEvent(this.repoPath, changes));
|
|
269
275
|
}
|
|
270
276
|
|
|
271
277
|
/** Push interpreted repo changes into the pipeline */
|
|
272
278
|
pushRepoChanges(changes: RepositoryChange[]): void {
|
|
273
279
|
if (this._disposed) return;
|
|
280
|
+
|
|
274
281
|
this.coalesceRepo(changes);
|
|
275
282
|
}
|
|
276
283
|
|
|
277
284
|
/** Push working tree file changes into the pipeline */
|
|
278
285
|
pushWorkingTreeChanges(paths: Iterable<string>): void {
|
|
279
286
|
if (this._disposed) return;
|
|
287
|
+
|
|
280
288
|
this._etagWorkingTree++;
|
|
281
289
|
this.coalesceWT(paths);
|
|
282
290
|
}
|
|
283
291
|
|
|
284
292
|
private static minDelay(delays: Map<number, number>, fallback: number): number {
|
|
285
293
|
if (delays.size === 0) return fallback;
|
|
294
|
+
|
|
286
295
|
let min = fallback;
|
|
287
296
|
for (const d of delays.values()) {
|
|
288
297
|
if (d < min) {
|
|
@@ -304,6 +313,7 @@ export class RepositoryWatchSession implements UnifiedDisposable {
|
|
|
304
313
|
this.repoTimer = undefined;
|
|
305
314
|
const event = this.pendingRepoEvent;
|
|
306
315
|
if (event == null) return;
|
|
316
|
+
|
|
307
317
|
this.pendingRepoEvent = undefined;
|
|
308
318
|
this.repoEmitter.fire(event);
|
|
309
319
|
this.onDidFireRepoChangeCallback?.(event);
|
|
@@ -146,7 +146,7 @@ export class CliGitProvider implements GitProvider {
|
|
|
146
146
|
folderPath = joinPaths(parentPath, `${remoteName}-${count}`);
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
await this._git.
|
|
149
|
+
await this._git.run({ cwd: parentPath }, 'clone', url, folderPath);
|
|
150
150
|
|
|
151
151
|
return folderPath;
|
|
152
152
|
}
|
package/src/git-cli/exec/git.ts
CHANGED
|
@@ -17,6 +17,7 @@ import type {
|
|
|
17
17
|
ResetErrorReason,
|
|
18
18
|
RevertErrorReason,
|
|
19
19
|
ShowErrorReason,
|
|
20
|
+
SigningErrorReason,
|
|
20
21
|
StashApplyErrorReason,
|
|
21
22
|
StashPushErrorReason,
|
|
22
23
|
TagErrorReason,
|
|
@@ -24,6 +25,7 @@ import type {
|
|
|
24
25
|
WorktreeDeleteErrorReason,
|
|
25
26
|
} from '../../git/errors.js';
|
|
26
27
|
import { WorkspaceUntrustedError } from '../../git/errors.js';
|
|
28
|
+
import type { SigningFormat } from '../../git/models/signature.js';
|
|
27
29
|
import { CancellationError, getAbortSignalId, isCancellationError } from '../../utils/cancellation.js';
|
|
28
30
|
import { getScopedCounter } from '../../utils/counter.js';
|
|
29
31
|
import { getDurationMilliseconds, hrtime } from '../../utils/hrtime.js';
|
|
@@ -37,7 +39,7 @@ import { compare, fromString } from '../../utils/version.js';
|
|
|
37
39
|
import { CancelledRunError, RunError } from './exec.errors.js';
|
|
38
40
|
import type { RunOptions, RunResult } from './exec.js';
|
|
39
41
|
import { fsExists, runSpawn } from './exec.js';
|
|
40
|
-
import type { GitCommandPriority,
|
|
42
|
+
import type { GitCommandPriority, GitResult, GitRunOptions, GitSpawnOptions } from './exec.types.js';
|
|
41
43
|
import type { FilteredGitFeatures, GitFeatureOrPrefix, GitFeatures } from './features.js';
|
|
42
44
|
import { gitFeaturesByVersion } from './features.js';
|
|
43
45
|
import type { GitQueueConfig } from './gitQueue.js';
|
|
@@ -74,6 +76,8 @@ export const GitErrors = {
|
|
|
74
76
|
detachedHead: /You are in 'detached HEAD' state/i,
|
|
75
77
|
entryNotUpToDate: /error:\s*Entry ['"].+['"] not uptodate\. Cannot merge\./i,
|
|
76
78
|
failedToDeleteDirectoryNotEmpty: /failed to delete '(.*?)': Directory not empty/i,
|
|
79
|
+
gpgNotFound: /gpg:?\s*(?:command\s+)?not found|'gpg' is not recognized as|cannot run gpg:/i,
|
|
80
|
+
gpgSignFailed: /^error:\s*gpg failed to sign the data/im,
|
|
77
81
|
invalidName: /fatal:\s*'.+?' is not a valid branch name/i,
|
|
78
82
|
invalidLineCount: /file .+? has only (\d+) lines/i,
|
|
79
83
|
invalidObjectName: /invalid object name: (.*)\s/i,
|
|
@@ -106,6 +110,8 @@ export const GitErrors = {
|
|
|
106
110
|
remoteAhead: /rejected because the remote contains work/i,
|
|
107
111
|
remoteConnectionFailed: /Could not read from remote repository/i,
|
|
108
112
|
remoteRejected: /rejected because the remote contains work/i,
|
|
113
|
+
signingKeyNotAvailable: /secret key not available|no secret key|no signing key/i,
|
|
114
|
+
sshNotFound: /ssh-keygen[^\n]*(?:not found|No such file or directory|is not recognized)/i,
|
|
109
115
|
stashConflictingStagedAndUnstagedLines: /Cannot remove worktree changes/i,
|
|
110
116
|
stashNothingToSave: /No local changes to save/i,
|
|
111
117
|
stashSavedWorkingDirAndIndexState: /Saved working directory and index state/i,
|
|
@@ -413,6 +419,52 @@ export function getGitCommandError<T extends GitCommand, TReturn extends GitComm
|
|
|
413
419
|
return creator(undefined);
|
|
414
420
|
}
|
|
415
421
|
|
|
422
|
+
function extractSigningErrorText(ex: unknown): string {
|
|
423
|
+
if (ex == null) return '';
|
|
424
|
+
if (ex instanceof GitError) return ex.stderr || ex.stdout || ex.message || '';
|
|
425
|
+
if (ex instanceof Error) return ex.message || '';
|
|
426
|
+
if (typeof ex === 'string') return ex;
|
|
427
|
+
if (typeof ex === 'number' || typeof ex === 'boolean' || typeof ex === 'bigint') return String(ex);
|
|
428
|
+
if (typeof ex === 'object' && 'message' in ex && typeof ex.message === 'string') return ex.message;
|
|
429
|
+
return '';
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Classifies a Git error as a signing-related failure using the {@link GitErrors}
|
|
434
|
+
* signing regexes. Returns the matched {@link SigningErrorReason}, or `undefined`
|
|
435
|
+
* when the error is not a recognized signing failure.
|
|
436
|
+
*
|
|
437
|
+
* Precedence is significant: `passphraseFailed` (gpg sign failure) is checked
|
|
438
|
+
* before `noKey`, matching the ordering used historically in patch.ts — a
|
|
439
|
+
* combined stderr like "error: gpg failed to sign … gpg: No secret key"
|
|
440
|
+
* resolves to `passphraseFailed`, the outer cause.
|
|
441
|
+
*/
|
|
442
|
+
export function classifySigningError(ex: unknown): SigningErrorReason | undefined {
|
|
443
|
+
const text = extractSigningErrorText(ex);
|
|
444
|
+
if (!text) return undefined;
|
|
445
|
+
if (GitErrors.gpgSignFailed.test(text)) return 'passphraseFailed';
|
|
446
|
+
if (GitErrors.signingKeyNotAvailable.test(text)) return 'noKey';
|
|
447
|
+
if (GitErrors.gpgNotFound.test(text)) return 'gpgNotFound';
|
|
448
|
+
if (GitErrors.sshNotFound.test(text)) return 'sshNotFound';
|
|
449
|
+
return undefined;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Infers the {@link SigningFormat} from stderr hints (e.g., mentions of
|
|
454
|
+
* `ssh-keygen` or `gpg.ssh.*` config keys). Returns `undefined` when no hints
|
|
455
|
+
* are present so callers can supply their own default (typically `'gpg'`).
|
|
456
|
+
*
|
|
457
|
+
* Used as a fallback when `config.getSigningConfig` is unavailable or rejects
|
|
458
|
+
* on the error path.
|
|
459
|
+
*/
|
|
460
|
+
export function inferSigningFormatFromError(ex: unknown): SigningFormat | undefined {
|
|
461
|
+
const text = extractSigningErrorText(ex);
|
|
462
|
+
if (!text) return undefined;
|
|
463
|
+
if (/\bssh-keygen\b|gpg\.ssh\.(?:program|allowedsignersfile)/i.test(text)) return 'ssh';
|
|
464
|
+
if (/\bgpg\b/i.test(text)) return 'gpg';
|
|
465
|
+
return undefined;
|
|
466
|
+
}
|
|
467
|
+
|
|
416
468
|
export interface GitOptions {
|
|
417
469
|
/** Custom environment variables to add to every git command */
|
|
418
470
|
env?: Record<string, string | undefined>;
|
|
@@ -456,7 +508,7 @@ const trailingNewlineRegex = /[\r|\n]+$/;
|
|
|
456
508
|
const uniqueCounterForStdin = getScopedCounter();
|
|
457
509
|
const uniqueCounterForStream = getScopedCounter();
|
|
458
510
|
|
|
459
|
-
type ExitCodeOnlyGitCommandOptions =
|
|
511
|
+
type ExitCodeOnlyGitCommandOptions = GitRunOptions & { exitCodeOnly: true };
|
|
460
512
|
|
|
461
513
|
export class Git {
|
|
462
514
|
/** Map of running git commands — avoids running duplicate overlapping commands */
|
|
@@ -579,16 +631,16 @@ export class Git {
|
|
|
579
631
|
);
|
|
580
632
|
}
|
|
581
633
|
|
|
582
|
-
async
|
|
634
|
+
async run(
|
|
583
635
|
options: ExitCodeOnlyGitCommandOptions,
|
|
584
636
|
...args: readonly (string | undefined)[]
|
|
585
637
|
): Promise<GitResult<unknown>>;
|
|
586
|
-
async
|
|
587
|
-
options:
|
|
638
|
+
async run<T extends string | Buffer = string>(
|
|
639
|
+
options: GitRunOptions,
|
|
588
640
|
...args: readonly (string | undefined)[]
|
|
589
641
|
): Promise<GitResult<T>>;
|
|
590
|
-
async
|
|
591
|
-
options:
|
|
642
|
+
async run<T extends string | Buffer = string>(
|
|
643
|
+
options: GitRunOptions,
|
|
592
644
|
...args: readonly (string | undefined)[]
|
|
593
645
|
): Promise<GitResult<T | unknown>> {
|
|
594
646
|
if (this.options.isTrusted?.() === false) throw new WorkspaceUntrustedError();
|
|
@@ -602,7 +654,7 @@ export class Git {
|
|
|
602
654
|
options.caching.commonPath ?? options.cwd!,
|
|
603
655
|
gitCommand,
|
|
604
656
|
async cacheable => {
|
|
605
|
-
const result = await this.
|
|
657
|
+
const result = await this.runCore<T>({ ...options, caching: undefined }, runArgs, gitCommand);
|
|
606
658
|
if (result.exitCode !== 0) {
|
|
607
659
|
cacheable.invalidate();
|
|
608
660
|
}
|
|
@@ -612,11 +664,11 @@ export class Git {
|
|
|
612
664
|
);
|
|
613
665
|
}
|
|
614
666
|
|
|
615
|
-
return this.
|
|
667
|
+
return this.runCore<T>(options, runArgs, gitCommand);
|
|
616
668
|
}
|
|
617
669
|
|
|
618
|
-
private async
|
|
619
|
-
options:
|
|
670
|
+
private async runCore<T extends string | Buffer>(
|
|
671
|
+
options: GitRunOptions,
|
|
620
672
|
args: string[],
|
|
621
673
|
gitCommand: string,
|
|
622
674
|
): Promise<GitResult<T | unknown>> {
|
|
@@ -679,7 +731,7 @@ export class Git {
|
|
|
679
731
|
// Execute through the queue (interactive/normal run immediately, background is throttled)
|
|
680
732
|
const gitPath = await this.path();
|
|
681
733
|
void this._queue
|
|
682
|
-
.
|
|
734
|
+
.run(priority, () => runSpawn<T>(gitPath, args, encoding ?? 'utf8', runOpts), cancellation)
|
|
683
735
|
.then(deferred.fulfill, (e: unknown) => deferred.cancel(e instanceof Error ? e : new Error(String(e))))
|
|
684
736
|
.finally(() => {
|
|
685
737
|
this.pendingCommands.delete(cacheKey);
|
|
@@ -695,8 +747,8 @@ export class Git {
|
|
|
695
747
|
try {
|
|
696
748
|
result = await promise;
|
|
697
749
|
return {
|
|
698
|
-
stdout: result.stdout
|
|
699
|
-
stderr: result.stderr
|
|
750
|
+
stdout: result.stdout,
|
|
751
|
+
stderr: result.stderr,
|
|
700
752
|
exitCode: result.exitCode ?? 0,
|
|
701
753
|
};
|
|
702
754
|
} catch (ex) {
|
|
@@ -723,15 +775,15 @@ export class Git {
|
|
|
723
775
|
if (errorHandling === 'ignore') {
|
|
724
776
|
if (ex instanceof RunError) {
|
|
725
777
|
return {
|
|
726
|
-
stdout: ex.stdout
|
|
727
|
-
stderr: ex.stderr
|
|
778
|
+
stdout: ex.stdout,
|
|
779
|
+
stderr: ex.stderr,
|
|
728
780
|
exitCode: ex.code != null ? (typeof ex.code === 'number' ? ex.code : parseInt(ex.code, 10)) : 0,
|
|
729
781
|
cancelled: ex instanceof CancelledRunError,
|
|
730
782
|
};
|
|
731
783
|
}
|
|
732
784
|
|
|
733
785
|
return {
|
|
734
|
-
stdout: ''
|
|
786
|
+
stdout: '',
|
|
735
787
|
stderr: undefined,
|
|
736
788
|
exitCode: 0,
|
|
737
789
|
cancelled: ex instanceof CancelledRunError,
|
|
@@ -747,7 +799,7 @@ export class Git {
|
|
|
747
799
|
|
|
748
800
|
defaultExceptionHandler(exception, options.cwd, start);
|
|
749
801
|
exception = undefined;
|
|
750
|
-
return { stdout: ''
|
|
802
|
+
return { stdout: '', stderr: result?.stderr, exitCode: result?.exitCode ?? 0 };
|
|
751
803
|
} finally {
|
|
752
804
|
this.logGitCommandComplete(gitCommand, exception, getDurationMilliseconds(start), waiting);
|
|
753
805
|
}
|
|
@@ -854,6 +906,7 @@ export class Git {
|
|
|
854
906
|
let cleanedUp = false;
|
|
855
907
|
const cleanup = () => {
|
|
856
908
|
if (cleanedUp) return;
|
|
909
|
+
|
|
857
910
|
cleanedUp = true;
|
|
858
911
|
|
|
859
912
|
try {
|
|
@@ -888,7 +941,7 @@ export class Git {
|
|
|
888
941
|
for await (const chunk of proc.stdout) {
|
|
889
942
|
buffers.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
890
943
|
}
|
|
891
|
-
yield await decode(Buffer.concat(buffers
|
|
944
|
+
yield await decode(Buffer.concat(buffers), { encoding: enc });
|
|
892
945
|
}
|
|
893
946
|
}
|
|
894
947
|
} finally {
|
|
@@ -914,7 +967,7 @@ export class Git {
|
|
|
914
967
|
}
|
|
915
968
|
|
|
916
969
|
async rev_parse__git_dir(cwd: string): Promise<{ path: string; commonPath?: string } | undefined> {
|
|
917
|
-
const result = await this.
|
|
970
|
+
const result = await this.run({ cwd: cwd, errors: 'ignore' }, 'rev-parse', '--git-dir', '--git-common-dir');
|
|
918
971
|
if (!result.stdout) return undefined;
|
|
919
972
|
|
|
920
973
|
// Keep trailing spaces which are part of the directory name
|
|
@@ -946,7 +999,7 @@ export class Git {
|
|
|
946
999
|
// Check if the folder is a bare clone: if it has a file named HEAD && `rev-parse --show-cdup` is empty
|
|
947
1000
|
if (await fsExists(joinPaths(cwd, 'HEAD'))) {
|
|
948
1001
|
try {
|
|
949
|
-
result = await this.
|
|
1002
|
+
result = await this.run(
|
|
950
1003
|
{ cwd: cwd, errors: 'throw', configs: ['-C', cwd] },
|
|
951
1004
|
'rev-parse',
|
|
952
1005
|
'--show-cdup',
|
|
@@ -962,7 +1015,7 @@ export class Git {
|
|
|
962
1015
|
}
|
|
963
1016
|
|
|
964
1017
|
try {
|
|
965
|
-
result = await this.
|
|
1018
|
+
result = await this.run({ cwd: cwd, errors: 'throw' }, 'rev-parse', '--show-toplevel');
|
|
966
1019
|
// Make sure to normalize: https://github.com/git-for-windows/git/issues/2478
|
|
967
1020
|
// Keep trailing spaces which are part of the directory name
|
|
968
1021
|
return !result.stdout
|
|
@@ -985,7 +1038,7 @@ export class Git {
|
|
|
985
1038
|
const inDotGit = GitWarnings.mustRunInWorkTree.test(ex.stderr ?? '');
|
|
986
1039
|
// Check if we are in a bare clone
|
|
987
1040
|
if (inDotGit && this.options.isTrusted?.() !== false) {
|
|
988
|
-
result = await this.
|
|
1041
|
+
result = await this.run({ cwd: cwd, errors: 'ignore' }, 'rev-parse', '--is-bare-repository');
|
|
989
1042
|
if (result.stdout.trim() === 'true') {
|
|
990
1043
|
const result = await this.rev_parse__git_dir(cwd);
|
|
991
1044
|
const repoPath = result?.commonPath ?? result?.path;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { GitCommandPriority } from './exec.types.js';
|
|
2
2
|
|
|
3
3
|
interface QueuedCommand {
|
|
4
|
-
|
|
4
|
+
run: () => Promise<unknown>;
|
|
5
5
|
resolve: (value: unknown) => void;
|
|
6
6
|
reject: (reason: unknown) => void;
|
|
7
7
|
queuedAt: number;
|
|
8
8
|
priority: GitCommandPriority;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
abortHandler?: () => void;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
/** Priority levels in descending order (highest first) */
|
|
@@ -14,6 +16,10 @@ const priorities: GitCommandPriority[] = ['interactive', 'normal', 'background']
|
|
|
14
16
|
/** How many extra slots interactive commands can use when at capacity */
|
|
15
17
|
const interactiveBurstCapacity = 2;
|
|
16
18
|
|
|
19
|
+
function abortReason(signal: AbortSignal): Error {
|
|
20
|
+
return signal.reason instanceof Error ? signal.reason : new Error('Aborted');
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
export interface GitQueueConfig {
|
|
18
24
|
/** Maximum number of concurrent git processes. Defaults to 7. */
|
|
19
25
|
maxConcurrent?: number;
|
|
@@ -67,6 +73,9 @@ export class GitQueue {
|
|
|
67
73
|
this._disposed = true;
|
|
68
74
|
for (const queue of this._queues.values()) {
|
|
69
75
|
for (const cmd of queue) {
|
|
76
|
+
if (cmd.signal != null && cmd.abortHandler != null) {
|
|
77
|
+
cmd.signal.removeEventListener('abort', cmd.abortHandler);
|
|
78
|
+
}
|
|
70
79
|
cmd.reject(new Error('GitQueue disposed'));
|
|
71
80
|
}
|
|
72
81
|
queue.length = 0;
|
|
@@ -89,7 +98,7 @@ export class GitQueue {
|
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
/** Check if a command at the given priority can execute immediately */
|
|
92
|
-
private
|
|
101
|
+
private canRunNow(priority: GitCommandPriority): boolean {
|
|
93
102
|
// Must yield to higher priority waiting
|
|
94
103
|
if (this.hasHigherPriorityWaiting(priority)) return false;
|
|
95
104
|
|
|
@@ -115,20 +124,32 @@ export class GitQueue {
|
|
|
115
124
|
return false;
|
|
116
125
|
}
|
|
117
126
|
|
|
118
|
-
/**
|
|
119
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Execute a git command with the specified priority.
|
|
129
|
+
*
|
|
130
|
+
* When `signal` is provided:
|
|
131
|
+
* - If already aborted, rejects immediately without running.
|
|
132
|
+
* - If aborted while queued, the command is removed from the queue and rejected before it ever runs.
|
|
133
|
+
* - If aborted while running, the in-flight spawn must honor the same signal separately
|
|
134
|
+
* (callers pass it via `runOpts.cancellation`); the queue does not interrupt running work.
|
|
135
|
+
*/
|
|
136
|
+
run<T>(priority: GitCommandPriority, fn: () => Promise<T>, signal?: AbortSignal): Promise<T> {
|
|
120
137
|
if (this._disposed) {
|
|
121
138
|
return Promise.reject(new Error('GitQueue disposed'));
|
|
122
139
|
}
|
|
123
140
|
|
|
124
|
-
if (
|
|
125
|
-
return
|
|
141
|
+
if (signal?.aborted) {
|
|
142
|
+
return Promise.reject(abortReason(signal));
|
|
126
143
|
}
|
|
127
144
|
|
|
128
|
-
|
|
145
|
+
if (!this.canRunNow(priority)) {
|
|
146
|
+
return this.enqueue(fn, priority, signal);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return this.runcore(fn);
|
|
129
150
|
}
|
|
130
151
|
|
|
131
|
-
private async
|
|
152
|
+
private async runcore<T>(fn: () => Promise<T>): Promise<T> {
|
|
132
153
|
this._activeCount++;
|
|
133
154
|
try {
|
|
134
155
|
return await fn();
|
|
@@ -138,7 +159,7 @@ export class GitQueue {
|
|
|
138
159
|
}
|
|
139
160
|
}
|
|
140
161
|
|
|
141
|
-
private enqueue<T>(fn: () => Promise<T>, priority: GitCommandPriority): Promise<T> {
|
|
162
|
+
private enqueue<T>(fn: () => Promise<T>, priority: GitCommandPriority, signal?: AbortSignal): Promise<T> {
|
|
142
163
|
const queue = this._queues.get(priority)!;
|
|
143
164
|
const maxDepth = this._config.maxQueueDepth ?? 500;
|
|
144
165
|
if (maxDepth > 0 && queue.length >= maxDepth) {
|
|
@@ -146,13 +167,29 @@ export class GitQueue {
|
|
|
146
167
|
}
|
|
147
168
|
|
|
148
169
|
return new Promise<T>((resolve, reject) => {
|
|
149
|
-
|
|
150
|
-
|
|
170
|
+
const cmd: QueuedCommand = {
|
|
171
|
+
run: fn,
|
|
151
172
|
resolve: resolve as (value: unknown) => void,
|
|
152
173
|
reject: reject,
|
|
153
174
|
queuedAt: Date.now(),
|
|
154
175
|
priority: priority,
|
|
155
|
-
|
|
176
|
+
signal: signal,
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
if (signal != null) {
|
|
180
|
+
cmd.abortHandler = () => {
|
|
181
|
+
const idx = queue.indexOf(cmd);
|
|
182
|
+
// If still queued, remove and reject so it never runs.
|
|
183
|
+
// If already dequeued, the running command should honor the signal at its own layer.
|
|
184
|
+
if (idx !== -1) {
|
|
185
|
+
queue.splice(idx, 1);
|
|
186
|
+
cmd.reject(abortReason(signal));
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
signal.addEventListener('abort', cmd.abortHandler, { once: true });
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
queue.push(cmd);
|
|
156
193
|
});
|
|
157
194
|
}
|
|
158
195
|
|
|
@@ -172,6 +209,13 @@ export class GitQueue {
|
|
|
172
209
|
}
|
|
173
210
|
|
|
174
211
|
private runQueued(cmd: QueuedCommand): void {
|
|
212
|
+
// Detach the abort listener now that the command has left the queue — any subsequent
|
|
213
|
+
// abort must be handled by the running spawn itself (via runOpts.cancellation).
|
|
214
|
+
if (cmd.signal != null && cmd.abortHandler != null) {
|
|
215
|
+
cmd.signal.removeEventListener('abort', cmd.abortHandler);
|
|
216
|
+
cmd.abortHandler = undefined;
|
|
217
|
+
}
|
|
218
|
+
|
|
175
219
|
const waitTime = Date.now() - cmd.queuedAt;
|
|
176
220
|
if (waitTime > 1000) {
|
|
177
221
|
this._hooks.onSlowQueue?.({
|
|
@@ -189,7 +233,7 @@ export class GitQueue {
|
|
|
189
233
|
|
|
190
234
|
this._activeCount++;
|
|
191
235
|
try {
|
|
192
|
-
cmd.
|
|
236
|
+
cmd.run()
|
|
193
237
|
.then(cmd.resolve, cmd.reject)
|
|
194
238
|
.finally(() => {
|
|
195
239
|
this._activeCount--;
|
|
@@ -217,33 +261,62 @@ export class GitQueue {
|
|
|
217
261
|
}
|
|
218
262
|
|
|
219
263
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
264
|
+
* Git global options that consume the next positional arg as their value
|
|
265
|
+
* (e.g. `--work-tree <path>`). Long-form `--name=value` is already skipped by
|
|
266
|
+
* the leading-dash check, so only the separated form needs explicit handling.
|
|
267
|
+
*/
|
|
268
|
+
const optionsTakingValue = new Set([
|
|
269
|
+
'-c',
|
|
270
|
+
'-C',
|
|
271
|
+
'--git-dir',
|
|
272
|
+
'--work-tree',
|
|
273
|
+
'--namespace',
|
|
274
|
+
'--exec-path',
|
|
275
|
+
'--super-prefix',
|
|
276
|
+
'--config-env',
|
|
277
|
+
'--attr-source',
|
|
278
|
+
'--list-cmds',
|
|
279
|
+
]);
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Infers a queue priority from the git command being invoked.
|
|
283
|
+
*
|
|
284
|
+
* Intentionally narrow: only returns 'background' for commands that are
|
|
285
|
+
* *always* read-only AND *always* potentially expensive. Polymorphic commands
|
|
286
|
+
* like `log` and `rev-list` (which can be quick bounded lookups or full-history
|
|
287
|
+
* walks) are deliberately omitted — call sites that perform heavy walks must
|
|
288
|
+
* pass `priority: 'background'` explicitly. Never upgrades to 'interactive'.
|
|
289
|
+
*
|
|
290
|
+
* No subcommand awareness (e.g. `stash list`, `branch -l`): the risk of
|
|
291
|
+
* misclassifying a write subcommand as background outweighs the gain.
|
|
222
292
|
*/
|
|
223
293
|
export function inferGitCommandPriority(args: readonly (string | undefined)[]): GitCommandPriority {
|
|
224
|
-
let skip = false;
|
|
225
294
|
let command: string | undefined;
|
|
226
|
-
for (
|
|
295
|
+
for (let i = 0; i < args.length; i++) {
|
|
296
|
+
const a = args[i];
|
|
227
297
|
if (a == null) continue;
|
|
228
|
-
if (
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
skip = true;
|
|
298
|
+
if (optionsTakingValue.has(a)) {
|
|
299
|
+
const next = args[i + 1];
|
|
300
|
+
if (next != null && !next.startsWith('-')) {
|
|
301
|
+
i++;
|
|
302
|
+
}
|
|
234
303
|
continue;
|
|
235
304
|
}
|
|
236
305
|
if (a.startsWith('-')) continue;
|
|
306
|
+
|
|
237
307
|
command = a;
|
|
238
308
|
break;
|
|
239
309
|
}
|
|
240
310
|
|
|
241
311
|
switch (command) {
|
|
242
|
-
case 'log':
|
|
243
|
-
case 'rev-list':
|
|
244
312
|
case 'for-each-ref':
|
|
245
313
|
case 'shortlog':
|
|
246
314
|
case 'reflog':
|
|
315
|
+
case 'name-rev':
|
|
316
|
+
case 'describe':
|
|
317
|
+
case 'cherry':
|
|
318
|
+
case 'count-objects':
|
|
319
|
+
case 'fsck':
|
|
247
320
|
return 'background';
|
|
248
321
|
default:
|
|
249
322
|
return 'normal';
|
|
@@ -176,6 +176,10 @@ const stashMapping = {
|
|
|
176
176
|
parents: '%P',
|
|
177
177
|
stashName: '%gd',
|
|
178
178
|
summary: '%gs',
|
|
179
|
+
// %s (commit subject) is git's authoritative `On <branch>: …` / `WIP on <branch>: …` record,
|
|
180
|
+
// present even when the reflog message (%gs) was customized (autostash, `git stash store -m`).
|
|
181
|
+
// Used downstream to extract `stashOnRef` reliably.
|
|
182
|
+
commitSubject: '%s',
|
|
179
183
|
};
|
|
180
184
|
|
|
181
185
|
type StashLogParser = LogParser<typeof stashMapping>;
|
|
@@ -416,6 +420,7 @@ function createLogParserWithFilesAndStats<T extends Record<string, string> | voi
|
|
|
416
420
|
|
|
417
421
|
endIndex = line.indexOf(' ', startIndex);
|
|
418
422
|
if (endIndex === -1) continue;
|
|
423
|
+
|
|
419
424
|
const newMode = line.substring(startIndex, endIndex);
|
|
420
425
|
|
|
421
426
|
// Parse old_sha and new_sha positions
|
|
@@ -882,7 +887,7 @@ function createLogParserWithPatch<T extends Record<string, string>>(
|
|
|
882
887
|
}
|
|
883
888
|
|
|
884
889
|
return {
|
|
885
|
-
status: (fileMatch[1] === 'rename' ? 'R' : 'M')
|
|
890
|
+
status: (fileMatch[1] === 'rename' ? 'R' : 'M') satisfies GitFileIndexStatus,
|
|
886
891
|
path: fileMatch[2],
|
|
887
892
|
originalPath: fileMatch[1] === 'rename' ? fileMatch[3] : undefined,
|
|
888
893
|
range: range,
|