@gitkraken/core-gitlens 0.5.110 → 0.5.112

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 (362) hide show
  1. package/CHANGELOG.md +19 -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 +38 -2
  18. package/dist/git/models/pullRequest.d.ts.map +1 -1
  19. package/dist/git/models/pullRequest.js +12 -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 +14 -1
  52. package/dist/git/utils/pullRequest.utils.d.ts.map +1 -1
  53. package/dist/git/utils/pullRequest.utils.js +31 -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 +55 -0
  203. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  204. package/dist/plus/git-github/api/github.js +177 -4
  205. package/dist/plus/git-github/api/github.js.map +1 -1
  206. package/dist/plus/git-github/models.d.ts +16 -0
  207. package/dist/plus/git-github/models.d.ts.map +1 -1
  208. package/dist/plus/git-github/models.js +29 -3
  209. package/dist/plus/git-github/models.js.map +1 -1
  210. package/dist/plus/git-github/providers/github/status.d.ts +1 -0
  211. package/dist/plus/git-github/providers/github/status.d.ts.map +1 -1
  212. package/dist/plus/git-github/providers/github/status.js.map +1 -1
  213. package/dist/plus/integrations/context.d.ts +4 -0
  214. package/dist/plus/integrations/context.d.ts.map +1 -1
  215. package/dist/plus/integrations/index.d.ts.map +1 -1
  216. package/dist/plus/integrations/index.js +2 -0
  217. package/dist/plus/integrations/index.js.map +1 -1
  218. package/dist/plus/integrations/models/gitHostIntegration.d.ts +6 -3
  219. package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -1
  220. package/dist/plus/integrations/models/gitHostIntegration.js +12 -2
  221. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  222. package/dist/plus/integrations/models/integration.d.ts +3 -1
  223. package/dist/plus/integrations/models/integration.d.ts.map +1 -1
  224. package/dist/plus/integrations/models/integration.js +2 -2
  225. package/dist/plus/integrations/models/integration.js.map +1 -1
  226. package/dist/plus/integrations/providers/accounts.d.ts.map +1 -1
  227. package/dist/plus/integrations/providers/accounts.js +4 -0
  228. package/dist/plus/integrations/providers/accounts.js.map +1 -1
  229. package/dist/plus/integrations/providers/azure/models.d.ts.map +1 -1
  230. package/dist/plus/integrations/providers/azure/models.js +3 -0
  231. package/dist/plus/integrations/providers/azure/models.js.map +1 -1
  232. package/dist/plus/integrations/providers/bitbucket/models.d.ts.map +1 -1
  233. package/dist/plus/integrations/providers/bitbucket/models.js +1 -0
  234. package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -1
  235. package/dist/plus/integrations/providers/github.d.ts +14 -2
  236. package/dist/plus/integrations/providers/github.d.ts.map +1 -1
  237. package/dist/plus/integrations/providers/github.js +55 -3
  238. package/dist/plus/integrations/providers/github.js.map +1 -1
  239. package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -1
  240. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  241. package/dist/plus/integrations/providers/models.d.ts.map +1 -1
  242. package/dist/plus/integrations/providers/models.js +30 -4
  243. package/dist/plus/integrations/providers/models.js.map +1 -1
  244. package/dist/plus/integrations/reads/broaden.d.ts.map +1 -1
  245. package/dist/plus/integrations/reads/broaden.js +6 -1
  246. package/dist/plus/integrations/reads/broaden.js.map +1 -1
  247. package/dist/plus/integrations/reads/drains.d.ts.map +1 -1
  248. package/dist/plus/integrations/reads/drains.js +7 -4
  249. package/dist/plus/integrations/reads/drains.js.map +1 -1
  250. package/dist/plus/integrations/reads/hierarchy.d.ts.map +1 -1
  251. package/dist/plus/integrations/reads/hierarchy.js +3 -1
  252. package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
  253. package/dist/plus/integrations/reads/issueTracker.d.ts.map +1 -1
  254. package/dist/plus/integrations/reads/issueTracker.js +8 -3
  255. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  256. package/dist/plus/integrations/reads/issues.d.ts.map +1 -1
  257. package/dist/plus/integrations/reads/issues.js +9 -4
  258. package/dist/plus/integrations/reads/issues.js.map +1 -1
  259. package/dist/plus/integrations/reads/pullRequests.d.ts.map +1 -1
  260. package/dist/plus/integrations/reads/pullRequests.js +9 -4
  261. package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
  262. package/dist/utils/env/browser/base64.d.ts +1 -1
  263. package/dist/utils/env/browser/base64.d.ts.map +1 -1
  264. package/dist/utils/env/node/base64.d.ts +1 -1
  265. package/dist/utils/env/node/base64.d.ts.map +1 -1
  266. package/dist/utils/env/node/base64.js +2 -0
  267. package/dist/utils/env/node/base64.js.map +1 -1
  268. package/dist/utils/keys/chord.d.ts +52 -0
  269. package/dist/utils/keys/chord.d.ts.map +1 -0
  270. package/dist/utils/keys/chord.js +135 -0
  271. package/dist/utils/keys/chord.js.map +1 -0
  272. package/dist/utils/keys/keybinding.d.ts +53 -0
  273. package/dist/utils/keys/keybinding.d.ts.map +1 -0
  274. package/dist/utils/keys/keybinding.js +58 -0
  275. package/dist/utils/keys/keybinding.js.map +1 -0
  276. package/dist/utils/path.d.ts +11 -0
  277. package/dist/utils/path.d.ts.map +1 -1
  278. package/dist/utils/path.js +13 -0
  279. package/dist/utils/path.js.map +1 -1
  280. package/package.json +13 -5
  281. package/src/git/cache.ts +383 -47
  282. package/src/git/context.ts +11 -0
  283. package/src/git/models/fileStatus.ts +1 -0
  284. package/src/git/models/issue.ts +4 -0
  285. package/src/git/models/mergeConflicts.ts +3 -2
  286. package/src/git/models/pullRequest.ts +33 -1
  287. package/src/git/models/repository.ts +58 -17
  288. package/src/git/models/statusFile.ts +3 -0
  289. package/src/git/providers/branches.ts +6 -0
  290. package/src/git/providers/commits.ts +11 -0
  291. package/src/git/providers/config.ts +18 -0
  292. package/src/git/providers/operations.ts +1 -0
  293. package/src/git/providers/pausedOperations.ts +2 -0
  294. package/src/git/providers/status.ts +1 -0
  295. package/src/git/utils/config.utils.ts +8 -0
  296. package/src/git/utils/issue.utils.ts +2 -0
  297. package/src/git/utils/pausedOperationStatus.utils.ts +28 -0
  298. package/src/git/utils/pullRequest.utils.ts +36 -0
  299. package/src/git/watching/changeEvent.ts +6 -1
  300. package/src/git/watching/classifyChange.ts +15 -1
  301. package/src/git/watching/watchService.ts +20 -3
  302. package/src/git/watching/watchSession.ts +41 -6
  303. package/src/git/watching/watcherPatterns.ts +1 -1
  304. package/src/git-cli/exec/git.ts +13 -3
  305. package/src/git-cli/providers/branches.ts +384 -132
  306. package/src/git-cli/providers/commits.ts +106 -15
  307. package/src/git-cli/providers/config.ts +229 -8
  308. package/src/git-cli/providers/contributors.ts +5 -1
  309. package/src/git-cli/providers/graph.ts +26 -13
  310. package/src/git-cli/providers/operations.ts +45 -20
  311. package/src/git-cli/providers/pausedOperations.ts +109 -17
  312. package/src/git-cli/providers/refs.ts +33 -3
  313. package/src/git-cli/providers/status.ts +25 -4
  314. package/src/git-cli/providers/worktrees.ts +5 -0
  315. package/src/git-cli/service.ts +0 -1
  316. package/src/plus/agents/providers/claudeCodeProvider.ts +1130 -87
  317. package/src/plus/agents/providers/claudeCodeTranscript.ts +95 -9
  318. package/src/plus/agents/types.ts +46 -2
  319. package/src/plus/ai/errors.ts +30 -0
  320. package/src/plus/ai/models/model.ts +56 -6
  321. package/src/plus/ai/models/promptTemplates.ts +1 -1
  322. package/src/plus/ai/models/provider.ts +69 -2
  323. package/src/plus/ai/prompts.ts +186 -61
  324. package/src/plus/ai/providers/anthropicProvider.ts +155 -47
  325. package/src/plus/ai/providers/deepSeekProvider.ts +11 -21
  326. package/src/plus/ai/providers/geminiProvider.ts +19 -0
  327. package/src/plus/ai/providers/gitkrakenProvider.ts +126 -3
  328. package/src/plus/ai/providers/huggingFaceProvider.ts +6 -0
  329. package/src/plus/ai/providers/mistralProvider.ts +102 -19
  330. package/src/plus/ai/providers/ollamaProvider.ts +55 -4
  331. package/src/plus/ai/providers/openAICompatibleProvider.ts +5 -0
  332. package/src/plus/ai/providers/openAICompatibleProviderBase.ts +360 -17
  333. package/src/plus/ai/providers/openRouterProvider.ts +17 -0
  334. package/src/plus/ai/providers/openaiProvider.ts +1 -0
  335. package/src/plus/ai/providers/responseFormatCache.ts +39 -0
  336. package/src/plus/ai/providers/xaiProvider.ts +10 -1
  337. package/src/plus/ai/utils/ai.utils.ts +14 -0
  338. package/src/plus/ai/utils/results.utils.ts +255 -31
  339. package/src/plus/git-github/api/github.ts +291 -7
  340. package/src/plus/git-github/models.ts +48 -2
  341. package/src/plus/git-github/providers/github/status.ts +1 -0
  342. package/src/plus/integrations/context.ts +4 -0
  343. package/src/plus/integrations/index.ts +2 -0
  344. package/src/plus/integrations/models/gitHostIntegration.ts +25 -2
  345. package/src/plus/integrations/models/integration.ts +23 -13
  346. package/src/plus/integrations/providers/accounts.ts +4 -0
  347. package/src/plus/integrations/providers/azure/models.ts +3 -0
  348. package/src/plus/integrations/providers/bitbucket/models.ts +1 -0
  349. package/src/plus/integrations/providers/github.ts +85 -1
  350. package/src/plus/integrations/providers/gitlab.ts +2 -10
  351. package/src/plus/integrations/providers/models.ts +36 -4
  352. package/src/plus/integrations/reads/broaden.ts +6 -1
  353. package/src/plus/integrations/reads/drains.ts +7 -4
  354. package/src/plus/integrations/reads/hierarchy.ts +3 -1
  355. package/src/plus/integrations/reads/issueTracker.ts +9 -3
  356. package/src/plus/integrations/reads/issues.ts +9 -4
  357. package/src/plus/integrations/reads/pullRequests.ts +9 -4
  358. package/src/utils/env/browser/base64.ts +1 -1
  359. package/src/utils/env/node/base64.ts +3 -1
  360. package/src/utils/keys/chord.ts +184 -0
  361. package/src/utils/keys/keybinding.ts +116 -0
  362. package/src/utils/path.ts +14 -0
