@gitkraken/core-gitlens 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/CHANGELOG.md +21 -2
  2. package/dist/git/remotes/azure-devops.js +3 -3
  3. package/dist/git/remotes/azure-devops.js.map +1 -1
  4. package/dist/git-cli/exec/git.js +1 -1
  5. package/dist/git-cli/providers/config.js +2 -2
  6. package/dist/git-cli/providers/pausedOperations.js +2 -2
  7. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  8. package/dist/git-cli/providers/staging.js +1 -1
  9. package/dist/ipc/discovery.js +1 -1
  10. package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
  11. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
  12. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -1
  13. package/dist/plus/integrations/authentication/configuredIntegrationService.js +9 -2
  14. package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -1
  15. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +1 -1
  16. package/dist/plus/integrations/index.d.ts +2 -2
  17. package/dist/plus/integrations/index.js.map +1 -1
  18. package/dist/plus/integrations/integrationService.d.ts +34 -0
  19. package/dist/plus/integrations/integrationService.js +90 -43
  20. package/dist/plus/integrations/integrationService.js.map +1 -1
  21. package/dist/plus/integrations/lite.js +5 -4
  22. package/dist/plus/integrations/lite.js.map +1 -1
  23. package/dist/plus/integrations/manager.d.ts +68 -23
  24. package/dist/plus/integrations/models/gitHostIntegration.d.ts +30 -14
  25. package/dist/plus/integrations/models/gitHostIntegration.js +59 -21
  26. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  27. package/dist/plus/integrations/models/integration.d.ts +3 -3
  28. package/dist/plus/integrations/models/integration.js +1 -1
  29. package/dist/plus/integrations/models/integration.js.map +1 -1
  30. package/dist/plus/integrations/models/issueReads.d.ts +17 -0
  31. package/dist/plus/integrations/models/pullRequestReads.d.ts +26 -0
  32. package/dist/plus/integrations/providers/azure/azure.d.ts +66 -1
  33. package/dist/plus/integrations/providers/azure/azure.js +192 -12
  34. package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
  35. package/dist/plus/integrations/providers/azure/search.d.ts +144 -0
  36. package/dist/plus/integrations/providers/azure/search.js +250 -0
  37. package/dist/plus/integrations/providers/azure/search.js.map +1 -0
  38. package/dist/plus/integrations/providers/azureDevOps.d.ts +54 -35
  39. package/dist/plus/integrations/providers/azureDevOps.js +154 -121
  40. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  41. package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +176 -0
  42. package/dist/plus/integrations/providers/azureDevOpsServer.js +560 -0
  43. package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -0
  44. package/dist/plus/integrations/providers/bitbucket-server/discovery.d.ts +12 -0
  45. package/dist/plus/integrations/providers/bitbucket-server/discovery.js +128 -0
  46. package/dist/plus/integrations/providers/bitbucket-server/discovery.js.map +1 -0
  47. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +10 -1
  48. package/dist/plus/integrations/providers/bitbucket-server/models.js +3 -2
  49. package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -1
  50. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.d.ts +58 -0
  51. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js +485 -0
  52. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js.map +1 -0
  53. package/dist/plus/integrations/providers/bitbucket-server.d.ts +52 -3
  54. package/dist/plus/integrations/providers/bitbucket-server.js +96 -20
  55. package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
  56. package/dist/plus/integrations/providers/bitbucket.js +1 -1
  57. package/dist/plus/integrations/providers/github.d.ts +5 -5
  58. package/dist/plus/integrations/providers/github.js +34 -33
  59. package/dist/plus/integrations/providers/github.js.map +1 -1
  60. package/dist/plus/integrations/providers/gitlab.d.ts +5 -3
  61. package/dist/plus/integrations/providers/gitlab.js +31 -27
  62. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  63. package/dist/plus/integrations/providers/issueSorts.d.ts +1 -0
  64. package/dist/plus/integrations/providers/jira-server.d.ts +9 -0
  65. package/dist/plus/integrations/providers/jira-server.js +13 -2
  66. package/dist/plus/integrations/providers/jira-server.js.map +1 -1
  67. package/dist/plus/integrations/providers/jira.js +1 -1
  68. package/dist/plus/integrations/providers/linear.js +1 -1
  69. package/dist/plus/integrations/providers/models.d.ts +9 -0
  70. package/dist/plus/integrations/providers/models.js +86 -0
  71. package/dist/plus/integrations/providers/models.js.map +1 -1
  72. package/dist/plus/integrations/providers/providersApi.d.ts +10 -0
  73. package/dist/plus/integrations/providers/providersApi.js +16 -1
  74. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  75. package/dist/plus/integrations/providers/utils.d.ts +12 -1
  76. package/dist/plus/integrations/providers/utils.js +36 -6
  77. package/dist/plus/integrations/providers/utils.js.map +1 -1
  78. package/dist/plus/integrations/reads/broaden.js +5 -5
  79. package/dist/plus/integrations/reads/broaden.js.map +1 -1
  80. package/dist/plus/integrations/reads/counts.d.ts +18 -4
  81. package/dist/plus/integrations/reads/counts.js +66 -15
  82. package/dist/plus/integrations/reads/counts.js.map +1 -1
  83. package/dist/plus/integrations/reads/cursors.js +1 -1
  84. package/dist/plus/integrations/reads/drains.d.ts +1 -0
  85. package/dist/plus/integrations/reads/filters.d.ts +1 -1
  86. package/dist/plus/integrations/reads/filters.js +17 -12
  87. package/dist/plus/integrations/reads/filters.js.map +1 -1
  88. package/dist/plus/integrations/reads/hierarchy.js +1 -1
  89. package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
  90. package/dist/plus/integrations/reads/issueTracker.js +1 -1
  91. package/dist/plus/integrations/reads/issues.js +1 -1
  92. package/dist/plus/integrations/reads/paging.js +1 -1
  93. package/dist/plus/integrations/reads/resolveRepository.d.ts +12 -11
  94. package/dist/plus/integrations/reads/resolveRepository.js +109 -18
  95. package/dist/plus/integrations/reads/resolveRepository.js.map +1 -1
  96. package/dist/plus/integrations/reads/searchIssues.js +4 -2
  97. package/dist/plus/integrations/reads/searchIssues.js.map +1 -1
  98. package/dist/plus/integrations/reads/searchPullRequests.js +9 -3
  99. package/dist/plus/integrations/reads/searchPullRequests.js.map +1 -1
  100. package/dist/plus/integrations/reads/trackerIssue.d.ts +9 -5
  101. package/dist/plus/integrations/reads/trackerIssue.js +15 -9
  102. package/dist/plus/integrations/reads/trackerIssue.js.map +1 -1
  103. package/dist/plus/integrations/reads/warnings.d.ts +6 -2
  104. package/dist/plus/integrations/reads/warnings.js +15 -19
  105. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  106. package/dist/plus/integrations/utils/domain.utils.d.ts +19 -0
  107. package/dist/plus/integrations/utils/domain.utils.js +36 -1
  108. package/dist/plus/integrations/utils/domain.utils.js.map +1 -1
  109. package/dist/plus/integrations/utils/integration.utils.d.ts +1 -0
  110. package/dist/plus/integrations/utils/integration.utils.js +12 -1
  111. package/dist/plus/integrations/utils/integration.utils.js.map +1 -1
  112. package/dist/utils/env/node/exec.js +2 -2
  113. package/docs/integrations.md +176 -73
  114. package/docs/kepler-read-api-parity.md +19 -6
  115. package/package.json +1 -1
