@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,6 +1,7 @@
1
1
  import type { Cache } from '../../../../git/cache.js';
2
2
  import { GitBranch } from '../../../../git/models/branch.js';
3
3
  import type { BranchContributionsOverview, GitBranchesSubProvider } from '../../../../git/providers/branches.js';
4
+ import type { GitCommandPriority } from '../../../../git/run.types.js';
4
5
  import { createRevisionRange, stripOrigin } from '../../../../git/utils/revision.utils.js';
5
6
  import type { BranchSortOptions } from '../../../../git/utils/sorting.js';
6
7
  import { sortBranches, sortContributors } from '../../../../git/utils/sorting.js';
@@ -8,6 +9,7 @@ import { debug } from '../../../../utils/decorators/log.js';
8
9
  import { getScopedLogger } from '../../../../utils/logger.scoped.js';
9
10
  import type { PagedResult, PagingOptions } from '../../../../utils/paging.js';
10
11
  import { emptyPagedResult } from '../../../../utils/paging.js';
12
+ import { getSettledValue } from '../../../../utils/promise.js';
11
13
  import type { CacheController } from '../../../../utils/promiseCache.js';
12
14
  import { toTokenInfo } from '../../api/tokenUtils.js';
13
15
  import { HeadType } from '../../context.js';
@@ -85,6 +87,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
85
87
  cancellation?: AbortSignal,
86
88
  ): Promise<PagedResult<GitBranch>> {
87
89
  if (repoPath == null) return emptyPagedResult;
90
+
88
91
  const path = repoPath;
89
92
 
90
93
  const scope = getScopedLogger();
@@ -175,12 +178,14 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
175
178
  }
176
179
  };
177
180
 
178
- // Bypass cache entirely for paged follow-ups they're driven by an opaque cursor and
179
- // don't represent "all branches".
180
- const branchesPromise =
181
- options?.paging?.cursor != null
182
- ? load()
183
- : this.cache.branches.getOrCreate(path, cacheable => load(cacheable), cancellation);
181
+ // Compose cache key with cursor so re-loads of the same page hit the cache;
182
+ // `repoPath` (no suffix) is reserved for the full "all branches" entry.
183
+ // TODO: `cache.branches` is `PromiseMap<RepoPath, ...>` keyed exactly by repoPath, so
184
+ // `clearCaches('branches')` / `unregisterRepoPath` will not invalidate composite-key entries.
185
+ // Acceptable today because branches don't change during a virtual-repo session, but the entries
186
+ // leak in memory until provider GC. Long-term: switch to RepoPromiseCacheMap or add prefix-invalidate.
187
+ const cacheKey = options?.paging?.cursor != null ? `${path}#${options.paging.cursor}` : path;
188
+ const branchesPromise = this.cache.branches.getOrCreate(cacheKey, cacheable => load(cacheable), cancellation);
184
189
 
185
190
  let result = await branchesPromise;
