@gitkraken/core-gitlens 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +23 -15
  3. package/dist/git/errors.d.ts +6 -5
  4. package/dist/git/errors.js +7 -6
  5. package/dist/git/errors.js.map +1 -1
  6. package/dist/git/features.d.ts +1 -1
  7. package/dist/git/features.js +1 -1
  8. package/dist/git/features.js.map +1 -1
  9. package/dist/git/models/remoteProvider.d.ts +4 -1
  10. package/dist/git/models/remoteProvider.js.map +1 -1
  11. package/dist/git/providers/provider.d.ts +4 -2
  12. package/dist/git/utils/branch.utils.d.ts +4 -1
  13. package/dist/git/utils/branch.utils.js +5 -2
  14. package/dist/git/utils/branch.utils.js.map +1 -1
  15. package/dist/git/utils/mergeConflicts.utils.js +2 -2
  16. package/dist/git/utils/mergeConflicts.utils.js.map +1 -1
  17. package/dist/git-cli/cliGitProvider.d.ts +14 -3
  18. package/dist/git-cli/cliGitProvider.js +71 -34
  19. package/dist/git-cli/cliGitProvider.js.map +1 -1
  20. package/dist/git-cli/exec/git.d.ts +7 -1
  21. package/dist/git-cli/exec/git.js +19 -4
  22. package/dist/git-cli/exec/git.js.map +1 -1
  23. package/dist/git-cli/providers/branchRemote.js +2 -5
  24. package/dist/git-cli/providers/branchRemote.js.map +1 -1
  25. package/dist/git-cli/providers/branches.js +4 -4
  26. package/dist/git-cli/providers/branches.js.map +1 -1
  27. package/dist/git-cli/providers/config.js +4 -1
  28. package/dist/git-cli/providers/config.js.map +1 -1
  29. package/dist/plus/ai/errors.d.ts +4 -1
  30. package/dist/plus/ai/errors.js +4 -0
  31. package/dist/plus/ai/errors.js.map +1 -1
  32. package/dist/plus/ai/providers/mistralProvider.js +1 -1
  33. package/dist/plus/ai/providers/mistralProvider.js.map +1 -1
  34. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -0
  35. package/dist/plus/ai/providers/openAICompatibleProviderBase.js.map +1 -1
  36. package/dist/plus/git-github/api/github.js +12 -13
  37. package/dist/plus/git-github/api/github.js.map +1 -1
  38. package/dist/plus/git-github/api/token.d.ts +2 -0
  39. package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts +1 -1
  40. package/dist/plus/integrations/authentication/cloudIntegrationService.js +6 -1
  41. package/dist/plus/integrations/authentication/cloudIntegrationService.js.map +1 -1
  42. package/dist/plus/integrations/authentication/configuredIntegrationService.js +2 -2
  43. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +18 -5
  44. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js.map +1 -1
  45. package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts +3 -1
  46. package/dist/plus/integrations/authentication/integrationAuthenticationService.js +4 -0
  47. package/dist/plus/integrations/authentication/integrationAuthenticationService.js.map +1 -1
  48. package/dist/plus/integrations/authentication/models.d.ts +2 -0
  49. package/dist/plus/integrations/authentication/models.js +2 -1
  50. package/dist/plus/integrations/authentication/models.js.map +1 -1
  51. package/dist/plus/integrations/authentication/observedAuthenticationProvider.js +1 -1
  52. package/dist/plus/integrations/authentication/rejectedTokenTracker.d.ts +5 -4
  53. package/dist/plus/integrations/authentication/rejectedTokenTracker.js +5 -4
  54. package/dist/plus/integrations/authentication/rejectedTokenTracker.js.map +1 -1
  55. package/dist/plus/integrations/index.d.ts +2 -2
  56. package/dist/plus/integrations/index.js +1 -1
  57. package/dist/plus/integrations/index.js.map +1 -1
  58. package/dist/plus/integrations/integrationService.d.ts +6 -0
  59. package/dist/plus/integrations/integrationService.js +3 -3
  60. package/dist/plus/integrations/integrationService.js.map +1 -1
  61. package/dist/plus/integrations/lite.js +1 -1
  62. package/dist/plus/integrations/manager.d.ts +51 -3
  63. package/dist/plus/integrations/models/gitHostIntegration.d.ts +14 -0
  64. package/dist/plus/integrations/models/gitHostIntegration.js +50 -41
  65. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  66. package/dist/plus/integrations/models/integration.d.ts +27 -5
  67. package/dist/plus/integrations/models/integration.js +57 -15
  68. package/dist/plus/integrations/models/integration.js.map +1 -1
  69. package/dist/plus/integrations/models/issueReads.d.ts +6 -0
  70. package/dist/plus/integrations/models/issuesIntegration.js +11 -11
  71. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
  72. package/dist/plus/integrations/providers/azure/azure.js +1 -1
  73. package/dist/plus/integrations/providers/azureDevOps.js +1 -1
  74. package/dist/plus/integrations/providers/azureDevOpsServer.js +1 -1
  75. package/dist/plus/integrations/providers/bitbucket/bitbucket.js +1 -1
  76. package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -1
  77. package/dist/plus/integrations/providers/bitbucket-server.js +1 -1
  78. package/dist/plus/integrations/providers/bitbucket.js +1 -1
  79. package/dist/plus/integrations/providers/github.js +1 -1
  80. package/dist/plus/integrations/providers/gitlab/gitlab.js +2 -2
  81. package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -1
  82. package/dist/plus/integrations/providers/gitlab.js +1 -1
  83. package/dist/plus/integrations/providers/jira-server.js +2 -2
  84. package/dist/plus/integrations/providers/jira.js +1 -1
  85. package/dist/plus/integrations/providers/linear.js +2 -2
  86. package/dist/plus/integrations/providers/linear.js.map +1 -1
  87. package/dist/plus/integrations/providers/models.js +2 -1
  88. package/dist/plus/integrations/providers/models.js.map +1 -1
  89. package/dist/plus/integrations/providers/providerErrors.js +9 -0
  90. package/dist/plus/integrations/providers/providerErrors.js.map +1 -1
  91. package/dist/plus/integrations/providers/providersApi.js +1 -1
  92. package/dist/plus/integrations/providers/trello.js +1 -1
  93. package/dist/plus/integrations/providers/utils.js +1 -1
  94. package/dist/plus/integrations/reads/counts.js +1 -1
  95. package/dist/plus/integrations/reads/cursors.js +1 -1
  96. package/dist/plus/integrations/reads/drains.d.ts +5 -4
  97. package/dist/plus/integrations/reads/drains.js +28 -8
  98. package/dist/plus/integrations/reads/drains.js.map +1 -1
  99. package/dist/plus/integrations/reads/hierarchy.js +1 -1
  100. package/dist/plus/integrations/reads/issueBatch.d.ts +1 -1
  101. package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
  102. package/dist/plus/integrations/reads/issueTracker.js +1 -1
  103. package/dist/plus/integrations/reads/issues.d.ts +2 -0
  104. package/dist/plus/integrations/reads/issues.js +5 -3
  105. package/dist/plus/integrations/reads/issues.js.map +1 -1
  106. package/dist/plus/integrations/reads/paging.d.ts +5 -6
  107. package/dist/plus/integrations/reads/paging.js +5 -6
  108. package/dist/plus/integrations/reads/paging.js.map +1 -1
  109. package/dist/plus/integrations/reads/pullRequests.d.ts +4 -0
  110. package/dist/plus/integrations/reads/pullRequests.js +4 -2
  111. package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
  112. package/dist/plus/integrations/reads/resolveRepository.js +1 -1
  113. package/dist/plus/integrations/reads/sweeps.js +42 -10
  114. package/dist/plus/integrations/reads/sweeps.js.map +1 -1
  115. package/dist/plus/integrations/results.d.ts +23 -3
  116. package/dist/plus/integrations/results.js.map +1 -1
  117. package/dist/plus/notifications/api.d.ts +20 -0
  118. package/dist/plus/notifications/api.js +89 -0
  119. package/dist/plus/notifications/api.js.map +1 -0
  120. package/dist/plus/notifications/context.d.ts +28 -0
  121. package/dist/plus/notifications/context.js +0 -0
  122. package/dist/plus/notifications/errors.d.ts +13 -0
  123. package/dist/plus/notifications/errors.js +22 -0
  124. package/dist/plus/notifications/errors.js.map +1 -0
  125. package/dist/plus/notifications/models.d.ts +94 -0
  126. package/dist/plus/notifications/models.js +0 -0
  127. package/dist/plus/notifications/notificationsService.d.ts +115 -0
  128. package/dist/plus/notifications/notificationsService.js +381 -0
  129. package/dist/plus/notifications/notificationsService.js.map +1 -0
  130. package/dist/plus/notifications/parse.d.ts +12 -0
  131. package/dist/plus/notifications/parse.js +152 -0
  132. package/dist/plus/notifications/parse.js.map +1 -0
  133. package/dist/plus/notifications/presentation.d.ts +28 -0
  134. package/dist/plus/notifications/presentation.js +55 -0
  135. package/dist/plus/notifications/presentation.js.map +1 -0
  136. package/dist/utils/env/node/exec.d.ts +10 -1
  137. package/dist/utils/env/node/exec.js +39 -2
  138. package/dist/utils/env/node/exec.js.map +1 -1
  139. package/docs/integrations.md +21 -2
  140. package/docs/notifications.md +239 -0
  141. package/package.json +21 -1
