@gitkraken/core-gitlens 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/dist/git/cache.d.ts +38 -8
  3. package/dist/git/cache.d.ts.map +1 -1
  4. package/dist/git/cache.js +120 -55
  5. package/dist/git/cache.js.map +1 -1
  6. package/dist/git/context.d.ts +19 -0
  7. package/dist/git/context.d.ts.map +1 -1
  8. package/dist/git/context.js.map +1 -1
  9. package/dist/git/features.d.ts +1 -1
  10. package/dist/git/features.d.ts.map +1 -1
  11. package/dist/git/features.js +1 -0
  12. package/dist/git/features.js.map +1 -1
  13. package/dist/git/models/commit.d.ts.map +1 -1
  14. package/dist/git/models/commit.js.map +1 -1
  15. package/dist/git/models/graph.d.ts +96 -0
  16. package/dist/git/models/graph.d.ts.map +1 -1
  17. package/dist/git/models/graph.js +24 -1
  18. package/dist/git/models/graph.js.map +1 -1
  19. package/dist/git/models/reference.d.ts +31 -0
  20. package/dist/git/models/reference.d.ts.map +1 -1
  21. package/dist/git/models/remote.d.ts.map +1 -1
  22. package/dist/git/models/remote.js.map +1 -1
  23. package/dist/git/models/remoteProvider.d.ts +1 -0
  24. package/dist/git/models/remoteProvider.d.ts.map +1 -1
  25. package/dist/git/models/remoteProvider.js.map +1 -1
  26. package/dist/git/models/repository.d.ts +30 -13
  27. package/dist/git/models/repository.d.ts.map +1 -1
  28. package/dist/git/models/repository.js +89 -87
  29. package/dist/git/models/repository.js.map +1 -1
  30. package/dist/git/models/search.d.ts +2 -2
  31. package/dist/git/models/search.d.ts.map +1 -1
  32. package/dist/git/models/statusFile.d.ts +9 -0
  33. package/dist/git/models/statusFile.d.ts.map +1 -1
  34. package/dist/git/models/statusFile.js +11 -0
  35. package/dist/git/models/statusFile.js.map +1 -1
  36. package/dist/git/models/worktree.d.ts +4 -1
  37. package/dist/git/models/worktree.d.ts.map +1 -1
  38. package/dist/git/models/worktree.js +2 -2
  39. package/dist/git/models/worktree.js.map +1 -1
  40. package/dist/git/parsers/diffParser.d.ts.map +1 -1
  41. package/dist/git/parsers/diffParser.js.map +1 -1
  42. package/dist/git/providers/branches.d.ts +15 -4
  43. package/dist/git/providers/branches.d.ts.map +1 -1
  44. package/dist/git/providers/commits.d.ts +4 -0
  45. package/dist/git/providers/commits.d.ts.map +1 -1
  46. package/dist/git/providers/config.d.ts +5 -4
  47. package/dist/git/providers/config.d.ts.map +1 -1
  48. package/dist/git/providers/operations.d.ts +61 -12
  49. package/dist/git/providers/operations.d.ts.map +1 -1
  50. package/dist/git/providers/pausedOperations.d.ts +3 -1
  51. package/dist/git/providers/pausedOperations.d.ts.map +1 -1
  52. package/dist/git/providers/refs.d.ts +23 -2
  53. package/dist/git/providers/refs.d.ts.map +1 -1
  54. package/dist/git/providers/staging.d.ts +16 -0
  55. package/dist/git/providers/staging.d.ts.map +1 -1
  56. package/dist/git/providers/status.d.ts +4 -1
  57. package/dist/git/providers/status.d.ts.map +1 -1
  58. package/dist/git/remotes/azure-devops.d.ts.map +1 -1
  59. package/dist/git/remotes/azure-devops.js.map +1 -1
  60. package/dist/git/remotes/custom.d.ts +2 -0
  61. package/dist/git/remotes/custom.d.ts.map +1 -1
  62. package/dist/git/remotes/custom.js +20 -0
  63. package/dist/git/remotes/custom.js.map +1 -1
  64. package/dist/git/{exec.types.d.ts → run.types.d.ts} +22 -3
  65. package/dist/git/run.types.d.ts.map +1 -0
  66. package/dist/git/run.types.js +2 -0
  67. package/dist/git/run.types.js.map +1 -0
  68. package/dist/git/service.d.ts.map +1 -1
  69. package/dist/git/service.js.map +1 -1
  70. package/dist/git/utils/autolink.utils.d.ts.map +1 -1
  71. package/dist/git/utils/autolink.utils.js.map +1 -1
  72. package/dist/git/utils/blame.utils.d.ts.map +1 -1
  73. package/dist/git/utils/blame.utils.js.map +1 -1
  74. package/dist/git/utils/conflictResolution.utils.d.ts +6 -0
  75. package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -0
  76. package/dist/git/utils/conflictResolution.utils.js +25 -0
  77. package/dist/git/utils/conflictResolution.utils.js.map +1 -0
  78. package/dist/git/utils/contributor.utils.d.ts +3 -0
  79. package/dist/git/utils/contributor.utils.d.ts.map +1 -1
  80. package/dist/git/utils/contributor.utils.js +22 -0
  81. package/dist/git/utils/contributor.utils.js.map +1 -1
  82. package/dist/git/utils/fileStatus.utils.d.ts +2 -1
  83. package/dist/git/utils/fileStatus.utils.d.ts.map +1 -1
  84. package/dist/git/utils/fileStatus.utils.js +4 -0
  85. package/dist/git/utils/fileStatus.utils.js.map +1 -1
  86. package/dist/git/utils/reachability.utils.d.ts +37 -0
  87. package/dist/git/utils/reachability.utils.d.ts.map +1 -0
  88. package/dist/git/utils/reachability.utils.js +96 -0
  89. package/dist/git/utils/reachability.utils.js.map +1 -0
  90. package/dist/git/utils/search.utils.d.ts.map +1 -1
  91. package/dist/git/utils/search.utils.js +3 -0
  92. package/dist/git/utils/search.utils.js.map +1 -1
  93. package/dist/git/utils/sorting.d.ts +8 -0
  94. package/dist/git/utils/sorting.d.ts.map +1 -1
  95. package/dist/git/utils/sorting.js +15 -0
  96. package/dist/git/utils/sorting.js.map +1 -1
  97. package/dist/git/utils/status.utils.d.ts.map +1 -1
  98. package/dist/git/utils/status.utils.js.map +1 -1
  99. package/dist/git/watching/classifyChange.d.ts.map +1 -1
  100. package/dist/git/watching/classifyChange.js +8 -0
  101. package/dist/git/watching/classifyChange.js.map +1 -1
  102. package/dist/git/watching/gitIgnoreFilter.js +1 -1
  103. package/dist/git/watching/gitIgnoreFilter.js.map +1 -1
  104. package/dist/git/watching/initWatcher.d.ts.map +1 -1
  105. package/dist/git/watching/initWatcher.js.map +1 -1
  106. package/dist/git/watching/watchGroup.d.ts.map +1 -1
  107. package/dist/git/watching/watchGroup.js.map +1 -1
  108. package/dist/git/watching/watchService.d.ts +4 -2
  109. package/dist/git/watching/watchService.d.ts.map +1 -1
  110. package/dist/git/watching/watchService.js +31 -6
  111. package/dist/git/watching/watchService.js.map +1 -1
  112. package/dist/git/watching/watchSession.d.ts +14 -12
  113. package/dist/git/watching/watchSession.d.ts.map +1 -1
  114. package/dist/git/watching/watchSession.js +56 -55
  115. package/dist/git/watching/watchSession.js.map +1 -1
  116. package/dist/git-cli/exec/exec.types.d.ts +1 -1
  117. package/dist/git-cli/exec/exec.types.d.ts.map +1 -1
  118. package/dist/git-cli/exec/git.d.ts +3 -3
  119. package/dist/git-cli/exec/git.d.ts.map +1 -1
  120. package/dist/git-cli/exec/git.js.map +1 -1
  121. package/dist/git-cli/exec/gitQueue.d.ts +10 -2
  122. package/dist/git-cli/exec/gitQueue.d.ts.map +1 -1
  123. package/dist/git-cli/exec/gitQueue.js +39 -12
  124. package/dist/git-cli/exec/gitQueue.js.map +1 -1
  125. package/dist/git-cli/parsers/blameParser.d.ts.map +1 -1
  126. package/dist/git-cli/parsers/blameParser.js.map +1 -1
  127. package/dist/git-cli/parsers/logParser.js.map +1 -1
  128. package/dist/git-cli/parsers/refParser.d.ts +3 -30
  129. package/dist/git-cli/parsers/refParser.d.ts.map +1 -1
  130. package/dist/git-cli/parsers/refParser.js +30 -30
  131. package/dist/git-cli/parsers/refParser.js.map +1 -1
  132. package/dist/git-cli/providers/blame.d.ts.map +1 -1
  133. package/dist/git-cli/providers/blame.js.map +1 -1
  134. package/dist/git-cli/providers/branches.d.ts +15 -5
  135. package/dist/git-cli/providers/branches.d.ts.map +1 -1
  136. package/dist/git-cli/providers/branches.js +99 -68
  137. package/dist/git-cli/providers/branches.js.map +1 -1
  138. package/dist/git-cli/providers/commits.d.ts +1 -0
  139. package/dist/git-cli/providers/commits.d.ts.map +1 -1
  140. package/dist/git-cli/providers/commits.js +86 -30
  141. package/dist/git-cli/providers/commits.js.map +1 -1
  142. package/dist/git-cli/providers/config.d.ts +19 -6
  143. package/dist/git-cli/providers/config.d.ts.map +1 -1
  144. package/dist/git-cli/providers/config.js +86 -38
  145. package/dist/git-cli/providers/config.js.map +1 -1
  146. package/dist/git-cli/providers/diff.d.ts.map +1 -1
  147. package/dist/git-cli/providers/diff.js +5 -3
  148. package/dist/git-cli/providers/diff.js.map +1 -1
  149. package/dist/git-cli/providers/graph.d.ts.map +1 -1
  150. package/dist/git-cli/providers/graph.js +139 -16
  151. package/dist/git-cli/providers/graph.js.map +1 -1
  152. package/dist/git-cli/providers/operations.d.ts +17 -14
  153. package/dist/git-cli/providers/operations.d.ts.map +1 -1
  154. package/dist/git-cli/providers/operations.js +135 -63
  155. package/dist/git-cli/providers/operations.js.map +1 -1
  156. package/dist/git-cli/providers/patch.d.ts.map +1 -1
  157. package/dist/git-cli/providers/patch.js.map +1 -1
  158. package/dist/git-cli/providers/pausedOperations.d.ts +3 -1
  159. package/dist/git-cli/providers/pausedOperations.d.ts.map +1 -1
  160. package/dist/git-cli/providers/pausedOperations.js +7 -1
  161. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  162. package/dist/git-cli/providers/refs.d.ts +19 -2
  163. package/dist/git-cli/providers/refs.d.ts.map +1 -1
  164. package/dist/git-cli/providers/refs.js +286 -2
  165. package/dist/git-cli/providers/refs.js.map +1 -1
  166. package/dist/git-cli/providers/revision.js.map +1 -1
  167. package/dist/git-cli/providers/staging.d.ts +6 -0
  168. package/dist/git-cli/providers/staging.d.ts.map +1 -1
  169. package/dist/git-cli/providers/staging.js +32 -0
  170. package/dist/git-cli/providers/staging.js.map +1 -1
  171. package/dist/git-cli/providers/stash.d.ts.map +1 -1
  172. package/dist/git-cli/providers/stash.js +20 -2
  173. package/dist/git-cli/providers/stash.js.map +1 -1
  174. package/dist/git-cli/providers/status.d.ts +4 -1
  175. package/dist/git-cli/providers/status.d.ts.map +1 -1
  176. package/dist/git-cli/providers/status.js +8 -4
  177. package/dist/git-cli/providers/status.js.map +1 -1
  178. package/dist/git-cli/providers/tags.d.ts.map +1 -1
  179. package/dist/git-cli/providers/tags.js +10 -6
  180. package/dist/git-cli/providers/tags.js.map +1 -1
  181. package/dist/ipc/discovery.d.ts +49 -0
  182. package/dist/ipc/discovery.d.ts.map +1 -0
  183. package/dist/ipc/discovery.js +147 -0
  184. package/dist/ipc/discovery.js.map +1 -0
  185. package/dist/ipc/ipcServer.d.ts +20 -0
  186. package/dist/ipc/ipcServer.d.ts.map +1 -0
  187. package/dist/ipc/ipcServer.js +162 -0
  188. package/dist/ipc/ipcServer.js.map +1 -0
  189. package/dist/plus/agents/providers/claudeCodeProvider.d.ts +167 -0
  190. package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -0
  191. package/dist/plus/agents/providers/claudeCodeProvider.js +1786 -0
  192. package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -0
  193. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts +36 -0
  194. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts.map +1 -0
  195. package/dist/plus/agents/providers/claudeCodeTranscript.js +171 -0
  196. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -0
  197. package/dist/plus/agents/sanitizePrompt.d.ts +15 -0
  198. package/dist/plus/agents/sanitizePrompt.d.ts.map +1 -0
  199. package/dist/plus/agents/sanitizePrompt.js +103 -0
  200. package/dist/plus/agents/sanitizePrompt.js.map +1 -0
  201. package/dist/plus/agents/stateMachine.d.ts +32 -0
  202. package/dist/plus/agents/stateMachine.d.ts.map +1 -0
  203. package/dist/plus/agents/stateMachine.js +180 -0
  204. package/dist/plus/agents/stateMachine.js.map +1 -0
  205. package/dist/plus/agents/types.d.ts +254 -0
  206. package/dist/plus/agents/types.d.ts.map +1 -0
  207. package/dist/plus/agents/types.js +49 -0
  208. package/dist/plus/agents/types.js.map +1 -0
  209. package/dist/plus/ai/errors.d.ts +4 -1
  210. package/dist/plus/ai/errors.d.ts.map +1 -1
  211. package/dist/plus/ai/errors.js +38 -0
  212. package/dist/plus/ai/errors.js.map +1 -1
  213. package/dist/plus/ai/models/model.d.ts +1 -1
  214. package/dist/plus/ai/models/model.d.ts.map +1 -1
  215. package/dist/plus/ai/models/model.js.map +1 -1
  216. package/dist/plus/ai/models/promptTemplates.d.ts +11 -2
  217. package/dist/plus/ai/models/promptTemplates.d.ts.map +1 -1
  218. package/dist/plus/ai/models/provider.d.ts +3 -0
  219. package/dist/plus/ai/models/provider.d.ts.map +1 -1
  220. package/dist/plus/ai/prompts.d.ts +1 -0
  221. package/dist/plus/ai/prompts.d.ts.map +1 -1
  222. package/dist/plus/ai/prompts.js +48 -8
  223. package/dist/plus/ai/prompts.js.map +1 -1
  224. package/dist/plus/ai/providers/gitkrakenProvider.d.ts +1 -1
  225. package/dist/plus/ai/providers/gitkrakenProvider.d.ts.map +1 -1
  226. package/dist/plus/ai/providers/gitkrakenProvider.js +4 -1
  227. package/dist/plus/ai/providers/gitkrakenProvider.js.map +1 -1
  228. package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts +4 -3
  229. package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts.map +1 -1
  230. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +9 -6
  231. package/dist/plus/ai/providers/openAICompatibleProviderBase.js.map +1 -1
  232. package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
  233. package/dist/plus/ai/utils/ai.utils.js +2 -0
  234. package/dist/plus/ai/utils/ai.utils.js.map +1 -1
  235. package/dist/plus/ai/utils/results.utils.d.ts.map +1 -1
  236. package/dist/plus/ai/utils/results.utils.js.map +1 -1
  237. package/dist/plus/git-github/api/github.d.ts +12 -1
  238. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  239. package/dist/plus/git-github/api/github.js +245 -51
  240. package/dist/plus/git-github/api/github.js.map +1 -1
  241. package/dist/plus/git-github/api/types.d.ts +8 -0
  242. package/dist/plus/git-github/api/types.d.ts.map +1 -1
  243. package/dist/plus/git-github/models.d.ts +1 -1
  244. package/dist/plus/git-github/models.d.ts.map +1 -1
  245. package/dist/plus/git-github/models.js.map +1 -1
  246. package/dist/plus/git-github/providers/github/blame.d.ts.map +1 -1
  247. package/dist/plus/git-github/providers/github/blame.js.map +1 -1
  248. package/dist/plus/git-github/providers/github/branches.d.ts +5 -1
  249. package/dist/plus/git-github/providers/github/branches.d.ts.map +1 -1
  250. package/dist/plus/git-github/providers/github/branches.js +47 -24
  251. package/dist/plus/git-github/providers/github/branches.js.map +1 -1
  252. package/dist/plus/git-github/providers/github/commits.d.ts.map +1 -1
  253. package/dist/plus/git-github/providers/github/commits.js +144 -92
  254. package/dist/plus/git-github/providers/github/commits.js.map +1 -1
  255. package/dist/plus/git-github/providers/github/diff.d.ts +1 -1
  256. package/dist/plus/git-github/providers/github/diff.d.ts.map +1 -1
  257. package/dist/plus/git-github/providers/github/diff.js +23 -9
  258. package/dist/plus/git-github/providers/github/diff.js.map +1 -1
  259. package/dist/plus/git-github/providers/github/refs.d.ts +9 -1
  260. package/dist/plus/git-github/providers/github/refs.d.ts.map +1 -1
  261. package/dist/plus/git-github/providers/github/refs.js +39 -14
  262. package/dist/plus/git-github/providers/github/refs.js.map +1 -1
  263. package/dist/plus/git-github/providers/github/revision.d.ts.map +1 -1
  264. package/dist/plus/git-github/providers/github/revision.js +1 -2
  265. package/dist/plus/git-github/providers/github/revision.js.map +1 -1
  266. package/dist/plus/git-github/providers/github/status.d.ts +4 -1
  267. package/dist/plus/git-github/providers/github/status.d.ts.map +1 -1
  268. package/dist/plus/git-github/providers/github/status.js +1 -1
  269. package/dist/plus/git-github/providers/github/status.js.map +1 -1
  270. package/dist/plus/git-github/providers/github/tags.d.ts.map +1 -1
  271. package/dist/plus/git-github/providers/github/tags.js +35 -36
  272. package/dist/plus/git-github/providers/github/tags.js.map +1 -1
  273. package/dist/plus/git-github/providers/githubGitProvider.d.ts.map +1 -1
  274. package/dist/plus/git-github/providers/githubGitProvider.js.map +1 -1
  275. package/dist/utils/color.d.ts.map +1 -1
  276. package/dist/utils/color.js.map +1 -1
  277. package/dist/utils/date.d.ts.map +1 -1
  278. package/dist/utils/date.js +6 -0
  279. package/dist/utils/date.js.map +1 -1
  280. package/dist/utils/debounce.js +1 -1
  281. package/dist/utils/decorators/serializable.d.ts.map +1 -1
  282. package/dist/utils/decorators/serializable.js.map +1 -1
  283. package/dist/utils/dedupedAsyncCache.d.ts +37 -0
  284. package/dist/utils/dedupedAsyncCache.d.ts.map +1 -0
  285. package/dist/utils/dedupedAsyncCache.js +68 -0
  286. package/dist/utils/dedupedAsyncCache.js.map +1 -0
  287. package/dist/utils/diff.d.ts +2 -0
  288. package/dist/utils/diff.d.ts.map +1 -0
  289. package/dist/utils/diff.js +53 -0
  290. package/dist/utils/diff.js.map +1 -0
  291. package/dist/utils/disposable.d.ts.map +1 -1
  292. package/dist/utils/disposable.js.map +1 -1
  293. package/dist/utils/env/node/exec.d.ts.map +1 -1
  294. package/dist/utils/env/node/exec.js.map +1 -1
  295. package/dist/utils/error.d.ts.map +1 -1
  296. package/dist/utils/error.js.map +1 -1
  297. package/dist/utils/iterable.d.ts +7 -1
  298. package/dist/utils/iterable.d.ts.map +1 -1
  299. package/dist/utils/iterable.js +12 -4
  300. package/dist/utils/iterable.js.map +1 -1
  301. package/dist/utils/logger.d.ts.map +1 -1
  302. package/dist/utils/logger.js.map +1 -1
  303. package/dist/utils/lruMap.d.ts +9 -0
  304. package/dist/utils/lruMap.d.ts.map +1 -1
  305. package/dist/utils/lruMap.js +26 -4
  306. package/dist/utils/lruMap.js.map +1 -1
  307. package/dist/utils/markdown.d.ts.map +1 -1
  308. package/dist/utils/markdown.js.map +1 -1
  309. package/dist/utils/mru.d.ts.map +1 -1
  310. package/dist/utils/mru.js.map +1 -1
  311. package/dist/utils/object.d.ts +22 -1
  312. package/dist/utils/object.d.ts.map +1 -1
  313. package/dist/utils/object.js +56 -3
  314. package/dist/utils/object.js.map +1 -1
  315. package/dist/utils/paging.js +14 -15
  316. package/dist/utils/paging.js.map +1 -1
  317. package/dist/utils/path.d.ts.map +1 -1
  318. package/dist/utils/path.js.map +1 -1
  319. package/dist/utils/promise.d.ts +1 -0
  320. package/dist/utils/promise.d.ts.map +1 -1
  321. package/dist/utils/promise.js +17 -0
  322. package/dist/utils/promise.js.map +1 -1
  323. package/dist/utils/promiseCache.d.ts +10 -0
  324. package/dist/utils/promiseCache.d.ts.map +1 -1
  325. package/dist/utils/promiseCache.js +34 -4
  326. package/dist/utils/promiseCache.js.map +1 -1
  327. package/dist/utils/string.d.ts.map +1 -1
  328. package/dist/utils/string.js +1 -1
  329. package/dist/utils/string.js.map +1 -1
  330. package/dist/utils/uri.d.ts.map +1 -1
  331. package/dist/utils/uri.js.map +1 -1
  332. package/dist/utils/version.d.ts.map +1 -1
  333. package/dist/utils/version.js.map +1 -1
  334. package/package.json +13 -1
  335. package/src/git/cache.ts +192 -90
  336. package/src/git/context.ts +21 -0
  337. package/src/git/features.ts +2 -0
  338. package/src/git/models/commit.ts +1 -0
  339. package/src/git/models/graph.ts +97 -0
  340. package/src/git/models/reference.ts +33 -0
  341. package/src/git/models/remote.ts +1 -0
  342. package/src/git/models/remoteProvider.ts +1 -0
  343. package/src/git/models/repository.ts +105 -96
  344. package/src/git/models/search.ts +2 -2
  345. package/src/git/models/statusFile.ts +12 -0
  346. package/src/git/models/worktree.ts +10 -2
  347. package/src/git/parsers/diffParser.ts +2 -0
  348. package/src/git/providers/branches.ts +22 -4
  349. package/src/git/providers/commits.ts +4 -0
  350. package/src/git/providers/config.ts +3 -5
  351. package/src/git/providers/operations.ts +65 -1
  352. package/src/git/providers/pausedOperations.ts +1 -0
  353. package/src/git/providers/refs.ts +32 -3
  354. package/src/git/providers/staging.ts +12 -0
  355. package/src/git/providers/status.ts +6 -1
  356. package/src/git/remotes/azure-devops.ts +2 -0
  357. package/src/git/remotes/custom.ts +23 -0
  358. package/src/git/{exec.types.ts → run.types.ts} +22 -2
  359. package/src/git/service.ts +1 -0
  360. package/src/git/utils/autolink.utils.ts +1 -0
  361. package/src/git/utils/blame.utils.ts +2 -0
  362. package/src/git/utils/conflictResolution.utils.ts +31 -0
  363. package/src/git/utils/contributor.utils.ts +24 -0
  364. package/src/git/utils/fileStatus.utils.ts +7 -1
  365. package/src/git/utils/reachability.utils.ts +109 -0
  366. package/src/git/utils/search.utils.ts +2 -0
  367. package/src/git/utils/sorting.ts +17 -0
  368. package/src/git/utils/status.utils.ts +1 -0
  369. package/src/git/watching/classifyChange.ts +9 -0
  370. package/src/git/watching/gitIgnoreFilter.ts +2 -2
  371. package/src/git/watching/initWatcher.ts +2 -0
  372. package/src/git/watching/watchGroup.ts +3 -0
  373. package/src/git/watching/watchService.ts +45 -7
  374. package/src/git/watching/watchSession.ts +71 -55
  375. package/src/git-cli/exec/exec.types.ts +2 -2
  376. package/src/git-cli/exec/git.ts +6 -5
  377. package/src/git-cli/exec/gitQueue.ts +41 -12
  378. package/src/git-cli/parsers/blameParser.ts +1 -0
  379. package/src/git-cli/parsers/logParser.ts +1 -0
  380. package/src/git-cli/parsers/refParser.ts +33 -34
  381. package/src/git-cli/providers/blame.ts +1 -0
  382. package/src/git-cli/providers/branches.ts +165 -93
  383. package/src/git-cli/providers/commits.ts +107 -37
  384. package/src/git-cli/providers/config.ts +101 -48
  385. package/src/git-cli/providers/diff.ts +10 -3
  386. package/src/git-cli/providers/graph.ts +156 -16
  387. package/src/git-cli/providers/operations.ts +208 -83
  388. package/src/git-cli/providers/patch.ts +1 -0
  389. package/src/git-cli/providers/pausedOperations.ts +8 -0
  390. package/src/git-cli/providers/refs.ts +247 -3
  391. package/src/git-cli/providers/revision.ts +2 -2
  392. package/src/git-cli/providers/staging.ts +33 -0
  393. package/src/git-cli/providers/stash.ts +20 -2
  394. package/src/git-cli/providers/status.ts +24 -5
  395. package/src/git-cli/providers/tags.ts +15 -16
  396. package/src/ipc/discovery.ts +186 -0
  397. package/src/ipc/ipcServer.ts +171 -0
  398. package/src/plus/agents/providers/claudeCodeProvider.ts +2122 -0
  399. package/src/plus/agents/providers/claudeCodeTranscript.ts +214 -0
  400. package/src/plus/agents/sanitizePrompt.ts +109 -0
  401. package/src/plus/agents/stateMachine.ts +197 -0
  402. package/src/plus/agents/types.ts +325 -0
  403. package/src/plus/ai/errors.ts +40 -0
  404. package/src/plus/ai/models/model.ts +1 -0
  405. package/src/plus/ai/models/promptTemplates.ts +13 -0
  406. package/src/plus/ai/models/provider.ts +7 -1
  407. package/src/plus/ai/prompts.ts +49 -8
  408. package/src/plus/ai/providers/gitkrakenProvider.ts +4 -0
  409. package/src/plus/ai/providers/openAICompatibleProviderBase.ts +21 -4
  410. package/src/plus/ai/utils/ai.utils.ts +2 -0
  411. package/src/plus/ai/utils/results.utils.ts +2 -0
  412. package/src/plus/git-github/api/github.ts +315 -57
  413. package/src/plus/git-github/api/types.ts +15 -0
  414. package/src/plus/git-github/models.ts +1 -1
  415. package/src/plus/git-github/providers/github/blame.ts +2 -0
  416. package/src/plus/git-github/providers/github/branches.ts +61 -31
  417. package/src/plus/git-github/providers/github/commits.ts +231 -160
  418. package/src/plus/git-github/providers/github/diff.ts +27 -19
  419. package/src/plus/git-github/providers/github/refs.ts +58 -23
  420. package/src/plus/git-github/providers/github/revision.ts +1 -2
  421. package/src/plus/git-github/providers/github/status.ts +6 -1
  422. package/src/plus/git-github/providers/github/tags.ts +61 -62
  423. package/src/plus/git-github/providers/githubGitProvider.ts +1 -0
  424. package/src/utils/color.ts +2 -0
  425. package/src/utils/date.ts +5 -0
  426. package/src/utils/debounce.ts +1 -1
  427. package/src/utils/decorators/serializable.ts +1 -0
  428. package/src/utils/dedupedAsyncCache.ts +74 -0
  429. package/src/utils/diff.ts +61 -0
  430. package/src/utils/disposable.ts +2 -0
  431. package/src/utils/env/node/exec.ts +2 -0
  432. package/src/utils/error.ts +1 -0
  433. package/src/utils/iterable.ts +17 -3
  434. package/src/utils/logger.ts +1 -0
  435. package/src/utils/lruMap.ts +29 -4
  436. package/src/utils/markdown.ts +1 -0
  437. package/src/utils/mru.ts +2 -0
  438. package/src/utils/object.ts +55 -4
  439. package/src/utils/paging.ts +14 -14
  440. package/src/utils/path.ts +1 -0
  441. package/src/utils/promise.ts +22 -0
  442. package/src/utils/promiseCache.ts +48 -16
  443. package/src/utils/string.ts +3 -1
  444. package/src/utils/uri.ts +1 -0
  445. package/src/utils/version.ts +1 -0
  446. package/dist/git/exec.types.d.ts.map +0 -1
  447. package/dist/git/exec.types.js +0 -2
  448. package/dist/git/exec.types.js.map +0 -1