@@ -24,7 +24,7 @@ import type { CliGitProviderInternal } from '../cliGitProvider.js';
24
24
  import type { Git } from '../exec/git.js';
25
25
  import { getGitCommandError } from '../exec/git.js';
26
26
 
27
- const todoCommitRegex = /^(?:p(?:ick)?|revert)\s+([a-f0-9]+)/i;
27
+ const todoCommitRegex = /^(?:p(?:ick)?|revert)\s+([a-f0-9]+)(?:\s+(.+))?$/i;
28
28
 
29
29
  type Operation = 'cherry-pick' | 'merge' | 'rebase-apply' | 'rebase-merge' | 'revert' | 'sequencer';
30
30
 
@@ -134,22 +134,25 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
134
134
  return undefined;
135
135
  }
136
136
 
137
- const [branchResult, mergeBaseResult] = await Promise.allSettled([
137
+ const [branchResult, mergeBaseResult, messageResult] = await Promise.allSettled([
138
138
  this.provider.branches.getCurrentBranchReference(repoPath, cancellation),
139
139
  this.provider.refs.getMergeBase(repoPath, 'CHERRY_PICK_HEAD', 'HEAD', undefined, cancellation),
140
+ this.getCommitMessage(repoPath, cherryPickHead, cancellation),
140
141
  ]);
141
142
  if (cancellation?.aborted) throw new CancellationError();
142
143
 
143
144
  const current = getSettledValue(branchResult)!;
144
145
  const mergeBase = getSettledValue(mergeBaseResult);
146
+ // Names the commit being applied, so consumers can say which one a skip would drop
147
+ const message = getSettledValue(messageResult);
145
148
 
146
149
  return {
147
150
  type: 'cherry-pick',
148
151
  repoPath: repoPath,
149
152
  mergeBase: mergeBase,
150
- HEAD: createReference(cherryPickHead, repoPath, { refType: 'revision' }),
153
+ HEAD: createReference(cherryPickHead, repoPath, { refType: 'revision', message: message }),
151
154
  current: current,
152
- incoming: createReference(cherryPickHead, repoPath, { refType: 'revision' }),
155
+ incoming: createReference(cherryPickHead, repoPath, { refType: 'revision', message: message }),
153
156
  } satisfies GitCherryPickStatus;
154
157
  }
155
158
  case 'merge': {
@@ -222,22 +225,25 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
222
225
  return undefined;
223
226
  }
224
227
 
225
- const [branchResult, mergeBaseResult] = await Promise.allSettled([
228
+ const [branchResult, mergeBaseResult, messageResult] = await Promise.allSettled([
226
229
  this.provider.branches.getCurrentBranchReference(repoPath, cancellation),
227
230
  this.provider.refs.getMergeBase(repoPath, 'REVERT_HEAD', 'HEAD', undefined, cancellation),
231
+ this.getCommitMessage(repoPath, revertHead, cancellation),
228
232
  ]);
229
233
  if (cancellation?.aborted) throw new CancellationError();
230
234
 
231
235
  const current = getSettledValue(branchResult)!;
232
236
  const mergeBase = getSettledValue(mergeBaseResult);
237
+ // Names the commit being reverted, so consumers can say which one a skip would drop
238
+ const message = getSettledValue(messageResult);
233
239
 
234
240
  return {
235
241
  type: 'revert',
236
242
  repoPath: repoPath,
237
243
  mergeBase: mergeBase,
238
- HEAD: createReference(revertHead, repoPath, { refType: 'revision' }),
244
+ HEAD: createReference(revertHead, repoPath, { refType: 'revision', message: message }),
239
245
  current: current,
240
- incoming: createReference(revertHead, repoPath, { refType: 'revision' }),
246
+ incoming: createReference(revertHead, repoPath, { refType: 'revision', message: message }),
241
247
  } satisfies GitRevertStatus;
242
248
  }
243
249
  case 'rebase-apply':
@@ -407,6 +413,10 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
407
413
  return undefined;
408
414
  }
409
415
 
416
+ // The todo line carries only the commit's SUBJECT (the other producers carry the full
417
+ // message) — good enough to name the commit a skip would drop, without another git call
418
+ const message = match?.[2]?.trim() || undefined;
419
+
410
420
  const [branchResult, mergeBaseResult] = await Promise.allSettled([
411
421
  this.provider.branches.getCurrentBranchReference(repoPath, cancellation),
412
422
  this.provider.refs.getMergeBase(repoPath, currentCommitSha, 'HEAD', undefined, cancellation),
@@ -421,9 +431,15 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
421
431
  type: 'cherry-pick',
422
432
  repoPath: repoPath,
423
433
  mergeBase: mergeBase,
424
- HEAD: createReference(currentCommitSha, repoPath, { refType: 'revision' }),
434
+ HEAD: createReference(currentCommitSha, repoPath, {
435
+ refType: 'revision',
436
+ message: message,
437
+ }),
425
438
  current: current,
426
- incoming: createReference(currentCommitSha, repoPath, { refType: 'revision' }),
439
+ incoming: createReference(currentCommitSha, repoPath, {
440
+ refType: 'revision',
441
+ message: message,
442
+ }),
427
443
  } satisfies GitCherryPickStatus;
428
444
  }
429
445
 
@@ -431,9 +447,12 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
431
447
  type: 'revert',
432
448
  repoPath: repoPath,
433
449
  mergeBase: mergeBase,
434
- HEAD: createReference(currentCommitSha, repoPath, { refType: 'revision' }),
450
+ HEAD: createReference(currentCommitSha, repoPath, { refType: 'revision', message: message }),
435
451
  current: current,
436
- incoming: createReference(currentCommitSha, repoPath, { refType: 'revision' }),
452
+ incoming: createReference(currentCommitSha, repoPath, {
453
+ refType: 'revision',
454
+ message: message,
455
+ }),
437
456
  } satisfies GitRevertStatus;