@@ -1,6 +1,6 @@
1
1
  import "./constants.js";
2
- import { toTokenInfo } from "./authentication/models.js";
3
2
  import { providersMetadata } from "./providers/models.js";
3
+ import { toTokenInfo } from "./authentication/models.js";
4
4
  import { GitHubApi } from "../git-github/api/github.js";
5
5
  import { AzureDevOpsApi } from "./providers/azure/azure.js";
6
6
  import { BitbucketApi } from "./providers/bitbucket/bitbucket.js";
@@ -24,9 +24,16 @@ export interface ProviderRepositoryInput {
24
24
  }
25
25
  export type ProviderRepositoriesInput = (string | number)[] | ProviderRepositoryInput[];
26
26
  /**
27
- * One provider slice in a pull-request sweep.
27
+ * One provider slice in a pull-request sweep: a provider, optionally pinned to one of its connections.
28
+ *
29
+ * A sweep may carry several targets of one provider, one per connection (two GitHub Enterprise installations,
30
+ * two Bitbucket Data Center servers, two github.com accounts). A target is identified by its provider,
31
+ * `connectionId` and the host its `domain` names; repeating one throws a `TypeError`. When a provider has more
32
+ * than one target, every one of them must name a `connectionId` or, on a self-managed provider, a `domain` (a cloud
33
+ * provider's read ignores `domain`): an unnamed target reads the provider's primary connection, which may be one
34
+ * of the named ones, so it would be read twice and its rows attributed ambiguously. A single unnamed target reads
35
+ * the primary connection.
28
36
  *
29
- * A sweep accepts at most one target per provider because its failure attribution is provider-scoped.
30
37
  * `domain` is a fallback for self-managed hosts whose authentication provider doesn't persist a configured
31
38
  * connection; a configured `connectionId` domain takes precedence when both are supplied. It must come from
32
39
  * the trusted authentication configuration, not repository or remote data.
@@ -36,7 +43,13 @@ export interface ProviderSweepTarget {
36
43
  connectionId?: string;
37
44
  domain?: string;
38
45
  /**
39
- * Relationship filters for this provider slice. With sweep-level `repos`, members are provider query
46
+ * Repositories this target reads, so each connection can carry its own. It overrides the sweep-level `repos`
47
+ * for this target, like `filters`; an empty array reads the target account-wide, as an empty sweep-level
48
+ * one does.
49
+ */
50
+ repos?: ProviderRepositoriesInput;
51
+ /**
52
+ * Relationship filters for this provider slice. With `repos`, members are provider query
40
53
  * constraints; without `repos`, they form an exact OR union. The whole set is validated against the
41
54
  * selected path's capabilities.
42
55
  *
@@ -127,6 +140,7 @@ export interface ProviderBroadenOrg {
127
140
  domain?: string;
128
141
  }
129
142
  type PullRequestSweepCommonOptions = {
143
+ /** Repositories every target reads unless it carries its own `repos`. */
130
144
  repos?: ProviderRepositoriesInput;