@@ -54,6 +54,7 @@ export class WatchGroup implements UnifiedDisposable {
54
54
  /** Dispose the entire group (common watcher + all root watchers). */
55
55
  dispose(): void {
56
56
  if (this._disposed) return;
57
+
57
58
  this._disposed = true;
58
59
 
59
60
  for (const entry of this._sessions.values()) {
@@ -132,6 +133,7 @@ export class WatchGroup implements UnifiedDisposable {
132
133
  private onCommonEvent(event: FileWatchEvent): void {
133
134
  // Compute relative path from common git dir
134
135
  if (!isDescendant(event.path, this.commonGitDir)) return;
136
+
135
137
  const relativePath = relative(this.commonGitDir, event.path);
136
138
  if (shouldIgnoreRepoPath(relativePath)) return;
137
139
 
@@ -161,6 +163,7 @@ export class WatchGroup implements UnifiedDisposable {
161
163
 
162
164
  private onRootEvent(event: FileWatchEvent, entry: SessionEntry): void {
163
165
  if (!isDescendant(event.path, entry.gitDirPath)) return;
166
+
164
167
  const relativePath = relative(entry.gitDirPath, event.path);
165
168
  if (shouldIgnoreRepoPath(relativePath)) return;
166
169
 
@@ -38,7 +38,16 @@ export interface WatchHandle {
38
38
  interface SessionRecord {
39
39
  readonly session: RepositoryWatchSession;
40
40
  readonly gitDir: GitDir;
41
- readonly watchHooks?: WatchHooks;
41
+ /**
42
+ * Hooks contributed by all current `watch()` callers for this repo path. Earlier
43
+ * implementations stored just the first caller's hooks (`WatchHooks | undefined`) and
44
+ * silently dropped subsequent callers' hooks — that broke the case where a low-level
45
+ * subscriber (e.g. the Graph's secondary-worktree WIP watcher) opened the session
46
+ * first without hooks, and a later `Repository.watch()` for the same path lost
47
+ * its `markFetched` / `onIgnoresChanged` wiring. Each `watch()` call adds its hooks
48
+ * to this set and removes them on dispose; fire sites iterate the set.
49
+ */
50
+ readonly watchHooks: Set<WatchHooks>;
42
51
  refCount: number;
43
52
  }
44
53
 
@@ -69,6 +78,8 @@ export class RepositoryWatchService implements UnifiedDisposable {
69
78
  private readonly watchGroups = new Map<string, WatchGroup>();
70
79
  private readonly wtWatchers = new Map<string, { watcher: FileWatcher; filter?: GitIgnoreFilter }>();
71
80
  private _disposed = false;
81
+ /** Global suspend state (driven by window focus); inherited by sessions created via {@link watch}. */
82
+ private _suspended = false;
72
83
 
73
84
  constructor(options: WatchServiceOptions) {
74
85
  this.provider = options.watchingProvider;
@@ -83,6 +94,7 @@ export class RepositoryWatchService implements UnifiedDisposable {
83
94
 
84
95
  dispose(): void {
85
96
  if (this._disposed) return;
97
+
86
98
  this._disposed = true;
87
99
 
88
100
  for (const record of this.sessionMap.values()) {
@@ -117,11 +129,15 @@ export class RepositoryWatchService implements UnifiedDisposable {
117
129
  let record = this.sessionMap.get(repoPath);
118
130
  if (record != null) {
119
131
  record.refCount++;
132
+ if (watchHooks != null) {
133
+ record.watchHooks.add(watchHooks);
134
+ }
120
135
  } else {
121
136
  const session = new RepositoryWatchSession({
122
137
  repoPath: repoPath,
123
138
  defaultRepoDelayMs: this.defaultRepoDelayMs,
124
139
  defaultWorkingTreeDelayMs: this.defaultWorkingTreeDelayMs,
140
+ suspended: this._suspended,
125
141
  lifecycle: {
126
142
  onFirstRepoSubscriber: (): void => {
127
143
  const rec = this.sessionMap.get(repoPath);
@@ -150,10 +166,15 @@ export class RepositoryWatchService implements UnifiedDisposable {
150
166
  },
151
167
  });
152
168
 
169
+ const watchHooksSet = new Set<WatchHooks>();
170
+ if (watchHooks != null) {
171
+ watchHooksSet.add(watchHooks);
172
+ }
173
+
153
174
  record = {
154
175
  session: session,
155
176
  gitDir: gitDir,
156
- watchHooks: watchHooks,
177
+ watchHooks: watchHooksSet,
157
178
  refCount: 1,
158
179
  };
159
180
  this.sessionMap.set(repoPath, record);
@@ -166,12 +187,16 @@ export class RepositoryWatchService implements UnifiedDisposable {
166
187
  session: sessionRef,
167
188
  dispose: (): void => {
168
189
  if (handleDisposed) return;
190
+
169
191
  handleDisposed = true;
170
192
 
171
193
  const rec = this.sessionMap.get(repoPath);
172
194
  if (rec == null) return;
173
195
 
174
196
  rec.refCount--;
197
+ if (watchHooks != null) {
198
+ rec.watchHooks.delete(watchHooks);
199
+ }
175
200
  if (rec.refCount <= 0) {
176
201
  this.sessionMap.delete(repoPath);
177
202
  this.disposeSessionRecord(rec);
@@ -185,15 +210,17 @@ export class RepositoryWatchService implements UnifiedDisposable {
185
210
  return this.sessionMap.get(repoPath)?.session;
186
211
  }
187
212
 
188
- /** Suspend all sessions */
213
+ /** Suspend all sessions and mark the service suspended so late-joining sessions start suspended */
189
214
  suspendAll(): void {
215
+ this._suspended = true;
190
216
  for (const record of this.sessionMap.values()) {
191
217
  record.session.suspend();
192
218
  }
193
219
  }
194
220
 
195
- /** Resume all sessions, with optional per-session delay */
221
+ /** Resume all sessions (clearing the global suspend state), with optional per-session delay */
196
222
  resumeAll(getDelay?: (session: RepositoryWatchSession) => number): void {
223
+ this._suspended = false;
197
224
  for (const record of this.sessionMap.values()) {
198
225
  const delayMs = getDelay?.(record.session);
199
226
  record.session.resume(delayMs);
@@ -229,11 +256,18 @@ export class RepositoryWatchService implements UnifiedDisposable {
229
256
  session.pushRepoChanges(changes);
230
257
  },
231
258
  onFetchHeadChanged: function (repoPath: string): void {
232
- watchHooks?.onFetchHeadChanged?.(repoPath);
259
+ // Iterate at fire time so callers that joined after the group was wired up
260
+ // still receive events (e.g. a `Repository.watch()` whose hooks landed
261
+ // after a hookless `GitRepositoryService.watch` registered first).
262
+ for (const h of watchHooks) {
263
+ h.onFetchHeadChanged?.(repoPath);
264
+ }
233
265
  },
234
266
  onIgnoresChanged: (repoPath: string): void => {
235
267
  this.refreshWorkingTreeFilter(repoPath);
236
- watchHooks?.onIgnoresChanged?.(repoPath);
268
+ for (const h of watchHooks) {
269
+ h.onIgnoresChanged?.(repoPath);
270
+ }
237
271
  },
238
272
  };
239
273
 
@@ -293,7 +327,10 @@ export class RepositoryWatchService implements UnifiedDisposable {
293
327
  if (filter != null) {
294
328
  void filter.refresh();
295
329
  }
296
- watchHooks?.onGitIgnoreChanged?.(repoPath);
330
+ // See `connectToWatchGroup` for the iterate-at-fire-time rationale.
331
+ for (const h of watchHooks) {
332
+ h.onGitIgnoreChanged?.(repoPath);
333
+ }
297
334
  // Don't push .gitignore itself as a working tree change
298
335
  return;
299
336
  }
@@ -341,6 +378,7 @@ function filterWorkingTreePaths(absolutePaths: string[], repoPath: string, filte
341
378
  const result: string[] = [];
342
379
  for (const p of absolutePaths) {
343
380
  if (!isDescendant(p, repoPath)) continue;
381
+
344
382
  const relativePath = relative(repoPath, p);
345
383
  if (!filter.isIgnored(relativePath)) {
346
384
  result.push(p);
@@ -37,6 +37,8 @@ export interface WatchSessionOptions {
37
37
  /** Default debounce for working tree changes. Default: 2500ms */
38
38
  readonly defaultWorkingTreeDelayMs?: number;
39
39
  readonly lifecycle?: WatchSessionLifecycle;
40
+ /** Initial suspended state — new sessions inherit the service-global suspend state. Default: false */
41
+ readonly suspended?: boolean;
40
42
  /**
41
43
  * Called whenever a debounced repo change event is dispatched to subscribers.
42
44
  * Does NOT count as a subscriber — used by WatchService for
@@ -66,16 +68,16 @@ export class RepositoryWatchSession implements UnifiedDisposable {
66
68
  private effectiveRepoMs: number;
67
69
  private readonly defaultRepoMs: number;
68
70
 
69
- private readonly wtEmitter = new Emitter<WorkingTreeChangeEvent>();
70
- private readonly wtDelays = new Map<number, number>();
71
- private wtNextId = 0;
72
- private pendingWTPaths = new Set<string>();
73
- private wtTimer: ReturnType<typeof setTimeout> | undefined;
74
- private effectiveWTMs: number;
75
- private readonly defaultWTMs: number;
71
+ private readonly workingTreeEmitter = new Emitter<WorkingTreeChangeEvent>();
72
+ private readonly workingTreeDelays = new Map<number, number>();
73
+ private workingTreeNextId = 0;
74
+ private pendingWorkingTreePaths = new Set<string>();
75
+ private workingTreeTimer: ReturnType<typeof setTimeout> | undefined;
76
+ private effectiveWorkingTreeMs: number;
77
+ private readonly defaultWorkingTreeMs: number;
76
78
 
77
79
  private _etagWorkingTree = 0;
78
- private _suspended = false;
80
+ private _suspended: boolean;
79
81
  private _disposed = false;
80
82
 
81
83
  private readonly lifecycle?: WatchSessionLifecycle;
@@ -84,11 +86,12 @@ export class RepositoryWatchSession implements UnifiedDisposable {
84
86
  constructor(options: WatchSessionOptions) {
85
87
  this.repoPath = options.repoPath;
86
88
  this.defaultRepoMs = options.defaultRepoDelayMs ?? defaultRepoDelay;
87
- this.defaultWTMs = options.defaultWorkingTreeDelayMs ?? defaultWorkingTreeDelay;
89
+ this.defaultWorkingTreeMs = options.defaultWorkingTreeDelayMs ?? defaultWorkingTreeDelay;
88
90
  this.effectiveRepoMs = this.defaultRepoMs;
89
- this.effectiveWTMs = this.defaultWTMs;
91
+ this.effectiveWorkingTreeMs = this.defaultWorkingTreeMs;
90
92
  this.lifecycle = options.lifecycle;
91
93
  this.onDidFireRepoChangeCallback = options.onDidFireRepoChange;
94
+ this._suspended = options.suspended ?? false;
92
95
  }
93
96
 
94
97
  [Symbol.dispose](): void {
@@ -97,18 +100,19 @@ export class RepositoryWatchSession implements UnifiedDisposable {
97
100
 
98
101
  dispose(): void {
99
102
  if (this._disposed) return;
103
+
100
104
  this._disposed = true;
101
105
 
102
106
  this.cancelRepoTimer();
103
- this.cancelWTTimer();
107
+ this.cancelWorkingTreeTimer();
104
108
 
105
109
  this.pendingRepoEvent = undefined;
106
- this.pendingWTPaths.clear();
110
+ this.pendingWorkingTreePaths.clear();
107
111
  this.repoDelays.clear();
108
- this.wtDelays.clear();
112
+ this.workingTreeDelays.clear();
109
113
 
110
114
  this.repoEmitter.dispose();
111
- this.wtEmitter.dispose();
115
+ this.workingTreeEmitter.dispose();
112
116
  }
113
117
 
114
118
  get suspended(): boolean {
@@ -116,7 +120,7 @@ export class RepositoryWatchSession implements UnifiedDisposable {
116
120
  }
117
121
 
118
122
  get hasPendingChanges(): boolean {
119
- return this.pendingRepoEvent != null || this.pendingWTPaths.size > 0;
123
+ return this.pendingRepoEvent != null || this.pendingWorkingTreePaths.size > 0;
120
124
  }
121
125
 
122
126
  get repoSubscriberCount(): number {
@@ -124,7 +128,7 @@ export class RepositoryWatchSession implements UnifiedDisposable {
124
128
  }
125
129
 
126
130
  get workingTreeSubscriberCount(): number {
127
- return this.wtDelays.size;
131
+ return this.workingTreeDelays.size;
128
132
  }
129
133
 
130
134
  /**
@@ -175,6 +179,7 @@ export class RepositoryWatchSession implements UnifiedDisposable {
175
179
  return Object.assign(
176
180
  createDisposable(() => {
177
181
  if (subDisposed) return;
182
+
178
183
  subDisposed = true;
179
184
 
180
185
  this.repoDelays.delete(id);
@@ -195,44 +200,45 @@ export class RepositoryWatchSession implements UnifiedDisposable {
195
200
  return Object.assign(
196
201
  createDisposable(() => {}),
197
202
  {
198
- onDidChangeWorkingTree: this.wtEmitter.event,
203
+ onDidChangeWorkingTree: this.workingTreeEmitter.event,
199
204
  },
200
205
  );
201
206
  }
202
207
 
203
- const id = this.wtNextId++;
204
- const delay = opts?.delayMs ?? this.defaultWTMs;
205
- const wasEmpty = this.wtDelays.size === 0;
206
- const prevDelay = this.effectiveWTMs;
208
+ const id = this.workingTreeNextId++;
209
+ const delay = opts?.delayMs ?? this.defaultWorkingTreeMs;
210
+ const wasEmpty = this.workingTreeDelays.size === 0;
211
+ const prevDelay = this.effectiveWorkingTreeMs;
207
212
 
208
- this.wtDelays.set(id, delay);
209
- this.recalcWTDelay();
213
+ this.workingTreeDelays.set(id, delay);
214
+ this.recalcWorkingTreeDelay();
210
215
 
211
216
  if (wasEmpty) {
212
217
  this.lifecycle?.onFirstWorkingTreeSubscriber?.();
213
218
  }
214
219
 
215
220
  // If the effective delay got shorter while a timer is running, reschedule sooner
216
- if (this.effectiveWTMs < prevDelay && this.wtTimer != null) {
217
- this.scheduleWTFlush();
221
+ if (this.effectiveWorkingTreeMs < prevDelay && this.workingTreeTimer != null) {
222
+ this.scheduleWorkingTreeFlush();
218
223
  }
219
224
 
220
225
  let subDisposed = false;
221
226
  return Object.assign(
222
227
  createDisposable(() => {
223
228
  if (subDisposed) return;
229
+
224
230
  subDisposed = true;
225
231
 
226
- this.wtDelays.delete(id);
227
- this.recalcWTDelay();
232
+ this.workingTreeDelays.delete(id);
233
+ this.recalcWorkingTreeDelay();
228
234
 
229
- if (this.wtDelays.size === 0) {
230
- this.cancelWTTimer();
231
- this.pendingWTPaths.clear();
235
+ if (this.workingTreeDelays.size === 0) {
236
+ this.cancelWorkingTreeTimer();
237
+ this.pendingWorkingTreePaths.clear();
232
238
  this.lifecycle?.onLastWorkingTreeSubscriber?.();
233
239
  }
234
240
  }),
235
- { onDidChangeWorkingTree: this.wtEmitter.event },
241
+ { onDidChangeWorkingTree: this.workingTreeEmitter.event },
236
242
  );
237
243
  }
238
244
 
@@ -240,49 +246,55 @@ export class RepositoryWatchSession implements UnifiedDisposable {
240
246
  this._suspended = true;
241
247
  // Cancel active timers — events continue to coalesce but don't fire
242
248
  this.cancelRepoTimer();
243
- this.cancelWTTimer();
249
+ this.cancelWorkingTreeTimer();
244
250
  }
245
251
 
246
252
  resume(delayMs?: number): void {
247
253
  if (!this._suspended) return;
254
+
248
255
  this._suspended = false;
249
256
 
250
257
  // Flush accumulated changes
251
258
  if (this.pendingRepoEvent != null) {
252
259
  this.scheduleRepoFlush(delayMs);
253
260
  }
254
- if (this.pendingWTPaths.size > 0) {
255
- this.scheduleWTFlush(delayMs);
261
+ if (this.pendingWorkingTreePaths.size > 0) {
262
+ this.scheduleWorkingTreeFlush(delayMs);
256
263
  }
257
264
  }
258
265
 
259
266
  /** Inject changes (e.g., after a git operation the caller performed). Goes through debounce + suspend. */
260
267
  fireChange(...changes: RepositoryChange[]): void {
261
268
  if (this._disposed || changes.length === 0) return;
269
+
262
270
  this.coalesceRepo(changes);
263
271
  }
264
272
 
265
273
  /** Immediate fire, bypassing debounce + suspend (for Closed/Opened). */
266
274
  fireChangeImmediate(...changes: RepositoryChange[]): void {
267
275
  if (this._disposed || changes.length === 0) return;
276
+
268
277
  this.repoEmitter.fire(new WatcherRepoChangeEvent(this.repoPath, changes));
269
278
  }
270
279
 
271
280
  /** Push interpreted repo changes into the pipeline */
272
281
  pushRepoChanges(changes: RepositoryChange[]): void {
273
282
  if (this._disposed) return;
283
+
274
284
  this.coalesceRepo(changes);
275
285
  }
276
286
 
277
287
  /** Push working tree file changes into the pipeline */
278
288
  pushWorkingTreeChanges(paths: Iterable<string>): void {
279
289
  if (this._disposed) return;
290
+
280
291
  this._etagWorkingTree++;
281
- this.coalesceWT(paths);
292
+ this.coalesceWorkingTrees(paths);
282
293
  }
283
294
 
284
295
  private static minDelay(delays: Map<number, number>, fallback: number): number {
285
296
  if (delays.size === 0) return fallback;
297
+
286
298
  let min = fallback;
287
299
  for (const d of delays.values()) {
288
300
  if (d < min) {
@@ -296,14 +308,18 @@ export class RepositoryWatchSession implements UnifiedDisposable {
296
308
  this.effectiveRepoMs = RepositoryWatchSession.minDelay(this.repoDelays, this.defaultRepoMs);
297
309
  }
298
310
 
299
- private recalcWTDelay(): void {
300
- this.effectiveWTMs = RepositoryWatchSession.minDelay(this.wtDelays, this.defaultWTMs);
311
+ private recalcWorkingTreeDelay(): void {
312
+ this.effectiveWorkingTreeMs = RepositoryWatchSession.minDelay(
313
+ this.workingTreeDelays,
314
+ this.defaultWorkingTreeMs,
315
+ );
301
316
  }
302
317
 
303
318
  private flushRepo(): void {
304
319
  this.repoTimer = undefined;
305
320
  const event = this.pendingRepoEvent;
306
321
  if (event == null) return;
322
+
307
323
  this.pendingRepoEvent = undefined;
308
324
  this.repoEmitter.fire(event);
309
325
  this.onDidFireRepoChangeCallback?.(event);
@@ -329,29 +345,29 @@ export class RepositoryWatchSession implements UnifiedDisposable {
329
345
  this.scheduleRepoFlush();
330
346
  }
331
347
 
332
- private flushWT(): void {
333
- this.wtTimer = undefined;
334
- if (this.pendingWTPaths.size === 0) return;
348
+ private flushWorkingTree(): void {
349
+ this.workingTreeTimer = undefined;
350
+ if (this.pendingWorkingTreePaths.size === 0) return;
335
351
 
336
- const paths = this.pendingWTPaths;
337
- this.pendingWTPaths = new Set();
338
- this.wtEmitter.fire({ repoPath: this.repoPath, paths: paths });
352
+ const paths = this.pendingWorkingTreePaths;
353
+ this.pendingWorkingTreePaths = new Set();
354
+ this.workingTreeEmitter.fire({ repoPath: this.repoPath, paths: paths });
339
355
  }
340
356
 
341
- private scheduleWTFlush(delayOverride?: number): void {
342
- if (this._suspended || this.pendingWTPaths.size === 0) return;
357
+ private scheduleWorkingTreeFlush(delayOverride?: number): void {
358
+ if (this._suspended || this.pendingWorkingTreePaths.size === 0) return;
343
359
 
344
- if (this.wtTimer != null) {
345
- clearTimeout(this.wtTimer);
360
+ if (this.workingTreeTimer != null) {
361
+ clearTimeout(this.workingTreeTimer);
346
362
  }
347
- this.wtTimer = setTimeout(() => this.flushWT(), delayOverride ?? this.effectiveWTMs);
363
+ this.workingTreeTimer = setTimeout(() => this.flushWorkingTree(), delayOverride ?? this.effectiveWorkingTreeMs);
348
364
  }
349
365
 
350
- private coalesceWT(paths: Iterable<string>): void {
366
+ private coalesceWorkingTrees(paths: Iterable<string>): void {
351
367
  for (const p of paths) {
352
- this.pendingWTPaths.add(p);
368
+ this.pendingWorkingTreePaths.add(p);
353
369
  }
354
- this.scheduleWTFlush();
370
+ this.scheduleWorkingTreeFlush();
355
371
  }
356
372
 
357
373
  private cancelRepoTimer(): void {
@@ -361,10 +377,10 @@ export class RepositoryWatchSession implements UnifiedDisposable {
361
377
  }
362
378
  }
363
379
 
364
- private cancelWTTimer(): void {
365
- if (this.wtTimer != null) {
366
- clearTimeout(this.wtTimer);
367
- this.wtTimer = undefined;
380
+ private cancelWorkingTreeTimer(): void {
381
+ if (this.workingTreeTimer != null) {
382
+ clearTimeout(this.workingTreeTimer);
383
+ this.workingTreeTimer = undefined;
368
384
  }
369
385
  }
370
386
  }
@@ -1,8 +1,8 @@
1
1
  export type {
2
2
  GitCommandPriority,
3
3
  GitErrorHandling,
4
- GitExecOptions,
4
+ GitRunOptions,
5
5
  GitResult,
6
6
  GitResultCache,
7
7
  GitSpawnOptions,
8
- } from '../../git/exec.types.js';
8
+ } from '../../git/run.types.js';
@@ -39,7 +39,7 @@ import { compare, fromString } from '../../utils/version.js';
39
39
  import { CancelledRunError, RunError } from './exec.errors.js';
40
40
  import type { RunOptions, RunResult } from './exec.js';
41
41
  import { fsExists, runSpawn } from './exec.js';
42
- import type { GitCommandPriority, GitExecOptions, GitResult, GitSpawnOptions } from './exec.types.js';
42
+ import type { GitCommandPriority, GitResult, GitRunOptions, GitSpawnOptions } from './exec.types.js';
43
43
  import type { FilteredGitFeatures, GitFeatureOrPrefix, GitFeatures } from './features.js';
44
44
  import { gitFeaturesByVersion } from './features.js';
45
45
  import type { GitQueueConfig } from './gitQueue.js';
@@ -508,7 +508,7 @@ const trailingNewlineRegex = /[\r|\n]+$/;
508
508
  const uniqueCounterForStdin = getScopedCounter();
509
509
  const uniqueCounterForStream = getScopedCounter();
510
510
 
511
- type ExitCodeOnlyGitCommandOptions = GitExecOptions & { exitCodeOnly: true };
511
+ type ExitCodeOnlyGitCommandOptions = GitRunOptions & { exitCodeOnly: true };
512
512
 
513
513
  export class Git {
514
514
  /** Map of running git commands — avoids running duplicate overlapping commands */
@@ -636,11 +636,11 @@ export class Git {
636
636
  ...args: readonly (string | undefined)[]
637
637
  ): Promise<GitResult<unknown>>;
638
638
  async run<T extends string | Buffer = string>(
639
- options: GitExecOptions,
639
+ options: GitRunOptions,
640
640
  ...args: readonly (string | undefined)[]
641
641
  ): Promise<GitResult<T>>;
642
642
  async run<T extends string | Buffer = string>(
643
- options: GitExecOptions,
643
+ options: GitRunOptions,
644
644
  ...args: readonly (string | undefined)[]
645
645
  ): Promise<GitResult<T | unknown>> {
646
646
  if (this.options.isTrusted?.() === false) throw new WorkspaceUntrustedError();
@@ -668,7 +668,7 @@ export class Git {
668
668
  }
669
669
 
670
670
  private async runCore<T extends string | Buffer>(
671
- options: GitExecOptions,
671
+ options: GitRunOptions,
672
672
  args: string[],
673
673
  gitCommand: string,
674
674
  ): Promise<GitResult<T | unknown>> {
@@ -906,6 +906,7 @@ export class Git {
906
906
  let cleanedUp = false;
907
907
  const cleanup = () => {
908
908
  if (cleanedUp) return;
909
+
909
910
  cleanedUp = true;
910
911
 
911
912
  try {
@@ -261,33 +261,62 @@ export class GitQueue {
261
261
  }
262
262
 
263
263
  /**
264
- * Infers priority from git command type.
265
- * Only downgrades to 'background' for expensive commands; never upgrades to 'interactive'.
264
+ * Git global options that consume the next positional arg as their value
265
+ * (e.g. `--work-tree <path>`). Long-form `--name=value` is already skipped by
266
+ * the leading-dash check, so only the separated form needs explicit handling.
267
+ */
268
+ const optionsTakingValue = new Set([
269
+ '-c',
270
+ '-C',
271
+ '--git-dir',
272
+ '--work-tree',
273
+ '--namespace',
274
+ '--exec-path',
275
+ '--super-prefix',
276
+ '--config-env',
277
+ '--attr-source',
278
+ '--list-cmds',
279
+ ]);
280
+
281
+ /**
282
+ * Infers a queue priority from the git command being invoked.
283
+ *
284
+ * Intentionally narrow: only returns 'background' for commands that are
285
+ * *always* read-only AND *always* potentially expensive. Polymorphic commands
286
+ * like `log` and `rev-list` (which can be quick bounded lookups or full-history
287
+ * walks) are deliberately omitted — call sites that perform heavy walks must
288
+ * pass `priority: 'background'` explicitly. Never upgrades to 'interactive'.
289
+ *
290
+ * No subcommand awareness (e.g. `stash list`, `branch -l`): the risk of
291
+ * misclassifying a write subcommand as background outweighs the gain.
266
292
  */
267
293
  export function inferGitCommandPriority(args: readonly (string | undefined)[]): GitCommandPriority {
268
- let skip = false;
269
294
  let command: string | undefined;
270
- for (const a of args) {
295
+ for (let i = 0; i < args.length; i++) {
296
+ const a = args[i];
271
297
  if (a == null) continue;
272
- if (skip) {
273
- skip = false;
274
- continue;
275
- }
276
- if (a === '-c' || a === '-C') {
277
- skip = true;
298
+ if (optionsTakingValue.has(a)) {
299
+ const next = args[i + 1];
300
+ if (next != null && !next.startsWith('-')) {
301
+ i++;
302
+ }
278
303
  continue;
279
304
  }
280
305
  if (a.startsWith('-')) continue;
306
+
281
307
  command = a;
282
308
  break;
283
309
  }
284
310
 
285
311
  switch (command) {
286
- case 'log':
287
- case 'rev-list':
288
312
  case 'for-each-ref':
289
313
  case 'shortlog':
290
314
  case 'reflog':
315
+ case 'name-rev':
316
+ case 'describe':
317
+ case 'cherry':
318
+ case 'count-objects':
319
+ case 'fsck':
291
320
  return 'background';
292
321
  default:
293
322
  return 'normal';
@@ -342,6 +342,7 @@ export async function* parseGitBlameAsync(stream: AsyncIterable<string>): AsyncG
342
342
  case 0x66 /* f — filename */:
343
343
  entry.path = line.substring(valueStart);
344
344
  yield entry;
345
+
345
346
  entry = undefined;
346
347
  break;
347
348
 
@@ -420,6 +420,7 @@ function createLogParserWithFilesAndStats<T extends Record<string, string> | voi
420
420
 
421
421
  endIndex = line.indexOf(' ', startIndex);
422
422
  if (endIndex === -1) continue;
423
+
423
424
  const newMode = line.substring(startIndex, endIndex);
424
425
 
425
426
  // Parse old_sha and new_sha positions