@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
@@ -0,0 +1,155 @@
1
+ import type { ProviderAccount, ProviderIssue, ProviderRequestFunction } from './models.js';
2
+
3
+ const jiraCloudApiUrl = 'https://api.atlassian.com/ex/jira';
4
+ const jiraIssueByKeyFields = [
5
+ 'assignee',
6
+ 'comment',
7
+ 'created',
8
+ 'creator',
9
+ 'description',
10
+ 'issuetype',
11
+ 'labels',
12
+ 'project',
13
+ 'status',
14
+ 'summary',
15
+ 'updated',
16
+ 'votes',
17
+ ];
18
+
19
+ type JiraIssueMemberResponse = {
20
+ accountId?: string;
21
+ displayName?: string | null;
22
+ emailAddress?: string | null;
23
+ avatarUrls?: Record<string, string | undefined>;
24
+ };
25
+
26
+ type JiraIssueStatusResponse = {
27
+ id: string;
28
+ name: string;
29
+ statusCategory: {
30
+ colorName: string;
31
+ key: string;
32
+ name: string;
33
+ };
34
+ };
35
+
36
+ type JiraIssueByKeyResponse = {
37
+ id: string;
38
+ key: string;
39
+ fields: {
40
+ assignee?: JiraIssueMemberResponse | null;
41
+ comment?: { comments?: unknown[]; total?: number };
42
+ created: string;
43
+ creator?: JiraIssueMemberResponse | null;
44
+ description?: string | null;
45
+ issuetype?: { name?: string | null };
46
+ labels?: string[];
47
+ project?: { id?: string | null; key?: string | null; name?: string | null };
48
+ status: JiraIssueStatusResponse;
49
+ summary: string;
50
+ updated: string;
51
+ votes?: { votes?: number | null };
52
+ };
53
+ };
54
+
55
+ function toAccount(member: JiraIssueMemberResponse | null | undefined): ProviderAccount | null {
56
+ if (member == null) return null;
57
+
58
+ return {
59
+ id: member.accountId ?? '',
60
+ name: member.displayName ?? null,
61
+ username: member.displayName ?? null,
62
+ email: member.emailAddress ?? null,
63
+ avatarUrl: member.avatarUrls?.['48x48'] ?? null,
64
+ url: null,
65
+ };
66
+ }
67
+
68
+ function toStatusCategory(key: string): 'TO_DO' | 'IN_PROGRESS' | 'DONE' {
69
+ switch (key.toLowerCase()) {
70
+ case 'new':
71
+ return 'TO_DO';
72
+ case 'indeterminate':
73
+ return 'IN_PROGRESS';
74
+ case 'done':
75
+ return 'DONE';
76
+ default:
77
+ return 'TO_DO';
78
+ }
79
+ }
80
+
81
+ function toIssueWebUrl(resourceUrl: string, key: string): string {
82
+ const url = new URL(resourceUrl);
83
+ url.pathname = `${url.pathname.replace(/\/+$/, '')}/browse/${encodeURIComponent(key)}`;
84
+ url.search = '';
85
+ url.hash = '';
86
+ return url.toString();
87
+ }
88
+
89
+ function fromJiraIssueByKey(issue: JiraIssueByKeyResponse, resourceId: string, resourceUrl: string): ProviderIssue {
90
+ const assignee = toAccount(issue.fields.assignee);
91
+ const project = issue.fields.project;
92
+ const status = issue.fields.status;
93
+
94
+ return {
95
+ id: issue.id,
96
+ commentCount: issue.fields.comment?.total ?? issue.fields.comment?.comments?.length ?? null,
97
+ number: issue.key,
98
+ title: issue.fields.summary,
99
+ url: toIssueWebUrl(resourceUrl, issue.key),
100
+ closedDate: null,
101
+ createdDate: new Date(issue.fields.created),
102
+ author: toAccount(issue.fields.creator),
103
+ updatedDate: new Date(issue.fields.updated),
104
+ assignees: assignee != null ? [assignee] : [],
105
+ description: issue.fields.description ?? null,
106
+ repository: null,
107
+ project:
108
+ project != null
109
+ ? {
110
+ name: project.name ?? '',
111
+ resourceId: resourceId,
112
+ key: project.key ?? null,
113
+ namespace: null,
114
+ id: project.id ?? null,
115
+ }
116
+ : undefined,
117
+ state: {
118
+ id: status.id,
119
+ name: status.name,
120
+ color: status.statusCategory.colorName,
121
+ category: toStatusCategory(status.statusCategory.key),
122
+ },
123
+ type: issue.fields.issuetype?.name ?? null,
124
+ upvoteCount: issue.fields.votes?.votes ?? null,
125
+ labels: (issue.fields.labels ?? []).map(label => ({
126
+ color: null,
127
+ description: null,
128
+ id: null,
129
+ name: label,
130
+ })),
131
+ };
132
+ }
133
+
134
+ /**
135
+ * The SDK's Jira point read performs resource and field discovery before the issue GET. This focused path uses
136
+ * caller-supplied resource identity so a cold lookup remains one upstream request.
137
+ */
138
+ export async function requestJiraIssueByKey(
139
+ request: ProviderRequestFunction,
140
+ accessToken: string,
141
+ resourceId: string,
142
+ resourceUrl: string,
143
+ key: string,
144
+ ): Promise<ProviderIssue> {
145
+ const url = new URL(
146
+ `${jiraCloudApiUrl}/${encodeURIComponent(resourceId)}/rest/api/2/issue/${encodeURIComponent(key)}`,
147
+ );
148
+ url.searchParams.set('fields', jiraIssueByKeyFields.join(','));
149
+
150
+ const response = await request<JiraIssueByKeyResponse>({
151
+ url: url.toString(),
152
+ headers: { Authorization: `Bearer ${accessToken}` },
153
+ });
154
+ return fromJiraIssueByKey(response.body, resourceId, resourceUrl);
155
+ }
@@ -12,7 +12,12 @@ import { toTokenWithInfo } from '../authentication/models.js';
12
12
  import { toCollectionScopeFailure } from '../collectionMetadata.js';
