@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.
Files changed (451) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/dist/git/cache.d.ts +49 -9
  3. package/dist/git/cache.d.ts.map +1 -1
  4. package/dist/git/cache.js +174 -14
  5. package/dist/git/cache.js.map +1 -1
  6. package/dist/git/context.d.ts +11 -2
  7. package/dist/git/context.d.ts.map +1 -1
  8. package/dist/git/context.js.map +1 -1
  9. package/dist/git/models/branch.d.ts +1 -0
  10. package/dist/git/models/branch.d.ts.map +1 -1
  11. package/dist/git/models/branch.js.map +1 -1
  12. package/dist/git/models/commit.d.ts +1 -9
  13. package/dist/git/models/commit.d.ts.map +1 -1
  14. package/dist/git/models/commit.js +4 -9
  15. package/dist/git/models/commit.js.map +1 -1
  16. package/dist/git/models/graph.d.ts +2 -4
  17. package/dist/git/models/graph.d.ts.map +1 -1
  18. package/dist/git/models/reference.d.ts +31 -0
  19. package/dist/git/models/reference.d.ts.map +1 -1
  20. package/dist/git/models/remote.d.ts.map +1 -1
  21. package/dist/git/models/remote.js.map +1 -1
  22. package/dist/git/models/repository.d.ts +20 -3
  23. package/dist/git/models/repository.d.ts.map +1 -1
  24. package/dist/git/models/repository.js +42 -5
  25. package/dist/git/models/repository.js.map +1 -1
  26. package/dist/git/models/search.d.ts +2 -2
  27. package/dist/git/models/search.d.ts.map +1 -1
  28. package/dist/git/models/worktree.d.ts +4 -1
  29. package/dist/git/models/worktree.d.ts.map +1 -1
  30. package/dist/git/models/worktree.js +2 -2
  31. package/dist/git/models/worktree.js.map +1 -1
  32. package/dist/git/parsers/diffParser.d.ts +0 -1
  33. package/dist/git/parsers/diffParser.d.ts.map +1 -1
  34. package/dist/git/parsers/diffParser.js +22 -61
  35. package/dist/git/parsers/diffParser.js.map +1 -1
  36. package/dist/git/providers/branches.d.ts +18 -4
  37. package/dist/git/providers/branches.d.ts.map +1 -1
  38. package/dist/git/providers/commits.d.ts +6 -0
  39. package/dist/git/providers/commits.d.ts.map +1 -1
  40. package/dist/git/providers/config.d.ts +6 -1
  41. package/dist/git/providers/config.d.ts.map +1 -1
  42. package/dist/git/providers/diff.d.ts +2 -0
  43. package/dist/git/providers/diff.d.ts.map +1 -1
  44. package/dist/git/providers/operations.d.ts +39 -10
  45. package/dist/git/providers/operations.d.ts.map +1 -1
  46. package/dist/git/providers/pausedOperations.d.ts +3 -1
  47. package/dist/git/providers/pausedOperations.d.ts.map +1 -1
  48. package/dist/git/providers/refs.d.ts +23 -2
  49. package/dist/git/providers/refs.d.ts.map +1 -1
  50. package/dist/git/providers/revision.d.ts +1 -1
  51. package/dist/git/providers/revision.d.ts.map +1 -1
  52. package/dist/git/providers/staging.d.ts +18 -0
  53. package/dist/git/providers/staging.d.ts.map +1 -1
  54. package/dist/git/providers/status.d.ts +4 -1
  55. package/dist/git/providers/status.d.ts.map +1 -1
  56. package/dist/git/remotes/azure-devops.d.ts.map +1 -1
  57. package/dist/git/remotes/azure-devops.js.map +1 -1
  58. package/dist/git/{exec.types.d.ts → run.types.d.ts} +22 -3
  59. package/dist/git/run.types.d.ts.map +1 -0
  60. package/dist/git/run.types.js +2 -0
  61. package/dist/git/run.types.js.map +1 -0
  62. package/dist/git/service.d.ts.map +1 -1
  63. package/dist/git/service.js.map +1 -1
  64. package/dist/git/utils/autolink.utils.d.ts.map +1 -1
  65. package/dist/git/utils/autolink.utils.js.map +1 -1
  66. package/dist/git/utils/blame.utils.d.ts.map +1 -1
  67. package/dist/git/utils/blame.utils.js.map +1 -1
  68. package/dist/git/utils/conflictResolution.utils.d.ts +6 -0
  69. package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -0
  70. package/dist/git/utils/conflictResolution.utils.js +25 -0
  71. package/dist/git/utils/conflictResolution.utils.js.map +1 -0
  72. package/dist/git/utils/fileStatus.utils.d.ts +2 -1
  73. package/dist/git/utils/fileStatus.utils.d.ts.map +1 -1
  74. package/dist/git/utils/fileStatus.utils.js +4 -0
  75. package/dist/git/utils/fileStatus.utils.js.map +1 -1
  76. package/dist/git/utils/search.utils.d.ts.map +1 -1
  77. package/dist/git/utils/search.utils.js +3 -0
  78. package/dist/git/utils/search.utils.js.map +1 -1
  79. package/dist/git/utils/sorting.d.ts +14 -0
  80. package/dist/git/utils/sorting.d.ts.map +1 -1
  81. package/dist/git/utils/sorting.js +34 -0
  82. package/dist/git/utils/sorting.js.map +1 -1
  83. package/dist/git/utils/status.utils.d.ts.map +1 -1
  84. package/dist/git/utils/status.utils.js.map +1 -1
  85. package/dist/git/watching/classifyChange.d.ts.map +1 -1
  86. package/dist/git/watching/classifyChange.js +8 -0
  87. package/dist/git/watching/classifyChange.js.map +1 -1
  88. package/dist/git/watching/gitIgnoreFilter.js +1 -1
  89. package/dist/git/watching/gitIgnoreFilter.js.map +1 -1
  90. package/dist/git/watching/initWatcher.d.ts.map +1 -1
  91. package/dist/git/watching/initWatcher.js.map +1 -1
  92. package/dist/git/watching/watchGroup.d.ts.map +1 -1
  93. package/dist/git/watching/watchGroup.js.map +1 -1
  94. package/dist/git/watching/watchService.d.ts.map +1 -1
  95. package/dist/git/watching/watchService.js +24 -4
  96. package/dist/git/watching/watchService.js.map +1 -1
  97. package/dist/git/watching/watchSession.d.ts.map +1 -1
  98. package/dist/git/watching/watchSession.js.map +1 -1
  99. package/dist/git-cli/cliGitProvider.js +1 -1
  100. package/dist/git-cli/cliGitProvider.js.map +1 -1
  101. package/dist/git-cli/exec/exec.types.d.ts +1 -1
  102. package/dist/git-cli/exec/exec.types.d.ts.map +1 -1
  103. package/dist/git-cli/exec/git.d.ts +31 -6
  104. package/dist/git-cli/exec/git.d.ts.map +1 -1
  105. package/dist/git-cli/exec/git.js +70 -9
  106. package/dist/git-cli/exec/git.js.map +1 -1
  107. package/dist/git-cli/exec/gitQueue.d.ts +22 -6
  108. package/dist/git-cli/exec/gitQueue.d.ts.map +1 -1
  109. package/dist/git-cli/exec/gitQueue.js +88 -24
  110. package/dist/git-cli/exec/gitQueue.js.map +1 -1
  111. package/dist/git-cli/parsers/blameParser.d.ts.map +1 -1
  112. package/dist/git-cli/parsers/blameParser.js.map +1 -1
  113. package/dist/git-cli/parsers/logParser.d.ts +1 -0
  114. package/dist/git-cli/parsers/logParser.d.ts.map +1 -1
  115. package/dist/git-cli/parsers/logParser.js +4 -0
  116. package/dist/git-cli/parsers/logParser.js.map +1 -1
  117. package/dist/git-cli/parsers/refParser.d.ts +3 -30
  118. package/dist/git-cli/parsers/refParser.d.ts.map +1 -1
  119. package/dist/git-cli/parsers/refParser.js +30 -30
  120. package/dist/git-cli/parsers/refParser.js.map +1 -1
  121. package/dist/git-cli/providers/blame.d.ts.map +1 -1
  122. package/dist/git-cli/providers/blame.js +1 -1
  123. package/dist/git-cli/providers/blame.js.map +1 -1
  124. package/dist/git-cli/providers/branches.d.ts +17 -5
  125. package/dist/git-cli/providers/branches.d.ts.map +1 -1
  126. package/dist/git-cli/providers/branches.js +245 -162
  127. package/dist/git-cli/providers/branches.js.map +1 -1
  128. package/dist/git-cli/providers/commits.d.ts +4 -0
  129. package/dist/git-cli/providers/commits.d.ts.map +1 -1
  130. package/dist/git-cli/providers/commits.js +120 -35
  131. package/dist/git-cli/providers/commits.js.map +1 -1
  132. package/dist/git-cli/providers/config.d.ts +11 -2
  133. package/dist/git-cli/providers/config.d.ts.map +1 -1
  134. package/dist/git-cli/providers/config.js +36 -11
  135. package/dist/git-cli/providers/config.js.map +1 -1
  136. package/dist/git-cli/providers/contributors.d.ts.map +1 -1
  137. package/dist/git-cli/providers/contributors.js +7 -4
  138. package/dist/git-cli/providers/contributors.js.map +1 -1
  139. package/dist/git-cli/providers/diff.d.ts +2 -0
  140. package/dist/git-cli/providers/diff.d.ts.map +1 -1
  141. package/dist/git-cli/providers/diff.js +92 -20
  142. package/dist/git-cli/providers/diff.js.map +1 -1
  143. package/dist/git-cli/providers/graph.d.ts.map +1 -1
  144. package/dist/git-cli/providers/graph.js +49 -28
  145. package/dist/git-cli/providers/graph.js.map +1 -1
  146. package/dist/git-cli/providers/operations.d.ts +30 -11
  147. package/dist/git-cli/providers/operations.d.ts.map +1 -1
  148. package/dist/git-cli/providers/operations.js +146 -43
  149. package/dist/git-cli/providers/operations.js.map +1 -1
  150. package/dist/git-cli/providers/patch.d.ts.map +1 -1
  151. package/dist/git-cli/providers/patch.js +15 -30
  152. package/dist/git-cli/providers/patch.js.map +1 -1
  153. package/dist/git-cli/providers/pausedOperations.d.ts +3 -1
  154. package/dist/git-cli/providers/pausedOperations.d.ts.map +1 -1
  155. package/dist/git-cli/providers/pausedOperations.js +13 -7
  156. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  157. package/dist/git-cli/providers/refs.d.ts +19 -2
  158. package/dist/git-cli/providers/refs.d.ts.map +1 -1
  159. package/dist/git-cli/providers/refs.js +312 -9
  160. package/dist/git-cli/providers/refs.js.map +1 -1
  161. package/dist/git-cli/providers/remotes.js +4 -4
  162. package/dist/git-cli/providers/remotes.js.map +1 -1
  163. package/dist/git-cli/providers/revision.d.ts +1 -1
  164. package/dist/git-cli/providers/revision.d.ts.map +1 -1
  165. package/dist/git-cli/providers/revision.js +15 -11
  166. package/dist/git-cli/providers/revision.js.map +1 -1
  167. package/dist/git-cli/providers/staging.d.ts +8 -0
  168. package/dist/git-cli/providers/staging.d.ts.map +1 -1
  169. package/dist/git-cli/providers/staging.js +52 -8
  170. package/dist/git-cli/providers/staging.js.map +1 -1
  171. package/dist/git-cli/providers/stash.d.ts +0 -8
  172. package/dist/git-cli/providers/stash.d.ts.map +1 -1
  173. package/dist/git-cli/providers/stash.js +63 -119
  174. package/dist/git-cli/providers/stash.js.map +1 -1
  175. package/dist/git-cli/providers/status.d.ts +4 -1
  176. package/dist/git-cli/providers/status.d.ts.map +1 -1
  177. package/dist/git-cli/providers/status.js +10 -9
  178. package/dist/git-cli/providers/status.js.map +1 -1
  179. package/dist/git-cli/providers/tags.d.ts.map +1 -1
  180. package/dist/git-cli/providers/tags.js +13 -9
  181. package/dist/git-cli/providers/tags.js.map +1 -1
  182. package/dist/git-cli/providers/worktrees.js +3 -3
  183. package/dist/git-cli/providers/worktrees.js.map +1 -1
  184. package/dist/ipc/discovery.d.ts +27 -0
  185. package/dist/ipc/discovery.d.ts.map +1 -0
  186. package/dist/ipc/discovery.js +38 -0
  187. package/dist/ipc/discovery.js.map +1 -0
  188. package/dist/ipc/ipcServer.d.ts +20 -0
  189. package/dist/ipc/ipcServer.d.ts.map +1 -0
  190. package/dist/ipc/ipcServer.js +162 -0
  191. package/dist/ipc/ipcServer.js.map +1 -0
  192. package/dist/plus/agents/providers/claudeCodeProvider.d.ts +114 -0
  193. package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -0
  194. package/dist/plus/agents/providers/claudeCodeProvider.js +1480 -0
  195. package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -0
  196. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts +36 -0
  197. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts.map +1 -0
  198. package/dist/plus/agents/providers/claudeCodeTranscript.js +171 -0
  199. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -0
  200. package/dist/plus/agents/sanitizePrompt.d.ts +15 -0
  201. package/dist/plus/agents/sanitizePrompt.d.ts.map +1 -0
  202. package/dist/plus/agents/sanitizePrompt.js +103 -0
  203. package/dist/plus/agents/sanitizePrompt.js.map +1 -0
  204. package/dist/plus/agents/stateMachine.d.ts +32 -0
  205. package/dist/plus/agents/stateMachine.d.ts.map +1 -0
  206. package/dist/plus/agents/stateMachine.js +180 -0
  207. package/dist/plus/agents/stateMachine.js.map +1 -0
  208. package/dist/plus/agents/types.d.ts +203 -0
  209. package/dist/plus/agents/types.d.ts.map +1 -0
  210. package/dist/plus/agents/types.js +49 -0
  211. package/dist/plus/agents/types.js.map +1 -0
  212. package/dist/plus/ai/constants.d.ts +2 -1
  213. package/dist/plus/ai/constants.d.ts.map +1 -1
  214. package/dist/plus/ai/constants.js +7 -0
  215. package/dist/plus/ai/constants.js.map +1 -1
  216. package/dist/plus/ai/errors.d.ts +4 -1
  217. package/dist/plus/ai/errors.d.ts.map +1 -1
  218. package/dist/plus/ai/errors.js +38 -0
  219. package/dist/plus/ai/errors.js.map +1 -1
  220. package/dist/plus/ai/models/model.d.ts +1 -1
  221. package/dist/plus/ai/models/model.d.ts.map +1 -1
  222. package/dist/plus/ai/models/model.js.map +1 -1
  223. package/dist/plus/ai/models/promptTemplates.d.ts +28 -2
  224. package/dist/plus/ai/models/promptTemplates.d.ts.map +1 -1
  225. package/dist/plus/ai/models/results.d.ts +28 -0
  226. package/dist/plus/ai/models/results.d.ts.map +1 -1
  227. package/dist/plus/ai/prompts.d.ts +4 -0
  228. package/dist/plus/ai/prompts.d.ts.map +1 -1
  229. package/dist/plus/ai/prompts.js +167 -1
  230. package/dist/plus/ai/prompts.js.map +1 -1
  231. package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
  232. package/dist/plus/ai/utils/ai.utils.js +2 -0
  233. package/dist/plus/ai/utils/ai.utils.js.map +1 -1
  234. package/dist/plus/ai/utils/results.utils.d.ts +3 -0
  235. package/dist/plus/ai/utils/results.utils.d.ts.map +1 -1
  236. package/dist/plus/ai/utils/results.utils.js +75 -0
  237. package/dist/plus/ai/utils/results.utils.js.map +1 -1
  238. package/dist/plus/ai/utils/truncation.utils.d.ts +1 -1
  239. package/dist/plus/ai/utils/truncation.utils.d.ts.map +1 -1
  240. package/dist/plus/ai/utils/truncation.utils.js.map +1 -1
  241. package/dist/plus/git-github/api/github.d.ts +10 -1
  242. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  243. package/dist/plus/git-github/api/github.js +156 -49
  244. package/dist/plus/git-github/api/github.js.map +1 -1
  245. package/dist/plus/git-github/api/types.d.ts +8 -0
  246. package/dist/plus/git-github/api/types.d.ts.map +1 -1
  247. package/dist/plus/git-github/models.d.ts +1 -1
  248. package/dist/plus/git-github/models.d.ts.map +1 -1
  249. package/dist/plus/git-github/models.js.map +1 -1
  250. package/dist/plus/git-github/providers/github/blame.d.ts.map +1 -1
  251. package/dist/plus/git-github/providers/github/blame.js.map +1 -1
  252. package/dist/plus/git-github/providers/github/branches.d.ts +5 -1
  253. package/dist/plus/git-github/providers/github/branches.d.ts.map +1 -1
  254. package/dist/plus/git-github/providers/github/branches.js +60 -22
  255. package/dist/plus/git-github/providers/github/branches.js.map +1 -1
  256. package/dist/plus/git-github/providers/github/commits.d.ts.map +1 -1
  257. package/dist/plus/git-github/providers/github/commits.js +144 -92
  258. package/dist/plus/git-github/providers/github/commits.js.map +1 -1
  259. package/dist/plus/git-github/providers/github/diff.d.ts +3 -1
  260. package/dist/plus/git-github/providers/github/diff.d.ts.map +1 -1
  261. package/dist/plus/git-github/providers/github/diff.js +23 -9
  262. package/dist/plus/git-github/providers/github/diff.js.map +1 -1
  263. package/dist/plus/git-github/providers/github/refs.d.ts +9 -1
  264. package/dist/plus/git-github/providers/github/refs.d.ts.map +1 -1
  265. package/dist/plus/git-github/providers/github/refs.js +38 -13
  266. package/dist/plus/git-github/providers/github/refs.js.map +1 -1
  267. package/dist/plus/git-github/providers/github/revision.d.ts.map +1 -1
  268. package/dist/plus/git-github/providers/github/revision.js +1 -2
  269. package/dist/plus/git-github/providers/github/revision.js.map +1 -1
  270. package/dist/plus/git-github/providers/github/status.d.ts +4 -1
  271. package/dist/plus/git-github/providers/github/status.d.ts.map +1 -1
  272. package/dist/plus/git-github/providers/github/status.js +1 -1
  273. package/dist/plus/git-github/providers/github/status.js.map +1 -1
  274. package/dist/plus/git-github/providers/github/tags.d.ts.map +1 -1
  275. package/dist/plus/git-github/providers/github/tags.js +35 -36
  276. package/dist/plus/git-github/providers/github/tags.js.map +1 -1
  277. package/dist/plus/git-github/providers/githubGitProvider.d.ts.map +1 -1
  278. package/dist/plus/git-github/providers/githubGitProvider.js.map +1 -1
  279. package/dist/utils/color.d.ts.map +1 -1
  280. package/dist/utils/color.js.map +1 -1
  281. package/dist/utils/decorators/log.js +1 -1
  282. package/dist/utils/decorators/log.js.map +1 -1
  283. package/dist/utils/decorators/sequentialize.d.ts.map +1 -1
  284. package/dist/utils/decorators/sequentialize.js +4 -2
  285. package/dist/utils/decorators/sequentialize.js.map +1 -1
  286. package/dist/utils/decorators/serializable.d.ts.map +1 -1
  287. package/dist/utils/decorators/serializable.js.map +1 -1
  288. package/dist/utils/dedupedAsyncCache.d.ts +37 -0
  289. package/dist/utils/dedupedAsyncCache.d.ts.map +1 -0
  290. package/dist/utils/dedupedAsyncCache.js +68 -0
  291. package/dist/utils/dedupedAsyncCache.js.map +1 -0
  292. package/dist/utils/diff.d.ts +2 -0
  293. package/dist/utils/diff.d.ts.map +1 -0
  294. package/dist/utils/diff.js +53 -0
  295. package/dist/utils/diff.js.map +1 -0
  296. package/dist/utils/disposable.d.ts.map +1 -1
  297. package/dist/utils/disposable.js.map +1 -1
  298. package/dist/utils/env/node/base64.js.map +1 -1
  299. package/dist/utils/env/node/exec.d.ts.map +1 -1
  300. package/dist/utils/env/node/exec.js.map +1 -1
  301. package/dist/utils/error.d.ts.map +1 -1
  302. package/dist/utils/error.js.map +1 -1
  303. package/dist/utils/formatter.d.ts.map +1 -1
  304. package/dist/utils/formatter.js +4 -10
  305. package/dist/utils/formatter.js.map +1 -1
  306. package/dist/utils/iterable.d.ts.map +1 -1
  307. package/dist/utils/iterable.js.map +1 -1
  308. package/dist/utils/logger.d.ts.map +1 -1
  309. package/dist/utils/logger.js.map +1 -1
  310. package/dist/utils/lruMap.d.ts +49 -0
  311. package/dist/utils/lruMap.d.ts.map +1 -0
  312. package/dist/utils/lruMap.js +103 -0
  313. package/dist/utils/lruMap.js.map +1 -0
  314. package/dist/utils/markdown.d.ts.map +1 -1
  315. package/dist/utils/markdown.js.map +1 -1
  316. package/dist/utils/mru.d.ts.map +1 -1
  317. package/dist/utils/mru.js.map +1 -1
  318. package/dist/utils/path.d.ts.map +1 -1
  319. package/dist/utils/path.js.map +1 -1
  320. package/dist/utils/promise.d.ts +1 -0
  321. package/dist/utils/promise.d.ts.map +1 -1
  322. package/dist/utils/promise.js +17 -0
  323. package/dist/utils/promise.js.map +1 -1
  324. package/dist/utils/promiseCache.d.ts +10 -0
  325. package/dist/utils/promiseCache.d.ts.map +1 -1
  326. package/dist/utils/promiseCache.js +22 -0
  327. package/dist/utils/promiseCache.js.map +1 -1
  328. package/dist/utils/string.d.ts.map +1 -1
  329. package/dist/utils/string.js.map +1 -1
  330. package/dist/utils/uri.d.ts.map +1 -1
  331. package/dist/utils/uri.js.map +1 -1
  332. package/dist/utils/version.d.ts +14 -0
  333. package/dist/utils/version.d.ts.map +1 -1
  334. package/dist/utils/version.js +48 -0
  335. package/dist/utils/version.js.map +1 -1
  336. package/package.json +13 -1
  337. package/src/git/cache.ts +309 -29
  338. package/src/git/context.ts +11 -2
  339. package/src/git/models/branch.ts +1 -0
  340. package/src/git/models/commit.ts +2 -17
  341. package/src/git/models/graph.ts +2 -4
  342. package/src/git/models/reference.ts +33 -0
  343. package/src/git/models/remote.ts +1 -0
  344. package/src/git/models/repository.ts +44 -6
  345. package/src/git/models/search.ts +2 -2
  346. package/src/git/models/worktree.ts +10 -2
  347. package/src/git/parsers/diffParser.ts +9 -44
  348. package/src/git/providers/branches.ts +25 -4
  349. package/src/git/providers/commits.ts +7 -0
  350. package/src/git/providers/config.ts +4 -0
  351. package/src/git/providers/diff.ts +8 -2
  352. package/src/git/providers/operations.ts +54 -3
  353. package/src/git/providers/pausedOperations.ts +1 -0
  354. package/src/git/providers/refs.ts +32 -3
  355. package/src/git/providers/revision.ts +5 -1
  356. package/src/git/providers/staging.ts +14 -0
  357. package/src/git/providers/status.ts +6 -1
  358. package/src/git/remotes/azure-devops.ts +2 -0
  359. package/src/git/{exec.types.ts → run.types.ts} +22 -2
  360. package/src/git/service.ts +1 -0
  361. package/src/git/utils/autolink.utils.ts +1 -0
  362. package/src/git/utils/blame.utils.ts +2 -0
  363. package/src/git/utils/conflictResolution.utils.ts +31 -0
  364. package/src/git/utils/fileStatus.utils.ts +7 -1
  365. package/src/git/utils/search.utils.ts +2 -0
  366. package/src/git/utils/sorting.ts +38 -0
  367. package/src/git/utils/status.utils.ts +1 -0
  368. package/src/git/watching/classifyChange.ts +9 -0
  369. package/src/git/watching/gitIgnoreFilter.ts +2 -2
  370. package/src/git/watching/initWatcher.ts +2 -0
  371. package/src/git/watching/watchGroup.ts +3 -0
  372. package/src/git/watching/watchService.ts +38 -5
  373. package/src/git/watching/watchSession.ts +10 -0
  374. package/src/git-cli/cliGitProvider.ts +1 -1
  375. package/src/git-cli/exec/exec.types.ts +2 -2
  376. package/src/git-cli/exec/git.ts +76 -23
  377. package/src/git-cli/exec/gitQueue.ts +98 -25
  378. package/src/git-cli/parsers/blameParser.ts +1 -0
  379. package/src/git-cli/parsers/logParser.ts +6 -1
  380. package/src/git-cli/parsers/refParser.ts +33 -34
  381. package/src/git-cli/providers/blame.ts +2 -1
  382. package/src/git-cli/providers/branches.ts +341 -196
  383. package/src/git-cli/providers/commits.ts +145 -46
  384. package/src/git-cli/providers/config.ts +50 -16
  385. package/src/git-cli/providers/contributors.ts +7 -12
  386. package/src/git-cli/providers/diff.ts +107 -20
  387. package/src/git-cli/providers/graph.ts +58 -29
  388. package/src/git-cli/providers/operations.ts +253 -57
  389. package/src/git-cli/providers/patch.ts +16 -37
  390. package/src/git-cli/providers/pausedOperations.ts +14 -6
  391. package/src/git-cli/providers/refs.ts +274 -11
  392. package/src/git-cli/providers/remotes.ts +4 -4
  393. package/src/git-cli/providers/revision.ts +22 -15
  394. package/src/git-cli/providers/staging.ts +51 -8
  395. package/src/git-cli/providers/stash.ts +67 -134
  396. package/src/git-cli/providers/status.ts +21 -10
  397. package/src/git-cli/providers/tags.ts +18 -19
  398. package/src/git-cli/providers/worktrees.ts +3 -3
  399. package/src/ipc/discovery.ts +56 -0
  400. package/src/ipc/ipcServer.ts +171 -0
  401. package/src/plus/agents/providers/claudeCodeProvider.ts +1782 -0
  402. package/src/plus/agents/providers/claudeCodeTranscript.ts +214 -0
  403. package/src/plus/agents/sanitizePrompt.ts +109 -0
  404. package/src/plus/agents/stateMachine.ts +197 -0
  405. package/src/plus/agents/types.ts +277 -0
  406. package/src/plus/ai/constants.ts +8 -0
  407. package/src/plus/ai/errors.ts +40 -0
  408. package/src/plus/ai/models/model.ts +1 -0
  409. package/src/plus/ai/models/promptTemplates.ts +42 -0
  410. package/src/plus/ai/models/results.ts +30 -0
  411. package/src/plus/ai/prompts.ts +171 -1
  412. package/src/plus/ai/utils/ai.utils.ts +2 -0
  413. package/src/plus/ai/utils/results.utils.ts +101 -0
  414. package/src/plus/ai/utils/truncation.utils.ts +3 -1
  415. package/src/plus/git-github/api/github.ts +199 -53
  416. package/src/plus/git-github/api/types.ts +15 -0
  417. package/src/plus/git-github/models.ts +1 -1
  418. package/src/plus/git-github/providers/github/blame.ts +2 -0
  419. package/src/plus/git-github/providers/github/branches.ts +75 -33
  420. package/src/plus/git-github/providers/github/commits.ts +231 -160
  421. package/src/plus/git-github/providers/github/diff.ts +35 -21
  422. package/src/plus/git-github/providers/github/refs.ts +57 -22
  423. package/src/plus/git-github/providers/github/revision.ts +1 -2
  424. package/src/plus/git-github/providers/github/status.ts +6 -1
  425. package/src/plus/git-github/providers/github/tags.ts +61 -62
  426. package/src/plus/git-github/providers/githubGitProvider.ts +1 -0
  427. package/src/utils/color.ts +2 -0
  428. package/src/utils/decorators/log.ts +1 -1
  429. package/src/utils/decorators/sequentialize.ts +8 -6
  430. package/src/utils/decorators/serializable.ts +1 -0
  431. package/src/utils/dedupedAsyncCache.ts +74 -0
  432. package/src/utils/diff.ts +61 -0
  433. package/src/utils/disposable.ts +2 -0
  434. package/src/utils/env/node/base64.ts +1 -1
  435. package/src/utils/env/node/exec.ts +4 -2
  436. package/src/utils/error.ts +1 -0
  437. package/src/utils/formatter.ts +4 -11
  438. package/src/utils/iterable.ts +4 -1
  439. package/src/utils/logger.ts +1 -0
  440. package/src/utils/lruMap.ts +112 -0
  441. package/src/utils/markdown.ts +1 -0
  442. package/src/utils/mru.ts +2 -0
  443. package/src/utils/path.ts +1 -0
  444. package/src/utils/promise.ts +22 -0
  445. package/src/utils/promiseCache.ts +24 -0
  446. package/src/utils/string.ts +2 -0
  447. package/src/utils/uri.ts +1 -0
  448. package/src/utils/version.ts +49 -0
  449. package/dist/git/exec.types.d.ts.map +0 -1
  450. package/dist/git/exec.types.js +0 -2
  451. 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.exec({ cwd: parentPath }, 'clone', url, folderPath);