@@ -113,39 +113,42 @@ provider before calling the token backend; never reuse an id discovered under a
113
113
  Every read returns `ProviderResult<T>` (`items` + `warnings` + `fetchFailed?`), and every paged read extends
114
114
  it with `page` + `hasMore` + `cursor?`. **No read throws for a provider-side failure** — see §6.
115
115
 
116
- | Method | Returns | Scope |
117
- | ---------------------------- | ------------------------- | --------------------------------------------------------------------------------------- |
118
- | `listOrgs` | `ProviderOrganization` | Orgs / workspaces / groups; issue-tracker resources (Jira sites, …). |
119
- | `listProjects` | `ProviderOrganization` | The project tier: Azure DevOps, and issue-tracker projects. |
120
- | `listRepos` | `ProviderRepositoryShape` | Repos of an `org`, or account-wide user-affiliated repos when `org` is omitted. |
121
- | `listPullRequestsPage` | `PullRequestShape` | With `repos`: those repos' PRs. Without: the user's PRs account-wide. |
122
- | `searchPullRequestsPage` | `PullRequestShape` | PRs involving the user that match structured criteria, optionally repo/org-scoped. |
123
- | `countPullRequests` | `PullRequestCountResult` | How many PRs match each scope, fetching none of them. See §5.1. |
124
- | `listIssuesPage` | `IssueShape` | Same split, for a **git host**'s issues. |
125
- | `searchIssuesPage` | `IssueShape` | Issues matching structured criteria over a repo/org scope — **no** `@me` binding. |
126
- | `countIssues` | `IssueCountResult` | How many match each scope, fetching none of them. See §5.1. |
127
- | `getIssuesBatch` | `IssueBatchResult` | Resolves N `(owner, repo, number)` coordinates in one request; an absence is proven. |
128
- | `getTrackerIssue` | `TrackerIssueResult` | Resolves ONE tracker issue by key within a resource; an absence is proven. Jira/Linear. |
129
- | `listIssueTrackerIssuesPage` | `IssueShape` | Jira (Cloud + Data Center) / Linear / Trello (issues live under resource → project). |
130
- | `sweepPullRequests` | `ProviderSweepResult` | Drains **every** page across providers (`maxPages`, default 100). |
131
- | `sweepClosedPullRequests` | `ProviderSweepResult` | Same, pinned to `['closed','merged']`. |
132
- | `broadenIssues` | `ProviderBroadenResult` | Per-org fan-out for every visible issue, unfiltered by assignee. |
133
- | `resolveRepository` | `ResolveRepositoryResult` | Remote URL → canonical provider identity (the `gk repo resolve` equivalent). |
134
- | `getSupportedFilters` | filter capability table | Static, connection-free. See §7. |
116
+ | Method | Returns | Scope |
117
+ | ---------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------- |
118
+ | `listOrgs` | `ProviderOrganization` | Orgs / workspaces / groups / Bitbucket DC projects; issue-tracker resources (Jira sites, …). |
119
+ | `listProjects` | `ProviderOrganization` | The project tier: Azure DevOps, and issue-tracker projects. |
120
+ | `listRepos` | `ProviderRepositoryShape` | Repos of an `org`, or account-wide user-affiliated repos when `org` is omitted. |
121
+ | `listPullRequestsPage` | `PullRequestShape` | With `repos`: those repos' PRs. Without: the user's PRs account-wide. |
122
+ | `searchPullRequestsPage` | `PullRequestShape` | PRs involving the user that match structured criteria, optionally repo/org-scoped. |
123
+ | `countPullRequests` | `PullRequestCountResult` | How many PRs match each scope, fetching none where the provider can count. See §5.1. |
124
+ | `listIssuesPage` | `IssueShape` | Same split, for a **git host**'s issues. |
125
+ | `searchIssuesPage` | `IssueShape` | Issues matching structured criteria over a repo/org scope — **no** `@me` binding. |
126
+ | `countIssues` | `IssueCountResult` | How many match each scope, fetching none of them. See §5.1. |
127
+ | `getIssuesBatch` | `IssueBatchResult` | Resolves N `(owner, repo, number)` coordinates in one request; an absence is proven. |
128
+ | `getTrackerIssue` | `TrackerIssueResult` | Resolves ONE tracker issue by key within a resource; an absence is proven. Jira (Cloud + Data Center) / Linear. |
129
+ | `listIssueTrackerIssuesPage` | `IssueShape` | Jira (Cloud + Data Center) / Linear / Trello (issues live under resource → project). |
130
+ | `sweepPullRequests` | `ProviderSweepResult` | Drains **every** page across providers (`maxPages`, default 100). |
131
+ | `sweepClosedPullRequests` | `ProviderSweepResult` | Same, pinned to `['closed','merged']`. |
132
+ | `broadenIssues` | `ProviderBroadenResult` | Per-org fan-out for every visible issue, unfiltered by assignee. |
133
+ | `resolveRepository` | `ResolveRepositoryResult` | Remote URL → canonical provider identity (the `gk repo resolve` equivalent). |
134
+ | `getSupportedFilters` | filter capability table | Static, connection-free. See §7. |
135
135
 
