@gitkraken/core-gitlens 0.5.109 → 0.5.111

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 (416) hide show
  1. package/CHANGELOG.md +48 -1
  2. package/dist/git/cache.d.ts +111 -6
  3. package/dist/git/cache.d.ts.map +1 -1
  4. package/dist/git/cache.js +312 -43
  5. package/dist/git/cache.js.map +1 -1
  6. package/dist/git/context.d.ts +11 -0
  7. package/dist/git/context.d.ts.map +1 -1
  8. package/dist/git/context.js.map +1 -1
  9. package/dist/git/models/fileStatus.d.ts +1 -0
  10. package/dist/git/models/fileStatus.d.ts.map +1 -1
  11. package/dist/git/models/fileStatus.js +1 -0
  12. package/dist/git/models/fileStatus.js.map +1 -1
  13. package/dist/git/models/issue.d.ts +4 -0
  14. package/dist/git/models/issue.d.ts.map +1 -1
  15. package/dist/git/models/mergeConflicts.d.ts +2 -0
  16. package/dist/git/models/mergeConflicts.d.ts.map +1 -1
  17. package/dist/git/models/pullRequest.d.ts +119 -2
  18. package/dist/git/models/pullRequest.d.ts.map +1 -1
  19. package/dist/git/models/pullRequest.js +27 -1
  20. package/dist/git/models/pullRequest.js.map +1 -1
  21. package/dist/git/models/repository.d.ts +32 -5
  22. package/dist/git/models/repository.d.ts.map +1 -1
  23. package/dist/git/models/repository.js +58 -12
  24. package/dist/git/models/repository.js.map +1 -1
  25. package/dist/git/models/statusFile.d.ts.map +1 -1
  26. package/dist/git/models/statusFile.js +3 -0
  27. package/dist/git/models/statusFile.js.map +1 -1
  28. package/dist/git/providers/branches.d.ts +2 -0
  29. package/dist/git/providers/branches.d.ts.map +1 -1
  30. package/dist/git/providers/commits.d.ts +8 -0
  31. package/dist/git/providers/commits.d.ts.map +1 -1
  32. package/dist/git/providers/config.d.ts +19 -1
  33. package/dist/git/providers/config.d.ts.map +1 -1
  34. package/dist/git/providers/operations.d.ts +1 -0
  35. package/dist/git/providers/operations.d.ts.map +1 -1
  36. package/dist/git/providers/pausedOperations.d.ts +2 -0
  37. package/dist/git/providers/pausedOperations.d.ts.map +1 -1
  38. package/dist/git/providers/status.d.ts +1 -0
  39. package/dist/git/providers/status.d.ts.map +1 -1
  40. package/dist/git/utils/config.utils.d.ts +3 -0
  41. package/dist/git/utils/config.utils.d.ts.map +1 -0
  42. package/dist/git/utils/config.utils.js +8 -0
  43. package/dist/git/utils/config.utils.js.map +1 -0
  44. package/dist/git/utils/issue.utils.d.ts.map +1 -1
  45. package/dist/git/utils/issue.utils.js +2 -0
  46. package/dist/git/utils/issue.utils.js.map +1 -1
  47. package/dist/git/utils/pausedOperationStatus.utils.d.ts +14 -0
  48. package/dist/git/utils/pausedOperationStatus.utils.d.ts.map +1 -1
  49. package/dist/git/utils/pausedOperationStatus.utils.js +23 -0
  50. package/dist/git/utils/pausedOperationStatus.utils.js.map +1 -1
  51. package/dist/git/utils/pullRequest.utils.d.ts +24 -1
  52. package/dist/git/utils/pullRequest.utils.d.ts.map +1 -1
  53. package/dist/git/utils/pullRequest.utils.js +71 -0
  54. package/dist/git/utils/pullRequest.utils.js.map +1 -1
  55. package/dist/git/watching/changeEvent.d.ts +6 -1
  56. package/dist/git/watching/changeEvent.d.ts.map +1 -1
  57. package/dist/git/watching/classifyChange.d.ts.map +1 -1
  58. package/dist/git/watching/classifyChange.js +14 -1
  59. package/dist/git/watching/classifyChange.js.map +1 -1
  60. package/dist/git/watching/watchService.d.ts.map +1 -1
  61. package/dist/git/watching/watchService.js +18 -3
  62. package/dist/git/watching/watchService.js.map +1 -1
  63. package/dist/git/watching/watchSession.d.ts +8 -1
  64. package/dist/git/watching/watchSession.d.ts.map +1 -1
  65. package/dist/git/watching/watchSession.js +38 -6
  66. package/dist/git/watching/watchSession.js.map +1 -1
  67. package/dist/git/watching/watcherPatterns.d.ts +2 -2
  68. package/dist/git/watching/watcherPatterns.d.ts.map +1 -1
  69. package/dist/git/watching/watcherPatterns.js +1 -1
  70. package/dist/git/watching/watcherPatterns.js.map +1 -1
  71. package/dist/git-cli/exec/git.d.ts +1 -1
  72. package/dist/git-cli/exec/git.d.ts.map +1 -1
  73. package/dist/git-cli/exec/git.js +13 -3
  74. package/dist/git-cli/exec/git.js.map +1 -1
  75. package/dist/git-cli/providers/branches.d.ts +19 -0
  76. package/dist/git-cli/providers/branches.d.ts.map +1 -1
  77. package/dist/git-cli/providers/branches.js +282 -78
  78. package/dist/git-cli/providers/branches.js.map +1 -1
  79. package/dist/git-cli/providers/commits.d.ts +4 -0
  80. package/dist/git-cli/providers/commits.d.ts.map +1 -1
  81. package/dist/git-cli/providers/commits.js +84 -11
  82. package/dist/git-cli/providers/commits.js.map +1 -1
  83. package/dist/git-cli/providers/config.d.ts +42 -0
  84. package/dist/git-cli/providers/config.d.ts.map +1 -1
  85. package/dist/git-cli/providers/config.js +186 -5
  86. package/dist/git-cli/providers/config.js.map +1 -1
  87. package/dist/git-cli/providers/contributors.d.ts.map +1 -1
  88. package/dist/git-cli/providers/contributors.js +1 -1
  89. package/dist/git-cli/providers/contributors.js.map +1 -1
  90. package/dist/git-cli/providers/graph.d.ts +2 -2
  91. package/dist/git-cli/providers/graph.d.ts.map +1 -1
  92. package/dist/git-cli/providers/graph.js +27 -9
  93. package/dist/git-cli/providers/graph.js.map +1 -1
  94. package/dist/git-cli/providers/operations.d.ts.map +1 -1
  95. package/dist/git-cli/providers/operations.js +40 -12
  96. package/dist/git-cli/providers/operations.js.map +1 -1
  97. package/dist/git-cli/providers/pausedOperations.d.ts +5 -0
  98. package/dist/git-cli/providers/pausedOperations.d.ts.map +1 -1
  99. package/dist/git-cli/providers/pausedOperations.js +87 -16
  100. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  101. package/dist/git-cli/providers/refs.d.ts +5 -3
  102. package/dist/git-cli/providers/refs.d.ts.map +1 -1
  103. package/dist/git-cli/providers/refs.js +33 -4
  104. package/dist/git-cli/providers/refs.js.map +1 -1
  105. package/dist/git-cli/providers/status.d.ts +1 -0
  106. package/dist/git-cli/providers/status.d.ts.map +1 -1
  107. package/dist/git-cli/providers/status.js +18 -3
  108. package/dist/git-cli/providers/status.js.map +1 -1
  109. package/dist/git-cli/providers/worktrees.d.ts.map +1 -1
  110. package/dist/git-cli/providers/worktrees.js +4 -0
  111. package/dist/git-cli/providers/worktrees.js.map +1 -1
  112. package/dist/git-cli/service.d.ts.map +1 -1
  113. package/dist/git-cli/service.js.map +1 -1
  114. package/dist/plus/agents/providers/claudeCodeProvider.d.ts +39 -1
  115. package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -1
  116. package/dist/plus/agents/providers/claudeCodeProvider.js +978 -71
  117. package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -1
  118. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts +24 -2
  119. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts.map +1 -1
  120. package/dist/plus/agents/providers/claudeCodeTranscript.js +84 -9
  121. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
  122. package/dist/plus/agents/types.d.ts +37 -2
  123. package/dist/plus/agents/types.d.ts.map +1 -1
  124. package/dist/plus/agents/types.js +2 -0
  125. package/dist/plus/agents/types.js.map +1 -1
  126. package/dist/plus/ai/errors.d.ts +10 -0
  127. package/dist/plus/ai/errors.d.ts.map +1 -1
  128. package/dist/plus/ai/errors.js +29 -0
  129. package/dist/plus/ai/errors.js.map +1 -1
  130. package/dist/plus/ai/models/model.d.ts +4 -0
  131. package/dist/plus/ai/models/model.d.ts.map +1 -1
  132. package/dist/plus/ai/models/model.js +51 -6
  133. package/dist/plus/ai/models/model.js.map +1 -1
  134. package/dist/plus/ai/models/promptTemplates.d.ts +1 -1
  135. package/dist/plus/ai/models/promptTemplates.d.ts.map +1 -1
  136. package/dist/plus/ai/models/provider.d.ts +60 -2
  137. package/dist/plus/ai/models/provider.d.ts.map +1 -1
  138. package/dist/plus/ai/prompts.d.ts +12 -0
  139. package/dist/plus/ai/prompts.d.ts.map +1 -1
  140. package/dist/plus/ai/prompts.js +177 -61
  141. package/dist/plus/ai/prompts.js.map +1 -1
  142. package/dist/plus/ai/providers/anthropicProvider.d.ts +10 -2
  143. package/dist/plus/ai/providers/anthropicProvider.d.ts.map +1 -1
  144. package/dist/plus/ai/providers/anthropicProvider.js +139 -46
  145. package/dist/plus/ai/providers/anthropicProvider.js.map +1 -1
  146. package/dist/plus/ai/providers/deepSeekProvider.d.ts +2 -0
  147. package/dist/plus/ai/providers/deepSeekProvider.d.ts.map +1 -1
  148. package/dist/plus/ai/providers/deepSeekProvider.js +10 -21
  149. package/dist/plus/ai/providers/deepSeekProvider.js.map +1 -1
  150. package/dist/plus/ai/providers/geminiProvider.d.ts +1 -0
  151. package/dist/plus/ai/providers/geminiProvider.d.ts.map +1 -1
  152. package/dist/plus/ai/providers/geminiProvider.js +19 -0
  153. package/dist/plus/ai/providers/geminiProvider.js.map +1 -1
  154. package/dist/plus/ai/providers/gitkrakenProvider.d.ts +5 -1
  155. package/dist/plus/ai/providers/gitkrakenProvider.d.ts.map +1 -1
  156. package/dist/plus/ai/providers/gitkrakenProvider.js +118 -3
  157. package/dist/plus/ai/providers/gitkrakenProvider.js.map +1 -1
  158. package/dist/plus/ai/providers/huggingFaceProvider.d.ts +1 -0
  159. package/dist/plus/ai/providers/huggingFaceProvider.d.ts.map +1 -1
  160. package/dist/plus/ai/providers/huggingFaceProvider.js +5 -0
  161. package/dist/plus/ai/providers/huggingFaceProvider.js.map +1 -1
  162. package/dist/plus/ai/providers/mistralProvider.d.ts +3 -1
  163. package/dist/plus/ai/providers/mistralProvider.d.ts.map +1 -1
  164. package/dist/plus/ai/providers/mistralProvider.js +99 -19
  165. package/dist/plus/ai/providers/mistralProvider.js.map +1 -1
  166. package/dist/plus/ai/providers/ollamaProvider.d.ts +4 -3
  167. package/dist/plus/ai/providers/ollamaProvider.d.ts.map +1 -1
  168. package/dist/plus/ai/providers/ollamaProvider.js +38 -3
  169. package/dist/plus/ai/providers/ollamaProvider.js.map +1 -1
  170. package/dist/plus/ai/providers/openAICompatibleProvider.d.ts +1 -0
  171. package/dist/plus/ai/providers/openAICompatibleProvider.d.ts.map +1 -1
  172. package/dist/plus/ai/providers/openAICompatibleProvider.js +4 -0
  173. package/dist/plus/ai/providers/openAICompatibleProvider.js.map +1 -1
  174. package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts +154 -5
  175. package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts.map +1 -1
  176. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +259 -10
  177. package/dist/plus/ai/providers/openAICompatibleProviderBase.js.map +1 -1
  178. package/dist/plus/ai/providers/openRouterProvider.d.ts +4 -0
  179. package/dist/plus/ai/providers/openRouterProvider.d.ts.map +1 -1
  180. package/dist/plus/ai/providers/openRouterProvider.js +9 -0
  181. package/dist/plus/ai/providers/openRouterProvider.js.map +1 -1
  182. package/dist/plus/ai/providers/openaiProvider.d.ts +1 -0
  183. package/dist/plus/ai/providers/openaiProvider.d.ts.map +1 -1
  184. package/dist/plus/ai/providers/openaiProvider.js +1 -0
  185. package/dist/plus/ai/providers/openaiProvider.js.map +1 -1
  186. package/dist/plus/ai/providers/responseFormatCache.d.ts +8 -0
  187. package/dist/plus/ai/providers/responseFormatCache.d.ts.map +1 -0
  188. package/dist/plus/ai/providers/responseFormatCache.js +25 -0
  189. package/dist/plus/ai/providers/responseFormatCache.js.map +1 -0
  190. package/dist/plus/ai/providers/xaiProvider.d.ts +1 -0
  191. package/dist/plus/ai/providers/xaiProvider.d.ts.map +1 -1
  192. package/dist/plus/ai/providers/xaiProvider.js +10 -1
  193. package/dist/plus/ai/providers/xaiProvider.js.map +1 -1
  194. package/dist/plus/ai/utils/ai.utils.d.ts +3 -0
  195. package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
  196. package/dist/plus/ai/utils/ai.utils.js +13 -0
  197. package/dist/plus/ai/utils/ai.utils.js.map +1 -1
  198. package/dist/plus/ai/utils/results.utils.d.ts +16 -2
  199. package/dist/plus/ai/utils/results.utils.d.ts.map +1 -1
  200. package/dist/plus/ai/utils/results.utils.js +204 -28
  201. package/dist/plus/ai/utils/results.utils.js.map +1 -1
  202. package/dist/plus/git-github/api/github.d.ts +92 -4
  203. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  204. package/dist/plus/git-github/api/github.js +324 -20
  205. package/dist/plus/git-github/api/github.js.map +1 -1
  206. package/dist/plus/git-github/api/pullRequestSearchQuery.d.ts +27 -1
  207. package/dist/plus/git-github/api/pullRequestSearchQuery.d.ts.map +1 -1
  208. package/dist/plus/git-github/api/pullRequestSearchQuery.js +73 -6
  209. package/dist/plus/git-github/api/pullRequestSearchQuery.js.map +1 -1
  210. package/dist/plus/git-github/models.d.ts +33 -5
  211. package/dist/plus/git-github/models.d.ts.map +1 -1
  212. package/dist/plus/git-github/models.js +43 -4
  213. package/dist/plus/git-github/models.js.map +1 -1
  214. package/dist/plus/git-github/providers/github/status.d.ts +1 -0
  215. package/dist/plus/git-github/providers/github/status.d.ts.map +1 -1
  216. package/dist/plus/git-github/providers/github/status.js.map +1 -1
  217. package/dist/plus/integrations/context.d.ts +4 -0
  218. package/dist/plus/integrations/context.d.ts.map +1 -1
  219. package/dist/plus/integrations/index.d.ts.map +1 -1
  220. package/dist/plus/integrations/index.js +2 -0
  221. package/dist/plus/integrations/index.js.map +1 -1
  222. package/dist/plus/integrations/integrationService.d.ts +16 -1
  223. package/dist/plus/integrations/integrationService.d.ts.map +1 -1
  224. package/dist/plus/integrations/integrationService.js +9 -1
  225. package/dist/plus/integrations/integrationService.js.map +1 -1
  226. package/dist/plus/integrations/manager.d.ts +45 -5
  227. package/dist/plus/integrations/manager.d.ts.map +1 -1
  228. package/dist/plus/integrations/models/gitHostIntegration.d.ts +18 -3
  229. package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -1
  230. package/dist/plus/integrations/models/gitHostIntegration.js +30 -2
  231. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  232. package/dist/plus/integrations/models/integration.d.ts +4 -2
  233. package/dist/plus/integrations/models/integration.d.ts.map +1 -1
  234. package/dist/plus/integrations/models/integration.js +2 -2
  235. package/dist/plus/integrations/models/integration.js.map +1 -1
  236. package/dist/plus/integrations/providerFilters.d.ts +1 -1
  237. package/dist/plus/integrations/providerFilters.d.ts.map +1 -1
  238. package/dist/plus/integrations/providers/accounts.d.ts +6 -0
  239. package/dist/plus/integrations/providers/accounts.d.ts.map +1 -0
  240. package/dist/plus/integrations/providers/accounts.js +34 -0
  241. package/dist/plus/integrations/providers/accounts.js.map +1 -0
  242. package/dist/plus/integrations/providers/azure/models.d.ts.map +1 -1
  243. package/dist/plus/integrations/providers/azure/models.js +3 -0
  244. package/dist/plus/integrations/providers/azure/models.js.map +1 -1
  245. package/dist/plus/integrations/providers/bitbucket/models.d.ts.map +1 -1
  246. package/dist/plus/integrations/providers/bitbucket/models.js +1 -0
  247. package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -1
  248. package/dist/plus/integrations/providers/github.d.ts +23 -2
  249. package/dist/plus/integrations/providers/github.d.ts.map +1 -1
  250. package/dist/plus/integrations/providers/github.js +169 -138
  251. package/dist/plus/integrations/providers/github.js.map +1 -1
  252. package/dist/plus/integrations/providers/gitlab.d.ts +9 -0
  253. package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -1
  254. package/dist/plus/integrations/providers/gitlab.js +23 -4
  255. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  256. package/dist/plus/integrations/providers/models.d.ts +14 -32
  257. package/dist/plus/integrations/providers/models.d.ts.map +1 -1
  258. package/dist/plus/integrations/providers/models.js +66 -109
  259. package/dist/plus/integrations/providers/models.js.map +1 -1
  260. package/dist/plus/integrations/providers/pullRequestReviews.d.ts +50 -0
  261. package/dist/plus/integrations/providers/pullRequestReviews.d.ts.map +1 -0
  262. package/dist/plus/integrations/providers/pullRequestReviews.js +99 -0
  263. package/dist/plus/integrations/providers/pullRequestReviews.js.map +1 -0
  264. package/dist/plus/integrations/reads/broaden.d.ts.map +1 -1
  265. package/dist/plus/integrations/reads/broaden.js +6 -1
  266. package/dist/plus/integrations/reads/broaden.js.map +1 -1
  267. package/dist/plus/integrations/reads/counts.d.ts +55 -0
  268. package/dist/plus/integrations/reads/counts.d.ts.map +1 -1
  269. package/dist/plus/integrations/reads/counts.js +146 -2
  270. package/dist/plus/integrations/reads/counts.js.map +1 -1
  271. package/dist/plus/integrations/reads/drains.d.ts +7 -1
  272. package/dist/plus/integrations/reads/drains.d.ts.map +1 -1
  273. package/dist/plus/integrations/reads/drains.js +20 -6
  274. package/dist/plus/integrations/reads/drains.js.map +1 -1
  275. package/dist/plus/integrations/reads/filters.d.ts.map +1 -1
  276. package/dist/plus/integrations/reads/filters.js +22 -0
  277. package/dist/plus/integrations/reads/filters.js.map +1 -1
  278. package/dist/plus/integrations/reads/hierarchy.d.ts.map +1 -1
  279. package/dist/plus/integrations/reads/hierarchy.js +3 -1
  280. package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
  281. package/dist/plus/integrations/reads/issueTracker.d.ts.map +1 -1
  282. package/dist/plus/integrations/reads/issueTracker.js +8 -3
  283. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  284. package/dist/plus/integrations/reads/issues.d.ts.map +1 -1
  285. package/dist/plus/integrations/reads/issues.js +9 -4
  286. package/dist/plus/integrations/reads/issues.js.map +1 -1
  287. package/dist/plus/integrations/reads/pullRequests.d.ts.map +1 -1
  288. package/dist/plus/integrations/reads/pullRequests.js +9 -4
  289. package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
  290. package/dist/plus/integrations/reads/searchPullRequests.d.ts +4 -3
  291. package/dist/plus/integrations/reads/searchPullRequests.d.ts.map +1 -1
  292. package/dist/plus/integrations/reads/searchPullRequests.js +6 -4
  293. package/dist/plus/integrations/reads/searchPullRequests.js.map +1 -1
  294. package/dist/plus/integrations/reads/sweeps.js +1 -1
  295. package/dist/plus/integrations/reads/sweeps.js.map +1 -1
  296. package/dist/plus/integrations/reads/warnings.d.ts +2 -2
  297. package/dist/plus/integrations/reads/warnings.d.ts.map +1 -1
  298. package/dist/plus/integrations/reads/warnings.js +11 -2
  299. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  300. package/dist/plus/integrations/results.d.ts +6 -1
  301. package/dist/plus/integrations/results.d.ts.map +1 -1
  302. package/dist/plus/integrations/results.js.map +1 -1
  303. package/dist/utils/env/browser/base64.d.ts +1 -1
  304. package/dist/utils/env/browser/base64.d.ts.map +1 -1
  305. package/dist/utils/env/node/base64.d.ts +1 -1
  306. package/dist/utils/env/node/base64.d.ts.map +1 -1
  307. package/dist/utils/env/node/base64.js +2 -0
  308. package/dist/utils/env/node/base64.js.map +1 -1
  309. package/dist/utils/keys/chord.d.ts +52 -0
  310. package/dist/utils/keys/chord.d.ts.map +1 -0
  311. package/dist/utils/keys/chord.js +135 -0
  312. package/dist/utils/keys/chord.js.map +1 -0
  313. package/dist/utils/keys/keybinding.d.ts +53 -0
  314. package/dist/utils/keys/keybinding.d.ts.map +1 -0
  315. package/dist/utils/keys/keybinding.js +58 -0
  316. package/dist/utils/keys/keybinding.js.map +1 -0
  317. package/dist/utils/path.d.ts +11 -0
  318. package/dist/utils/path.d.ts.map +1 -1
  319. package/dist/utils/path.js +13 -0
  320. package/dist/utils/path.js.map +1 -1
  321. package/docs/integrations.md +76 -10
  322. package/docs/kepler-read-api-parity.md +9 -0
  323. package/package.json +13 -5
  324. package/src/git/cache.ts +383 -47
  325. package/src/git/context.ts +11 -0
  326. package/src/git/models/fileStatus.ts +1 -0
  327. package/src/git/models/issue.ts +4 -0
  328. package/src/git/models/mergeConflicts.ts +3 -2
  329. package/src/git/models/pullRequest.ts +117 -1
  330. package/src/git/models/repository.ts +58 -17
  331. package/src/git/models/statusFile.ts +3 -0
  332. package/src/git/providers/branches.ts +6 -0
  333. package/src/git/providers/commits.ts +11 -0
  334. package/src/git/providers/config.ts +18 -0
  335. package/src/git/providers/operations.ts +1 -0
  336. package/src/git/providers/pausedOperations.ts +2 -0
  337. package/src/git/providers/status.ts +1 -0
  338. package/src/git/utils/config.utils.ts +8 -0
  339. package/src/git/utils/issue.utils.ts +2 -0
  340. package/src/git/utils/pausedOperationStatus.utils.ts +28 -0
  341. package/src/git/utils/pullRequest.utils.ts +86 -0
  342. package/src/git/watching/changeEvent.ts +6 -1
  343. package/src/git/watching/classifyChange.ts +15 -1
  344. package/src/git/watching/watchService.ts +20 -3
  345. package/src/git/watching/watchSession.ts +41 -6
  346. package/src/git/watching/watcherPatterns.ts +1 -1
  347. package/src/git-cli/exec/git.ts +13 -3
  348. package/src/git-cli/providers/branches.ts +384 -132
  349. package/src/git-cli/providers/commits.ts +106 -15
  350. package/src/git-cli/providers/config.ts +229 -8
  351. package/src/git-cli/providers/contributors.ts +5 -1
  352. package/src/git-cli/providers/graph.ts +26 -13
  353. package/src/git-cli/providers/operations.ts +45 -20
  354. package/src/git-cli/providers/pausedOperations.ts +109 -17
  355. package/src/git-cli/providers/refs.ts +33 -3
  356. package/src/git-cli/providers/status.ts +25 -4
  357. package/src/git-cli/providers/worktrees.ts +5 -0
  358. package/src/git-cli/service.ts +0 -1
  359. package/src/plus/agents/providers/claudeCodeProvider.ts +1130 -87
  360. package/src/plus/agents/providers/claudeCodeTranscript.ts +95 -9
  361. package/src/plus/agents/types.ts +46 -2
  362. package/src/plus/ai/errors.ts +30 -0
  363. package/src/plus/ai/models/model.ts +56 -6
  364. package/src/plus/ai/models/promptTemplates.ts +1 -1
  365. package/src/plus/ai/models/provider.ts +69 -2
  366. package/src/plus/ai/prompts.ts +186 -61
  367. package/src/plus/ai/providers/anthropicProvider.ts +155 -47
  368. package/src/plus/ai/providers/deepSeekProvider.ts +11 -21
  369. package/src/plus/ai/providers/geminiProvider.ts +19 -0
  370. package/src/plus/ai/providers/gitkrakenProvider.ts +126 -3
  371. package/src/plus/ai/providers/huggingFaceProvider.ts +6 -0
  372. package/src/plus/ai/providers/mistralProvider.ts +102 -19
  373. package/src/plus/ai/providers/ollamaProvider.ts +55 -4
  374. package/src/plus/ai/providers/openAICompatibleProvider.ts +5 -0
  375. package/src/plus/ai/providers/openAICompatibleProviderBase.ts +360 -17
  376. package/src/plus/ai/providers/openRouterProvider.ts +17 -0
  377. package/src/plus/ai/providers/openaiProvider.ts +1 -0
  378. package/src/plus/ai/providers/responseFormatCache.ts +39 -0
  379. package/src/plus/ai/providers/xaiProvider.ts +10 -1
  380. package/src/plus/ai/utils/ai.utils.ts +14 -0
  381. package/src/plus/ai/utils/results.utils.ts +255 -31
  382. package/src/plus/git-github/api/github.ts +467 -23
  383. package/src/plus/git-github/api/pullRequestSearchQuery.ts +81 -7
  384. package/src/plus/git-github/models.ts +77 -7
  385. package/src/plus/git-github/providers/github/status.ts +1 -0
  386. package/src/plus/integrations/context.ts +4 -0
  387. package/src/plus/integrations/index.ts +2 -0
  388. package/src/plus/integrations/integrationService.ts +25 -2
  389. package/src/plus/integrations/manager.ts +50 -5
  390. package/src/plus/integrations/models/gitHostIntegration.ts +54 -2
  391. package/src/plus/integrations/models/integration.ts +24 -13
  392. package/src/plus/integrations/providerFilters.ts +6 -1
  393. package/src/plus/integrations/providers/accounts.ts +38 -0
  394. package/src/plus/integrations/providers/azure/models.ts +3 -0
  395. package/src/plus/integrations/providers/bitbucket/models.ts +1 -0
  396. package/src/plus/integrations/providers/github.ts +218 -145
  397. package/src/plus/integrations/providers/gitlab.ts +30 -20
  398. package/src/plus/integrations/providers/models.ts +99 -127
  399. package/src/plus/integrations/providers/pullRequestReviews.ts +122 -0
  400. package/src/plus/integrations/reads/broaden.ts +6 -1
  401. package/src/plus/integrations/reads/counts.ts +273 -2
  402. package/src/plus/integrations/reads/drains.ts +19 -6
  403. package/src/plus/integrations/reads/filters.ts +22 -0
  404. package/src/plus/integrations/reads/hierarchy.ts +3 -1
  405. package/src/plus/integrations/reads/issueTracker.ts +9 -3
  406. package/src/plus/integrations/reads/issues.ts +9 -4
  407. package/src/plus/integrations/reads/pullRequests.ts +9 -4
  408. package/src/plus/integrations/reads/searchPullRequests.ts +12 -4
  409. package/src/plus/integrations/reads/sweeps.ts +1 -1
  410. package/src/plus/integrations/reads/warnings.ts +12 -1
  411. package/src/plus/integrations/results.ts +6 -1
  412. package/src/utils/env/browser/base64.ts +1 -1
  413. package/src/utils/env/node/base64.ts +3 -1
  414. package/src/utils/keys/chord.ts +184 -0
  415. package/src/utils/keys/keybinding.ts +116 -0
  416. package/src/utils/path.ts +14 -0
