@gitkraken/core-gitlens 0.2.0 → 0.3.1

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 (448) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/dist/git/cache.d.ts +38 -8
  3. package/dist/git/cache.d.ts.map +1 -1
  4. package/dist/git/cache.js +120 -55
  5. package/dist/git/cache.js.map +1 -1
  6. package/dist/git/context.d.ts +19 -0
  7. package/dist/git/context.d.ts.map +1 -1
  8. package/dist/git/context.js.map +1 -1
  9. package/dist/git/features.d.ts +1 -1
  10. package/dist/git/features.d.ts.map +1 -1
  11. package/dist/git/features.js +1 -0
  12. package/dist/git/features.js.map +1 -1
  13. package/dist/git/models/commit.d.ts.map +1 -1
  14. package/dist/git/models/commit.js.map +1 -1
  15. package/dist/git/models/graph.d.ts +96 -0
  16. package/dist/git/models/graph.d.ts.map +1 -1
  17. package/dist/git/models/graph.js +24 -1
  18. package/dist/git/models/graph.js.map +1 -1
  19. package/dist/git/models/reference.d.ts +31 -0
  20. package/dist/git/models/reference.d.ts.map +1 -1
  21. package/dist/git/models/remote.d.ts.map +1 -1
  22. package/dist/git/models/remote.js.map +1 -1
  23. package/dist/git/models/remoteProvider.d.ts +1 -0
  24. package/dist/git/models/remoteProvider.d.ts.map +1 -1
  25. package/dist/git/models/remoteProvider.js.map +1 -1
  26. package/dist/git/models/repository.d.ts +30 -13
  27. package/dist/git/models/repository.d.ts.map +1 -1
  28. package/dist/git/models/repository.js +89 -87
  29. package/dist/git/models/repository.js.map +1 -1
  30. package/dist/git/models/search.d.ts +2 -2
  31. package/dist/git/models/search.d.ts.map +1 -1
  32. package/dist/git/models/statusFile.d.ts +9 -0
  33. package/dist/git/models/statusFile.d.ts.map +1 -1
  34. package/dist/git/models/statusFile.js +11 -0
  35. package/dist/git/models/statusFile.js.map +1 -1
  36. package/dist/git/models/worktree.d.ts +4 -1
  37. package/dist/git/models/worktree.d.ts.map +1 -1
  38. package/dist/git/models/worktree.js +2 -2
  39. package/dist/git/models/worktree.js.map +1 -1
  40. package/dist/git/parsers/diffParser.d.ts.map +1 -1
  41. package/dist/git/parsers/diffParser.js.map +1 -1
  42. package/dist/git/providers/branches.d.ts +15 -4
  43. package/dist/git/providers/branches.d.ts.map +1 -1
  44. package/dist/git/providers/commits.d.ts +4 -0
  45. package/dist/git/providers/commits.d.ts.map +1 -1
  46. package/dist/git/providers/config.d.ts +5 -4
  47. package/dist/git/providers/config.d.ts.map +1 -1
  48. package/dist/git/providers/operations.d.ts +61 -12
  49. package/dist/git/providers/operations.d.ts.map +1 -1
  50. package/dist/git/providers/pausedOperations.d.ts +3 -1
  51. package/dist/git/providers/pausedOperations.d.ts.map +1 -1
  52. package/dist/git/providers/refs.d.ts +23 -2
  53. package/dist/git/providers/refs.d.ts.map +1 -1
  54. package/dist/git/providers/staging.d.ts +16 -0
  55. package/dist/git/providers/staging.d.ts.map +1 -1
  56. package/dist/git/providers/status.d.ts +4 -1
  57. package/dist/git/providers/status.d.ts.map +1 -1
  58. package/dist/git/remotes/azure-devops.d.ts.map +1 -1
  59. package/dist/git/remotes/azure-devops.js.map +1 -1
  60. package/dist/git/remotes/custom.d.ts +2 -0
  61. package/dist/git/remotes/custom.d.ts.map +1 -1
  62. package/dist/git/remotes/custom.js +20 -0
  63. package/dist/git/remotes/custom.js.map +1 -1
  64. package/dist/git/{exec.types.d.ts → run.types.d.ts} +22 -3
  65. package/dist/git/run.types.d.ts.map +1 -0
  66. package/dist/git/run.types.js +2 -0
  67. package/dist/git/run.types.js.map +1 -0
  68. package/dist/git/service.d.ts.map +1 -1
  69. package/dist/git/service.js.map +1 -1
  70. package/dist/git/utils/autolink.utils.d.ts.map +1 -1
  71. package/dist/git/utils/autolink.utils.js.map +1 -1
  72. package/dist/git/utils/blame.utils.d.ts.map +1 -1
  73. package/dist/git/utils/blame.utils.js.map +1 -1
  74. package/dist/git/utils/conflictResolution.utils.d.ts +6 -0
  75. package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -0
  76. package/dist/git/utils/conflictResolution.utils.js +25 -0
  77. package/dist/git/utils/conflictResolution.utils.js.map +1 -0
  78. package/dist/git/utils/contributor.utils.d.ts +3 -0
  79. package/dist/git/utils/contributor.utils.d.ts.map +1 -1
  80. package/dist/git/utils/contributor.utils.js +22 -0
  81. package/dist/git/utils/contributor.utils.js.map +1 -1
  82. package/dist/git/utils/fileStatus.utils.d.ts +2 -1
  83. package/dist/git/utils/fileStatus.utils.d.ts.map +1 -1
  84. package/dist/git/utils/fileStatus.utils.js +4 -0
  85. package/dist/git/utils/fileStatus.utils.js.map +1 -1
  86. package/dist/git/utils/reachability.utils.d.ts +37 -0
  87. package/dist/git/utils/reachability.utils.d.ts.map +1 -0
  88. package/dist/git/utils/reachability.utils.js +96 -0
  89. package/dist/git/utils/reachability.utils.js.map +1 -0
  90. package/dist/git/utils/search.utils.d.ts.map +1 -1
  91. package/dist/git/utils/search.utils.js +3 -0
  92. package/dist/git/utils/search.utils.js.map +1 -1
  93. package/dist/git/utils/sorting.d.ts +8 -0
  94. package/dist/git/utils/sorting.d.ts.map +1 -1
  95. package/dist/git/utils/sorting.js +15 -0
  96. package/dist/git/utils/sorting.js.map +1 -1
  97. package/dist/git/utils/status.utils.d.ts.map +1 -1
  98. package/dist/git/utils/status.utils.js.map +1 -1
  99. package/dist/git/watching/classifyChange.d.ts.map +1 -1
  100. package/dist/git/watching/classifyChange.js +8 -0
  101. package/dist/git/watching/classifyChange.js.map +1 -1
  102. package/dist/git/watching/gitIgnoreFilter.js +1 -1
  103. package/dist/git/watching/gitIgnoreFilter.js.map +1 -1
  104. package/dist/git/watching/initWatcher.d.ts.map +1 -1
  105. package/dist/git/watching/initWatcher.js.map +1 -1
  106. package/dist/git/watching/watchGroup.d.ts.map +1 -1
  107. package/dist/git/watching/watchGroup.js.map +1 -1
  108. package/dist/git/watching/watchService.d.ts +4 -2
  109. package/dist/git/watching/watchService.d.ts.map +1 -1
  110. package/dist/git/watching/watchService.js +31 -6
  111. package/dist/git/watching/watchService.js.map +1 -1
  112. package/dist/git/watching/watchSession.d.ts +14 -12
  113. package/dist/git/watching/watchSession.d.ts.map +1 -1
  114. package/dist/git/watching/watchSession.js +56 -55
  115. package/dist/git/watching/watchSession.js.map +1 -1
  116. package/dist/git-cli/exec/exec.types.d.ts +1 -1
  117. package/dist/git-cli/exec/exec.types.d.ts.map +1 -1
  118. package/dist/git-cli/exec/git.d.ts +3 -3
  119. package/dist/git-cli/exec/git.d.ts.map +1 -1
  120. package/dist/git-cli/exec/git.js.map +1 -1
  121. package/dist/git-cli/exec/gitQueue.d.ts +10 -2
  122. package/dist/git-cli/exec/gitQueue.d.ts.map +1 -1
  123. package/dist/git-cli/exec/gitQueue.js +39 -12
  124. package/dist/git-cli/exec/gitQueue.js.map +1 -1
  125. package/dist/git-cli/parsers/blameParser.d.ts.map +1 -1
  126. package/dist/git-cli/parsers/blameParser.js.map +1 -1
  127. package/dist/git-cli/parsers/logParser.js.map +1 -1
  128. package/dist/git-cli/parsers/refParser.d.ts +3 -30
  129. package/dist/git-cli/parsers/refParser.d.ts.map +1 -1
  130. package/dist/git-cli/parsers/refParser.js +30 -30
  131. package/dist/git-cli/parsers/refParser.js.map +1 -1
  132. package/dist/git-cli/providers/blame.d.ts.map +1 -1
  133. package/dist/git-cli/providers/blame.js.map +1 -1
  134. package/dist/git-cli/providers/branches.d.ts +15 -5
  135. package/dist/git-cli/providers/branches.d.ts.map +1 -1
  136. package/dist/git-cli/providers/branches.js +99 -68
  137. package/dist/git-cli/providers/branches.js.map +1 -1
  138. package/dist/git-cli/providers/commits.d.ts +1 -0
  139. package/dist/git-cli/providers/commits.d.ts.map +1 -1
  140. package/dist/git-cli/providers/commits.js +86 -30
  141. package/dist/git-cli/providers/commits.js.map +1 -1
  142. package/dist/git-cli/providers/config.d.ts +19 -6
  143. package/dist/git-cli/providers/config.d.ts.map +1 -1
  144. package/dist/git-cli/providers/config.js +86 -38
  145. package/dist/git-cli/providers/config.js.map +1 -1
  146. package/dist/git-cli/providers/diff.d.ts.map +1 -1
  147. package/dist/git-cli/providers/diff.js +5 -3
  148. package/dist/git-cli/providers/diff.js.map +1 -1
  149. package/dist/git-cli/providers/graph.d.ts.map +1 -1
  150. package/dist/git-cli/providers/graph.js +139 -16
  151. package/dist/git-cli/providers/graph.js.map +1 -1
  152. package/dist/git-cli/providers/operations.d.ts +17 -14
  153. package/dist/git-cli/providers/operations.d.ts.map +1 -1
  154. package/dist/git-cli/providers/operations.js +135 -63
  155. package/dist/git-cli/providers/operations.js.map +1 -1
  156. package/dist/git-cli/providers/patch.d.ts.map +1 -1
  157. package/dist/git-cli/providers/patch.js.map +1 -1
  158. package/dist/git-cli/providers/pausedOperations.d.ts +3 -1
  159. package/dist/git-cli/providers/pausedOperations.d.ts.map +1 -1
  160. package/dist/git-cli/providers/pausedOperations.js +7 -1
  161. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  162. package/dist/git-cli/providers/refs.d.ts +19 -2
  163. package/dist/git-cli/providers/refs.d.ts.map +1 -1
  164. package/dist/git-cli/providers/refs.js +286 -2
  165. package/dist/git-cli/providers/refs.js.map +1 -1
  166. package/dist/git-cli/providers/revision.js.map +1 -1
  167. package/dist/git-cli/providers/staging.d.ts +6 -0
  168. package/dist/git-cli/providers/staging.d.ts.map +1 -1
  169. package/dist/git-cli/providers/staging.js +32 -0
  170. package/dist/git-cli/providers/staging.js.map +1 -1
  171. package/dist/git-cli/providers/stash.d.ts.map +1 -1
  172. package/dist/git-cli/providers/stash.js +20 -2
  173. package/dist/git-cli/providers/stash.js.map +1 -1
  174. package/dist/git-cli/providers/status.d.ts +4 -1
  175. package/dist/git-cli/providers/status.d.ts.map +1 -1
  176. package/dist/git-cli/providers/status.js +8 -4
  177. package/dist/git-cli/providers/status.js.map +1 -1
  178. package/dist/git-cli/providers/tags.d.ts.map +1 -1
  179. package/dist/git-cli/providers/tags.js +10 -6
  180. package/dist/git-cli/providers/tags.js.map +1 -1
  181. package/dist/ipc/discovery.d.ts +49 -0
  182. package/dist/ipc/discovery.d.ts.map +1 -0
  183. package/dist/ipc/discovery.js +147 -0
  184. package/dist/ipc/discovery.js.map +1 -0
  185. package/dist/ipc/ipcServer.d.ts +20 -0
  186. package/dist/ipc/ipcServer.d.ts.map +1 -0
  187. package/dist/ipc/ipcServer.js +162 -0
  188. package/dist/ipc/ipcServer.js.map +1 -0
  189. package/dist/plus/agents/providers/claudeCodeProvider.d.ts +167 -0
  190. package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -0
  191. package/dist/plus/agents/providers/claudeCodeProvider.js +1786 -0
  192. package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -0
  193. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts +36 -0
  194. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts.map +1 -0
  195. package/dist/plus/agents/providers/claudeCodeTranscript.js +171 -0
  196. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -0
  197. package/dist/plus/agents/sanitizePrompt.d.ts +15 -0
  198. package/dist/plus/agents/sanitizePrompt.d.ts.map +1 -0
  199. package/dist/plus/agents/sanitizePrompt.js +103 -0
  200. package/dist/plus/agents/sanitizePrompt.js.map +1 -0
  201. package/dist/plus/agents/stateMachine.d.ts +32 -0
  202. package/dist/plus/agents/stateMachine.d.ts.map +1 -0
  203. package/dist/plus/agents/stateMachine.js +180 -0
  204. package/dist/plus/agents/stateMachine.js.map +1 -0
  205. package/dist/plus/agents/types.d.ts +254 -0
  206. package/dist/plus/agents/types.d.ts.map +1 -0
  207. package/dist/plus/agents/types.js +49 -0
  208. package/dist/plus/agents/types.js.map +1 -0
  209. package/dist/plus/ai/errors.d.ts +4 -1
  210. package/dist/plus/ai/errors.d.ts.map +1 -1
  211. package/dist/plus/ai/errors.js +38 -0
  212. package/dist/plus/ai/errors.js.map +1 -1
  213. package/dist/plus/ai/models/model.d.ts +1 -1
  214. package/dist/plus/ai/models/model.d.ts.map +1 -1
  215. package/dist/plus/ai/models/model.js.map +1 -1
  216. package/dist/plus/ai/models/promptTemplates.d.ts +11 -2
  217. package/dist/plus/ai/models/promptTemplates.d.ts.map +1 -1
  218. package/dist/plus/ai/models/provider.d.ts +3 -0
  219. package/dist/plus/ai/models/provider.d.ts.map +1 -1
  220. package/dist/plus/ai/prompts.d.ts +1 -0
  221. package/dist/plus/ai/prompts.d.ts.map +1 -1
  222. package/dist/plus/ai/prompts.js +48 -8
  223. package/dist/plus/ai/prompts.js.map +1 -1
  224. package/dist/plus/ai/providers/gitkrakenProvider.d.ts +1 -1
  225. package/dist/plus/ai/providers/gitkrakenProvider.d.ts.map +1 -1
  226. package/dist/plus/ai/providers/gitkrakenProvider.js +4 -1
  227. package/dist/plus/ai/providers/gitkrakenProvider.js.map +1 -1
  228. package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts +4 -3
  229. package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts.map +1 -1
  230. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +9 -6
  231. package/dist/plus/ai/providers/openAICompatibleProviderBase.js.map +1 -1
  232. package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
  233. package/dist/plus/ai/utils/ai.utils.js +2 -0
  234. package/dist/plus/ai/utils/ai.utils.js.map +1 -1
  235. package/dist/plus/ai/utils/results.utils.d.ts.map +1 -1
  236. package/dist/plus/ai/utils/results.utils.js.map +1 -1
  237. package/dist/plus/git-github/api/github.d.ts +12 -1
  238. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  239. package/dist/plus/git-github/api/github.js +245 -51
  240. package/dist/plus/git-github/api/github.js.map +1 -1
  241. package/dist/plus/git-github/api/types.d.ts +8 -0
  242. package/dist/plus/git-github/api/types.d.ts.map +1 -1
  243. package/dist/plus/git-github/models.d.ts +1 -1
  244. package/dist/plus/git-github/models.d.ts.map +1 -1
  245. package/dist/plus/git-github/models.js.map +1 -1
  246. package/dist/plus/git-github/providers/github/blame.d.ts.map +1 -1
  247. package/dist/plus/git-github/providers/github/blame.js.map +1 -1
  248. package/dist/plus/git-github/providers/github/branches.d.ts +5 -1
  249. package/dist/plus/git-github/providers/github/branches.d.ts.map +1 -1
  250. package/dist/plus/git-github/providers/github/branches.js +47 -24
  251. package/dist/plus/git-github/providers/github/branches.js.map +1 -1
  252. package/dist/plus/git-github/providers/github/commits.d.ts.map +1 -1
  253. package/dist/plus/git-github/providers/github/commits.js +144 -92
  254. package/dist/plus/git-github/providers/github/commits.js.map +1 -1
  255. package/dist/plus/git-github/providers/github/diff.d.ts +1 -1
  256. package/dist/plus/git-github/providers/github/diff.d.ts.map +1 -1
  257. package/dist/plus/git-github/providers/github/diff.js +23 -9
  258. package/dist/plus/git-github/providers/github/diff.js.map +1 -1
  259. package/dist/plus/git-github/providers/github/refs.d.ts +9 -1
  260. package/dist/plus/git-github/providers/github/refs.d.ts.map +1 -1
  261. package/dist/plus/git-github/providers/github/refs.js +39 -14
  262. package/dist/plus/git-github/providers/github/refs.js.map +1 -1
  263. package/dist/plus/git-github/providers/github/revision.d.ts.map +1 -1
  264. package/dist/plus/git-github/providers/github/revision.js +1 -2
  265. package/dist/plus/git-github/providers/github/revision.js.map +1 -1
  266. package/dist/plus/git-github/providers/github/status.d.ts +4 -1
  267. package/dist/plus/git-github/providers/github/status.d.ts.map +1 -1
  268. package/dist/plus/git-github/providers/github/status.js +1 -1
  269. package/dist/plus/git-github/providers/github/status.js.map +1 -1
  270. package/dist/plus/git-github/providers/github/tags.d.ts.map +1 -1
  271. package/dist/plus/git-github/providers/github/tags.js +35 -36
  272. package/dist/plus/git-github/providers/github/tags.js.map +1 -1
  273. package/dist/plus/git-github/providers/githubGitProvider.d.ts.map +1 -1
  274. package/dist/plus/git-github/providers/githubGitProvider.js.map +1 -1
  275. package/dist/utils/color.d.ts.map +1 -1
  276. package/dist/utils/color.js.map +1 -1
  277. package/dist/utils/date.d.ts.map +1 -1
  278. package/dist/utils/date.js +6 -0
  279. package/dist/utils/date.js.map +1 -1
  280. package/dist/utils/debounce.js +1 -1
  281. package/dist/utils/decorators/serializable.d.ts.map +1 -1
  282. package/dist/utils/decorators/serializable.js.map +1 -1
  283. package/dist/utils/dedupedAsyncCache.d.ts +37 -0
  284. package/dist/utils/dedupedAsyncCache.d.ts.map +1 -0
  285. package/dist/utils/dedupedAsyncCache.js +68 -0
  286. package/dist/utils/dedupedAsyncCache.js.map +1 -0
  287. package/dist/utils/diff.d.ts +2 -0
  288. package/dist/utils/diff.d.ts.map +1 -0
  289. package/dist/utils/diff.js +53 -0
  290. package/dist/utils/diff.js.map +1 -0
  291. package/dist/utils/disposable.d.ts.map +1 -1
  292. package/dist/utils/disposable.js.map +1 -1
  293. package/dist/utils/env/node/exec.d.ts.map +1 -1
  294. package/dist/utils/env/node/exec.js.map +1 -1
  295. package/dist/utils/error.d.ts.map +1 -1
  296. package/dist/utils/error.js.map +1 -1
  297. package/dist/utils/iterable.d.ts +7 -1
  298. package/dist/utils/iterable.d.ts.map +1 -1
  299. package/dist/utils/iterable.js +12 -4
  300. package/dist/utils/iterable.js.map +1 -1
  301. package/dist/utils/logger.d.ts.map +1 -1
  302. package/dist/utils/logger.js.map +1 -1
  303. package/dist/utils/lruMap.d.ts +9 -0
  304. package/dist/utils/lruMap.d.ts.map +1 -1
  305. package/dist/utils/lruMap.js +26 -4
  306. package/dist/utils/lruMap.js.map +1 -1
  307. package/dist/utils/markdown.d.ts.map +1 -1
  308. package/dist/utils/markdown.js.map +1 -1
  309. package/dist/utils/mru.d.ts.map +1 -1
  310. package/dist/utils/mru.js.map +1 -1
  311. package/dist/utils/object.d.ts +22 -1
  312. package/dist/utils/object.d.ts.map +1 -1
  313. package/dist/utils/object.js +56 -3
  314. package/dist/utils/object.js.map +1 -1
  315. package/dist/utils/paging.js +14 -15
  316. package/dist/utils/paging.js.map +1 -1
  317. package/dist/utils/path.d.ts.map +1 -1
  318. package/dist/utils/path.js.map +1 -1
  319. package/dist/utils/promise.d.ts +1 -0
  320. package/dist/utils/promise.d.ts.map +1 -1
  321. package/dist/utils/promise.js +17 -0
  322. package/dist/utils/promise.js.map +1 -1
  323. package/dist/utils/promiseCache.d.ts +10 -0
  324. package/dist/utils/promiseCache.d.ts.map +1 -1
  325. package/dist/utils/promiseCache.js +34 -4
  326. package/dist/utils/promiseCache.js.map +1 -1
  327. package/dist/utils/string.d.ts.map +1 -1
  328. package/dist/utils/string.js +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.map +1 -1
  333. package/dist/utils/version.js.map +1 -1
  334. package/package.json +13 -1
  335. package/src/git/cache.ts +192 -90
  336. package/src/git/context.ts +21 -0
  337. package/src/git/features.ts +2 -0
  338. package/src/git/models/commit.ts +1 -0
  339. package/src/git/models/graph.ts +97 -0
  340. package/src/git/models/reference.ts +33 -0
  341. package/src/git/models/remote.ts +1 -0
  342. package/src/git/models/remoteProvider.ts +1 -0
  343. package/src/git/models/repository.ts +105 -96
  344. package/src/git/models/search.ts +2 -2
  345. package/src/git/models/statusFile.ts +12 -0
  346. package/src/git/models/worktree.ts +10 -2
  347. package/src/git/parsers/diffParser.ts +2 -0
  348. package/src/git/providers/branches.ts +22 -4
  349. package/src/git/providers/commits.ts +4 -0
  350. package/src/git/providers/config.ts +3 -5
  351. package/src/git/providers/operations.ts +65 -1
  352. package/src/git/providers/pausedOperations.ts +1 -0
  353. package/src/git/providers/refs.ts +32 -3
  354. package/src/git/providers/staging.ts +12 -0
  355. package/src/git/providers/status.ts +6 -1
  356. package/src/git/remotes/azure-devops.ts +2 -0
  357. package/src/git/remotes/custom.ts +23 -0
  358. package/src/git/{exec.types.ts → run.types.ts} +22 -2
  359. package/src/git/service.ts +1 -0
  360. package/src/git/utils/autolink.utils.ts +1 -0
  361. package/src/git/utils/blame.utils.ts +2 -0
  362. package/src/git/utils/conflictResolution.utils.ts +31 -0
  363. package/src/git/utils/contributor.utils.ts +24 -0
  364. package/src/git/utils/fileStatus.utils.ts +7 -1
  365. package/src/git/utils/reachability.utils.ts +109 -0
  366. package/src/git/utils/search.utils.ts +2 -0
  367. package/src/git/utils/sorting.ts +17 -0
  368. package/src/git/utils/status.utils.ts +1 -0
  369. package/src/git/watching/classifyChange.ts +9 -0
  370. package/src/git/watching/gitIgnoreFilter.ts +2 -2
  371. package/src/git/watching/initWatcher.ts +2 -0
  372. package/src/git/watching/watchGroup.ts +3 -0
  373. package/src/git/watching/watchService.ts +45 -7
  374. package/src/git/watching/watchSession.ts +71 -55
  375. package/src/git-cli/exec/exec.types.ts +2 -2
  376. package/src/git-cli/exec/git.ts +6 -5
  377. package/src/git-cli/exec/gitQueue.ts +41 -12
  378. package/src/git-cli/parsers/blameParser.ts +1 -0
  379. package/src/git-cli/parsers/logParser.ts +1 -0
  380. package/src/git-cli/parsers/refParser.ts +33 -34
  381. package/src/git-cli/providers/blame.ts +1 -0
  382. package/src/git-cli/providers/branches.ts +165 -93
  383. package/src/git-cli/providers/commits.ts +107 -37
  384. package/src/git-cli/providers/config.ts +101 -48
  385. package/src/git-cli/providers/diff.ts +10 -3
  386. package/src/git-cli/providers/graph.ts +156 -16
  387. package/src/git-cli/providers/operations.ts +208 -83
  388. package/src/git-cli/providers/patch.ts +1 -0
  389. package/src/git-cli/providers/pausedOperations.ts +8 -0
  390. package/src/git-cli/providers/refs.ts +247 -3
  391. package/src/git-cli/providers/revision.ts +2 -2
  392. package/src/git-cli/providers/staging.ts +33 -0
  393. package/src/git-cli/providers/stash.ts +20 -2
  394. package/src/git-cli/providers/status.ts +24 -5
  395. package/src/git-cli/providers/tags.ts +15 -16
  396. package/src/ipc/discovery.ts +186 -0
  397. package/src/ipc/ipcServer.ts +171 -0
  398. package/src/plus/agents/providers/claudeCodeProvider.ts +2122 -0
  399. package/src/plus/agents/providers/claudeCodeTranscript.ts +214 -0
  400. package/src/plus/agents/sanitizePrompt.ts +109 -0
  401. package/src/plus/agents/stateMachine.ts +197 -0
  402. package/src/plus/agents/types.ts +325 -0
  403. package/src/plus/ai/errors.ts +40 -0
  404. package/src/plus/ai/models/model.ts +1 -0
  405. package/src/plus/ai/models/promptTemplates.ts +13 -0
  406. package/src/plus/ai/models/provider.ts +7 -1
  407. package/src/plus/ai/prompts.ts +49 -8
  408. package/src/plus/ai/providers/gitkrakenProvider.ts +4 -0
  409. package/src/plus/ai/providers/openAICompatibleProviderBase.ts +21 -4
  410. package/src/plus/ai/utils/ai.utils.ts +2 -0
  411. package/src/plus/ai/utils/results.utils.ts +2 -0
  412. package/src/plus/git-github/api/github.ts +315 -57
  413. package/src/plus/git-github/api/types.ts +15 -0
  414. package/src/plus/git-github/models.ts +1 -1
  415. package/src/plus/git-github/providers/github/blame.ts +2 -0
  416. package/src/plus/git-github/providers/github/branches.ts +61 -31
  417. package/src/plus/git-github/providers/github/commits.ts +231 -160
  418. package/src/plus/git-github/providers/github/diff.ts +27 -19
  419. package/src/plus/git-github/providers/github/refs.ts +58 -23
  420. package/src/plus/git-github/providers/github/revision.ts +1 -2
  421. package/src/plus/git-github/providers/github/status.ts +6 -1
  422. package/src/plus/git-github/providers/github/tags.ts +61 -62
  423. package/src/plus/git-github/providers/githubGitProvider.ts +1 -0
  424. package/src/utils/color.ts +2 -0
  425. package/src/utils/date.ts +5 -0
  426. package/src/utils/debounce.ts +1 -1
  427. package/src/utils/decorators/serializable.ts +1 -0
  428. package/src/utils/dedupedAsyncCache.ts +74 -0
  429. package/src/utils/diff.ts +61 -0
  430. package/src/utils/disposable.ts +2 -0
  431. package/src/utils/env/node/exec.ts +2 -0
  432. package/src/utils/error.ts +1 -0
  433. package/src/utils/iterable.ts +17 -3
  434. package/src/utils/logger.ts +1 -0
  435. package/src/utils/lruMap.ts +29 -4
  436. package/src/utils/markdown.ts +1 -0
  437. package/src/utils/mru.ts +2 -0
  438. package/src/utils/object.ts +55 -4
  439. package/src/utils/paging.ts +14 -14
  440. package/src/utils/path.ts +1 -0
  441. package/src/utils/promise.ts +22 -0
  442. package/src/utils/promiseCache.ts +48 -16
  443. package/src/utils/string.ts +3 -1
  444. package/src/utils/uri.ts +1 -0
  445. package/src/utils/version.ts +1 -0
  446. package/dist/git/exec.types.d.ts.map +0 -1
  447. package/dist/git/exec.types.js +0 -2
  448. package/dist/git/exec.types.js.map +0 -1