438
457
  }
439
458
  }
@@ -442,6 +461,33 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
442
461
  return status;
443
462
  }
444
463
 
464
+ /** Memoized per repo by sha — forced status re-reads on FS noise (every file save while resolving
465
+ * conflicts) would otherwise re-spawn `git log` for an unchanging commit. */
466
+ private readonly _commitMessageCache = new Map<string, { sha: string; message: string | undefined }>();
467
+
468
+ private async getCommitMessage(
469
+ repoPath: string,
470
+ sha: string,
471
+ cancellation?: AbortSignal,
472
+ ): Promise<string | undefined> {
473
+ const cached = this._commitMessageCache.get(repoPath);
474
+ if (cached?.sha === sha) return cached.message;
475
+
476
+ const result = await this.git.run(
477
+ { cwd: repoPath, cancellation: cancellation, errors: 'ignore' },
478
+ 'log',
479
+ '-1',
480
+ '--format=%B',
481
+ sha,
482
+ );
483
+ const message = result.stdout.trim() || undefined;
484
+ // Don't cache a miss — a transient failure would otherwise stick for the operation's lifetime
485
+ if (message != null) {
486
+ this._commitMessageCache.set(repoPath, { sha: sha, message: message });
487
+ }
488
+ return message;
489
+ }
490
+
445
491
  private async readDotGitFile(
446
492
  gitDir: GitDir,
447
493
  pathParts: string[],
@@ -487,7 +533,9 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
487
533
  const args = [status.type, options?.quit ? '--quit' : '--abort'];
488
534
 
489
535
  try {
490
- await this.git.run({ cwd: repoPath, errors: 'throw' }, ...args);
536
+ // Unbounded like the operations it undoes — an abort of a large rebase can outrun the default
537
+ // command timeout, and being SIGTERM'd partway through would leave the repo mid-abort.
538
+ await this.git.run({ cwd: repoPath, errors: 'throw', timeout: 0 }, ...args);
491
539
  this.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'status');
492
540
  this.context.hooks?.repository?.onChanged?.(repoPath, ['head', 'heads', 'index']);
493
541
  } catch (ex) {
@@ -511,7 +559,7 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
511
559
  @debug()
512
560
  async continuePausedOperation(
513
561
  repoPath: string,
514
- options?: { skip?: boolean; messageEditor?: string },
562
+ options?: { allowEmpty?: boolean; skip?: boolean; messageEditor?: string },
515
563
  ): Promise<void> {
516
564
  const scope = getScopedLogger();
517
565
 
@@ -535,12 +583,42 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
535
583
  }
536
584
 
537
585
  try {
586
+ if (options?.allowEmpty) {
587
+ const commitArgs = ['commit', '--allow-empty', '--no-edit'];
588
+ try {
589
+ // Git won't record the empty commit on its own; making it explicitly (`--no-edit` reuses the
590
+ // message git already prepared) is what lets the operation move past it.
591
+ await this.git.run({ cwd: repoPath, errors: 'throw' }, ...commitArgs);
592
+ } catch (ex) {
593
+ scope?.error(ex);
594
+ // Same reason taxonomy, but attributed to the commit that actually failed
595
+ throw getGitCommandError(
596
+ 'paused-operation-continue',
597
+ ex,
598
+ reason =>
599
+ new PausedOperationContinueError(
600
+ {
601
+ reason: reason,
602
+ operation: status,
603
+ skip: false,
604
+ gitCommand: { repoPath: repoPath, args: commitArgs },
605
+ },
606
+ ex,
607
+ ),
608
+ );
609
+ }
610
+ }
611
+
538
612
  await this.git.run(
539
613
  {
540
614
  cwd: repoPath,
541
615
  errors: 'throw',
542
616
  configs: configs,
543
617
  env: env,
618
+ // A `--continue` that opens the commit-message editor blocks for as long as the user leaves
619
+ // that tab open, which is unbounded — the default `advanced.git.timeout` would SIGTERM it
620
+ // mid-operation. The start paths (merge/rebase/revert) opt out for the same reason.
621
+ timeout: 0,
544
622
  // The runner dedups in-flight commands by args only — it ignores per-call `configs`/`env`.
545
623
  // A headless continue (with `GIT_EDITOR`) and a plain `--continue` would therefore collapse
546
624
  // into one execution, so the plain one could silently run headless (auto-accepting a commit
@@ -550,11 +628,10 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
550
628
  },
551
629
  ...args,
552
630
  );
553
- this.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'status');
554
- this.context.hooks?.repository?.onChanged?.(repoPath, ['head', 'heads', 'index']);
555
631
  } catch (ex) {
556
- scope?.error(ex);
557
- throw getGitCommandError(
632
+ if (PausedOperationContinueError.is(ex)) throw ex;
633
+
634
+ const error = getGitCommandError(
558
635
  'paused-operation-continue',
559
636
  ex,
560
637
  reason =>
@@ -568,6 +645,21 @@ export class PausedOperationsGitSubProvider implements GitPausedOperationsSubPro
568
645
  ex,
569
646
  ),
570
647
  );
648
+
649
+ // An empty commit concludes a single-commit cherry-pick/revert outright, leaving its
650
+ // `--continue` nothing to continue — the operation finished either way.
651
+ if (!options?.allowEmpty || !PausedOperationContinueError.is(error, 'nothingToContinue')) {
652
+ scope?.error(ex);
653
+ throw error;
654
+ }
655
+ } finally {
656
+ // Notify unconditionally rather than only on success: a throwing `--continue` can still have
657
+ // mutated the repo (committing the resolved step, then stopping on the NEXT step's conflict or
658
+ // empty commit), and the error alone can't distinguish that from a no-op failure. Invalidating
659
+ // after a genuine no-op only costs a re-read; not invalidating after a real advance leaves
660
+ // consumers rendering a stale step.
661
+ this.context.hooks?.cache?.onReset?.(repoPath, 'branches', 'status');
662
+ this.context.hooks?.repository?.onChanged?.(repoPath, ['head', 'heads', 'index']);
571
663
  }
