@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
@@ -1,5 +1,6 @@
1
1
  import type { GitBranchReference, GitReference } from '../models/reference.js';
2
2
  import type { GitConflictFile } from '../models/staging.js';
3
+ import type { GitRunOptions } from '../run.types.js';
3
4
 
4
5
  export interface GitOperationResult {
5
6
  readonly conflicted: boolean;
@@ -7,16 +8,51 @@ export interface GitOperationResult {
7
8
  readonly conflicts?: GitConflictFile[];
8
9
  }
9
10
 
11
+ /**
12
+ * Spawn-layer overrides callers can pass to user-initiated git operations to inject per-call
13
+ * environment variables, an `AbortSignal` for cancellation, or a custom `timeout`. Forwarded
14
+ * verbatim to the underlying `git.run(...)` invocation; cannot override op-owned fields like
15
+ * `cwd`, `configs`, `errors`, or `stdin`.
16
+ *
17
+ * Note: passing `timeout` overrides per-op safety defaults. `merge`, `rebase`, and `revert`
18
+ * intentionally disable the timeout (set it to 0) because those operations can take a long
19
+ * time; a caller-supplied `timeout` will replace that "no timeout" setting, so use with care.
20
+ */
21
+ export type GitOperationRunOptions = Pick<GitRunOptions, 'env' | 'cancellation' | 'timeout'>;
22
+
10
23
  export interface GitOperationsSubProvider {
11
24
  checkout(
12
25
  repoPath: string,
13
26
  ref: string,
14
27
  options?: { createBranch?: string | undefined } | { path?: string | undefined },
28
+ runOptions?: GitOperationRunOptions,
29
+ ): Promise<void>;
30
+ /**
31
+ * Checks out one side of a conflicted path during a paused merge/rebase/cherry-pick.
32
+ * Executes `git checkout --ours|--theirs -- <path>`, leaving the file unstaged.
33
+ */
34
+ checkoutConflictedPath(
35
+ repoPath: string,
36
+ path: string,
37
+ side: 'ours' | 'theirs',
38
+ runOptions?: GitOperationRunOptions,
39
+ ): Promise<void>;
40
+ /**
41
+ * Checks out one side for multiple conflicted paths during a paused merge/rebase/cherry-pick.
42
+ * Batches paths into `git checkout --ours|--theirs -- <paths...>`, chunked to stay under the
43
+ * CLI length limit. Leaves files unstaged.
44
+ */
45
+ checkoutConflictedPaths(
46
+ repoPath: string,
47
+ paths: string[],
48
+ side: 'ours' | 'theirs',
49
+ runOptions?: GitOperationRunOptions,
15
50
  ): Promise<void>;
16
51
  cherryPick(
17
52
  repoPath: string,
18
53
  revs: string[],
19
- options?: { edit?: boolean; noCommit?: boolean },
54
+ options?: { edit?: boolean; noCommit?: boolean; source?: unknown },
55
+ runOptions?: GitOperationRunOptions,
20
56
  ): Promise<GitOperationResult>;
21
57
  commit(
22
58
  repoPath: string,
@@ -28,7 +64,9 @@ export interface GitOperationsSubProvider {
28
64
  author?: string;
29
65
  date?: string;
30
66
  signoff?: boolean;
67
+ source?: unknown;
31
68
  },
69
+ runOptions?: GitOperationRunOptions,
32
70
  ): Promise<void>;
33
71
  fetch(
34
72
  repoPath: string,
@@ -39,11 +77,13 @@ export interface GitOperationsSubProvider {
39
77
  pull?: boolean | undefined;
40
78
  remote?: string | undefined;
41
79
  },
80
+ runOptions?: GitOperationRunOptions,
42
81
  ): Promise<void>;
43
82
  merge(
44
83
  repoPath: string,
45
84
  ref: string,
46
- options?: { fastForward?: boolean | 'only'; noCommit?: boolean; squash?: boolean },
85
+ options?: { fastForward?: boolean | 'only'; noCommit?: boolean; squash?: boolean; source?: unknown },
86
+ runOptions?: GitOperationRunOptions,
47
87
  ): Promise<GitOperationResult>;
48
88
  pull(
49
89
  repoPath: string,
@@ -51,7 +91,9 @@ export interface GitOperationsSubProvider {
51
91
  branch?: GitBranchReference | undefined;
52
92
  rebase?: boolean | undefined;
53
93
  tags?: boolean | undefined;
94
+ source?: unknown;
54
95
  },
96
+ runOptions?: GitOperationRunOptions,
55
97
  ): Promise<void>;
56
98
  push(
57
99
  repoPath: string,
@@ -60,6 +102,7 @@ export interface GitOperationsSubProvider {
60
102
  force?: boolean | undefined;
61
103
  publish?: { remote: string };
62
104
  },
105
+ runOptions?: GitOperationRunOptions,
63
106
  ): Promise<void>;
64
107
  rebase(
65
108
  repoPath: string,
@@ -71,12 +114,20 @@ export interface GitOperationsSubProvider {
71
114
  interactive?: boolean;
72
115
  onto?: string;
73
116
  updateRefs?: boolean;
117
+ source?: unknown;
74
118
  },
119
+ runOptions?: GitOperationRunOptions,
75
120
  ): Promise<GitOperationResult>;
76
121
  reset(
77
122
  repoPath: string,
78
123
  rev: string,
79
124
  options?: { mode?: 'hard' | 'keep' | 'merge' | 'mixed' | 'soft' },
125
+ runOptions?: GitOperationRunOptions,
80
126
  ): Promise<void>;
81
- revert(repoPath: string, refs: string[], options?: { editMessage?: boolean }): Promise<GitOperationResult>;
127
+ revert(
128
+ repoPath: string,
129
+ refs: string[],
130
+ options?: { editMessage?: boolean; source?: unknown },
131
+ runOptions?: GitOperationRunOptions,
132
+ ): Promise<GitOperationResult>;
82
133
  }
@@ -3,6 +3,7 @@ import type { GitPausedOperationStatus } from '../models/pausedOperationStatus.j
3
3
  export interface GitPausedOperationsSubProvider {
4
4
  getPausedOperationStatus(
5
5
  repoPath: string,
6
+ options?: { force?: boolean },
6
7
  cancellation?: AbortSignal,
7
8
  ): Promise<GitPausedOperationStatus | undefined>;
8
9
  abortPausedOperation(repoPath: string, options?: { quit?: boolean }): Promise<void>;
@@ -1,7 +1,8 @@
1
1
  import type { Uri } from '../../utils/uri.js';
2
2
  import type { GitBranch } from '../models/branch.js';
3
- import type { GitReference } from '../models/reference.js';
3
+ import type { GitReference, GitRefTip } from '../models/reference.js';
4
4
  import type { GitTag } from '../models/tag.js';
5
+ import type { GitCommandPriority } from '../run.types.js';
5
6
 
6
7
  export interface GitRefsSubProvider {
7
8
  checkIfCouldBeValidBranchOrTagName(repoPath: string, ref: string): Promise<boolean>;
@@ -9,11 +10,39 @@ export interface GitRefsSubProvider {
9
10
  repoPath: string,
10
11
  ref1: string,
11
12
  ref2: string,
12
- options?: { forkPoint?: boolean | undefined },
13
+ options?: { forkPoint?: boolean | undefined; priority?: GitCommandPriority },
13
14
  cancellation?: AbortSignal,
14
15
  ): Promise<string | undefined>;
15
16
  getReference(repoPath: string, ref: string, cancellation?: AbortSignal): Promise<GitReference | undefined>;
16
- getSymbolicReferenceName?(repoPath: string, ref: string, cancellation?: AbortSignal): Promise<string | undefined>;
17
+ /**
18
+ * Lightweight enumeration of ref tips (heads/remotes/tags) — no enrichment.
19
+ * Use this when you need a SHA-to-refs map; use `getBranches`/`getTags` for full models.
20
+ */
21
+ getRefTips(
22
+ repoPath: string,
23
+ options?: { include?: ReadonlyArray<'heads' | 'remotes' | 'tags'> },
24
+ cancellation?: AbortSignal,
25
+ ): Promise<GitRefTip[]>;
26
+ /**
27
+ * Batch reachability — for each input SHA, the refs whose tips contain it.
28
+ *
29
+ * One bounded `git rev-list --topo-order --parents --all ^<oldestSha>^@` walk; ref-set
30
+ * propagation runs in memory. Cost is O(walked subgraph), not O(N × refs) like the per-sha
31
+ * `getBranchesWithCommits([sha])` pattern. Pass the oldest SHA in your dataset to bound the walk.
32
+ */
33
+ getRefsContainingShas(
34
+ repoPath: string,
35
+ shas: ReadonlySet<string> | readonly string[],
36
+ oldestSha: string,
37
+ options?: { include?: ReadonlyArray<'heads' | 'remotes' | 'tags'> },
38
+ cancellation?: AbortSignal,
39
+ ): Promise<Map<string, GitRefTip[]>>;
40
+ getSymbolicReferenceName?(
41
+ repoPath: string,
42
+ ref: string,
43
+ options?: { priority?: GitCommandPriority },
44
+ cancellation?: AbortSignal,
45
+ ): Promise<string | undefined>;
17
46
  hasBranchOrTag(
18
47
  repoPath: string | undefined,
19
48
  options?: {
@@ -17,7 +17,11 @@ export interface ResolvedRevision {
17
17
  }
18
18
 
19
19
  export interface GitRevisionSubProvider {
20
- exists?(repoPath: string, path: string, revOrOptions?: string | { untracked?: boolean }): Promise<boolean>;
20
+ exists?(
21
+ repoPath: string,
22
+ path: string,
23
+ revOrOptions?: string | { untracked?: 'only' | 'include' },
24
+ ): Promise<boolean>;
21
25
  getRevisionContent(repoPath: string, path: string, rev: string): Promise<Uint8Array | undefined>;
22
26
  getSubmoduleHead?(repoPath: string, submodulePath: string): Promise<string | undefined>;
23
27
  /** Gets tracked file paths from the index (reflects working tree state, even during rebase) */
@@ -19,4 +19,18 @@ export interface GitStagingSubProvider {
19
19
  unstageFile(repoPath: string, pathOrUri: string | Uri): Promise<void>;
20
20
  unstageFiles(repoPath: string, pathsOrUris: (string | Uri)[]): Promise<void>;
21
21
  unstageDirectory(repoPath: string, directoryOrUri: string | Uri): Promise<void>;
22
+ /**
23
+ * Removes a file from both the working tree and the index in a single operation
24
+ * (`git rm [-f] -- <path>`). Use during conflict resolution when the user has chosen a
25
+ * side that is itself a deletion — atomic, so it can't leave a working-tree-modified
26
+ * file accidentally staged with content. Pass `force: true` to discard local
27
+ * modifications (required for conflicted files).
28
+ */
29
+ removeFile(repoPath: string, pathOrUri: string | Uri, options?: { force?: boolean }): Promise<void>;
30
+ /**
31
+ * Batched form of {@link removeFile}. Chunks paths to stay under the CLI length limit.
32
+ */
33
+ removeFiles(repoPath: string, pathsOrUris: (string | Uri)[], options?: { force?: boolean }): Promise<void>;
34
+ stageAll(repoPath: string): Promise<void>;
35
+ unstageAll(repoPath: string): Promise<void>;
22
36
  }
@@ -3,6 +3,7 @@ import type { GitFile } from '../models/file.js';
3
3
  import type { GitConflictFile } from '../models/staging.js';
4
4
  import type { GitStatus } from '../models/status.js';
5
5
  import type { GitStatusFile } from '../models/statusFile.js';
6
+ import type { GitCommandPriority } from '../run.types.js';
6
7
 
7
8
  export interface GitWorkingChangesState {
8
9
  staged: boolean;
@@ -11,7 +12,11 @@ export interface GitWorkingChangesState {
11
12
  }
12
13
 
13
14
  export interface GitStatusSubProvider {
14
- getStatus(repoPath: string | undefined, cancellation?: AbortSignal): Promise<GitStatus | undefined>;
15
+ getStatus(
16
+ repoPath: string | undefined,
17
+ options?: { priority?: GitCommandPriority },
18
+ cancellation?: AbortSignal,
19
+ ): Promise<GitStatus | undefined>;
15
20
  getStatusForFile?(
16
21
  repoPath: string,
17
22
  pathOrUri: string | Uri,
@@ -34,6 +34,7 @@ function parseVstsHttpsUrl(url: URL): [string, string, string] {
34
34
  const owner = getVSTSOwner(url);
35
35
  const match = azureProjectRepoRegex.exec(url.pathname);
36
36
  if (match == null) throw new Error(`Invalid VSTS URL: ${url.toString()}`);
37
+
37
38
  const [, project, repo] = match;
38
39
  return [owner, project, repo];
39
40
  }
@@ -43,6 +44,7 @@ const azureHttpsUrlRegex2 = /([^/]+)\/([^/]+)\/_git\/([^/]+)/;
43
44
  function parseAzureNewStyleUrl(url: URL): [string, string, string] {
44
45
  const match = azureHttpsUrlRegex2.exec(url.pathname);
45
46
  if (match == null) throw new Error(`Invalid Azure URL: ${url.toString()}`);
47
+
46
48
  const [, owner, project, repo] = match;
47
49
  return [owner, project, repo];
48
50
  }
@@ -27,11 +27,11 @@ export interface GitResultCache {
27
27
  * Priority levels for git commands.
28
28
  * - `interactive`: User-initiated operations (blame, hover) - highest priority
29
29
  * - `normal`: Standard operations (status, config) - default priority
30
- * - `background`: Expensive operations (log, graph) - can be throttled
30
+ * - `background`: Expensive operations (graph rendering, full history walks) - can be throttled
31
31
  */
32
32
  export type GitCommandPriority = 'interactive' | 'normal' | 'background';
33
33
 
34
- export interface GitExecOptions {
34
+ export interface GitRunOptions {
35
35
  cancellation?: AbortSignal;
36
36
  configs?: readonly string[];
37
37
  readonly correlationKey?: string;
@@ -63,6 +63,26 @@ export interface GitExecOptions {
63
63
  readonly timeout?: number;
64
64
  }
65
65
 
66
+ /**
67
+ * Untyped escape hatch for raw `git <args>` invocation, returned by
68
+ * `GlGitProvider.createUnsafeGit`.
69
+ *
70
+ * "Unsafe" here means **bypasses the typed safety net** the rest of GitLens relies on
71
+ * — sub-provider cancellation/caching/decorator behaviors and signing-awareness do
72
+ * not apply when commands are issued through this object. It does NOT imply command
73
+ * injection risk; the caller still controls the args.
74
+ *
75
+ * Hand instances to libraries that need to issue arbitrary git commands
76
+ * (`@gitkraken/compose-tools`, `@gitkraken/shared-tools` undo). Inside GitLens
77
+ * itself, prefer the typed sub-providers on `RepositoryService` (`branches`,
78
+ * `commits`, `diff`, `staging`, `stash`, `status`, …). Holding an `UnsafeGit`
79
+ * just to call `run(...)` for an ad-hoc command is almost always wrong — the
80
+ * abstraction exists so it can be handed off, not used directly.
81
+ */
82
+ export interface UnsafeGit {
83
+ run(args: readonly string[], options?: GitRunOptions): Promise<GitResult>;
84
+ }
85
+
66
86
  export interface GitSpawnOptions {
67
87
  cancellation?: AbortSignal;
68
88
  configs?: readonly string[];
@@ -77,6 +77,7 @@ export class GitService implements UnifiedDisposable {
77
77
  if (GitService._instance != null) {
78
78
  throw new Error('GitService already exists — only one instance is allowed');
79
79
  }
80
+
80
81
  const instance = new GitService(watchingProvider);
81
82
  GitService._instance = instance;
82
83
  return instance;
@@ -179,6 +179,7 @@ export function getBranchAutolinks(
179
179
  for (const regex of ref.branchNameRegexes) {
180
180
  match = branchName.match(regex);
181
181
  if (!match?.groups) continue;
182
+
182
183
  num = match.groups.issueKeyNumber;
183
184
  const linkUrl = ref.url?.replace(numRegex, num);
184
185
  autolinks.set(linkUrl, {
@@ -249,6 +249,7 @@ export function buildDirtyBlame(cleanBlame: GitBlame, mapping: LineMappingResult
249
249
  const lineCountsBySha = new Map<string, number>();
250
250
  for (const blameLine of dirtyBlameLines) {
251
251
  if (blameLine == null) continue;
252
+
252
253
  lineCountsBySha.set(blameLine.sha, (lineCountsBySha.get(blameLine.sha) ?? 0) + 1);
253
254
  }
254
255
 
@@ -276,6 +277,7 @@ export function buildDirtyBlame(cleanBlame: GitBlame, mapping: LineMappingResult
276
277
  for (const [, c] of commits) {
277
278
  if (!c.author.name) continue;
278
279
  if (authors.has(c.author.name)) continue;
280
+
279
281
  authors.set(c.author.name, { name: c.author.name, lineCount: 0, current: c.author.current });
280
282
  }
281
283
 
@@ -0,0 +1,31 @@
1
+ import type { GitFileConflictStatus } from '../models/fileStatus.js';
2
+
3
+ export type ConflictResolutionAction = 'take-ours' | 'take-theirs' | 'delete' | 'unsupported';
4
+
5
+ export function classifyConflictAction(
6
+ status: GitFileConflictStatus,
7
+ resolution: 'current' | 'incoming',
8
+ ): ConflictResolutionAction {
9
+ const takeCurrent = resolution === 'current';
10
+
11
+ if (status === 'DD') return 'delete';
12
+ if (status === 'UD' && !takeCurrent) return 'delete';
13
+ if (status === 'DU' && takeCurrent) return 'delete';
14
+
15
+ // `git checkout --{ours,theirs}` fails when the requested stage is absent.
16
+ // Single-file UI filters these out; bulk resolve surfaces them as failures.
17
+ if (status === 'UA' && takeCurrent) return 'unsupported';
18
+ if (status === 'AU' && !takeCurrent) return 'unsupported';
19
+
20
+ return takeCurrent ? 'take-ours' : 'take-theirs';
21
+ }
22
+
23
+ // Stage Current is invalid when the current side has no content to take (added/deleted only by them, or both deleted)
24
+ export function canStageCurrent(status: GitFileConflictStatus): boolean {
25
+ return status !== 'UA' && status !== 'DD';
26
+ }
27
+
28
+ // Stage Incoming is invalid when the incoming side has no content to take (added/deleted only by us, or both deleted)
29
+ export function canStageIncoming(status: GitFileConflictStatus): boolean {
30
+ return status !== 'AU' && status !== 'DD';
31
+ }
@@ -1,4 +1,4 @@
1
- import type { GitFileStatus } from '../models/fileStatus.js';
1
+ import type { GitFileConflictStatus, GitFileStatus } from '../models/fileStatus.js';
2
2
 
3
3
  const statusIconsMap = {
4
4
  '.': undefined,
@@ -47,3 +47,9 @@ const statusTextMap = {
47
47
  export function getGitFileStatusText(status: GitFileStatus | keyof typeof statusTextMap): string {
48
48
  return statusTextMap[status] ?? 'Unknown';
49
49
  }
50
+
51
+ const conflictStatuses = new Set<string>(['U', 'AA', 'AU', 'UA', 'DD', 'DU', 'UD', 'UU']);
52
+
53
+ export function isConflictStatus(status: string | undefined): status is 'U' | GitFileConflictStatus {
54
+ return status != null && conflictStatuses.has(status);
55
+ }
@@ -274,6 +274,8 @@ export function parseSearchQueryGitCommand(
274
274
  searchArgs.add('--no-walk');
275
275
  } else if (value === 'tip') {
276
276
  filters.type = 'tip';
277
+ } else if (value === 'wip') {
278
+ filters.type = 'wip';
277
279
  }
278
280
  }
279
281
 
@@ -1,9 +1,11 @@
1
1
  import { sortCompare } from '../../utils/string.js';
2
+ import { compareByVersionDescending } from '../../utils/version.js';
2
3
  import type { GitBranch } from '../models/branch.js';
3
4
  import type { GitContributor } from '../models/contributor.js';
4
5
  import type { GitRemote } from '../models/remote.js';
5
6
  import type { GitTag } from '../models/tag.js';
6
7
  import type { GitWorktree } from '../models/worktree.js';
8
+ import type { GitCommitReachability } from '../providers/commits.js';
7
9
 
8
10
  export type BranchSorting = 'date:desc' | 'date:asc' | 'name:asc' | 'name:desc';
9
11
  export type TagSorting = 'date:desc' | 'date:asc' | 'name:asc' | 'name:desc';
@@ -25,6 +27,42 @@ export interface BranchSortOptions {
25
27
  openedWorktreesByBranch?: Set<string>;
26
28
  }
27
29
 
30
+ /**
31
+ * Comparator for sorting reachable refs to match `git for-each-ref` ordering: current first,
32
+ * local before remote, tags by version descending. Use with `.sort()` or `.toSorted()`.
33
+ */
34
+ export function compareReachableRefs(
35
+ a: GitCommitReachability['refs'][number],
36
+ b: GitCommitReachability['refs'][number],
37
+ ): number {
38
+ if (a.current && !b.current) return -1;
39
+ if (!a.current && b.current) return 1;
40
+ if (a.refType === 'branch' && b.refType === 'branch') {
41
+ if (a.remote !== b.remote) return a.remote ? 1 : -1;
42
+ }
43
+ if (a.refType === 'tag' && b.refType === 'tag') {
44
+ return compareByVersionDescending(a.name, b.name);
45
+ }
46
+ return 0;
47
+ }
48
+
49
+ // Hoisted from `compareRefTips` so we don't re-allocate the lookup per sort iteration.
50
+ const refTipTypeOrder = { branch: 0, remote: 1, tag: 2 } as const;
51
+
52
+ /**
53
+ * Comparator for `GitRefTip` arrays — local branch < remote branch < tag, tags by version desc.
54
+ * Mirrors `compareReachableRefs` for the lighter ref-tip shape.
55
+ */
56
+ export function compareRefTips(a: { type: 'branch' | 'remote' | 'tag'; name: string }, b: typeof a): number {
57
+ if (a.type !== b.type) {
58
+ return refTipTypeOrder[a.type] - refTipTypeOrder[b.type];
59
+ }
60
+ if (a.type === 'tag') {
61
+ return compareByVersionDescending(a.name, b.name);
62
+ }
63
+ return 0;
64
+ }
65
+
28
66
  export function sortBranches(branches: GitBranch[], options?: BranchSortOptions): GitBranch[] {
29
67
  options = { current: true, groupByType: true, orderBy: 'date:desc', ...options };
30
68
 
@@ -69,6 +69,7 @@ export function getUpstreamStatus(
69
69
  },
70
70
  ): string {
71
71
  if (upstream == null) return options?.empty ?? '';
72
+
72
73
  const {
73
74
  state: { ahead, behind },
74
75
  } = upstream;
@@ -17,6 +17,15 @@ const classifyRegex =
17
17
  * handles it as a last-fetched timestamp).
18
18
  */
19
19
  export function classifyGitDirChange(relativePath: string): RepositoryChange[] | undefined {
20
+ // User-edited todo file (and its backup) — handled by VS Code's TextDocument
21
+ // events in the rebase webview (see `rebaseWebviewProvider.ts`). Suppress here
22
+ // to avoid thrashing the repo update path on every save during an interactive
23
+ // rebase; rebase lifecycle (start/stop/step) still fires from sibling files
24
+ // in `rebase-merge/` and the directory itself.
25
+ if (relativePath.endsWith('/git-rebase-todo') || relativePath.endsWith('/git-rebase-todo.backup')) {
26
+ return undefined;
27
+ }
28
+
20
29
  const match = classifyRegex.exec(relativePath);
21
30
  if (match == null) return undefined;
22
31
 
@@ -1,7 +1,7 @@
1
- import { getScopedCounter } from '../../utils/counter.js';
2
- import { fileUri } from '../../utils/uri.js';
3
1
  import type { Ignore } from 'ignore';
4
2
  import ignore from 'ignore';
3
+ import { getScopedCounter } from '../../utils/counter.js';
4
+ import { fileUri } from '../../utils/uri.js';
5
5
  import type { FileSystemProvider } from '../context.js';
6
6
 
7
7
  export interface GitIgnoreFilterOptions {
@@ -36,6 +36,7 @@ export class RepositoryInitWatcher implements UnifiedDisposable {
36
36
 
37
37
  dispose(): void {
38
38
  if (this._disposed) return;
39
+
39
40
  this._disposed = true;
40
41
 
41
42
  for (const watcher of this.watchers.values()) {
@@ -60,6 +61,7 @@ export class RepositoryInitWatcher implements UnifiedDisposable {
60
61
 
61
62
  const watcher = this.provider.createWatcher(basePath, gitInitGlob, event => {
62
63
  if (event.reason !== 'create') return;
64
+
63
65
  this.emitter.fire({ path: event.path, basePath: basePath });
64
66
  });
65
67
 
@@ -54,6 +54,7 @@ export class WatchGroup implements UnifiedDisposable {
54
54
  /** Dispose the entire group (common watcher + all root watchers). */
55
55
  dispose(): void {
56
56
  if (this._disposed) return;
57
+
57
58
  this._disposed = true;
58
59
 
59
60
  for (const entry of this._sessions.values()) {
@@ -132,6 +133,7 @@ export class WatchGroup implements UnifiedDisposable {
132
133
  private onCommonEvent(event: FileWatchEvent): void {
133
134
  // Compute relative path from common git dir
134
135
  if (!isDescendant(event.path, this.commonGitDir)) return;
136
+
135
137
  const relativePath = relative(this.commonGitDir, event.path);
136
138
  if (shouldIgnoreRepoPath(relativePath)) return;
137
139
 
@@ -161,6 +163,7 @@ export class WatchGroup implements UnifiedDisposable {
161
163
 
162
164
  private onRootEvent(event: FileWatchEvent, entry: SessionEntry): void {
163
165
  if (!isDescendant(event.path, entry.gitDirPath)) return;
166
+
164
167
  const relativePath = relative(entry.gitDirPath, event.path);
165
168
  if (shouldIgnoreRepoPath(relativePath)) return;
166
169
 
@@ -38,7 +38,16 @@ export interface WatchHandle {
38
38
  interface SessionRecord {
39
39
  readonly session: RepositoryWatchSession;
40
40
  readonly gitDir: GitDir;
41
- readonly watchHooks?: WatchHooks;
41
+ /**
42
+ * Hooks contributed by all current `watch()` callers for this repo path. Earlier
43
+ * implementations stored just the first caller's hooks (`WatchHooks | undefined`) and
44
+ * silently dropped subsequent callers' hooks — that broke the case where a low-level
45
+ * subscriber (e.g. the Graph's secondary-worktree WIP watcher) opened the session
46
+ * first without hooks, and a later `Repository.setupWatching` for the same path lost
47
+ * its `markFetched` / `onIgnoresChanged` wiring. Each `watch()` call adds its hooks
48
+ * to this set and removes them on dispose; fire sites iterate the set.
49
+ */
50
+ readonly watchHooks: Set<WatchHooks>;
42
51
  refCount: number;
43
52
  }
44
53
 
@@ -83,6 +92,7 @@ export class RepositoryWatchService implements UnifiedDisposable {
83
92
 
84
93
  dispose(): void {
85
94
  if (this._disposed) return;
95
+
86
96
  this._disposed = true;
87
97
 
88
98
  for (const record of this.sessionMap.values()) {
@@ -117,6 +127,9 @@ export class RepositoryWatchService implements UnifiedDisposable {
117
127
  let record = this.sessionMap.get(repoPath);
118
128
  if (record != null) {
119
129
  record.refCount++;
130
+ if (watchHooks != null) {
131
+ record.watchHooks.add(watchHooks);
132
+ }
120
133
  } else {
121
134
  const session = new RepositoryWatchSession({
122
135
  repoPath: repoPath,
@@ -150,10 +163,15 @@ export class RepositoryWatchService implements UnifiedDisposable {
150
163
  },
151
164
  });
152
165
 
166
+ const watchHooksSet = new Set<WatchHooks>();
167
+ if (watchHooks != null) {
168
+ watchHooksSet.add(watchHooks);
169
+ }
170
+
153
171
  record = {
154
172
  session: session,
155
173
  gitDir: gitDir,
156
- watchHooks: watchHooks,
174
+ watchHooks: watchHooksSet,
157
175
  refCount: 1,
158
176
  };
159
177
  this.sessionMap.set(repoPath, record);
@@ -166,12 +184,16 @@ export class RepositoryWatchService implements UnifiedDisposable {
166
184
  session: sessionRef,
167
185
  dispose: (): void => {
168
186
  if (handleDisposed) return;
187
+
169
188
  handleDisposed = true;
170
189
 
171
190
  const rec = this.sessionMap.get(repoPath);
172
191
  if (rec == null) return;
173
192
 
174
193
  rec.refCount--;
194
+ if (watchHooks != null) {
195
+ rec.watchHooks.delete(watchHooks);
196
+ }
175
197
  if (rec.refCount <= 0) {
176
198
  this.sessionMap.delete(repoPath);
177
199
  this.disposeSessionRecord(rec);
@@ -229,11 +251,18 @@ export class RepositoryWatchService implements UnifiedDisposable {
229
251
  session.pushRepoChanges(changes);
230
252
  },
231
253
  onFetchHeadChanged: function (repoPath: string): void {
232
- watchHooks?.onFetchHeadChanged?.(repoPath);
254
+ // Iterate at fire time so callers that joined after the group was wired up
255
+ // still receive events (e.g. a `Repository.setupWatching` whose hooks landed
256
+ // after a hookless `GitRepositoryService.watch` registered first).
257
+ for (const h of watchHooks) {
258
+ h.onFetchHeadChanged?.(repoPath);
259
+ }
233
260
  },
234
261
  onIgnoresChanged: (repoPath: string): void => {
235
262
  this.refreshWorkingTreeFilter(repoPath);
236
- watchHooks?.onIgnoresChanged?.(repoPath);
263
+ for (const h of watchHooks) {
264
+ h.onIgnoresChanged?.(repoPath);
265
+ }
237
266
  },
238
267
  };
239
268
 
@@ -293,7 +322,10 @@ export class RepositoryWatchService implements UnifiedDisposable {
293
322
  if (filter != null) {
294
323
  void filter.refresh();
295
324
  }
296
- watchHooks?.onGitIgnoreChanged?.(repoPath);
325
+ // See `connectToWatchGroup` for the iterate-at-fire-time rationale.
326
+ for (const h of watchHooks) {
327
+ h.onGitIgnoreChanged?.(repoPath);
328
+ }
297
329
  // Don't push .gitignore itself as a working tree change
298
330
  return;
299
331
  }
@@ -341,6 +373,7 @@ function filterWorkingTreePaths(absolutePaths: string[], repoPath: string, filte
341
373
  const result: string[] = [];
342
374
  for (const p of absolutePaths) {
343
375
  if (!isDescendant(p, repoPath)) continue;
376
+
344
377
  const relativePath = relative(repoPath, p);
345
378
  if (!filter.isIgnored(relativePath)) {
346
379
  result.push(p);