@@ -1,3 +1,4 @@
1
+ import type { GkConfigInvalidationTarget } from '../cache.js';
1
2
  import type { GitDir } from '../models/repository.js';
2
3
  import type { SigningConfig, ValidationResult } from '../models/signature.js';
3
4
  import type { GitUser } from '../models/user.js';
@@ -87,16 +88,13 @@ export interface GitConfigSubProvider {
87
88
  | []
88
89
  >;
89
90
 
90
- getGkConfig?(
91
- repoPath: string,
92
- key: GkConfigKeys | DeprecatedGkConfigKeys,
93
- options?: { type?: GitConfigType },
94
- ): Promise<string | undefined>;
91
+ getGkConfig?(repoPath: string, key: GkConfigKeys | DeprecatedGkConfigKeys): Promise<string | undefined>;
95
92
  getGkConfigRegex?(repoPath: string, pattern: string): Promise<Map<string, string>>;
96
93
  setGkConfig?(
97
94
  repoPath: string,
98
95
  key: GkConfigKeys | DeprecatedGkConfigKeys,
99
96
  value: string | undefined,
97
+ options?: { skipInvalidation?: readonly GkConfigInvalidationTarget[] },
100
98
  ): Promise<void>;
101
99
 
102
100
  getSigningConfig?(repoPath: string): Promise<SigningConfig>;
@@ -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,34 @@ 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 {
24
+ /**
25
+ * Switches the repository to a branch or ref. Pure branch/ref switching — does not accept
26
+ * a path. For path-level operations use {@link restore}.
27
+ */
11
28
  checkout(
12
29
  repoPath: string,
13
30
  ref: string,
14
- options?: { createBranch?: string | undefined } | { path?: string | undefined },
31
+ options?: { createBranch?: string | undefined },
32
+ runOptions?: GitOperationRunOptions,
15
33
  ): Promise<void>;
16
34
  cherryPick(
17
35
  repoPath: string,
18
36
  revs: string[],
19
37
  options?: { edit?: boolean; noCommit?: boolean; source?: unknown },
38
+ runOptions?: GitOperationRunOptions,
20
39
  ): Promise<GitOperationResult>;
21
40
  commit(
22
41
  repoPath: string,
@@ -30,6 +49,7 @@ export interface GitOperationsSubProvider {
30
49
  signoff?: boolean;
31
50
  source?: unknown;
32
51
  },
52
+ runOptions?: GitOperationRunOptions,
33
53
  ): Promise<void>;
34
54
  fetch(
35
55
  repoPath: string,
@@ -40,11 +60,13 @@ export interface GitOperationsSubProvider {
40
60
  pull?: boolean | undefined;
41
61
  remote?: string | undefined;
42
62
  },
63
+ runOptions?: GitOperationRunOptions,
43
64
  ): Promise<void>;
44
65
  merge(
45
66
  repoPath: string,
46
67
  ref: string,
47
68
  options?: { fastForward?: boolean | 'only'; noCommit?: boolean; squash?: boolean; source?: unknown },
69
+ runOptions?: GitOperationRunOptions,
48
70
  ): Promise<GitOperationResult>;
49
71
  pull(
50
72
  repoPath: string,
@@ -54,6 +76,7 @@ export interface GitOperationsSubProvider {
54
76
  tags?: boolean | undefined;
55
77
  source?: unknown;
56
78
  },
79
+ runOptions?: GitOperationRunOptions,
57
80
  ): Promise<void>;
58
81
  push(
59
82
  repoPath: string,
@@ -62,6 +85,7 @@ export interface GitOperationsSubProvider {
62
85
  force?: boolean | undefined;
63
86
  publish?: { remote: string };
64
87
  },
88
+ runOptions?: GitOperationRunOptions,
65
89
  ): Promise<void>;
66
90
  rebase(
67
91
  repoPath: string,
@@ -69,21 +93,61 @@ export interface GitOperationsSubProvider {
69
93
  options?: {
70
94
  autoStash?: boolean;
71
95
  branch?: string;
96
+ /** Command set as `sequence.editor` — edits the interactive rebase todo list. */
72
97
  editor?: string;
73
98
  interactive?: boolean;
99
+ /**
100
+ * Set when the `editor` is a script that rewrites the todo by command word + SHA (e.g. the
101
+ * Commit Graph's headless squash/drop/reword) rather than a human. Forces git to emit a plain,
102
+ * natural-order todo by disabling `rebase.autosquash` (which would reorder commits and rewrite
103
+ * `pick`→`fixup` for `fixup!`/`squash!` commits) and `rebase.abbreviateCommands` (which would
104
+ * emit `p` instead of `pick`). Both honor the user's git config otherwise.
105
+ */
106
+ programmaticEditor?: boolean;
107
+ /**
108
+ * Command git uses to edit per-commit messages (the combined message a `squash` produces, or a
109
+ * `reword`). Applied as `GIT_EDITOR` — which git's interactive-rebase `reword`/`squash` step honors,
110
+ * unlike `core.editor` — with `core.editor` also set as a fallback. When omitted, git falls back to
111
+ * the user's configured editor.
112
+ */
113
+ messageEditor?: string;
74
114
  onto?: string;
75
115
  updateRefs?: boolean;
76
116
  source?: unknown;
77
117
  },
118
+ runOptions?: GitOperationRunOptions,
78
119
  ): Promise<GitOperationResult>;
79
120
  reset(
80
121
  repoPath: string,
81
122
  rev: string,
82
123
  options?: { mode?: 'hard' | 'keep' | 'merge' | 'mixed' | 'soft' },
124
+ runOptions?: GitOperationRunOptions,
125
+ ): Promise<void>;
126
+ /**
127
+ * Restores the working-tree copy of one or more paths. Single path or array; arrays are
128
+ * chunked under the CLI length limit and dispatched as one git invocation per chunk
129
+ * (typically one for normal-sized batches).
130
+ *
131
+ * Source selection — `options` is mutually exclusive (`side` wins if both are supplied):
132
+ *
133
+ * - **No options** (`git checkout -- <paths>`): copies the index to the working tree, leaving
134
+ * the index untouched. Use to drop unstaged changes (mixed-file partial discard preserves
135
+ * the staged portion this way).
136
+ * - **`{ ref }`** (`git checkout <ref> -- <paths>`): resets BOTH the index and the working
137
+ * tree of the path(s) to `<ref>`. Use to fully revert files to HEAD, a specific commit, etc.
138
+ * - **`{ side }`** (`git checkout --ours|--theirs -- <paths>`): conflict-resolution
139
+ * shortcut, valid only during a paused merge/rebase/cherry-pick. Leaves files unstaged.
140
+ */
141
+ restore(
142
+ repoPath: string,
143
+ path: string | string[],
144
+ options?: { ref?: string; side?: 'ours' | 'theirs' },
145
+ runOptions?: GitOperationRunOptions,
83
146
  ): Promise<void>;
84
147
  revert(
85
148
  repoPath: string,
86
149
  refs: string[],
87
150
  options?: { editMessage?: boolean; source?: unknown },
151
+ runOptions?: GitOperationRunOptions,
88
152
  ): Promise<GitOperationResult>;
89
153
  }
@@ -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?: {
@@ -19,6 +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>;
22
34
  stageAll(repoPath: string): Promise<void>;
23
35
  unstageAll(repoPath: string): Promise<void>;
24
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
  }
@@ -35,6 +35,29 @@ export class CustomRemoteProvider extends RemoteProvider {
35
35
  return [];
36
36
  }
37
37
 
38
+ get avatarUrlTemplate(): string | undefined {
39
+ return this.urls.avatar;
40
+ }
41
+
42
+ getUrlForAvatar(email: string, size: number): string | undefined {
43
+ if (this.urls.avatar == null) return undefined;
44
+
45
+ // Split on the last `@` so local-parts that contain `@` are preserved (per RFC 5322)
46
+ const at = email.lastIndexOf('@');
47
+ const emailName = at === -1 ? email : email.slice(0, at);
48
+ const domain = at === -1 ? '' : email.slice(at + 1);
49
+
50
+ // Component-encode identity values — commit emails are attacker-controllable and
51
+ // must never be able to inject URL-structural characters (`/`, `?`, `#`, ...) into the
52
+ // resulting URL
53
+ return interpolate(this.urls.avatar, {
54
+ email: encodeURIComponent(email),
55
+ emailName: encodeURIComponent(emailName),
56
+ domain: encodeURIComponent(domain),
57
+ size: String(size),
58
+ });
59
+ }
60
+
38
61
  protected override getUrlForRepository(): string {
39
62
  return this.getUrl(this.urls.repository, this.getContext());
40
63
  }
@@ -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
+ }
@@ -79,3 +79,27 @@ export function calculateDistribution<T extends string>(
79
79
  export function matchContributor(c: GitContributor, user: GitUser): boolean {
80
80
  return c.name === user.name && c.email === user.email && c.username === user.username;
81
81
  }
82
+
83
+ /** Appends `Co-authored-by:` trailers for the given coauthors to a commit message, replacing
84
+ * any existing trailer block. Each coauthor is the `Name <email>` form (GitContributor.coauthor). */
85
+ export function appendCoauthorsToMessage(message: string, coauthors: Iterable<string>): string {
86
+ const index = message.indexOf('Co-authored-by: ');
87
+ if (index !== -1) {
88
+ message = message.substring(0, index - 1).trimEnd();
89
+ }
90
+
91
+ for (const coauthor of coauthors) {
92
+ let newlines;
93
+ if (message.includes('Co-authored-by: ')) {
94
+ newlines = '\n';
95
+ } else if (message.length !== 0 && message.endsWith('\n')) {
96
+ newlines = '\n\n';
97
+ } else {
98
+ newlines = '\n\n\n';
99
+ }
100
+
101
+ message += `${newlines}Co-authored-by: ${coauthor}`;
102
+ }
103
+
104
+ return message;
105
+ }
@@ -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
+ }
@@ -0,0 +1,109 @@
1
+ import { base64, fromBase64 } from '../../utils/base64.js';
2
+ import type { GraphReachabilityTable } from '../models/graph.js';
3
+ import type { GitCommitReachability } from '../providers/commits.js';
4
+
5
+ type ReachableRef = GitCommitReachability['refs'][number];
6
+
7
+ /**
8
+ * Canonical dictionary key for a reachable ref. The `r`/`l` discriminator keeps a remote branch from
9
+ * colliding with a local branch of the same name; the `refType` prefix separates tags from branches.
10
+ * Single-sourced here so the encoder ({@link createReachabilityTableBuilder}) and any future consumer
11
+ * can't drift on the convention.
12
+ */
13
+ export function reachableRefKey(ref: ReachableRef): string {
14
+ return `${ref.refType}:${ref.refType === 'branch' && ref.remote ? 'r' : 'l'}:${ref.name}`;
15
+ }
16
+
17
+ // Monotonic generation counter — each builder (i.e. each fresh graph walk) gets a distinct id, while a
18
+ // builder reused across `more()` pagination keeps its id. Only ever incremented host-side (the encoder);
19
+ // the webview treats the id as opaque. Module-scoped so ids are unique across a session's builders.
20
+ let nextReachabilityTableId = 0;
21
+
22
+ /**
23
+ * Builds a {@link GraphReachabilityTable} incrementally: interns refs into a shared dictionary and
24
+ * distinct membership bitmaps into a deduplicated set list. Kept next to {@link decodeReachabilitySet}
25
+ * (its exact inverse) so the wire format — first-seen dictionary indexing, LSB-first bit packing,
26
+ * base64 — has a single owner and a round-trippable test, rather than an encoder and decoder that can
27
+ * silently diverge across packages.
28
+ *
29
+ * Append-only by construction: an index, once assigned, is never reused — so a builder kept alive
30
+ * across paginated loads accumulates a table whose existing indices stay valid as it grows.
31
+ */
32
+ export function createReachabilityTableBuilder(): {
33
+ intern: (refs: Iterable<ReachableRef> | undefined) => number | undefined;
34
+ build: () => GraphReachabilityTable | undefined;
35
+ } {
36
+ const id = ++nextReachabilityTableId;
37
+ const dictionary: GitCommitReachability['refs'] = [];
38
+ const refKeyToIndex = new Map<string, number>();
39
+ const sets: string[] = [];
40
+ const setKeyToIndex = new Map<string, number>();
41
+
42
+ return {
43
+ /** Interns a ref set, returning its index into `sets`, or undefined when the set is empty. */
44
+ intern: (refs: Iterable<ReachableRef> | undefined): number | undefined => {
45
+ if (refs == null) return undefined;
46
+
47
+ let maxIndex = -1;
48
+ const indices: number[] = [];
49
+ for (const ref of refs) {
50
+ const key = reachableRefKey(ref);
51
+ let index = refKeyToIndex.get(key);
52
+ if (index == null) {
53
+ index = dictionary.length;
54
+ refKeyToIndex.set(key, index);
55
+ dictionary.push(ref);
56
+ }
57
+ indices.push(index);
58
+ if (index > maxIndex) {
59
+ maxIndex = index;
60
+ }
61
+ }
62
+ if (indices.length === 0) return undefined;
63
+
64
+ // Pack into a bitset sized to this set's high-water dictionary index, then intern by base64.
65
+ const bytes = new Uint8Array((maxIndex >> 3) + 1);
66
+ for (const index of indices) {
67
+ bytes[index >> 3] |= 1 << (index & 7);
68
+ }
69
+ const encoded = base64(bytes);
70
+ let setIndex = setKeyToIndex.get(encoded);
71
+ if (setIndex == null) {
72
+ setIndex = sets.length;
73
+ setKeyToIndex.set(encoded, setIndex);
74
+ sets.push(encoded);
75
+ }
76
+ return setIndex;
77
+ },
78
+
79
+ /** The accumulated table, or undefined when nothing was interned. */
80
+ build: (): GraphReachabilityTable | undefined =>
81
+ dictionary.length ? { id: id, dictionary: dictionary, sets: sets } : undefined,
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Decodes the membership bitmap at `index` in a {@link GraphReachabilityTable} back into its list of
87
+ * reachable refs. Refs come back in the table's first-seen dictionary order — callers that need the
88
+ * canonical display order (current-first / local-before-remote / tags newest-first) sort the result
89
+ * with `compareReachableRefs`. Returns an empty array for an out-of-range/missing set index.
90
+ *
91
+ * The bitmap is at most `ceil(dictionary.length / 8)` bytes; earlier (shorter) bitmaps packed against
92
+ * a smaller dictionary stay valid — only bits actually present can be set, so the loop stops at the
93
+ * shorter of the dictionary length and the bitmap's bit count rather than scanning a guaranteed-zero tail.
94
+ */
95
+ export function decodeReachabilitySet(table: GraphReachabilityTable, index: number): GitCommitReachability['refs'] {
96
+ const { dictionary, sets } = table;
97
+ const encoded = sets[index];
98
+ if (encoded == null) return [];
99
+
100
+ const bytes = fromBase64(encoded);
101
+ const refs: GitCommitReachability['refs'] = [];
102
+ const count = Math.min(dictionary.length, bytes.length * 8);
103
+ for (let i = 0; i < count; i++) {
104
+ if ((bytes[i >> 3] ?? 0) & (1 << (i & 7))) {
105
+ refs.push(dictionary[i]);
106
+ }
107
+ }
108
+ return refs;
109
+ }
@@ -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
 
@@ -46,6 +46,23 @@ export function compareReachableRefs(
46
46
  return 0;
47
47
  }
48
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
+
49
66
  export function sortBranches(branches: GitBranch[], options?: BranchSortOptions): GitBranch[] {
50
67
  options = { current: true, groupByType: true, orderBy: 'date:desc', ...options };
51
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