136
136
  A provider that cannot serve a surface says so explicitly — a warning explaining that the operation is
137
137
  unsupported plus `fetchFailed`, never a silent empty page. That distinction is the whole point of the result
138
138
  shape: an empty `items` with no warning means "this account genuinely has nothing".
139
139
 
140
- `getTrackerIssue` takes `resourceId` for both supported trackers. Jira Cloud also takes `resourceUrl`, the site URL
140
+ `getTrackerIssue` takes `resourceId` for every supported tracker. Jira Cloud also takes `resourceUrl`, the site URL
141
141
  returned by `listOrgs`; the REST response only supplies an API `self` link, so the caller provides the already-known
142
- site identity rather than making this point read perform resource discovery. Linear does not need it.
142
+ site identity rather than making this point read perform resource discovery. Linear does not need it, and neither
143
+ does Jira Data Center, whose browser link is built from the connection's own base URL.
143
144
 
144
- `getTrackerIssue` does **not** serve Jira Data Center. That read takes no `domain`, so for a host-keyed tracker it
145
- would answer from whichever connection is primary — a different instance's issue under the right key, since two
146
- self-hosted instances routinely share project and issue keys. It is refused explicitly (warning + `fetchFailed`)
147
- rather than answered wrongly. Use `listIssueTrackerIssuesPage` with a `domain`, or read the issue through the
148
- integration for that host.
145
+ For Jira Data Center `resourceId` is the host — the instance's single resource, as `listOrgs` reports it — and the
146
+ read takes the `domain` its siblings take to select the instance. Unlike them it never falls back to the primary
147
+ connection: a self-managed tracker requires a `domain` or a `connectionId` with a configured host, and is refused
148
+ (warning + `fetchFailed`) otherwise. Two self-hosted instances routinely share project and issue keys, and this
149
+ read's `issue: undefined` is a proven absence a caller may cache, so an answer from whichever host happens to be
150
+ primary would be cached under a key that names a different instance. For the same reason a `resourceId` that names
151
+ a different host than the one the read resolves to is refused rather than read.
149
152
 
150
153
  ## 5. Paging
151
154
 
@@ -214,9 +217,11 @@ Omit `relationships` to search every PR in the supplied repo/org scope; without
214
217
  relationship is mandatory. This is deliberately not `involves:@me`: that GitHub shortcut excludes
215
218
  `review-requested` but includes `commenter`, so it cannot match the adjacent visible-PR list.
216
219
 
217
- The provider always orders this read most-recently-updated-first. A threaded `cursor` is exactly one upstream
218
- request; GitHub puts every active relationship × state facet into aliases in that one GraphQL document. A page
219
- number without a cursor walks from page 1. At GitHub's 1,000-result-per-facet ceiling, `page.truncated` is true and
220
+ The read is ordered by `criteria.sort`, most-recently-updated-first when omitted; the keys a provider accepts are
221
+ `getSupportedFilters().pullRequestSearch.sorts`. On GitHub/GHE a threaded `cursor` is exactly one upstream request,
222
+ since every active relationship × state facet travels as an alias in one GraphQL document; Bitbucket Data Center
223
+ has no such batching and spends one request per repository × relationship facet still being read. A page number
224
+ without a cursor walks from page 1. At GitHub's 1,000-result-per-facet ceiling, `page.truncated` is true and
220
225
  the warning's `omission` carries `totalCount`, `limit`, and `recovery: 'none'`. `totalCount` is the largest
