@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,3 +1,11 @@
1
+ import type {
2
+ AIReviewDetailResult,
3
+ AIReviewFinding,
4
+ AIReviewFocusArea,
5
+ AIReviewResult,
6
+ AIReviewSeverity,
7
+ } from '../models/results.js';
8
+
1
9
  const summaryTagRegex = /<summary>([\s\S]*?)(?:<\/summary>|$)/;
2
10
  const bodyTagRegex = /<body>([\s\S]*?)(?:<\/body>|$)/;
3
11
  const codeBlockRegex = /```([\s\S]*?)```/;
@@ -48,3 +56,96 @@ export function splitMessageIntoSummaryAndBody(message: string): { readonly summ
48
56
  body: message.substring(index + 1).trim(),
49
57
  };
50
58
  }
59
+
60
+ const overviewTagRegex = /<overview>([\s\S]*?)(?:<\/overview>|$)/;
61
+ const areaTagRegex = /<area\s+([^>]*)>([\s\S]*?)(?:<\/area>|$)/g;
62
+ const findingTagRegex = /<finding\s+([^>]*)>([\s\S]*?)(?:<\/finding>|$)/g;
63
+ const labelTagRegex = /<label>([\s\S]*?)(?:<\/label>|$)/;
64
+ const rationaleTagRegex = /<rationale>([\s\S]*?)(?:<\/rationale>|$)/;
65
+ const titleTagRegex = /<title>([\s\S]*?)(?:<\/title>|$)/;
66
+ const descriptionTagRegex = /<description>([\s\S]*?)(?:<\/description>|$)/;
67
+ const findingsBlockRegex = /<findings>([\s\S]*?)(?:<\/findings>|$)/;
68
+
69
+ function parseAttr(attrs: string, name: string): string | undefined {
70
+ const match = new RegExp(`${name}="([^"]*)"`, 'i').exec(attrs);
71
+ return match?.[1]?.trim() || undefined;
72
+ }
73
+
74
+ function parseSeverity(value: string | undefined): AIReviewSeverity {
75
+ if (value === 'critical' || value === 'warning' || value === 'suggestion') return value;
76
+ return 'suggestion';
77
+ }
78
+
79
+ function parseLineRange(value: string | undefined): { start: number; end: number } | undefined {
80
+ if (!value) return undefined;
81
+
82
+ const parts = value.split('-');
83
+ const start = parseInt(parts[0], 10);
84
+ if (isNaN(start)) return undefined;
85
+
86
+ const end = parts.length > 1 ? parseInt(parts[1], 10) : start;
87
+ return { start: start, end: isNaN(end) ? start : end };
88
+ }
89
+
90
+ function parseFindings(content: string, idPrefix: string): AIReviewFinding[] {
91
+ const findings: AIReviewFinding[] = [];
92
+ let findingIndex = 0;
93
+
94
+ for (const match of content.matchAll(findingTagRegex)) {
95
+ const attrs = match[1];
96
+ const inner = match[2];
97
+ findingIndex++;
98
+
99
+ findings.push({
100
+ id: `${idPrefix}-f${findingIndex}`,
101
+ severity: parseSeverity(parseAttr(attrs, 'severity')),
102
+ title: inner.match(titleTagRegex)?.[1]?.trim() ?? 'Untitled finding',
103
+ description: inner.match(descriptionTagRegex)?.[1]?.trim() ?? '',
104
+ filePath: parseAttr(attrs, 'file'),
105
+ lineRange: parseLineRange(parseAttr(attrs, 'lines')),
106
+ });
107
+ }
108
+
109
+ return findings;
110
+ }
111
+
112
+ export function parseReviewResult(result: string, mode: 'single-pass' | 'two-pass'): AIReviewResult {
113
+ result = result.trim();
114
+
115
+ const overview = result.match(overviewTagRegex)?.[1]?.trim() ?? '';
116
+
117
+ const focusAreas: AIReviewFocusArea[] = [];
118
+ let areaIndex = 0;
119
+
120
+ for (const match of result.matchAll(areaTagRegex)) {
121
+ const attrs = match[1];
122
+ const inner = match[2];
123
+ areaIndex++;
124
+
125
+ const id = `area-${areaIndex}`;
126
+ const filesAttr = parseAttr(attrs, 'files');
127
+
128
+ const findingsBlock = inner.match(findingsBlockRegex)?.[1];
129
+ const findings = findingsBlock ? parseFindings(findingsBlock, id) : undefined;
130
+
131
+ focusAreas.push({
132
+ id: id,
133
+ label: inner.match(labelTagRegex)?.[1]?.trim() ?? 'Untitled area',
134
+ rationale: inner.match(rationaleTagRegex)?.[1]?.trim() ?? '',
135
+ severity: parseSeverity(parseAttr(attrs, 'severity')),
136
+ files: filesAttr?.split(',').map(f => f.trim()) ?? [],
137
+ findings: findings,
138
+ });
139
+ }
140
+
141
+ return { overview: overview, focusAreas: focusAreas, mode: mode };
142
+ }
143
+
144
+ export function parseReviewDetailResult(result: string, focusAreaId: string): AIReviewDetailResult {
145
+ result = result.trim();
146
+
147
+ const findingsBlock = result.match(findingsBlockRegex)?.[1] ?? result;
148
+ const findings = parseFindings(findingsBlock, focusAreaId);
149
+
150
+ return { findings: findings };
151
+ }
@@ -52,7 +52,9 @@ type DiffTemplateType =
52
52
  | 'generate-create-cloudPatch'