131
145
  /** Named `states` to match {@link IntegrationManager.listPullRequestsPage}; a mismatch here read as silently ignored. */
132
146
  states?: PullRequestStateFilter[];
@@ -158,6 +172,20 @@ type PullRequestSweepCommonOptions = {
158
172
  */
159
173
  includeReviews?: boolean;
160
174
  forceSync?: boolean;
175
+ /**
176
+ * Repo-scoped targets only: most per-repository requests one provider read keeps in flight. Defaults to 6.
177
+ * Only hosts that read repository by repository fan out — GitLab, GitLab self-managed, Bitbucket Cloud,
178
+ * Bitbucket Data Center and Azure DevOps; GitHub/GHE send one query whatever the repo count. A sweep runs up
179
+ * to 6 targets at once, each with this bound.
180
+ */
181
+ scopeConcurrency?: number;
182
+ /**
183
+ * Azure DevOps, repo-scoped targets only: `false` skips the lookup that fills each row's clone URLs, saving one
184
+ * request per repository (and fork source) per page. Rows then carry no `refs.base.url`/`refs.head.url`
185
+ * (empty) and no `cloneHttps`/`cloneSsh`, so leave it on for rows that will be checked out or matched to local
186
+ * remotes. Defaults to `true`; other providers ignore it.
187
+ */
188
+ includeRemoteInfo?: boolean;
161
189
  /**
162
190
  * Page budget per provider. A stop at this budget with a resumable cursor is reported as
163
191
  * `pagination-incomplete` with `recovery: 'page-budget'`. A part no budget reaches is reported beside it
@@ -379,6 +407,20 @@ export interface IntegrationManager {
379
407
  * ignores the option, so it is a hint rather than a guarantee about which fields are present.
380
408
  */
381
409
  summary?: boolean;
410
+ /**
411
+ * Repo-scoped only: most per-repository requests one provider read keeps in flight. Defaults to 6. Only hosts
412
+ * that read repository by repository fan out — GitLab, GitLab self-managed, Bitbucket Cloud,
413
+ * Bitbucket Data Center and Azure DevOps; GitHub/GHE send one query whatever the repo count. The
414
+ * account-wide read ignores it.
415
+ */
416
+ scopeConcurrency?: number;
417
+ /**
418
+ * Azure DevOps, repo-scoped only (the account-wide read ignores it): `false` skips the lookup that fills each
419
+ * row's clone URLs, saving one request per repository (and fork source) per page. Rows then carry no
420
+ * `refs.base.url`/`refs.head.url` (empty) and no `cloneHttps`/`cloneSsh`, so leave it on for rows that will be
421
+ * checked out or matched to local remotes. Defaults to `true`; other providers ignore it.
422
+ */
423
+ includeRemoteInfo?: boolean;
382
424
  }): Promise<ProviderPagedResult<PullRequestShape>>;