@@ -11,7 +11,6 @@ export type { PullRequestState };
11
11
 
12
12
  export interface PullRequestShape extends IssueOrPullRequest {
13
13
  readonly author: PullRequestMember;
14
- readonly body?: string;
15
14
  /**
16
15
  * Canonical base-repository identity returned by the provider. Some providers
17
16
  * scope pull-request ids to a repository, so consumers must not have to infer
@@ -23,11 +22,23 @@ export interface PullRequestShape extends IssueOrPullRequest {
23
22
  readonly isDraft?: boolean;
24
23
  readonly additions?: number;
25
24
  readonly deletions?: number;
25
+ readonly filesChanged?: number;
26
+ readonly body?: string;
26
27
  readonly mergeableState?: PullRequestMergeableState;
27
28
  readonly reviewDecision?: PullRequestReviewDecision;
28
29
  readonly reviewRequests?: PullRequestReviewer[];
30
+ /**
31
+ * Reviews already submitted, as opposed to the still-pending {@link reviewRequests}. Absent means the read
32
+ * didn't fetch reviews; empty means nobody has reviewed. Those are different answers and neither substitutes
33
+ * for the other, so which one you get is provider- and read-dependent: GitHub/GHE carry reviews on the
34
+ * repo-scoped read and the filtered search, and on the account-wide read only where `includeReviews` opts
35
+ * into the full projection, while GitLab never populates the field at all.
36
+ * {@link PullRequestReviewer.commitOid} is the narrower promise: only the full GitHub/GHE projection has it.
37
+ */
38
+ readonly latestReviews?: PullRequestReviewer[];
29
39
  readonly assignees?: PullRequestMember[];
30
40
  readonly project?: IssueProject;
41
+ readonly stack?: PullRequestStackInfo;
31
42
  readonly number?: number;
32
43
  readonly authoredByMe?: boolean;
33
44
  }
