@gitkraken/core-gitlens 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (451) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/dist/git/cache.d.ts +49 -9
  3. package/dist/git/cache.d.ts.map +1 -1
  4. package/dist/git/cache.js +174 -14
  5. package/dist/git/cache.js.map +1 -1
  6. package/dist/git/context.d.ts +11 -2
  7. package/dist/git/context.d.ts.map +1 -1
  8. package/dist/git/context.js.map +1 -1
  9. package/dist/git/models/branch.d.ts +1 -0
  10. package/dist/git/models/branch.d.ts.map +1 -1
  11. package/dist/git/models/branch.js.map +1 -1
  12. package/dist/git/models/commit.d.ts +1 -9
  13. package/dist/git/models/commit.d.ts.map +1 -1
  14. package/dist/git/models/commit.js +4 -9
  15. package/dist/git/models/commit.js.map +1 -1
  16. package/dist/git/models/graph.d.ts +2 -4
  17. package/dist/git/models/graph.d.ts.map +1 -1
  18. package/dist/git/models/reference.d.ts +31 -0
  19. package/dist/git/models/reference.d.ts.map +1 -1
  20. package/dist/git/models/remote.d.ts.map +1 -1
  21. package/dist/git/models/remote.js.map +1 -1
  22. package/dist/git/models/repository.d.ts +20 -3
  23. package/dist/git/models/repository.d.ts.map +1 -1
  24. package/dist/git/models/repository.js +42 -5
  25. package/dist/git/models/repository.js.map +1 -1
  26. package/dist/git/models/search.d.ts +2 -2
  27. package/dist/git/models/search.d.ts.map +1 -1
  28. package/dist/git/models/worktree.d.ts +4 -1
  29. package/dist/git/models/worktree.d.ts.map +1 -1
  30. package/dist/git/models/worktree.js +2 -2
  31. package/dist/git/models/worktree.js.map +1 -1
  32. package/dist/git/parsers/diffParser.d.ts +0 -1
  33. package/dist/git/parsers/diffParser.d.ts.map +1 -1
  34. package/dist/git/parsers/diffParser.js +22 -61
  35. package/dist/git/parsers/diffParser.js.map +1 -1
  36. package/dist/git/providers/branches.d.ts +18 -4
  37. package/dist/git/providers/branches.d.ts.map +1 -1
  38. package/dist/git/providers/commits.d.ts +6 -0
  39. package/dist/git/providers/commits.d.ts.map +1 -1
  40. package/dist/git/providers/config.d.ts +6 -1
  41. package/dist/git/providers/config.d.ts.map +1 -1
  42. package/dist/git/providers/diff.d.ts +2 -0
  43. package/dist/git/providers/diff.d.ts.map +1 -1
  44. package/dist/git/providers/operations.d.ts +39 -10
  45. package/dist/git/providers/operations.d.ts.map +1 -1
  46. package/dist/git/providers/pausedOperations.d.ts +3 -1
  47. package/dist/git/providers/pausedOperations.d.ts.map +1 -1
  48. package/dist/git/providers/refs.d.ts +23 -2
  49. package/dist/git/providers/refs.d.ts.map +1 -1
  50. package/dist/git/providers/revision.d.ts +1 -1
  51. package/dist/git/providers/revision.d.ts.map +1 -1
  52. package/dist/git/providers/staging.d.ts +18 -0
  53. package/dist/git/providers/staging.d.ts.map +1 -1
  54. package/dist/git/providers/status.d.ts +4 -1
  55. package/dist/git/providers/status.d.ts.map +1 -1
  56. package/dist/git/remotes/azure-devops.d.ts.map +1 -1
  57. package/dist/git/remotes/azure-devops.js.map +1 -1
  58. package/dist/git/{exec.types.d.ts → run.types.d.ts} +22 -3
  59. package/dist/git/run.types.d.ts.map +1 -0
  60. package/dist/git/run.types.js +2 -0
  61. package/dist/git/run.types.js.map +1 -0
  62. package/dist/git/service.d.ts.map +1 -1
  63. package/dist/git/service.js.map +1 -1
  64. package/dist/git/utils/autolink.utils.d.ts.map +1 -1
  65. package/dist/git/utils/autolink.utils.js.map +1 -1
  66. package/dist/git/utils/blame.utils.d.ts.map +1 -1
  67. package/dist/git/utils/blame.utils.js.map +1 -1
  68. package/dist/git/utils/conflictResolution.utils.d.ts +6 -0
  69. package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -0
  70. package/dist/git/utils/conflictResolution.utils.js +25 -0
  71. package/dist/git/utils/conflictResolution.utils.js.map +1 -0
  72. package/dist/git/utils/fileStatus.utils.d.ts +2 -1
  73. package/dist/git/utils/fileStatus.utils.d.ts.map +1 -1
  74. package/dist/git/utils/fileStatus.utils.js +4 -0
  75. package/dist/git/utils/fileStatus.utils.js.map +1 -1
  76. package/dist/git/utils/search.utils.d.ts.map +1 -1
  77. package/dist/git/utils/search.utils.js +3 -0
  78. package/dist/git/utils/search.utils.js.map +1 -1
  79. package/dist/git/utils/sorting.d.ts +14 -0
  80. package/dist/git/utils/sorting.d.ts.map +1 -1
  81. package/dist/git/utils/sorting.js +34 -0
  82. package/dist/git/utils/sorting.js.map +1 -1
  83. package/dist/git/utils/status.utils.d.ts.map +1 -1
  84. package/dist/git/utils/status.utils.js.map +1 -1
  85. package/dist/git/watching/classifyChange.d.ts.map +1 -1
  86. package/dist/git/watching/classifyChange.js +8 -0
  87. package/dist/git/watching/classifyChange.js.map +1 -1
  88. package/dist/git/watching/gitIgnoreFilter.js +1 -1
  89. package/dist/git/watching/gitIgnoreFilter.js.map +1 -1
  90. package/dist/git/watching/initWatcher.d.ts.map +1 -1
  91. package/dist/git/watching/initWatcher.js.map +1 -1
  92. package/dist/git/watching/watchGroup.d.ts.map +1 -1
  93. package/dist/git/watching/watchGroup.js.map +1 -1
  94. package/dist/git/watching/watchService.d.ts.map +1 -1
  95. package/dist/git/watching/watchService.js +24 -4
  96. package/dist/git/watching/watchService.js.map +1 -1
  97. package/dist/git/watching/watchSession.d.ts.map +1 -1
  98. package/dist/git/watching/watchSession.js.map +1 -1
  99. package/dist/git-cli/cliGitProvider.js +1 -1
  100. package/dist/git-cli/cliGitProvider.js.map +1 -1
  101. package/dist/git-cli/exec/exec.types.d.ts +1 -1
  102. package/dist/git-cli/exec/exec.types.d.ts.map +1 -1
  103. package/dist/git-cli/exec/git.d.ts +31 -6
  104. package/dist/git-cli/exec/git.d.ts.map +1 -1
  105. package/dist/git-cli/exec/git.js +70 -9
  106. package/dist/git-cli/exec/git.js.map +1 -1
  107. package/dist/git-cli/exec/gitQueue.d.ts +22 -6
  108. package/dist/git-cli/exec/gitQueue.d.ts.map +1 -1
  109. package/dist/git-cli/exec/gitQueue.js +88 -24
  110. package/dist/git-cli/exec/gitQueue.js.map +1 -1
  111. package/dist/git-cli/parsers/blameParser.d.ts.map +1 -1
  112. package/dist/git-cli/parsers/blameParser.js.map +1 -1
  113. package/dist/git-cli/parsers/logParser.d.ts +1 -0
  114. package/dist/git-cli/parsers/logParser.d.ts.map +1 -1
  115. package/dist/git-cli/parsers/logParser.js +4 -0
  116. package/dist/git-cli/parsers/logParser.js.map +1 -1
  117. package/dist/git-cli/parsers/refParser.d.ts +3 -30
  118. package/dist/git-cli/parsers/refParser.d.ts.map +1 -1
  119. package/dist/git-cli/parsers/refParser.js +30 -30
  120. package/dist/git-cli/parsers/refParser.js.map +1 -1
  121. package/dist/git-cli/providers/blame.d.ts.map +1 -1
  122. package/dist/git-cli/providers/blame.js +1 -1
  123. package/dist/git-cli/providers/blame.js.map +1 -1
  124. package/dist/git-cli/providers/branches.d.ts +17 -5
  125. package/dist/git-cli/providers/branches.d.ts.map +1 -1
  126. package/dist/git-cli/providers/branches.js +245 -162
  127. package/dist/git-cli/providers/branches.js.map +1 -1
  128. package/dist/git-cli/providers/commits.d.ts +4 -0
  129. package/dist/git-cli/providers/commits.d.ts.map +1 -1
  130. package/dist/git-cli/providers/commits.js +120 -35
  131. package/dist/git-cli/providers/commits.js.map +1 -1
  132. package/dist/git-cli/providers/config.d.ts +11 -2
  133. package/dist/git-cli/providers/config.d.ts.map +1 -1
  134. package/dist/git-cli/providers/config.js +36 -11
  135. package/dist/git-cli/providers/config.js.map +1 -1
  136. package/dist/git-cli/providers/contributors.d.ts.map +1 -1
  137. package/dist/git-cli/providers/contributors.js +7 -4
  138. package/dist/git-cli/providers/contributors.js.map +1 -1
  139. package/dist/git-cli/providers/diff.d.ts +2 -0
  140. package/dist/git-cli/providers/diff.d.ts.map +1 -1
  141. package/dist/git-cli/providers/diff.js +92 -20
  142. package/dist/git-cli/providers/diff.js.map +1 -1
  143. package/dist/git-cli/providers/graph.d.ts.map +1 -1
  144. package/dist/git-cli/providers/graph.js +49 -28
  145. package/dist/git-cli/providers/graph.js.map +1 -1
  146. package/dist/git-cli/providers/operations.d.ts +30 -11
  147. package/dist/git-cli/providers/operations.d.ts.map +1 -1
  148. package/dist/git-cli/providers/operations.js +146 -43
  149. package/dist/git-cli/providers/operations.js.map +1 -1
  150. package/dist/git-cli/providers/patch.d.ts.map +1 -1
  151. package/dist/git-cli/providers/patch.js +15 -30
  152. package/dist/git-cli/providers/patch.js.map +1 -1
  153. package/dist/git-cli/providers/pausedOperations.d.ts +3 -1
  154. package/dist/git-cli/providers/pausedOperations.d.ts.map +1 -1
  155. package/dist/git-cli/providers/pausedOperations.js +13 -7
  156. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  157. package/dist/git-cli/providers/refs.d.ts +19 -2
  158. package/dist/git-cli/providers/refs.d.ts.map +1 -1
  159. package/dist/git-cli/providers/refs.js +312 -9
  160. package/dist/git-cli/providers/refs.js.map +1 -1
  161. package/dist/git-cli/providers/remotes.js +4 -4
  162. package/dist/git-cli/providers/remotes.js.map +1 -1
  163. package/dist/git-cli/providers/revision.d.ts +1 -1
  164. package/dist/git-cli/providers/revision.d.ts.map +1 -1
  165. package/dist/git-cli/providers/revision.js +15 -11
  166. package/dist/git-cli/providers/revision.js.map +1 -1
  167. package/dist/git-cli/providers/staging.d.ts +8 -0
  168. package/dist/git-cli/providers/staging.d.ts.map +1 -1
  169. package/dist/git-cli/providers/staging.js +52 -8
  170. package/dist/git-cli/providers/staging.js.map +1 -1
  171. package/dist/git-cli/providers/stash.d.ts +0 -8
  172. package/dist/git-cli/providers/stash.d.ts.map +1 -1
  173. package/dist/git-cli/providers/stash.js +63 -119
  174. package/dist/git-cli/providers/stash.js.map +1 -1
  175. package/dist/git-cli/providers/status.d.ts +4 -1
  176. package/dist/git-cli/providers/status.d.ts.map +1 -1
  177. package/dist/git-cli/providers/status.js +10 -9
  178. package/dist/git-cli/providers/status.js.map +1 -1
  179. package/dist/git-cli/providers/tags.d.ts.map +1 -1
  180. package/dist/git-cli/providers/tags.js +13 -9
  181. package/dist/git-cli/providers/tags.js.map +1 -1
  182. package/dist/git-cli/providers/worktrees.js +3 -3
  183. package/dist/git-cli/providers/worktrees.js.map +1 -1
  184. package/dist/ipc/discovery.d.ts +27 -0
  185. package/dist/ipc/discovery.d.ts.map +1 -0
  186. package/dist/ipc/discovery.js +38 -0
  187. package/dist/ipc/discovery.js.map +1 -0
  188. package/dist/ipc/ipcServer.d.ts +20 -0
  189. package/dist/ipc/ipcServer.d.ts.map +1 -0
  190. package/dist/ipc/ipcServer.js +162 -0
  191. package/dist/ipc/ipcServer.js.map +1 -0
  192. package/dist/plus/agents/providers/claudeCodeProvider.d.ts +114 -0
  193. package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -0
  194. package/dist/plus/agents/providers/claudeCodeProvider.js +1480 -0
  195. package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -0
  196. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts +36 -0
  197. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts.map +1 -0
  198. package/dist/plus/agents/providers/claudeCodeTranscript.js +171 -0
  199. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -0
  200. package/dist/plus/agents/sanitizePrompt.d.ts +15 -0
  201. package/dist/plus/agents/sanitizePrompt.d.ts.map +1 -0
  202. package/dist/plus/agents/sanitizePrompt.js +103 -0
  203. package/dist/plus/agents/sanitizePrompt.js.map +1 -0
  204. package/dist/plus/agents/stateMachine.d.ts +32 -0
  205. package/dist/plus/agents/stateMachine.d.ts.map +1 -0
  206. package/dist/plus/agents/stateMachine.js +180 -0
  207. package/dist/plus/agents/stateMachine.js.map +1 -0
  208. package/dist/plus/agents/types.d.ts +203 -0
  209. package/dist/plus/agents/types.d.ts.map +1 -0
  210. package/dist/plus/agents/types.js +49 -0
  211. package/dist/plus/agents/types.js.map +1 -0
  212. package/dist/plus/ai/constants.d.ts +2 -1
  213. package/dist/plus/ai/constants.d.ts.map +1 -1
  214. package/dist/plus/ai/constants.js +7 -0
  215. package/dist/plus/ai/constants.js.map +1 -1
  216. package/dist/plus/ai/errors.d.ts +4 -1
  217. package/dist/plus/ai/errors.d.ts.map +1 -1
  218. package/dist/plus/ai/errors.js +38 -0
  219. package/dist/plus/ai/errors.js.map +1 -1
  220. package/dist/plus/ai/models/model.d.ts +1 -1
  221. package/dist/plus/ai/models/model.d.ts.map +1 -1
  222. package/dist/plus/ai/models/model.js.map +1 -1
  223. package/dist/plus/ai/models/promptTemplates.d.ts +28 -2
  224. package/dist/plus/ai/models/promptTemplates.d.ts.map +1 -1
  225. package/dist/plus/ai/models/results.d.ts +28 -0
  226. package/dist/plus/ai/models/results.d.ts.map +1 -1
  227. package/dist/plus/ai/prompts.d.ts +4 -0
  228. package/dist/plus/ai/prompts.d.ts.map +1 -1
  229. package/dist/plus/ai/prompts.js +167 -1
  230. package/dist/plus/ai/prompts.js.map +1 -1
  231. package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
  232. package/dist/plus/ai/utils/ai.utils.js +2 -0
  233. package/dist/plus/ai/utils/ai.utils.js.map +1 -1
  234. package/dist/plus/ai/utils/results.utils.d.ts +3 -0
  235. package/dist/plus/ai/utils/results.utils.d.ts.map +1 -1
  236. package/dist/plus/ai/utils/results.utils.js +75 -0
  237. package/dist/plus/ai/utils/results.utils.js.map +1 -1
  238. package/dist/plus/ai/utils/truncation.utils.d.ts +1 -1
  239. package/dist/plus/ai/utils/truncation.utils.d.ts.map +1 -1
  240. package/dist/plus/ai/utils/truncation.utils.js.map +1 -1
  241. package/dist/plus/git-github/api/github.d.ts +10 -1
  242. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  243. package/dist/plus/git-github/api/github.js +156 -49
  244. package/dist/plus/git-github/api/github.js.map +1 -1
  245. package/dist/plus/git-github/api/types.d.ts +8 -0
  246. package/dist/plus/git-github/api/types.d.ts.map +1 -1
  247. package/dist/plus/git-github/models.d.ts +1 -1
  248. package/dist/plus/git-github/models.d.ts.map +1 -1
  249. package/dist/plus/git-github/models.js.map +1 -1
  250. package/dist/plus/git-github/providers/github/blame.d.ts.map +1 -1
  251. package/dist/plus/git-github/providers/github/blame.js.map +1 -1
  252. package/dist/plus/git-github/providers/github/branches.d.ts +5 -1
  253. package/dist/plus/git-github/providers/github/branches.d.ts.map +1 -1
  254. package/dist/plus/git-github/providers/github/branches.js +60 -22
  255. package/dist/plus/git-github/providers/github/branches.js.map +1 -1
  256. package/dist/plus/git-github/providers/github/commits.d.ts.map +1 -1
  257. package/dist/plus/git-github/providers/github/commits.js +144 -92
  258. package/dist/plus/git-github/providers/github/commits.js.map +1 -1
  259. package/dist/plus/git-github/providers/github/diff.d.ts +3 -1
  260. package/dist/plus/git-github/providers/github/diff.d.ts.map +1 -1
  261. package/dist/plus/git-github/providers/github/diff.js +23 -9
  262. package/dist/plus/git-github/providers/github/diff.js.map +1 -1
  263. package/dist/plus/git-github/providers/github/refs.d.ts +9 -1
  264. package/dist/plus/git-github/providers/github/refs.d.ts.map +1 -1
  265. package/dist/plus/git-github/providers/github/refs.js +38 -13
  266. package/dist/plus/git-github/providers/github/refs.js.map +1 -1
  267. package/dist/plus/git-github/providers/github/revision.d.ts.map +1 -1
  268. package/dist/plus/git-github/providers/github/revision.js +1 -2
  269. package/dist/plus/git-github/providers/github/revision.js.map +1 -1
  270. package/dist/plus/git-github/providers/github/status.d.ts +4 -1
  271. package/dist/plus/git-github/providers/github/status.d.ts.map +1 -1
  272. package/dist/plus/git-github/providers/github/status.js +1 -1
  273. package/dist/plus/git-github/providers/github/status.js.map +1 -1
  274. package/dist/plus/git-github/providers/github/tags.d.ts.map +1 -1
  275. package/dist/plus/git-github/providers/github/tags.js +35 -36
  276. package/dist/plus/git-github/providers/github/tags.js.map +1 -1
  277. package/dist/plus/git-github/providers/githubGitProvider.d.ts.map +1 -1
  278. package/dist/plus/git-github/providers/githubGitProvider.js.map +1 -1
  279. package/dist/utils/color.d.ts.map +1 -1
  280. package/dist/utils/color.js.map +1 -1
  281. package/dist/utils/decorators/log.js +1 -1
  282. package/dist/utils/decorators/log.js.map +1 -1
  283. package/dist/utils/decorators/sequentialize.d.ts.map +1 -1
  284. package/dist/utils/decorators/sequentialize.js +4 -2
  285. package/dist/utils/decorators/sequentialize.js.map +1 -1
  286. package/dist/utils/decorators/serializable.d.ts.map +1 -1
  287. package/dist/utils/decorators/serializable.js.map +1 -1
  288. package/dist/utils/dedupedAsyncCache.d.ts +37 -0
  289. package/dist/utils/dedupedAsyncCache.d.ts.map +1 -0
  290. package/dist/utils/dedupedAsyncCache.js +68 -0
  291. package/dist/utils/dedupedAsyncCache.js.map +1 -0
  292. package/dist/utils/diff.d.ts +2 -0
  293. package/dist/utils/diff.d.ts.map +1 -0
  294. package/dist/utils/diff.js +53 -0
  295. package/dist/utils/diff.js.map +1 -0
  296. package/dist/utils/disposable.d.ts.map +1 -1
  297. package/dist/utils/disposable.js.map +1 -1
  298. package/dist/utils/env/node/base64.js.map +1 -1
  299. package/dist/utils/env/node/exec.d.ts.map +1 -1
  300. package/dist/utils/env/node/exec.js.map +1 -1
  301. package/dist/utils/error.d.ts.map +1 -1
  302. package/dist/utils/error.js.map +1 -1
  303. package/dist/utils/formatter.d.ts.map +1 -1
  304. package/dist/utils/formatter.js +4 -10
  305. package/dist/utils/formatter.js.map +1 -1
  306. package/dist/utils/iterable.d.ts.map +1 -1
  307. package/dist/utils/iterable.js.map +1 -1
  308. package/dist/utils/logger.d.ts.map +1 -1
  309. package/dist/utils/logger.js.map +1 -1
  310. package/dist/utils/lruMap.d.ts +49 -0
  311. package/dist/utils/lruMap.d.ts.map +1 -0
  312. package/dist/utils/lruMap.js +103 -0
  313. package/dist/utils/lruMap.js.map +1 -0
  314. package/dist/utils/markdown.d.ts.map +1 -1
  315. package/dist/utils/markdown.js.map +1 -1
  316. package/dist/utils/mru.d.ts.map +1 -1
  317. package/dist/utils/mru.js.map +1 -1
  318. package/dist/utils/path.d.ts.map +1 -1
  319. package/dist/utils/path.js.map +1 -1
  320. package/dist/utils/promise.d.ts +1 -0
  321. package/dist/utils/promise.d.ts.map +1 -1
  322. package/dist/utils/promise.js +17 -0
  323. package/dist/utils/promise.js.map +1 -1
  324. package/dist/utils/promiseCache.d.ts +10 -0
  325. package/dist/utils/promiseCache.d.ts.map +1 -1
  326. package/dist/utils/promiseCache.js +22 -0
  327. package/dist/utils/promiseCache.js.map +1 -1
  328. package/dist/utils/string.d.ts.map +1 -1
  329. package/dist/utils/string.js.map +1 -1
  330. package/dist/utils/uri.d.ts.map +1 -1
  331. package/dist/utils/uri.js.map +1 -1
  332. package/dist/utils/version.d.ts +14 -0
  333. package/dist/utils/version.d.ts.map +1 -1
  334. package/dist/utils/version.js +48 -0
  335. package/dist/utils/version.js.map +1 -1
  336. package/package.json +13 -1
  337. package/src/git/cache.ts +309 -29
  338. package/src/git/context.ts +11 -2
  339. package/src/git/models/branch.ts +1 -0
  340. package/src/git/models/commit.ts +2 -17
  341. package/src/git/models/graph.ts +2 -4
  342. package/src/git/models/reference.ts +33 -0
  343. package/src/git/models/remote.ts +1 -0
  344. package/src/git/models/repository.ts +44 -6
  345. package/src/git/models/search.ts +2 -2
  346. package/src/git/models/worktree.ts +10 -2
  347. package/src/git/parsers/diffParser.ts +9 -44
  348. package/src/git/providers/branches.ts +25 -4
  349. package/src/git/providers/commits.ts +7 -0
  350. package/src/git/providers/config.ts +4 -0
  351. package/src/git/providers/diff.ts +8 -2
  352. package/src/git/providers/operations.ts +54 -3
  353. package/src/git/providers/pausedOperations.ts +1 -0
  354. package/src/git/providers/refs.ts +32 -3
  355. package/src/git/providers/revision.ts +5 -1
  356. package/src/git/providers/staging.ts +14 -0
  357. package/src/git/providers/status.ts +6 -1
  358. package/src/git/remotes/azure-devops.ts +2 -0
  359. package/src/git/{exec.types.ts → run.types.ts} +22 -2
  360. package/src/git/service.ts +1 -0
  361. package/src/git/utils/autolink.utils.ts +1 -0
  362. package/src/git/utils/blame.utils.ts +2 -0
  363. package/src/git/utils/conflictResolution.utils.ts +31 -0
  364. package/src/git/utils/fileStatus.utils.ts +7 -1
  365. package/src/git/utils/search.utils.ts +2 -0
  366. package/src/git/utils/sorting.ts +38 -0
  367. package/src/git/utils/status.utils.ts +1 -0
  368. package/src/git/watching/classifyChange.ts +9 -0
  369. package/src/git/watching/gitIgnoreFilter.ts +2 -2
  370. package/src/git/watching/initWatcher.ts +2 -0
  371. package/src/git/watching/watchGroup.ts +3 -0
  372. package/src/git/watching/watchService.ts +38 -5
  373. package/src/git/watching/watchSession.ts +10 -0
  374. package/src/git-cli/cliGitProvider.ts +1 -1
  375. package/src/git-cli/exec/exec.types.ts +2 -2
  376. package/src/git-cli/exec/git.ts +76 -23
  377. package/src/git-cli/exec/gitQueue.ts +98 -25
  378. package/src/git-cli/parsers/blameParser.ts +1 -0
  379. package/src/git-cli/parsers/logParser.ts +6 -1
  380. package/src/git-cli/parsers/refParser.ts +33 -34
  381. package/src/git-cli/providers/blame.ts +2 -1
  382. package/src/git-cli/providers/branches.ts +341 -196
  383. package/src/git-cli/providers/commits.ts +145 -46
  384. package/src/git-cli/providers/config.ts +50 -16
  385. package/src/git-cli/providers/contributors.ts +7 -12
  386. package/src/git-cli/providers/diff.ts +107 -20
  387. package/src/git-cli/providers/graph.ts +58 -29
  388. package/src/git-cli/providers/operations.ts +253 -57
  389. package/src/git-cli/providers/patch.ts +16 -37
  390. package/src/git-cli/providers/pausedOperations.ts +14 -6
  391. package/src/git-cli/providers/refs.ts +274 -11
  392. package/src/git-cli/providers/remotes.ts +4 -4
  393. package/src/git-cli/providers/revision.ts +22 -15
  394. package/src/git-cli/providers/staging.ts +51 -8
  395. package/src/git-cli/providers/stash.ts +67 -134
  396. package/src/git-cli/providers/status.ts +21 -10
  397. package/src/git-cli/providers/tags.ts +18 -19
  398. package/src/git-cli/providers/worktrees.ts +3 -3
  399. package/src/ipc/discovery.ts +56 -0
  400. package/src/ipc/ipcServer.ts +171 -0
  401. package/src/plus/agents/providers/claudeCodeProvider.ts +1782 -0
  402. package/src/plus/agents/providers/claudeCodeTranscript.ts +214 -0
  403. package/src/plus/agents/sanitizePrompt.ts +109 -0
  404. package/src/plus/agents/stateMachine.ts +197 -0
  405. package/src/plus/agents/types.ts +277 -0
  406. package/src/plus/ai/constants.ts +8 -0
  407. package/src/plus/ai/errors.ts +40 -0
  408. package/src/plus/ai/models/model.ts +1 -0
  409. package/src/plus/ai/models/promptTemplates.ts +42 -0
  410. package/src/plus/ai/models/results.ts +30 -0
  411. package/src/plus/ai/prompts.ts +171 -1
  412. package/src/plus/ai/utils/ai.utils.ts +2 -0
  413. package/src/plus/ai/utils/results.utils.ts +101 -0
  414. package/src/plus/ai/utils/truncation.utils.ts +3 -1
  415. package/src/plus/git-github/api/github.ts +199 -53
  416. package/src/plus/git-github/api/types.ts +15 -0
  417. package/src/plus/git-github/models.ts +1 -1
  418. package/src/plus/git-github/providers/github/blame.ts +2 -0
  419. package/src/plus/git-github/providers/github/branches.ts +75 -33
  420. package/src/plus/git-github/providers/github/commits.ts +231 -160
  421. package/src/plus/git-github/providers/github/diff.ts +35 -21
  422. package/src/plus/git-github/providers/github/refs.ts +57 -22
  423. package/src/plus/git-github/providers/github/revision.ts +1 -2
  424. package/src/plus/git-github/providers/github/status.ts +6 -1
  425. package/src/plus/git-github/providers/github/tags.ts +61 -62
  426. package/src/plus/git-github/providers/githubGitProvider.ts +1 -0
  427. package/src/utils/color.ts +2 -0
  428. package/src/utils/decorators/log.ts +1 -1
  429. package/src/utils/decorators/sequentialize.ts +8 -6
  430. package/src/utils/decorators/serializable.ts +1 -0
  431. package/src/utils/dedupedAsyncCache.ts +74 -0
  432. package/src/utils/diff.ts +61 -0
  433. package/src/utils/disposable.ts +2 -0
  434. package/src/utils/env/node/base64.ts +1 -1
  435. package/src/utils/env/node/exec.ts +4 -2
  436. package/src/utils/error.ts +1 -0
  437. package/src/utils/formatter.ts +4 -11
  438. package/src/utils/iterable.ts +4 -1
  439. package/src/utils/logger.ts +1 -0
  440. package/src/utils/lruMap.ts +112 -0
  441. package/src/utils/markdown.ts +1 -0
  442. package/src/utils/mru.ts +2 -0
  443. package/src/utils/path.ts +1 -0
  444. package/src/utils/promise.ts +22 -0
  445. package/src/utils/promiseCache.ts +24 -0
  446. package/src/utils/string.ts +2 -0
  447. package/src/utils/uri.ts +1 -0
  448. package/src/utils/version.ts +49 -0
  449. package/dist/git/exec.types.d.ts.map +0 -1
  450. package/dist/git/exec.types.js +0 -2
  451. package/dist/git/exec.types.js.map +0 -1