149
+ await this._git.run({ cwd: parentPath }, 'clone', url, folderPath);
150
150
 
151
151
  return folderPath;
152
152
  }
@@ -1,8 +1,8 @@
1
1
  export type {
2
2
  GitCommandPriority,
3
3
  GitErrorHandling,
4
- GitExecOptions,
4
+ GitRunOptions,
5
5
  GitResult,
6
6
  GitResultCache,
7
7
  GitSpawnOptions,
8
- } from '../../git/exec.types.js';
8
+ } from '../../git/run.types.js';
@@ -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, GitExecOptions, GitResult, GitSpawnOptions } from './exec.types.js';
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 = GitExecOptions & { exitCodeOnly: true };
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 exec(
634
+ async run(
583
635
  options: ExitCodeOnlyGitCommandOptions,
584
636
  ...args: readonly (string | undefined)[]
585
637
  ): Promise<GitResult<unknown>>;
586
- async exec<T extends string | Buffer = string>(
587
- options: GitExecOptions,
638
+ async run<T extends string | Buffer = string>(
639
+ options: GitRunOptions,
588
640
  ...args: readonly (string | undefined)[]
589
641
  ): Promise<GitResult<T>>;
590
- async exec<T extends string | Buffer = string>(
591
- options: GitExecOptions,
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.execCore<T>({ ...options, caching: undefined }, runArgs, gitCommand);
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.execCore<T>(options, runArgs, gitCommand);
667
+ return this.runCore<T>(options, runArgs, gitCommand);
616
668
  }
617
669
 
618
- private async execCore<T extends string | Buffer>(
619
- options: GitExecOptions,
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
- .execute(priority, () => runSpawn<T>(gitPath, args, encoding ?? 'utf8', runOpts))
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 as T,
699
- stderr: result.stderr as T | undefined,
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 as T,
727
- stderr: ex.stderr as T | undefined,
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: '' as T,
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: '' as T, stderr: result?.stderr as T | undefined, exitCode: result?.exitCode ?? 0 };
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 as ReadonlyArray<Uint8Array>), { encoding: enc });
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.exec({ cwd: cwd, errors: 'ignore' }, 'rev-parse', '--git-dir', '--git-common-dir');
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.exec(
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.exec({ cwd: cwd, errors: 'throw' }, 'rev-parse', '--show-toplevel');
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.exec({ cwd: cwd, errors: 'ignore' }, 'rev-parse', '--is-bare-repository');
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
- execute: () => Promise<unknown>;
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 canExecuteNow(priority: GitCommandPriority): boolean {
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
- /** Execute a git command with the specified priority */
119
- execute<T>(priority: GitCommandPriority, fn: () => Promise<T>): Promise<T> {
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 (!this.canExecuteNow(priority)) {
125
- return this.enqueue(fn, priority);
141
+ if (signal?.aborted) {
142
+ return Promise.reject(abortReason(signal));
126
143
  }
127
144
 
128
- return this.run(fn);
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 run<T>(fn: () => Promise<T>): Promise<T> {
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
- queue.push({
150
- execute: fn as () => Promise<unknown>,
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.execute()
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
- * Infers priority from git command type.
221
- * Only downgrades to 'background' for expensive commands; never upgrades to 'interactive'.
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 (const a of args) {
295
+ for (let i = 0; i < args.length; i++) {
296
+ const a = args[i];
227
297
  if (a == null) continue;
228
- if (skip) {
229
- skip = false;
230
- continue;
231
- }
232
- if (a === '-c' || a === '-C') {
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';
@@ -342,6 +342,7 @@ export async function* parseGitBlameAsync(stream: AsyncIterable<string>): AsyncG
342
342
  case 0x66 /* f — filename */:
343
343
  entry.path = line.substring(valueStart);
344
344
  yield entry;
345
+
345
346
  entry = undefined;
346
347
  break;
347
348
 
@@ -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') as GitFileIndexStatus,
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,