383
425
  /**
384
426
  * Pull requests matching structured criteria over a repository/organization or current-user relationship
@@ -525,6 +567,12 @@ export interface IntegrationManager {
525
567
  */
526
568
  itemsPerPage?: number;
527
569
  forceSync?: boolean;
570
+ /**
571
+ * Most per-repository requests (per-project for Azure DevOps) one provider read keeps in flight. Defaults
572
+ * to 6. Only GitLab, GitLab self-managed and Azure DevOps fan out; GitHub/GHE send one query whatever the
573
+ * repo count. Account-wide reads ignore it.
574
+ */
575
+ scopeConcurrency?: number;
528
576
  connectionId?: string;
529
577
  /** Self-managed host domain fallback; see {@link ProviderSweepTarget.domain}. */
530
578
  domain?: string;
@@ -43,6 +43,20 @@ type MyPullRequestsForReposOptions = {
43
43
  state?: PullRequestStateFilter | PullRequestStateFilter[];
44
44
  /** Requests the lightweight row shape without per-row build status or commit count. */
45
45
  summary?: boolean;
46
+ /**
47
+ * Most per-repository requests one provider read keeps in flight. Defaults to 6. Only hosts that read repository
48
+ * by repository fan out — GitLab, GitLab self-managed, Bitbucket Cloud, Bitbucket Data Center and Azure DevOps;
49
+ * GitHub/GHE send one query whatever the repo count. A value that isn't a finite number >= 1 falls back to the
50
+ * default.
51
+ */
52
+ scopeConcurrency?: number;
53
+ /**
54
+ * Azure DevOps only, repo-scoped: `false` skips the lookup that fills each row's clone URLs, saving one
55
+ * request per repository (and fork source) per page. Rows then carry no `refs.base.url`/`refs.head.url`
56
+ * (empty) and no `cloneHttps`/`cloneSsh`, so leave it on for rows that will be checked out or matched to local
57
+ * remotes. Defaults to `true`; other providers ignore it.
58
+ */
59
+ includeRemoteInfo?: boolean;
46
60
  };
47
61
  /** A repository as the batch and branch reads name it. */