572
664
  }
573
665
  }
@@ -42,17 +42,30 @@ export class RefsGitSubProvider implements GitRefsSubProvider {
42
42
  }
43
43
 
44
44
  /**
45
- * Raw `git for-each-ref` records covering branches, remotes, and tags in a single pass.
46
- * CLI-internal — siblings call via `this.provider.refs.getRefs(...)`. The `RefRecord` shape
45
+ * Raw `git for-each-ref` records covering branches, remotes, tags, and replace-refs in a single
46
+ * pass. CLI-internal — siblings call via `this.provider.refs.getRefs(...)`. The `RefRecord` shape
47
47
  * is `for-each-ref`-specific and intentionally absent from the public `GitRefsSubProvider`
48
48
  * interface.
49
49
  */
50
50
  @debug()
51
- async getRefs(repoPath: string, cancellation?: AbortSignal): Promise<RefRecord[]> {
51
+ async getRefs(repoPath: string, cancellation?: AbortSignal, options?: { force?: boolean }): Promise<RefRecord[]> {
52
52
  if (!repoPath) return [];
53
53
 
54
54
  const scope = getScopedLogger();
55
55
 
56
+ // Forces a fresh enumeration: evicts the shared cache entry (and the derived `refTips` projection,
57
+ // which would otherwise still answer from the old records) so the factory below re-runs and
58
+ // repopulates both from one spawn. Deliberately `delete`, not `invalidate` — soft-invalidation
59
+ // leaves an in-flight entry rideable, so a caller needing a point-in-time read (the graph's tip
60
+ // gate) could join an enumeration that started before the change it's trying to detect. Evicting
61
+ // is safe mid-flight: the in-flight factory's settle is ownership-guarded and won't evict the
62
+ // successor installed here.
63
+ if (options?.force) {
64
+ const commonPath = this.cache.getCommonPath(repoPath);
65
+ this.cache.refs.delete(commonPath);
66
+ this.cache.refTips.delete(commonPath);
67
+ }
68
+
56
69
  return this.cache.getRefs(
57
70
  repoPath,
58
71
  async (commonPath, cacheable, signal) => {
@@ -66,7 +79,24 @@ export class RefsGitSubProvider implements GitRefsSubProvider {
66
79
  'refs/heads/',
67
80
  'refs/remotes/',
68
81
  'refs/tags/',
82
+ // `git replace`/grafts — not surfaced to branch/tag/refTip consumers (filtered by
83
+ // refname prefix), but needed by the graph's replace-ref change gate (graph.ts).
84
+ 'refs/replace/',
69
85
  );
86
+ // Under `errors: 'ignore'` a cancelled run RESOLVES empty rather than throwing, so the
87
+ // catch below never sees it and an empty enumeration would be cached as a real answer —
88
+ // permanently, since this map has no TTL. Same guard `git.run`'s own caching path uses.
89
+ // The graph's tip gate calls this with `force: true` and supersedes itself freely, so it
90
+ // is routinely the sole registrant on the aggregate whose abort kills the spawn.
91
+ // Covers a FAILED enumeration too, not just a cancelled one: a transient `for-each-ref`
92
+ // failure (a lingering `index.lock`, EMFILE, the git dir briefly unavailable) also
93
+ // resolves empty, and caching that `[]` would blank every branch, tag and ref-tip
94
+ // consumer for the rest of the session. A genuinely ref-less repo still exits cleanly
95
+ // with empty stdout, so it caches as before.
96
+ if (result.completion.status !== 'exited' || result.exitCode !== 0 || signal?.aborted) {
97
+ cacheable?.invalidate();
98
+ return [];
99
+ }
70
100
  if (!result?.stdout) return [];
71
101
 
72
102
  using sw = maybeStopWatch(scope, { log: { onlyExit: true, level: 'debug' } });
@@ -286,7 +286,13 @@ export class StatusGitSubProvider implements GitStatusSubProvider {
286
286
  @debug()
287
287
  hasWorkingChanges(
288
288
  repoPath: string,
289
- options?: { staged?: boolean; unstaged?: boolean; untracked?: boolean; throwOnError?: boolean },
289
+ options?: {
290
+ staged?: boolean;
291
+ unstaged?: boolean;
292
+ untracked?: boolean;
293
+ throwOnError?: boolean;
294
+ priority?: GitCommandPriority;
295
+ },
290
296
  cancellation?: AbortSignal,
291
297
  ): Promise<boolean> {
292
298
  const scope = getScopedLogger();
@@ -296,16 +302,28 @@ export class StatusGitSubProvider implements GitStatusSubProvider {
296
302
  const untracked = options?.untracked ?? true;
297
303
  // `throwOnError` is in the key because it changes the RESULT on git failure (throw vs `false`) — a
298
304
  // throwing caller must not join, and be silently satisfied by, a non-throwing caller's graceful run.
305
+ // `priority` is in the key for a different reason: it doesn't change the answer, but a joiner INHERITS
306
+ // the in-flight run's scheduling. `GitQueue` refuses to start background work while anything is
307
+ // waiting at normal/interactive, so letting a foreground caller (the overview's dirty pill, the
308
+ // Worktrees view) join a `background` probe would strand it for the whole graph load. Splitting the
309
+ // two lanes costs at most one extra spawn; joining costs unbounded foreground latency.
299
310
  const throwOnError = options?.throwOnError ?? false;
311
+ const priority = options?.priority ?? 'default';
300
312
 
301
313
  return this.dedupeByStatusGeneration(
302
314
  repoPath,
303
- `hasWorkingChanges:${staged}:${unstaged}:${untracked}:${throwOnError}`,
315
+ `hasWorkingChanges:${staged}:${unstaged}:${untracked}:${throwOnError}:${priority}`,
304
316
  async (correlationKey, signal) => {
305
317
  try {
306
318
  if (staged || unstaged) {
307
319
  const result = await this.git.run(
308
- { cwd: repoPath, cancellation: signal, errors: 'ignore', correlationKey: correlationKey },
320
+ {
321
+ cwd: repoPath,
322
+ cancellation: signal,
323
+ errors: 'ignore',
324
+ correlationKey: correlationKey,
325
+ ...(options?.priority != null ? { priority: options.priority } : undefined),
326
+ },
309
327
  'diff',
310
328
  '--quiet',
311
329
  staged && unstaged ? 'HEAD' : staged ? '--staged' : undefined,
@@ -322,7 +340,10 @@ export class StatusGitSubProvider implements GitStatusSubProvider {
322
340
  }
323
341
  }
324
342
 
325
- // Check for untracked files
343
+ // Check for untracked files. NOTE: this runs through `git.stream`, which spawns directly
344
+ // and never enters the queue — so `priority` above doesn't reach it. Only clean worktrees
345
+ // get this far (a dirty one already returned above), and callers fanning out across many
346
+ // worktrees are expected to bound their own concurrency.
326
347
  if (untracked) {
327
348
  const hasUntracked = await this.hasUntrackedFiles(repoPath, signal);
328
349
  if (hasUntracked) {
@@ -65,6 +65,11 @@ export class WorktreesGitSubProvider implements GitWorktreesSubProvider {
65
65
  try {
66
66
  await this.git.run({ cwd: repoPath }, ...args);
67
67
 
68
+ if (options?.createBranch) {
69
+ // Evict the cached base only — see `checkout -b` for why the persisted keys are left alone.
70
+ this.cache.deleteBaseBranchName(repoPath, options.createBranch);
71
+ }
72
+
68
73
  this.context.hooks?.cache?.onReset?.(
69
74
  repoPath,
70
75
  ...(options?.createBranch ? (['branches', 'worktrees'] as const) : (['worktrees'] as const)),
@@ -78,6 +78,5 @@ export function createCliGitService(options: CliGitServiceOptions): GitService {
78
78
  // miss. Subscriptions are torn down with the service (its `watchService`'s emitters are disposed on dispose).
79
79
  service.watchService?.onDidChangeWorkingTree(repoPath => provider.cache.onWorkingTreeChanged(repoPath));
80
80
  service.watchService?.onDidChangeRepository(e => provider.cache.onRepositoryChanged(e.repoPath, e.changes));
81
-
82
81
  return service;
83
82
  }