@@ -65,6 +76,12 @@ export class PullRequest implements PullRequestShape {
65
76
  public readonly statusCheckRollupState?: PullRequestStatusCheckRollupState,
66
77
  public readonly project?: IssueProject,
67
78
  public readonly version?: number,
79
+ /** Commits on the head that aren't on the base. Appended rather than slotted with the other counts:
80
+ * this constructor is positional and every mapper passes through it. */
81
+ public readonly commitCount?: number,
82
+ public readonly stack?: PullRequestStackInfo,
83
+ public readonly filesChanged?: number,
84
+ /** The pull request's description, as markdown. */
68
85
  public readonly body?: string,
69
86
  public readonly number?: number,
70
87
  public readonly authoredByMe?: boolean,
@@ -145,6 +162,10 @@ export interface PullRequestMember {
145
162
  * presentation.
146
163
  */
147
164
  name?: string;
165
+ /** The provider's handle for this person, when it has one — GitHub's login, Azure's `uniqueName` (a UPN,
166
+ * so an email), Bitbucket's mutable `nickname`. Display/labelling only: it is neither guaranteed present
167
+ * (GitLab's native mapper has none) nor a stable identity, so never key a match off it. */
168
+ username?: string;
148
169
  avatarUrl?: string;
149
170
  url?: string;
150
171
  }
@@ -154,12 +175,50 @@ export enum PullRequestFilter {
154
175
  Author = 'author',
155
176
  Assignee = 'assignee',
156
177
  ReviewRequested = 'review-requested',
178
+ /**
179
+ * PRs the user has already reviewed (GitHub `reviewed-by:@me`), as opposed to `ReviewRequested` (a
180
+ * still-pending request). Distinguishes "waiting on the author after my review" from "waiting for my
181
+ * review". Not expressible on the repo-scoped listing — no provider SDK exposes a reviewed-by axis there —
182
+ * so it is advertised for the account-wide read and for the filtered search (which can still bound itself
183
+ * to repositories or an org), never under `supportedPullRequestFilters`.
184
+ */
185
+ Reviewed = 'reviewed-by',
157
186
  Mention = 'mention',
158
187
  }
159
188
 
160
189
  /** Selects which pull request states a read should include. `all` covers open + closed + merged. */
161
190
  export type PullRequestStateFilter = 'open' | 'closed' | 'merged' | 'all';
162
191
 
192
+ /**
193
+ * A field a pull-request read can be ordered by, provider-neutral.
194
+ *
195
+ * Only two, and deliberately so — unlike {@link IssueSortField} this is the INTERSECTION of what GitHub's PR
196
+ * search can order by server-side and what a {@link PullRequestShape} carries, because the filtered PR search
197
+ * always merges its relationship × state facets in the facade and so must re-order the union itself (see
198
+ * `getPullRequestComparator`). `created` and `updated` are both. A field GitHub cannot order PRs by, or one a
199
+ * merged page can't reproduce, is left out rather than advertised and then approximated: relevance is unstable
200
+ * and has no comparable value on a merge, and priority is not a pull-request concept on any provider that has PRs.
201
+ */
202
+ export type PullRequestSortField =
203
+ /** Creation date. */
204
+ | 'created'
205
+ /** Last activity. */
206
+ | 'updated';
207
+
208
+ /**
209
+ * How a pull-request read is ordered, as `field:direction` — the same serializable shape {@link IssueSorting}
210
+ * and `BranchSorting` use, so a consumer can persist it, compare it, or bind it straight to a setting or dropdown.
211
+ */
212
+ export type PullRequestSorting = `${PullRequestSortField}:asc` | `${PullRequestSortField}:desc`;
213
+
214
+ /**
215
+ * The order the filtered pull-request search applies when the caller asks for none: most recently updated first,
216
+ * which is what it served before ordering was an option. Named once rather than per layer — the criteria model
217
+ * documents it, the GitHub query emits it, and the result-ceiling warning quotes it — so the three cannot
218
+ * disagree about what "the default" is.
219
+ */
220
+ export const defaultPullRequestSort: PullRequestSorting = 'updated:desc';
221
+
163
222
  /**
164
223
  * What the filtered pull-request search narrows on.
165
224
  *
@@ -181,8 +240,27 @@ export interface PullRequestSearchCriteria {
181
240
  relationships?: PullRequestFilter[];
182
241
  /** Pull request states to union. Empty/omitted reads open PRs; `all` subsumes every other member. */
183
242
  states?: PullRequestStateFilter[];
243
+ /** ISO date (`YYYY-MM-DD`). The most effective narrowing criterion by far on a large scope. */
244
+ updatedAfter?: string;
245
+ /** ISO date (`YYYY-MM-DD`). */
246
+ createdAfter?: string;
184
247
  /** Includes PRs from archived repositories. They are excluded by default. */
185
248
  includeArchived?: boolean;
249
+ /**
250
+ * Narrows on draft state: `true` returns only drafts, `false` only ready-for-review PRs. Omitted places no
251
+ * constraint. A boolean rather than a truthy flag because `false` is a distinct request, not the absence of one.
252
+ */
253
+ draft?: boolean;
254
+ /**
255
+ * How to order the results. Omitted means `updated:desc`, which is what this search has always served.
256
+ *
257
+ * Validated all-or-nothing against {@link PullRequestSearchCapabilities.sorts} like every other criterion: a
258
+ * key the provider can't express server-side refuses the WHOLE read rather than falling back to the default,
259
+ * because combined with the provider's result ceiling another order returns a different subset than was asked
260
+ * for and the paging that comes with it describes that other subset. Do not change it mid-pagination — a
261
+ * cursor carries the sort it was produced under; drop the cursor instead of threading it under a new key.
262
+ */
263
+ sort?: PullRequestSorting;
186
264
  }