13
13
  import { IssuesCloudHostIntegrationId } from '../constants.js';
14
14
  import { IntegrationReadUnavailableError } from '../errors.js';
15
- import type { AccountWideIssuesResult, IssuesForProjectOptions, SearchMyIssuesOptions } from '../models/issueReads.js';
15
+ import type {
16
+ AccountWideIssuesResult,
17
+ IssuesForProjectOptions,
18
+ ProjectIssuesDrain,
19
+ SearchMyIssuesOptions,
20
+ } from '../models/issueReads.js';
16
21
  import { IssuesIntegration } from '../models/issuesIntegration.js';
17
22
  import type { ProviderApiCollectionResult, ProviderIssue } from './models.js';
18
23
  import { fromProviderIssue, providersMetadata, toIssueShape } from './models.js';
@@ -219,7 +224,7 @@ export class LinearIntegration extends IssuesIntegration<IssuesCloudHostIntegrat
219
224
  session: ProviderAuthenticationSession,
220
225
  project: ResourceDescriptor,
221
226
  options?: IssuesForProjectOptions,
222
- ): Promise<{ values: IssueShape[]; truncated: boolean; metadata?: CollectionMetadata } | undefined> {
227
+ ): Promise<ProjectIssuesDrain | undefined> {
223
228
  if (!isIssueResourceDescriptor(project)) return undefined;
224
229
 
225
230
  const api = await this.getProvidersApi();
@@ -256,6 +261,8 @@ export class LinearIntegration extends IssuesIntegration<IssuesCloudHostIntegrat
256
261
  requestCount += 1;
257
262
  hasMore = result.paging?.more ?? false;
258
263
  const nextCursor = result.paging?.cursor;
264
+ truncated ||= result.paging?.truncated === true;
265
+ collectionMetadata = mergeCollectionMetadata(collectionMetadata, result.metadata);
259
266
  for (const issue of result.values) {
260
267
  const shape = toIssueShape(issue, this);
261
268
  if (shape != null) {
@@ -270,7 +277,6 @@ export class LinearIntegration extends IssuesIntegration<IssuesCloudHostIntegrat
270
277
  }
271
278
 
272
279
  cursor = nextCursor;
273
- // More pages remain but we've hit the backstop: the drain is incomplete.
274
280
  if (hasMore && requestCount >= maxPagesPerRequest) {
275
281
  truncated = true;
276
282
  }
@@ -294,14 +300,16 @@ export class LinearIntegration extends IssuesIntegration<IssuesCloudHostIntegrat
294
300
  'could not resolve the current user to scope issues to',
295
301
  );
296
302
  }