221
226
  provider-reported pre-ceiling facet count, matching the per-search ceiling's unit; it is not the returned or
222
227
  still-reachable row count. Free text is sanitized so qualifier-shaped tokens such as `org:other` are removed
@@ -328,11 +333,23 @@ const counts = await manager.countPullRequests({
328
333
  });
329
334
  ```
330
335
 
331
- The one difference is inherent to pull requests: a scope's `states` (open/closed/merged) are counted as
332
- independent searches, so the reported `count` is the **largest** of them — the same total
336
+ The one difference is inherent to pull requests: on GitHub/GHE a scope's `states` (open/closed/merged) are
337
+ counted as independent searches, so the reported `count` is the **largest** of them — the same total
333
338
  `searchPullRequestsPage` surfaces — not their sum. Because the result ceiling applies per search, that max is
334
339
  what `exceedsProviderLimit` compares against. Several states in one scope are therefore fine (they are
335
- disjoint); only several relationships are refused.
340
+ disjoint); only several relationships are refused, except on Bitbucket Data Center (below). Azure DevOps Server
341
+ reads every state in one drain, so its count is their union (the sum, since states are disjoint), again the total
342
+ its search pages through.
343
+
344
+ Bitbucket Data Center has no count query, no total on its pages and no result ceiling, so it counts by reading
345
+ each facet's first page of up to 1,000 pull requests through the same predicates the search applies. Its `count`
346
+ is therefore the exact **union** of the requested states — the number of rows the search returns — and when a
347
+ facet has more than one page it comes back with `lowerBound: true`: a floor, to be shown as "N+" and treated as
348
+ at least that expensive. Absent `lowerBound` means the count is exact, though computed from the rows read rather
349
+ than reported by the server. Because it reads the
350
+ rows, it also counts several relationships in one scope as their exact union, the same OR the search applies, so
351
+ the one-relationship-per-scope refusal does not apply there. Each scope is its own set of requests, so a Bitbucket
352
+ Data Center count is not free the way a GitHub one is; debounce and cache it.
336
353
 
337
354
  ## 6. Failures: warnings, `fetchFailed`, `truncated`
338
355
 
@@ -539,7 +556,7 @@ read, and GitHub's carries `latestReviews` natively; account-wide (no `repos`) i
539
556
  no option opts it back in. `commitOid` is absent from both: only the full projection populates it.
540
557
 
541
558
  The paginated read that does carry the full projection is `searchPullRequestsPage` with
542
- `criteria.relationships` (GitHub/GHE, which is also the only family that exposes a filtered PR search at all):
559
+ `criteria.relationships` on GitHub/GHE (Bitbucket Data Center also exposes the search, with its native row shape):
543
560
  its results always include the review projection with `commitOid`, it honors `itemsPerPage`, and one threaded
544
561
  cursor page is exactly one upstream request — every relationship × state facet travels in the same query,
545
562
  unlike the account-wide read, which spends one request per facet per page. So a surface that pages
@@ -551,31 +568,40 @@ reach for `includeReviews`, which only exists on the all-at-once sweep.
551
568
  Derived from the provider models and `providersMetadata`. ✓ supported · ✗ reported unsupported
552
569
  (warning + `fetchFailed`) · — not applicable. Self-managed variants inherit their cloud family's hooks.
553
570
 
554
- | Surface | GitHub / GHE | GitLab / self-hosted | Bitbucket | Bitbucket DC | Azure DevOps (+ Server) | Jira (+ DC) | Linear | Trello |
555
- | ---------------------------- | :----------: | :------------------: | :-------: | :----------: | :---------------------: | :------------: | :----: | :----: |
556
- | `listOrgs` | ✓ | ✓ | ✓ | ✗ | ✓ | ✓ | ✓ | ✓ |
557
- | `listProjects` | — | — | — | — | ✓ | ✓ | ✓ | ✓ |
558
- | `listRepos` (`org`) | ✓ | ✓ | ✓ | ✗ | ✓ | ✗ | ✗ | ✗ |
559
- | `listRepos` (account-wide) | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
560
- | PRs, repo-scoped | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
561
- | PRs, account-wide | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
562
- | PR `states` account-wide | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — |
563
- | `searchPullRequestsPage` | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
564
- | `countPullRequests` | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
565
- | Issues, repo-scoped | ✓ | ✓ | ✗ | ✗ | ✓ | — | — | — |
566
- | Issues, account-wide | ✓ | ✓ | ✗ | ✗ | ✓ | — | — | — |
567
- | `searchIssuesPage` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
568
- | `countIssues` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
569
- | `getIssuesBatch` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
570
- | `getTrackerIssue` | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ (Cloud only) | ✓ | ✗ |
571
- | Issues by `org`/`project` | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✓ | ✓ |
572
- | `listIssueTrackerIssuesPage` | — | — | — | — | — | ✓ | ✓ | ✓ |
573
- | `broadenIssues` | ✓ | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ |
574
- | `resolveRepository` | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
575
-
576
- Jira Data Center inherits Jira Cloud's row everywhere except `getTrackerIssue`, which it reports unsupported (see
577
- §4). Its reads are addressed per host, so `domain` selects the instance and every read below is scoped to that one
578
- connection; a read that omits it gets the primary configured host. `listOrgs` returns exactly one resource — the
571
+ | Surface | GitHub / GHE | GitLab / self-hosted | Bitbucket | Bitbucket DC | Azure DevOps (+ Server) | Jira (+ DC) | Linear | Trello |
572
+ | ---------------------------- | :----------: | :------------------: | :-------: | :----------: | :---------------------: | :---------: | :----: | :----: |
573
+ | `listOrgs` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
574
+ | `listProjects` | — | — | — | — | ✓ | ✓ | ✓ | ✓ |
575
+ | `listRepos` (`org`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
576
+ | `listRepos` (account-wide) | ✓ | ✓ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ |
577
+ | PRs, repo-scoped | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
578
+ | PRs, account-wide | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
579
+ | PR `states` account-wide | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — |
580
+ | `searchPullRequestsPage` | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ |
581
+ | `countPullRequests` | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ |
582
+ | Issues, repo-scoped | ✓ | ✓ | ✗ | ✗ | ✓ | — | — | — |
583
+ | Issues, account-wide | ✓ | ✓ | ✗ | ✗ | ✓ | — | — | — |
584
+ | `searchIssuesPage` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
585
+ | `countIssues` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
586
+ | `getIssuesBatch` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
587
+ | `getTrackerIssue` | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✗ |
588
+ | Issues by `org`/`project` | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ | ✓ | ✓ |
589
+ | `listIssueTrackerIssuesPage` | — | — | — | — | — | ✓ | ✓ | ✓ |
590
+ | `broadenIssues` | ✓ | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ |
591
+ | `resolveRepository` | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
592
+
593
+ Bitbucket Data Center exposes its projects through `listOrgs`: both `id` and `name` are the project key.
594
+ Pass that key as `org` to `listRepos` to select a project, or omit `org` to enumerate all accessible repositories,
595
+ including personal repositories. It has no additional project tier, so `listProjects` is not applicable.
596
+ Project discovery drains up to 20 pages and reports `fetchFailed` with warnings if incomplete. Repository
597
+ discovery returns one page with an opaque continuation cursor; reuse it with the same connection and `org`.
598
+ Both reads deduplicate results across pages and retain the configured installation URL, including its context path.
599
+ A link the server returns is kept only when it names that entry on the configured installation; otherwise the web and
600
+ HTTPS links are rebuilt from the configured URL and an SSH link, whose host and port cannot be derived, is omitted.
601
+
602
+ Jira Data Center inherits Jira Cloud's row. Its reads are addressed per host, so `domain` selects the instance and
603
+ every read below is scoped to that one connection; a paged read that omits it gets the primary configured host,
604
+ while `getTrackerIssue` refuses instead (see §4). `listOrgs` returns exactly one resource — the
579
605
  instance itself, synthesized from the configured host rather than fetched — and its projects carry the display name
580
606
  as `key`, because `/rest/api/2/project` reports no project key; reads address the project by id regardless. No
581
607
  autolinks are registered for the same reason: an autolink prefix has to be the project key.
@@ -590,8 +616,16 @@ exposes a reviewed-by axis on the repo-scoped read, so it is absent from the rep
590
616
  PR **search** capabilities (`getSupportedFilters().pullRequestSearch`): GitHub/GHE express relationships
591
617
  `Author, Assignee, ReviewRequested, Reviewed, Mention`, states `open, closed, merged, all`, `text`, `updatedAfter`,
592
618
  `createdAfter`, `includeArchived`, `draft`, repository/organization scopes, and sorts
593
- `updated:desc|asc, created:desc|asc`. Every other provider declares empty lists and false flags, so the read is
594
- refused rather than returning a page that did not apply a requested criterion or scope. `updatedAfter` /
619
+ `updated:desc|asc, created:desc|asc`. Bitbucket Data Center expresses relationships `Author, ReviewRequested,
620
+ Reviewed`, states `open, closed, merged, all`, `text` (title or description), `includeArchived`, `draft`, the
621
+ repository scope, and sorts `updated:desc|asc` — no assignee or mention (its pull requests have neither), no date
622
+ filters, no `created` order, and no organization scope, since it has no project-wide pull-request list. Azure DevOps
623
+ Server expresses relationships `Author, Assignee, ReviewRequested` (the last two both read Azure's reviewers, since
624
+ it has no separate assignee), the same four states, `text` (title or description), `updatedAfter`, `createdAfter`,
625
+ `draft`, repository/organization scopes and `updated:desc|asc, created:desc|asc`; not `Reviewed`, `Mention` or
626
+ `includeArchived`. Every other provider — including Azure DevOps Services — declares empty lists and false flags,
627
+ so the read is refused rather than returning a page that did not
628
+ apply a requested criterion or scope. `updatedAfter` /
595
629
  `createdAfter` are ISO `YYYY-MM-DD` and are the most effective narrowing on a large scope — the way to bound a broad
596
630
  closed-PR read, rather than capping page iterations. `draft` is tri-state: `true` returns only drafts, `false` only
597
631
  ready-for-review PRs, and omitting it places no constraint — so a consumer sending `draft: false` must not treat it
@@ -604,11 +638,13 @@ Account-wide issue filters: GitHub/GHE `Author, Assignee, Mention` · Azure `Aut
604
638
  `Assignee, Author` · everything else none.
