@gitkraken/core-gitlens 0.5.113 → 0.5.115

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 (349) hide show
  1. package/CHANGELOG.md +42 -1
  2. package/dist/git/cache.d.ts +4 -0
  3. package/dist/git/cache.d.ts.map +1 -1
  4. package/dist/git/cache.js +33 -0
  5. package/dist/git/cache.js.map +1 -1
  6. package/dist/git/context.d.ts +10 -0
  7. package/dist/git/context.d.ts.map +1 -1
  8. package/dist/git/context.js.map +1 -1
  9. package/dist/git/errors.d.ts +6 -3
  10. package/dist/git/errors.d.ts.map +1 -1
  11. package/dist/git/errors.js +9 -1
  12. package/dist/git/errors.js.map +1 -1
  13. package/dist/git/features.d.ts +1 -1
  14. package/dist/git/features.d.ts.map +1 -1
  15. package/dist/git/features.js +38 -0
  16. package/dist/git/features.js.map +1 -1
  17. package/dist/git/gitHealth.d.ts +153 -0
  18. package/dist/git/gitHealth.d.ts.map +1 -0
  19. package/dist/git/gitHealth.js +353 -0
  20. package/dist/git/gitHealth.js.map +1 -0
  21. package/dist/git/models/search.d.ts +6 -3
  22. package/dist/git/models/search.d.ts.map +1 -1
  23. package/dist/git/models/search.js +5 -1
  24. package/dist/git/models/search.js.map +1 -1
  25. package/dist/git/parsers/diffParser.d.ts +8 -2
  26. package/dist/git/parsers/diffParser.d.ts.map +1 -1
  27. package/dist/git/parsers/diffParser.js +27 -4
  28. package/dist/git/parsers/diffParser.js.map +1 -1
  29. package/dist/git/providers/config.d.ts +36 -3
  30. package/dist/git/providers/config.d.ts.map +1 -1
  31. package/dist/git/providers/graph.d.ts +9 -0
  32. package/dist/git/providers/graph.d.ts.map +1 -1
  33. package/dist/git/providers/maintenance.d.ts +222 -0
  34. package/dist/git/providers/maintenance.d.ts.map +1 -0
  35. package/dist/git/providers/maintenance.js +20 -0
  36. package/dist/git/providers/maintenance.js.map +1 -0
  37. package/dist/git/providers/operations.d.ts +10 -0
  38. package/dist/git/providers/operations.d.ts.map +1 -1
  39. package/dist/git/providers/pausedOperations.d.ts +3 -0
  40. package/dist/git/providers/pausedOperations.d.ts.map +1 -1
  41. package/dist/git/providers/provider.d.ts +2 -0
  42. package/dist/git/providers/provider.d.ts.map +1 -1
  43. package/dist/git/providers/tags.d.ts +3 -0
  44. package/dist/git/providers/tags.d.ts.map +1 -1
  45. package/dist/git/repositoryService.d.ts +1 -0
  46. package/dist/git/repositoryService.d.ts.map +1 -1
  47. package/dist/git/repositoryService.js.map +1 -1
  48. package/dist/git/run.types.d.ts +8 -0
  49. package/dist/git/run.types.d.ts.map +1 -1
  50. package/dist/git/service.js +3 -0
  51. package/dist/git/service.js.map +1 -1
  52. package/dist/git/utils/search.utils.d.ts.map +1 -1
  53. package/dist/git/utils/search.utils.js +112 -5
  54. package/dist/git/utils/search.utils.js.map +1 -1
  55. package/dist/git/watching/watchService.d.ts +3 -0
  56. package/dist/git/watching/watchService.d.ts.map +1 -1
  57. package/dist/git/watching/watchService.js +8 -0
  58. package/dist/git/watching/watchService.js.map +1 -1
  59. package/dist/git-cli/cliGitProvider.d.ts +11 -0
  60. package/dist/git-cli/cliGitProvider.d.ts.map +1 -1
  61. package/dist/git-cli/cliGitProvider.js +12 -0
  62. package/dist/git-cli/cliGitProvider.js.map +1 -1
  63. package/dist/git-cli/exec/git.d.ts +23 -1
  64. package/dist/git-cli/exec/git.d.ts.map +1 -1
  65. package/dist/git-cli/exec/git.js +83 -8
  66. package/dist/git-cli/exec/git.js.map +1 -1
  67. package/dist/git-cli/exec/gitQueue.d.ts +2 -0
  68. package/dist/git-cli/exec/gitQueue.d.ts.map +1 -1
  69. package/dist/git-cli/exec/gitQueue.js +19 -17
  70. package/dist/git-cli/exec/gitQueue.js.map +1 -1
  71. package/dist/git-cli/parsers/logParser.d.ts.map +1 -1
  72. package/dist/git-cli/parsers/logParser.js +4 -1
  73. package/dist/git-cli/parsers/logParser.js.map +1 -1
  74. package/dist/git-cli/providers/blame.d.ts.map +1 -1
  75. package/dist/git-cli/providers/blame.js +4 -7
  76. package/dist/git-cli/providers/blame.js.map +1 -1
  77. package/dist/git-cli/providers/branches.d.ts.map +1 -1
  78. package/dist/git-cli/providers/branches.js +13 -3
  79. package/dist/git-cli/providers/branches.js.map +1 -1
  80. package/dist/git-cli/providers/commits.d.ts.map +1 -1
  81. package/dist/git-cli/providers/commits.js +34 -3
  82. package/dist/git-cli/providers/commits.js.map +1 -1
  83. package/dist/git-cli/providers/config.d.ts +27 -0
  84. package/dist/git-cli/providers/config.d.ts.map +1 -1
  85. package/dist/git-cli/providers/config.js +31 -6
  86. package/dist/git-cli/providers/config.js.map +1 -1
  87. package/dist/git-cli/providers/graph.d.ts +8 -0
  88. package/dist/git-cli/providers/graph.d.ts.map +1 -1
  89. package/dist/git-cli/providers/graph.js +85 -6
  90. package/dist/git-cli/providers/graph.js.map +1 -1
  91. package/dist/git-cli/providers/maintenance.d.ts +306 -0
  92. package/dist/git-cli/providers/maintenance.d.ts.map +1 -0
  93. package/dist/git-cli/providers/maintenance.js +2129 -0
  94. package/dist/git-cli/providers/maintenance.js.map +1 -0
  95. package/dist/git-cli/providers/operations.d.ts +1 -0
  96. package/dist/git-cli/providers/operations.d.ts.map +1 -1
  97. package/dist/git-cli/providers/operations.js +8 -0
  98. package/dist/git-cli/providers/operations.js.map +1 -1
  99. package/dist/git-cli/providers/pausedOperations.d.ts +1 -0
  100. package/dist/git-cli/providers/pausedOperations.d.ts.map +1 -1
  101. package/dist/git-cli/providers/pausedOperations.js +1 -1
  102. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  103. package/dist/git-cli/providers/tags.d.ts +3 -0
  104. package/dist/git-cli/providers/tags.d.ts.map +1 -1
  105. package/dist/git-cli/providers/tags.js +23 -1
  106. package/dist/git-cli/providers/tags.js.map +1 -1
  107. package/dist/plus/agents/agentCapabilities.d.ts +77 -0
  108. package/dist/plus/agents/agentCapabilities.d.ts.map +1 -0
  109. package/dist/plus/agents/agentCapabilities.js +197 -0
  110. package/dist/plus/agents/agentCapabilities.js.map +1 -0
  111. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts +77 -13
  112. package/dist/plus/agents/providers/claudeCodeTranscript.d.ts.map +1 -1
  113. package/dist/plus/agents/providers/claudeCodeTranscript.js +263 -55
  114. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
  115. package/dist/plus/agents/providers/{claudeCodeProvider.d.ts → gkAgentProvider.d.ts} +52 -19
  116. package/dist/plus/agents/providers/gkAgentProvider.d.ts.map +1 -0
  117. package/dist/plus/agents/providers/{claudeCodeProvider.js → gkAgentProvider.js} +935 -262
  118. package/dist/plus/agents/providers/gkAgentProvider.js.map +1 -0
  119. package/dist/plus/agents/types.d.ts +113 -35
  120. package/dist/plus/agents/types.d.ts.map +1 -1
  121. package/dist/plus/agents/types.js +7 -4
  122. package/dist/plus/agents/types.js.map +1 -1
  123. package/dist/plus/ai/models/promptTemplates.d.ts +1 -1
  124. package/dist/plus/ai/models/promptTemplates.d.ts.map +1 -1
  125. package/dist/plus/ai/prompts.d.ts +4 -0
  126. package/dist/plus/ai/prompts.d.ts.map +1 -1
  127. package/dist/plus/ai/prompts.js +59 -4
  128. package/dist/plus/ai/prompts.js.map +1 -1
  129. package/dist/plus/git-github/api/github.d.ts +44 -1
  130. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  131. package/dist/plus/git-github/api/github.js +355 -62
  132. package/dist/plus/git-github/api/github.js.map +1 -1
  133. package/dist/plus/git-github/api/issueSearchQuery.d.ts +13 -0
  134. package/dist/plus/git-github/api/issueSearchQuery.d.ts.map +1 -1
  135. package/dist/plus/git-github/api/issueSearchQuery.js +41 -0
  136. package/dist/plus/git-github/api/issueSearchQuery.js.map +1 -1
  137. package/dist/plus/git-github/providers/github/blame.d.ts.map +1 -1
  138. package/dist/plus/git-github/providers/github/blame.js +2 -1
  139. package/dist/plus/git-github/providers/github/blame.js.map +1 -1
  140. package/dist/plus/integrations/collectionMetadata.d.ts +2 -0
  141. package/dist/plus/integrations/collectionMetadata.d.ts.map +1 -1
  142. package/dist/plus/integrations/collectionMetadata.js +17 -1
  143. package/dist/plus/integrations/collectionMetadata.js.map +1 -1
  144. package/dist/plus/integrations/context.d.ts +4 -1
  145. package/dist/plus/integrations/context.d.ts.map +1 -1
  146. package/dist/plus/integrations/index.d.ts +1 -0
  147. package/dist/plus/integrations/index.d.ts.map +1 -1
  148. package/dist/plus/integrations/integrationService.d.ts +20 -1
  149. package/dist/plus/integrations/integrationService.d.ts.map +1 -1
  150. package/dist/plus/integrations/integrationService.js +12 -4
  151. package/dist/plus/integrations/integrationService.js.map +1 -1
  152. package/dist/plus/integrations/manager.d.ts +48 -0
  153. package/dist/plus/integrations/manager.d.ts.map +1 -1
  154. package/dist/plus/integrations/models/gitHostIntegration.d.ts +53 -26
  155. package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -1
  156. package/dist/plus/integrations/models/gitHostIntegration.js +123 -47
  157. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  158. package/dist/plus/integrations/models/integration.d.ts +10 -1
  159. package/dist/plus/integrations/models/integration.d.ts.map +1 -1
  160. package/dist/plus/integrations/models/integration.js +52 -19
  161. package/dist/plus/integrations/models/integration.js.map +1 -1
  162. package/dist/plus/integrations/models/issueCache.d.ts +16 -0
  163. package/dist/plus/integrations/models/issueCache.d.ts.map +1 -0
  164. package/dist/plus/integrations/models/issueCache.js +9 -0
  165. package/dist/plus/integrations/models/issueCache.js.map +1 -0
  166. package/dist/plus/integrations/models/issueReads.d.ts +13 -0
  167. package/dist/plus/integrations/models/issueReads.d.ts.map +1 -1
  168. package/dist/plus/integrations/models/issuesIntegration.d.ts +11 -13
  169. package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -1
  170. package/dist/plus/integrations/models/issuesIntegration.js +15 -1
  171. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
  172. package/dist/plus/integrations/providers/azureDevOps.d.ts +3 -5
  173. package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -1
  174. package/dist/plus/integrations/providers/azureDevOps.js +9 -8
  175. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  176. package/dist/plus/integrations/providers/bitbucket-server.d.ts +3 -5
  177. package/dist/plus/integrations/providers/bitbucket-server.d.ts.map +1 -1
  178. package/dist/plus/integrations/providers/bitbucket-server.js +2 -2
  179. package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
  180. package/dist/plus/integrations/providers/bitbucket.d.ts +3 -5
  181. package/dist/plus/integrations/providers/bitbucket.d.ts.map +1 -1
  182. package/dist/plus/integrations/providers/bitbucket.js +2 -1
  183. package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
  184. package/dist/plus/integrations/providers/github.d.ts +12 -5
  185. package/dist/plus/integrations/providers/github.d.ts.map +1 -1
  186. package/dist/plus/integrations/providers/github.js +10 -3
  187. package/dist/plus/integrations/providers/github.js.map +1 -1
  188. package/dist/plus/integrations/providers/gitlab.d.ts +3 -5
  189. package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -1
  190. package/dist/plus/integrations/providers/gitlab.js +2 -2
  191. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  192. package/dist/plus/integrations/providers/jira.d.ts +3 -7
  193. package/dist/plus/integrations/providers/jira.d.ts.map +1 -1
  194. package/dist/plus/integrations/providers/jira.js +35 -22
  195. package/dist/plus/integrations/providers/jira.js.map +1 -1
  196. package/dist/plus/integrations/providers/jiraIssueByKey.d.ts +7 -0
  197. package/dist/plus/integrations/providers/jiraIssueByKey.d.ts.map +1 -0
  198. package/dist/plus/integrations/providers/jiraIssueByKey.js +102 -0
  199. package/dist/plus/integrations/providers/jiraIssueByKey.js.map +1 -0
  200. package/dist/plus/integrations/providers/linear.d.ts +3 -7
  201. package/dist/plus/integrations/providers/linear.d.ts.map +1 -1
  202. package/dist/plus/integrations/providers/linear.js +23 -22
  203. package/dist/plus/integrations/providers/linear.js.map +1 -1
  204. package/dist/plus/integrations/providers/models.d.ts +3 -1
  205. package/dist/plus/integrations/providers/models.d.ts.map +1 -1
  206. package/dist/plus/integrations/providers/models.js +10 -4
  207. package/dist/plus/integrations/providers/models.js.map +1 -1
  208. package/dist/plus/integrations/providers/providerErrors.d.ts +7 -0
  209. package/dist/plus/integrations/providers/providerErrors.d.ts.map +1 -0
  210. package/dist/plus/integrations/providers/providerErrors.js +91 -0
  211. package/dist/plus/integrations/providers/providerErrors.js.map +1 -0
  212. package/dist/plus/integrations/providers/providersApi.d.ts +3 -2
  213. package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -1
  214. package/dist/plus/integrations/providers/providersApi.js +18 -52
  215. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  216. package/dist/plus/integrations/providers/trello.d.ts +2 -7
  217. package/dist/plus/integrations/providers/trello.d.ts.map +1 -1
  218. package/dist/plus/integrations/providers/trello.js +3 -1
  219. package/dist/plus/integrations/providers/trello.js.map +1 -1
  220. package/dist/plus/integrations/providers/utils/providerPaging.d.ts +2 -0
  221. package/dist/plus/integrations/providers/utils/providerPaging.d.ts.map +1 -1
  222. package/dist/plus/integrations/providers/utils/providerPaging.js +12 -7
  223. package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
  224. package/dist/plus/integrations/reads/broaden.d.ts +47 -10
  225. package/dist/plus/integrations/reads/broaden.d.ts.map +1 -1
  226. package/dist/plus/integrations/reads/broaden.js +144 -33
  227. package/dist/plus/integrations/reads/broaden.js.map +1 -1
  228. package/dist/plus/integrations/reads/filters.d.ts +18 -0
  229. package/dist/plus/integrations/reads/filters.d.ts.map +1 -1
  230. package/dist/plus/integrations/reads/filters.js +37 -1
  231. package/dist/plus/integrations/reads/filters.js.map +1 -1
  232. package/dist/plus/integrations/reads/issueBatch.d.ts +51 -0
  233. package/dist/plus/integrations/reads/issueBatch.d.ts.map +1 -0
  234. package/dist/plus/integrations/reads/issueBatch.js +91 -0
  235. package/dist/plus/integrations/reads/issueBatch.js.map +1 -0
  236. package/dist/plus/integrations/reads/issueTracker.d.ts.map +1 -1
  237. package/dist/plus/integrations/reads/issueTracker.js +23 -17
  238. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  239. package/dist/plus/integrations/reads/sweeps.d.ts.map +1 -1
  240. package/dist/plus/integrations/reads/sweeps.js +5 -3
  241. package/dist/plus/integrations/reads/sweeps.js.map +1 -1
  242. package/dist/plus/integrations/reads/trackerIssue.d.ts +21 -0
  243. package/dist/plus/integrations/reads/trackerIssue.d.ts.map +1 -0
  244. package/dist/plus/integrations/reads/trackerIssue.js +51 -0
  245. package/dist/plus/integrations/reads/trackerIssue.js.map +1 -0
  246. package/dist/plus/integrations/reads/warnings.d.ts +2 -15
  247. package/dist/plus/integrations/reads/warnings.d.ts.map +1 -1
  248. package/dist/plus/integrations/reads/warnings.js +19 -1
  249. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  250. package/dist/plus/integrations/results.d.ts +4 -20
  251. package/dist/plus/integrations/results.d.ts.map +1 -1
  252. package/dist/plus/integrations/results.js.map +1 -1
  253. package/dist/utils/promise.d.ts +2 -0
  254. package/dist/utils/promise.d.ts.map +1 -1
  255. package/dist/utils/promise.js +11 -0
  256. package/dist/utils/promise.js.map +1 -1
  257. package/dist/utils/promiseCache.d.ts +19 -0
  258. package/dist/utils/promiseCache.d.ts.map +1 -1
  259. package/dist/utils/promiseCache.js +30 -0
  260. package/dist/utils/promiseCache.js.map +1 -1
  261. package/dist/utils/resourceUsage.d.ts +5 -0
  262. package/dist/utils/resourceUsage.d.ts.map +1 -0
  263. package/dist/utils/resourceUsage.js +2 -0
  264. package/dist/utils/resourceUsage.js.map +1 -0
  265. package/dist/utils/string.d.ts +12 -0
  266. package/dist/utils/string.d.ts.map +1 -1
  267. package/dist/utils/string.js +36 -1
  268. package/dist/utils/string.js.map +1 -1
  269. package/docs/integrations.md +48 -33
  270. package/docs/kepler-read-api-parity.md +25 -4
  271. package/package.json +12 -4
  272. package/src/git/cache.ts +36 -0
  273. package/src/git/context.ts +11 -0
  274. package/src/git/errors.ts +13 -1
  275. package/src/git/features.ts +51 -0
  276. package/src/git/gitHealth.ts +522 -0
  277. package/src/git/models/search.ts +19 -4
  278. package/src/git/parsers/diffParser.ts +27 -4
  279. package/src/git/providers/config.ts +42 -1
  280. package/src/git/providers/graph.ts +12 -0
  281. package/src/git/providers/maintenance.ts +224 -0
  282. package/src/git/providers/operations.ts +10 -0
  283. package/src/git/providers/pausedOperations.ts +3 -0
  284. package/src/git/providers/provider.ts +2 -0
  285. package/src/git/providers/tags.ts +1 -0
  286. package/src/git/repositoryService.ts +1 -0
  287. package/src/git/run.types.ts +8 -0
  288. package/src/git/service.ts +3 -0
  289. package/src/git/utils/search.utils.ts +129 -5
  290. package/src/git/watching/watchService.ts +10 -0
  291. package/src/git-cli/cliGitProvider.ts +25 -0
  292. package/src/git-cli/exec/git.ts +120 -6
  293. package/src/git-cli/exec/gitQueue.ts +19 -17
  294. package/src/git-cli/parsers/logParser.ts +4 -1
  295. package/src/git-cli/providers/blame.ts +3 -8
  296. package/src/git-cli/providers/branches.ts +28 -8
  297. package/src/git-cli/providers/commits.ts +34 -2
  298. package/src/git-cli/providers/config.ts +38 -6
  299. package/src/git-cli/providers/graph.ts +107 -7
  300. package/src/git-cli/providers/maintenance.ts +2599 -0
  301. package/src/git-cli/providers/operations.ts +11 -0
  302. package/src/git-cli/providers/pausedOperations.ts +7 -2
  303. package/src/git-cli/providers/tags.ts +36 -1
  304. package/src/plus/agents/agentCapabilities.ts +286 -0
  305. package/src/plus/agents/providers/claudeCodeTranscript.ts +313 -58
  306. package/src/plus/agents/providers/{claudeCodeProvider.ts → gkAgentProvider.ts} +1123 -277
  307. package/src/plus/agents/types.ts +137 -40
  308. package/src/plus/ai/models/promptTemplates.ts +1 -1
  309. package/src/plus/ai/prompts.ts +62 -4
  310. package/src/plus/git-github/api/github.ts +404 -82
  311. package/src/plus/git-github/api/issueSearchQuery.ts +49 -1
  312. package/src/plus/git-github/providers/github/blame.ts +2 -1
  313. package/src/plus/integrations/collectionMetadata.ts +23 -1
  314. package/src/plus/integrations/context.ts +1 -1
  315. package/src/plus/integrations/index.ts +1 -0
  316. package/src/plus/integrations/integrationService.ts +29 -4
  317. package/src/plus/integrations/manager.ts +48 -0
  318. package/src/plus/integrations/models/gitHostIntegration.ts +165 -129
  319. package/src/plus/integrations/models/integration.ts +57 -22
  320. package/src/plus/integrations/models/issueCache.ts +29 -0
  321. package/src/plus/integrations/models/issueReads.ts +15 -0
  322. package/src/plus/integrations/models/issuesIntegration.ts +38 -8
  323. package/src/plus/integrations/providers/azureDevOps.ts +16 -13
  324. package/src/plus/integrations/providers/bitbucket-server.ts +4 -6
  325. package/src/plus/integrations/providers/bitbucket.ts +3 -4
  326. package/src/plus/integrations/providers/github.ts +23 -7
  327. package/src/plus/integrations/providers/gitlab.ts +4 -6
  328. package/src/plus/integrations/providers/jira.ts +52 -26
  329. package/src/plus/integrations/providers/jiraIssueByKey.ts +155 -0
  330. package/src/plus/integrations/providers/linear.ts +38 -25
  331. package/src/plus/integrations/providers/models.ts +17 -5
  332. package/src/plus/integrations/providers/providerErrors.ts +115 -0
  333. package/src/plus/integrations/providers/providersApi.ts +26 -68
  334. package/src/plus/integrations/providers/trello.ts +5 -4
  335. package/src/plus/integrations/providers/utils/providerPaging.ts +14 -7
  336. package/src/plus/integrations/reads/broaden.ts +282 -70
  337. package/src/plus/integrations/reads/filters.ts +39 -1
  338. package/src/plus/integrations/reads/issueBatch.ts +197 -0
  339. package/src/plus/integrations/reads/issueTracker.ts +26 -24
  340. package/src/plus/integrations/reads/sweeps.ts +19 -12
  341. package/src/plus/integrations/reads/trackerIssue.ts +105 -0
  342. package/src/plus/integrations/reads/warnings.ts +23 -17
  343. package/src/plus/integrations/results.ts +4 -20
  344. package/src/utils/promise.ts +15 -0
  345. package/src/utils/promiseCache.ts +43 -0
  346. package/src/utils/resourceUsage.ts +5 -0
  347. package/src/utils/string.ts +38 -1
  348. package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +0 -1
  349. package/dist/plus/agents/providers/claudeCodeProvider.js.map +0 -1