297
- return {
298
- values: issues.filter(issue => issue.assignees?.some(a => a.id === viewerId)),
299
- truncated: truncated,
300
- metadata: collectionMetadata,
301
- };
303
+
304
+ const values = issues.filter(issue => issue.assignees?.some(a => a.id === viewerId));
305
+ return truncated
306
+ ? { values: values, truncated: true, recovery: 'none', metadata: collectionMetadata }
307
+ : { values: values, truncated: false, metadata: collectionMetadata };
302
308
  }
303
309
 
304
- return { values: issues, truncated: truncated, metadata: collectionMetadata };
310
+ return truncated
311
+ ? { values: issues, truncated: true, recovery: 'none', metadata: collectionMetadata }
312
+ : { values: issues, truncated: false, metadata: collectionMetadata };
305
313
  }
306
314
 
307
315
  override get id(): IssuesCloudHostIntegrationId.Linear {
@@ -433,30 +441,35 @@ export class LinearIntegration extends IssuesIntegration<IssuesCloudHostIntegrat
433
441
  return result && fromProviderIssue(result, this);
434
442
  }
435
443
 
444
+ protected override async getProviderIssueByResourceId(
445
+ session: ProviderAuthenticationSession,
446
+ resourceId: string,
447
+ id: string,
448
+ _resourceUrl: string | undefined,
449
+ ): Promise<Issue | undefined> {
450
+ const api = await this.getProvidersApi();
451
+ const result = await api.getIssue(toTokenWithInfo(this.id, session), {
452
+ resourceId: resourceId,
453
+ number: id,
454
+ });
455
+ return result && fromProviderIssue(result, this);
456
+ }
457
+
436
458
  private async getRawProviderIssue(
437
459
  session: ProviderAuthenticationSession,
438
460
  resource: ResourceDescriptor,
439
461
  id: string,
440
462
  ): Promise<ProviderIssue | undefined> {
441
463
  const api = await this.getProvidersApi();
442
- try {
443
- if (!isIssueResourceDescriptor(resource)) {
444
- Logger.error(undefined, 'getProviderIssue: resource is not an IssueResourceDescriptor');
445
- return undefined;
446
- }
447
-
448
- const result = await api.getIssue(toTokenWithInfo(this.id, session), {
449
- resourceId: resource.id,
450
- number: id,
451
- });
452
-
453
- if (result == null) return undefined;
454
-
455
- return result;
456
- } catch (ex) {
457
- Logger.error(ex, 'getProviderIssue');
464
+ if (!isIssueResourceDescriptor(resource)) {
465
+ Logger.error(undefined, 'getProviderIssue: resource is not an IssueResourceDescriptor');
458
466
  return undefined;
459
467
  }
468
+
469
+ return api.getIssue(toTokenWithInfo(this.id, session), {
470
+ resourceId: resource.id,
471
+ number: id,
472
+ });
460
473
  }
461
474
  private getIssueAutolinkLikeUrl(issue: ProviderIssue): string | null {
462
475
  const url = issue.url;
@@ -1229,13 +1229,24 @@ function toIssueIdentifier(value: string | number): string {
1229
1229
  return String(value);
1230
1230
  }
1231
1231
 
1232
- export function toIssueShape(issue: ProviderIssue, provider: ProviderReference): IssueShape | undefined {
1232
+ export function toIssueShape(
1233
+ issue: ProviderIssue,
1234
+ provider: ProviderReference,
1235
+ options?: { reliableStateCategory?: boolean },
1236
+ ): IssueShape | undefined {
1233
1237
  // TODO: Add some protections/baselines rather than killing the transformation here
1234
1238
  // `author` is intentionally not required: some providers have no per-item creator (e.g. Trello cards,
1235
1239
  // which the SDK maps with `author: null`), and dropping every such item would discard the whole board.
1236
1240
  // Fall back to an empty author instead so these issues still surface.
1237
1241
  if (issue.updatedDate == null || issue.url == null) return undefined;
1238
1242
 
1243
+ // Jira SDK results derive this category from a localized display name and default unknown names to DONE.
1244
+ // Only the direct point read opts in because it maps Jira's stable status-category key itself.
1245
+ const closed =
1246
+ issue.closedDate != null ||
1247
+ (issue.state?.category === 'DONE' &&
1248
+ (provider.id !== IssuesCloudHostIntegrationId.Jira || options?.reliableStateCategory === true));
1249
+
1239
1250
  return {
1240
1251
  type: 'issue',
1241
1252
  provider: provider,
@@ -1254,8 +1265,8 @@ export function toIssueShape(issue: ProviderIssue, provider: ProviderReference):
1254
1265
  createdDate: issue.createdDate,
1255
1266
  updatedDate: issue.updatedDate,
1256
1267
  closedDate: issue.closedDate ?? undefined,
1257
- closed: issue.closedDate != null,
1258
- state: issue.closedDate != null ? 'closed' : 'opened',
1268
+ closed: closed,
1269
+ state: closed ? 'closed' : 'opened',
1259
1270
  author: {
1260
1271
  id: issue.author?.id ?? '',
1261
1272
  // An absent name stays absent, matching {@link fromProviderAccount}; see `IssueMember.name`.
@@ -1688,6 +1699,7 @@ export function fromProviderIssue(
1688
1699
  options?: { project?: IssueProject },
1689
1700
  ): Issue {
1690
1701
  const identifier = toIssueIdentifier(issue.number);
1702
+ const closed = issue.closedDate != null || issue.state?.category === 'DONE';
1691
1703
  return new Issue(
1692
1704
  integration,
1693
1705
  identifier,
@@ -1696,8 +1708,8 @@ export function fromProviderIssue(
1696
1708
  issue.url ?? '',
1697
1709
  issue.createdDate,
1698
1710
  issue.updatedDate ?? issue.closedDate ?? issue.createdDate,
1699
- issue.closedDate != null,
1700
- issue.closedDate != null ? 'closed' : 'opened',
1711
+ closed,
1712
+ closed ? 'closed' : 'opened',
1701
1713
  fromProviderAccount(issue.author),
1702
1714
  issue.assignees?.map(fromProviderAccount) ?? undefined,
1703
1715
  issue.repository != null
@@ -0,0 +1,115 @@
1
+ import type { TokenWithInfo } from '../authentication/models.js';
2
+ import type { IntegrationIds } from '../constants.js';
3
+ import { IssuesCloudHostIntegrationId } from '../constants.js';
4
+ import {
5
+ AuthenticationError,
6
+ AuthenticationErrorReason,
7
+ isRateLimitResponse,
8
+ RequestClientError,
9
+ RequestNotFoundError,
10
+ toError,
11
+ toRateLimitError,
12
+ } from '../errors.js';
13
+
14
+ const linearIssueNotFoundMessage = /^Linear issue not found: .+$/i;
15
+ const maxProviderErrorBodyLength = 500;
16
+
17
+ type ProviderGraphQLError = {
18
+ message?: unknown;
19
+ extensions?: { code?: unknown };
20
+ };
21
+
22
+ function getProviderGraphQLErrors(body: unknown): ProviderGraphQLError[] {
23
+ if (body == null || typeof body !== 'object') return [];
24
+
25
+ const errors = (body as { errors?: unknown }).errors;
26
+ return Array.isArray(errors)
27
+ ? errors.filter((error): error is ProviderGraphQLError => error != null && typeof error === 'object')
28
+ : [];
29
+ }
30
+
31
+ function isLinearRateLimitError(providerId: IntegrationIds, ex: unknown): boolean {
32
+ if (providerId !== IssuesCloudHostIntegrationId.Linear) return false;
33
+
34
+ const body = (ex as { response?: { body?: unknown } }).response?.body;
35
+ return getProviderGraphQLErrors(body).some(error => error.extensions?.code === 'RATELIMITED');
36
+ }
37
+
38
+ export function isProviderIssueNotFoundError(providerId: IntegrationIds, ex: unknown): boolean {
39
+ if (providerId === IssuesCloudHostIntegrationId.Linear) {
40
+ return ex instanceof Error && linearIssueNotFoundMessage.test(ex.message);
41
+ }
42
+
43
+ const status = (ex as { response?: { status?: unknown } }).response?.status;
44
+ return status === 404 || status === 410 || status === 422;
45
+ }
46
+
47
+ export function throwProviderError(tokenWithInfo: TokenWithInfo, error: unknown): never {
48
+ const { accessToken: token, ...tokenInfo } = tokenWithInfo;
49
+ const providerId = tokenWithInfo.providerId;
50
+ const normalizedError = toError(error);
51
+ // Linear reports GraphQL throttling as HTTP 400, so its structured code must win over generic 4xx handling.
52
+ if (isLinearRateLimitError(providerId, error)) {
53
+ throw toRateLimitError(normalizedError, token);
54
+ }
55
+
56
+ const status = (error as { response?: { status?: unknown } }).response?.status;
57
+ if (typeof status === 'number') {
58
+ switch (status) {
59
+ case 404:
60
+ case 410:
61
+ case 422:
62
+ throw new RequestNotFoundError(normalizedError);
63
+ case 429:
64
+ throw toRateLimitError(normalizedError, token);
65
+ case 401:
66
+ case 403:
67
+ // Some hosts overload 403 for throttling; classify that before asking the user to reconnect.
68
+ if (isRateLimitResponse({ status: status, message: normalizedError.message })) {
69
+ throw toRateLimitError(normalizedError, token);
70
+ }
71
+ throw new AuthenticationError(
72
+ tokenInfo,
73
+ status === 401 ? AuthenticationErrorReason.Unauthorized : AuthenticationErrorReason.Forbidden,
74
+ normalizedError,
75
+ );
76
+ default:
77
+ if (status >= 400 && status < 500) {
78
+ throw new RequestClientError(normalizedError);
79
+ }
80
+ }
81
+ }
82
+
83
+ throw error;
84
+ }
85
+
86
+ /** Extracts the useful provider prose from an already-parsed SDK response body. */
87
+ export function getProviderResponseBodyMessage(body: unknown): string | undefined {
88
+ let message: string | undefined;
89
+ if (typeof body === 'string') {
90
+ message = body;
91
+ } else if (body != null && typeof body === 'object') {
92
+ const { message: direct, error } = body as { message?: unknown; error?: unknown };
93
+ if (typeof direct === 'string') {
94
+ message = direct;
95
+ } else if (typeof error === 'string') {
96
+ message = error;
97
+ } else if (error != null && typeof error === 'object') {
98
+ const nested = (error as { message?: unknown }).message;
99
+ if (typeof nested === 'string') {
100
+ message = nested;
101
+ }
102
+ }
103
+ if (message == null) {
104
+ const graphQLError = getProviderGraphQLErrors(body)[0];
105
+ if (typeof graphQLError?.message === 'string') {
106
+ message = graphQLError.message;
107
+ } else if (typeof graphQLError?.extensions?.code === 'string') {
108
+ message = graphQLError.extensions.code;
109
+ }
110
+ }
111
+ }
112
+
113
+ message = message?.trim();
114
+ return message ? message.slice(0, maxProviderErrorBodyLength) : undefined;
115
+ }
@@ -20,15 +20,8 @@ import {
20
20
  GitSelfManagedHostIntegrationId,
21
21
  IssuesCloudHostIntegrationId,
22
22
  } from '../constants.js';
23
- import {
24
- AuthenticationError,
25
- AuthenticationErrorReason,
26
- isRateLimitResponse,
27
- RequestClientError,
28
- RequestNotFoundError,
29
- toError,
30
- toRateLimitError,
31
- } from '../errors.js';
23
+ import { RequestNotFoundError, toError } from '../errors.js';
24
+ import { requestJiraIssueByKey } from './jiraIssueByKey.js';
32
25
  import type {
33
26
  GetIssueFn,
34
27
  GetIssuesForReposFn,
@@ -69,6 +62,7 @@ import type {
69
62
  PullRequestFilter,
70
63
  } from './models.js';
71
64
  import { isRepoIdsInput, providersMetadata } from './models.js';
65
+ import { getProviderResponseBodyMessage, isProviderIssueNotFoundError, throwProviderError } from './providerErrors.js';
72
66
  import {
73
67
  collectProviderPagedResult,
74
68
  mergeCollectionMetadata,
@@ -88,7 +82,6 @@ const createProviderApis: ProviderApisFactory =
88
82
  // `Repository <x> not found`. Anchoring to that shape (rather than a loose `not found` substring) keeps
89
83
  // the message fallbacks from misclassifying unrelated GraphQL/transport failures as a confident negative.
90
84
  const repoNotFoundMessage = /^Repository .+ not found$/i;
91
-
92
85
  // Duck-typed rather than `ex instanceof GraphQLErrors`, because importing the class as a value makes this
93
86
  // module unloadable from plain Node ESM consumers: `@gitkraken/provider-apis` is CommonJS and declares its
94
87
  // exports through getters, which Node's `cjs-module-lexer` cannot see, so the only named exports it can
@@ -562,43 +555,13 @@ export class ProvidersApi {
562
555
  }
563
556
 
564
557
  private handleProviderError<T>(tokenWithInfo: TokenWithInfo, error: any): T {
565
- const { accessToken: token, ...tokenInfo } = tokenWithInfo;
566
558
  const providerId = tokenWithInfo.providerId;
567
559
  const provider = this.providers[providerId];
568
560
  if (provider == null) {
569
561
  throw new Error(`Provider with id ${providerId} not registered`);
570
562
  }
571
563
 
572
- if (error?.response?.status != null) {
573
- const status: number = error.response.status;
574
- switch (status) {
575
- case 404: // Not found
576
- case 410: // Gone
577
- case 422: // Unprocessable Entity
578
- throw new RequestNotFoundError(error);
579
- case 429: // Too Many Requests
580
- throw toRateLimitError(error, token);
581
- case 401: // Unauthorized
582
- case 403: // Forbidden
583
- // A throttled request arrives on both statuses depending on the host (see
584
- // `isRateLimitResponse`); 403 previously skipped the check, so every provider going through the
585
- // SDK reported a rate limit as `auth` and asked the user to reconnect a healthy account.
586
- if (isRateLimitResponse({ status: status, message: error.message })) {
587
- throw toRateLimitError(error, token);
588
- }
589
- throw new AuthenticationError(
590
- tokenInfo,
591
- status === 401 ? AuthenticationErrorReason.Unauthorized : AuthenticationErrorReason.Forbidden,
592
- error,
593
- );
594
- default:
595
- if (status >= 400 && status < 500) {
596
- throw new RequestClientError(error);
597
- }
598
- }
599
- }
600
-
601
- throw error;
564
+ return throwProviderError(tokenWithInfo, error);
602
565
  }
603
566
 
604
567
  async getPagedResult<T>(
@@ -878,7 +841,7 @@ export class ProvidersApi {
878
841
  /** See {@link GetIssuesOptions.sort}. Linear expresses `created`/`updated`, descending only. */
879
842
  sort?: IssueSorting;
880
843
  },
881
- ): Promise<PagedResult<ProviderIssue>> {
844
+ ): Promise<ProviderApiPagedResult<ProviderIssue>> {
882
845
  const { provider, tokenWithInfo } = await this.ensureProviderTokenAndFunction(
883
846
  tokenOptInfo,
884
847
  'getLinearIssuesFn',
@@ -1522,7 +1485,7 @@ export class ProvidersApi {
1522
1485
  tokenOptInfo: TokenOptInfo,
1523
1486
  reposOrIds: ProviderReposInput,
1524
1487
  options?: GetIssuesOptions & { isPAT?: boolean; baseUrl?: string },
1525
- ): Promise<PagedResult<ProviderIssue>> {
1488
+ ): Promise<ProviderApiPagedResult<ProviderIssue>> {
1526
1489
  const { provider, tokenWithInfo } = await this.ensureProviderTokenAndFunction(
1527
1490
  tokenOptInfo,
1528
1491
  'getIssuesForReposFn',
@@ -1837,6 +1800,24 @@ export class ProvidersApi {
1837
1800
  );
1838
1801
  }
1839
1802
 
1803
+ async getJiraIssueByKey(
1804
+ tokenOptInfo: TokenWithInfo<IssuesCloudHostIntegrationId.Jira>,
1805
+ resourceId: string,
1806
+ resourceUrl: string,
1807
+ key: string,
1808
+ ): Promise<ProviderIssue | undefined> {
1809
+ const { tokenWithInfo } = await this.ensureProviderToken(tokenOptInfo);
1810
+
1811
+ try {
1812
+ return await requestJiraIssueByKey(this.request, tokenWithInfo.accessToken, resourceId, resourceUrl, key);
1813
+ } catch (e) {
1814
+ const status = (e as { response?: { status?: unknown } }).response?.status;
1815
+ if (status === 404) return undefined;
1816
+
1817
+ return this.handleProviderError<ProviderIssue | undefined>(tokenWithInfo, e);
1818
+ }
1819
+ }
1820
+
1840
1821
  async getIssue(
1841
1822
  tokenOptInfo: TokenWithInfo,
1842
1823
  input: { resourceId: string; number: string } | { namespace: string; name: string; number: string },
@@ -1854,6 +1835,8 @@ export class ProvidersApi {
1854
1835
 
1855
1836
  return result?.data;
1856
1837
  } catch (e) {
1838
+ if (isProviderIssueNotFoundError(tokenWithInfo.providerId, e)) return undefined;
1839
+
1857
1840
  return this.handleProviderError<ProviderIssue | undefined>(tokenWithInfo, e);
1858
1841
  }
1859
1842
  }
@@ -1896,28 +1879,3 @@ async function parseFetchResponseForApi<T>(response: Response): Promise<Provider
1896
1879
 
1897
1880
  return result;
1898
1881
  }
1899
-
1900
- const maxProviderErrorBodyLength = 500;
1901
-
1902
- /** Extracts the useful provider prose from an already-parsed SDK response body. */
1903
- function getProviderResponseBodyMessage(body: unknown): string | undefined {
1904
- let message: string | undefined;
1905
- if (typeof body === 'string') {
1906
- message = body;
1907
- } else if (body != null && typeof body === 'object') {
1908
- const { message: direct, error } = body as { message?: unknown; error?: unknown };
1909
- if (typeof direct === 'string') {
1910
- message = direct;
1911
- } else if (typeof error === 'string') {
1912
- message = error;
1913
- } else if (error != null && typeof error === 'object') {
1914
- const nested = (error as { message?: unknown }).message;
1915
- if (typeof nested === 'string') {
1916
- message = nested;
1917
- }
1918
- }
1919
- }
1920
-
1921
- message = message?.trim();
1922
- return message ? message.slice(0, maxProviderErrorBodyLength) : undefined;
1923
- }
@@ -1,4 +1,3 @@
1
- import type { CollectionMetadata } from '@gitkraken/provider-apis';
2
1
  import type { Account } from '../../../git/models/author.js';
3
2
  import type { Issue, IssueShape } from '../../../git/models/issue.js';
4
3
  import type { IssueOrPullRequest, IssueOrPullRequestType } from '../../../git/models/issueOrPullRequest.js';
@@ -9,7 +8,7 @@ import type { ProviderAuthenticationSession } from '../authentication/models.js'
9
8
  import { toTokenWithInfo } from '../authentication/models.js';
10
9
  import { IssuesCloudHostIntegrationId } from '../constants.js';
11
10
  import { IntegrationReadUnavailableError } from '../errors.js';
12
- import type { IssuesForProjectOptions } from '../models/issueReads.js';
11
+ import type { IssuesForProjectOptions, ProjectIssuesDrain } from '../models/issueReads.js';
13
12
  import { IssuesIntegration } from '../models/issuesIntegration.js';
14
13
  import { fromProviderIssue, providersMetadata, toIssueShape } from './models.js';
15
14
 
@@ -104,7 +103,7 @@ export class TrelloIntegration extends IssuesIntegration<IssuesCloudHostIntegrat
104
103
  session: ProviderAuthenticationSession,
105
104
  project: ResourceDescriptor,
106
105
  options?: IssuesForProjectOptions,
107
- ): Promise<{ values: IssueShape[]; truncated: boolean; metadata?: CollectionMetadata } | undefined> {
106
+ ): Promise<ProjectIssuesDrain | undefined> {
108
107
  // A non-issue descriptor genuinely has nothing to read (empty), but a missing app key is a broken read.
109
108
  if (!isIssueResourceDescriptor(project)) return undefined;
110
109
 
@@ -141,7 +140,9 @@ export class TrelloIntegration extends IssuesIntegration<IssuesCloudHostIntegrat
141
140
  // never a cursor. Surface that as terminal truncation; there is no next page to fetch, so retrying the
142
141
  // same read cannot recover the omitted cards (D11).
143
142
  const truncated = result.metadata != null && result.metadata.completeness !== 'complete';
144
- return { values: values, truncated: truncated, metadata: result.metadata };
143
+ return truncated
144
+ ? { values: values, truncated: true, recovery: 'none', metadata: result.metadata }
145
+ : { values: values, truncated: false, metadata: result.metadata };
145
146
  }
146
147
 
147
148
  protected override searchProviderMyIssues(
@@ -32,17 +32,24 @@ export function parsePageCursor(cursor: string | undefined): number | undefined
32
32
  }
33
33
 
34
34
  /** Preserves successful sibling scopes, but doesn't turn an all-scope provider failure into an empty success. */
35
- export async function flatSettledOrThrow<T>(promises: Promise<T[]>[]): Promise<T[]> {
36
- const results = await Promise.allSettled(promises);
37
- const fulfilled = results.filter((result): result is PromiseFulfilledResult<T[]> => result.status === 'fulfilled');
38
- if (fulfilled.length === 0) {
39
- const rejected = results.find((result): result is PromiseRejectedResult => result.status === 'rejected');
40
- if (rejected != null) throw rejected.reason;
41
- }
35
+ export function throwIfAllSettledFailed<T>(results: PromiseSettledResult<T>[]): void {
36
+ if (results.some(result => result.status === 'fulfilled')) return;
37
+
38
+ const rejected = results.find((result): result is PromiseRejectedResult => result.status === 'rejected');
39
+ if (rejected != null) throw rejected.reason;
40
+ }
42
41
 
42
+ export function flatSettledResultsOrThrow<T>(results: PromiseSettledResult<T[]>[]): T[] {
43
+ throwIfAllSettledFailed(results);
44
+
45
+ const fulfilled = results.filter((result): result is PromiseFulfilledResult<T[]> => result.status === 'fulfilled');
43
46
  return fulfilled.flatMap(result => result.value);
44
47
  }
45
48
 
49
+ export async function flatSettledOrThrow<T>(promises: Promise<T[]>[]): Promise<T[]> {
50
+ return flatSettledResultsOrThrow(await Promise.allSettled(promises));
51
+ }
52
+
46
53
  /** Precedence for merged completeness: any known omission (`partial`) wins, then inability to confirm
47
54
  * (`unknown`), and only an all-`complete` set of pages stays `complete`. */
48
55
  const completenessRank: Record<CollectionCompleteness, number> = { partial: 2, unknown: 1, complete: 0 };