605
639
  Issue **search** criteria (`getSupportedFilters().issueSearch`): GitHub/GHE express all of them —
606
640
  relationships `authored, assigned, mentioned, any-assignee, unassigned`, plus `text`, `labels`, `milestone`,
607
- `updatedAfter`, `createdAfter`, `withoutLinkedPullRequest`, `state` — and every other provider declares none,
608
- so the read is refused there rather than serving a list that was never narrowed. GitLab and Azure could
609
- express most of it (GitLab: `search`, `updated_after`, `labels`, `milestone`, one relationship per REST call;
610
- Azure: WIQL per project), so the gap is unimplemented rather than impossible; `withoutLinkedPullRequest` and
611
- free text have no equivalent on either.
641
+ `updatedAfter`, `createdAfter`, `withoutLinkedPullRequest`, `state`. Azure DevOps Server expresses relationships
642
+ `authored, assigned, any-assignee, unassigned`, `text` (a title substring), `labels` (whole tags), `updatedAfter`,
643
+ `createdAfter` and `state`, and sorts `updated`, `created`, `closed`, `comments` and `title` in both directions —
644
+ not `mentioned` (`@RecentMentions` only reaches back 30 days), `milestone` or `withoutLinkedPullRequest`, and not
645
+ `priority`/`resolved`, whose process-template fields an on-premises collection may not define. Every other provider
646
+ declares none, so the read is refused there rather than serving a list that was never narrowed. GitLab and Azure
647
+ DevOps Services could express most of it, so the gap is unimplemented rather than impossible.
612
648
 