53
53
  | 'generate-create-codeSuggestion'
54
54
  | 'generate-create-pullRequest'
55
- | 'explain-changes';
55
+ | 'explain-changes'
56
+ | 'review-changes'
57
+ | 'review-detail';
56
58
 
57
59
  /** File type base scores (0-100, higher = more important) */
58
60
  const fileTypeScores: Record<string, number> = {
@@ -1,3 +1,7 @@
1
+ import { graphql, GraphqlResponseError } from '@octokit/graphql';
2
+ import { request } from '@octokit/request';
3
+ import { RequestError } from '@octokit/request-error';
4
+ import type { Endpoints, RequestParameters } from '@octokit/types';
1
5
  import {
2
6
  AuthenticationError,
3
7
  AuthenticationErrorReason,
@@ -37,10 +41,6 @@ import { maybeStopWatch } from '../../../utils/stopwatch.js';
37
41
  import { parseUri } from '../../../utils/uri.js';
38
42
  import type { Version } from '../../../utils/version.js';
39
43
  import { fromString, satisfies } from '../../../utils/version.js';
40
- import { graphql, GraphqlResponseError } from '@octokit/graphql';
41
- import { request } from '@octokit/request';
42
- import { RequestError } from '@octokit/request-error';
43
- import type { Endpoints, RequestParameters } from '@octokit/types';
44
44
  import type {
45
45
  GitHubBlame,
46
46
  GitHubBlameRange,
@@ -120,7 +120,7 @@ repository {
120
120
  const gqlPullRequestFragment = `
121
121
  ${gqlPullRequestLiteFragment}
122
122
  additions
123
- assignees(first: 10) {
123
+ assignees(first: 25) {
124
124
  nodes {
125
125
  login
126
126
  avatarUrl(size: $avatarSize)
@@ -134,7 +134,7 @@ mergedBy {
134
134
  login
135
135
  }
136
136
  reviewDecision
137
- latestReviews(first: 10) {
137
+ latestReviews(first: 25) {
138
138
  nodes {
139
139
  author {
140
140
  login
@@ -144,7 +144,7 @@ latestReviews(first: 10) {
144
144
  state
145
145
  }
146
146
  }
147
- reviewRequests(first: 10) {
147
+ reviewRequests(first: 25) {
148
148
  nodes {
149
149
  asCodeOwner
150
150
  id
@@ -187,7 +187,7 @@ author {
187
187
  comments {
188
188
  totalCount
189
189
  }
190
- labels(first: 20) {
190
+ labels(first: 50) {
191
191
  nodes {
192
192
  color
193
193
  name
@@ -1138,7 +1138,7 @@ export class GitHubApi {
1138
1138
  endingLine
1139
1139
  commit {
1140
1140
  oid
1141
- parents(first: 3) { nodes { oid } }
1141
+ parents(first: 8) { nodes { oid } }
1142
1142
  message
1143
1143
  additions
1144
1144
  changedFiles
@@ -1406,7 +1406,7 @@ export class GitHubApi {
1406
1406
  $until: GitTimestamp!
1407
1407
  ) {
1408
1408
  repository(owner: $owner, name: $repo) {
1409
- refs(first: 20, refPrefix: "refs/heads/") {
1409
+ refs(first: 100, refPrefix: "refs/heads/") {
1410
1410
  nodes {
1411
1411
  name
1412
1412
  target {
@@ -1691,7 +1691,7 @@ export class GitHubApi {
1691
1691
  ... on Commit {
1692
1692
  oid
1693
1693
  message
1694
- parents(first: 3) { nodes { oid } }
1694
+ parents(first: 8) { nodes { oid } }
1695
1695
  additions
1696
1696
  changedFiles
1697
1697
  deletions
@@ -1767,6 +1767,115 @@ export class GitHubApi {
1767
1767
  }
1768
1768
  }
1769
1769
 
1770
+ @trace({
1771
+ args: (token, owner, repo, ref) => ({
1772
+ token: `<token:${token.microHash}>`,
1773
+ owner: owner,
1774
+ repo: repo,
1775
+ ref: ref,
1776
+ }),
1777
+ })
1778
+ async getCommitShas(
1779
+ token: GitHubTokenInfo,
1780
+ owner: string,
1781
+ repo: string,
1782
+ ref: string,
1783
+ options?: {
1784
+ after?: string;
1785
+ before?: string;
1786
+ limit?: number;
1787
+ path?: string;
1788
+ since?: string | Date;
1789
+ until?: string | Date;
1790
+ },
1791
+ ): Promise<PagedResult<string>> {
1792
+ const scope = getScopedLogger();
1793
+
1794
+ interface QueryResult {
1795
+ repository:
1796
+ | {
1797
+ object:
1798
+ | {
1799
+ history: {
1800
+ pageInfo: GitHubPageInfo;
1801
+ nodes: { oid: string }[];
1802
+ };
1803
+ }
1804
+ | null
1805
+ | undefined;
1806
+ }
1807
+ | null
1808
+ | undefined;
1809
+ }
1810
+
1811
+ try {
1812
+ const query = `query getCommitShas(
1813
+ $owner: String!
1814
+ $repo: String!
1815
+ $ref: String!
1816
+ $path: String
1817
+ $after: String
1818
+ $before: String
1819
+ $limit: Int = 100
1820
+ $since: GitTimestamp
1821
+ $until: GitTimestamp
1822
+ ) {
1823
+ repository(name: $repo, owner: $owner) {
1824
+ object(expression: $ref) {
1825
+ ... on Commit {
1826
+ history(first: $limit, path: $path, after: $after, before: $before, since: $since, until: $until) {
1827
+ pageInfo {
1828
+ startCursor
1829
+ endCursor
1830
+ hasNextPage
1831
+ hasPreviousPage
1832
+ }
1833
+ nodes {
1834
+ ... on Commit { oid }
1835
+ }
1836
+ }
1837
+ }
1838
+ }
1839
+ }
1840
+ }`;
1841
+
1842
+ const rsp = await this.graphql<QueryResult>(
1843
+ undefined,
1844
+ token,
1845
+ query,
1846
+ {
1847
+ owner: owner,
1848
+ repo: repo,
1849
+ ref: ref,
1850
+ after: options?.after,
1851
+ before: options?.before,
1852
+ path: options?.path,
1853
+ limit: Math.min(100, options?.limit ?? 100),
1854
+ since: typeof options?.since === 'string' ? options?.since : options?.since?.toISOString(),
1855
+ until: typeof options?.until === 'string' ? options?.until : options?.until?.toISOString(),
1856
+ },
1857
+ scope,
1858
+ );
1859
+ const history = rsp?.repository?.object?.history;
1860
+ if (history == null) return emptyPagedResult;
1861
+
1862
+ return {
1863
+ paging:
1864
+ history.pageInfo.endCursor != null
1865
+ ? {
1866
+ cursor: history.pageInfo.endCursor ?? undefined,
1867
+ more: history.pageInfo.hasNextPage,
1868
+ }
1869
+ : undefined,
1870
+ values: history.nodes.map(n => n.oid),
1871
+ };
1872
+ } catch (ex) {
1873
+ if (ex instanceof RequestNotFoundError) return emptyPagedResult;
1874
+
1875
+ throw this.handleException(ex, undefined, scope);
1876
+ }
1877
+ }
1878
+
1770
1879
  private async getCommitsCoreRange(
1771
1880
  token: GitHubTokenInfo,
1772
1881
  owner: string,
@@ -1830,7 +1939,7 @@ export class GitHubApi {
1830
1939
  object(expression: $ref) {
1831
1940
  ...on Commit {
1832
1941
  oid
1833
- parents(first: 3) { nodes { oid } }
1942
+ parents(first: 8) { nodes { oid } }
1834
1943
  message
1835
1944
  additions
1836
1945
  changedFiles
@@ -2016,12 +2125,12 @@ export class GitHubApi {
2016
2125
  $until: GitTimestamp!
2017
2126
  ) {
2018
2127
  repository(owner: $owner, name: $repo) {
2019
- refs(first: 20, refPrefix: "refs/tags/") {
2128
+ refs(first: 100, refPrefix: "refs/tags/") {
2020
2129
  nodes {
2021
2130
  name
2022
2131
  target {
2023
2132
  ... on Commit {
2024
- history(first: 3, since: $since until: $until) {
2133
+ history(first: 10, since: $since until: $until) {
2025
2134
  nodes { oid }
2026
2135
  }
2027
2136
  }
@@ -2757,6 +2866,10 @@ export class GitHubApi {
2757
2866
  return version ?? undefined;
2758
2867
  }
2759
2868
 
2869
+ // Inflight dedupe: identical concurrent GraphQL requests share a single promise
2870
+ // to cut redundant traffic during graph/details enrichment bursts.
2871
+ private readonly _pendingGraphQL = new Map<string, Promise<unknown>>();
2872
+
2760
2873
  private async graphql<T>(
2761
2874
  provider: Provider | undefined,
2762
2875
  token: GitHubTokenInfo,
@@ -2766,56 +2879,89 @@ export class GitHubApi {
2766
2879
  cancellation?: CancellationToken | undefined,
2767
2880
  ): Promise<T | undefined> {
2768
2881
  const { accessToken, ...tokenInfo } = token;
2769
- try {
2770
- let aborter: AbortController | undefined;
2771
- if (cancellation != null) {
2772
- if (cancellation.isCancellationRequested) throw new CancellationError();
2773
2882
 
2774
- aborter = new AbortController();
2775
- cancellation.onCancellationRequested(() => aborter!.abort());
2776
-
2777
- variables = {
2778
- ...variables,
2779
- request: { ...variables?.request, signal: aborter.signal },
2780
- };
2883
+ // Only dedupe when no cancellation/request option is in play — sharing a promise that
2884
+ // carries one caller's AbortSignal would let one cancellation cancel for everyone.
2885
+ const dedupable = cancellation == null && variables?.request == null;
2886
+ let dedupeKey: string | undefined;
2887
+ if (dedupable) {
2888
+ try {
2889
+ dedupeKey = `${token.microHash}|${provider?.id ?? ''}|${query}|${JSON.stringify(variables ?? null)}`;
2890
+ } catch {
2891
+ // Non-serializable variable (BigInt, function, circular ref) — fall through to direct exec.
2892
+ dedupeKey = undefined;
2781
2893
  }
2894
+ if (dedupeKey != null) {
2895
+ const inflight = this._pendingGraphQL.get(dedupeKey);
2896
+ if (inflight != null) return inflight as Promise<T | undefined>;
2897
+ }
2898
+ }
2782
2899
 
2783
- return await this.config.wrapForForcedInsecureSSL(provider?.getIgnoreSSLErrors() ?? false, () =>
2784
- this.getDefaults(accessToken, graphql)(query, variables),
2785
- );
2786
- } catch (ex) {
2787
- if (ex instanceof GraphqlResponseError) {
2788
- switch (ex.errors?.[0]?.type) {
2789
- case 'NOT_FOUND':
2790
- throw new RequestNotFoundError(ex);
2791
- case 'FORBIDDEN':
2792
- throw new AuthenticationError(tokenInfo, AuthenticationErrorReason.Forbidden, ex);
2793
- case 'RATE_LIMITED': {
2794
- let resetAt: number | undefined;
2795
-
2796
- const reset = ex.headers?.['x-ratelimit-reset'];
2797
- if (reset != null) {
2798
- resetAt = parseInt(reset, 10);
2799
- if (Number.isNaN(resetAt)) {
2800
- resetAt = undefined;
2900
+ const run = async (): Promise<T | undefined> => {
2901
+ try {
2902
+ let aborter: AbortController | undefined;
2903
+ if (cancellation != null) {
2904
+ if (cancellation.isCancellationRequested) throw new CancellationError();
2905
+
2906
+ aborter = new AbortController();
2907
+ cancellation.onCancellationRequested(() => aborter!.abort());
2908
+
2909
+ variables = {
2910
+ ...variables,
2911
+ request: { ...variables?.request, signal: aborter.signal },
2912
+ };
2913
+ }
2914
+
2915
+ return await this.config.wrapForForcedInsecureSSL(provider?.getIgnoreSSLErrors() ?? false, () =>
2916
+ this.getDefaults(accessToken, graphql)(query, variables),
2917
+ );
2918
+ } catch (ex) {
2919
+ if (ex instanceof GraphqlResponseError) {
2920
+ switch (ex.errors?.[0]?.type) {
2921
+ case 'NOT_FOUND':
2922
+ throw new RequestNotFoundError(ex);
2923
+ case 'FORBIDDEN':
2924
+ throw new AuthenticationError(tokenInfo, AuthenticationErrorReason.Forbidden, ex);
2925
+ case 'RATE_LIMITED': {
2926
+ let resetAt: number | undefined;
2927
+
2928
+ const reset = ex.headers?.['x-ratelimit-reset'];
2929
+ if (reset != null) {
2930
+ resetAt = parseInt(reset, 10);
2931
+ if (Number.isNaN(resetAt)) {
2932
+ resetAt = undefined;
2933
+ }
2801
2934
  }
2935
+
2936
+ throw new RequestRateLimitError(ex, accessToken, resetAt);
2802
2937
  }
2938
+ }
2803
2939
 
2804
- throw new RequestRateLimitError(ex, accessToken, resetAt);
2940
+ if (Logger.isDebugging) {
2941
+ this.config.onDebugError?.(`GitHub request failed: ${ex.errors?.[0]?.message ?? ex.message}`);
2805
2942
  }
2943
+ } else if (ex instanceof RequestError || ex.name === 'AbortError') {
2944
+ this.handleRequestError(provider, token, ex, scope);
2945
+ } else if (Logger.isDebugging) {
2946
+ this.config.onDebugError?.(`GitHub request failed: ${ex.message}`);
2806
2947
  }
2807
2948
 
2808
- if (Logger.isDebugging) {
2809
- this.config.onDebugError?.(`GitHub request failed: ${ex.errors?.[0]?.message ?? ex.message}`);
2810
- }
2811
- } else if (ex instanceof RequestError || ex.name === 'AbortError') {
2812
- this.handleRequestError(provider, token, ex, scope);
2813
- } else if (Logger.isDebugging) {
2814
- this.config.onDebugError?.(`GitHub request failed: ${ex.message}`);
2949
+ throw ex;
2815
2950
  }
2951
+ };
2816
2952
 
2817
- throw ex;
2818
- }
2953
+ if (dedupeKey == null) return run();
2954
+
2955
+ const promise = run();
2956
+ this._pendingGraphQL.set(dedupeKey, promise);
2957
+ // Clear from the inflight map once the promise settles — successes and failures both
2958
+ // clear, so failed requests don't poison subsequent retries.
2959
+ void promise.finally(() => {
2960
+ if (this._pendingGraphQL.get(dedupeKey) === promise) {
2961
+ this._pendingGraphQL.delete(dedupeKey);
2962
+ }
2963
+ });
2964
+ return promise;
2819
2965
  }
2820
2966
 
2821
2967
  private async request<R extends keyof Endpoints>(
@@ -103,6 +103,21 @@ export interface GitHubApiClient {
103
103
  },
104
104
  ): Promise<PagedResult<GitHubCommit> & { viewer?: string }>;
105
105
 
106
+ getCommitShas(
107
+ token: GitHubTokenInfo,
108
+ owner: string,
109
+ repo: string,
110
+ ref: string,
111
+ options?: {
112
+ after?: string;
113
+ before?: string;
114
+ limit?: number;
115
+ path?: string;
116
+ since?: string | Date;
117
+ until?: string | Date;
118
+ },
119
+ ): Promise<PagedResult<string>>;
120
+
106
121
  getCommitRefs(
107
122
  token: GitHubTokenInfo,
108
123
  owner: string,
@@ -1,3 +1,4 @@
1
+ import type { Endpoints } from '@octokit/types';
1
2
  import { GitFileIndexStatus } from '../../git/models/fileStatus.js';
2
3
  import type { IssueLabel } from '../../git/models/issue.js';
3
4
  import { Issue, RepositoryAccessLevel } from '../../git/models/issue.js';
@@ -10,7 +11,6 @@ import {
10
11
  PullRequestStatusCheckRollupState,
11
12
  } from '../../git/models/pullRequest.js';
12
13
  import type { Provider } from '../../git/models/remoteProvider.js';
13
- import type { Endpoints } from '@octokit/types';
14
14
 
15
15
  export interface GitHubBlame {
16
16
  ranges: GitHubBlameRange[];
@@ -73,6 +73,7 @@ export class BlameGitHubSubProvider implements GitBlameSubProvider {
73
73
  let blameLine = blame.lines[editorLine];
74
74
  if (blameLine == null) {
75
75
  if (blame.lines.length !== editorLine) return undefined;
76
+
76
77
  blameLine = blame.lines[editorLine - 1];
77
78
  }
78
79
 
@@ -106,6 +107,7 @@ export class BlameGitHubSubProvider implements GitBlameSubProvider {
106
107
  try {
107
108
  const context = await this.provider.ensureRepositoryContext(repoPath);
108
109
  if (context == null) return undefined;
110
+
109
111
  const { metadata, github, session } = context;
110
112
 
111
113
  const root = this.provider.createVirtualUri(repoPath, undefined);