@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
@@ -20,6 +20,8 @@ export function getActionName(action: AIActionType): string {
20
20
  return 'Create Pull Request Details (Preview)';
21
21
  case 'generate-commits':
22
22
  return 'Generate Commits (Preview)';
23
+ case 'conflict-resolution':
24
+ return 'Resolve Conflicts with AI (Preview)';
23
25
  case 'generate-searchQuery':
24
26
  return 'Generate Search Query (Preview)';
25
27
  }
@@ -78,9 +78,11 @@ function parseSeverity(value: string | undefined): AIReviewSeverity {
78
78
 
79
79
  function parseLineRange(value: string | undefined): { start: number; end: number } | undefined {
80
80
  if (!value) return undefined;
81
+
81
82
  const parts = value.split('-');
82
83
  const start = parseInt(parts[0], 10);
83
84
  if (isNaN(start)) return undefined;
85
+
84
86
  const end = parts.length > 1 ? parseInt(parts[1], 10) : start;
85
87
  return { start: start, end: isNaN(end) ? start : end };
86
88
  }
@@ -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,
@@ -74,6 +74,46 @@ interface CancellationToken {
74
74
  const emptyPagedResult: PagedResult<any> = Object.freeze({ values: [] });
75
75
  const emptyBlameResult: GitHubBlame = Object.freeze({ ranges: [] });
76
76
 
77
+ // Transient gateway/network failures (e.g. an upstream `502 Bad Gateway`) are worth a few quick
78
+ // retries before surfacing to the caller. octokit provides no built-in retry for the standalone
79
+ // `request`/`graphql` functions we use (its retry/throttle plugins only attach to the `Octokit`
80
+ // class), so we retry here — but only for idempotent reads (REST GET/HEAD, GraphQL queries),
81
+ // never for mutations.
82
+ const maxRequestRetries = 2;
83
+ const requestRetryBaseDelay = 300; // ms
84
+ const requestRetryMaxDelay = 2000; // ms
85
+
86
+ function isRetryableTransientError(ex: unknown): ex is RequestError {
87
+ // An aborted request is rethrown as the original `AbortError` (not a `RequestError`), so it is
88
+ // excluded here. octokit maps a fetch/network failure to a `RequestError` with status 500 and
89
+ // no response — those, along with real gateway statuses, are transient and safe to retry.
90
+ if (!(ex instanceof RequestError)) return false;
91
+
92
+ switch (ex.status) {
93
+ case 502: // Bad Gateway
94
+ case 503: // Service Unavailable
95
+ case 504: // Gateway Timeout
96
+ return true;
97
+ case 500: // Internal Server Error — only the network-failure variant (no response)
98
+ return ex.response == null;
99
+ default:
100
+ return false;
101
+ }
102
+ }
103
+
104
+ function getRequestRetryDelay(attempt: number): number {
105
+ // Exponential backoff with equal jitter, capped — spreads retries so a brief upstream blip
106
+ // isn't hammered by every in-flight request landing on the same schedule.
107
+ const backoff = Math.min(requestRetryMaxDelay, requestRetryBaseDelay * 2 ** (attempt - 1));
108
+ return Math.round(backoff / 2 + Math.random() * (backoff / 2));
109
+ }
110
+
111
+ // Matches a GraphQL document whose operation is definitely a read query — the `query` keyword as
112
+ // the first significant token, after any leading whitespace or `#` comment lines. We retry only
113
+ // when this matches; a mutation (even one prefixed by a comment), a subscription, or anything we
114
+ // can't classify is left non-retryable so a transient failure can never re-run a mutation.
115
+ const graphqlReadQueryRegex = /^(?:\s|#[^\n]*\n?)*query\b/;
116
+
77
117
  const gqlIssueOrPullRequestFragment = `
78
118
  closed
79
119
  closedAt
@@ -120,7 +160,7 @@ repository {
120
160
  const gqlPullRequestFragment = `
121
161
  ${gqlPullRequestLiteFragment}
122
162
  additions
123
- assignees(first: 10) {
163
+ assignees(first: 25) {
124
164
  nodes {
125
165
  login
126
166
  avatarUrl(size: $avatarSize)
@@ -134,7 +174,7 @@ mergedBy {
134
174
  login
135
175
  }
136
176
  reviewDecision
137
- latestReviews(first: 10) {
177
+ latestReviews(first: 25) {
138
178
  nodes {
139
179
  author {
140
180
  login
@@ -144,7 +184,7 @@ latestReviews(first: 10) {
144
184
  state
145
185
  }
146
186
  }
147
- reviewRequests(first: 10) {
187
+ reviewRequests(first: 25) {
148
188
  nodes {
149
189
  asCodeOwner
150
190
  id
@@ -187,7 +227,7 @@ author {
187
227
  comments {
188
228
  totalCount
189
229
  }
190
- labels(first: 20) {
230
+ labels(first: 50) {
191
231
  nodes {
192
232
  color
193
233
  name
@@ -1138,7 +1178,7 @@ export class GitHubApi {
1138
1178
  endingLine
1139
1179
  commit {
1140
1180
  oid
1141
- parents(first: 3) { nodes { oid } }
1181
+ parents(first: 8) { nodes { oid } }
1142
1182
  message
1143
1183
  additions
1144
1184
  changedFiles
@@ -1406,7 +1446,7 @@ export class GitHubApi {
1406
1446
  $until: GitTimestamp!
1407
1447
  ) {
1408
1448
  repository(owner: $owner, name: $repo) {
1409
- refs(first: 20, refPrefix: "refs/heads/") {
1449
+ refs(first: 100, refPrefix: "refs/heads/") {
1410
1450
  nodes {
1411
1451
  name
1412
1452
  target {
@@ -1691,7 +1731,7 @@ export class GitHubApi {
1691
1731
  ... on Commit {
1692
1732
  oid
1693
1733
  message
1694
- parents(first: 3) { nodes { oid } }
1734
+ parents(first: 8) { nodes { oid } }
1695
1735
  additions
1696
1736
  changedFiles
1697
1737
  deletions
@@ -1767,6 +1807,115 @@ export class GitHubApi {
1767
1807
  }
1768
1808
  }
1769
1809
 
1810
+ @trace({
1811
+ args: (token, owner, repo, ref) => ({
1812
+ token: `<token:${token.microHash}>`,
1813
+ owner: owner,
1814
+ repo: repo,
1815
+ ref: ref,
1816
+ }),
1817
+ })
1818
+ async getCommitShas(
1819
+ token: GitHubTokenInfo,
1820
+ owner: string,
1821
+ repo: string,
1822
+ ref: string,
1823
+ options?: {
1824
+ after?: string;
1825
+ before?: string;
1826
+ limit?: number;
1827
+ path?: string;
1828
+ since?: string | Date;
1829
+ until?: string | Date;
1830
+ },
1831
+ ): Promise<PagedResult<string>> {
1832
+ const scope = getScopedLogger();
1833
+
1834
+ interface QueryResult {
1835
+ repository:
1836
+ | {
1837
+ object:
1838
+ | {
1839
+ history: {
1840
+ pageInfo: GitHubPageInfo;
1841
+ nodes: { oid: string }[];
1842
+ };
1843
+ }
1844
+ | null
1845
+ | undefined;
1846
+ }
1847
+ | null
1848
+ | undefined;
1849
+ }
1850
+
1851
+ try {
1852
+ const query = `query getCommitShas(
1853
+ $owner: String!
1854
+ $repo: String!
1855
+ $ref: String!
1856
+ $path: String
1857
+ $after: String
1858
+ $before: String
1859
+ $limit: Int = 100
1860
+ $since: GitTimestamp
1861
+ $until: GitTimestamp
1862
+ ) {
1863
+ repository(name: $repo, owner: $owner) {
1864
+ object(expression: $ref) {
1865
+ ... on Commit {
1866
+ history(first: $limit, path: $path, after: $after, before: $before, since: $since, until: $until) {
1867
+ pageInfo {
1868
+ startCursor
1869
+ endCursor
1870
+ hasNextPage
1871
+ hasPreviousPage
1872
+ }
1873
+ nodes {
1874
+ ... on Commit { oid }
1875
+ }
1876
+ }
1877
+ }
1878
+ }
1879
+ }
1880
+ }`;
1881
+
1882
+ const rsp = await this.graphql<QueryResult>(
1883
+ undefined,
1884
+ token,
1885
+ query,
1886
+ {
1887
+ owner: owner,
1888
+ repo: repo,
1889
+ ref: ref,
1890
+ after: options?.after,
1891
+ before: options?.before,
1892
+ path: options?.path,
1893
+ limit: Math.min(100, options?.limit ?? 100),
1894
+ since: typeof options?.since === 'string' ? options?.since : options?.since?.toISOString(),
1895
+ until: typeof options?.until === 'string' ? options?.until : options?.until?.toISOString(),
1896
+ },
1897
+ scope,
1898
+ );
1899
+ const history = rsp?.repository?.object?.history;
1900
+ if (history == null) return emptyPagedResult;
1901
+
1902
+ return {
1903
+ paging:
1904
+ history.pageInfo.endCursor != null
1905
+ ? {
1906
+ cursor: history.pageInfo.endCursor ?? undefined,
1907
+ more: history.pageInfo.hasNextPage,
1908
+ }
1909
+ : undefined,
1910
+ values: history.nodes.map(n => n.oid),
1911
+ };
1912
+ } catch (ex) {
1913
+ if (ex instanceof RequestNotFoundError) return emptyPagedResult;
1914
+
1915
+ throw this.handleException(ex, undefined, scope);
1916
+ }
1917
+ }
1918
+
1770
1919
  private async getCommitsCoreRange(
1771
1920
  token: GitHubTokenInfo,
1772
1921
  owner: string,
@@ -1830,7 +1979,7 @@ export class GitHubApi {
1830
1979
  object(expression: $ref) {
1831
1980
  ...on Commit {
1832
1981
  oid
1833
- parents(first: 3) { nodes { oid } }
1982
+ parents(first: 8) { nodes { oid } }
1834
1983
  message
1835
1984
  additions
1836
1985
  changedFiles
@@ -2016,12 +2165,12 @@ export class GitHubApi {
2016
2165
  $until: GitTimestamp!
2017
2166
  ) {
2018
2167
  repository(owner: $owner, name: $repo) {
2019
- refs(first: 20, refPrefix: "refs/tags/") {
2168
+ refs(first: 100, refPrefix: "refs/tags/") {
2020
2169
  nodes {
2021
2170
  name
2022
2171
  target {
2023
2172
  ... on Commit {
2024
- history(first: 3, since: $since until: $until) {
2173
+ history(first: 10, since: $since until: $until) {
2025
2174
  nodes { oid }
2026
2175
  }
2027
2176
  }
@@ -2757,6 +2906,59 @@ export class GitHubApi {
2757
2906
  return version ?? undefined;
2758
2907
  }
2759
2908
 
2909
+ // Runs `execute`, retrying transient gateway/network failures with backoff. `retryable` gates
2910
+ // retries to idempotent reads; `signal` lets an in-flight cancellation abort the backoff wait.
2911
+ private async requestWithRetries<T>(
2912
+ execute: () => Promise<T>,
2913
+ retryable: boolean,
2914
+ signal: AbortSignal | undefined,
2915
+ scope: ScopedLogger | undefined,
2916
+ ): Promise<T> {
2917
+ let attempt = 0;
2918
+ while (true) {
2919
+ try {
2920
+ return await execute();
2921
+ } catch (ex) {
2922
+ if (!retryable || attempt >= maxRequestRetries || signal?.aborted || !isRetryableTransientError(ex)) {
2923
+ throw ex;
2924
+ }
2925
+
2926
+ attempt++;
2927
+ const delay = getRequestRetryDelay(attempt);
2928
+ scope?.warn(
2929
+ `Transient request failure (status ${ex.status}); retrying ${attempt}/${maxRequestRetries} in ${delay}ms`,
2930
+ );
2931
+ await this.delayWithAbort(delay, signal);
2932
+ // Bail rather than retry if we were cancelled while waiting
2933
+ if (signal?.aborted) throw new CancellationError();
2934
+ }
2935
+ }
2936
+ }
2937
+
2938
+ private delayWithAbort(ms: number, signal: AbortSignal | undefined): Promise<void> {
2939
+ return new Promise<void>(resolve => {
2940
+ if (signal?.aborted) {
2941
+ resolve();
2942
+ return;
2943
+ }
2944
+
2945
+ let timer: ReturnType<typeof setTimeout>;
2946
+ const onAbort = () => {
2947
+ clearTimeout(timer);
2948
+ resolve();
2949
+ };
2950
+ timer = setTimeout(() => {
2951
+ signal?.removeEventListener('abort', onAbort);
2952
+ resolve();
2953
+ }, ms);
2954
+ signal?.addEventListener('abort', onAbort, { once: true });
2955
+ });
2956
+ }
2957
+
2958
+ // Inflight dedupe: identical concurrent GraphQL requests share a single promise
2959
+ // to cut redundant traffic during graph/details enrichment bursts.
2960
+ private readonly _pendingGraphQL = new Map<string, Promise<unknown>>();
2961
+
2760
2962
  private async graphql<T>(
2761
2963
  provider: Provider | undefined,
2762
2964
  token: GitHubTokenInfo,
@@ -2766,56 +2968,101 @@ export class GitHubApi {
2766
2968
  cancellation?: CancellationToken | undefined,
2767
2969
  ): Promise<T | undefined> {
2768
2970
  const { accessToken, ...tokenInfo } = token;
2769
- try {
2770
- let aborter: AbortController | undefined;
2771
- if (cancellation != null) {
2772
- if (cancellation.isCancellationRequested) throw new CancellationError();
2773
-
2774
- aborter = new AbortController();
2775
- cancellation.onCancellationRequested(() => aborter!.abort());
2776
2971
 
2777
- variables = {
2778
- ...variables,
2779
- request: { ...variables?.request, signal: aborter.signal },
2780
- };
2972
+ // Only dedupe when no cancellation/request option is in play — sharing a promise that
2973
+ // carries one caller's AbortSignal would let one cancellation cancel for everyone.
2974
+ const dedupable = cancellation == null && variables?.request == null;
2975
+ let dedupeKey: string | undefined;
2976
+ if (dedupable) {
2977
+ try {
2978
+ dedupeKey = `${token.microHash}|${provider?.id ?? ''}|${query}|${JSON.stringify(variables ?? null)}`;
2979
+ } catch {
2980
+ // Non-serializable variable (BigInt, function, circular ref) — fall through to direct exec.
2981
+ dedupeKey = undefined;
2982
+ }
2983
+ if (dedupeKey != null) {
2984
+ const inflight = this._pendingGraphQL.get(dedupeKey);
2985
+ if (inflight != null) return inflight as Promise<T | undefined>;
2781
2986
  }
2987
+ }
2782
2988
 
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;
2989
+ const run = async (): Promise<T | undefined> => {
2990
+ try {
2991
+ let aborter: AbortController | undefined;
2992
+ if (cancellation != null) {
2993
+ if (cancellation.isCancellationRequested) throw new CancellationError();
2994
+
2995
+ aborter = new AbortController();
2996
+ cancellation.onCancellationRequested(() => aborter!.abort());
2997
+
2998
+ variables = {
2999
+ ...variables,
3000
+ request: { ...variables?.request, signal: aborter.signal },
3001
+ };
3002
+ }
3003
+
3004
+ // Retry transient gateway/network failures, but only confirmed read queries — never
3005
+ // mutations (re-running one isn't idempotent)
3006
+ const retryable = graphqlReadQueryRegex.test(query);
3007
+ return await this.requestWithRetries(
3008
+ () =>
3009
+ this.config.wrapForForcedInsecureSSL(provider?.getIgnoreSSLErrors() ?? false, () =>
3010
+ this.getDefaults(accessToken, graphql)(query, variables),
3011
+ ),
3012
+ retryable,
3013
+ aborter?.signal,
3014
+ scope,
3015
+ );
3016
+ } catch (ex) {
3017
+ if (ex instanceof GraphqlResponseError) {
3018
+ switch (ex.errors?.[0]?.type) {
3019
+ case 'NOT_FOUND':
3020
+ throw new RequestNotFoundError(ex);
3021
+ case 'FORBIDDEN':
3022
+ throw new AuthenticationError(tokenInfo, AuthenticationErrorReason.Forbidden, ex);
3023
+ case 'RATE_LIMITED': {
3024
+ let resetAt: number | undefined;
3025
+
3026
+ const reset = ex.headers?.['x-ratelimit-reset'];
3027
+ if (reset != null) {
3028
+ resetAt = parseInt(reset, 10);
3029
+ if (Number.isNaN(resetAt)) {
3030
+ resetAt = undefined;
3031
+ }
2801
3032
  }
3033
+
3034
+ throw new RequestRateLimitError(ex, accessToken, resetAt);
2802
3035
  }
3036
+ }
2803
3037
 
2804
- throw new RequestRateLimitError(ex, accessToken, resetAt);
3038
+ if (Logger.isDebugging) {
3039
+ this.config.onDebugError?.(`GitHub request failed: ${ex.errors?.[0]?.message ?? ex.message}`);
2805
3040
  }
3041
+ } else if (ex instanceof RequestError || ex.name === 'AbortError') {
3042
+ this.handleRequestError(provider, token, ex, scope);
3043
+ } else if (Logger.isDebugging) {
3044
+ this.config.onDebugError?.(`GitHub request failed: ${ex.message}`);
2806
3045
  }
2807
3046
 
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}`);
3047
+ throw ex;
2815
3048
  }
2816
-
2817
- throw ex;
2818
- }
3049
+ };
3050
+
3051
+ if (dedupeKey == null) return run();
3052
+
3053
+ const promise = run();
3054
+ this._pendingGraphQL.set(dedupeKey, promise);
3055
+ // Clear from the inflight map once the promise settles — successes and failures both
3056
+ // clear, so failed requests don't poison subsequent retries. Use `then(cleanup, cleanup)`
3057
+ // rather than `finally` so a rejected request doesn't spawn an orphaned (unhandled) promise;
3058
+ // the real caller still receives the rejection via the returned `promise`.
3059
+ const cleanup = () => {
3060
+ if (this._pendingGraphQL.get(dedupeKey) === promise) {
3061
+ this._pendingGraphQL.delete(dedupeKey);
3062
+ }
3063
+ };
3064
+ promise.then(cleanup, cleanup);
3065
+ return promise;
2819
3066
  }
2820
3067
 
2821
3068
  private async request<R extends keyof Endpoints>(
@@ -2828,16 +3075,27 @@ export class GitHubApi {
2828
3075
  ): Promise<Endpoints[R]['response']> {
2829
3076
  const { accessToken } = token;
2830
3077
  try {
3078
+ let signal: AbortSignal | undefined;
2831
3079
  if (cancellation != null) {
2832
3080
  if (cancellation.isCancellationRequested) throw new CancellationError();
2833
3081
 
2834
3082
  const aborter = new AbortController();
2835
3083
  cancellation.onCancellationRequested(() => aborter.abort());
2836
- options = { ...options, request: { ...options?.request, signal: aborter.signal } };
3084
+ signal = aborter.signal;
3085
+ options = { ...options, request: { ...options?.request, signal: signal } };
2837
3086
  }
2838
3087
 
2839
- return (await this.config.wrapForForcedInsecureSSL(provider?.getIgnoreSSLErrors() ?? false, () =>
2840
- this.getDefaults(accessToken, request)(route as string, options),
3088
+ // Retry transient gateway/network failures on idempotent reads only
3089
+ const method = route.split(' ', 1)[0].toUpperCase();
3090
+ const retryable = method === 'GET' || method === 'HEAD';
3091
+ return (await this.requestWithRetries(
3092
+ () =>
3093
+ this.config.wrapForForcedInsecureSSL(provider?.getIgnoreSSLErrors() ?? false, () =>
3094
+ this.getDefaults(accessToken, request)(route as string, options),
3095
+ ),
3096
+ retryable,
3097
+ signal,
3098
+ scope,
2841
3099
  )) as Endpoints[R]['response'];
2842
3100
  } catch (ex) {
2843
3101
  if (ex instanceof RequestError || ex.name === 'AbortError') {
@@ -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);