613
649
  > `supportedCloudIntegrationDescriptors.supports` (in `constants.ts`) describes what GitLens _advertises in
614
650
  > its connect UI_, including enrichment-only capabilities. It is **not** the read-capability answer — use
@@ -699,14 +735,71 @@ Markdown by this package.
699
735
  repo walk (list per workspace). The account-wide PR read drains every workspace and returns **one
700
736
  aggregate page** (no cross-workspace cursor), so `itemsPerPage` doesn't apply. The review-requested slice
701
737
  is opt-in via `includeReviewRequested: true`, because it costs an O(workspaces × repos) fan-out.
702
- - **Bitbucket Data Center** — no org discovery, no repo discovery, no issues. `provider-apis` converts the
703
- public 1-based page number to the REST `start` offset and normalizes `nextPageStart` back to a page number;
704
- the facade carries that number inside its opaque cursor.
738
+ - **Bitbucket Data Center** — projects are the org tier; repositories can be listed by project or account-wide.
739
+ Discovery follows exact `nextPageStart` offsets, with cursors bound to the connection and scope. It has no
740
+ issues. Pull-request reads use the SDK's 1-based page numbers, carried inside their own opaque cursors.
741
+ The filtered PR search reads each requested repository × relationship as its own request (a relationship
742
+ without repositories reads the user's dashboard; `Reviewed` there is two requests, the reviewer and the
743
+ participant lists, because the dashboard only filters by review status together with a role), follows each
744
+ facet's own `nextPageStart`, and binds its
745
+ cursor to the connection, the configured installation URL and the query. Every criterion is re-checked on the
746
+ rows returned, so a server that ignores one (`draft` before 8.18) narrows instead of widening. A repository that
747
+ fails becomes a scoped warning with `fetchFailed` while the others still answer, and is retried once, at the
748
+ page it missed, on the next page; if the retry fails too it is dropped and reported on every later page, so one
749
+ that never answers can't hold `hasMore` open. A 401, or a 403 on the dashboard, is the credential and fails the
750
+ read; a 403 on one repository is that repository refusing the token, reported for it alone. Several states
751
+ (and `closed`, which is `DECLINED` plus `SUPERSEDED`) are read as every state and filtered, rather than costing
752
+ a request each.
705
753
  - **Azure DevOps** — org + project scoped. Repo-scoped reads accept one org per call. Account-wide reads
706
754
  drain every project of every org and return one aggregate page; a failed project becomes a scoped warning
707
755
  while its siblings survive. Only Azure can narrow an account-wide issue read by `org`/`project`.
708
756
  `resolveRepository` needs a project in the remote URL. Azure DevOps Server uses the trusted connection's