@@ -66,6 +66,21 @@ export type IssuesForProjectOptions = {
66
66
  sort?: IssueSorting;
67
67
  };
68
68
 
69
+ export type ProjectIssuesDrain = {
70
+ values: IssueShape[];
71
+ metadata?: CollectionMetadata;
72
+ } & (
73
+ | { truncated: false }
74
+ | {
75
+ truncated: true;
76
+ /**
77
+ * `narrow-scope` means a smaller server-side scope avoids this truncation. `none` covers incomplete
78
+ * results without that guarantee, including Linear's client-side assignee filtering.
79
+ */
80
+ recovery: 'narrow-scope' | 'none';
81
+ }
82
+ );
83
+
69
84
  /**
70
85
  * Options for the REPO-scoped issue read (`GitHostIntegration.getMyIssuesForRepos*`), the git-host counterpart of
71
86
  * {@link IssuesForProjectOptions}.
@@ -1,17 +1,16 @@
1
- import type { CollectionMetadata } from '@gitkraken/provider-apis';
2
1
  import type { Account } from '../../../git/models/author.js';
3
- import type { IssueShape } from '../../../git/models/issue.js';
2
+ import type { Issue, IssueShape } from '../../../git/models/issue.js';
4
3
  import type { ResourceDescriptor } from '../../../git/models/resourceDescriptor.js';
5
4
  import { gate } from '../../../utils/decorators/gate.js';
6
5
  import { trace } from '../../../utils/decorators/log.js';
7
6
  import { getScopedLogger } from '../../../utils/logger.scoped.js';
8
7
  import type { ProviderAuthenticationSession } from '../authentication/models.js';
9
8
  import type { IntegrationIds } from '../constants.js';
10
- import { toError } from '../errors.js';
9
+ import { IntegrationReadUnavailableError, toError } from '../errors.js';
11
10
  import type { ProviderApiCollectionResult } from '../providers/models.js';
12
11
  import type { Integration, IntegrationResult, IntegrationType } from './integration.js';
13
12
  import { IntegrationBase } from './integration.js';
14
- import type { IssuesForProjectOptions } from './issueReads.js';
13
+ import type { IssuesForProjectOptions, ProjectIssuesDrain } from './issueReads.js';
15
14
 
16
15
  export function isIssuesIntegration(integration: Integration): integration is IssuesIntegration {
17
16
  return integration.type === 'issues';
@@ -23,6 +22,39 @@ export abstract class IssuesIntegration<
23
22
  > extends IntegrationBase<ID> {
24
23
  readonly type: IntegrationType = 'issues';
25
24
 
25
+ get supportsIssueLookupByResourceId(): boolean {
26
+ return this.getProviderIssueByResourceId != null;
27
+ }
28
+
29
+ getIssueByResourceIdResult(
30
+ resourceId: string,
31
+ id: string,
32
+ options?: { connectionId?: string; expiryOverride?: boolean | number; resourceUrl?: string },
33
+ ): Promise<IntegrationResult<Issue | undefined>> {
34
+ const getProviderIssue = this.getProviderIssueByResourceId;
35
+ if (getProviderIssue == null) {
36
+ return Promise.resolve({
37
+ error: new IntegrationReadUnavailableError(
38
+ this.name,
39
+ 'does not support direct issue reads by resource id',
40
+ ),
41
+ });
42
+ }
43
+
44
+ const { resourceUrl, ...readOptions } = options ?? {};
45
+ const resource = { key: resourceId, resourceId: resourceId, resourceUrl: resourceUrl };
46
+ return this.getIssueResultCore(resource, id, readOptions, session =>
47
+ getProviderIssue.call(this, session, resourceId, id, resourceUrl),
48
+ );
49
+ }
50
+
51
+ protected getProviderIssueByResourceId?(
52
+ _session: ProviderAuthenticationSession,
53
+ _resourceId: string,
54
+ _id: string,
55
+ _resourceUrl: string | undefined,
56
+ ): Promise<Issue | undefined>;
57
+
26
58
  @trace()
27
59
  async getAccountForResource(resource: T, connectionId?: string): Promise<Account | undefined> {
28
60
  return (await this.getAccountForResourceResult(resource, connectionId))?.value;
@@ -177,9 +209,7 @@ export abstract class IssuesIntegration<
177
209
  project: T,
178
210
  options?: IssuesForProjectOptions,
179
211
  connectionId?: string,
180
- ): Promise<
181
- IntegrationResult<{ values: IssueShape[]; truncated: boolean; metadata?: CollectionMetadata } | undefined>
182
- > {
212
+ ): Promise<IntegrationResult<ProjectIssuesDrain | undefined>> {
183
213
  const scope = getScopedLogger();
184
214
  const session = await this.resolveReadSession(connectionId, scope);
185
215
  if (session == null) return undefined;
@@ -210,7 +240,7 @@ export abstract class IssuesIntegration<
210
240
  session: ProviderAuthenticationSession,
211
241
  project: T,
212
242
  options?: IssuesForProjectOptions,
213
- ): Promise<{ values: IssueShape[]; truncated: boolean; metadata?: CollectionMetadata } | undefined> {
243
+ ): Promise<ProjectIssuesDrain | undefined> {
214
244
  const values = await this.getProviderIssuesForProject(session, project, options);
215
245
  if (values == null) return undefined;
216
246
  return { values: values, truncated: false };
@@ -14,6 +14,7 @@ import type { ResourceDescriptor } from '../../../git/models/resourceDescriptor.
14
14
  import { base64 } from '../../../utils/base64.js';
15
15
  import { CancellationError } from '../../../utils/cancellation.js';
16
16
  import type { Emitter } from '../../../utils/event.js';
17
+ import { mapSettledBounded } from '../../../utils/promise.js';
17
18
  import type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';
18
19
  import type { IntegrationAuthenticationService } from '../authentication/integrationAuthenticationService.js';
19
20
  import type {
@@ -23,10 +24,10 @@ import type {
23
24
  } from '../authentication/models.js';
24
25
  import { toTokenWithInfo } from '../authentication/models.js';
25
26
  import { toCollectionScopeFailure } from '../collectionMetadata.js';
26
- import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../constants.js';
27
+ import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId, providerFanOutConcurrency } from '../constants.js';
27
28
  import type { IntegrationServiceContext } from '../context.js';
28
29
  import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
29
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
30
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
30
31
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
31
32
  import type { AccountWideIssuesResult, IntegrationKey, SearchMyIssuesOptions } from '../models/integration.js';
32
33
  import type {
@@ -56,7 +57,11 @@ import {
56
57
  toProviderPullRequestStates,
57
58
  } from './models.js';
58
59
  import type { ProvidersApi } from './providersApi.js';
59
- import { collectProviderPagedResult, flatSettledOrThrow, mergeCollectionMetadata } from './utils/providerPaging.js';
60
+ import {
61
+ collectProviderPagedResult,
62
+ flatSettledResultsOrThrow,
63
+ mergeCollectionMetadata,
64
+ } from './utils/providerPaging.js';
60
65
 
61
66
  function getAzureRepositoryIdentity(repo: Pick<AzureRepositoryDescriptor, 'owner' | 'name' | 'project'>): {
62
67
  resourceName: string;
@@ -654,9 +659,7 @@ export abstract class AzureDevOpsIntegrationBase<
654
659
  session: ProviderAuthenticationSession,
655
660
  repos?: AzureRepositoryDescriptor[],
656
661
  _cancellation?: AbortSignal,
657
- _silent?: boolean,
658
- state?: PullRequestStateFilter,
659
- _options?: SearchMyPullRequestsOptions,
662
+ options?: SearchMyPullRequestsOptions,
660
663
  ): Promise<PullRequest[] | undefined> {
661
664
  const api = await this.getProvidersApi();
662
665
  if (repos != null) {
@@ -664,7 +667,7 @@ export abstract class AzureDevOpsIntegrationBase<
664
667
  return undefined;
665
668
  }
666
669
 
667
- const states = toProviderPullRequestStates(state);
670
+ const states = toProviderPullRequestStates(options?.state);
668
671
 
669
672
  const user = await this.getProviderCurrentAccount(session);
670
673
  // Azure filters key on the identity GUID (account id), not the display name — see
@@ -683,21 +686,21 @@ export abstract class AzureDevOpsIntegrationBase<
683
686
  .filter(r => r != null)
684
687
  .flat();
685
688
 
686
- const { tokenWithInfo, options } = this.getApiOptions(session);
689
+ const { tokenWithInfo, options: apiOptions } = this.getApiOptions(session);
687
690
  const projectInputs = projects.values.map(p => ({ namespace: p.resourceName, project: p.name }));
688
691
  // Legacy array-returning path (Launchpad/focus view): unwrap `.values` from the SDK collection result.
689
692
  // The metadata (partial/failures) isn't surfaced here because this path's return type has no warning
690
693
  // channel; the metadata-aware ProviderBackend surface is getProviderMyPullRequestsForUser above.
691
694
  const assignedPrs = (
692
695
  await api.getPullRequestsForAzureProjects(tokenWithInfo, projectInputs, {
693
- ...options,
696
+ ...apiOptions,
694
697
  assigneeLogins: [user.id],
695
698
  states: states,
696
699
  })
697
700
  ).values.map(pr => this.fromAzureProviderPullRequest(pr, repoDescriptors, projects.values));
698
701
  const authoredPrs = (
699
702
  await api.getPullRequestsForAzureProjects(tokenWithInfo, projectInputs, {
700
- ...options,
703
+ ...apiOptions,
701
704
  authorLogin: user.id,
702
705
  states: states,
703
706
  })
@@ -883,7 +886,7 @@ export abstract class AzureDevOpsIntegrationBase<
883
886
  searchQuery: string,
884
887
  repos?: AzureRepositoryDescriptor[],
885
888
  cancellation?: AbortSignal,
886
- options?: { include?: PullRequestState[] },
889
+ options?: SearchPullRequestsOptions,
887
890
  ): Promise<PullRequest[] | undefined> {
888
891
  if (cancellation?.aborted) throw new CancellationError();
889
892
 
@@ -939,8 +942,8 @@ export abstract class AzureDevOpsIntegrationBase<
939
942
  project: { namespace: project.resourceName, project: project.name },
940
943
  }));
941
944
 
942
- const providerPullRequests = await flatSettledOrThrow(
943
- searchScopes.map(async scope => {
945
+ const providerPullRequests = flatSettledResultsOrThrow(
946
+ await mapSettledBounded(searchScopes, providerFanOutConcurrency, async scope => {
944
947
  const values: ProviderPullRequest[] = [];
945
948
  let page: number | undefined;
946
949
  for (let i = 0; i < 20; i++) {
@@ -25,7 +25,7 @@ import { toTokenWithInfo } from '../authentication/models.js';
25
25
  import { GitSelfManagedHostIntegrationId } from '../constants.js';
26
26
  import type { IntegrationServiceContext } from '../context.js';
27
27
  import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
28
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
28
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
29
29
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
30
30
  import type { IntegrationKey } from '../models/integration.js';
31
31
  import type { BitbucketRepositoryDescriptor } from './bitbucket/models.js';
@@ -251,9 +251,7 @@ export class BitbucketServerIntegration extends GitHostIntegration<
251
251
  session: ProviderAuthenticationSession,
252
252
  repos?: BitbucketRepositoryDescriptor[],
253
253
  _cancellation?: AbortSignal,
254
- _silent?: boolean,
255
- state?: PullRequestStateFilter,
256
- _options?: SearchMyPullRequestsOptions,
254
+ options?: SearchMyPullRequestsOptions,
257
255
  ): Promise<PullRequest[] | undefined> {
258
256
  if (repos != null) {
259
257
  // TODO: implement repos version
@@ -268,7 +266,7 @@ export class BitbucketServerIntegration extends GitHostIntegration<
268
266
  const prs = await api.getBitbucketServerPullRequestsForCurrentUser(
269
267
  toTokenWithInfo(this.id, session),
270
268
  this.apiBaseUrl,
271
- { states: toProviderPullRequestStates(state) },
269
+ { states: toProviderPullRequestStates(options?.state) },
272
270
  );
273
271
  return prs?.data.map(pr => fromProviderPullRequest(pr, this));
274
272
  }
@@ -331,7 +329,7 @@ export class BitbucketServerIntegration extends GitHostIntegration<
331
329
  searchQuery: string,
332
330
  repos?: BitbucketRepositoryDescriptor[],
333
331
  cancellation?: AbortSignal,
334
- options?: { include?: PullRequestState[] },
332
+ options?: SearchPullRequestsOptions,
335
333
  ): Promise<PullRequest[] | undefined> {
336
334
  if (cancellation?.aborted) throw new CancellationError();
337
335
 
@@ -23,7 +23,7 @@ import type {
23
23
  import { toTokenWithInfo } from '../authentication/models.js';
24
24
  import { toCollectionScopeFailure } from '../collectionMetadata.js';
25
25
  import { GitCloudHostIntegrationId } from '../constants.js';
26
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
26
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
27
27
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
28
28
  import type { BitbucketRepositoryDescriptor, BitbucketWorkspaceDescriptor } from './bitbucket/models.js';
29
29
  import type {
@@ -321,8 +321,6 @@ export class BitbucketIntegration extends GitHostIntegration<
321
321
  session: ProviderAuthenticationSession,
322
322
  repos?: BitbucketRepositoryDescriptor[],
323
323
  _cancellation?: AbortSignal,
324
- _silent?: boolean,
325
- state?: PullRequestStateFilter,
326
324
  options?: SearchMyPullRequestsOptions,
327
325
  ): Promise<PullRequest[] | undefined> {
328
326
  if (repos != null) {
@@ -330,6 +328,7 @@ export class BitbucketIntegration extends GitHostIntegration<
330
328
  return undefined;
331
329
  }
332
330
 
331
+ const state = options?.state;
333
332
  const states = toProviderPullRequestStates(state);
334
333
 
335
334
  const api = await this.getProvidersApi();
@@ -624,7 +623,7 @@ export class BitbucketIntegration extends GitHostIntegration<
624
623
  searchQuery: string,
625
624
  repos?: BitbucketRepositoryDescriptor[],
626
625
  cancellation?: AbortSignal,
627
- options?: { include?: PullRequestState[] },
626
+ options?: SearchPullRequestsOptions,
628
627
  ): Promise<PullRequest[] | undefined> {
629
628
  if (cancellation?.aborted) throw new CancellationError();
630
629
 
@@ -26,7 +26,7 @@ import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../c
26
26
  import type { IntegrationServiceContext } from '../context.js';
27
27
  import { IntegrationReadUnavailableError } from '../errors.js';
28
28
  import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
29
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
29
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
30
30
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
31
31
  import type {
32
32
  ProviderIssueSearchPage,
@@ -397,9 +397,7 @@ abstract class GitHubIntegrationBase<ID extends GitHubIntegrationIds> extends Gi
397
397
  session: ProviderAuthenticationSession,
398
398
  repos?: GitHubRepositoryDescriptor[],
399
399
  cancellation?: AbortSignal,
400
- silent?: boolean,
401
- state?: PullRequestStateFilter,
402
- _options?: SearchMyPullRequestsOptions,
400
+ options?: SearchMyPullRequestsOptions,
403
401
  ): Promise<PullRequest[] | undefined> {
404
402
  return (await this.authenticationService.apis.github)?.searchMyPullRequests(
405
403
  this,
@@ -407,8 +405,8 @@ abstract class GitHubIntegrationBase<ID extends GitHubIntegrationIds> extends Gi
407
405
  {
408
406
  repos: repos?.map(r => `${r.owner}/${r.name}`),
409
407
  baseUrl: this.apiBaseUrl,
410
- silent: silent,
411
- state: state,
408
+ silent: options?.silent,
409
+ state: options?.state,
412
410
  },
413
411
  cancellation,
414
412
  );
@@ -689,6 +687,24 @@ abstract class GitHubIntegrationBase<ID extends GitHubIntegrationIds> extends Gi
689
687
  );
690
688
  }
691
689
 
690
+ /**
691
+ * Resolves several issues by `(owner, repo, number)` in ONE request, by aliasing the point read rather than a
692
+ * search — see {@link GitHubApi.getIssuesBatch} for why that distinction is the whole design.
693
+ */
694
+ protected override async getProviderIssuesBatch(
695
+ session: ProviderAuthenticationSession,
696
+ coordinates: readonly { owner: string; repo: string; number: number }[],
697
+ cancellation?: AbortSignal,
698
+ ): Promise<(IssueShape | undefined)[] | undefined> {
699
+ return (await this.authenticationService.apis.github)?.getIssuesBatch(
700
+ this,
701
+ toTokenWithInfo(this.id, session),
702
+ coordinates,
703
+ { baseUrl: this.apiBaseUrl, includeBody: true },
704
+ cancellation,
705
+ );
706
+ }
707
+
692
708
  /**
693
709
  * Counts several pull-request scopes in ONE request. Like {@link countProviderIssues}, GitHub's `search`
694
710
  * reports `issueCount` on a zero-node selection, so a count preview costs no pull-request transfer.
@@ -716,7 +732,7 @@ abstract class GitHubIntegrationBase<ID extends GitHubIntegrationIds> extends Gi
716
732
  searchQuery: string,
717
733
  repos?: GitHubRepositoryDescriptor[],
718
734
  cancellation?: AbortSignal,
719
- options?: { include?: PullRequestState[] },
735
+ options?: SearchPullRequestsOptions,
720
736
  ): Promise<PullRequest[] | undefined> {
721
737
  return (await this.authenticationService.apis.github)?.searchPullRequests(
722
738
  this,
@@ -25,7 +25,7 @@ import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../c
25
25
  import type { IntegrationServiceContext } from '../context.js';
26
26
  import { IntegrationReadUnavailableError } from '../errors.js';
27
27
  import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
28
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
28
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
29
29
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
30
30
  import type { AccountWideIssuesResult, SearchMyIssuesOptions } from '../models/integration.js';
31
31
  import type { GitLabIntegrationIds } from './gitlab/gitlab.utils.js';
@@ -406,9 +406,7 @@ abstract class GitLabIntegrationBase<ID extends GitLabIntegrationIds> extends Gi
406
406
  session: ProviderAuthenticationSession,
407
407
  repos?: GitLabRepositoryDescriptor[],
408
408
  _cancellation?: AbortSignal,
409
- _silent?: boolean,
410
- state?: PullRequestStateFilter,
411
- _options?: SearchMyPullRequestsOptions,
409
+ options?: SearchMyPullRequestsOptions,
412
410
  ): Promise<PullRequest[] | undefined> {
413
411
  const api = await this.getProvidersApi();
414
412
  // Resolve the username from THIS session's token (multi-account: `session` may be a non-primary
@@ -421,7 +419,7 @@ abstract class GitLabIntegrationBase<ID extends GitLabIntegrationIds> extends Gi
421
419
  const apiResult = await api.getPullRequestsForUser(toTokenWithInfo(this.id, session), username, {
422
420
  isPAT: this.isEnterprise,
423
421
  baseUrl: this.isEnterprise ? `https://${this.domain}` : undefined,
424
- states: toProviderPullRequestStates(state),
422
+ states: toProviderPullRequestStates(options?.state),
425
423
  });
426
424
 
427
425
  if (apiResult == null) {
@@ -709,7 +707,7 @@ abstract class GitLabIntegrationBase<ID extends GitLabIntegrationIds> extends Gi
709
707
  searchQuery: string,
710
708
  repos?: GitLabRepositoryDescriptor[],
711
709
  cancellation?: AbortSignal,
712
- options?: { include?: PullRequestState[] },
710
+ options?: SearchPullRequestsOptions,
713
711
  ): Promise<PullRequest[] | undefined> {
714
712
  const api = await this.authenticationService.apis.gitlab;
715
713
  if (!api) {
@@ -10,7 +10,7 @@ import type { ProviderAuthenticationSession } from '../authentication/models.js'
10
10
  import { toTokenWithInfo } from '../authentication/models.js';
11
11
  import { throwIfCallerContractError, toCollectionScopeFailure } from '../collectionMetadata.js';
12
12
  import { IssuesCloudHostIntegrationId } from '../constants.js';
13
- import type { IssuesForProjectOptions } from '../models/issueReads.js';
13
+ import type { IssuesForProjectOptions, ProjectIssuesDrain } from '../models/issueReads.js';
14
14
  import { IssuesIntegration } from '../models/issuesIntegration.js';
15
15
  import type { ProviderApiCollectionResult, ProviderIssue } from './models.js';
16
16
  import { IssueFilter, providersMetadata, toAccount, toIssueShape } from './models.js';
@@ -20,6 +20,12 @@ const metadata = providersMetadata[IssuesCloudHostIntegrationId.Jira];
20
20
  const authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });
21
21
  const maxPagesPerRequest = 10;
22
22
 
23
+ type JiraProjectIssuesDrain<T> = {
24
+ issues: T[];
25
+ status: 'complete' | 'backstop' | 'incomplete';
26
+ metadata?: CollectionMetadata;
27
+ };
28
+
23
29
  export type JiraBaseDescriptor = IssueResourceDescriptor;
24
30
 
25
31
  export interface JiraOrganizationDescriptor extends JiraBaseDescriptor {
@@ -244,16 +250,11 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
244
250
  session: ProviderAuthenticationSession,
245
251
  project: JiraProjectDescriptor,
246
252
  options?: IssuesForProjectOptions,
247
- ): Promise<{ values: IssueShape[]; truncated: boolean; metadata?: CollectionMetadata } | undefined> {
253
+ ): Promise<ProjectIssuesDrain | undefined> {
248
254
  const tokenWithInfo = toTokenWithInfo(this.id, session);
249
255
 
250
256
  const api = await this.getProvidersApi();
251
257
 
252
- // Drain every page for a project read (bounded by a defensive backstop): the paged wrapper preserves the
253
- // SDK's cursor, unlike the plain read which silently caps at the first page. `filter` undefined = the
254
- // unscoped project read. Reports `truncated` when the drain stopped at the backstop with more pages
255
- // still available, and records a structured failure if a page-level error discarded the rest of the drain,
256
- // so the facade can warn + set fetchFailed while preserving the already-fetched prefix.
257
258
  const projectScope = {
258
259
  providerId: this.id,
259
260
  resourceId: project.resourceId,
@@ -263,10 +264,10 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
263
264
  authorLogin?: string;
264
265
  assigneeLogins?: string[];
265
266
  mentionLogin?: string;
266
- }): Promise<{ issues: ProviderIssue[]; truncated: boolean; metadata?: CollectionMetadata }> => {
267
+ }): Promise<JiraProjectIssuesDrain<ProviderIssue>> => {
267
268
  const collected: ProviderIssue[] = [];
268
269
  let cursor: string | undefined;
269
- let truncated = false;
270
+ let status: JiraProjectIssuesDrain<ProviderIssue>['status'] = 'complete';
270
271
  let metadata: CollectionMetadata | undefined;
271
272
  for (let i = 0; i < maxPagesPerRequest; i++) {
272
273
  let result: Awaited<ReturnType<typeof api.getIssuesForProjectPaged>> | undefined;
@@ -283,7 +284,7 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
283
284
  // than an empty partial success.
284
285
  if (collected.length === 0) throw ex;
285
286
 
286
- truncated = true;
287
+ status = 'incomplete';
287
288
  metadata = mergeCollectionMetadata(metadata, {
288
289
  completeness: 'partial',
289
290
  failures: [toCollectionScopeFailure(projectScope, ex)],
@@ -293,7 +294,7 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
293
294
  if (result == null) {
294
295
  if (cursor == null) break;
295
296
 
296
- truncated = true;
297
+ status = 'incomplete';
297
298
  metadata = mergeCollectionMetadata(metadata, {
298
299
  completeness: 'partial',
299
300
  failures: [
@@ -312,7 +313,7 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
312
313
  // The provider claims more pages but gave no advancing cursor: we can't continue, so the drain
313
314
  // is incomplete — flag it rather than silently stopping (matches drainPullRequests/Repositories).
314
315
  if (result.nextCursor == null || result.nextCursor === cursor) {
315
- truncated = true;
316
+ status = 'incomplete';
316
317
  metadata = mergeCollectionMetadata(metadata, {
317
318
  completeness: 'partial',
318
319
  failures: [
@@ -326,18 +327,21 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
326
327
  }
327
328
 
328
329
  cursor = result.nextCursor;
329
- // More pages remain but we're at the last allowed iteration: the drain is incomplete.
330
330
  if (i === maxPagesPerRequest - 1) {
331
- truncated = true;
331
+ status = 'backstop';
332
332
  }
333
333
  }
334
- return { issues: collected, truncated: truncated, metadata: metadata };
334
+ return {
335
+ issues: collected,
336
+ status: status,
337
+ metadata: metadata,
338
+ };
335
339
  };
336
340
 
337
341
  const getSearchedUserIssuesForFilter = async (
338
342
  user: string,
339
343
  filter: IssueFilter,
340
- ): Promise<{ issues: IssueShape[]; truncated: boolean; metadata?: CollectionMetadata }> => {
344
+ ): Promise<JiraProjectIssuesDrain<IssueShape>> => {
341
345
  const result = await drainIssues({
342
346
  authorLogin: filter === IssueFilter.Author ? user : undefined,
343
347
  assigneeLogins: filter === IssueFilter.Assignee ? [user] : undefined,
@@ -348,7 +352,7 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
348
352
  issues: result.issues
349
353
  .map(issue => toIssueShape(issue, this))
350
354
  .filter((r): r is IssueShape => r !== undefined),
351
- truncated: result.truncated,
355
+ status: result.status,
352
356
  metadata: result.metadata,
353
357
  };
354
358
  };
@@ -415,7 +419,7 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
415
419
  continue;
416
420
  }
417
421
 
418
- if (outcome.value.truncated) {
422
+ if (outcome.value.status !== 'complete') {
419
423
  truncated = true;
420
424
  }
421
425
  if (outcome.value.metadata != null) {
@@ -428,17 +432,23 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
428
432
  }
429
433
  }
430
434
 
431
- return { values: [...resultsById.values()], truncated: truncated, metadata: metadata };
435
+ return truncated
436
+ ? { values: [...resultsById.values()], truncated: true, recovery: 'none', metadata: metadata }
437
+ : { values: [...resultsById.values()], truncated: false, metadata: metadata };
432
438
  }
433
439
 
434
440
  const unscoped = await drainIssues({});
435
- return {
436
- values: unscoped.issues
437
- .map(issue => toIssueShape(issue, this))
438
- .filter((result): result is IssueShape => result !== undefined),
439
- truncated: unscoped.truncated,
440
- metadata: unscoped.metadata,
441
- };
441
+ const values = unscoped.issues
442
+ .map(issue => toIssueShape(issue, this))
443
+ .filter((result): result is IssueShape => result !== undefined);
444
+ return unscoped.status !== 'complete'
445
+ ? {
446
+ values: values,
447
+ truncated: true,
448
+ recovery: unscoped.status === 'backstop' ? 'narrow-scope' : 'none',
449
+ metadata: unscoped.metadata,
450
+ }
451
+ : { values: values, truncated: false, metadata: unscoped.metadata };
442
452
  }
443
453
 
444
454
  protected override async searchProviderMyIssues(
@@ -516,6 +526,22 @@ export class JiraIntegration extends IssuesIntegration<IssuesCloudHostIntegratio
516
526
  return issue != null ? { ...issue, type: 'issue' } : undefined;
517
527
  }
518
528
 
529
+ protected override async getProviderIssueByResourceId(
530
+ session: ProviderAuthenticationSession,
531
+ resourceId: string,
532
+ id: string,
533
+ resourceUrl: string | undefined,
534
+ ): Promise<Issue | undefined> {
535
+ if (resourceUrl == null) {
536
+ throw new Error('Jira direct issue reads require a resource URL');
537
+ }
538
+
539
+ const api = await this.getProvidersApi();
540
+ const apiResult = await api.getJiraIssueByKey(toTokenWithInfo(this.id, session), resourceId, resourceUrl, id);
541
+ const issue = apiResult != null ? toIssueShape(apiResult, this, { reliableStateCategory: true }) : undefined;
542
+ return issue != null ? { ...issue, type: 'issue' } : undefined;
543
+ }
544
+
519
545
  protected override async providerOnConnect(): Promise<void> {
520
546
  this._autolinks = undefined;
521
547
  if (this._session == null) return;