187
265
 
188
266
  /**
@@ -195,11 +273,21 @@ export interface PullRequestSearchCapabilities {
195
273
  /** Individual state values the provider can union in one logical search. */
196
274
  states: PullRequestStateFilter[];
197
275
  text: boolean;
276
+ updatedAfter: boolean;
277
+ createdAfter: boolean;
198
278
  includeArchived: boolean;
279
+ /** Whether the provider can constrain the search by draft state server-side. */
280
+ draft: boolean;
199
281
  /** Whether the manager's repository-descriptor scope is supported. */
200
282
  repositoryScope: boolean;
201
283
  /** Whether the manager's organization scope is supported. */
202
284
  organizationScope: boolean;
285
+ /**
286
+ * Sort keys the search can express server-side. Always contains at least `updated:desc` — the historical
287
+ * default — when the search exists at all, so it is never empty for a usable surface; a provider without a
288
+ * filtered PR search reports an empty `relationships`, which is already the signal there is no surface to order.
289
+ */
290
+ sorts: PullRequestSorting[];
203
291
  }
204
292
 
205
293
  export interface PullRequestRef {
@@ -223,10 +311,38 @@ export interface PullRequestRefs {
223
311
  isCrossRepository: boolean;
224
312
  }
225
313
 
314
+ /**
315
+ * A pull request's membership in a stack — an ordered chain of dependent pull requests where each
316
+ * targets the branch of the one below it.
317
+ *
318
+ * `baseRef` is the stack's ultimate target (its trunk) and is NOT the same as `refs.base`, which for
319
+ * anything above the bottom layer names the layer below. Use `refs.base` to diff a single layer; use
320
+ * `baseRef` to answer where the work ultimately lands.
321
+ */
322
+ export interface PullRequestStackInfo {
323
+ id: string;
324
+ /** Identifies the stack within its repository. */
325
+ number: number;
326
+ /** Total pull requests in the stack. */
327
+ size: number;
328
+ /** This pull request's layer, 1-based, where 1 is closest to `baseRef`. */
329
+ position: number;
330
+ /** The branch the bottom of the stack targets. */
331
+ baseRef: string;
332
+ }
333
+
226
334
  export interface PullRequestReviewer {
227
335
  isCodeOwner?: boolean;
228
336
  reviewer: PullRequestMember;
229
337
  state: PullRequestReviewState;
338
+ /**
339
+ * The head commit oid this review was submitted against (GitHub). Lets a consumer tell "the PR moved past
340
+ * my review" (oid !== the PR's current head) from a review still at the tip — without a per-review
341
+ * timestamp. Only populated where the full GitHub/GHE projection is selected: the filtered search read, and
342
+ * an account-wide sweep that opts in with `includeReviews`. Undefined elsewhere, including reviews the
343
+ * repo-scoped read carries natively.
344
+ */
345
+ commitOid?: string;
230
346
  }
231
347
 
232
348
  export type PullRequestRepositoryIdentityDescriptor = RequireSomeWithProps<
@@ -7,12 +7,12 @@ import type { UnifiedDisposable } from '../../utils/disposable.js';
7
7
  import { createDisposable } from '../../utils/disposable.js';
8
8
  import type { Event } from '../../utils/event.js';
9
9
  import { Emitter } from '../../utils/event.js';
10
- import { basename, normalizePath } from '../../utils/path.js';
10
+ import { some } from '../../utils/iterable.js';
11
+ import { basename, isDescendant, normalizePath } from '../../utils/path.js';
11
12
  import type { Uri } from '../../utils/uri.js';
12
- import { fileUri } from '../../utils/uri.js';
13
13
  import type { GitProviderDescriptor } from '../providers/types.js';
14
14
  import { getCommonRepositoryUri } from '../utils/repository.utils.js';
15
- import type { WatcherRepoChangeEvent } from '../watching/changeEvent.js';
15
+ import type { WatcherRepoChangeEvent, WorkingTreeChangeEvent } from '../watching/changeEvent.js';
16
16
  import type { RepositoryWatchService, WatchHandle, WatchHooks } from '../watching/watchService.js';
17
17
  import type { RepositorySubscription } from '../watching/watchSession.js';
18
18
  import { RepositoryChangeEvent } from './repositoryChangeEvent.js';
@@ -107,10 +107,44 @@ export interface RepositoryInit {
107
107
  readonly watchService: RepositoryWatchService;
108
108
  }
109
109
 
110
- export interface RepositoryWorkingTreeChangeEvent {
111
- readonly repository: Repository;
112
- /** URIs of changed files */
113
- readonly uris: ReadonlySet<Uri>;
110
+ /**
111
+ * An event describing working tree file changes.
112
+ *
113
+ * Deliberately exposes no path collection. Consumers react by refreshing, and a refresh re-reads current
114
+ * state — so the paths only ever gate whether to bother, never what the answer is. A partial set would
115
+ * read as usable while quietly licensing the one harmful outcome (concluding a file did NOT change), so
116
+ * {@link changed} is the only way to ask.
117
+ */
118
+ export class RepositoryWorkingTreeChangeEvent {
119
+ constructor(
120
+ readonly repository: Repository,
121
+ /** Absolute paths changed in this batch; partial when {@link incomplete}. */
122
+ private readonly paths: ReadonlySet<string>,
123
+ /** Whether paths were dropped, so {@link paths} can't be used to rule anything out. */
124
+ private readonly incomplete: boolean,
125
+ ) {}
126
+
127
+ /**
128
+ * Whether `uri` — or anything beneath it, when it's a folder — changed in this batch.
129
+ *
130
+ * Conservative: `true` whenever the batch is incomplete, since a miss would then prove nothing. Matches
131
+ * on paths rather than URIs so nothing has to be allocated to answer.
132
+ */
133
+ changed(uri: Uri): boolean {
134
+ if (this.incomplete) return true;
135
+
136
+ const path = uri.fsPath;
137
+ return some(this.paths, p => p === path || isDescendant(p, path));
138
+ }
139
+
140
+ toString(): string {
141
+ if (this.incomplete) return `{ repository: ${this.repository.name ?? ''}, paths: incomplete }`;
142
+
143
+ const [first] = this.paths;
144
+ return `{ repository: ${this.repository.name ?? ''}, paths(${this.paths.size}): [${first ?? ''}${
145
+ this.paths.size > 1 ? ', ...' : ''
146
+ }] }`;
147
+ }
114
148
  }
115
149
 
116
150
  export class Repository {
@@ -140,7 +174,8 @@ export class Repository {
140
174
  protected _watchHandle: WatchHandle | undefined;
141
175
  protected readonly _watchService: RepositoryWatchService;
142
176
 
143
- private _pendingWorkingTreeChange?: RepositoryWorkingTreeChangeEvent;
177
+ private _pendingWorkingTreePaths?: Set<string>;
178
+ private _pendingWorkingTreeIncomplete = false;
144
179
  private _pendingWorkingTreeFlush = false;
145
180
  private _repoChangeListener: UnifiedDisposable | undefined;
146
181
  /** Outstanding leases on the shared {@link _watchHandle} across `watch()` + `watchWorkingTree()`. */
@@ -318,7 +353,7 @@ export class Repository {
318
353
  if (acquired == null) return createDisposable(() => {});
319
354
 
320
355
  const sub = acquired.handle.session.subscribeToWorkingTree({ delayMs: delay });
321
- const listener = sub.onDidChangeWorkingTree(e => this.onWorkingTreeChanged(e.paths));
356
+ const listener = sub.onDidChangeWorkingTree(e => this.onWorkingTreeChanged(e));
322
357
 
323
358
  return createDisposable(
324
359
  () => {
@@ -409,24 +444,30 @@ export class Repository {
409
444
  * `_onDidChangeWorkingTree` emission. Without this coalescing, every WIP-dependent listener
410
445
  * (graph, file history, compare branch, etc.) would fire N times for N active subscriptions.
411
446
  */
412
- protected onWorkingTreeChanged(paths: ReadonlySet<string>): void {
447
+ /** Takes the session event whole rather than spreading it across parameters — a subclass override that
448
+ * dropped a trailing positional argument silently defeated this pipeline once already. */
449
+ protected onWorkingTreeChanged(e: WorkingTreeChangeEvent): void {
413
450
  this._updatedAt = Date.now();
414
451
 
415
- this._pendingWorkingTreeChange ??= { repository: this, uris: new Set<Uri>() };
416
- for (const p of paths) {
417
- (this._pendingWorkingTreeChange.uris as Set<Uri>).add(fileUri(p));
452
+ this._pendingWorkingTreePaths ??= new Set<string>();
453
+ for (const p of e.paths) {
454
+ this._pendingWorkingTreePaths.add(p);
418
455
  }
456
+ this._pendingWorkingTreeIncomplete ||= e.incomplete;
419
457
 
420
458
  if (this._pendingWorkingTreeFlush) return;
421
459
 
422
460
  this._pendingWorkingTreeFlush = true;
423
461
  queueMicrotask(() => {
424
462
  this._pendingWorkingTreeFlush = false;
425
- const e = this._pendingWorkingTreeChange;
426
- if (e == null) return;
463
+ const paths = this._pendingWorkingTreePaths;
464
+ if (paths == null) return;
465
+
466
+ const incomplete = this._pendingWorkingTreeIncomplete;
467
+ this._pendingWorkingTreePaths = undefined;
468
+ this._pendingWorkingTreeIncomplete = false;
427
469
 
428
- this._pendingWorkingTreeChange = undefined;
429
- this._onDidChangeWorkingTree.fire(e);
470
+ this._onDidChangeWorkingTree.fire(new RepositoryWorkingTreeChangeEvent(this, paths, incomplete));
430
471
  });
431
472
  }
432
473
 
@@ -86,6 +86,9 @@ export class GitStatusFile implements GitFile {
86
86
  case 'M':
87
87
  this.workingTreeStatus = GitFileWorkingTreeStatus.Modified;
88
88
  break;
89
+ case 'T':
90
+ this.workingTreeStatus = GitFileWorkingTreeStatus.TypeChanged;
91
+ break;
89
92
  }
90
93
  }
91
94
  }
@@ -102,6 +102,12 @@ export interface GitBranchesSubProvider {
102
102
  targetBranch: string,
103
103
  cancellation?: AbortSignal,
104
104
  ): Promise<ConflictDetectionResult>;
105
+ /** Detects conflicts when an autostash is reapplied onto the tree an integration produced */
106
+ getPotentialStashReapplyConflicts?(
107
+ repoPath: string,
108
+ ontoTreeOid: string,
109
+ cancellation?: AbortSignal,
110
+ ): Promise<ConflictDetectionResult>;
105
111
  getBaseBranchName?(
106
112
  repoPath: string,
107
113
  ref: string,
@@ -8,6 +8,7 @@ import type { GitRevisionRange } from '../models/revision.js';
8
8
  import type { SearchQuery } from '../models/search.js';
9
9
  import type { CommitSignature, SshSignedCommit } from '../models/signature.js';
10
10
  import type { GitUser } from '../models/user.js';
11
+ import type { GitCommandPriority } from '../run.types.js';
11
12
  import type { DiffRange } from './types.js';
12
13
 
13
14
  export interface LeftRightCommitCountResult {
@@ -82,6 +83,16 @@ export interface GitCommitsSubProvider {
82
83
  * Cheap early-exit probe (`rev-list --not --remotes <rev> -n 1`) — it does NOT count them. Returns
83
84
  * `undefined` when it can't be determined. */
84
85
  hasUnpublishedCommits?(repoPath: string, rev: string, cancellation?: AbortSignal): Promise<boolean | undefined>;
86
+ /** Batched form of {@link hasUnpublishedCommits}: returns the subset of `shas` with commits not reachable
87
+ * from any remote-tracking ref, in ONE walk rather than a spawn per sha. Pass tips from any worktrees of
88
+ * the same repo — the object store and `refs/remotes` are shared, so a single `repoPath` covers them all.
89
+ * Callers should skip this when the repo has no remotes (every local commit would qualify). */
90
+ filterUnpublishedShas?(
91
+ repoPath: string,
92
+ shas: readonly string[],
93
+ options?: { priority?: GitCommandPriority },
94
+ cancellation?: AbortSignal,
95
+ ): Promise<Set<string>>;
85
96
  /** Cheap author/committer date lookup for a single revision. Skips the full commit parse (no files, parents, or message) — use when only the dates are needed. Pass a full SHA so caching stays correct (commits are immutable; refs are not). */
86
97
  getCommitDates?(
87
98
  repoPath: string,
@@ -13,8 +13,16 @@ export type GitCoreConfigKeys =
13
13
  | 'gpg.ssh.program'
14
14
  | 'gpg.ssh.allowedSignersFile'
15
15
  | 'init.defaultBranch'
16
+ /** `merge.autoStash` — whether `git merge` (and so a merging `git pull`) stashes and reapplies uncommitted changes */
17
+ | 'merge.autoStash'
18
+ /** `pull.autoStash` — overrides `merge.autoStash`/`rebase.autoStash` for `git pull`, in either mode */
19
+ | 'pull.autoStash'
16
20
  /** `pull.rebase` — whether `git pull` rebases instead of merging; also accepts `merges`/`interactive` */
17
21
  | 'pull.rebase'
22
+ /** `rebase.autoStash` — whether `git rebase` (and so a rebasing `git pull`) stashes and reapplies uncommitted changes */
23
+ | 'rebase.autoStash'
24
+ /** `rebase.updateRefs` — whether `git rebase` also updates branches pointing to the rebased commits */
25
+ | 'rebase.updateRefs'
18
26
  | 'user.email'
19
27
  | 'user.name'
20
28
  | 'user.signingkey';
@@ -100,6 +108,16 @@ export interface GitConfigSubProvider {
100
108
  value: string | undefined,
101
109
  options?: { skipInvalidation?: readonly GkConfigInvalidationTarget[] },
102
110
  ): Promise<void>;
111
+ /**
112
+ * Drops every gk key stored for `ref` — call when a branch stops existing under that name. Deliberately
113
+ * includes user-owned values (`gk-merge-target-user`, `gk-disposition`, `gk-associated-issues`): the
114
+ * branch is confirmed gone, and leaving them would hand the next branch reusing that name a dead one's
115
+ * starred state and issue links. Only call where git guarantees the name is free —
116
+ * a completed delete.
117
+ */
118
+ removeGkConfigBranchSection?(repoPath: string, ref: string): Promise<void>;
119
+ /** Moves every gk key stored for `oldRef` to `newRef` — call when a branch is renamed. */
120
+ renameGkConfigBranchSection?(repoPath: string, oldRef: string, newRef: string): Promise<void>;
103
121
 
104
122
  getSigningConfig?(repoPath: string): Promise<SigningConfig>;
105
123
  getSigningConfigFlags?(config: SigningConfig): string[];
@@ -112,6 +112,7 @@ export interface GitOperationsSubProvider {
112
112
  */
113
113
  messageEditor?: string;
114
114
  onto?: string;
115
+ /** `true` → `--update-refs`, `false` → `--no-update-refs`, omitted → git config (`rebase.updateRefs`) decides. */
115
116
  updateRefs?: boolean;
116
117
  source?: unknown;
117
118
  },
@@ -10,6 +10,8 @@ export interface GitPausedOperationsSubProvider {
10
10
  continuePausedOperation(
11
11
  repoPath: string,
12
12
  options?: {
13
+ /** Records the empty commit the operation refused to create, then concludes it (cherry-pick/revert) */
14
+ allowEmpty?: boolean;
13
15
  skip?: boolean;
14
16
  /** Editor command used if the operation needs to edit a commit message (e.g. `true` to keep the original message without opening an editor) */
15
17
  messageEditor?: string;
@@ -37,6 +37,7 @@ export interface GitStatusSubProvider {
37
37
  unstaged?: boolean;
38
38
  untracked?: boolean;
39
39
  throwOnError?: boolean;
40
+ priority?: GitCommandPriority;
40
41
  },
41
42
  cancellation?: AbortSignal,
42
43
  ): Promise<boolean>;
@@ -0,0 +1,8 @@
1
+ const falseValues = new Set(['', 'false', 'no', 'off', '0']);
2
+
3
+ /** Interprets a git config value with git's boolean semantics; `undefined` in → `undefined` out (unset). */
4
+ export function parseGitBoolean(value: string | null | undefined): boolean | undefined {
5
+ if (value == null) return undefined;
6
+
7
+ return !falseValues.has(value.trim().toLowerCase());
8
+ }
@@ -134,6 +134,7 @@ export function serializeIssue(value: IssueShape): IssueShape {
134
134
  : {
135
135
  id: value.author.id,
136
136
  name: value.author.name,
137
+ username: value.author.username,
137
138
  avatarUrl: value.author.avatarUrl,
138
139
  url: value.author.url,
139
140
  },
@@ -157,6 +158,7 @@ export function serializeIssue(value: IssueShape): IssueShape {
157
158
  assignees: value.assignees.map(assignee => ({
158
159
  id: assignee.id,
159
160
  name: assignee.name,
161
+ username: assignee.username,
160
162
  avatarUrl: assignee.avatarUrl,
161
163
  url: assignee.url,
162
164
  })),
@@ -23,30 +23,58 @@ export function getConflictCurrentRef(status: GitPausedOperationStatus): GitRefe
23
23
  return status.current;
24
24
  }
25
25
 
26
+ /** `name` is the Title Case form for buttons/actions; `prose` is the sentence form ("Cherry-pick paused"). */
26
27
  export const pausedOperationStatusStringsByType = {
27
28
  'cherry-pick': {
29
+ name: 'Cherry Pick',
30
+ prose: 'Cherry-pick',
28
31
  label: 'Cherry picking',
29
32
  conflicts: 'Resolve conflicts to continue cherry picking',
30
33
  directionality: 'into',
31
34
  },
32
35
  merge: {
36
+ name: 'Merge',
37
+ prose: 'Merge',
33
38
  label: 'Merging',
34
39
  conflicts: 'Resolve conflicts to continue merging',
35
40
  directionality: 'into',
36
41
  },
37
42
  rebase: {
43
+ name: 'Rebase',
44
+ prose: 'Rebase',
38
45
  label: 'Rebasing',
39
46
  conflicts: 'Resolve conflicts to continue rebasing',
40
47
  directionality: 'onto',
41
48
  pending: 'Pending rebase of',
42
49
  },
43
50
  revert: {
51
+ name: 'Revert',
52
+ prose: 'Revert',
44
53
  label: 'Reverting',
45
54
  conflicts: 'Resolve conflicts to continue reverting',
46
55
  directionality: 'in',
47
56
  },
48
57
  } as const;
49
58
 
59
+ export type PausedOperationVariant = 'conflicts' | 'pending' | 'ready';
60
+
61
+ /** Codicon per variant — shared so the bar and the WIP badge can't drift. */
62
+ export const pausedOperationVariantIcons: Record<PausedOperationVariant, string> = {
63
+ conflicts: 'warning',
64
+ pending: 'circle-outline',
65
+ ready: 'check',
66
+ };
67
+
68
+ /** Unresolved conflicts outrank a rebase that hasn't reached its first step — neither can continue, but only conflicts are actionable. */
69
+ export function getPausedOperationVariant(
70
+ status: GitPausedOperationStatus,
71
+ hasConflicts: boolean,
72
+ ): PausedOperationVariant {
73
+ if (hasConflicts) return 'conflicts';
74
+ if (status.type === 'rebase' && status.steps.total === 0) return 'pending';
75
+ return 'ready';
76
+ }
77
+
50
78
  /**
51
79
  * Resolves the correct file paths for each side of a merge conflict diff when the file may have been renamed.
52
80
  *
@@ -4,9 +4,72 @@ import type {
4
4
  PullRequestRefs,
5
5
  PullRequestRepositoryIdentityDescriptor,
6
6
  PullRequestShape,
7
+ PullRequestSortField,
8
+ PullRequestSorting,
9
+ PullRequestStackInfo,
7
10
  } from '../models/pullRequest.js';
8
11
  import { shortenRevision } from './revision.utils.js';
9
12
 
13
+ /** How many pull requests a merge action affects — unstacked is always 1; a stacked merge lands either
14
+ * just this layer and everything below it (`position`), or the whole stack (`wholeStack`). The one
15
+ * source every merge-confirmation and merge-action label counts from, so they can't drift apart.
16
+ * Takes only the two fields it needs (not the full {@link PullRequestStackInfo}) since callers on the
17
+ * webview side carry narrower serialized stack shapes. */
18
+ export function getStackedMergeCount(
19
+ stack: Pick<PullRequestStackInfo, 'position' | 'size'> | undefined,
20
+ options?: { wholeStack?: boolean },
21
+ ): number {
22
+ if (stack == null) return 1;
23
+ return options?.wholeStack ? stack.size : stack.position;
24
+ }
25
+
26
+ /**
27
+ * How each sort field is read off a {@link PullRequestShape}, for the filtered PR search, which MERGES its
28
+ * relationship × state facets in the facade and so has to order the union itself instead of trusting the
29
+ * per-facet server order. Only the fields the shape carries appear — the same rule as `getIssueComparator`, and
30
+ * the reason {@link PullRequestSortField} is just these two.
31
+ */
32
+ const pullRequestSortValues: Partial<
33
+ Record<PullRequestSortField, (pr: PullRequestShape) => number | Date | string | undefined>
34
+ > = {
35
+ created: pr => pr.createdDate,
36
+ updated: pr => pr.updatedDate,
37
+ };
38
+
39
+ /**
40
+ * A comparator for one sort key over normalized pull requests, or `undefined` when the field isn't derivable
41
+ * from a {@link PullRequestShape} — the signal that the key is only honorable on a SINGLE-origin read where the
42
+ * provider already ordered the page. Missing values sort LAST in both directions (partitioned before any
43
+ * arithmetic so two missing values compare equal, exactly as `getIssueComparator` does).
44
+ *
45
+ * Note it orders whatever it is handed. Sorting a page already capped at the result ceiling does not make it the
46
+ * top N.
47
+ */
48
+ export function getPullRequestComparator(
49
+ sort: PullRequestSorting,
50
+ ): ((a: PullRequestShape, b: PullRequestShape) => number) | undefined {
51
+ const [field, direction] = sort.split(':') as [PullRequestSortField, 'asc' | 'desc'];
52
+ const getValue = pullRequestSortValues[field];
53
+ if (getValue == null) return undefined;
54
+
55
+ return (a, b) => {
56
+ const left = toComparable(getValue(a));
57
+ const right = toComparable(getValue(b));
58
+ if (left == null || right == null) {
59
+ if (left == null && right == null) return 0;
60
+
61
+ return left == null ? 1 : -1;
62
+ }
63
+
64
+ const ordered = left < right ? -1 : left > right ? 1 : 0;
65
+ return direction === 'asc' ? ordered : -ordered;
66
+ };
67
+ }
68
+
69
+ function toComparable(value: number | Date | string | undefined): number | string | undefined {
70
+ return value instanceof Date ? value.getTime() : value;
71
+ }
72
+
10
73
  export interface PullRequestUrlIdentity<TProvider extends string = string> {
11
74
  provider?: TProvider;
12
75
 
@@ -41,6 +104,18 @@ export function getPullRequestIdentityFromMaybeUrl(search: string): PullRequestU
41
104
  return prNumber == null ? undefined : { ownerAndRepo: undefined, prNumber: prNumber, provider: undefined };
42
105
  }
43
106
 
107
+ /** A pull request's display number from its url, or `undefined` for a url naming no pull request. Anchors
108
+ * on the provider's pull request path segment (GitHub `pull`, Bitbucket `pull-requests`, GitLab
109
+ * `merge_requests`, Azure `pullrequest`) so a digit-leading owner (`github.com/1Password/x/pull/123`)
110
+ * can't win. */
111
+ export function getPullRequestNumberFromUrl(url: string): string | undefined {
112
+ // No loose fallback: `getPullRequestIdentityFromMaybeUrl` scans for any `/<digits>`, which reads a bare
113
+ // repository url like `github.com/1Password/sdk` as pull request #1. Callers that hold a real pull
114
+ // request fall back to its id instead, and the one that asks whether a pasted url names a pull request
115
+ // needs "no" for an answer.
116
+ return url.match(/(?:pull|pull-requests|merge_requests|pullrequest)\/(\d+)(?:\b|\/|$)/)?.[1];
117
+ }
118
+
44
119
  export function getRepositoryIdentityForPullRequest(
45
120
  pr: PullRequest,
46
121
  headRepo: boolean = true,
@@ -103,6 +178,7 @@ export function serializePullRequest(value: PullRequest): PullRequestShape {
103
178
  author: {
104
179
  id: value.author.id,
105
180
  name: value.author.name,
181
+ username: value.author.username,
106
182
  avatarUrl: value.author.avatarUrl,
107
183
  url: value.author.url,
108
184
  },
@@ -143,6 +219,7 @@ export function serializePullRequest(value: PullRequest): PullRequestShape {
143
219
  thumbsUpCount: value.thumbsUpCount,
144
220
  reviewDecision: value.reviewDecision,
145
221
  reviewRequests: value.reviewRequests,
222
+ latestReviews: value.latestReviews,
146
223
  assignees: value.assignees,
147
224
  authoredByMe: value.authoredByMe,
148
225
  project: value.project
@@ -153,6 +230,15 @@ export function serializePullRequest(value: PullRequest): PullRequestShape {
153
230
  resourceName: value.project.resourceName,
154
231
  }
155
232
  : undefined,
233
+ stack: value.stack
234
+ ? {
235
+ id: value.stack.id,
236
+ number: value.stack.number,
237
+ size: value.stack.size,
238
+ position: value.stack.position,
239
+ baseRef: value.stack.baseRef,
240
+ }
241
+ : undefined,
156
242
  };
157
243
  return serialized;
158
244
  }
@@ -85,6 +85,11 @@ export class WatcherRepoChangeEvent {
85
85
  */
86
86
  export interface WorkingTreeChangeEvent {
87
87
  readonly repoPath: string;
88
- /** Absolute paths of changed files (post-gitignore filtering) */
88
+ /** Absolute paths of changed files (post-gitignore filtering). Partial when {@link incomplete}. */
89
89
  readonly paths: ReadonlySet<string>;
90
+ /**
91
+ * `true` when more paths changed than the accumulator retains, so {@link paths} is a partial set and a
92
+ * miss does NOT mean the file is unchanged. Consumers testing membership must treat this as a match.
93
+ */
94
+ readonly incomplete: boolean;
90
95
  }