709
- domain/protocol as `baseUrl`; the remote host must match that configured connection.
757
+ `baseUrl`, including its installation path. A repository's virtual directory must match that path and is
758
+ applied once; a connection addressed at the host root takes the repository's own virtual directory. An address
759
+ that also names a collection (`https://server/tfs/DefaultCollection`) reads that collection without repeating it:
760
+ discovery reports it as the one collection visible there, since Azure only lists collections at the server level,
761
+ and another collection's repositories need an address without the collection. Installation paths match case-insensitively, as IIS serves them. An SSH remote
762
+ that names no virtual directory is read against the whole address, since it can't tell a virtual directory from
763
+ another collection named there.
764
+
765
+ Azure DevOps Server also has the filtered searches and their counts, with the collection applied exactly once
766
+ whichever way the address is written. Scope names are encoded as URL segments (collections, projects,
767
+ repositories) or escaped as WIQL string literals (a repository's project in the work-item query), never spliced
768
+ into a qualifier syntax, so names with spaces or quotes are accepted there.
769
+ - **Work items** (`searchIssuesPage` / `countIssues`) run ONE WIQL query per page over ONE collection, with every
770
+ relationship OR-ed in it, so an item matching two relationships is one row and the count is the exact size of
771
+ the same match set. `org` names the collection; without it the repositories' collection is used, and without
772
+ either the only collection the account can see. A search across several collections is refused (pass `org`),
773
+ as is one whose repositories name a project the collection doesn't have. Repositories bound the query by
774
+ their project, since work items belong to projects. The page reads the first 20,000 matches (Azure's documented
775
+ query result limit), bounded with `$top`; past that it is `truncated` with a `provider-limit` omission carrying
776
+ `limit` and `sort` but no `totalCount`, and the count reports `exceedsProviderLimit: true` with no `count` rather
777
+ than the limit. Verified against Azure DevOps Server 2020 with 20,014 matches. A server that refuses the match set
778
+ even with `$top` (`VS402337`) fails the page (warning + `fetchFailed`, "narrow the search"), since no bounded query
779
+ could serve that order's first window; its count still reports `exceedsProviderLimit`.
780
+ A pagination pages through the ids its first page queried, kept while it keeps reading (5 minutes after the last
781
+ page, 30 at most, among the 50 most recently read paginations); every first page queries its own, so a pagination of the same query started later never
782
+ replaces it. A continuation whose snapshot is gone is refused (warning + `fetchFailed`) rather than resumed
783
+ against a fresh query, where an item moved by the `updated` order could be skipped. Restart without the cursor.
784
+ A cursor is bound to its query and refused under another one. `page` without a cursor walks from page 1 against
785
+ a fresh query. Requests use REST `api-version=5.0`, so Azure DevOps Server 2019 or later is required.
786
+ - **Pull requests** (`searchPullRequestsPage` / `countPullRequests`) drain every facet — each repository, or each
787
+ project of the `org` (every visible project when only relationships bound the search), times each
788
+ relationship — reading up to 1,000 pull requests per facet, then apply text, draft and dates, union by repository
789
+ identity (so pull request #1 in two projects stays two rows) and order the result. A pagination pages through
790
+ the drain its own first page read while it keeps reading (5 minutes after the last page, 30 at most, among the 50
791
+ most recently read paginations), from a
792
+ keyset cursor; a later first page of the same query drains anew without replacing it. A continuation whose drain
793
+ is gone, or handed to another connection, is refused like an expired work-item snapshot, since a re-drain could
794
+ move a pull request whose close date changed past the position already served. The count reuses the drain a
795
+ first page of the same query read within the last minute, and drains afresh otherwise, so a polled count stays
796
+ live. A facet that exceeds the drain bound makes the result `truncated` with no total, and its count `undefined`.
797
+ Dates that aren't `YYYY-MM-DD` are refused before anything is read, and in a count only for their own scope. A facet whose
798
+ read fails fails the whole search rather than serving a union with a hole in its order. Text matches the title
799
+ or the first 400 characters of the description (all a pull request list returns), and `updatedAfter` compares
800
+ Azure's close date (or creation date while open), since Azure reports no last-activity date. `itemsPerPage`
801
+ is per page here, not per facet. A repository name of `.` or `..` is refused rather than resolved as a path.
802
+
710
803
  - **Jira (Cloud + Data Center) / Linear / Trello** — paged by **project**, not by issue: `itemsPerPage` counts projects (default
711
804
  20), each drained in full. Passing none of `page`/`cursor`/`itemsPerPage` aggregates every matched project
712
805
  in one page. A single project exceeding its internal drain backstop shows up as `page.truncated`.
@@ -718,11 +811,21 @@ Markdown by this package.
718
811
  recovered. `hasMore` reports only untouched forward progress. A cursor can therefore remain with
719
812
  `hasMore: false`; reusing it is an explicit manual retry of failed work, not a normal paging loop.
720
813
 
814
+ Self-managed descriptors keep `domain` as the normalized host and expose the configured installation address
815
+ in `baseUrl`. Provider requests use the selected connection's address, including during account discovery.
816
+ HTTPS repository resolution requires the configured host, web port, and installation path; the installation
817
+ prefix is removed before parsing the repository identity. Without a `connectionId`, the connection whose
818
+ installation path is the longest prefix of the remote resolves it (the primary on a tie); a remote under an
819
+ installation that an unpinned read can't reach through its own session resolves as `host-mismatch` rather
820
+ than through another installation's session. SSH resolution uses the configured web address and
821
+ port, since the SSH endpoint can use a different port and omit the web installation path. If several configured
822
+ web authorities share an SSH hostname, select one with `connectionId` or a trusted `domain`.
823
+
721
824
  **`broadenIssues` vs `searchIssuesPage`.** `broadenIssues` now reads each org through the org-scoped
722
- filtered search where the provider declares one (GitHub/GHE), so it no longer discovers repositories first
723
- and no longer routes through the SDK read's recovery walk — one request per page, per org. A provider with
724
- no filtered search (Azure DevOps, GitLab) still takes the repository drain, since refusing the org would be
725
- worse. It remains the read for "fan out across these orgs, whatever repos they turn out to contain", with
825
+ filtered search where the provider declares one (GitHub/GHE, Azure DevOps Server), so it no longer discovers
826
+ repositories first and no longer routes through the SDK read's recovery walk — one request per page, per org. A
827
+ provider with no filtered search (Azure DevOps Services, GitLab) still takes the repository drain, since refusing
828
+ the org would be worse. It remains the read for "fan out across these orgs, whatever repos they turn out to contain", with
726
829
  per-provider attribution (`broadenedProviderIds` / `failedProviderIds` / `incompleteProviderIds`) that the
727
830
  single-provider search doesn't produce; reach for `searchIssuesPage` when you want ONE scope with an order
728
831
  you control.
@@ -156,11 +156,12 @@ was the standing argument for refusing a multi-repo "assigned to anyone" read. M
156
156
  `org:gitkraken` 315. Any scope works; only the unscoped form is meaningless (6.7 M), which is what the guards
157
157
  actually refuse.
158
158
 
159
- **Provider coverage:** GitHub/GHE only. GitLab and Azure declare no `issueSearch` capability, so the read is
160
- refused there rather than serving an unnarrowed list — unimplemented, not impossible: GitLab maps to `search` /
161
- `updated_after` / `labels` / `milestone` with one relationship per REST call (its `assignee_username` +
162
- `author_username` compose with AND, so relationships must stay separate drains), and Azure to per-project WIQL.
163
- `withoutLinkedPullRequest` and free text have no equivalent on either.
159
+ **Provider coverage:** GitHub/GHE, and Azure DevOps Server through one collection-scoped WIQL query (#5876; see
160
+ [`integrations.md` §9](./integrations.md#9-per-provider-behavior-worth-designing-around) for what it declares).
161
+ GitLab and Azure DevOps Services declare no `issueSearch` capability, so the read is refused there rather than
162
+ serving an unnarrowed list — unimplemented, not impossible: GitLab maps to `search` / `updated_after` / `labels` /
163
+ `milestone` with one relationship per REST call (its `assignee_username` + `author_username` compose with AND, so
164
+ relationships must stay separate drains).
164
165
 
165
166
  **`countPullRequests`** is the PR twin, closing the asymmetry the audit flagged: the PR side had
166
167
  `searchPullRequestsPage` but no count probe, so an explicit "search everywhere" on PRs ran blind while the same
@@ -169,7 +170,10 @@ action on issues showed a number. It reuses GitHub's `issueCount`-on-a-zero-node
169
170
  one-relationship-per-scope rules. The one PR-specific decision: a scope's `states` are counted as independent
170
171
  searches, so the reported count is the **largest** of them (the total `searchPullRequestsPage` itself surfaces
171
172
  via `Math.max` over facets), not their sum, and `exceedsProviderLimit` compares that max against the per-search
172
- ceiling. GitHub/GHE only, matching `searchPullRequestsPage`.
173
+ ceiling. GitHub/GHE, Bitbucket Data Center and Azure DevOps Server, matching `searchPullRequestsPage`. Bitbucket
174
+ Data Center counts by reading, so it reports the exact union (a floor with `lowerBound` past its first page) and
175
+ accepts several relationships in one scope; Azure's count is the union of the states from the same facet drain its
176
+ search pages through, or `undefined` past the drain bound.
173
177
 
174
178
  **Since done:** `broadenIssues`' inner per-org read WAS swapped onto the filtered search (#5804). Only that
175
179
  inner read changed — the fan-out keeps its own result type, per-org cursor bundle and per-provider
@@ -198,5 +202,14 @@ than a browser link; supplying both retains the one-request contract. Linear nee
198
202
  Linear only; Trello refuses because its single-issue read can fall back to a capped board scan for a numeric
199
203
  identifier, where a "not found" result cannot be distinguished from a card beyond the cap.
200
204
 
205
+ **Jira Data Center point reads (#5872).** The same read serves a self-hosted Jira instance once it carries the host:
206
+ `getTrackerIssue` takes the `domain` its paged siblings already took, and `resourceId` is the host itself (the
207
+ instance's single resource; one naming another host than the read resolves to is refused). It does NOT fall back to the primary connection the way the paged reads do — a
208
+ self-managed tracker requires a `domain` or a `connectionId` with a configured host and is refused otherwise —
209
+ because its proven absence is cacheable and two self-hosted instances routinely issue the same keys, so an answer
210
+ from whichever host is primary would be cached under a key naming a different instance. The branch-association
211
+ resolver (`getIssueFromGitConfigEntityIdentifier`) follows the same rule from the other side: its resolver receives
212
+ the identifier's `domain`, and a Jira Data Center identifier without one is dropped rather than resolved.
213
+
201
214
  **Kepler-side follow-up:** `ProviderScopeFilter` carries a single `repo?: string` today and needs the criteria
202
215
  set; the `provider-data` adapter then routes "All visible" to `searchIssuesPage` + `countIssues`.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gitkraken/core-gitlens",
3
3
  "description": "GitLens core — shared Git / AI / GitHub primitives for internal GitKraken consumption",
4
- "version": "0.7.0",
4
+ "version": "0.7.1",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": {
7
7
  "name": "GitKraken",