48
62
  export type RepositoryCoordinate = {
@@ -3,6 +3,7 @@ import { ensureArray } from "../../../utils/array.js";
3
3
  import { isCancellationError } from "../../../utils/cancellation.js";
4
4
  import { Logger as _logger } from "../../../utils/logger.js";
5
5
  import { getScopedLogger } from "../../../utils/logger.scoped.js";
6
+ import { mapSettledBounded } from "../../../utils/promise.js";
6
7
  import { trace } from "../../../utils/decorators/log.js";
7
8
  import __decorate from "../../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
8
9
  import { RequestNotFoundError } from "../../../git/errors.js";
@@ -12,12 +13,12 @@ import { toError } from "../errors.js";
12
13
  import "../constants.js";
13
14
  import { isAzureProviderId } from "../providers/providerErrors.js";
14
15
  import { throwIfCallerContractError, toCollectionFailureError, toCollectionScopeFailure, toUnsettledScopeFailure, unsettledMissMessage } from "../collectionMetadata.js";
15
- import { toTokenWithInfo } from "../authentication/models.js";
16
16
  import "../providerFilters.js";
17
- import { areDomainsOnSameHost } from "../utils/domain.utils.js";
18
- import { getSelfManagedBaseUrl, isGitSelfManagedHostIntegrationId } from "../utils/integration.utils.js";
19
17
  import { mergeCollectionMetadata, throwIfAllSettledFailed } from "../providers/utils/providerPaging.js";
18
+ import { areDomainsOnSameHost } from "../utils/domain.utils.js";
20
19
  import { isRepoIdsInput, toIssueShape, toProviderIssueStates, toProviderPullRequestStates } from "../providers/models.js";
20
+ import { getSelfManagedBaseUrl, isGitSelfManagedHostIntegrationId } from "../utils/integration.utils.js";
21
+ import { toTokenWithInfo } from "../authentication/models.js";
21
22
  import { IntegrationBase, isReadSessionFailure } from "./integration.js";
22
23
  //#region ../plus/integrations/src/models/gitHostIntegration.ts
23
24
  /**
@@ -30,6 +31,10 @@ import { IntegrationBase, isReadSessionFailure } from "./integration.js";
30
31
  function sendsBasicCredential(providerId, session) {
31
32
  return isAzureProviderId(providerId) ? session.type !== "oauth" : void 0;
32
33
  }
34
+ /** A finite number >= 1 truncated to an integer; anything else (which would starve the pool) is the default. */
35
+ function resolveScopeConcurrency(value) {
36
+ return value != null && Number.isFinite(value) && value >= 1 ? Math.trunc(value) : 6;
37
+ }
33
38
  /**
34
39
  * Rejects each slot that read nothing (`isMiss`) for a coordinate whose repository couldn't be settled (see
35
40
  * {@link GitHostIntegration.resolveRepositoryCoordinates}): it may have addressed another repository, so its miss is
@@ -337,7 +342,7 @@ var GitHostIntegration = class extends IntegrationBase {
337
342
  scope,
338
343
  connectionId
339
344
  });
340
- else this.resetRequestExceptionCount("getOrganizationsForUser");
345
+ else this.resetRequestExceptionCount("getOrganizationsForUser", connectionId);
341
346
  return {
342
347
  value: result,
343
348
  duration: performance.now() - start
@@ -369,7 +374,7 @@ var GitHostIntegration = class extends IntegrationBase {
369
374
  try {
370
375
  const result = await this.getProviderProjectsForOrg(session, org);
371
376
  await this.confirmScopedAuthFailures(session, result?.metadata);
372
- this.resetRequestExceptionCount("getProjectsForOrg");
377
+ this.resetRequestExceptionCount("getProjectsForOrg", connectionId);
373
378
  return {
374
379
  value: result,
375
380
  duration: performance.now() - start
@@ -404,7 +409,7 @@ var GitHostIntegration = class extends IntegrationBase {
404
409
  try {
405
410
  const result = await this.getProviderRepositoriesForOrg?.(session, org, options);
406
411
  await this.confirmScopedAuthFailures(session, result?.metadata);
407
- this.resetRequestExceptionCount("getRepositoriesForOrg");
412
+ this.resetRequestExceptionCount("getRepositoriesForOrg", options?.connectionId);
408
413
  return {
409
414
  value: result,
410
415
  duration: performance.now() - start
@@ -436,7 +441,7 @@ var GitHostIntegration = class extends IntegrationBase {
436
441
  try {
437
442
  const result = await this.getProviderRepositoriesForUser(session, options);
438
443
  await this.confirmScopedAuthFailures(session, result?.metadata);
439
- this.resetRequestExceptionCount("getRepositoriesForUser");
444
+ this.resetRequestExceptionCount("getRepositoriesForUser", options?.connectionId);
440
445
  return {
441
446
  value: result,
442
447
  duration: performance.now() - start
@@ -628,6 +633,7 @@ var GitHostIntegration = class extends IntegrationBase {
628
633
  };
629
634
  }
630
635
  const unsettledProjects = toUnsettledScopeKeys(reposOrRepoIds, unsettled, (r) => `${r.namespace}\0${r.project}`);
636
+ const scopeConcurrency = resolveScopeConcurrency(options?.scopeConcurrency);
631
637
  const cursors = this.parseCursorInfo(options?.cursor).cursors ?? [];
632
638
  let projectInputs = Array.from(projects.values(), (project) => ({
633
639
  namespace: organization,
@@ -641,7 +647,7 @@ var GitHostIntegration = class extends IntegrationBase {
641
647
  let truncated = false;
642
648
  let metadata;
643
649
  const data = [];
644
- const settled = await Promise.allSettled(projectInputs.map(async (projectInput) => {
650
+ const settled = await mapSettledBounded(projectInputs, scopeConcurrency, async (projectInput) => {
645
651
  return {
646
652
  projectInput,
647
653
  results: await api.getIssuesForAzureProject(toTokenWithInfo(providerId, session), projectInput.namespace, projectInput.project, {
@@ -655,7 +661,7 @@ var GitHostIntegration = class extends IntegrationBase {
655
661
  sort: options?.sort
656
662
  })
657
663
  };
658
- }));
664
+ });
659
665
  throwIfAllSettledFailed(settled);
660
666
  for (let i = 0; i < settled.length; i++) {
661
667
  const outcome = settled[i];
@@ -700,7 +706,7 @@ var GitHostIntegration = class extends IntegrationBase {
700
706
  }
701
707
  if (options?.page != null) cursor.page = options.page;
702
708
  await this.confirmScopedAuthFailures(session, metadata);
703
- this.resetRequestExceptionCount("getIssuesForRepos");
709
+ this.resetRequestExceptionCount("getIssuesForRepos", connectionId);
704
710
  return {
705
711
  value: {
706
712
  values: data,
@@ -751,6 +757,7 @@ var GitHostIntegration = class extends IntegrationBase {
751
757
  };
752
758
  }
753
759
  if (api.getProviderIssuesPagingMode(providerId) === "repo" && !repoIdsInput) {
760
+ const scopeConcurrency = resolveScopeConcurrency(options?.scopeConcurrency);
754
761
  const cursors = this.parseCursorInfo(options?.cursor).cursors ?? [];
755
762
  let repoInputs = reposOrRepoIds.map((repo) => ({
756
763
  repo,
@@ -763,7 +770,7 @@ var GitHostIntegration = class extends IntegrationBase {
763
770
  let truncated = false;
764
771
  let metadata;
765
772
  const data = [];
766
- const settled = await Promise.allSettled(repoInputs.map(async (repoInput) => {
773
+ const settled = await mapSettledBounded(repoInputs, scopeConcurrency, async (repoInput) => {
767
774
  return {
768
775
  repoInput,
769
776
  results: await api.getIssuesForRepo(toTokenWithInfo(providerId, session), repoInput.repo, {
@@ -776,7 +783,7 @@ var GitHostIntegration = class extends IntegrationBase {
776
783
  sort: options?.sort
777
784
  })
778
785
  };
779
- }));
786
+ });
780
787
  throwIfAllSettledFailed(settled);
781
788
  for (let i = 0; i < settled.length; i++) {
782
789
  const outcome = settled[i];
@@ -806,7 +813,7 @@ var GitHostIntegration = class extends IntegrationBase {
806
813
  }
807
814
  if (options?.page != null) cursor.page = options.page;
808
815
  await this.confirmScopedAuthFailures(session, metadata);
809
- this.resetRequestExceptionCount("getIssuesForRepos");
816
+ this.resetRequestExceptionCount("getIssuesForRepos", connectionId);
810
817
  return {
811
818
  value: {
812
819
  values: data,
@@ -856,7 +863,7 @@ var GitHostIntegration = class extends IntegrationBase {
856
863
  };
857
864
  }
858
865
  await this.confirmScopedAuthFailures(session, result.metadata);
859
- this.resetRequestExceptionCount("getIssuesForRepos");
866
+ this.resetRequestExceptionCount("getIssuesForRepos", connectionId);
860
867
  return {
861
868
  value: result,
862
869
  duration: performance.now() - start
@@ -1018,6 +1025,8 @@ var GitHostIntegration = class extends IntegrationBase {
1018
1025
  if (api.getProviderPullRequestsPagingMode(providerId) === "repo" && !api.isRepoIdsInput(reposOrRepoIds)) {
1019
1026
  const toRepoInputKey = (r) => `${r.namespace}\0${r.project ?? ""}\0${r.name}`;
1020
1027
  const unsettledRepos = toUnsettledScopeKeys(reposOrRepoIds, unsettled, toRepoInputKey);
1028
+ let scopeConcurrency = resolveScopeConcurrency(options?.scopeConcurrency);
1029
+ if (providerId === "bitbucket-server") scopeConcurrency = Math.max(1, Math.floor(scopeConcurrency / Math.max(1, states?.length ?? 1)));
1021
1030
  const cursors = this.parseCursorInfo(options?.cursor).cursors ?? [];
1022
1031
  let repoInputs = reposOrRepoIds.map((repo) => ({
1023
1032
  repo,
@@ -1031,7 +1040,7 @@ var GitHostIntegration = class extends IntegrationBase {
1031
1040
  let metadata;
1032
1041
  const failures = [];
1033
1042
  const data = [];
1034
- const settled = await Promise.allSettled(repoInputs.map(async (repoInput) => {
1043
+ const settled = await mapSettledBounded(repoInputs, scopeConcurrency, async (repoInput) => {
1035
1044
  return {
1036
1045
  repoInput,
1037
1046
  results: await api.getPullRequestsForRepo(toTokenWithInfo(providerId, session), repoInput.repo, {
@@ -1042,10 +1051,10 @@ var GitHostIntegration = class extends IntegrationBase {
1042
1051
  page: repoInput.cursor == null ? options?.page : void 0,
1043
1052
  pageSize: options?.pageSize,
1044
1053
  states,
1045
- includeRemoteInfo: isAzureProviderId(providerId) ? true : void 0
1054
+ includeRemoteInfo: isAzureProviderId(providerId) && options?.includeRemoteInfo !== false ? true : void 0
1046
1055
  })
1047
1056
  };
1048
- }));
1057
+ });
1049
1058
  throwIfAllSettledFailed(settled);
1050
1059
  settled.forEach((outcome, i) => {
1051
1060
  if (outcome.status !== "fulfilled") {
@@ -1078,7 +1087,7 @@ var GitHostIntegration = class extends IntegrationBase {
1078
1087
  });
1079
1088
  if (options?.page != null) cursor.page = options.page;
1080
1089
  await this.confirmScopedAuthFailures(session, metadata);
1081
- this.resetRequestExceptionCount("getPullRequestsForRepos");
1090
+ this.resetRequestExceptionCount("getPullRequestsForRepos", connectionId);
1082
1091
  return {
1083
1092
  value: {
1084
1093
  values: data,
@@ -1112,11 +1121,11 @@ var GitHostIntegration = class extends IntegrationBase {
1112
1121
  page: options?.page,
1113
1122
  pageSize: options?.pageSize,
1114
1123
  states,
1115
- includeRemoteInfo: isAzureProviderId(providerId) ? true : void 0,
1124
+ includeRemoteInfo: isAzureProviderId(providerId) && options?.includeRemoteInfo !== false ? true : void 0,
1116
1125
  fields: options?.summary ? summaryPullRequestFields : void 0
1117
1126
  });
1118
1127
  await this.confirmScopedAuthFailures(session, result.metadata);
1119
- this.resetRequestExceptionCount("getPullRequestsForRepos");
1128
+ this.resetRequestExceptionCount("getPullRequestsForRepos", connectionId);
1120
1129
  return {
1121
1130
  value: result,
1122
1131
  duration: performance.now() - start
@@ -1141,7 +1150,7 @@ var GitHostIntegration = class extends IntegrationBase {
1141
1150
  const start = performance.now();
1142
1151
  try {
1143
1152
  const prs = await this.searchProviderMyPullRequests(session, ensureArray(repos), cancellation, searchOptions);
1144
- this.resetRequestExceptionCount("searchMyPullRequests");
1153
+ this.resetRequestExceptionCount("searchMyPullRequests", connectionId);
1145
1154
  return {
1146
1155
  value: prs,
1147
1156
  duration: performance.now() - start
@@ -1175,7 +1184,7 @@ var GitHostIntegration = class extends IntegrationBase {
1175
1184
  try {
1176
1185
  const result = await this.getProviderMyPullRequestsForUser(session, options);
1177
1186
  await this.confirmScopedAuthFailures(session, result?.metadata);
1178
- this.resetRequestExceptionCount("getMyPullRequestsForUser");
1187
+ this.resetRequestExceptionCount("getMyPullRequestsForUser", connectionId);
1179
1188
  return {
1180
1189
  value: result,
1181
1190
  duration: performance.now() - start
@@ -1243,7 +1252,7 @@ var GitHostIntegration = class extends IntegrationBase {
1243
1252
  try {
1244
1253
  const result = await this.searchProviderPullRequestsPage?.(session, options, cancellation);
1245
1254
  await this.confirmScopedAuthFailures(session, result?.metadata);
1246
- this.resetRequestExceptionCount("searchPullRequestsPage");
1255
+ this.resetRequestExceptionCount("searchPullRequestsPage", connectionId);
1247
1256
  return {
1248
1257
  value: result,
1249
1258
  duration: performance.now() - start
@@ -1267,7 +1276,7 @@ var GitHostIntegration = class extends IntegrationBase {
1267
1276
  if (session == null || isReadSessionFailure(session)) return void 0;
1268
1277
  try {
1269
1278
  const prs = await this.searchProviderPullRequests?.(session, searchQuery, ensureArray(repos), cancellation, searchOptions);
1270
- this.resetRequestExceptionCount("searchPullRequests");
1279
+ this.resetRequestExceptionCount("searchPullRequests", connectionId);
1271
1280
  return prs;
1272
1281
  } catch (ex) {
1273
1282
  this.handleProviderException("searchPullRequests", ex, {
@@ -1294,7 +1303,7 @@ var GitHostIntegration = class extends IntegrationBase {
1294
1303
  const start = performance.now();
1295
1304
  try {
1296
1305
  const result = await this.searchProviderIssuesPage?.(session, options, cancellation);
1297
- this.resetRequestExceptionCount("searchIssuesPage");
1306
+ this.resetRequestExceptionCount("searchIssuesPage", connectionId);
1298
1307
  return {
1299
1308
  value: result,
1300
1309
  duration: performance.now() - start
@@ -1325,7 +1334,7 @@ var GitHostIntegration = class extends IntegrationBase {
1325
1334
  const start = performance.now();
1326
1335
  try {
1327
1336
  const counts = await this.countProviderIssues?.(session, scopes, cancellation);
1328
- this.resetRequestExceptionCount("countIssues");
1337
+ this.resetRequestExceptionCount("countIssues", connectionId);
1329
1338
  return {
1330
1339
  value: counts,
1331
1340
  duration: performance.now() - start
@@ -1375,15 +1384,15 @@ var GitHostIntegration = class extends IntegrationBase {
1375
1384
  const targets = await this.resolveRepositoryCoordinates(session, coordinates, cancellation);
1376
1385
  slots = await this.getProviderIssuesBatch?.(session, targets.coordinates, cancellation);
1377
1386
  if (slots == null) {
1378
- this.resetRequestExceptionCount("getIssuesBatch");
1387
+ this.resetRequestExceptionCount("getIssuesBatch", connectionId);
1379
1388
  return {
1380
1389
  value: void 0,
1381
1390
  duration: performance.now() - start
1382
1391
  };
1383
1392
  }
1384
1393
  const settled = await this.settleResolvedSlots(session, targets, slots, (issue) => issue == null);
1385
- this.resetRequestExceptionCount("getIssuesBatch");
1386
- this.reportDeferredRequestFailures(settled, false);
1394
+ this.resetRequestExceptionCount("getIssuesBatch", connectionId);
1395
+ this.reportDeferredRequestFailures(settled, false, connectionId);
1387
1396
  return {
1388
1397
  value: settled,
1389
1398
  duration: performance.now() - start
@@ -1393,7 +1402,7 @@ var GitHostIntegration = class extends IntegrationBase {
1393
1402
  scope,
1394
1403
  connectionId
1395
1404
  });
1396
- this.reportDeferredRequestFailures(slots, !struck);
1405
+ this.reportDeferredRequestFailures(slots, !struck, connectionId);
1397
1406
  return {
1398
1407
  error: toError(ex),
1399
1408
  duration: performance.now() - start
@@ -1427,15 +1436,15 @@ var GitHostIntegration = class extends IntegrationBase {
1427
1436
  const targets = await this.resolveRepositoryCoordinates(session, coordinates, cancellation);
1428
1437
  slots = await this.getProviderPullRequestsBatch?.(session, targets.coordinates, options, cancellation);
1429
1438
  if (slots == null) {
1430
- this.resetRequestExceptionCount("getPullRequestsBatch");
1439
+ this.resetRequestExceptionCount("getPullRequestsBatch", connectionId);
1431
1440
  return {
1432
1441
  value: void 0,
1433
1442
  duration: performance.now() - start
1434
1443
  };
1435
1444
  }
1436
1445
  const settled = await this.settleResolvedSlots(session, targets, slots, (pr) => pr == null);
1437
- this.resetRequestExceptionCount("getPullRequestsBatch");
1438
- this.reportDeferredRequestFailures(settled, false);
1446
+ this.resetRequestExceptionCount("getPullRequestsBatch", connectionId);
1447
+ this.reportDeferredRequestFailures(settled, false, connectionId);
1439
1448
  return {
1440
1449
  value: settled,
1441
1450
  duration: performance.now() - start
@@ -1445,7 +1454,7 @@ var GitHostIntegration = class extends IntegrationBase {
1445
1454
  scope,
1446
1455
  connectionId
1447
1456
  });
1448
- this.reportDeferredRequestFailures(slots, !struck);
1457
+ this.reportDeferredRequestFailures(slots, !struck, connectionId);
1449
1458
  return {
1450
1459
  error: toError(ex),
1451
1460
  duration: performance.now() - start
@@ -1479,7 +1488,7 @@ var GitHostIntegration = class extends IntegrationBase {
1479
1488
  duration: performance.now() - start
1480
1489
  };
1481
1490
  const settled = await this.settleResolvedSlots(session, targets, read, (fields) => fields == null, { keepOtherFailures: true });
1482
- if (settled.some((slot) => slot.status === "fulfilled")) this.resetRequestExceptionCount("getIssuesEtagFields");
1491
+ if (settled.some((slot) => slot.status === "fulfilled")) this.resetRequestExceptionCount("getIssuesEtagFields", connectionId);
1483
1492
  return {
1484
1493
  value: settled,
1485
1494
  duration: performance.now() - start
@@ -1516,7 +1525,7 @@ var GitHostIntegration = class extends IntegrationBase {
1516
1525
  duration: performance.now() - start
1517
1526
  };
1518
1527
  const settled = await this.settleResolvedSlots(session, targets, read, (fields) => fields == null, { keepOtherFailures: true });
1519
- if (settled.some((slot) => slot.status === "fulfilled")) this.resetRequestExceptionCount("getPullRequestsEtagFields");
1528
+ if (settled.some((slot) => slot.status === "fulfilled")) this.resetRequestExceptionCount("getPullRequestsEtagFields", connectionId);
1520
1529
  return {
1521
1530
  value: settled,
1522
1531
  duration: performance.now() - start
@@ -1557,15 +1566,15 @@ var GitHostIntegration = class extends IntegrationBase {
1557
1566
  const resolved = await this.resolveRepositoryCoordinates(session, targets, cancellation);
1558
1567
  slots = await this.getProviderPullRequestsForBranches?.(session, resolved.coordinates, options, cancellation);
1559
1568
  if (slots == null) {
1560
- this.resetRequestExceptionCount("getPullRequestsForBranches");
1569
+ this.resetRequestExceptionCount("getPullRequestsForBranches", connectionId);
1561
1570
  return {
1562
1571
  value: void 0,
1563
1572
  duration: performance.now() - start
1564
1573
  };
1565
1574
  }
1566
1575
  const settled = await this.settleResolvedSlots(session, resolved, slots, (found) => found.pullRequests.length === 0 && !found.truncated);
1567
- this.resetRequestExceptionCount("getPullRequestsForBranches");
1568
- this.reportDeferredRequestFailures(settled, false);
1576
+ this.resetRequestExceptionCount("getPullRequestsForBranches", connectionId);
1577
+ this.reportDeferredRequestFailures(settled, false, connectionId);
1569
1578
  return {
1570
1579
  value: settled,
1571
1580
  duration: performance.now() - start
@@ -1575,7 +1584,7 @@ var GitHostIntegration = class extends IntegrationBase {
1575
1584
  scope,
1576
1585
  connectionId
1577
1586
  });
1578
- this.reportDeferredRequestFailures(slots, !struck);
1587
+ this.reportDeferredRequestFailures(slots, !struck, connectionId);
1579
1588
  return {
1580
1589
  error: toError(ex),
1581
1590
  duration: performance.now() - start
@@ -1595,7 +1604,7 @@ var GitHostIntegration = class extends IntegrationBase {
1595
1604
  const start = performance.now();
1596
1605
  try {
1597
1606
  const counts = await this.countProviderPullRequests?.(session, scopes, cancellation);
1598
- this.resetRequestExceptionCount("countPullRequests");
1607
+ this.resetRequestExceptionCount("countPullRequests", connectionId);
1599
1608
  return {
1600
1609
  value: counts,
1601
1610
  duration: performance.now() - start