@@ -22,6 +22,7 @@ import { encodeGitLensRevisionUriAuthority } from '../../../../git/utils/uriAuth
22
22
  import { debug } from '../../../../utils/decorators/log.js';
23
23
  import { union } from '../../../../utils/iterable.js';
24
24
  import { getScopedLogger } from '../../../../utils/logger.scoped.js';
25
+ import { getSettledValue } from '../../../../utils/promise.js';
25
26
  import type { Uri } from '../../../../utils/uri.js';
26
27
  import { fromUri } from '../../../../utils/uri.js';
27
28
  import { toTokenInfo } from '../../api/tokenUtils.js';
@@ -58,12 +59,18 @@ export class DiffGitSubProvider implements GitDiffSubProvider {
58
59
  async getChangedFilesCount(
59
60
  repoPath: string,
60
61
  to?: string,
61
- _from?: string,
62
- _options?: { uris?: (string | Uri)[] },
62
+ from?: string,
63
+ _options?: { uris?: (string | Uri)[]; includeUntracked?: boolean },
63
64
  _cancellation?: AbortSignal,
64
65
  ): Promise<GitDiffShortStat | undefined> {
65
- // TODO@eamodio if there is no ref we can't return anything, until we can get at the change store from RemoteHub
66
- if (!to) return undefined;
66
+ // Virtual GitHub repos have no working tree, so no working changes can exist.
67
+ // Without any refs, return empty stats rather than undefined to avoid "uncertain state" callers.
68
+ if (!to && !from) return { additions: 0, deletions: 0, files: 0 };
69
+
70
+ // If only `from` is provided, compare against HEAD
71
+ if (!to) {
72
+ to = 'HEAD';
73
+ }
67
74
 
68
75
  const commit = await this.provider.commits.getCommit(repoPath, to);
69
76
  if (commit?.stats == null) return undefined;
@@ -79,7 +86,13 @@ export class DiffGitSubProvider implements GitDiffSubProvider {
79
86
  repoPath: string,
80
87
  ref1OrRange: string | GitRevisionRange,
81
88
  ref2?: string,
82
- _options?: { filters?: GitDiffFilter[]; path?: string; renameLimit?: number; similarityThreshold?: number },
89
+ _options?: {
90
+ filters?: GitDiffFilter[];
91
+ includeUntracked?: boolean;
92
+ path?: string;
93
+ renameLimit?: number;
94
+ similarityThreshold?: number;
95
+ },
83
96
  ): Promise<GitFile[] | undefined> {
84
97
  if (repoPath == null) return undefined;
85
98
 
@@ -109,27 +122,28 @@ export class DiffGitSubProvider implements GitDiffSubProvider {
109
122
  }
110
123
 
111
124
  try {
112
- let result = await github.getComparison(
113
- toTokenInfo(this.provider.authenticationProviderId, session),
114
- metadata.repo.owner,
115
- metadata.repo.name,
116
- stripOrigin(range),
117
- );
118
-
119
- const files1 = result?.files;
125
+ const token = toTokenInfo(this.provider.authenticationProviderId, session);
120
126
 
121
- let files = files1;
127
+ let files;
122
128
  if (range2) {
123
- result = await github.getComparison(
124
- toTokenInfo(this.provider.authenticationProviderId, session),
125
- metadata.repo.owner,
126
- metadata.repo.name,
127
- stripOrigin(range2),
128
- );
129
+ // GitHub doesn't support `..`, so issue both `...` comparisons in parallel and union the results.
130
+ const [result1, result2] = await Promise.allSettled([
131
+ github.getComparison(token, metadata.repo.owner, metadata.repo.name, stripOrigin(range)),
132
+ github.getComparison(token, metadata.repo.owner, metadata.repo.name, stripOrigin(range2)),
133
+ ]);
129
134
 
130
- const files2 = result?.files;
135
+ const files1 = getSettledValue(result1)?.files;
136
+ const files2 = getSettledValue(result2)?.files;
131
137
 
132
138
  files = [...new Set(union(files1, files2))];
139
+ } else {
140
+ const result = await github.getComparison(
141
+ token,
142
+ metadata.repo.owner,
143
+ metadata.repo.name,
144
+ stripOrigin(range),
145
+ );
146
+ files = result?.files;
133
147
  }
134
148
 
135
149
  return files?.map(f => ({
@@ -1,9 +1,10 @@
1
1
  import type { Cache } from '../../../../git/cache.js';
2
2
  import type { GitBranch } from '../../../../git/models/branch.js';
3
- import type { GitReference } from '../../../../git/models/reference.js';
3
+ import type { GitReference, GitRefTip } from '../../../../git/models/reference.js';
4
4
  import { deletedOrMissing } from '../../../../git/models/revision.js';
5
5
  import type { GitTag } from '../../../../git/models/tag.js';
6
6
  import type { GitRefsSubProvider } from '../../../../git/providers/refs.js';
7
+ import type { GitCommandPriority } from '../../../../git/run.types.js';
7
8
  import { createReference } from '../../../../git/utils/reference.utils.js';
8
9
  import {
9
10
  createRevisionRange,
@@ -31,32 +32,42 @@ export class RefsGitSubProvider implements GitRefsSubProvider {
31
32
  }
32
33
 
33
34
  @debug()
34
- async getMergeBase(
35
+ getMergeBase(
35
36
  repoPath: string,
36
37
  ref1: string,
37
38
  ref2: string,
38
- _options?: { forkPoint?: boolean },
39
+ _options?: { forkPoint?: boolean; priority?: GitCommandPriority },
39
40
  _cancellation?: AbortSignal,
40
41
  ): Promise<string | undefined> {
41
- if (repoPath == null) return undefined;
42
-
43
- const scope = getScopedLogger();
44
-
45
- const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
46
-
47
- try {
48
- const result = await github.getComparison(
49
- toTokenInfo(this.provider.authenticationProviderId, session),
50
- metadata.repo.owner,
51
- metadata.repo.name,
52
- createRevisionRange(stripOrigin(ref1), stripOrigin(ref2), '...'),
53
- );
54
- return result?.merge_base_commit?.sha;
55
- } catch (ex) {
56
- scope?.error(ex);
57
- debugger;
58
- return undefined;
59
- }
42
+ if (repoPath == null) return Promise.resolve(undefined);
43
+
44
+ const a = stripOrigin(ref1);
45
+ const b = stripOrigin(ref2);
46
+ // `merge-base` is symmetric, so normalize ref order in the cache key to coalesce
47
+ // `(A, B)` and `(B, A)` lookups onto a single entry.
48
+ const [left, right] = a < b ? [a, b] : [b, a];
49
+ const cacheKey = `${left}...${right}`;
50
+ const queryRange = createRevisionRange(a, b, '...');
51
+
52
+ return this.cache.mergeBase.getOrCreate(repoPath, cacheKey, async () => {
53
+ const scope = getScopedLogger();
54
+
55
+ const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
56
+
57
+ try {
58
+ const result = await github.getComparison(
59
+ toTokenInfo(this.provider.authenticationProviderId, session),
60
+ metadata.repo.owner,
61
+ metadata.repo.name,
62
+ queryRange,
63
+ );
64
+ return result?.merge_base_commit?.sha;
65
+ } catch (ex) {
66
+ scope?.error(ex);
67
+ debugger;
68
+ return undefined;
69
+ }
70
+ });
60
71
  }
61
72
 
62
73
  @debug()
@@ -90,6 +101,30 @@ export class RefsGitSubProvider implements GitRefsSubProvider {
90
101
  return createReference(ref, repoPath, { refType: 'revision' });
91
102
  }
92
103
 
104
+ @debug()
105
+ getRefTips(
106
+ _repoPath: string,
107
+ _options?: { include?: ReadonlyArray<'heads' | 'remotes' | 'tags'> },
108
+ _cancellation?: AbortSignal,
109
+ ): Promise<GitRefTip[]> {
110
+ // Not implemented for GitHub virtual repos — current consumers (timeline slice-by-branch)
111
+ // gate this off via `!repo.virtual`. A future implementation can use GraphQL `refs` /
112
+ // `commit.associatedRefs`.
113
+ return Promise.resolve([]);
114
+ }
115
+
116
+ @debug()
117
+ getRefsContainingShas(
118
+ _repoPath: string,
119
+ _shas: ReadonlySet<string> | readonly string[],
120
+ _oldestSha: string,
121
+ _options?: { include?: ReadonlyArray<'heads' | 'remotes' | 'tags'> },
122
+ _cancellation?: AbortSignal,
123
+ ): Promise<Map<string, GitRefTip[]>> {
124
+ // See `getRefTips` — gated off for virtual repos until GraphQL `commit.associatedRefs` lands.
125
+ return Promise.resolve(new Map<string, GitRefTip[]>());
126
+ }
127
+
93
128
  @debug()
94
129
  async hasBranchOrTag(
95
130
  repoPath: string | undefined,
@@ -98,8 +98,7 @@ export class RevisionGitSubProvider implements GitRevisionSubProvider {
98
98
  });
99
99
  }
100
100
 
101
- // TODO@eamodio: Implement this
102
- return [];
101
+ return result;
103
102
  }
104
103
 
105
104
  @debug()
@@ -2,6 +2,7 @@ import type { GitFile } from '../../../../git/models/file.js';
2
2
  import type { GitConflictFile } from '../../../../git/models/staging.js';
3
3
  import { GitStatus } from '../../../../git/models/status.js';
4
4
  import type { GitStatusSubProvider, GitWorkingChangesState } from '../../../../git/providers/status.js';
5
+ import type { GitCommandPriority } from '../../../../git/run.types.js';
5
6
  import { gate } from '../../../../utils/decorators/gate.js';
6
7
  import { debug } from '../../../../utils/decorators/log.js';
7
8
  import { HeadType } from '../../context.js';
@@ -12,7 +13,11 @@ export class StatusGitSubProvider implements GitStatusSubProvider {
12
13
 
13
14
  @gate()
14
15
  @debug()
15
- async getStatus(repoPath: string | undefined, _cancellation?: AbortSignal): Promise<GitStatus | undefined> {
16
+ async getStatus(
17
+ repoPath: string | undefined,
18
+ _options?: { priority?: GitCommandPriority },
19
+ _cancellation?: AbortSignal,
20
+ ): Promise<GitStatus | undefined> {
16
21
  if (repoPath == null) return undefined;
17
22
 
18
23
  const context = await this.provider.ensureRepositoryContext(repoPath);
@@ -33,72 +33,71 @@ export class TagsGitSubProvider implements GitTagsSubProvider {
33
33
  ): Promise<PagedResult<GitTag>> {
34
34
  if (repoPath == null) return emptyPagedResult;
35
35
 
36
+ const path = repoPath;
37
+
36
38
  const scope = getScopedLogger();
37
39
 
38
- const tagsPromise = options?.paging?.cursor
39
- ? undefined
40
- : this.cache.tags.getOrCreate(
41
- repoPath,
42
- async cancellable => {
43
- try {
44
- const { metadata, github, session } = await this.provider.ensureRepositoryContext(repoPath);
45
-
46
- const tags: GitTag[] = [];
47
-
48
- let cursor = options?.paging?.cursor;
49
- const loadAll = cursor == null;
50
-
51
- let authoredDate;
52
- let committedDate;
53
-
54
- while (true) {
55
- const result = await github.getTags(
56
- toTokenInfo(this.provider.authenticationProviderId, session),
57
- metadata.repo.owner,
58
- metadata.repo.name,
59
- { cursor: cursor },
60
- );
61
-
62
- for (const tag of result.values) {
63
- authoredDate =
64
- tag.target.authoredDate ??
65
- tag.target.target?.authoredDate ??
66
- tag.target.tagger?.date;
67
- committedDate =
68
- tag.target.committedDate ??
69
- tag.target.target?.committedDate ??
70
- tag.target.tagger?.date;
71
-
72
- tags.push(
73
- new GitTag(
74
- repoPath,
75
- tag.name,
76
- tag.target.target?.oid ?? tag.target.oid,
77
- tag.target.message ?? tag.target.target?.message ?? '',
78
- authoredDate != null ? new Date(authoredDate) : undefined,
79
- committedDate != null ? new Date(committedDate) : undefined,
80
- ),
81
- );
82
- }
83
-
84
- if (!result.paging?.more || !loadAll) return { ...result, values: tags };
85
-
86
- cursor = result.paging.cursor;
87
- }
88
- } catch (ex) {
89
- cancellable.invalidate();
90
- scope?.error(ex);
91
- debugger;
92
-
93
- return emptyPagedResult;
40
+ // Compose cache key with cursor so re-loads of the same page hit the cache;
41
+ // `repoPath` (no suffix) is reserved for the full "all tags" entry.
42
+ // TODO: `cache.tags` is `PromiseMap<RepoPath, ...>` keyed exactly by repoPath, so
43
+ // `clearCaches('tags')` / `unregisterRepoPath` will not invalidate composite-key entries.
44
+ // Acceptable today because tags rarely move during a virtual-repo session, but the entries
45
+ // leak in memory until provider GC. Long-term: switch to RepoPromiseCacheMap or add prefix-invalidate.
46
+ const cacheKey = options?.paging?.cursor != null ? `${path}#${options.paging.cursor}` : path;
47
+ const tagsPromise = this.cache.tags.getOrCreate(
48
+ cacheKey,
49
+ async cancellable => {
50
+ try {
51
+ const { metadata, github, session } = await this.provider.ensureRepositoryContext(path);
52
+
53
+ const tags: GitTag[] = [];
54
+
55
+ let cursor = options?.paging?.cursor;
56
+ const loadAll = cursor == null;
57
+
58
+ let authoredDate;
59
+ let committedDate;
60
+
61
+ while (true) {
62
+ const result = await github.getTags(
63
+ toTokenInfo(this.provider.authenticationProviderId, session),
64
+ metadata.repo.owner,
65
+ metadata.repo.name,
66
+ { cursor: cursor },
67
+ );
68
+
69
+ for (const tag of result.values) {
70
+ authoredDate =
71
+ tag.target.authoredDate ?? tag.target.target?.authoredDate ?? tag.target.tagger?.date;
72
+ committedDate =
73
+ tag.target.committedDate ?? tag.target.target?.committedDate ?? tag.target.tagger?.date;
74
+
75
+ tags.push(
76
+ new GitTag(
77
+ path,
78
+ tag.name,
79
+ tag.target.target?.oid ?? tag.target.oid,
80
+ tag.target.message ?? tag.target.target?.message ?? '',
81
+ authoredDate != null ? new Date(authoredDate) : undefined,
82
+ committedDate != null ? new Date(committedDate) : undefined,
83
+ ),
84
+ );
94
85
  }
95
- },
96
- cancellation,
97
- );
98
86
 
99
- if (tagsPromise == null) {
100
- return emptyPagedResult;
101
- }
87
+ if (!result.paging?.more || !loadAll) return { ...result, values: tags };
88
+
89
+ cursor = result.paging.cursor;
90
+ }
91
+ } catch (ex) {
92
+ cancellable.invalidate();
93
+ scope?.error(ex);
94
+ debugger;
95
+
96
+ return emptyPagedResult;
97
+ }
98
+ },
99
+ cancellation,
100
+ );
102
101
 
103
102
  let result = await tagsPromise;
104
103
  if (options?.filter != null) {
@@ -152,6 +152,7 @@ export class GitHubGitProvider implements GitHubGitProviderInternal, GitProvider
152
152
 
153
153
  getPagingLimit(limit?: number): number {
154
154
  if (limit === 0) return 0;
155
+
155
156
  limit = Math.min(limit ?? this.context.config?.paging?.limit ?? 100, 100);
156
157
  if (limit !== 0 && limit < 100) {
157
158
  limit = Math.max(limit, 1);
@@ -568,6 +568,7 @@ export class Color {
568
568
  if (of.isLighterThan(relative)) {
569
569
  return of;
570
570
  }
571
+
571
572
  factor = factor ? factor : 0.5;
572
573
  const lum1 = of.getRelativeLuminance();
573
574
  const lum2 = relative.getRelativeLuminance();
@@ -579,6 +580,7 @@ export class Color {
579
580
  if (of.isDarkerThan(relative)) {
580
581
  return of;
581
582
  }
583
+
582
584
  factor = factor ? factor : 0.5;
583
585
  const lum1 = of.getRelativeLuminance();
584
586
  const lum2 = relative.getRelativeLuminance();
@@ -265,7 +265,7 @@ function log<T extends (...arg: any[]) => any>(
265
265
  }
266
266
 
267
267
  if (result != null && isPromise(result)) {
268
- result.then(logResult, logError);
268
+ void result.then(logResult, logError).catch(() => {});
269
269
  } else {
270
270
  logResult(result);
271
271
  }
@@ -103,12 +103,14 @@ export function sequentialize<T extends (...args: any[]) => any>(
103
103
  }
104
104
 
105
105
  // Cleanup when done
106
- void promise.finally(() => {
107
- const s = this[prop];
108
- if (s?.promise === promise && s.waiting == null) {
109
- this[prop] = undefined;
110
- }
111
- });
106
+ void promise
107
+ .finally(() => {
108
+ const s = this[prop];
109
+ if (s?.promise === promise && s.waiting == null) {
110
+ this[prop] = undefined;
111
+ }
112
+ })
113
+ .catch(() => {});
112
114
 
113
115
  return promise;
114
116
  };
@@ -18,6 +18,7 @@ export function serializable(target: Function): void {
18
18
  while (proto != null && proto !== Object.prototype) {
19
19
  for (const key of Object.getOwnPropertyNames(proto)) {
20
20
  if (key === 'constructor') continue;
21
+
21
22
  const desc = Object.getOwnPropertyDescriptor(proto, key);
22
23
  if (desc?.get != null) {
23
24
  getterKeys.add(key);
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Per-key cache for async resolution that dedupes concurrent first-time callers and caches the
3
+ * resolved value (including `undefined`) for subsequent reads.
4
+ *
5
+ * Two internal Maps drive the semantics:
6
+ * - `_resolved` holds settled values. `has(key)` distinguishes a cached `undefined` from "never
7
+ * resolved", so callers can intentionally cache "no result" without re-running the resolver.
8
+ * - `_resolving` holds in-flight Promises. While a key resolves, concurrent `getOrResolve` callers
9
+ * share the same Promise instead of each invoking the resolver.
10
+ *
11
+ * Failed resolutions do not poison the cache — the entry is removed when the in-flight Promise
12
+ * rejects, so the next call retries.
13
+ */
14
+ export class DedupedAsyncCache<K, V> {
15
+ private readonly _resolved = new Map<K, V>();
16
+ private readonly _resolving = new Map<K, Promise<V>>();
17
+
18
+ /** True iff `key` has a settled value cached. Distinct from "currently resolving". */
19
+ has(key: K): boolean {
20
+ return this._resolved.has(key);
21
+ }
22
+
23
+ /** Settled value for `key`, or `undefined` when not yet cached. May also legitimately return
24
+ * `undefined` for a key whose cached value is `undefined`; use `has` to disambiguate. */
25
+ get(key: K): V | undefined {
26
+ return this._resolved.get(key);
27
+ }
28
+
29
+ /** Populates the cache directly, bypassing the resolver. Used by callers that already know the
30
+ * value (e.g. event payloads, post-write reconciles) and want subsequent reads to hit. */
31
+ set(key: K, value: V): void {
32
+ this._resolved.set(key, value);
33
+ }
34
+
35
+ /** Removes both the settled value and any in-flight Promise for `key`. */
36
+ delete(key: K): void {
37
+ this._resolved.delete(key);
38
+ this._resolving.delete(key);
39
+ }
40
+
41
+ /** Clears everything — both settled values and in-flight Promises. */
42
+ clear(): void {
43
+ this._resolved.clear();
44
+ this._resolving.clear();
45
+ }
46
+
47
+ /**
48
+ * Returns the cached value for `key`, invoking `resolver` only on a cache miss. Concurrent
49
+ * cache-miss callers for the same key share the same in-flight Promise — `resolver` is invoked
50
+ * exactly once per cache fill. If `resolver` rejects, the entry is removed so subsequent calls
51
+ * retry rather than receiving a permanently cached failure.
52
+ */
53
+ getOrResolve(key: K, resolver: () => Promise<V>): Promise<V> {
54
+ if (this._resolved.has(key)) {
55
+ // Map.get returns `V | undefined`; `has` confirmed presence, so the value (even if it
56
+ // is `undefined` by intent) is the cached one. Cast pins the return type.
57
+ return Promise.resolve(this._resolved.get(key) as V);
58
+ }
59
+
60
+ const existing = this._resolving.get(key);
61
+ if (existing != null) return existing;
62
+
63
+ const pending = resolver()
64
+ .then(value => {
65
+ this._resolved.set(key, value);
66
+ return value;
67
+ })
68
+ .finally(() => {
69
+ this._resolving.delete(key);
70
+ });
71
+ this._resolving.set(key, pending);
72
+ return pending;
73
+ }
74
+ }
@@ -0,0 +1,61 @@
1
+ // Annotates diff to make is easier for agentic reference to line number.
2
+ // Brackets sit AFTER the line-type marker so file-level diff parsers
3
+ // (e.g. `filterDiffFiles`) that key off `diff --git` / `+++` / `---` headers still work.
4
+ export function annotateDiffWithNewLineNumbers(diff: string): string {
5
+ if (!diff) return diff;
6
+
7
+ const lines = diff.split('\n');
8
+ const out: string[] = new Array(lines.length);
9
+ let newLine = 0;
10
+ let inHunk = false;
11
+
12
+ for (let i = 0; i < lines.length; i++) {
13
+ const line = lines[i];
14
+
15
+ if (line.startsWith('@@')) {
16
+ const match = /\+(\d+)(?:,\d+)?\s/.exec(line);
17
+ newLine = match != null ? parseInt(match[1], 10) : 0;
18
+ inHunk = true;
19
+ out[i] = line;
20
+ continue;
21
+ }
22
+
23
+ if (
24
+ line.startsWith('diff --git') ||
25
+ line.startsWith('index ') ||
26
+ line.startsWith('--- ') ||
27
+ line.startsWith('+++ ') ||
28
+ line.startsWith('new file') ||
29
+ line.startsWith('deleted file') ||
30
+ line.startsWith('rename ') ||
31
+ line.startsWith('copy ') ||
32
+ line.startsWith('similarity ') ||
33
+ line.startsWith('dissimilarity ') ||
34
+ line.startsWith('Binary files')
35
+ ) {
36
+ inHunk = false;
37
+ out[i] = line;
38
+ continue;
39
+ }
40
+
41
+ if (!inHunk || line.startsWith('\\')) {
42
+ out[i] = line;
43
+ continue;
44
+ }
45
+
46
+ const marker = line[0];
47
+ if (marker === '-') {
48
+ out[i] = `-[ ]${line.slice(1)}`;
49
+ continue;
50
+ }
51
+ if (marker === '+' || marker === ' ') {
52
+ out[i] = `${marker}[${String(newLine).padStart(5, ' ')}]${line.slice(1)}`;
53
+ newLine++;
54
+ continue;
55
+ }
56
+
57
+ out[i] = line;
58
+ }
59
+
60
+ return out.join('\n');
61
+ }
@@ -13,6 +13,7 @@ export function createDisposable(
13
13
  options?: { once?: boolean },
14
14
  ): UnifiedDisposable | undefined {
15
15
  if (dispose == null) return undefined;
16
+
16
17
  if (options?.once) {
17
18
  dispose = once(dispose);
18
19
  }
@@ -61,6 +62,7 @@ export function fromDisposables(
61
62
  let disposed = false;
62
63
  const dispose = () => {
63
64
  if (disposed) return;
65
+
64
66
  disposed = true;
65
67
 
66
68
  for (const d of disposables) {
@@ -5,7 +5,7 @@ export function base64(data: string | Uint8Array): string {
5
5
  }
6
6
 
7
7
  export function fromBase64(s: string): Uint8Array {
8
- return Buffer.from(s, 'base64') as unknown as Uint8Array;
8
+ return Buffer.from(s, 'base64');
9
9
  }
10
10
 
11
11
  /**
@@ -287,6 +287,7 @@ export function run<T extends number | string>(
287
287
  `Non-UTF-8 encoding '${encoding}' requested but no decode function configured`,
288
288
  );
289
289
  }
290
+
290
291
  stdoutDecoded = await decode(
291
292
  Buffer.from(stdout, 'binary'),
292
293
  encoding ? { encoding: encoding } : undefined,
@@ -311,6 +312,7 @@ export function run<T extends number | string>(
311
312
  if (decode == null) {
312
313
  throw new Error(`Non-UTF-8 encoding '${encoding}' requested but no decode function configured`);
313
314
  }
315
+
314
316
  resolve(
315
317
  (await decode(
316
318
  Buffer.from(stdout, 'binary'),
@@ -373,8 +375,8 @@ export function runSpawn<T extends string | Buffer>(
373
375
  function getStdio<T>(
374
376
  encoding: BufferEncoding | 'buffer' | string,
375
377
  ): { stdout: T; stderr: T } | Promise<{ stdout: T; stderr: T }> {
376
- const stdout = Buffer.concat(stdoutBuffers as ReadonlyArray<Uint8Array>);
377
- const stderr = Buffer.concat(stderrBuffers as ReadonlyArray<Uint8Array>);
378
+ const stdout = Buffer.concat(stdoutBuffers);
379
+ const stderr = Buffer.concat(stderrBuffers);
378
380
  if (encoding === 'utf8' || encoding === 'binary') {
379
381
  return { stdout: stdout.toString(encoding) as T, stderr: stderr.toString(encoding) as T };
380
382
  }
@@ -7,6 +7,7 @@
7
7
  export function isErrorLike(v: unknown): v is { name: string; message: string; stack?: string } {
8
8
  if (v == null || typeof v !== 'object') return false;
9
9
  if (v instanceof Error) return true;
10
+
10
11
  const o = v as { name?: unknown; message?: unknown };
11
12
  return typeof o.name === 'string' && typeof o.message === 'string';
12
13
  }
@@ -176,23 +176,16 @@ export abstract class Formatter<Item = any, Options extends FormatOptions = Form
176
176
  options.tokenOptions = tokenOptions;
177
177
  }
178
178
 
179
- if (this._formatter == null) {
180
- this._formatter = new formatter(item, options);
181
- } else {
182
- this._formatter.reset(item, options);
183
- }
184
-
185
- return interpolateAsync(template, this._formatter);
179
+ // Always allocate a fresh formatter: `interpolateAsync` awaits between tokens, so a
180
+ // concurrent call that reset a shared instance would poison in-flight token resolution.
181
+ return interpolateAsync(template, new formatter(item, options));
186
182
  }
187
183
 
188
184
  static has<TOptions extends FormatOptions>(
189
185
  template: string,
190
186
  ...tokens: (keyof NonNullable<TOptions['tokenOptions']>)[]
191
187
  ): boolean {
192
- const token =
193
- tokens.length === 1
194
- ? (tokens[0] as string)
195
- : (`(${tokens.join('|')})` as keyof NonNullable<TOptions['tokenOptions']> as string);
188
+ const token = tokens.length === 1 ? (tokens[0] as string) : `(${tokens.join('|')})`;
196
189
 
197
190
  let regex = hasTokenRegexMap.get(token);
198
191
  if (regex == null) {