186
191
  if (options?.filter != null) {
@@ -201,33 +206,34 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
201
206
  async getBranchContributionsOverview(
202
207
  repoPath: string,
203
208
  ref: string,
204
- options?: { associatedPullRequest?: Promise<{ refs?: { base?: { branch: string } } } | undefined> },
209
+ // `priority` is unused the GitHub provider doesn't go through the local git command
210
+ // queue, so the priority signal has no effect here. Accepted for interface compatibility.
211
+ options?: {
212
+ associatedPullRequest?: Promise<{ refs?: { base?: { branch: string } } } | undefined>;
213
+ priority?: GitCommandPriority;
214
+ },
205
215
  _cancellation?: AbortSignal,
206
216
  ): Promise<BranchContributionsOverview | undefined> {
207
217
  const scope = getScopedLogger();
208
218
 
209
- try {
210
- let mergeTarget: string | undefined;
211
-
212
- // PR-based lookup (GitHub provider has no stored targets or base branch detection)
213
- if (options?.associatedPullRequest != null) {
214
- const pr = await options.associatedPullRequest;
215
- if (pr?.refs?.base != null) {
216
- mergeTarget = pr.refs.base.branch;
217
- }
218
- }
219
-
220
- mergeTarget ??= await this.getDefaultBranchName(repoPath);
221
- if (mergeTarget == null) return undefined;
222
-
219
+ // Expensive body — runs only on cache miss. Closes over `mergeTarget` so the cache key
220
+ // (`${ref}|${mergeTarget}`) fully captures every input that affects the result.
221
+ const fetchBody = async (mergeTarget: string): Promise<BranchContributionsOverview | undefined> => {
223
222
  const mergeBase = await this.provider.refs.getMergeBase(repoPath, ref, mergeTarget);
224
223
  if (mergeBase == null) return undefined;
225
224
 
226
- const result = await this.provider.contributors.getContributors(
227
- repoPath,
228
- createRevisionRange(mergeBase, ref, '..'),
229
- { stats: true },
230
- );
225
+ // Fetch the merge-base commit's committer date in parallel with contributors so consumers
226
+ // that just need the date for the scope window don't pay a separate round-trip.
227
+ // `allSettled` so a transient failure in one side doesn't drop the overview entirely.
228
+ const [contributorsSettled, mergeBaseCommitSettled] = await Promise.allSettled([
229
+ this.provider.contributors.getContributors(repoPath, createRevisionRange(mergeBase, ref, '..'), {
230
+ stats: true,
231
+ }),
232
+ this.provider.commits.getCommit(repoPath, mergeBase),
233
+ ]);
234
+
235
+ const result = getSettledValue(contributorsSettled) ?? { contributors: [] };
236
+ const mergeBaseCommit = getSettledValue(mergeBaseCommitSettled);
231
237
 
232
238
  sortContributors(result.contributors, { orderBy: 'score:desc' });
233
239
 
@@ -265,6 +271,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
265
271
  branch: ref,
266
272
  mergeTarget: mergeTarget,
267
273
  mergeBase: mergeBase,
274
+ mergeBaseDate: mergeBaseCommit?.committer?.date ?? mergeBaseCommit?.author?.date,
268
275
 
269
276
  commits: totalCommits,
270
277
  files: totalFiles,
@@ -276,6 +283,31 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
276
283
 
277
284
  contributors: result.contributors,
278
285
  };
286
+ };
287
+
288
+ try {
289
+ // Resolve `mergeTarget` (PR base or default branch). Only the expensive body below is
290
+ // cached — keyed on `${ref}|${mergeTarget}` so callers that resolve to the same target
291
+ // share the result, while differing targets get independent slots.
292
+ let mergeTarget: string | undefined;
293
+
294
+ if (options?.associatedPullRequest != null) {
295
+ const pr = await options.associatedPullRequest;
296
+ if (pr?.refs?.base != null) {
297
+ mergeTarget = pr.refs.base.branch;
298
+ }
299
+ }
300
+
301
+ mergeTarget ??= await this.getDefaultBranchName(repoPath);
302
+ if (mergeTarget == null) return undefined;
303
+
304
+ // Safe to cache despite PR retargeting: the cache key includes the resolved `mergeTarget`,
305
+ // so a retargeted PR resolves to a fresh slot and the old entry is stale-but-unused (and
306
+ // TTL-evicts). The prior "no outer cache here" rationale assumed a `ref`-only key.
307
+ const resolvedTarget = mergeTarget;
308
+ return await this.cache.getBranchOverview(repoPath, `${ref}|${resolvedTarget}`, () =>
309
+ fetchBody(resolvedTarget),
310
+ );
279
311
  } catch (ex) {
280
312
  scope?.error(ex);
281
313
  return undefined;
@@ -333,20 +365,30 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
333
365
  @debug()
334
366
  async getDefaultBranchName(
335
367
  repoPath: string | undefined,
336
- _remote?: string,
368
+ remote?: string,
369
+ // `priority` is unused — the GitHub provider doesn't go through the local git command
370
+ // queue, so the priority signal has no effect here. Accepted for interface compatibility.
371
+ _options?: { priority?: GitCommandPriority },
337
372
  _cancellation?: AbortSignal,
338
373
  ): Promise<string | undefined> {
339
374
  if (repoPath == null) return undefined;
340
375
 
376
+ remote ??= 'origin';
377
+
341
378
  const scope = getScopedLogger();
342
379
 
380
+ // Throw inside the factory so RepoPromiseCacheMap's default `expireOnError` evicts the
381
+ // entry — a transient API failure shouldn't poison the cache for the rest of the session.
382
+ // The outer try/catch preserves the existing `undefined`-on-error contract for callers.
343
383
  try {
344
- const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
345
- return await github.getDefaultBranchName(
346
- toTokenInfo(this.provider.authenticationProviderId, session),
347
- metadata.repo.owner,
348
- metadata.repo.name,
349
- );
384
+ return await this.cache.getDefaultBranchName(repoPath, remote, async () => {
385
+ const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
386
+ return github.getDefaultBranchName(
387
+ toTokenInfo(this.provider.authenticationProviderId, session),
388
+ metadata.repo.owner,
389
+ metadata.repo.name,
390
+ );
391
+ });
350
392
  } catch (ex) {
351
393
  scope?.error(ex);
352
394
  debugger;
@@ -41,94 +41,103 @@ export class CommitsGitSubProvider implements GitCommitsSubProvider {
41
41
  ) {}
42
42
 
43
43
  @debug()
44
- async getCommit(repoPath: string, rev: string, _cancellation?: AbortSignal): Promise<GitCommit | undefined> {
45
- if (repoPath == null) return undefined;
46
-
47
- const scope = getScopedLogger();
44
+ getCommit(repoPath: string, rev: string, _cancellation?: AbortSignal): Promise<GitCommit | undefined> {
45
+ if (repoPath == null) return Promise.resolve(undefined);
48
46
 
49
- try {
50
- if (isUncommitted(rev, true)) {
47
+ // Don't cache uncommitted-changes synthesis — it's date-sensitive
48
+ if (isUncommitted(rev, true)) {
49
+ return (async () => {
51
50
  return createUncommittedChangesCommit(
52
51
  repoPath,
53
52
  rev,
54
53
  new Date(),
55
54
  await this.provider.config.getCurrentUser(repoPath),
56
55
  );
57
- }
56
+ })();
57
+ }
58
58
 
59
- const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
59
+ // TODO: resolve symbolic refs (HEAD, branch names) to SHA before caching to avoid
60
+ // short staleness windows. For now we cascade-clear on 'branch'/'branches'.
61
+ return this.cache.commit.getOrCreate(repoPath, stripOrigin(rev), async () => {
62
+ const scope = getScopedLogger();
60
63
 
61
- const commit = await github.getCommit(
62
- toTokenInfo(this.provider.authenticationProviderId, session),
63
- metadata.repo.owner,
64
- metadata.repo.name,
65
- stripOrigin(rev),
66
- );
67
- if (commit == null) return undefined;
64
+ try {
65
+ const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
68
66
 
69
- const repoUri = coerceUri(repoPath);
67
+ const commit = await github.getCommit(
68
+ toTokenInfo(this.provider.authenticationProviderId, session),
69
+ metadata.repo.owner,
70
+ metadata.repo.name,
71
+ stripOrigin(rev),
72
+ );
73
+ if (commit == null) return undefined;
70
74
 
71
- const { viewer = session.account.label } = commit;
72
-
73
- return new GitCommit(
74
- repoPath,
75
- commit.oid,
76
- new GitCommitIdentity(
77
- commit.author.name,
78
- commit.author.email,
79
- new Date(commit.author.date),
80
- commit.author.avatarUrl,
81
- isViewer(commit.author.name, viewer),
82
- ),
83
- new GitCommitIdentity(
84
- commit.committer.name,
85
- commit.committer.email,
86
- new Date(commit.committer.date),
87
- undefined,
88
- isViewer(commit.committer.name, viewer),
89
- ),
90
- commit.message.split('\n', 1)[0],
91
- commit.parents.nodes.map(p => p.oid),
92
- commit.message,
93
- {
94
- files: commit.files?.map(f => toFileChange(repoUri, repoPath, f)),
95
- },
96
- {
97
- files: commit.changedFiles ?? 0,
98
- additions: commit.additions ?? 0,
99
- deletions: commit.deletions ?? 0,
100
- },
101
- [],
102
- );
103
- } catch (ex) {
104
- scope?.error(ex);
105
- debugger;
106
- return undefined;
107
- }
75
+ const repoUri = coerceUri(repoPath);
76
+
77
+ const { viewer = session.account.label } = commit;
78
+
79
+ return new GitCommit(
80
+ repoPath,
81
+ commit.oid,
82
+ new GitCommitIdentity(
83
+ commit.author.name,
84
+ commit.author.email,
85
+ new Date(commit.author.date),
86
+ commit.author.avatarUrl,
87
+ isViewer(commit.author.name, viewer),
88
+ ),
89
+ new GitCommitIdentity(
90
+ commit.committer.name,
91
+ commit.committer.email,
92
+ new Date(commit.committer.date),
93
+ undefined,
94
+ isViewer(commit.committer.name, viewer),
95
+ ),
96
+ commit.message.split('\n', 1)[0],
97
+ commit.parents.nodes.map(p => p.oid),
98
+ commit.message,
99
+ {
100
+ files: commit.files?.map(f => toFileChange(repoUri, repoPath, f)),
101
+ },
102
+ {
103
+ files: commit.changedFiles ?? 0,
104
+ additions: commit.additions ?? 0,
105
+ deletions: commit.deletions ?? 0,
106
+ },
107
+ [],
108
+ );
109
+ } catch (ex) {
110
+ scope?.error(ex);
111
+ debugger;
112
+ return undefined;
113
+ }
114
+ });
108
115
  }
109
116
 
110
117
  @debug()
111
- async getCommitCount(repoPath: string, rev: string, _cancellation?: AbortSignal): Promise<number | undefined> {
112
- if (repoPath == null) return undefined;
118
+ getCommitCount(repoPath: string, rev: string, _cancellation?: AbortSignal): Promise<number | undefined> {
119
+ if (repoPath == null) return Promise.resolve(undefined);
113
120
 
114
- const scope = getScopedLogger();
121
+ return this.cache.commitCount.getOrCreate(repoPath, stripOrigin(rev), async () => {
122
+ const scope = getScopedLogger();
115
123
 
116
- try {
117
- const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
124
+ try {
125
+ const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
118
126
 
119
- const count = await github.getCommitCount(
120
- toTokenInfo(this.provider.authenticationProviderId, session),
121
- metadata.repo.owner,
122
- metadata.repo.name,
123
- stripOrigin(rev),
124
- );
127
+ const count = await github.getCommitCount(
128
+ toTokenInfo(this.provider.authenticationProviderId, session),
129
+ metadata.repo.owner,
130
+ metadata.repo.name,
131
+ stripOrigin(rev),
132
+ );
125
133
 
126
- return count;
127
- } catch (ex) {
128
- scope?.error(ex);
129
- debugger;
130
- return undefined;
131
- }
134
+ return count;
135
+ } catch (ex) {
136
+ scope?.error(ex);
137
+ debugger;
138
+ return undefined;
139
+ }
140
+ });
132
141
  }
133
142
 
134
143
  @debug()
@@ -149,102 +158,111 @@ export class CommitsGitSubProvider implements GitCommitsSubProvider {
149
158
  ): Promise<GitCommit | undefined> {
150
159
  if (repoPath == null) return undefined;
151
160
 
152
- const scope = getScopedLogger();
153
-
154
- try {
155
- const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
161
+ const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
156
162
 
157
- const rootUri = this.provider.getProviderRootUri(this.provider.getAbsoluteUri(pathOrUri, repoPath));
158
- const file = this.provider.getRelativePath(this.provider.getAbsoluteUri(pathOrUri, repoPath), rootUri);
163
+ const rootUri = this.provider.getProviderRootUri(this.provider.getAbsoluteUri(pathOrUri, repoPath));
164
+ const file = this.provider.getRelativePath(this.provider.getAbsoluteUri(pathOrUri, repoPath), rootUri);
165
+
166
+ // Resolve HEAD/empty rev to the metadata revision so the cache key is stable across callers
167
+ const resolvedRev = !rev || rev === 'HEAD' ? (await metadata.getRevision()).revision : rev;
168
+ // Path-scoped variant lives in the same slot as `getCommit` but with a `|file` suffix to
169
+ // keep it distinct from the unscoped commit entry.
170
+ const cacheKey = `${stripOrigin(resolvedRev)}|${file}`;
171
+
172
+ return this.cache.commit.getOrCreate(repoPath, cacheKey, async () => {
173
+ const scope = getScopedLogger();
174
+
175
+ try {
176
+ const commit = await github.getCommitForFile(
177
+ toTokenInfo(this.provider.authenticationProviderId, session),
178
+ metadata.repo.owner,
179
+ metadata.repo.name,
180
+ stripOrigin(resolvedRev),
181
+ file,
182
+ );
183
+ if (commit == null) return undefined;
159
184
 
160
- rev = !rev || rev === 'HEAD' ? (await metadata.getRevision()).revision : rev;
161
- const commit = await github.getCommitForFile(
162
- toTokenInfo(this.provider.authenticationProviderId, session),
163
- metadata.repo.owner,
164
- metadata.repo.name,
165
- stripOrigin(rev),
166
- file,
167
- );
168
- if (commit == null) return undefined;
185
+ const repoUri = coerceUri(repoPath);
186
+ const { viewer = session.account.label } = commit;
169
187
 
170
- const repoUri = coerceUri(repoPath);
171
- const { viewer = session.account.label } = commit;
172
-
173
- return new GitCommit(
174
- repoPath,
175
- commit.oid,
176
- new GitCommitIdentity(
177
- commit.author.name,
178
- commit.author.email,
179
- new Date(commit.author.date),
180
- commit.author.avatarUrl,
181
- isViewer(commit.author.name, viewer),
182
- ),
183
- new GitCommitIdentity(
184
- commit.committer.name,
185
- commit.committer.email,
186
- new Date(commit.committer.date),
187
- undefined,
188
- isViewer(commit.committer.name, viewer),
189
- ),
190
- commit.message.split('\n', 1)[0],
191
- commit.parents.nodes.map(p => p.oid),
192
- commit.message,
193
- commit.files != null
194
- ? {
195
- files: undefined,
196
- filtered: {
197
- files: commit.files?.map(f => toFileChange(repoUri, repoPath, f)),
198
- pathspec: file,
199
- },
200
- }
201
- : undefined,
202
- {
203
- files: commit.changedFiles ?? 0,
204
- additions: commit.additions ?? 0,
205
- deletions: commit.deletions ?? 0,
206
- },
207
- [],
208
- );
209
- } catch (ex) {
210
- scope?.error(ex);
211
- debugger;
212
- return undefined;
213
- }
188
+ return new GitCommit(
189
+ repoPath,
190
+ commit.oid,
191
+ new GitCommitIdentity(
192
+ commit.author.name,
193
+ commit.author.email,
194
+ new Date(commit.author.date),
195
+ commit.author.avatarUrl,
196
+ isViewer(commit.author.name, viewer),
197
+ ),
198
+ new GitCommitIdentity(
199
+ commit.committer.name,
200
+ commit.committer.email,
201
+ new Date(commit.committer.date),
202
+ undefined,
203
+ isViewer(commit.committer.name, viewer),
204
+ ),
205
+ commit.message.split('\n', 1)[0],
206
+ commit.parents.nodes.map(p => p.oid),
207
+ commit.message,
208
+ commit.files != null
209
+ ? {
210
+ files: undefined,
211
+ filtered: {
212
+ files: commit.files?.map(f => toFileChange(repoUri, repoPath, f)),
213
+ pathspec: file,
214
+ },
215
+ }
216
+ : undefined,
217
+ {
218
+ files: commit.changedFiles ?? 0,
219
+ additions: commit.additions ?? 0,
220
+ deletions: commit.deletions ?? 0,
221
+ },
222
+ [],
223
+ );
224
+ } catch (ex) {
225
+ scope?.error(ex);
226
+ debugger;
227
+ return undefined;
228
+ }
229
+ });
214
230
  }
215
231
 
216
232
  @debug()
217
- async getLeftRightCommitCount(
233
+ getLeftRightCommitCount(
218
234
  repoPath: string,
219
235
  range: GitRevisionRange,
220
236
  _options?: { authors?: GitUser[]; excludeMerges?: boolean },
221
237
  _cancellation?: AbortSignal,
222
238
  ): Promise<LeftRightCommitCountResult | undefined> {
223
- if (repoPath == null) return undefined;
239
+ if (repoPath == null) return Promise.resolve(undefined);
224
240
 
225
- const scope = getScopedLogger();
241
+ return this.cache.leftRightCommitCount.getOrCreate(repoPath, stripOrigin(range), async () => {
242
+ const scope = getScopedLogger();
226
243
 
227
- const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
244
+ const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
228
245
 
229
- try {
230
- const result = await github.getComparison(
231
- toTokenInfo(this.provider.authenticationProviderId, session),
232
- metadata.repo.owner,
233
- metadata.repo.name,
234
- stripOrigin(range),
235
- );
246
+ try {
247
+ const result = await github.getComparison(
248
+ toTokenInfo(this.provider.authenticationProviderId, session),
249
+ metadata.repo.owner,
250
+ metadata.repo.name,
251
+ stripOrigin(range),
252
+ );
236
253
 
237
- if (result == null) return undefined;
254
+ if (result == null) return undefined;
238
255
 
239
- return {
240
- left: result.behind_by,
241
- right: result.ahead_by,
242
- };
243
- } catch (ex) {
244
- scope?.error(ex);
245
- debugger;
246
- return undefined;
247
- }
256
+ return {
257
+ left: result.behind_by,
258
+ right: result.ahead_by,
259
+ };
260
+ } catch (ex) {
261
+ scope?.error(ex);
262
+ debugger;
263
+ return undefined;
264
+ }
265
+ });
248
266
  }
249
267
 
250
268
  @debug()
@@ -445,6 +463,7 @@ export class CommitsGitSubProvider implements GitCommitsSubProvider {
445
463
 
446
464
  const context = await this.provider.ensureRepositoryContext(repoPath);
447
465
  if (context == null) return undefined;
466
+
448
467
  const { metadata, github, session } = context;
449
468
 
450
469
  const uri = this.provider.getAbsoluteUri(path, repoPath);
@@ -601,19 +620,71 @@ export class CommitsGitSubProvider implements GitCommitsSubProvider {
601
620
  options?: GitLogShasOptions,
602
621
  cancellation?: AbortSignal,
603
622
  ): Promise<Iterable<string>> {
604
- // TODO@eamodio optimize this
623
+ if (repoPath == null) return [];
605
624
 
606
- let log: GitLog | undefined;
607
- if (options?.pathOrUri != null) {
608
- log = await this.getLogForPath(repoPath, options.pathOrUri, rev, options, cancellation);
609
- } else {
610
- log = await this.getLog(repoPath, rev, options, cancellation);
625
+ const scope = getScopedLogger();
626
+
627
+ // `authors` and `all` filters aren't supported by the lightweight SHA-only query;
628
+ // fall back to the full log path when set.
629
+ if (options?.authors?.length || options?.all) {
630
+ let log: GitLog | undefined;
631
+ if (options?.pathOrUri != null) {
632
+ log = await this.getLogForPath(repoPath, options.pathOrUri, rev, options, cancellation);
633
+ } else {
634
+ log = await this.getLog(repoPath, rev, options, cancellation);
635
+ }
636
+ if (log == null) return [];
637
+
638
+ const shas = map(log.commits.values(), c => c.ref);
639
+ // Note: reversal only applies to the first page — subsequent pages loaded via pagination are not reversed
640
+ return options?.reverse ? [...shas].reverse() : shas;
611
641
  }
612
- if (log == null) return [];
613
642
 
614
- const shas = map(log.commits.values(), c => c.ref);
615
- // Note: reversal only applies to the first page — subsequent pages loaded via pagination are not reversed
616
- return options?.reverse ? [...shas].reverse() : shas;
643
+ const limit = this.provider.getPagingLimit(options?.limit);
644
+
645
+ try {
646
+ const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
647
+
648
+ rev = !rev || rev === 'HEAD' ? (await metadata.getRevision()).revision : rev;
649
+
650
+ let path: string | undefined;
651
+ if (options?.pathOrUri != null) {
652
+ const rootUri = this.provider.getProviderRootUri(
653
+ this.provider.getAbsoluteUri(options.pathOrUri, repoPath),
654
+ );
655
+ path = this.provider.getRelativePath(
656
+ this.provider.getAbsoluteUri(options.pathOrUri, repoPath),
657
+ rootUri,
658
+ );
659
+ }
660
+
661
+ const strippedRev = stripOrigin(rev);
662
+ const sinceISO = options?.since ? new Date(options.since).toISOString() : '';
663
+ const cacheKey = `${strippedRev}|${path ?? ''}|${sinceISO}|${limit}|${options?.cursor ?? ''}`;
664
+
665
+ const shas = await this.cache.logShas.getOrCreate(repoPath, cacheKey, async () => {
666
+ const result = await github.getCommitShas(
667
+ toTokenInfo(this.provider.authenticationProviderId, session),
668
+ metadata.repo.owner,
669
+ metadata.repo.name,
670
+ strippedRev,
671
+ {
672
+ after: options?.cursor,
673
+ limit: limit,
674
+ path: path,
675
+ since: options?.since ? new Date(options.since) : undefined,
676
+ },
677
+ );
678
+ return result.values;
679
+ });
680
+
681
+ // Note: reversal only applies to the first page — subsequent pages loaded via pagination are not reversed
682
+ return options?.reverse ? shas.toReversed() : shas;
683
+ } catch (ex) {
684
+ scope?.error(ex);
685
+ debugger;
686
+ return [];
687
+ }
617
688
  }
618
689
 
619
690
  @debug()