@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,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';
@@ -86,6 +87,7 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
86
87
  cancellation?: AbortSignal,
87
88
  ): Promise<PagedResult<GitBranch>> {
88
89
  if (repoPath == null) return emptyPagedResult;
90
+
89
91
  const path = repoPath;
90
92
 
91
93
  const scope = getScopedLogger();
@@ -176,12 +178,14 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
176
178
  }
177
179
  };
178
180
 
179
- // Bypass cache entirely for paged follow-ups they're driven by an opaque cursor and
180
- // don't represent "all branches".
181
- const branchesPromise =
182
- options?.paging?.cursor != null
183
- ? load()
184
- : 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);
185
189
 
186
190
  let result = await branchesPromise;
187
191
  if (options?.filter != null) {
@@ -202,28 +206,19 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
202
206
  async getBranchContributionsOverview(
203
207
  repoPath: string,
204
208
  ref: string,
205
- 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
+ },
206
215
  _cancellation?: AbortSignal,
207
216
  ): Promise<BranchContributionsOverview | undefined> {
208
217
  const scope = getScopedLogger();
209
218
 
210
- // No outer cache here GitHub provider has no stored-target safety net (no Tier 1
211
- // equivalent), so the result is purely PR-resolution-dependent and a `ref`-keyed cache
212
- // would serve stale data when the PR is later retargeted.
213
- try {
214
- let mergeTarget: string | undefined;
215
-
216
- // PR-based lookup (GitHub provider has no stored targets or base branch detection)
217
- if (options?.associatedPullRequest != null) {
218
- const pr = await options.associatedPullRequest;
219
- if (pr?.refs?.base != null) {
220
- mergeTarget = pr.refs.base.branch;
221
- }
222
- }
223
-
224
- mergeTarget ??= await this.getDefaultBranchName(repoPath);
225
- if (mergeTarget == null) return undefined;
226
-
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> => {
227
222
  const mergeBase = await this.provider.refs.getMergeBase(repoPath, ref, mergeTarget);
228
223
  if (mergeBase == null) return undefined;
229
224
 
@@ -288,6 +283,31 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
288
283
 
289
284
  contributors: result.contributors,
290
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
+ );
291
311
  } catch (ex) {
292
312
  scope?.error(ex);
293
313
  return undefined;
@@ -345,20 +365,30 @@ export class BranchesGitSubProvider implements GitBranchesSubProvider {
345
365
  @debug()
346
366
  async getDefaultBranchName(
347
367
  repoPath: string | undefined,
348
- _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 },
349
372
  _cancellation?: AbortSignal,
350
373
  ): Promise<string | undefined> {
351
374
  if (repoPath == null) return undefined;
352
375
 
376
+ remote ??= 'origin';
377
+
353
378
  const scope = getScopedLogger();
354
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.
355
383
  try {
356
- const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
357
- return await github.getDefaultBranchName(
358
- toTokenInfo(this.provider.authenticationProviderId, session),
359
- metadata.repo.owner,
360
- metadata.repo.name,
361
- );
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
+ });
362
392
  } catch (ex) {
363
393
  scope?.error(ex);
364
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()