@gitkraken/core-gitlens 0.10.1 → 0.10.3
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.
- package/CHANGELOG.md +17 -1
- package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts +40 -27
- package/dist/plus/integrations/authentication/configuredIntegrationService.js +92 -22
- package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -1
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +10 -6
- package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js.map +1 -1
- package/dist/plus/integrations/collectionMetadata.d.ts +1 -1
- package/dist/plus/integrations/collectionMetadata.js +19 -8
- package/dist/plus/integrations/collectionMetadata.js.map +1 -1
- package/dist/plus/integrations/errors.d.ts +2 -0
- package/dist/plus/integrations/errors.js +45 -1
- package/dist/plus/integrations/errors.js.map +1 -1
- package/dist/plus/integrations/integrationService.js +2 -1
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.js +18 -16
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +46 -8
- package/dist/plus/integrations/models/integration.js +159 -54
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/providers/azure/azure.js +2 -6
- package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.d.ts +1 -2
- package/dist/plus/integrations/providers/azureDevOps.js +12 -5
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
- package/dist/plus/integrations/providers/github.js +1 -4
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/issueSorts.d.ts +0 -1
- package/dist/plus/integrations/providers/jira.js +1 -0
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/linear.js +1 -0
- package/dist/plus/integrations/providers/linear.js.map +1 -1
- package/dist/plus/integrations/reads/drains.d.ts +0 -1
- package/dist/plus/integrations/results.d.ts +8 -5
- package/dist/plus/integrations/results.js +3 -1
- package/dist/plus/integrations/results.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitHostIntegration.js","names":[],"sources":["../../../../../plus/integrations/src/models/gitHostIntegration.ts"],"sourcesContent":["import type { CollectionMetadata, CollectionScopeFailure, GitHubPullRequestFieldMap } from '@gitkraken/provider-apis';\nimport type { Account, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { IssueSearchCriteria, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequestState as PullRequestState } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type {\n\tPullRequest,\n\tPullRequestMergeMethod,\n\tPullRequestSearchCriteria,\n\tPullRequestShape,\n\tPullRequestStackInfo,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport type { ResourceDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\nimport type { PullRequestUrlIdentity } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { ensureArray } from '@gitlens/utils/array.js';\nimport { isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { trace } from '@gitlens/utils/decorators/log.js';\nimport { first } from '@gitlens/utils/iterable.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport type { PagedResult } from '@gitlens/utils/paging.js';\nimport type { ProviderAuthenticationSession } from '../authentication/models.js';\nimport { toTokenWithInfo } from '../authentication/models.js';\nimport type { ProviderScopeFailure } from '../collectionMetadata.js';\nimport {\n\tthrowIfCallerContractError,\n\ttoCollectionFailureError,\n\ttoCollectionScopeFailure,\n} from '../collectionMetadata.js';\nimport type { IntegrationIds } from '../constants.js';\nimport { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../constants.js';\nimport { toError } from '../errors.js';\nimport type {\n\tGetIssuesOptions,\n\tGetPullRequestsOptions,\n\tPagedProjectInput,\n\tPagedRepoInput,\n\tProviderAccount,\n\tProviderApiPagedResult,\n\tProviderHierarchyResult,\n\tProviderIssue,\n\tProviderOrganization,\n\tProviderPullRequest,\n\tProviderRepoInput,\n\tProviderReposInput,\n\tProviderRepository,\n} from '../providers/models.js';\nimport {\n\tIssueFilter,\n\tPagingMode,\n\tPullRequestFilter,\n\ttoIssueShape,\n\ttoProviderIssueStates,\n\ttoProviderPullRequestStates,\n} from '../providers/models.js';\nimport { isAzureProviderId } from '../providers/providerErrors.js';\nimport type { ProvidersApi } from '../providers/providersApi.js';\nimport { mergeCollectionMetadata, throwIfAllSettledFailed } from '../providers/utils/providerPaging.js';\nimport { areDomainsOnSameHost } from '../utils/domain.utils.js';\nimport { getSelfManagedBaseUrl, isGitSelfManagedHostIntegrationId } from '../utils/integration.utils.js';\nimport type {\n\tBatchSlot,\n\tIntegrationResult,\n\tIntegrationType,\n\tIssueEtagFields,\n\tIssueEtagInclude,\n\tProviderIssueSearchPage,\n\tProviderPullRequestCount,\n\tProviderPullRequestSearchPage,\n\tProviderSearchCount,\n\tPullRequestEtagFields,\n\tPullRequestEtagInclude,\n} from './integration.js';\nimport { IntegrationBase, isReadSessionFailure } from './integration.js';\nimport type { MyIssuesForReposOptions } from './issueReads.js';\n\n/**\n * Whether an SDK read for `providerId` must send the session's secret as an HTTP Basic credential.\n *\n * Azure DevOps authenticates a PAT only as Basic — Azure DevOps Server refuses one sent as a bearer token outright —\n * and the Azure integration's own reads already pass it that way (`AzureDevOpsIntegrationBase.getApiOptions`). The\n * reads here are shared by every host, so they have to ask; every other provider keeps the SDK's default.\n */\nfunction sendsBasicCredential(providerId: IntegrationIds, session: ProviderAuthenticationSession): boolean | undefined {\n\treturn isAzureProviderId(providerId) ? session.type !== 'oauth' : undefined;\n}\n\n/** Read options for {@link GitHostIntegration.searchMyPullRequests} and the provider hook behind it. */\nexport type SearchMyPullRequestsOptions = {\n\t/** Suppresses the user-facing notification when the read fails. */\n\tsilent?: boolean;\n\t/**\n\t * PR states to include (open/closed/merged/all). Providers that cannot express it in a single query\n\t * filter the normalized results; omitted preserves the historical open-only behavior.\n\t */\n\tstate?: PullRequestStateFilter;\n\tincludeReviewRequested?: boolean;\n};\n\n/** Read options for {@link GitHostIntegration.searchPullRequests} and the provider hook behind it. */\nexport type SearchPullRequestsOptions = {\n\t/** PR states to include; omitted preserves the provider's default. */\n\tinclude?: PullRequestState[];\n};\n\ntype MyPullRequestsForReposOptions = {\n\tfilters?: PullRequestFilter[];\n\tcursor?: string;\n\tcustomUrl?: string;\n\tpage?: number;\n\tpageSize?: number;\n\t/** PR states to include; when omitted the provider returns its default (open only). */\n\tstate?: PullRequestStateFilter | PullRequestStateFilter[];\n\t/** Requests the lightweight row shape without per-row build status or commit count. */\n\tsummary?: boolean;\n};\n\n/**\n * Rejects a read the provider can't serve as asked: logs the reason and returns it as the `{ error }` half of an\n * {@link IntegrationResult}, timed from `start`.\n *\n * A single builder because these refusals are a contract, not incidental returns — the read cores below reject on\n * unsupported input, an inexpressible filter set, or an unresolvable filter account, and each one must reach the\n * caller as an error it can surface as a warning rather than as an empty success. Writing the message once also\n * keeps the logged text and the thrown text from drifting apart, which is exactly what happened while each site\n * spelled its message out twice.\n */\nfunction unsupportedRead<T>(message: string, start: number, logContext?: string): IntegrationResult<T> {\n\tLogger.warn(message, logContext);\n\treturn { error: new Error(message), duration: performance.now() - start };\n}\n\n/**\n * Both fields gate the same GitHub `commits` subtree, so either truthy key retains the build-status rollup.\n * An absent map retains the full row; a summary read explicitly drops both optional fields.\n */\nconst summaryPullRequestFields: Required<GitHubPullRequestFieldMap> = {\n\theadCommit: false,\n\tcommitCount: false,\n};\n\nexport abstract class GitHostIntegration<\n\tID extends IntegrationIds = IntegrationIds,\n\tT extends ResourceDescriptor = ResourceDescriptor,\n> extends IntegrationBase<ID> {\n\treadonly type: IntegrationType = 'git';\n\n\t/** The self-managed installation `session` addresses, validated against this integration's host. */\n\tprotected getSelfManagedInstallationUrl(session: ProviderAuthenticationSession): string {\n\t\tconst baseUrl = getSelfManagedBaseUrl(\n\t\t\tthis.id,\n\t\t\tsession.baseUrl ?? (session.domain || this.domain),\n\t\t\tsession.protocol,\n\t\t);\n\t\tif (baseUrl == null || !areDomainsOnSameHost(baseUrl, this.domain)) {\n\t\t\tthrow new Error('Invalid self-managed integration base URL');\n\t\t}\n\n\t\treturn baseUrl;\n\t}\n\n\tprotected getSelfManagedApiBaseUrl(session: ProviderAuthenticationSession): string {\n\t\tconst baseUrl = this.getSelfManagedInstallationUrl(session);\n\t\tswitch (this.id) {\n\t\t\tcase GitSelfManagedHostIntegrationId.CloudGitHubEnterprise:\n\t\t\t\treturn `${baseUrl}/api/v3`;\n\t\t\tcase GitSelfManagedHostIntegrationId.BitbucketServer:\n\t\t\t\treturn `${baseUrl}/rest/api/1.0`;\n\t\t\tdefault:\n\t\t\t\treturn baseUrl;\n\t\t}\n\t}\n\n\t/** The base the repository-list reads hand the provider client for a self-managed host. */\n\tprotected getRepositoriesApiBaseUrl(session: ProviderAuthenticationSession, _repos: ProviderReposInput): string {\n\t\treturn this.getSelfManagedApiBaseUrl(session);\n\t}\n\n\t@gate()\n\t@trace()\n\tasync getAccountForEmail(repo: T, email: string, options?: { avatarSize?: number }): Promise<Account | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst connected = this.maybeConnected ?? (await this.isConnected());\n\t\tif (!connected) return undefined;\n\n\t\tawait this.refreshSessionIfExpired(scope);\n\n\t\ttry {\n\t\t\tconst author = await this.getProviderAccountForEmail(this._session!, repo, email, options);\n\t\t\tthis.resetRequestExceptionCount('getAccountForEmail');\n\t\t\treturn author;\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getAccountForEmail', ex, { scope: scope });\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprotected abstract getProviderAccountForEmail(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\temail: string,\n\t\toptions?: { avatarSize?: number },\n\t): Promise<Account | undefined>;\n\n\t/**\n\t * Returns the SSH signing keys (full OpenSSH-format `<type> <key> [comment]` strings) registered by the accounts\n\t * matching the given emails on this integration, for building an `allowed_signers` file. Keyed by lowercased email;\n\t * emails with no match (and unsupported integrations) are absent. Batching the lookups is left to the integration.\n\t */\n\t@gate()\n\t@trace()\n\tasync getSshSigningKeysForEmails(repo: T, emails: string[]): Promise<Map<string, string[]>> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst connected = this.maybeConnected ?? (await this.isConnected());\n\t\tif (!connected) return new Map();\n\n\t\tawait this.refreshSessionIfExpired(scope);\n\n\t\ttry {\n\t\t\tconst keys = await this.getProviderSshSigningKeysForEmails(this._session!, repo, emails);\n\t\t\tthis.resetRequestExceptionCount('getSshSigningKeysForEmails');\n\t\t\treturn keys;\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getSshSigningKeysForEmails', ex, { scope: scope });\n\t\t\treturn new Map();\n\t\t}\n\t}\n\n\t/** Override in integrations that expose users' SSH signing keys. Defaults to none. */\n\tprotected getProviderSshSigningKeysForEmails(\n\t\t_session: ProviderAuthenticationSession,\n\t\t_repo: T,\n\t\t_emails: string[],\n\t): Promise<Map<string, string[]>> {\n\t\treturn Promise.resolve(new Map<string, string[]>());\n\t}\n\n\t@gate()\n\t@trace()\n\tasync getAccountForCommit(\n\t\trepo: T,\n\t\trev: string,\n\t\toptions?: { avatarSize?: number },\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst connected = this.maybeConnected ?? (await this.isConnected());\n\t\tif (!connected) return undefined;\n\n\t\tawait this.refreshSessionIfExpired(scope);\n\n\t\ttry {\n\t\t\tconst author = await this.getProviderAccountForCommit(this._session!, repo, rev, options);\n\t\t\tthis.resetRequestExceptionCount('getAccountForCommit');\n\t\t\treturn author;\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getAccountForCommit', ex, { scope: scope });\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprotected abstract getProviderAccountForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\trev: string,\n\t\toptions?: { avatarSize?: number },\n\t): Promise<Account | UnidentifiedAuthor | undefined>;\n\n\t@trace()\n\tasync getDefaultBranch(\n\t\trepo: T,\n\t\toptions?: { cancellation?: AbortSignal; expiryOverride?: boolean | number },\n\t): Promise<DefaultBranch | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst connected = this.maybeConnected ?? (await this.isConnected());\n\t\tif (!connected) return undefined;\n\n\t\tawait this.refreshSessionIfExpired(scope);\n\n\t\tconst defaultBranch = this.ctx.cache.getRepositoryDefaultBranch(\n\t\t\trepo,\n\t\t\tthis,\n\t\t\t() => ({\n\t\t\t\tvalue: (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.getProviderDefaultBranch(this._session!, repo, options?.cancellation);\n\t\t\t\t\t\tthis.resetRequestExceptionCount('getDefaultBranch');\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tthis.handleProviderException('getDefaultBranch', ex, { scope: scope });\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\t{ expiryOverride: options?.expiryOverride },\n\t\t);\n\t\treturn defaultBranch;\n\t}\n\n\tgetRepoInfo?(repo: {\n\t\towner: string;\n\t\tname: string;\n\t\tproject?: string;\n\t\tconnectionId?: string;\n\t}): Promise<ProviderRepository | undefined>;\n\n\t/**\n\t * Settles what one repository's refusal of the credential means, as a batch read settles a refused target (see\n\t * `IntegrationBase.settleBatchRefusals`): the scope failure it is recorded as, against that repository (and, on\n\t * Azure DevOps, its project), with its cause named once the credential checks out. A refused credential throws\n\t * its own error, which the caller reports for the connection instead of the repository's refusal.\n\t */\n\tasync settleRepositoryRefusal(\n\t\trepo: { owner: string; name: string; project?: string; connectionId?: string },\n\t\trefusal: unknown,\n\t): Promise<ProviderScopeFailure | undefined> {\n\t\tconst session = await this.resolveReadSessionOrThrow(repo.connectionId, undefined);\n\t\tif (session == null) return undefined;\n\n\t\tconst [slot] = await this.settleBatchRefusals(\n\t\t\tsession,\n\t\t\t[{ owner: repo.owner, repo: repo.name, project: repo.project }],\n\t\t\t[{ status: 'rejected', reason: refusal }],\n\t\t);\n\t\treturn slot?.status === 'rejected' ? slot.failure : undefined;\n\t}\n\n\t/** Stack membership for every stacked pull request in the repository, keyed by pull request number.\n\t * Only hosts with a stacks concept implement this (currently GitHub). */\n\tgetStacksByPullRequestNumber?(\n\t\towner: string,\n\t\trepo: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<Map<number, PullRequestStackInfo> | undefined>;\n\n\tprotected abstract getProviderDefaultBranch(\n\t\t{ accessToken }: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\tcancellation?: AbortSignal,\n\t): Promise<DefaultBranch | undefined>;\n\n\t@trace()\n\tasync getRepositoryMetadata(\n\t\trepo: T,\n\t\toptions?: { cancellation?: AbortSignal; expiryOverride?: boolean | number },\n\t): Promise<RepositoryMetadata | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst connected = this.maybeConnected ?? (await this.isConnected());\n\t\tif (!connected) return undefined;\n\n\t\tawait this.refreshSessionIfExpired(scope);\n\n\t\tconst metadata = this.ctx.cache.getRepositoryMetadata(\n\t\t\trepo,\n\t\t\tthis,\n\t\t\t() => ({\n\t\t\t\tvalue: (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.getProviderRepositoryMetadata(\n\t\t\t\t\t\t\tthis._session!,\n\t\t\t\t\t\t\trepo,\n\t\t\t\t\t\t\toptions?.cancellation,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.resetRequestExceptionCount('getRepositoryMetadata');\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tthis.handleProviderException('getRepositoryMetadata', ex, { scope: scope });\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\t{ expiryOverride: options?.expiryOverride },\n\t\t);\n\t\treturn metadata;\n\t}\n\n\tprotected abstract getProviderRepositoryMetadata(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined>;\n\n\t/**\n\t * Whether this git host implements generic org discovery. False for providers that register no\n\t * {@link getProviderOrganizationsForUser} hook — the facade uses this to\n\t * report `unsupported` instead of a silent empty list, which is indistinguishable from \"has no orgs\".\n\t */\n\tget supportsOrganizationDiscovery(): boolean {\n\t\treturn this.getProviderOrganizationsForUser != null;\n\t}\n\n\t/** Whether this git host implements generic repository discovery ({@link getProviderRepositoriesForOrg}). */\n\tget supportsRepositoryDiscovery(): boolean {\n\t\treturn this.getProviderRepositoriesForOrg != null;\n\t}\n\n\t/**\n\t * Whether this git host has a project tier between org and repo ({@link getProviderProjectsForOrg}). Only\n\t * Azure DevOps does; the facade uses this to skip the read entirely rather than call a core that returns\n\t * `undefined` for a session-less reason and be misread as a broken connection.\n\t */\n\tget supportsProjectDiscovery(): boolean {\n\t\treturn this.getProviderProjectsForOrg != null;\n\t}\n\n\t/**\n\t * Whether this git host implements the account-wide user-affiliated repository read\n\t * ({@link getProviderRepositoriesForUser}) — the org-less `gk provider repos <provider>` equivalent.\n\t */\n\tget supportsUserRepositoryDiscovery(): boolean {\n\t\treturn this.getProviderRepositoriesForUser != null;\n\t}\n\n\t/**\n\t * Whether this git host exposes issues on the ProviderBackend surface. Most git hosts do; a host with no\n\t * usable issue tracker overrides this to false — Bitbucket Cloud (deprecated in favor of dedicated issue\n\t * integrations like Jira) and Bitbucket Data Center (never had one) — so the facade reports issues as\n\t * unsupported instead of serving a partial/deprecated source or failing inside a provider client that\n\t * registers no issue function at all.\n\t *\n\t * Keep this in sync with {@link ProviderMetadata.supportedIssueFilters}: a provider that declares no issue\n\t * filters and no issue read is answering the same capability question twice, and the two must agree.\n\t */\n\tget supportsIssues(): boolean {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Whether this host has the cheap check behind the batch pull request read's etags\n\t * ({@link getProviderPullRequestsEtagFields}). The read decides before calling anything, so a host without one\n\t * full-reads every target in a single call.\n\t */\n\tget supportsPullRequestEtags(): boolean {\n\t\treturn this.getProviderPullRequestsEtagFields != null;\n\t}\n\n\t/** The issue twin of {@link supportsPullRequestEtags}: whether {@link getProviderIssuesEtagFields} exists. */\n\tget supportsIssueEtags(): boolean {\n\t\treturn this.getProviderIssuesEtagFields != null;\n\t}\n\n\t/**\n\t * Lists the organizations (orgs/workspaces/groups) the current user belongs to on this host.\n\t * `truncated === true` means the defensive page-drain backstop stopped before the upstream listing was\n\t * exhausted.\n\t *\n\t * Resolves the session for `connectionId` (or the primary connection when omitted, honoring multi-account\n\t * reads) and recovers a thrown error into `{ error }` so callers can surface it as a warning instead of\n\t * swallowing it to `undefined`.\n\t */\n\t@trace()\n\tasync getOrganizationsForUserResult(\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderHierarchyResult<ProviderOrganization> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderOrganizationsForUser?.(session);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tconst authFailure = result?.metadata?.failures?.find(\n\t\t\t\tfailure =>\n\t\t\t\t\tfailure.kind === 'authentication' &&\n\t\t\t\t\tfailure.scope != null &&\n\t\t\t\t\tfailure.scope.providerId === this.id &&\n\t\t\t\t\tObject.keys(failure.scope).length === 1,\n\t\t\t);\n\t\t\tif (authFailure != null) {\n\t\t\t\tthis.handleProviderException(\n\t\t\t\t\t'getOrganizationsForUser',\n\t\t\t\t\ttoCollectionFailureError(authFailure, toTokenWithInfo(this.id, session)),\n\t\t\t\t\t{ scope: scope, connectionId: connectionId },\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.resetRequestExceptionCount('getOrganizationsForUser');\n\t\t\t}\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getOrganizationsForUser', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderOrganizationsForUser?(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization> | undefined>;\n\n\t/**\n\t * Result-returning list of the projects a git host exposes beneath its orgs, unified into the\n\t * {@link ProviderOrganization} shape. Only Azure DevOps has a project tier between org and repo; other\n\t * git hosts have none and leave {@link getProviderProjectsForOrg} undefined, so this returns `undefined`\n\t * for them (the ProviderBackend facade then treats them as having no projects). With `org`, scopes to\n\t * that org's projects; without, returns projects across every org the user can see.\n\t */\n\t@trace()\n\tasync getProjectsForOrgResult(\n\t\torg?: string,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderHierarchyResult<ProviderOrganization> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tif (this.getProviderProjectsForOrg == null) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderProjectsForOrg(session, org);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getProjectsForOrg');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getProjectsForOrg', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderProjectsForOrg?(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg?: string,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization> | undefined>;\n\n\t/**\n\t * Lists repositories under the given organization (org/workspace/group) one page at a time — follow\n\t * `paging.cursor` to page, or drain with the integrations provider paging helper.\n\t * `options.project` is only meaningful for Azure DevOps, whose repos are scoped by `org` + `project`;\n\t * every other host ignores it. (Azure without a project can't page its cross-project merge, so it\n\t * returns all matches in a single page.) `truncated === true` means the defensive page-drain\n\t * backstop stopped before the upstream listing was exhausted.\n\t *\n\t * Resolves the session for `connectionId` (or the primary connection when omitted) and recovers a thrown\n\t * error into `{ error }`, so a caller surfaces it as a warning instead of a silent `undefined`.\n\t */\n\t@trace()\n\tasync getRepositoriesForOrgResult(\n\t\torg: string,\n\t\toptions?: { project?: string; cursor?: string; connectionId?: string },\n\t): Promise<IntegrationResult<ProviderHierarchyResult<ProviderRepository> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(options?.connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderRepositoriesForOrg?.(session, org, options);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getRepositoriesForOrg');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getRepositoriesForOrg', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: options?.connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderRepositoriesForOrg?(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg: string,\n\t\toptions?: { project?: string; cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined>;\n\n\t/**\n\t * Result-returning account-wide, user-affiliated repository read (the org-less\n\t * `gk provider repos <provider>` equivalent): repositories the user owns, collaborates on, or can\n\t * access through org membership — NOT every repo of every org. Optional: providers without a native\n\t * user-affiliated listing (Bitbucket workspaces, Azure orgs, which require an org/workspace scope)\n\t * leave the hook undefined and the facade reports the read as unsupported so callers fan out per org.\n\t */\n\t@trace()\n\tasync getRepositoriesForUserResult(options?: {\n\t\tcursor?: string;\n\t\tconnectionId?: string;\n\t}): Promise<IntegrationResult<ProviderHierarchyResult<ProviderRepository> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(options?.connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tif (this.getProviderRepositoriesForUser == null) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderRepositoriesForUser(session, options);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getRepositoriesForUser');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getRepositoriesForUser', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: options?.connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderRepositoriesForUser?(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined>;\n\n\tasync mergePullRequest(\n\t\tpr: PullRequest,\n\t\toptions?: { mergeMethod?: PullRequestMergeMethod },\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst connected = this.maybeConnected ?? (await this.isConnected());\n\t\tif (!connected) return false;\n\n\t\tawait this.refreshSessionIfExpired(scope);\n\n\t\ttry {\n\t\t\tconst result = await this.mergeProviderPullRequest(this._session!, pr, options, cancellation);\n\t\t\tthis.resetRequestExceptionCount('mergePullRequest');\n\t\t\treturn result;\n\t\t} catch (ex) {\n\t\t\tif (isCancellationError(ex)) return false;\n\n\t\t\tthis.handleProviderException('mergePullRequest', ex, { scope: scope });\n\t\t\treturn false;\n\t\t} finally {\n\t\t\t// A merge attempt just changed the state of more than this pull request on the server (a\n\t\t\t// stacked merge lands every layer below and retargets every layer above) whether it succeeded\n\t\t\t// or failed partway through — so cached pull requests can't be trusted either way. Without\n\t\t\t// this, ref pills and branch enrichment keep serving the pre-merge object until its expiry.\n\t\t\tthis.ctx.cache.deletePullRequests();\n\t\t}\n\t}\n\n\tprotected abstract mergeProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tpr: PullRequest,\n\t\toptions?: { mergeMethod?: PullRequestMergeMethod },\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean>;\n\n\t@trace()\n\tasync getPullRequestForBranch(\n\t\trepo: T,\n\t\tbranch: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t\texpiryOverride?: boolean | number;\n\t\t\tinclude?: PullRequestState[];\n\t\t\t/** Rethrow a failed lookup instead of folding it into `undefined`, for callers that must tell\n\t\t\t * \"no pull request\" apart from \"couldn't ask\". */\n\t\t\tthrowOnError?: boolean;\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst connected = this.maybeConnected ?? (await this.isConnected());\n\t\tif (!connected) return undefined;\n\n\t\tawait this.refreshSessionIfExpired(scope);\n\n\t\tconst { expiryOverride, throwOnError, ...opts } = options ?? {};\n\n\t\tconst pr = this.ctx.cache.getPullRequestForBranch(\n\t\t\tbranch,\n\t\t\trepo,\n\t\t\tthis,\n\t\t\tcacheable => ({\n\t\t\t\tvalue: (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.getProviderPullRequestForBranch(this._session!, repo, branch, opts);\n\t\t\t\t\t\tthis.resetRequestExceptionCount('getPullRequestForBranch');\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t// A failed lookup is not an answer: left cached, the `undefined` below reads as \"no pull\n\t\t\t\t\t\t// request\" for the bucket's whole expiry (an hour by branch).\n\t\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t\t\tthis.handleProviderException('getPullRequestForBranch', ex, { scope: scope });\n\t\t\t\t\t\tif (throwOnError) throw ex;\n\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\t{ expiryOverride: expiryOverride },\n\t\t);\n\t\treturn pr;\n\t}\n\n\tprotected abstract getProviderPullRequestForBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\tbranch: string,\n\t\toptions?: { avatarSize?: number; include?: PullRequestState[] },\n\t): Promise<PullRequest | undefined>;\n\n\t@trace()\n\tasync getPullRequestForCommit(\n\t\trepo: T,\n\t\trev: string,\n\t\toptions?: { expiryOverride?: boolean | number; throwOnError?: boolean },\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst connected = this.maybeConnected ?? (await this.isConnected());\n\t\tif (!connected) return undefined;\n\n\t\tawait this.refreshSessionIfExpired(scope);\n\n\t\tconst { throwOnError, ...cacheOptions } = options ?? {};\n\n\t\tconst pr = this.ctx.cache.getPullRequestForSha(\n\t\t\trev,\n\t\t\trepo,\n\t\t\tthis,\n\t\t\tcacheable => ({\n\t\t\t\tvalue: (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.getProviderPullRequestForCommit(this._session!, repo, rev);\n\t\t\t\t\t\tthis.resetRequestExceptionCount('getPullRequestForCommit');\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t// A failed lookup is not an answer — and the by-sha bucket never expires a miss.\n\t\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t\t\tthis.handleProviderException('getPullRequestForCommit', ex, { scope: scope });\n\t\t\t\t\t\tif (throwOnError) throw ex;\n\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\tcacheOptions,\n\t\t);\n\t\treturn pr;\n\t}\n\n\tprotected abstract getProviderPullRequestForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\trev: string,\n\t): Promise<PullRequest | undefined>;\n\n\t/**\n\t * Memoized identity lookups backing filter resolution. Keyed by the session's token fingerprint plus the\n\t * scope of the lookup (base URL, and the Azure organization for the per-instance variant), so a different\n\t * account, host, or org never reuses an entry and a rotated token simply misses.\n\t *\n\t * Not cleared when the token changes: one integration instance serves every connection of its provider\n\t * (multi-account), so clearing on a fingerprint change would make two accounts reading in alternation\n\t * evict each other and defeat the memo. Entries are bounded by tokens x hosts x orgs seen — a handful for\n\t * the life of the integration.\n\t */\n\tprivate readonly _filterAccounts = new Map<string, Promise<ProviderAccount | undefined>>();\n\n\t/**\n\t * Resolves the account a repo-scoped read turns `IssueFilter`/`PullRequestFilter` into a provider\n\t * login/id with, memoized per token+scope.\n\t *\n\t * Every FILTERED read needs this, and `ProvidersApi.getCurrentUser` is a bare round trip — unlike\n\t * {@link IntegrationBase.getCurrentAccount}, which the host caches. So a consumer that fans ONE page out\n\t * into several filtered reads paid one identity request PER read, all resolving the same account: a\n\t * per-user-facet fan-out (author + assignee + review-requested) doubled its request count, and paid it\n\t * again on every page turn.\n\t *\n\t * The promise is memoized rather than the value, so concurrent facets share one in-flight request instead\n\t * of racing. A rejection is evicted so the next read retries rather than caching a failure — matching how\n\t * `getCurrentAccount` invalidates on error.\n\t */\n\tprivate getFilterAccount(\n\t\tapi: ProvidersApi,\n\t\tsession: ProviderAuthenticationSession,\n\t\tcustomUrl: string | undefined,\n\t\torganization?: string,\n\t): Promise<ProviderAccount | undefined> {\n\t\tconst key = `${this.getSessionFingerprint(session)}:${customUrl ?? ''}:${organization ?? ''}`;\n\n\t\tlet pending = this._filterAccounts.get(key);\n\t\tif (pending == null) {\n\t\t\tconst tokenWithInfo = toTokenWithInfo(this.authProvider.id, session);\n\t\t\tpending = (\n\t\t\t\torganization != null\n\t\t\t\t\t? api.getCurrentUserForInstance(tokenWithInfo, organization, {\n\t\t\t\t\t\t\tbaseUrl: customUrl,\n\t\t\t\t\t\t\tisPAT: sendsBasicCredential(this.id, session),\n\t\t\t\t\t\t})\n\t\t\t\t\t: api.getCurrentUser(tokenWithInfo, { baseUrl: customUrl })\n\t\t\t).catch((ex: unknown) => {\n\t\t\t\tthis._filterAccounts.delete(key);\n\t\t\t\tthrow ex;\n\t\t\t});\n\t\t\tthis._filterAccounts.set(key, pending);\n\t\t}\n\n\t\treturn pending;\n\t}\n\n\tasync getMyIssuesForRepos(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyIssuesForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<PagedResult<ProviderIssue> | undefined> {\n\t\treturn (await this.getMyIssuesForReposResult(reposOrRepoIds, options, connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getMyIssuesForRepos}. Resolves the session for `connectionId`\n\t * (or the primary connection when omitted, so multi-account reads use the right token) and recovers\n\t * thrown errors and validation failures into `{ error }` so callers can surface them as warnings\n\t * rather than swallowing them to `undefined`.\n\t */\n\tasync getMyIssuesForReposResult(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyIssuesForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<(PagedResult<ProviderIssue> & { metadata?: CollectionMetadata }) | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst providerId = this.authProvider.id;\n\t\tconst states = toProviderIssueStates(options?.state);\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary. The session\n\t\t// is resolved here for connectivity/bail; the connection's token is applied per API call below.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet customUrl: string | undefined;\n\t\tlet api: ProvidersApi;\n\t\ttry {\n\t\t\tcustomUrl =\n\t\t\t\toptions?.customUrl ??\n\t\t\t\t(isGitSelfManagedHostIntegrationId(providerId)\n\t\t\t\t\t? this.getRepositoriesApiBaseUrl(session, reposOrRepoIds)\n\t\t\t\t\t: undefined);\n\t\t\tapi = await this.getProvidersApi();\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssuesForRepos', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t\tconst repoIdsInput = api.isRepoIdsInput(reposOrRepoIds);\n\t\tif (\n\t\t\tproviderId !== GitCloudHostIntegrationId.GitLab &&\n\t\t\t(repoIdsInput ||\n\t\t\t\t(isAzureProviderId(providerId) &&\n\t\t\t\t\t!reposOrRepoIds.every(repo => repo.project != null && repo.namespace != null)))\n\t\t) {\n\t\t\treturn unsupportedRead(`Unsupported input for provider ${providerId}`, start, 'getIssuesForRepos');\n\t\t}\n\n\t\tlet getIssuesOptions: GetIssuesOptions | undefined;\n\t\tif (isAzureProviderId(providerId)) {\n\t\t\tconst organizations = new Set<string>();\n\t\t\tconst projects = new Set<string>();\n\t\t\tfor (const repo of reposOrRepoIds as ProviderRepoInput[]) {\n\t\t\t\torganizations.add(repo.namespace);\n\t\t\t\tprojects.add(repo.project!);\n\t\t\t}\n\n\t\t\tif (organizations.size > 1) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Multiple organizations not supported for provider ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getIssuesForRepos',\n\t\t\t\t);\n\t\t\t} else if (organizations.size === 0) {\n\t\t\t\treturn unsupportedRead(`No organizations found for provider ${providerId}`, start, 'getIssuesForRepos');\n\t\t\t}\n\n\t\t\tconst organization: string = first(organizations.values())!;\n\n\t\t\tif (options?.filters != null) {\n\t\t\t\tif (!api.providerSupportsIssueFilters(providerId, options.filters)) {\n\t\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t\t`Unsupported filters for provider ${providerId}`,\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\t'getIssuesForRepos',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tlet userAccount: ProviderAccount | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tuserAccount = await this.getFilterAccount(api, session, customUrl, organization);\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\t\tscope: scope,\n\t\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t\t});\n\t\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t\t}\n\n\t\t\t\tif (userAccount == null) {\n\t\t\t\t\treturn unsupportedRead(`Unable to get current user for ${providerId}`, start, 'getIssuesForRepos');\n\t\t\t\t}\n\n\t\t\t\tconst userFilterProperty = userAccount.name;\n\n\t\t\t\tif (userFilterProperty == null) {\n\t\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t\t`Unable to get user property for filter for ${providerId}`,\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\t'getIssuesForRepos',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tgetIssuesOptions = {\n\t\t\t\t\tauthorLogin: options.filters.includes(IssueFilter.Author) ? userFilterProperty : undefined,\n\t\t\t\t\tassigneeLogins:\n\t\t\t\t\t\t!options.includeAllAssignees && options.filters.includes(IssueFilter.Assignee)\n\t\t\t\t\t\t\t? [userFilterProperty]\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\tmentionLogin: options.filters.includes(IssueFilter.Mention) ? userFilterProperty : undefined,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst cursorInfo = this.parseCursorInfo<PagedProjectInput>(options?.cursor);\n\t\t\tconst cursors: PagedProjectInput[] = cursorInfo.cursors ?? [];\n\t\t\tlet projectInputs: PagedProjectInput[] = Array.from(projects.values(), project => ({\n\t\t\t\tnamespace: organization,\n\t\t\t\tproject: project,\n\t\t\t\tcursor: undefined,\n\t\t\t}));\n\t\t\tif (cursors.length > 0) {\n\t\t\t\tprojectInputs = cursors;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cursor: { cursors: PagedProjectInput[]; page?: number } = { cursors: [] };\n\t\t\t\tlet hasMore = false;\n\t\t\t\tlet truncated = false;\n\t\t\t\tlet metadata: CollectionMetadata | undefined;\n\t\t\t\tconst data: ProviderIssue[] = [];\n\t\t\t\t// `allSettled`, not `Promise.all`: one project's read rejecting must not discard every sibling\n\t\t\t\t// project's already-fetched issues and cursors. A rejected project is recorded as a structured\n\t\t\t\t// failure so the facade can warn and set `fetchFailed` instead of reporting a partial project set\n\t\t\t\t// as complete.\n\t\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\t\tprojectInputs.map(async projectInput => {\n\t\t\t\t\t\tconst results = await api.getIssuesForAzureProject(\n\t\t\t\t\t\t\ttoTokenWithInfo(providerId, session),\n\t\t\t\t\t\t\tprojectInput.namespace,\n\t\t\t\t\t\t\tprojectInput.project,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t...getIssuesOptions,\n\t\t\t\t\t\t\t\tcursor: projectInput.cursor,\n\t\t\t\t\t\t\t\tbaseUrl: customUrl,\n\t\t\t\t\t\t\t\tisPAT: sendsBasicCredential(providerId, session),\n\t\t\t\t\t\t\t\t// Continuation is driven by the per-project cursor; only apply an explicit page on the\n\t\t\t\t\t\t\t\t// first request so it can't clobber a continuation cursor on later pages.\n\t\t\t\t\t\t\t\tpage: projectInput.cursor == null ? options?.page : undefined,\n\t\t\t\t\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\t\t\t\t\tstates: states,\n\t\t\t\t\t\t\t\tsort: options?.sort,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { projectInput: projectInput, results: results };\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthrowIfAllSettledFailed(settled);\n\n\t\t\t\tfor (let i = 0; i < settled.length; i++) {\n\t\t\t\t\tconst outcome = settled[i];\n\t\t\t\t\tconst projectInput = projectInputs[i];\n\t\t\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\t\t\t// Errors that really are per-scope (auth, rate limit, a missing project) degrade below; one\n\t\t\t\t\t\t// that is a fact about the call is re-thrown instead — see `throwIfCallerContractError`.\n\t\t\t\t\t\tthrowIfCallerContractError(outcome.reason);\n\n\t\t\t\t\t\ttruncated = true;\n\t\t\t\t\t\tconst failure = toCollectionScopeFailure(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproviderId: providerId,\n\t\t\t\t\t\t\t\tresourceId: projectInput.namespace,\n\t\t\t\t\t\t\t\tprojectId: projectInput.project,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutcome.reason,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tmetadata = mergeCollectionMetadata(metadata, {\n\t\t\t\t\t\t\tcompleteness: 'partial',\n\t\t\t\t\t\t\tfailures: [failure],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { projectInput: _projectInput, results } = outcome.value;\n\t\t\t\t\tdata.push(...results.values);\n\t\t\t\t\tif (results.paging?.more) {\n\t\t\t\t\t\thasMore = true;\n\t\t\t\t\t\tcursor.cursors.push({\n\t\t\t\t\t\t\tnamespace: projectInput.namespace,\n\t\t\t\t\t\t\tproject: projectInput.project,\n\t\t\t\t\t\t\tcursor: results.paging.cursor,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Keep the requested page number in the composite cursor so the facade can report the real\n\t\t\t\t// currentPage when the consumer continues using only the cursor.\n\t\t\t\tif (options?.page != null) {\n\t\t\t\t\tcursor.page = options.page;\n\t\t\t\t}\n\n\t\t\t\tawait this.confirmScopedAuthFailures(session, metadata);\n\t\t\t\tthis.resetRequestExceptionCount('getIssuesForRepos');\n\t\t\t\treturn {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tvalues: data,\n\t\t\t\t\t\tpaging: {\n\t\t\t\t\t\t\tmore: hasMore,\n\t\t\t\t\t\t\tcursor: JSON.stringify(cursor),\n\t\t\t\t\t\t\ttruncated: truncated || undefined,\n\t\t\t\t\t\t\t// Echo the requested numbered page so the facade reports the real currentPage for\n\t\t\t\t\t\t\t// numbered-page hosts (GitLab/Bitbucket/Azure), not a synthesized 1. Cursor-only hosts\n\t\t\t\t\t\t\t// leave `page` undefined via their own reads.\n\t\t\t\t\t\t\tpage: options?.page,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmetadata: metadata,\n\t\t\t\t\t},\n\t\t\t\t\tduration: performance.now() - start,\n\t\t\t\t};\n\t\t\t} catch (ex) {\n\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t}\n\t\t}\n\t\tif (options?.filters != null) {\n\t\t\t// Validate the requested filters against what this provider actually supports — same guard the Azure\n\t\t\t// branch above applies. Without it an unsupported filter (e.g. GitLab has no Mention endpoint) would\n\t\t\t// resolve to no filter property being set and silently degrade to an unfiltered, project-wide read.\n\t\t\tif (!api.providerSupportsIssueFilters(providerId, options.filters)) {\n\t\t\t\treturn unsupportedRead(`Unsupported filters for provider ${providerId}`, start, 'getIssuesForRepos');\n\t\t\t}\n\n\t\t\tlet userAccount: ProviderAccount | undefined;\n\t\t\ttry {\n\t\t\t\tuserAccount = await this.getFilterAccount(api, session, customUrl);\n\t\t\t} catch (ex) {\n\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tif (userAccount == null) {\n\t\t\t\treturn unsupportedRead(`Unable to get current user for ${providerId}`, start, 'getIssuesForRepos');\n\t\t\t}\n\n\t\t\tconst userFilterProperty = userAccount.username;\n\t\t\tif (userFilterProperty == null) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Unable to get user property for filter for ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getIssuesForRepos',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tgetIssuesOptions = {\n\t\t\t\tauthorLogin: options.filters.includes(IssueFilter.Author) ? userFilterProperty : undefined,\n\t\t\t\tassigneeLogins:\n\t\t\t\t\t!options.includeAllAssignees && options.filters.includes(IssueFilter.Assignee)\n\t\t\t\t\t\t? [userFilterProperty]\n\t\t\t\t\t\t: undefined,\n\t\t\t\tmentionLogin: options.filters.includes(IssueFilter.Mention) ? userFilterProperty : undefined,\n\t\t\t};\n\t\t}\n\n\t\tif (api.getProviderIssuesPagingMode(providerId) === PagingMode.Repo && !repoIdsInput) {\n\t\t\tconst cursorInfo = this.parseCursorInfo<PagedRepoInput>(options?.cursor);\n\t\t\tconst cursors: PagedRepoInput[] = cursorInfo.cursors ?? [];\n\t\t\tlet repoInputs: PagedRepoInput[] = reposOrRepoIds.map(repo => ({ repo: repo, cursor: undefined }));\n\t\t\tif (cursors.length > 0) {\n\t\t\t\trepoInputs = cursors;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cursor: { cursors: PagedRepoInput[]; page?: number } = { cursors: [] };\n\t\t\t\tlet hasMore = false;\n\t\t\t\tlet truncated = false;\n\t\t\t\tlet metadata: CollectionMetadata | undefined;\n\t\t\t\tconst data: ProviderIssue[] = [];\n\t\t\t\t// `allSettled`, not `Promise.all`: one repo's read rejecting must not discard every sibling repo's\n\t\t\t\t// already-fetched issues and cursors. A rejected repo is recorded as a structured failure so the\n\t\t\t\t// facade can warn and set `fetchFailed` instead of reporting a partial repo set as complete.\n\t\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\t\trepoInputs.map(async repoInput => {\n\t\t\t\t\t\tconst results = await api.getIssuesForRepo(\n\t\t\t\t\t\t\ttoTokenWithInfo(providerId, session),\n\t\t\t\t\t\t\trepoInput.repo,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t...getIssuesOptions,\n\t\t\t\t\t\t\t\tcursor: repoInput.cursor,\n\t\t\t\t\t\t\t\tbaseUrl: customUrl,\n\t\t\t\t\t\t\t\t// Continuation is driven by the per-repo cursor; only apply an explicit page on the\n\t\t\t\t\t\t\t\t// first request so it can't clobber a continuation cursor on later pages.\n\t\t\t\t\t\t\t\tpage: repoInput.cursor == null ? options?.page : undefined,\n\t\t\t\t\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\t\t\t\t\tstates: states,\n\t\t\t\t\t\t\t\tsort: options?.sort,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { repoInput: repoInput, results: results };\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthrowIfAllSettledFailed(settled);\n\n\t\t\t\tfor (let i = 0; i < settled.length; i++) {\n\t\t\t\t\tconst outcome = settled[i];\n\t\t\t\t\tconst repoInput = repoInputs[i];\n\t\t\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\t\t\t// See the project fan-out above. Reachable in practice even though the facade validates the\n\t\t\t\t\t\t// key first — a self-managed GitLab can reject an `IssueSort` member the SDK declares, which\n\t\t\t\t\t\t// is only discoverable from the response.\n\t\t\t\t\t\tthrowIfCallerContractError(outcome.reason);\n\n\t\t\t\t\t\ttruncated = true;\n\t\t\t\t\t\tconst failure = toCollectionScopeFailure(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproviderId: providerId,\n\t\t\t\t\t\t\t\trepositoryId: `${repoInput.repo.namespace}/${repoInput.repo.name}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutcome.reason,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tmetadata = mergeCollectionMetadata(metadata, {\n\t\t\t\t\t\t\tcompleteness: 'partial',\n\t\t\t\t\t\t\tfailures: [failure],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { repoInput: _repoInput, results } = outcome.value;\n\t\t\t\t\tdata.push(...results.values);\n\t\t\t\t\tif (results.paging?.more) {\n\t\t\t\t\t\thasMore = true;\n\t\t\t\t\t\tcursor.cursors.push({ repo: repoInput.repo, cursor: results.paging.cursor });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (options?.page != null) {\n\t\t\t\t\tcursor.page = options.page;\n\t\t\t\t}\n\n\t\t\t\tawait this.confirmScopedAuthFailures(session, metadata);\n\t\t\t\tthis.resetRequestExceptionCount('getIssuesForRepos');\n\t\t\t\treturn {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tvalues: data,\n\t\t\t\t\t\tpaging: {\n\t\t\t\t\t\t\tmore: hasMore,\n\t\t\t\t\t\t\tcursor: JSON.stringify(cursor),\n\t\t\t\t\t\t\ttruncated: truncated || undefined,\n\t\t\t\t\t\t\t// Echo the requested numbered page so the facade reports the real currentPage for\n\t\t\t\t\t\t\t// numbered-page hosts (GitLab/Bitbucket/Azure), not a synthesized 1. Cursor-only hosts\n\t\t\t\t\t\t\t// leave `page` undefined via their own reads.\n\t\t\t\t\t\t\tpage: options?.page,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmetadata: metadata,\n\t\t\t\t\t},\n\t\t\t\t\tduration: performance.now() - start,\n\t\t\t\t};\n\t\t\t} catch (ex) {\n\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst tokenWithInfo = toTokenWithInfo(providerId, session);\n\t\t\tconst result = await api.getIssuesForRepos(tokenWithInfo, reposOrRepoIds, {\n\t\t\t\t...getIssuesOptions,\n\t\t\t\tcursor: options?.cursor,\n\t\t\t\tbaseUrl: customUrl,\n\t\t\t\tisPAT: sendsBasicCredential(providerId, session),\n\t\t\t\tpage: options?.page,\n\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\tstates: states,\n\t\t\t\tsort: options?.sort,\n\t\t\t});\n\t\t\tconst failures = result.metadata?.failures;\n\t\t\tif (\n\t\t\t\trepoIdsInput &&\n\t\t\t\treposOrRepoIds.length > 0 &&\n\t\t\t\tresult.values.length === 0 &&\n\t\t\t\tfailures?.length === reposOrRepoIds.length\n\t\t\t) {\n\t\t\t\tconst ex = toCollectionFailureError(failures[0], tokenWithInfo);\n\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: ex, duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tawait this.confirmScopedAuthFailures(session, result.metadata);\n\t\t\tthis.resetRequestExceptionCount('getIssuesForRepos');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * Repo-scoped \"my issues\" read returning the normalized {@link IssueShape} the ProviderBackend facade\n\t * consumes (`listIssuesPage({ repos })`, `broadenIssues`). Maps {@link getMyIssuesForReposResult} — the raw\n\t * provider-apis path — to IssueShape.\n\t *\n\t * It's the seam rather than an inline map so a provider whose only issue client already yields normalized\n\t * shapes, and isn't wired into the raw path, can override it and serve these reads without a\n\t * `ProviderIssue` round-trip. No provider does today: the one candidate (Bitbucket Cloud's legacy\n\t * `getUsersIssuesForRepo`) reports `supportsIssues: false`, so the facade never reaches this for it.\n\t */\n\tasync getMyIssuesForReposAsShapesResult(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyIssuesForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<(PagedResult<IssueShape> & { metadata?: CollectionMetadata }) | undefined>> {\n\t\tconst result = await this.getMyIssuesForReposResult(reposOrRepoIds, options, connectionId);\n\t\tif (result == null) return undefined;\n\t\tif (result.error != null) return { error: result.error, duration: result.duration };\n\t\tif (result.value == null) return { value: undefined, duration: result.duration };\n\n\t\tconst values = result.value.values\n\t\t\t.map(issue => toIssueShape(issue, this, { projection: 'repos' }))\n\t\t\t.filter((issue): issue is IssueShape => issue != null);\n\t\treturn { value: { ...result.value, values: values }, duration: result.duration };\n\t}\n\n\tasync getMyPullRequestsForRepos(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyPullRequestsForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<ProviderApiPagedResult<ProviderPullRequest> | undefined> {\n\t\treturn (await this.getMyPullRequestsForReposResult(reposOrRepoIds, options, connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getMyPullRequestsForRepos}. Resolves the session for `connectionId`\n\t * (or the primary connection when omitted, so multi-account reads use the right token) and recovers\n\t * thrown errors and validation failures into `{ error }` so callers can surface them as warnings\n\t * rather than swallowing them to `undefined`.\n\t */\n\tasync getMyPullRequestsForReposResult(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyPullRequestsForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderApiPagedResult<ProviderPullRequest> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst providerId = this.authProvider.id;\n\t\tconst states = toProviderPullRequestStates(options?.state);\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary. The session\n\t\t// is resolved here for connectivity/bail; the connection's token is applied per API call below.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet customUrl: string | undefined;\n\t\tlet api: ProvidersApi;\n\t\ttry {\n\t\t\tcustomUrl =\n\t\t\t\toptions?.customUrl ??\n\t\t\t\t(isGitSelfManagedHostIntegrationId(providerId)\n\t\t\t\t\t? this.getRepositoriesApiBaseUrl(session, reposOrRepoIds)\n\t\t\t\t\t: undefined);\n\t\t\tapi = await this.getProvidersApi();\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t\tif (\n\t\t\tproviderId !== GitCloudHostIntegrationId.GitLab &&\n\t\t\t(api.isRepoIdsInput(reposOrRepoIds) ||\n\t\t\t\t(isAzureProviderId(providerId) &&\n\t\t\t\t\t!reposOrRepoIds.every(repo => repo.project != null && repo.namespace != null)))\n\t\t) {\n\t\t\treturn unsupportedRead(`Unsupported input for provider ${providerId}`, start);\n\t\t}\n\n\t\tlet getPullRequestsOptions: GetPullRequestsOptions | undefined;\n\t\tif (options?.filters != null) {\n\t\t\tif (!api.providerSupportsPullRequestFilters(providerId, options.filters)) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Unsupported filters for provider ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet userAccount: ProviderAccount | undefined;\n\t\t\tif (isAzureProviderId(providerId)) {\n\t\t\t\tconst organizations = new Set<string>();\n\t\t\t\tfor (const repo of reposOrRepoIds as ProviderRepoInput[]) {\n\t\t\t\t\torganizations.add(repo.namespace);\n\t\t\t\t}\n\n\t\t\t\tif (organizations.size > 1) {\n\t\t\t\t\tLogger.warn(\n\t\t\t\t\t\t`Multiple organizations not supported for provider ${providerId}`,\n\t\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t\t);\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: new Error(`Multiple organizations not supported for provider ${providerId}`),\n\t\t\t\t\t\tduration: performance.now() - start,\n\t\t\t\t\t};\n\t\t\t\t} else if (organizations.size === 0) {\n\t\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t\t`No organizations found for provider ${providerId}`,\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst organization: string = first(organizations.values())!;\n\t\t\t\ttry {\n\t\t\t\t\tuserAccount = await this.getFilterAccount(api, session, customUrl, organization);\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\t\t\tscope: scope,\n\t\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t\t});\n\t\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tuserAccount = await this.getFilterAccount(api, session, customUrl);\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\t\t\tscope: scope,\n\t\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t\t});\n\t\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (userAccount == null) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Unable to get current user for ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet userFilterProperty: string | null;\n\t\t\tswitch (providerId) {\n\t\t\t\tcase GitCloudHostIntegrationId.Bitbucket:\n\t\t\t\tcase GitCloudHostIntegrationId.AzureDevOps:\n\t\t\t\tcase GitSelfManagedHostIntegrationId.AzureDevOpsServer:\n\t\t\t\t\tuserFilterProperty = userAccount.id;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tuserFilterProperty = userAccount.username;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (userFilterProperty == null) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Unable to get user property for filter for ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Route the \"review requested from me\" filter to the field each provider actually reads:\n\t\t\t// GitHub/GitLab expect a login (reviewRequestedLogin), Bitbucket/Azure an account id (reviewerId),\n\t\t\t// and Bitbucket Server a login (reviewerLogin). `userFilterProperty` is already the account id for\n\t\t\t// Bitbucket/Azure and the username for the rest.\n\t\t\tlet reviewRequestedLogin: string | undefined;\n\t\t\tlet reviewerId: string | undefined;\n\t\t\tlet reviewerLogin: string | undefined;\n\t\t\tif (options.filters.includes(PullRequestFilter.ReviewRequested)) {\n\t\t\t\tswitch (providerId) {\n\t\t\t\t\tcase GitCloudHostIntegrationId.Bitbucket:\n\t\t\t\t\tcase GitCloudHostIntegrationId.AzureDevOps:\n\t\t\t\t\tcase GitSelfManagedHostIntegrationId.AzureDevOpsServer:\n\t\t\t\t\t\treviewerId = userFilterProperty;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase GitSelfManagedHostIntegrationId.BitbucketServer:\n\t\t\t\t\t\treviewerLogin = userFilterProperty;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treviewRequestedLogin = userFilterProperty;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tgetPullRequestsOptions = {\n\t\t\t\tauthorLogin: options.filters.includes(PullRequestFilter.Author) ? userFilterProperty : undefined,\n\t\t\t\tassigneeLogins: options.filters.includes(PullRequestFilter.Assignee) ? [userFilterProperty] : undefined,\n\t\t\t\treviewRequestedLogin: reviewRequestedLogin,\n\t\t\t\treviewerId: reviewerId,\n\t\t\t\treviewerLogin: reviewerLogin,\n\t\t\t\tmentionLogin: options.filters.includes(PullRequestFilter.Mention) ? userFilterProperty : undefined,\n\t\t\t};\n\t\t}\n\n\t\tif (\n\t\t\tapi.getProviderPullRequestsPagingMode(providerId) === PagingMode.Repo &&\n\t\t\t!api.isRepoIdsInput(reposOrRepoIds)\n\t\t) {\n\t\t\tconst cursorInfo = this.parseCursorInfo<PagedRepoInput>(options?.cursor);\n\t\t\tconst cursors: PagedRepoInput[] = cursorInfo.cursors ?? [];\n\t\t\tlet repoInputs: PagedRepoInput[] = reposOrRepoIds.map(repo => ({ repo: repo, cursor: undefined }));\n\t\t\tif (cursors.length > 0) {\n\t\t\t\trepoInputs = cursors;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cursor: { cursors: PagedRepoInput[]; page?: number } = { cursors: [] };\n\t\t\t\tlet hasMore = false;\n\t\t\t\tlet truncated = false;\n\t\t\t\tlet metadata: CollectionMetadata | undefined;\n\t\t\t\tconst failures: CollectionScopeFailure[] = [];\n\t\t\t\tconst data: ProviderPullRequest[] = [];\n\t\t\t\t// `allSettled`, not `Promise.all`: one repo's read rejecting must not discard every sibling repo's\n\t\t\t\t// already-fetched PRs and cursors. A rejected repo becomes a structured `CollectionScopeFailure`\n\t\t\t\t// (attributed to that repo) so the facade warns on it + sets `fetchFailed`, while the survivors and\n\t\t\t\t// their continuation cursors are still returned.\n\t\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\t\trepoInputs.map(async repoInput => {\n\t\t\t\t\t\tconst results = await api.getPullRequestsForRepo(\n\t\t\t\t\t\t\ttoTokenWithInfo(providerId, session),\n\t\t\t\t\t\t\trepoInput.repo,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t...getPullRequestsOptions,\n\t\t\t\t\t\t\t\tcursor: repoInput.cursor,\n\t\t\t\t\t\t\t\tisPAT: sendsBasicCredential(providerId, session),\n\t\t\t\t\t\t\t\t// Per repository: an unfiltered read may span organizations, and a host can narrow the base\n\t\t\t\t\t\t\t\t// to each repository's own.\n\t\t\t\t\t\t\t\tbaseUrl:\n\t\t\t\t\t\t\t\t\toptions?.customUrl == null && isGitSelfManagedHostIntegrationId(providerId)\n\t\t\t\t\t\t\t\t\t\t? this.getRepositoriesApiBaseUrl(session, [repoInput.repo])\n\t\t\t\t\t\t\t\t\t\t: customUrl,\n\t\t\t\t\t\t\t\t// Continuation is driven by the per-repo cursor; only apply an explicit page on the\n\t\t\t\t\t\t\t\t// first request so it can't clobber a continuation cursor on later pages.\n\t\t\t\t\t\t\t\tpage: repoInput.cursor == null ? options?.page : undefined,\n\t\t\t\t\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\t\t\t\t\tstates: states,\n\t\t\t\t\t\t\t\t// Azure DevOps only populates clone URLs on request (extra call); no-op elsewhere.\n\t\t\t\t\t\t\t\tincludeRemoteInfo: isAzureProviderId(providerId) ? true : undefined,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { repoInput: repoInput, results: results };\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthrowIfAllSettledFailed(settled);\n\n\t\t\t\t// `allSettled` preserves order, so `settled[i]` is `repoInputs[i]`.\n\t\t\t\tsettled.forEach((outcome, i) => {\n\t\t\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\t\t\tconst failedRepo = repoInputs[i].repo;\n\t\t\t\t\t\tfailures.push(\n\t\t\t\t\t\t\ttoCollectionScopeFailure(\n\t\t\t\t\t\t\t\t{ providerId: providerId, repositoryId: `${failedRepo.namespace}/${failedRepo.name}` },\n\t\t\t\t\t\t\t\toutcome.reason,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { repoInput, results } = outcome.value;\n\t\t\t\t\tdata.push(...results.values);\n\t\t\t\t\t// Fan-out across repos: preserve each repo's SDK completeness/failures and its terminal\n\t\t\t\t\t// truncation so a single failed/incomplete repo isn't lost when merged with its siblings.\n\t\t\t\t\tmetadata = mergeCollectionMetadata(metadata, results.metadata);\n\t\t\t\t\tif (results.paging?.truncated) {\n\t\t\t\t\t\ttruncated = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (results.paging?.more) {\n\t\t\t\t\t\thasMore = true;\n\t\t\t\t\t\tcursor.cursors.push({ repo: repoInput.repo, cursor: results.paging.cursor });\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Merge the GitLens-side per-repo rejections into the SDK metadata so both flow through the same\n\t\t\t\t// warning/fetchFailed assessment downstream.\n\t\t\t\tif (failures.length > 0) {\n\t\t\t\t\tmetadata = mergeCollectionMetadata(metadata, { completeness: 'partial', failures: failures });\n\t\t\t\t}\n\n\t\t\t\t// Keep the requested page number in the composite cursor so the facade can report the real\n\t\t\t\t// currentPage when the consumer continues using only the cursor.\n\t\t\t\tif (options?.page != null) {\n\t\t\t\t\tcursor.page = options.page;\n\t\t\t\t}\n\n\t\t\t\tawait this.confirmScopedAuthFailures(session, metadata);\n\t\t\t\tthis.resetRequestExceptionCount('getPullRequestsForRepos');\n\t\t\t\treturn {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tvalues: data,\n\t\t\t\t\t\tpaging: {\n\t\t\t\t\t\t\tmore: hasMore,\n\t\t\t\t\t\t\tcursor: JSON.stringify(cursor),\n\t\t\t\t\t\t\ttruncated: truncated || undefined,\n\t\t\t\t\t\t\t// Echo the requested numbered page so the facade reports the real currentPage for\n\t\t\t\t\t\t\t// numbered-page hosts (GitLab/Bitbucket/Azure), not a synthesized 1. Cursor-only hosts\n\t\t\t\t\t\t\t// leave `page` undefined via their own reads.\n\t\t\t\t\t\t\tpage: options?.page,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmetadata: metadata,\n\t\t\t\t\t},\n\t\t\t\t\tduration: performance.now() - start,\n\t\t\t\t};\n\t\t\t} catch (ex) {\n\t\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await api.getPullRequestsForRepos(toTokenWithInfo(providerId, session), reposOrRepoIds, {\n\t\t\t\t...getPullRequestsOptions,\n\t\t\t\tcursor: options?.cursor,\n\t\t\t\tisPAT: sendsBasicCredential(providerId, session),\n\t\t\t\tbaseUrl: customUrl,\n\t\t\t\tpage: options?.page,\n\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\tstates: states,\n\t\t\t\t// Azure DevOps only populates clone URLs on request (extra call); no-op elsewhere.\n\t\t\t\tincludeRemoteInfo: isAzureProviderId(providerId) ? true : undefined,\n\t\t\t\tfields: options?.summary ? summaryPullRequestFields : undefined,\n\t\t\t});\n\t\t\tawait this.confirmScopedAuthFailures(session, result.metadata);\n\t\t\tthis.resetRequestExceptionCount('getPullRequestsForRepos');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/** Account-wide (or repo-scoped) search for the current user's pull requests. */\n\t@trace()\n\tasync searchMyPullRequests(\n\t\trepos?: T | T[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions & { connectionId?: string },\n\t): Promise<IntegrationResult<PullRequest[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst { connectionId, ...searchOptions } = options ?? {};\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst prs = await this.searchProviderMyPullRequests(\n\t\t\t\tsession,\n\t\t\t\tensureArray(repos),\n\t\t\t\tcancellation,\n\t\t\t\tsearchOptions,\n\t\t\t);\n\t\t\tthis.resetRequestExceptionCount('searchMyPullRequests');\n\t\t\treturn { value: prs, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('searchMyPullRequests', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tsilent: true,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\terror: toError(ex),\n\t\t\t\tduration: performance.now() - start,\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Account-wide, user-scoped counterpart of {@link getMyPullRequestsForReposResult} that returns each host's raw\n\t * rows: provider-apis' `ProviderPullRequest`, or GitHub's own `PullRequest`, still to be tagged for the read\n\t * (`toPullRequestRow`). Unlike the repo-scoped core, this needs no\n\t * `repos` — it reads the current user's pull requests across the account, so the ProviderBackend sweep\n\t * can drive its Kanban \"done\" column even when no repositories are supplied (where the repo-scoped core\n\t * rejects an empty `repos` input). Recovers thrown errors into `{ error }` so callers surface warnings.\n\t */\n\tasync getMyPullRequestsForUserResult(\n\t\toptions?: {\n\t\t\tstate?: PullRequestStateFilter[];\n\t\t\tcursor?: string;\n\t\t\tincludeReviewRequested?: boolean;\n\t\t\t/** Exact OR union of account-wide relationships to include. */\n\t\t\tfilters?: PullRequestFilter[];\n\t\t\t/** Request only the stable list fields, omitting optional provider enrichments. */\n\t\t\tsummary?: boolean;\n\t\t},\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderApiPagedResult<ProviderPullRequest | PullRequest> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tif (this.getProviderMyPullRequestsForUser == null) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderMyPullRequestsForUser(session, options);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getMyPullRequestsForUser');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getMyPullRequestsForUser', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * Reads the current user's pull requests across the whole account using each provider's native \"my PRs\"\n\t * query, returning its raw rows (see {@link getMyPullRequestsForUserResult}). Without `filters`, the exact user\n\t * scopes depend on provider-native\n\t * behavior and options like `includeReviewRequested`. With `filters`, each member is an exact account-wide OR\n\t * relationship validated by the facade before this provider hook is called. Optional: providers that can't\n\t * express an account-wide user query leave it undefined and the surface falls back to repo-scoped.\n\t *\n\t * These native user queries are cursor-based, so `cursor` (not a page number) drives continuation; there\n\t * is no jump-to-page-N and no per-call page size on this path.\n\t *\n\t * `includeReviewRequested` opts into the review-requested slice for providers whose account-wide read\n\t * only returns authored PRs natively and must fan out per-repo to add reviewer PRs (Bitbucket). It's off\n\t * by default so a sweep pays gkcli-parity cost (authored only) unless the caller deliberately opts in;\n\t * providers whose native query already covers review-requested PRs ignore it.\n\t */\n\tprotected getProviderMyPullRequestsForUser?(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: {\n\t\t\tstate?: PullRequestStateFilter[];\n\t\t\tcursor?: string;\n\t\t\tincludeReviewRequested?: boolean;\n\t\t\tfilters?: PullRequestFilter[];\n\t\t\tsummary?: boolean;\n\t\t},\n\t): Promise<ProviderApiPagedResult<ProviderPullRequest | PullRequest> | undefined>;\n\n\t/**\n\t * The current account as each of `pullRequests` identifies its members, in order: what a raw row's\n\t * `authoredByMe` and `viewer` are resolved against when it's mapped. Most hosts give a person one id, so every\n\t * row gets the account itself; Azure DevOps Server answers per collection (see `AzureDevOpsServerIntegration`).\n\t * Throws only when the account itself can't be read.\n\t */\n\tasync getPullRequestViewers(\n\t\tpullRequests: readonly (ProviderPullRequest | PullRequest)[],\n\t\tconnectionId?: string,\n\t): Promise<({ id: string; username?: string } | undefined)[]> {\n\t\tconst account = await this.getCurrentAccount({ connectionId: connectionId });\n\t\tconst viewer = account != null ? { id: account.id, username: account.username } : undefined;\n\t\treturn pullRequests.map(() => viewer);\n\t}\n\n\t/**\n\t * Parses a Repo/Project paging cursor into its `cursors` bundle. Guards against valid JSON whose\n\t * `cursors` is a truthy non-array (e.g. `{ \"cursors\": \"...\" }`), which would otherwise bypass the\n\t * `?? []` fallback at call sites and flow into `.map()` downstream, throwing instead of degrading to\n\t * the first page.\n\t */\n\tprivate parseCursorInfo<T>(cursor?: string): { cursors?: T[] } {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(cursor ?? '{}') as { cursors?: T[] };\n\t\t\treturn Array.isArray(parsed?.cursors) ? parsed : {};\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tprotected abstract searchProviderMyPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: T[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the filtered pull-request search. Errors become the soft\n\t * `{ error }` branch so the public facade can preserve an empty account and a failed request as distinct\n\t * outcomes.\n\t */\n\tasync searchPullRequestsPageResult(\n\t\toptions: {\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: PullRequestSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t\t/** See {@link IntegrationManager.searchPullRequestsPage}. */\n\t\t\tsummary?: boolean;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderPullRequestSearchPage | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.searchProviderPullRequestsPage?.(session, options, cancellation);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('searchPullRequestsPage');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('searchPullRequestsPage', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/** Must agree with `ProviderMetadata.supportedPullRequestSearch`. */\n\tprotected searchProviderPullRequestsPage?(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions: {\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: PullRequestSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t\t/** See the caller's option of the same name on {@link searchPullRequestsPage}. */\n\t\t\tsummary?: boolean;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestSearchPage | undefined>;\n\n\t/** Free-text search across pull requests, optionally narrowed to `repos`. */\n\t@trace()\n\tasync searchPullRequests(\n\t\tsearchQuery: string,\n\t\trepos?: T | T[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions & { connectionId?: string },\n\t): Promise<PullRequest[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst { connectionId, ...searchOptions } = options ?? {};\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return undefined;\n\n\t\ttry {\n\t\t\tconst prs = await this.searchProviderPullRequests?.(\n\t\t\t\tsession,\n\t\t\t\tsearchQuery,\n\t\t\t\tensureArray(repos),\n\t\t\t\tcancellation,\n\t\t\t\tsearchOptions,\n\t\t\t);\n\t\t\tthis.resetRequestExceptionCount('searchPullRequests');\n\t\t\treturn prs;\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('searchPullRequests', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprotected searchProviderPullRequests?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tsearchQuery: string,\n\t\trepos?: T[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the FILTERED issue search — issues matching structured criteria over a\n\t * repository/org scope, with no forced relationship to the current user. Recovers thrown errors into\n\t * `{ error }` so the facade surfaces a warning instead of a silent empty page.\n\t *\n\t * Distinct from every other issue read on this class: {@link searchMyIssuesWithTruncationResult} is bound to\n\t * the current user by construction, and {@link getMyIssuesForReposAsShapesResult} goes through the SDK's\n\t * repo-scoped read (whose over-limit recovery walk can cost up to 128 requests). This one is one request per\n\t * page and carries no relationship it wasn't asked for.\n\t */\n\tasync searchIssuesPageResult(\n\t\toptions: {\n\t\t\t/**\n\t\t\t * Repositories to search, as namespace/name descriptors. NOT repository ids: a search query names\n\t\t\t * repositories by path, so an id-based input can't be expressed and the facade rejects it before here.\n\t\t\t */\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: IssueSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderIssueSearchPage | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.searchProviderIssuesPage?.(session, options, cancellation);\n\t\t\tthis.resetRequestExceptionCount('searchIssuesPage');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('searchIssuesPage', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL, like {@link searchProviderPullRequests}: a provider that can't express the criteria server-side\n\t * doesn't implement it, and the facade refuses the read (warning + `fetchFailed`) rather than serving a list\n\t * that was never narrowed. Whether a provider implements this must agree with what\n\t * `ProviderMetadata.supportedIssueSearch` declares.\n\t */\n\tprotected searchProviderIssuesPage?(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions: {\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: IssueSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderIssueSearchPage | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the count-only probe: how many issues MATCH each scope, transferring no issues\n\t * at all. Recovers thrown errors into `{ error }` like the reads around it.\n\t *\n\t * Counts come back POSITIONALLY — one per input scope, in order — because a caller's key must never reach the\n\t * provider query. See {@link ProviderSearchCount} for what each slot can hold; `undefined` means the provider\n\t * didn't report a count for it, never zero matches.\n\t */\n\tasync countIssuesResult(\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: IssueSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderSearchCount[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst counts = await this.countProviderIssues?.(session, scopes, cancellation);\n\t\t\tthis.resetRequestExceptionCount('countIssues');\n\t\t\treturn { value: counts, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('countIssues', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: only a provider that can answer \"how many match\" WITHOUT fetching the matches implements this.\n\t * GitHub's search reports `issueCount` on a zero-node selection, and Azure DevOps Server's WIQL returns the\n\t * matching ids without their details; GitLab's REST exposes a total on some endpoints but not for a\n\t * search-shaped query. A provider that can't answer doesn't implement it and the facade refuses the probe, so a\n\t * consumer hides its count rather than being shown a fabricated one.\n\t */\n\tprotected countProviderIssues?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: IssueSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderSearchCount[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the BATCH issue read: resolves several `(owner, repo, number)` coordinates, plus\n\t * `project` on Azure DevOps, in ONE call to {@link getProviderIssuesBatch}. One settled slot per input\n\t * coordinate: `fulfilled` with `undefined` means the issue does not exist or is not visible to this token;\n\t * `rejected` means that target could not be checked, never that it is absent.\n\t *\n\t * Distinct from every search on this class, and deliberately so. A search answers \"what matches\"; this answers\n\t * \"does this exact issue exist\", which is the question a caller correlating a branch name to an issue is\n\t * actually asking. It has no result ceiling, no ordering and no cursor, and — the property that matters most —\n\t * an absent slot is a PROVEN ABSENCE rather than \"not found within a page budget\", so a caller can cache a\n\t * miss instead of re-walking for it forever.\n\t *\n\t * Results come back POSITIONALLY — one per input coordinate, in order — for the same reason\n\t * {@link countIssuesResult} does: a caller's key must never reach the provider query.\n\t *\n\t * Failure isolation happens PER TARGET, mirroring {@link getPullRequestsBatchResult}: the whole call counts\n\t * as a failure against the integration's request-exception budget only when EVERY slot rejected, and not even\n\t * then when a credential that checks out was refused by each target's own scope (`settleBatchRefusals`).\n\t * Server errors and timeouts on the targets show one notice however many hit one, and cost a strike only as\n\t * part of that whole-call failure (`reportDeferredRequestFailures`), so a call spends at most one. A batch read\n\t * with etags makes up to two such calls (a full read of the targets without an etag, and a full read of the ones\n\t * that changed), so it can spend two; its cheap check ({@link getIssuesEtagFieldsResult}) spends nothing unless\n\t * the credential is refused.\n\t */\n\tasync getIssuesBatchResult(\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<IssueShape | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet slots: PromiseSettledResult<IssueShape | undefined>[] | undefined;\n\t\ttry {\n\t\t\tslots = await this.getProviderIssuesBatch?.(session, coordinates, cancellation);\n\t\t\tif (slots == null) {\n\t\t\t\tthis.resetRequestExceptionCount('getIssuesBatch');\n\t\t\t\treturn { value: undefined, duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, coordinates, slots);\n\n\t\t\tthis.resetRequestExceptionCount('getIssuesBatch');\n\t\t\tthis.reportDeferredRequestFailures(slots, false);\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tconst struck = this.handleProviderException('getIssuesBatch', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\tthis.reportDeferredRequestFailures(slots, !struck);\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: one settled slot per input coordinate, in order, in the same shape the list reads return for this\n\t * provider. `fulfilled` with `undefined` is a PROVEN ABSENCE a caller may cache; `rejected` means that target\n\t * could not be checked — never conflate the two, so a host implements this only where it can tell them apart.\n\t *\n\t * GitHub/GHE alias up to 25 coordinates into one document and so chunk internally; a chunk that throws rejects\n\t * every slot in that chunk, not the ones in other chunks. GitLab and Azure DevOps read one issue per request and\n\t * fan out with `mapSettledBounded`, so one target's failure rejects only its own slot. Bitbucket has no issues.\n\t */\n\tprotected getProviderIssuesBatch?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<IssueShape | undefined>[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the BATCH pull request read: resolves several coordinates, in any state, BY\n\t * IDENTITY, in ONE call to {@link getProviderPullRequestsBatch}. One settled slot per input coordinate:\n\t * `fulfilled` with `undefined` means the pull request does not exist or is not visible to this token;\n\t * `rejected` means that target could not be checked, never that it is absent.\n\t *\n\t * Failure isolation happens PER TARGET, not per call: a hook that reads one pull request per request (every\n\t * host but GitHub/GHE) fans its coordinates out itself and settles each independently, so one bad target\n\t * rejects only its own slot. Mirrors {@link getMyPullRequestsForReposResult}'s per-repo fan-out — the whole\n\t * call counts as a failure against the integration's request-exception budget only when EVERY slot rejected,\n\t * and not even then when a credential that checks out was refused by each target's own scope\n\t * (`settleBatchRefusals`). Server errors and timeouts on the targets show one notice however many hit one, and\n\t * cost a strike only as part of that whole-call failure (`reportDeferredRequestFailures`), so one call spends at\n\t * most one. A batch read with etags makes up to two such calls (a full read of the targets without an etag, and a\n\t * full read of the ones that changed), so it can spend two; its cheap check\n\t * ({@link getPullRequestsEtagFieldsResult}) spends nothing unless the credential is refused.\n\t */\n\tasync getPullRequestsBatchResult(\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions?: { currentAccount?: { id: string; username?: string } },\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<PullRequestShape | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet slots: PromiseSettledResult<PullRequestShape | undefined>[] | undefined;\n\t\ttry {\n\t\t\tslots = await this.getProviderPullRequestsBatch?.(session, coordinates, options, cancellation);\n\t\t\tif (slots == null) {\n\t\t\t\tthis.resetRequestExceptionCount('getPullRequestsBatch');\n\t\t\t\treturn { value: undefined, duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, coordinates, slots);\n\n\t\t\tthis.resetRequestExceptionCount('getPullRequestsBatch');\n\t\t\tthis.reportDeferredRequestFailures(slots, false);\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tconst struck = this.handleProviderException('getPullRequestsBatch', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\tthis.reportDeferredRequestFailures(slots, !struck);\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: resolves several coordinates, returning one settled slot per input coordinate, in order, in the\n\t * same shape the list reads return for this provider. `fulfilled` with `undefined` is a PROVEN ABSENCE a\n\t * caller may cache; `rejected` means that target could not be checked — never conflate the two.\n\t *\n\t * A provider that reads one pull request per upstream request (every host but GitHub/GHE) fans its\n\t * coordinates out with `mapSettledBounded`, so one target's failure rejects only its own slot instead of\n\t * taking the whole call down. GitHub/GHE alias up to 25 coordinates into one document and so chunk\n\t * internally; a chunk that throws rejects every slot in that chunk, not the ones in other chunks.\n\t */\n\tprotected getProviderPullRequestsBatch?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string } } | undefined,\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<PullRequestShape | undefined>[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the cheap check behind the batch issue read's etags: each coordinate's change\n\t * state ({@link IssueEtagFields}), plus the inputs of each of `options.etagIncludes`, in ONE call to\n\t * {@link getProviderIssuesEtagFields}. The slots mean what\n\t * {@link getIssuesBatchResult}'s do — `fulfilled` with `undefined` is a PROVEN ABSENCE, `rejected` means that\n\t * target could not be checked.\n\t *\n\t * Unlike there, failures other than a refused credential are never the call's: every slot comes back as it\n\t * settled, even when none answered, so each failed target is judged by its own reason. Such failures spend no\n\t * strike and show no notice, since the targets they touch fall through to the full read, which does both if the\n\t * host really is failing, or are dropped as rate-limited or without a connection. Refusals are settled as there\n\t * (`settleBatchRefusals` with `keepOtherFailures`), and only a refused credential fails the call, on the auth path\n\t * (`handleEtagCheckException`). The failure budget is reset only when some target answered.\n\t */\n\tasync getIssuesEtagFieldsResult(\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { etagIncludes?: readonly IssueEtagInclude[] },\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<IssueEtagFields | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst slots = await this.getProviderIssuesEtagFields?.(session, coordinates, options, cancellation);\n\t\t\tif (slots == null) return { value: undefined, duration: performance.now() - start };\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, coordinates, slots, { keepOtherFailures: true });\n\n\t\t\tif (slots.some(slot => slot.status === 'fulfilled')) {\n\t\t\t\tthis.resetRequestExceptionCount('getIssuesEtagFields');\n\t\t\t}\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleEtagCheckException('getIssuesEtagFields', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: the cheap check behind the batch issue read's etags — one settled slot per input coordinate, in\n\t * order, holding the issue's change state in the vocabulary {@link getProviderIssuesBatch}'s rows end in, so\n\t * both reads compute the same etag. Each include's inputs are read only when it is listed in\n\t * `options.etagIncludes`, and only where a full row carries them. `fulfilled` with `undefined` is a PROVEN\n\t * ABSENCE, as there. A host implements this only where it is cheaper than the full read.\n\t */\n\tprotected getProviderIssuesEtagFields?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { etagIncludes?: readonly IssueEtagInclude[] },\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<IssueEtagFields | undefined>[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the cheap check behind the batch pull request read's etags: each coordinate's\n\t * change state ({@link PullRequestEtagFields}), plus the inputs of each of `options.etagIncludes`, in ONE call to\n\t * {@link getProviderPullRequestsEtagFields}. The slots mean what {@link getPullRequestsBatchResult}'s do —\n\t * `fulfilled` with `undefined` is a PROVEN ABSENCE, `rejected` means that target could not be checked. Failures\n\t * are judged and budgeted as in {@link getIssuesEtagFieldsResult}: only a refused credential fails the call or\n\t * spends a strike.\n\t */\n\tasync getPullRequestsEtagFieldsResult(\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { etagIncludes?: readonly PullRequestEtagInclude[] },\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<PullRequestEtagFields | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst slots = await this.getProviderPullRequestsEtagFields?.(session, coordinates, options, cancellation);\n\t\t\tif (slots == null) return { value: undefined, duration: performance.now() - start };\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, coordinates, slots, { keepOtherFailures: true });\n\n\t\t\tif (slots.some(slot => slot.status === 'fulfilled')) {\n\t\t\t\tthis.resetRequestExceptionCount('getPullRequestsEtagFields');\n\t\t\t}\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleEtagCheckException('getPullRequestsEtagFields', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: the cheap check behind the batch pull request read's etags — one settled slot per input coordinate,\n\t * in order, holding the pull request's change state in the vocabulary {@link getProviderPullRequestsBatch}'s\n\t * rows end in, after their WHOLE conversion chain, so both reads compute the same etag. Each include's inputs are\n\t * read only when it is listed in `options.etagIncludes`. `fulfilled` with `undefined` is a PROVEN ABSENCE, as\n\t * there. A host implements this only where it is cheaper than the full read.\n\t */\n\tprotected getProviderPullRequestsEtagFields?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { etagIncludes?: readonly PullRequestEtagInclude[] },\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<PullRequestEtagFields | undefined>[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the pull-requests-by-branch read: for each target, every pull request whose head\n\t * is that branch, in any state, in ONE call to {@link getProviderPullRequestsForBranches}. One settled slot\n\t * per target: `fulfilled` with an empty list means the host answered and nothing matched; `rejected` means\n\t * that target could not be checked, never that it has no pull requests.\n\t *\n\t * Uncached, and deliberately not built on {@link getPullRequestForBranch}: that read caches through\n\t * `IntegrationCacheProvider.getPullRequestForBranch`, answers one pull request, and on several hosts looks the\n\t * branch ref up, which answers \"none\" once a merged pull request's branch is deleted.\n\t *\n\t * Failure isolation is per target, as in {@link getPullRequestsBatchResult}: the whole call counts against the\n\t * request-exception budget only when EVERY slot rejected, and not when each target's own scope refused a\n\t * credential that checks out. Server errors and timeouts on the targets show one notice however many hit one, and\n\t * cost a strike only as part of that whole-call failure.\n\t */\n\tasync getPullRequestsForBranchesResult(\n\t\ttargets: readonly { owner: string; repo: string; project?: string; branch: string; headOwner?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string }; limit: number },\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet slots: PromiseSettledResult<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined;\n\t\ttry {\n\t\t\tslots = await this.getProviderPullRequestsForBranches?.(session, targets, options, cancellation);\n\t\t\tif (slots == null) {\n\t\t\t\tthis.resetRequestExceptionCount('getPullRequestsForBranches');\n\t\t\t\treturn { value: undefined, duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, targets, slots);\n\n\t\t\tthis.resetRequestExceptionCount('getPullRequestsForBranches');\n\t\t\tthis.reportDeferredRequestFailures(slots, false);\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tconst struck = this.handleProviderException('getPullRequestsForBranches', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\tthis.reportDeferredRequestFailures(slots, !struck);\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: one settled slot per target, in order. A fulfilled slot lists the matching pull requests, newest\n\t * first and at most `options.limit` of them, in the same shape the list reads return for this provider where\n\t * the host allows it; `truncated` means more may match than were returned.\n\t *\n\t * A row matches only when its head branch is the target's `branch` AND its head repository is the base\n\t * repository itself (`headOwner` omitted) or the fork `headOwner` owns — a same-named branch in some other\n\t * fork is a different branch. A host that reads one target per request fans out with `mapSettledBounded`, so\n\t * one target's failure rejects only its own slot; GitHub/GHE alias up to 25 targets per request, and a request\n\t * that throws rejects only its own targets.\n\t */\n\tprotected getProviderPullRequestsForBranches?(\n\t\tsession: ProviderAuthenticationSession,\n\t\ttargets: readonly { owner: string; repo: string; project?: string; branch: string; headOwner?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string }; limit: number },\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined>;\n\n\t/**\n\t * The PR twin of {@link countIssuesResult}: counts each scope's pull requests, transferring none where the\n\t * provider has a count query. Each slot is a {@link ProviderPullRequestCount}, so a provider that can only count\n\t * by reading (Bitbucket Data Center) can mark a figure it stopped short of as a floor, or an `Error` refusing only\n\t * that scope (Azure DevOps Server).\n\t */\n\tasync countPullRequestsResult(\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<(ProviderPullRequestCount | Error)[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst counts = await this.countProviderPullRequests?.(session, scopes, cancellation);\n\t\t\tthis.resetRequestExceptionCount('countPullRequests');\n\t\t\treturn { value: counts, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('countPullRequests', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL, like {@link countProviderIssues}: only a provider that can answer \"how many match\" implements it —\n\t * GitHub/GHE with a zero-node search, Bitbucket Data Center by reading within a budget and reporting a floor\n\t * past it, Azure DevOps Server from the drain its search reads. Must agree with\n\t * `ProviderMetadata.supportedPullRequestSearch`, which the facade validates against.\n\t */\n\tprotected countProviderPullRequests?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<(ProviderPullRequestCount | Error)[] | undefined>;\n\n\tgetPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {\n\t\treturn this.getProviderPullRequestIdentityFromMaybeUrl?.(search);\n\t}\n\n\tprotected getProviderPullRequestIdentityFromMaybeUrl?(search: string): PullRequestUrlIdentity | undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gitHostIntegration.js","names":[],"sources":["../../../../../plus/integrations/src/models/gitHostIntegration.ts"],"sourcesContent":["import type { CollectionMetadata, CollectionScopeFailure, GitHubPullRequestFieldMap } from '@gitkraken/provider-apis';\nimport type { Account, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { IssueSearchCriteria, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequestState as PullRequestState } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type {\n\tPullRequest,\n\tPullRequestMergeMethod,\n\tPullRequestSearchCriteria,\n\tPullRequestShape,\n\tPullRequestStackInfo,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport type { ResourceDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\nimport type { PullRequestUrlIdentity } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { ensureArray } from '@gitlens/utils/array.js';\nimport { isCancellationError } from '@gitlens/utils/cancellation.js';\nimport { gate } from '@gitlens/utils/decorators/gate.js';\nimport { trace } from '@gitlens/utils/decorators/log.js';\nimport { first } from '@gitlens/utils/iterable.js';\nimport { Logger } from '@gitlens/utils/logger.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport type { PagedResult } from '@gitlens/utils/paging.js';\nimport type { ProviderAuthenticationSession } from '../authentication/models.js';\nimport { toTokenWithInfo } from '../authentication/models.js';\nimport type { ProviderScopeFailure } from '../collectionMetadata.js';\nimport {\n\tthrowIfCallerContractError,\n\ttoCollectionFailureError,\n\ttoCollectionScopeFailure,\n} from '../collectionMetadata.js';\nimport type { IntegrationIds } from '../constants.js';\nimport { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../constants.js';\nimport { toError } from '../errors.js';\nimport type {\n\tGetIssuesOptions,\n\tGetPullRequestsOptions,\n\tPagedProjectInput,\n\tPagedRepoInput,\n\tProviderAccount,\n\tProviderApiPagedResult,\n\tProviderHierarchyResult,\n\tProviderIssue,\n\tProviderOrganization,\n\tProviderPullRequest,\n\tProviderRepoInput,\n\tProviderReposInput,\n\tProviderRepository,\n} from '../providers/models.js';\nimport {\n\tIssueFilter,\n\tPagingMode,\n\tPullRequestFilter,\n\ttoIssueShape,\n\ttoProviderIssueStates,\n\ttoProviderPullRequestStates,\n} from '../providers/models.js';\nimport { isAzureProviderId } from '../providers/providerErrors.js';\nimport type { ProvidersApi } from '../providers/providersApi.js';\nimport { mergeCollectionMetadata, throwIfAllSettledFailed } from '../providers/utils/providerPaging.js';\nimport { areDomainsOnSameHost } from '../utils/domain.utils.js';\nimport { getSelfManagedBaseUrl, isGitSelfManagedHostIntegrationId } from '../utils/integration.utils.js';\nimport type {\n\tBatchSlot,\n\tIntegrationResult,\n\tIntegrationType,\n\tIssueEtagFields,\n\tIssueEtagInclude,\n\tProviderIssueSearchPage,\n\tProviderPullRequestCount,\n\tProviderPullRequestSearchPage,\n\tProviderSearchCount,\n\tPullRequestEtagFields,\n\tPullRequestEtagInclude,\n} from './integration.js';\nimport { IntegrationBase, isReadSessionFailure } from './integration.js';\nimport type { MyIssuesForReposOptions } from './issueReads.js';\n\n/**\n * Whether an SDK read for `providerId` must send the session's secret as an HTTP Basic credential.\n *\n * Azure DevOps authenticates a PAT only as Basic — Azure DevOps Server refuses one sent as a bearer token outright —\n * and the Azure integration's own reads already pass it that way (`AzureDevOpsIntegrationBase.getApiOptions`). The\n * reads here are shared by every host, so they have to ask; every other provider keeps the SDK's default.\n */\nfunction sendsBasicCredential(providerId: IntegrationIds, session: ProviderAuthenticationSession): boolean | undefined {\n\treturn isAzureProviderId(providerId) ? session.type !== 'oauth' : undefined;\n}\n\n/** Read options for {@link GitHostIntegration.searchMyPullRequests} and the provider hook behind it. */\nexport type SearchMyPullRequestsOptions = {\n\t/** Suppresses the user-facing notification when the read fails. */\n\tsilent?: boolean;\n\t/**\n\t * PR states to include (open/closed/merged/all). Providers that cannot express it in a single query\n\t * filter the normalized results; omitted preserves the historical open-only behavior.\n\t */\n\tstate?: PullRequestStateFilter;\n\tincludeReviewRequested?: boolean;\n};\n\n/** Read options for {@link GitHostIntegration.searchPullRequests} and the provider hook behind it. */\nexport type SearchPullRequestsOptions = {\n\t/** PR states to include; omitted preserves the provider's default. */\n\tinclude?: PullRequestState[];\n};\n\ntype MyPullRequestsForReposOptions = {\n\tfilters?: PullRequestFilter[];\n\tcursor?: string;\n\tcustomUrl?: string;\n\tpage?: number;\n\tpageSize?: number;\n\t/** PR states to include; when omitted the provider returns its default (open only). */\n\tstate?: PullRequestStateFilter | PullRequestStateFilter[];\n\t/** Requests the lightweight row shape without per-row build status or commit count. */\n\tsummary?: boolean;\n};\n\n/**\n * Rejects a read the provider can't serve as asked: logs the reason and returns it as the `{ error }` half of an\n * {@link IntegrationResult}, timed from `start`.\n *\n * A single builder because these refusals are a contract, not incidental returns — the read cores below reject on\n * unsupported input, an inexpressible filter set, or an unresolvable filter account, and each one must reach the\n * caller as an error it can surface as a warning rather than as an empty success. Writing the message once also\n * keeps the logged text and the thrown text from drifting apart, which is exactly what happened while each site\n * spelled its message out twice.\n */\nfunction unsupportedRead<T>(message: string, start: number, logContext?: string): IntegrationResult<T> {\n\tLogger.warn(message, logContext);\n\treturn { error: new Error(message), duration: performance.now() - start };\n}\n\n/**\n * Both fields gate the same GitHub `commits` subtree, so either truthy key retains the build-status rollup.\n * An absent map retains the full row; a summary read explicitly drops both optional fields.\n */\nconst summaryPullRequestFields: Required<GitHubPullRequestFieldMap> = {\n\theadCommit: false,\n\tcommitCount: false,\n};\n\nexport abstract class GitHostIntegration<\n\tID extends IntegrationIds = IntegrationIds,\n\tT extends ResourceDescriptor = ResourceDescriptor,\n> extends IntegrationBase<ID> {\n\treadonly type: IntegrationType = 'git';\n\n\t/** The self-managed installation `session` addresses, validated against this integration's host. */\n\tprotected getSelfManagedInstallationUrl(session: ProviderAuthenticationSession): string {\n\t\tconst baseUrl = getSelfManagedBaseUrl(\n\t\t\tthis.id,\n\t\t\tsession.baseUrl ?? (session.domain || this.domain),\n\t\t\tsession.protocol,\n\t\t);\n\t\tif (baseUrl == null || !areDomainsOnSameHost(baseUrl, this.domain)) {\n\t\t\tthrow new Error('Invalid self-managed integration base URL');\n\t\t}\n\n\t\treturn baseUrl;\n\t}\n\n\tprotected getSelfManagedApiBaseUrl(session: ProviderAuthenticationSession): string {\n\t\tconst baseUrl = this.getSelfManagedInstallationUrl(session);\n\t\tswitch (this.id) {\n\t\t\tcase GitSelfManagedHostIntegrationId.CloudGitHubEnterprise:\n\t\t\t\treturn `${baseUrl}/api/v3`;\n\t\t\tcase GitSelfManagedHostIntegrationId.BitbucketServer:\n\t\t\t\treturn `${baseUrl}/rest/api/1.0`;\n\t\t\tdefault:\n\t\t\t\treturn baseUrl;\n\t\t}\n\t}\n\n\t/** The base the repository-list reads hand the provider client for a self-managed host. */\n\tprotected getRepositoriesApiBaseUrl(session: ProviderAuthenticationSession, _repos: ProviderReposInput): string {\n\t\treturn this.getSelfManagedApiBaseUrl(session);\n\t}\n\n\t@gate()\n\t@trace()\n\tasync getAccountForEmail(repo: T, email: string, options?: { avatarSize?: number }): Promise<Account | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif ((await this.prepareSessionLookup()) != null) return undefined;\n\n\t\ttry {\n\t\t\tconst author = await this.getProviderAccountForEmail(this._session!, repo, email, options);\n\t\t\tthis.resetRequestExceptionCount('getAccountForEmail');\n\t\t\treturn author;\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getAccountForEmail', ex, { scope: scope });\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprotected abstract getProviderAccountForEmail(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\temail: string,\n\t\toptions?: { avatarSize?: number },\n\t): Promise<Account | undefined>;\n\n\t/**\n\t * Returns the SSH signing keys (full OpenSSH-format `<type> <key> [comment]` strings) registered by the accounts\n\t * matching the given emails on this integration, for building an `allowed_signers` file. Keyed by lowercased email;\n\t * emails with no match (and unsupported integrations) are absent. Batching the lookups is left to the integration.\n\t */\n\t@gate()\n\t@trace()\n\tasync getSshSigningKeysForEmails(repo: T, emails: string[]): Promise<Map<string, string[]>> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif ((await this.prepareSessionLookup()) != null) return new Map();\n\n\t\ttry {\n\t\t\tconst keys = await this.getProviderSshSigningKeysForEmails(this._session!, repo, emails);\n\t\t\tthis.resetRequestExceptionCount('getSshSigningKeysForEmails');\n\t\t\treturn keys;\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getSshSigningKeysForEmails', ex, { scope: scope });\n\t\t\treturn new Map();\n\t\t}\n\t}\n\n\t/** Override in integrations that expose users' SSH signing keys. Defaults to none. */\n\tprotected getProviderSshSigningKeysForEmails(\n\t\t_session: ProviderAuthenticationSession,\n\t\t_repo: T,\n\t\t_emails: string[],\n\t): Promise<Map<string, string[]>> {\n\t\treturn Promise.resolve(new Map<string, string[]>());\n\t}\n\n\t@gate()\n\t@trace()\n\tasync getAccountForCommit(\n\t\trepo: T,\n\t\trev: string,\n\t\toptions?: { avatarSize?: number },\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif ((await this.prepareSessionLookup()) != null) return undefined;\n\n\t\ttry {\n\t\t\tconst author = await this.getProviderAccountForCommit(this._session!, repo, rev, options);\n\t\t\tthis.resetRequestExceptionCount('getAccountForCommit');\n\t\t\treturn author;\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getAccountForCommit', ex, { scope: scope });\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprotected abstract getProviderAccountForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\trev: string,\n\t\toptions?: { avatarSize?: number },\n\t): Promise<Account | UnidentifiedAuthor | undefined>;\n\n\t@trace()\n\tasync getDefaultBranch(\n\t\trepo: T,\n\t\toptions?: { cancellation?: AbortSignal; expiryOverride?: boolean | number },\n\t): Promise<DefaultBranch | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif ((await this.prepareSessionLookup()) != null) return undefined;\n\n\t\tconst defaultBranch = this.ctx.cache.getRepositoryDefaultBranch(\n\t\t\trepo,\n\t\t\tthis,\n\t\t\t() => ({\n\t\t\t\tvalue: (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.getProviderDefaultBranch(this._session!, repo, options?.cancellation);\n\t\t\t\t\t\tthis.resetRequestExceptionCount('getDefaultBranch');\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tthis.handleProviderException('getDefaultBranch', ex, { scope: scope });\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\t{ expiryOverride: options?.expiryOverride },\n\t\t);\n\t\treturn defaultBranch;\n\t}\n\n\tgetRepoInfo?(repo: {\n\t\towner: string;\n\t\tname: string;\n\t\tproject?: string;\n\t\tconnectionId?: string;\n\t}): Promise<ProviderRepository | undefined>;\n\n\t/**\n\t * Settles what one repository's refusal of the credential means, as a batch read settles a refused target (see\n\t * `IntegrationBase.settleBatchRefusals`): the scope failure it is recorded as, against that repository (and, on\n\t * Azure DevOps, its project), with its cause named once the credential checks out. A refused credential throws\n\t * its own error, which the caller reports for the connection instead of the repository's refusal.\n\t */\n\tasync settleRepositoryRefusal(\n\t\trepo: { owner: string; name: string; project?: string; connectionId?: string },\n\t\trefusal: unknown,\n\t): Promise<ProviderScopeFailure | undefined> {\n\t\tconst session = await this.resolveReadSessionOrThrow(repo.connectionId, undefined);\n\t\tif (session == null) return undefined;\n\n\t\tconst [slot] = await this.settleBatchRefusals(\n\t\t\tsession,\n\t\t\t[{ owner: repo.owner, repo: repo.name, project: repo.project }],\n\t\t\t[{ status: 'rejected', reason: refusal }],\n\t\t);\n\t\treturn slot?.status === 'rejected' ? slot.failure : undefined;\n\t}\n\n\t/** Stack membership for every stacked pull request in the repository, keyed by pull request number.\n\t * Only hosts with a stacks concept implement this (currently GitHub). */\n\tgetStacksByPullRequestNumber?(\n\t\towner: string,\n\t\trepo: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<Map<number, PullRequestStackInfo> | undefined>;\n\n\tprotected abstract getProviderDefaultBranch(\n\t\t{ accessToken }: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\tcancellation?: AbortSignal,\n\t): Promise<DefaultBranch | undefined>;\n\n\t@trace()\n\tasync getRepositoryMetadata(\n\t\trepo: T,\n\t\toptions?: { cancellation?: AbortSignal; expiryOverride?: boolean | number },\n\t): Promise<RepositoryMetadata | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif ((await this.prepareSessionLookup()) != null) return undefined;\n\n\t\tconst metadata = this.ctx.cache.getRepositoryMetadata(\n\t\t\trepo,\n\t\t\tthis,\n\t\t\t() => ({\n\t\t\t\tvalue: (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.getProviderRepositoryMetadata(\n\t\t\t\t\t\t\tthis._session!,\n\t\t\t\t\t\t\trepo,\n\t\t\t\t\t\t\toptions?.cancellation,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.resetRequestExceptionCount('getRepositoryMetadata');\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tthis.handleProviderException('getRepositoryMetadata', ex, { scope: scope });\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\t{ expiryOverride: options?.expiryOverride },\n\t\t);\n\t\treturn metadata;\n\t}\n\n\tprotected abstract getProviderRepositoryMetadata(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined>;\n\n\t/**\n\t * Whether this git host implements generic org discovery. False for providers that register no\n\t * {@link getProviderOrganizationsForUser} hook — the facade uses this to\n\t * report `unsupported` instead of a silent empty list, which is indistinguishable from \"has no orgs\".\n\t */\n\tget supportsOrganizationDiscovery(): boolean {\n\t\treturn this.getProviderOrganizationsForUser != null;\n\t}\n\n\t/** Whether this git host implements generic repository discovery ({@link getProviderRepositoriesForOrg}). */\n\tget supportsRepositoryDiscovery(): boolean {\n\t\treturn this.getProviderRepositoriesForOrg != null;\n\t}\n\n\t/**\n\t * Whether this git host has a project tier between org and repo ({@link getProviderProjectsForOrg}). Only\n\t * Azure DevOps does; the facade uses this to skip the read entirely rather than call a core that returns\n\t * `undefined` for a session-less reason and be misread as a broken connection.\n\t */\n\tget supportsProjectDiscovery(): boolean {\n\t\treturn this.getProviderProjectsForOrg != null;\n\t}\n\n\t/**\n\t * Whether this git host implements the account-wide user-affiliated repository read\n\t * ({@link getProviderRepositoriesForUser}) — the org-less `gk provider repos <provider>` equivalent.\n\t */\n\tget supportsUserRepositoryDiscovery(): boolean {\n\t\treturn this.getProviderRepositoriesForUser != null;\n\t}\n\n\t/**\n\t * Whether this git host exposes issues on the ProviderBackend surface. Most git hosts do; a host with no\n\t * usable issue tracker overrides this to false — Bitbucket Cloud (deprecated in favor of dedicated issue\n\t * integrations like Jira) and Bitbucket Data Center (never had one) — so the facade reports issues as\n\t * unsupported instead of serving a partial/deprecated source or failing inside a provider client that\n\t * registers no issue function at all.\n\t *\n\t * Keep this in sync with {@link ProviderMetadata.supportedIssueFilters}: a provider that declares no issue\n\t * filters and no issue read is answering the same capability question twice, and the two must agree.\n\t */\n\tget supportsIssues(): boolean {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Whether this host has the cheap check behind the batch pull request read's etags\n\t * ({@link getProviderPullRequestsEtagFields}). The read decides before calling anything, so a host without one\n\t * full-reads every target in a single call.\n\t */\n\tget supportsPullRequestEtags(): boolean {\n\t\treturn this.getProviderPullRequestsEtagFields != null;\n\t}\n\n\t/** The issue twin of {@link supportsPullRequestEtags}: whether {@link getProviderIssuesEtagFields} exists. */\n\tget supportsIssueEtags(): boolean {\n\t\treturn this.getProviderIssuesEtagFields != null;\n\t}\n\n\t/**\n\t * Lists the organizations (orgs/workspaces/groups) the current user belongs to on this host.\n\t * `truncated === true` means the defensive page-drain backstop stopped before the upstream listing was\n\t * exhausted.\n\t *\n\t * Resolves the session for `connectionId` (or the primary connection when omitted, honoring multi-account\n\t * reads) and recovers a thrown error into `{ error }` so callers can surface it as a warning instead of\n\t * swallowing it to `undefined`.\n\t */\n\t@trace()\n\tasync getOrganizationsForUserResult(\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderHierarchyResult<ProviderOrganization> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderOrganizationsForUser?.(session);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tconst authFailure = result?.metadata?.failures?.find(\n\t\t\t\tfailure =>\n\t\t\t\t\tfailure.kind === 'authentication' &&\n\t\t\t\t\tfailure.scope != null &&\n\t\t\t\t\tfailure.scope.providerId === this.id &&\n\t\t\t\t\tObject.keys(failure.scope).length === 1,\n\t\t\t);\n\t\t\tif (authFailure != null) {\n\t\t\t\tthis.handleProviderException(\n\t\t\t\t\t'getOrganizationsForUser',\n\t\t\t\t\ttoCollectionFailureError(authFailure, toTokenWithInfo(this.id, session)),\n\t\t\t\t\t{ scope: scope, connectionId: connectionId },\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.resetRequestExceptionCount('getOrganizationsForUser');\n\t\t\t}\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getOrganizationsForUser', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderOrganizationsForUser?(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization> | undefined>;\n\n\t/**\n\t * Result-returning list of the projects a git host exposes beneath its orgs, unified into the\n\t * {@link ProviderOrganization} shape. Only Azure DevOps has a project tier between org and repo; other\n\t * git hosts have none and leave {@link getProviderProjectsForOrg} undefined, so this returns `undefined`\n\t * for them (the ProviderBackend facade then treats them as having no projects). With `org`, scopes to\n\t * that org's projects; without, returns projects across every org the user can see.\n\t */\n\t@trace()\n\tasync getProjectsForOrgResult(\n\t\torg?: string,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderHierarchyResult<ProviderOrganization> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tif (this.getProviderProjectsForOrg == null) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderProjectsForOrg(session, org);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getProjectsForOrg');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getProjectsForOrg', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderProjectsForOrg?(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg?: string,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization> | undefined>;\n\n\t/**\n\t * Lists repositories under the given organization (org/workspace/group) one page at a time — follow\n\t * `paging.cursor` to page, or drain with the integrations provider paging helper.\n\t * `options.project` is only meaningful for Azure DevOps, whose repos are scoped by `org` + `project`;\n\t * every other host ignores it. (Azure without a project can't page its cross-project merge, so it\n\t * returns all matches in a single page.) `truncated === true` means the defensive page-drain\n\t * backstop stopped before the upstream listing was exhausted.\n\t *\n\t * Resolves the session for `connectionId` (or the primary connection when omitted) and recovers a thrown\n\t * error into `{ error }`, so a caller surfaces it as a warning instead of a silent `undefined`.\n\t */\n\t@trace()\n\tasync getRepositoriesForOrgResult(\n\t\torg: string,\n\t\toptions?: { project?: string; cursor?: string; connectionId?: string },\n\t): Promise<IntegrationResult<ProviderHierarchyResult<ProviderRepository> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(options?.connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderRepositoriesForOrg?.(session, org, options);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getRepositoriesForOrg');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getRepositoriesForOrg', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: options?.connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderRepositoriesForOrg?(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg: string,\n\t\toptions?: { project?: string; cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined>;\n\n\t/**\n\t * Result-returning account-wide, user-affiliated repository read (the org-less\n\t * `gk provider repos <provider>` equivalent): repositories the user owns, collaborates on, or can\n\t * access through org membership — NOT every repo of every org. Optional: providers without a native\n\t * user-affiliated listing (Bitbucket workspaces, Azure orgs, which require an org/workspace scope)\n\t * leave the hook undefined and the facade reports the read as unsupported so callers fan out per org.\n\t */\n\t@trace()\n\tasync getRepositoriesForUserResult(options?: {\n\t\tcursor?: string;\n\t\tconnectionId?: string;\n\t}): Promise<IntegrationResult<ProviderHierarchyResult<ProviderRepository> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(options?.connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tif (this.getProviderRepositoriesForUser == null) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderRepositoriesForUser(session, options);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getRepositoriesForUser');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getRepositoriesForUser', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: options?.connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\tprotected getProviderRepositoriesForUser?(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined>;\n\n\tasync mergePullRequest(\n\t\tpr: PullRequest,\n\t\toptions?: { mergeMethod?: PullRequestMergeMethod },\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tconst scope = getScopedLogger();\n\n\t\tif ((await this.prepareSessionLookup()) != null) return false;\n\n\t\ttry {\n\t\t\tconst result = await this.mergeProviderPullRequest(this._session!, pr, options, cancellation);\n\t\t\tthis.resetRequestExceptionCount('mergePullRequest');\n\t\t\treturn result;\n\t\t} catch (ex) {\n\t\t\tif (isCancellationError(ex)) return false;\n\n\t\t\tthis.handleProviderException('mergePullRequest', ex, { scope: scope });\n\t\t\treturn false;\n\t\t} finally {\n\t\t\t// A merge attempt just changed the state of more than this pull request on the server (a\n\t\t\t// stacked merge lands every layer below and retargets every layer above) whether it succeeded\n\t\t\t// or failed partway through — so cached pull requests can't be trusted either way. Without\n\t\t\t// this, ref pills and branch enrichment keep serving the pre-merge object until its expiry.\n\t\t\tthis.ctx.cache.deletePullRequests();\n\t\t}\n\t}\n\n\tprotected abstract mergeProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tpr: PullRequest,\n\t\toptions?: { mergeMethod?: PullRequestMergeMethod },\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean>;\n\n\t@trace()\n\tasync getPullRequestForBranch(\n\t\trepo: T,\n\t\tbranch: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t\texpiryOverride?: boolean | number;\n\t\t\tinclude?: PullRequestState[];\n\t\t\t/** Rethrow a failed lookup instead of folding it into `undefined`, for callers that must tell\n\t\t\t * \"no pull request\" apart from \"couldn't ask\". */\n\t\t\tthrowOnError?: boolean;\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst refreshFailure = await this.prepareSessionLookup();\n\t\tif (refreshFailure === 'unconnected') return undefined;\n\n\t\tconst { expiryOverride, throwOnError, ...opts } = options ?? {};\n\t\tif (refreshFailure != null) {\n\t\t\tif (throwOnError) throw refreshFailure;\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst pr = this.ctx.cache.getPullRequestForBranch(\n\t\t\tbranch,\n\t\t\trepo,\n\t\t\tthis,\n\t\t\tcacheable => ({\n\t\t\t\tvalue: (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.getProviderPullRequestForBranch(this._session!, repo, branch, opts);\n\t\t\t\t\t\tthis.resetRequestExceptionCount('getPullRequestForBranch');\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t// A failed lookup is not an answer: left cached, the `undefined` below reads as \"no pull\n\t\t\t\t\t\t// request\" for the bucket's whole expiry (an hour by branch).\n\t\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t\t\tthis.handleProviderException('getPullRequestForBranch', ex, { scope: scope });\n\t\t\t\t\t\tif (throwOnError) throw ex;\n\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\t{ expiryOverride: expiryOverride },\n\t\t);\n\t\treturn pr;\n\t}\n\n\tprotected abstract getProviderPullRequestForBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\tbranch: string,\n\t\toptions?: { avatarSize?: number; include?: PullRequestState[] },\n\t): Promise<PullRequest | undefined>;\n\n\t@trace()\n\tasync getPullRequestForCommit(\n\t\trepo: T,\n\t\trev: string,\n\t\toptions?: { expiryOverride?: boolean | number; throwOnError?: boolean },\n\t): Promise<PullRequest | undefined> {\n\t\tconst scope = getScopedLogger();\n\n\t\tconst refreshFailure = await this.prepareSessionLookup();\n\t\tif (refreshFailure === 'unconnected') return undefined;\n\n\t\tconst { throwOnError, ...cacheOptions } = options ?? {};\n\t\tif (refreshFailure != null) {\n\t\t\tif (throwOnError) throw refreshFailure;\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst pr = this.ctx.cache.getPullRequestForSha(\n\t\t\trev,\n\t\t\trepo,\n\t\t\tthis,\n\t\t\tcacheable => ({\n\t\t\t\tvalue: (async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await this.getProviderPullRequestForCommit(this._session!, repo, rev);\n\t\t\t\t\t\tthis.resetRequestExceptionCount('getPullRequestForCommit');\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\t// A failed lookup is not an answer — and the by-sha bucket never expires a miss.\n\t\t\t\t\t\tcacheable.invalidate();\n\t\t\t\t\t\tthis.handleProviderException('getPullRequestForCommit', ex, { scope: scope });\n\t\t\t\t\t\tif (throwOnError) throw ex;\n\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t})(),\n\t\t\t}),\n\t\t\tcacheOptions,\n\t\t);\n\t\treturn pr;\n\t}\n\n\tprotected abstract getProviderPullRequestForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: T,\n\t\trev: string,\n\t): Promise<PullRequest | undefined>;\n\n\t/**\n\t * Memoized identity lookups backing filter resolution. Keyed by the session's token fingerprint plus the\n\t * scope of the lookup (base URL, and the Azure organization for the per-instance variant), so a different\n\t * account, host, or org never reuses an entry and a rotated token simply misses.\n\t *\n\t * Not cleared when the token changes: one integration instance serves every connection of its provider\n\t * (multi-account), so clearing on a fingerprint change would make two accounts reading in alternation\n\t * evict each other and defeat the memo. Entries are bounded by tokens x hosts x orgs seen — a handful for\n\t * the life of the integration.\n\t */\n\tprivate readonly _filterAccounts = new Map<string, Promise<ProviderAccount | undefined>>();\n\n\t/**\n\t * Resolves the account a repo-scoped read turns `IssueFilter`/`PullRequestFilter` into a provider\n\t * login/id with, memoized per token+scope.\n\t *\n\t * Every FILTERED read needs this, and `ProvidersApi.getCurrentUser` is a bare round trip — unlike\n\t * {@link IntegrationBase.getCurrentAccount}, which the host caches. So a consumer that fans ONE page out\n\t * into several filtered reads paid one identity request PER read, all resolving the same account: a\n\t * per-user-facet fan-out (author + assignee + review-requested) doubled its request count, and paid it\n\t * again on every page turn.\n\t *\n\t * The promise is memoized rather than the value, so concurrent facets share one in-flight request instead\n\t * of racing. A rejection is evicted so the next read retries rather than caching a failure — matching how\n\t * `getCurrentAccount` invalidates on error.\n\t */\n\tprivate getFilterAccount(\n\t\tapi: ProvidersApi,\n\t\tsession: ProviderAuthenticationSession,\n\t\tcustomUrl: string | undefined,\n\t\torganization?: string,\n\t): Promise<ProviderAccount | undefined> {\n\t\tconst key = `${this.getSessionFingerprint(session)}:${customUrl ?? ''}:${organization ?? ''}`;\n\n\t\tlet pending = this._filterAccounts.get(key);\n\t\tif (pending == null) {\n\t\t\tconst tokenWithInfo = toTokenWithInfo(this.authProvider.id, session);\n\t\t\tpending = (\n\t\t\t\torganization != null\n\t\t\t\t\t? api.getCurrentUserForInstance(tokenWithInfo, organization, {\n\t\t\t\t\t\t\tbaseUrl: customUrl,\n\t\t\t\t\t\t\tisPAT: sendsBasicCredential(this.id, session),\n\t\t\t\t\t\t})\n\t\t\t\t\t: api.getCurrentUser(tokenWithInfo, { baseUrl: customUrl })\n\t\t\t).catch((ex: unknown) => {\n\t\t\t\tthis._filterAccounts.delete(key);\n\t\t\t\tthrow ex;\n\t\t\t});\n\t\t\tthis._filterAccounts.set(key, pending);\n\t\t}\n\n\t\treturn pending;\n\t}\n\n\tasync getMyIssuesForRepos(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyIssuesForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<PagedResult<ProviderIssue> | undefined> {\n\t\treturn (await this.getMyIssuesForReposResult(reposOrRepoIds, options, connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getMyIssuesForRepos}. Resolves the session for `connectionId`\n\t * (or the primary connection when omitted, so multi-account reads use the right token) and recovers\n\t * thrown errors and validation failures into `{ error }` so callers can surface them as warnings\n\t * rather than swallowing them to `undefined`.\n\t */\n\tasync getMyIssuesForReposResult(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyIssuesForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<(PagedResult<ProviderIssue> & { metadata?: CollectionMetadata }) | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst providerId = this.authProvider.id;\n\t\tconst states = toProviderIssueStates(options?.state);\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary. The session\n\t\t// is resolved here for connectivity/bail; the connection's token is applied per API call below.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet customUrl: string | undefined;\n\t\tlet api: ProvidersApi;\n\t\ttry {\n\t\t\tcustomUrl =\n\t\t\t\toptions?.customUrl ??\n\t\t\t\t(isGitSelfManagedHostIntegrationId(providerId)\n\t\t\t\t\t? this.getRepositoriesApiBaseUrl(session, reposOrRepoIds)\n\t\t\t\t\t: undefined);\n\t\t\tapi = await this.getProvidersApi();\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssuesForRepos', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t\tconst repoIdsInput = api.isRepoIdsInput(reposOrRepoIds);\n\t\tif (\n\t\t\tproviderId !== GitCloudHostIntegrationId.GitLab &&\n\t\t\t(repoIdsInput ||\n\t\t\t\t(isAzureProviderId(providerId) &&\n\t\t\t\t\t!reposOrRepoIds.every(repo => repo.project != null && repo.namespace != null)))\n\t\t) {\n\t\t\treturn unsupportedRead(`Unsupported input for provider ${providerId}`, start, 'getIssuesForRepos');\n\t\t}\n\n\t\tlet getIssuesOptions: GetIssuesOptions | undefined;\n\t\tif (isAzureProviderId(providerId)) {\n\t\t\tconst organizations = new Set<string>();\n\t\t\tconst projects = new Set<string>();\n\t\t\tfor (const repo of reposOrRepoIds as ProviderRepoInput[]) {\n\t\t\t\torganizations.add(repo.namespace);\n\t\t\t\tprojects.add(repo.project!);\n\t\t\t}\n\n\t\t\tif (organizations.size > 1) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Multiple organizations not supported for provider ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getIssuesForRepos',\n\t\t\t\t);\n\t\t\t} else if (organizations.size === 0) {\n\t\t\t\treturn unsupportedRead(`No organizations found for provider ${providerId}`, start, 'getIssuesForRepos');\n\t\t\t}\n\n\t\t\tconst organization: string = first(organizations.values())!;\n\n\t\t\tif (options?.filters != null) {\n\t\t\t\tif (!api.providerSupportsIssueFilters(providerId, options.filters)) {\n\t\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t\t`Unsupported filters for provider ${providerId}`,\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\t'getIssuesForRepos',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tlet userAccount: ProviderAccount | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tuserAccount = await this.getFilterAccount(api, session, customUrl, organization);\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\t\tscope: scope,\n\t\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t\t});\n\t\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t\t}\n\n\t\t\t\tif (userAccount == null) {\n\t\t\t\t\treturn unsupportedRead(`Unable to get current user for ${providerId}`, start, 'getIssuesForRepos');\n\t\t\t\t}\n\n\t\t\t\tconst userFilterProperty = userAccount.name;\n\n\t\t\t\tif (userFilterProperty == null) {\n\t\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t\t`Unable to get user property for filter for ${providerId}`,\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\t'getIssuesForRepos',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tgetIssuesOptions = {\n\t\t\t\t\tauthorLogin: options.filters.includes(IssueFilter.Author) ? userFilterProperty : undefined,\n\t\t\t\t\tassigneeLogins:\n\t\t\t\t\t\t!options.includeAllAssignees && options.filters.includes(IssueFilter.Assignee)\n\t\t\t\t\t\t\t? [userFilterProperty]\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\tmentionLogin: options.filters.includes(IssueFilter.Mention) ? userFilterProperty : undefined,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst cursorInfo = this.parseCursorInfo<PagedProjectInput>(options?.cursor);\n\t\t\tconst cursors: PagedProjectInput[] = cursorInfo.cursors ?? [];\n\t\t\tlet projectInputs: PagedProjectInput[] = Array.from(projects.values(), project => ({\n\t\t\t\tnamespace: organization,\n\t\t\t\tproject: project,\n\t\t\t\tcursor: undefined,\n\t\t\t}));\n\t\t\tif (cursors.length > 0) {\n\t\t\t\tprojectInputs = cursors;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cursor: { cursors: PagedProjectInput[]; page?: number } = { cursors: [] };\n\t\t\t\tlet hasMore = false;\n\t\t\t\tlet truncated = false;\n\t\t\t\tlet metadata: CollectionMetadata | undefined;\n\t\t\t\tconst data: ProviderIssue[] = [];\n\t\t\t\t// `allSettled`, not `Promise.all`: one project's read rejecting must not discard every sibling\n\t\t\t\t// project's already-fetched issues and cursors. A rejected project is recorded as a structured\n\t\t\t\t// failure so the facade can warn and set `fetchFailed` instead of reporting a partial project set\n\t\t\t\t// as complete.\n\t\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\t\tprojectInputs.map(async projectInput => {\n\t\t\t\t\t\tconst results = await api.getIssuesForAzureProject(\n\t\t\t\t\t\t\ttoTokenWithInfo(providerId, session),\n\t\t\t\t\t\t\tprojectInput.namespace,\n\t\t\t\t\t\t\tprojectInput.project,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t...getIssuesOptions,\n\t\t\t\t\t\t\t\tcursor: projectInput.cursor,\n\t\t\t\t\t\t\t\tbaseUrl: customUrl,\n\t\t\t\t\t\t\t\tisPAT: sendsBasicCredential(providerId, session),\n\t\t\t\t\t\t\t\t// Continuation is driven by the per-project cursor; only apply an explicit page on the\n\t\t\t\t\t\t\t\t// first request so it can't clobber a continuation cursor on later pages.\n\t\t\t\t\t\t\t\tpage: projectInput.cursor == null ? options?.page : undefined,\n\t\t\t\t\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\t\t\t\t\tstates: states,\n\t\t\t\t\t\t\t\tsort: options?.sort,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { projectInput: projectInput, results: results };\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthrowIfAllSettledFailed(settled);\n\n\t\t\t\tfor (let i = 0; i < settled.length; i++) {\n\t\t\t\t\tconst outcome = settled[i];\n\t\t\t\t\tconst projectInput = projectInputs[i];\n\t\t\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\t\t\t// Errors that really are per-scope (auth, rate limit, a missing project) degrade below; one\n\t\t\t\t\t\t// that is a fact about the call is re-thrown instead — see `throwIfCallerContractError`.\n\t\t\t\t\t\tthrowIfCallerContractError(outcome.reason);\n\n\t\t\t\t\t\ttruncated = true;\n\t\t\t\t\t\tconst failure = toCollectionScopeFailure(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproviderId: providerId,\n\t\t\t\t\t\t\t\tresourceId: projectInput.namespace,\n\t\t\t\t\t\t\t\tprojectId: projectInput.project,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutcome.reason,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tmetadata = mergeCollectionMetadata(metadata, {\n\t\t\t\t\t\t\tcompleteness: 'partial',\n\t\t\t\t\t\t\tfailures: [failure],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { projectInput: _projectInput, results } = outcome.value;\n\t\t\t\t\tdata.push(...results.values);\n\t\t\t\t\tif (results.paging?.more) {\n\t\t\t\t\t\thasMore = true;\n\t\t\t\t\t\tcursor.cursors.push({\n\t\t\t\t\t\t\tnamespace: projectInput.namespace,\n\t\t\t\t\t\t\tproject: projectInput.project,\n\t\t\t\t\t\t\tcursor: results.paging.cursor,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Keep the requested page number in the composite cursor so the facade can report the real\n\t\t\t\t// currentPage when the consumer continues using only the cursor.\n\t\t\t\tif (options?.page != null) {\n\t\t\t\t\tcursor.page = options.page;\n\t\t\t\t}\n\n\t\t\t\tawait this.confirmScopedAuthFailures(session, metadata);\n\t\t\t\tthis.resetRequestExceptionCount('getIssuesForRepos');\n\t\t\t\treturn {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tvalues: data,\n\t\t\t\t\t\tpaging: {\n\t\t\t\t\t\t\tmore: hasMore,\n\t\t\t\t\t\t\tcursor: JSON.stringify(cursor),\n\t\t\t\t\t\t\ttruncated: truncated || undefined,\n\t\t\t\t\t\t\t// Echo the requested numbered page so the facade reports the real currentPage for\n\t\t\t\t\t\t\t// numbered-page hosts (GitLab/Bitbucket/Azure), not a synthesized 1. Cursor-only hosts\n\t\t\t\t\t\t\t// leave `page` undefined via their own reads.\n\t\t\t\t\t\t\tpage: options?.page,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmetadata: metadata,\n\t\t\t\t\t},\n\t\t\t\t\tduration: performance.now() - start,\n\t\t\t\t};\n\t\t\t} catch (ex) {\n\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t}\n\t\t}\n\t\tif (options?.filters != null) {\n\t\t\t// Validate the requested filters against what this provider actually supports — same guard the Azure\n\t\t\t// branch above applies. Without it an unsupported filter (e.g. GitLab has no Mention endpoint) would\n\t\t\t// resolve to no filter property being set and silently degrade to an unfiltered, project-wide read.\n\t\t\tif (!api.providerSupportsIssueFilters(providerId, options.filters)) {\n\t\t\t\treturn unsupportedRead(`Unsupported filters for provider ${providerId}`, start, 'getIssuesForRepos');\n\t\t\t}\n\n\t\t\tlet userAccount: ProviderAccount | undefined;\n\t\t\ttry {\n\t\t\t\tuserAccount = await this.getFilterAccount(api, session, customUrl);\n\t\t\t} catch (ex) {\n\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tif (userAccount == null) {\n\t\t\t\treturn unsupportedRead(`Unable to get current user for ${providerId}`, start, 'getIssuesForRepos');\n\t\t\t}\n\n\t\t\tconst userFilterProperty = userAccount.username;\n\t\t\tif (userFilterProperty == null) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Unable to get user property for filter for ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getIssuesForRepos',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tgetIssuesOptions = {\n\t\t\t\tauthorLogin: options.filters.includes(IssueFilter.Author) ? userFilterProperty : undefined,\n\t\t\t\tassigneeLogins:\n\t\t\t\t\t!options.includeAllAssignees && options.filters.includes(IssueFilter.Assignee)\n\t\t\t\t\t\t? [userFilterProperty]\n\t\t\t\t\t\t: undefined,\n\t\t\t\tmentionLogin: options.filters.includes(IssueFilter.Mention) ? userFilterProperty : undefined,\n\t\t\t};\n\t\t}\n\n\t\tif (api.getProviderIssuesPagingMode(providerId) === PagingMode.Repo && !repoIdsInput) {\n\t\t\tconst cursorInfo = this.parseCursorInfo<PagedRepoInput>(options?.cursor);\n\t\t\tconst cursors: PagedRepoInput[] = cursorInfo.cursors ?? [];\n\t\t\tlet repoInputs: PagedRepoInput[] = reposOrRepoIds.map(repo => ({ repo: repo, cursor: undefined }));\n\t\t\tif (cursors.length > 0) {\n\t\t\t\trepoInputs = cursors;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cursor: { cursors: PagedRepoInput[]; page?: number } = { cursors: [] };\n\t\t\t\tlet hasMore = false;\n\t\t\t\tlet truncated = false;\n\t\t\t\tlet metadata: CollectionMetadata | undefined;\n\t\t\t\tconst data: ProviderIssue[] = [];\n\t\t\t\t// `allSettled`, not `Promise.all`: one repo's read rejecting must not discard every sibling repo's\n\t\t\t\t// already-fetched issues and cursors. A rejected repo is recorded as a structured failure so the\n\t\t\t\t// facade can warn and set `fetchFailed` instead of reporting a partial repo set as complete.\n\t\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\t\trepoInputs.map(async repoInput => {\n\t\t\t\t\t\tconst results = await api.getIssuesForRepo(\n\t\t\t\t\t\t\ttoTokenWithInfo(providerId, session),\n\t\t\t\t\t\t\trepoInput.repo,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t...getIssuesOptions,\n\t\t\t\t\t\t\t\tcursor: repoInput.cursor,\n\t\t\t\t\t\t\t\tbaseUrl: customUrl,\n\t\t\t\t\t\t\t\t// Continuation is driven by the per-repo cursor; only apply an explicit page on the\n\t\t\t\t\t\t\t\t// first request so it can't clobber a continuation cursor on later pages.\n\t\t\t\t\t\t\t\tpage: repoInput.cursor == null ? options?.page : undefined,\n\t\t\t\t\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\t\t\t\t\tstates: states,\n\t\t\t\t\t\t\t\tsort: options?.sort,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { repoInput: repoInput, results: results };\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthrowIfAllSettledFailed(settled);\n\n\t\t\t\tfor (let i = 0; i < settled.length; i++) {\n\t\t\t\t\tconst outcome = settled[i];\n\t\t\t\t\tconst repoInput = repoInputs[i];\n\t\t\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\t\t\t// See the project fan-out above. Reachable in practice even though the facade validates the\n\t\t\t\t\t\t// key first — a self-managed GitLab can reject an `IssueSort` member the SDK declares, which\n\t\t\t\t\t\t// is only discoverable from the response.\n\t\t\t\t\t\tthrowIfCallerContractError(outcome.reason);\n\n\t\t\t\t\t\ttruncated = true;\n\t\t\t\t\t\tconst failure = toCollectionScopeFailure(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproviderId: providerId,\n\t\t\t\t\t\t\t\trepositoryId: `${repoInput.repo.namespace}/${repoInput.repo.name}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutcome.reason,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tmetadata = mergeCollectionMetadata(metadata, {\n\t\t\t\t\t\t\tcompleteness: 'partial',\n\t\t\t\t\t\t\tfailures: [failure],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { repoInput: _repoInput, results } = outcome.value;\n\t\t\t\t\tdata.push(...results.values);\n\t\t\t\t\tif (results.paging?.more) {\n\t\t\t\t\t\thasMore = true;\n\t\t\t\t\t\tcursor.cursors.push({ repo: repoInput.repo, cursor: results.paging.cursor });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (options?.page != null) {\n\t\t\t\t\tcursor.page = options.page;\n\t\t\t\t}\n\n\t\t\t\tawait this.confirmScopedAuthFailures(session, metadata);\n\t\t\t\tthis.resetRequestExceptionCount('getIssuesForRepos');\n\t\t\t\treturn {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tvalues: data,\n\t\t\t\t\t\tpaging: {\n\t\t\t\t\t\t\tmore: hasMore,\n\t\t\t\t\t\t\tcursor: JSON.stringify(cursor),\n\t\t\t\t\t\t\ttruncated: truncated || undefined,\n\t\t\t\t\t\t\t// Echo the requested numbered page so the facade reports the real currentPage for\n\t\t\t\t\t\t\t// numbered-page hosts (GitLab/Bitbucket/Azure), not a synthesized 1. Cursor-only hosts\n\t\t\t\t\t\t\t// leave `page` undefined via their own reads.\n\t\t\t\t\t\t\tpage: options?.page,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmetadata: metadata,\n\t\t\t\t\t},\n\t\t\t\t\tduration: performance.now() - start,\n\t\t\t\t};\n\t\t\t} catch (ex) {\n\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst tokenWithInfo = toTokenWithInfo(providerId, session);\n\t\t\tconst result = await api.getIssuesForRepos(tokenWithInfo, reposOrRepoIds, {\n\t\t\t\t...getIssuesOptions,\n\t\t\t\tcursor: options?.cursor,\n\t\t\t\tbaseUrl: customUrl,\n\t\t\t\tisPAT: sendsBasicCredential(providerId, session),\n\t\t\t\tpage: options?.page,\n\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\tstates: states,\n\t\t\t\tsort: options?.sort,\n\t\t\t});\n\t\t\tconst failures = result.metadata?.failures;\n\t\t\tif (\n\t\t\t\trepoIdsInput &&\n\t\t\t\treposOrRepoIds.length > 0 &&\n\t\t\t\tresult.values.length === 0 &&\n\t\t\t\tfailures?.length === reposOrRepoIds.length\n\t\t\t) {\n\t\t\t\tconst ex = toCollectionFailureError(failures[0], tokenWithInfo);\n\t\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: ex, duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tawait this.confirmScopedAuthFailures(session, result.metadata);\n\t\t\tthis.resetRequestExceptionCount('getIssuesForRepos');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getIssuesForRepos', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * Repo-scoped \"my issues\" read returning the normalized {@link IssueShape} the ProviderBackend facade\n\t * consumes (`listIssuesPage({ repos })`, `broadenIssues`). Maps {@link getMyIssuesForReposResult} — the raw\n\t * provider-apis path — to IssueShape.\n\t *\n\t * It's the seam rather than an inline map so a provider whose only issue client already yields normalized\n\t * shapes, and isn't wired into the raw path, can override it and serve these reads without a\n\t * `ProviderIssue` round-trip. No provider does today: the one candidate (Bitbucket Cloud's legacy\n\t * `getUsersIssuesForRepo`) reports `supportsIssues: false`, so the facade never reaches this for it.\n\t */\n\tasync getMyIssuesForReposAsShapesResult(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyIssuesForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<(PagedResult<IssueShape> & { metadata?: CollectionMetadata }) | undefined>> {\n\t\tconst result = await this.getMyIssuesForReposResult(reposOrRepoIds, options, connectionId);\n\t\tif (result == null) return undefined;\n\t\tif (result.error != null) return { error: result.error, duration: result.duration };\n\t\tif (result.value == null) return { value: undefined, duration: result.duration };\n\n\t\tconst values = result.value.values\n\t\t\t.map(issue => toIssueShape(issue, this, { projection: 'repos' }))\n\t\t\t.filter((issue): issue is IssueShape => issue != null);\n\t\treturn { value: { ...result.value, values: values }, duration: result.duration };\n\t}\n\n\tasync getMyPullRequestsForRepos(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyPullRequestsForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<ProviderApiPagedResult<ProviderPullRequest> | undefined> {\n\t\treturn (await this.getMyPullRequestsForReposResult(reposOrRepoIds, options, connectionId))?.value;\n\t}\n\n\t/**\n\t * Result-returning core of {@link getMyPullRequestsForRepos}. Resolves the session for `connectionId`\n\t * (or the primary connection when omitted, so multi-account reads use the right token) and recovers\n\t * thrown errors and validation failures into `{ error }` so callers can surface them as warnings\n\t * rather than swallowing them to `undefined`.\n\t */\n\tasync getMyPullRequestsForReposResult(\n\t\treposOrRepoIds: ProviderReposInput,\n\t\toptions?: MyPullRequestsForReposOptions,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderApiPagedResult<ProviderPullRequest> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst providerId = this.authProvider.id;\n\t\tconst states = toProviderPullRequestStates(options?.state);\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary. The session\n\t\t// is resolved here for connectivity/bail; the connection's token is applied per API call below.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet customUrl: string | undefined;\n\t\tlet api: ProvidersApi;\n\t\ttry {\n\t\t\tcustomUrl =\n\t\t\t\toptions?.customUrl ??\n\t\t\t\t(isGitSelfManagedHostIntegrationId(providerId)\n\t\t\t\t\t? this.getRepositoriesApiBaseUrl(session, reposOrRepoIds)\n\t\t\t\t\t: undefined);\n\t\t\tapi = await this.getProvidersApi();\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t\tif (\n\t\t\tproviderId !== GitCloudHostIntegrationId.GitLab &&\n\t\t\t(api.isRepoIdsInput(reposOrRepoIds) ||\n\t\t\t\t(isAzureProviderId(providerId) &&\n\t\t\t\t\t!reposOrRepoIds.every(repo => repo.project != null && repo.namespace != null)))\n\t\t) {\n\t\t\treturn unsupportedRead(`Unsupported input for provider ${providerId}`, start);\n\t\t}\n\n\t\tlet getPullRequestsOptions: GetPullRequestsOptions | undefined;\n\t\tif (options?.filters != null) {\n\t\t\tif (!api.providerSupportsPullRequestFilters(providerId, options.filters)) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Unsupported filters for provider ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet userAccount: ProviderAccount | undefined;\n\t\t\tif (isAzureProviderId(providerId)) {\n\t\t\t\tconst organizations = new Set<string>();\n\t\t\t\tfor (const repo of reposOrRepoIds as ProviderRepoInput[]) {\n\t\t\t\t\torganizations.add(repo.namespace);\n\t\t\t\t}\n\n\t\t\t\tif (organizations.size > 1) {\n\t\t\t\t\tLogger.warn(\n\t\t\t\t\t\t`Multiple organizations not supported for provider ${providerId}`,\n\t\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t\t);\n\t\t\t\t\treturn {\n\t\t\t\t\t\terror: new Error(`Multiple organizations not supported for provider ${providerId}`),\n\t\t\t\t\t\tduration: performance.now() - start,\n\t\t\t\t\t};\n\t\t\t\t} else if (organizations.size === 0) {\n\t\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t\t`No organizations found for provider ${providerId}`,\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst organization: string = first(organizations.values())!;\n\t\t\t\ttry {\n\t\t\t\t\tuserAccount = await this.getFilterAccount(api, session, customUrl, organization);\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\t\t\tscope: scope,\n\t\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t\t});\n\t\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tuserAccount = await this.getFilterAccount(api, session, customUrl);\n\t\t\t\t} catch (ex) {\n\t\t\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\t\t\tscope: scope,\n\t\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t\t});\n\t\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (userAccount == null) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Unable to get current user for ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet userFilterProperty: string | null;\n\t\t\tswitch (providerId) {\n\t\t\t\tcase GitCloudHostIntegrationId.Bitbucket:\n\t\t\t\tcase GitCloudHostIntegrationId.AzureDevOps:\n\t\t\t\tcase GitSelfManagedHostIntegrationId.AzureDevOpsServer:\n\t\t\t\t\tuserFilterProperty = userAccount.id;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tuserFilterProperty = userAccount.username;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (userFilterProperty == null) {\n\t\t\t\treturn unsupportedRead(\n\t\t\t\t\t`Unable to get user property for filter for ${providerId}`,\n\t\t\t\t\tstart,\n\t\t\t\t\t'getPullRequestsForRepos',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Route the \"review requested from me\" filter to the field each provider actually reads:\n\t\t\t// GitHub/GitLab expect a login (reviewRequestedLogin), Bitbucket/Azure an account id (reviewerId),\n\t\t\t// and Bitbucket Server a login (reviewerLogin). `userFilterProperty` is already the account id for\n\t\t\t// Bitbucket/Azure and the username for the rest.\n\t\t\tlet reviewRequestedLogin: string | undefined;\n\t\t\tlet reviewerId: string | undefined;\n\t\t\tlet reviewerLogin: string | undefined;\n\t\t\tif (options.filters.includes(PullRequestFilter.ReviewRequested)) {\n\t\t\t\tswitch (providerId) {\n\t\t\t\t\tcase GitCloudHostIntegrationId.Bitbucket:\n\t\t\t\t\tcase GitCloudHostIntegrationId.AzureDevOps:\n\t\t\t\t\tcase GitSelfManagedHostIntegrationId.AzureDevOpsServer:\n\t\t\t\t\t\treviewerId = userFilterProperty;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase GitSelfManagedHostIntegrationId.BitbucketServer:\n\t\t\t\t\t\treviewerLogin = userFilterProperty;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treviewRequestedLogin = userFilterProperty;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tgetPullRequestsOptions = {\n\t\t\t\tauthorLogin: options.filters.includes(PullRequestFilter.Author) ? userFilterProperty : undefined,\n\t\t\t\tassigneeLogins: options.filters.includes(PullRequestFilter.Assignee) ? [userFilterProperty] : undefined,\n\t\t\t\treviewRequestedLogin: reviewRequestedLogin,\n\t\t\t\treviewerId: reviewerId,\n\t\t\t\treviewerLogin: reviewerLogin,\n\t\t\t\tmentionLogin: options.filters.includes(PullRequestFilter.Mention) ? userFilterProperty : undefined,\n\t\t\t};\n\t\t}\n\n\t\tif (\n\t\t\tapi.getProviderPullRequestsPagingMode(providerId) === PagingMode.Repo &&\n\t\t\t!api.isRepoIdsInput(reposOrRepoIds)\n\t\t) {\n\t\t\tconst cursorInfo = this.parseCursorInfo<PagedRepoInput>(options?.cursor);\n\t\t\tconst cursors: PagedRepoInput[] = cursorInfo.cursors ?? [];\n\t\t\tlet repoInputs: PagedRepoInput[] = reposOrRepoIds.map(repo => ({ repo: repo, cursor: undefined }));\n\t\t\tif (cursors.length > 0) {\n\t\t\t\trepoInputs = cursors;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cursor: { cursors: PagedRepoInput[]; page?: number } = { cursors: [] };\n\t\t\t\tlet hasMore = false;\n\t\t\t\tlet truncated = false;\n\t\t\t\tlet metadata: CollectionMetadata | undefined;\n\t\t\t\tconst failures: CollectionScopeFailure[] = [];\n\t\t\t\tconst data: ProviderPullRequest[] = [];\n\t\t\t\t// `allSettled`, not `Promise.all`: one repo's read rejecting must not discard every sibling repo's\n\t\t\t\t// already-fetched PRs and cursors. A rejected repo becomes a structured `CollectionScopeFailure`\n\t\t\t\t// (attributed to that repo) so the facade warns on it + sets `fetchFailed`, while the survivors and\n\t\t\t\t// their continuation cursors are still returned.\n\t\t\t\tconst settled = await Promise.allSettled(\n\t\t\t\t\trepoInputs.map(async repoInput => {\n\t\t\t\t\t\tconst results = await api.getPullRequestsForRepo(\n\t\t\t\t\t\t\ttoTokenWithInfo(providerId, session),\n\t\t\t\t\t\t\trepoInput.repo,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t...getPullRequestsOptions,\n\t\t\t\t\t\t\t\tcursor: repoInput.cursor,\n\t\t\t\t\t\t\t\tisPAT: sendsBasicCredential(providerId, session),\n\t\t\t\t\t\t\t\t// Per repository: an unfiltered read may span organizations, and a host can narrow the base\n\t\t\t\t\t\t\t\t// to each repository's own.\n\t\t\t\t\t\t\t\tbaseUrl:\n\t\t\t\t\t\t\t\t\toptions?.customUrl == null && isGitSelfManagedHostIntegrationId(providerId)\n\t\t\t\t\t\t\t\t\t\t? this.getRepositoriesApiBaseUrl(session, [repoInput.repo])\n\t\t\t\t\t\t\t\t\t\t: customUrl,\n\t\t\t\t\t\t\t\t// Continuation is driven by the per-repo cursor; only apply an explicit page on the\n\t\t\t\t\t\t\t\t// first request so it can't clobber a continuation cursor on later pages.\n\t\t\t\t\t\t\t\tpage: repoInput.cursor == null ? options?.page : undefined,\n\t\t\t\t\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\t\t\t\t\tstates: states,\n\t\t\t\t\t\t\t\t// Azure DevOps only populates clone URLs on request (extra call); no-op elsewhere.\n\t\t\t\t\t\t\t\tincludeRemoteInfo: isAzureProviderId(providerId) ? true : undefined,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { repoInput: repoInput, results: results };\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthrowIfAllSettledFailed(settled);\n\n\t\t\t\t// `allSettled` preserves order, so `settled[i]` is `repoInputs[i]`.\n\t\t\t\tsettled.forEach((outcome, i) => {\n\t\t\t\t\tif (outcome.status !== 'fulfilled') {\n\t\t\t\t\t\tconst failedRepo = repoInputs[i].repo;\n\t\t\t\t\t\tfailures.push(\n\t\t\t\t\t\t\ttoCollectionScopeFailure(\n\t\t\t\t\t\t\t\t{ providerId: providerId, repositoryId: `${failedRepo.namespace}/${failedRepo.name}` },\n\t\t\t\t\t\t\t\toutcome.reason,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { repoInput, results } = outcome.value;\n\t\t\t\t\tdata.push(...results.values);\n\t\t\t\t\t// Fan-out across repos: preserve each repo's SDK completeness/failures and its terminal\n\t\t\t\t\t// truncation so a single failed/incomplete repo isn't lost when merged with its siblings.\n\t\t\t\t\tmetadata = mergeCollectionMetadata(metadata, results.metadata);\n\t\t\t\t\tif (results.paging?.truncated) {\n\t\t\t\t\t\ttruncated = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (results.paging?.more) {\n\t\t\t\t\t\thasMore = true;\n\t\t\t\t\t\tcursor.cursors.push({ repo: repoInput.repo, cursor: results.paging.cursor });\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Merge the GitLens-side per-repo rejections into the SDK metadata so both flow through the same\n\t\t\t\t// warning/fetchFailed assessment downstream.\n\t\t\t\tif (failures.length > 0) {\n\t\t\t\t\tmetadata = mergeCollectionMetadata(metadata, { completeness: 'partial', failures: failures });\n\t\t\t\t}\n\n\t\t\t\t// Keep the requested page number in the composite cursor so the facade can report the real\n\t\t\t\t// currentPage when the consumer continues using only the cursor.\n\t\t\t\tif (options?.page != null) {\n\t\t\t\t\tcursor.page = options.page;\n\t\t\t\t}\n\n\t\t\t\tawait this.confirmScopedAuthFailures(session, metadata);\n\t\t\t\tthis.resetRequestExceptionCount('getPullRequestsForRepos');\n\t\t\t\treturn {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tvalues: data,\n\t\t\t\t\t\tpaging: {\n\t\t\t\t\t\t\tmore: hasMore,\n\t\t\t\t\t\t\tcursor: JSON.stringify(cursor),\n\t\t\t\t\t\t\ttruncated: truncated || undefined,\n\t\t\t\t\t\t\t// Echo the requested numbered page so the facade reports the real currentPage for\n\t\t\t\t\t\t\t// numbered-page hosts (GitLab/Bitbucket/Azure), not a synthesized 1. Cursor-only hosts\n\t\t\t\t\t\t\t// leave `page` undefined via their own reads.\n\t\t\t\t\t\t\tpage: options?.page,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmetadata: metadata,\n\t\t\t\t\t},\n\t\t\t\t\tduration: performance.now() - start,\n\t\t\t\t};\n\t\t\t} catch (ex) {\n\t\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\t\tscope: scope,\n\t\t\t\t\tconnectionId: connectionId,\n\t\t\t\t});\n\t\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await api.getPullRequestsForRepos(toTokenWithInfo(providerId, session), reposOrRepoIds, {\n\t\t\t\t...getPullRequestsOptions,\n\t\t\t\tcursor: options?.cursor,\n\t\t\t\tisPAT: sendsBasicCredential(providerId, session),\n\t\t\t\tbaseUrl: customUrl,\n\t\t\t\tpage: options?.page,\n\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\tstates: states,\n\t\t\t\t// Azure DevOps only populates clone URLs on request (extra call); no-op elsewhere.\n\t\t\t\tincludeRemoteInfo: isAzureProviderId(providerId) ? true : undefined,\n\t\t\t\tfields: options?.summary ? summaryPullRequestFields : undefined,\n\t\t\t});\n\t\t\tawait this.confirmScopedAuthFailures(session, result.metadata);\n\t\t\tthis.resetRequestExceptionCount('getPullRequestsForRepos');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getPullRequestsForRepos', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/** Account-wide (or repo-scoped) search for the current user's pull requests. */\n\t@trace()\n\tasync searchMyPullRequests(\n\t\trepos?: T | T[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions & { connectionId?: string },\n\t): Promise<IntegrationResult<PullRequest[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst { connectionId, ...searchOptions } = options ?? {};\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst prs = await this.searchProviderMyPullRequests(\n\t\t\t\tsession,\n\t\t\t\tensureArray(repos),\n\t\t\t\tcancellation,\n\t\t\t\tsearchOptions,\n\t\t\t);\n\t\t\tthis.resetRequestExceptionCount('searchMyPullRequests');\n\t\t\treturn { value: prs, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('searchMyPullRequests', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tsilent: true,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn {\n\t\t\t\terror: toError(ex),\n\t\t\t\tduration: performance.now() - start,\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Account-wide, user-scoped counterpart of {@link getMyPullRequestsForReposResult} that returns each host's raw\n\t * rows: provider-apis' `ProviderPullRequest`, or GitHub's own `PullRequest`, still to be tagged for the read\n\t * (`toPullRequestRow`). Unlike the repo-scoped core, this needs no\n\t * `repos` — it reads the current user's pull requests across the account, so the ProviderBackend sweep\n\t * can drive its Kanban \"done\" column even when no repositories are supplied (where the repo-scoped core\n\t * rejects an empty `repos` input). Recovers thrown errors into `{ error }` so callers surface warnings.\n\t */\n\tasync getMyPullRequestsForUserResult(\n\t\toptions?: {\n\t\t\tstate?: PullRequestStateFilter[];\n\t\t\tcursor?: string;\n\t\t\tincludeReviewRequested?: boolean;\n\t\t\t/** Exact OR union of account-wide relationships to include. */\n\t\t\tfilters?: PullRequestFilter[];\n\t\t\t/** Request only the stable list fields, omitting optional provider enrichments. */\n\t\t\tsummary?: boolean;\n\t\t},\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderApiPagedResult<ProviderPullRequest | PullRequest> | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tif (this.getProviderMyPullRequestsForUser == null) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.getProviderMyPullRequestsForUser(session, options);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('getMyPullRequestsForUser');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('getMyPullRequestsForUser', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * Reads the current user's pull requests across the whole account using each provider's native \"my PRs\"\n\t * query, returning its raw rows (see {@link getMyPullRequestsForUserResult}). Without `filters`, the exact user\n\t * scopes depend on provider-native\n\t * behavior and options like `includeReviewRequested`. With `filters`, each member is an exact account-wide OR\n\t * relationship validated by the facade before this provider hook is called. Optional: providers that can't\n\t * express an account-wide user query leave it undefined and the surface falls back to repo-scoped.\n\t *\n\t * These native user queries are cursor-based, so `cursor` (not a page number) drives continuation; there\n\t * is no jump-to-page-N and no per-call page size on this path.\n\t *\n\t * `includeReviewRequested` opts into the review-requested slice for providers whose account-wide read\n\t * only returns authored PRs natively and must fan out per-repo to add reviewer PRs (Bitbucket). It's off\n\t * by default so a sweep pays gkcli-parity cost (authored only) unless the caller deliberately opts in;\n\t * providers whose native query already covers review-requested PRs ignore it.\n\t */\n\tprotected getProviderMyPullRequestsForUser?(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: {\n\t\t\tstate?: PullRequestStateFilter[];\n\t\t\tcursor?: string;\n\t\t\tincludeReviewRequested?: boolean;\n\t\t\tfilters?: PullRequestFilter[];\n\t\t\tsummary?: boolean;\n\t\t},\n\t): Promise<ProviderApiPagedResult<ProviderPullRequest | PullRequest> | undefined>;\n\n\t/**\n\t * The current account as each of `pullRequests` identifies its members, in order: what a raw row's\n\t * `authoredByMe` and `viewer` are resolved against when it's mapped. Most hosts give a person one id, so every\n\t * row gets the account itself; Azure DevOps Server answers per collection (see `AzureDevOpsServerIntegration`).\n\t * Throws only when the account itself can't be read.\n\t */\n\tasync getPullRequestViewers(\n\t\tpullRequests: readonly (ProviderPullRequest | PullRequest)[],\n\t\tconnectionId?: string,\n\t): Promise<({ id: string; username?: string } | undefined)[]> {\n\t\tconst account = await this.getCurrentAccount({ connectionId: connectionId });\n\t\tconst viewer = account != null ? { id: account.id, username: account.username } : undefined;\n\t\treturn pullRequests.map(() => viewer);\n\t}\n\n\t/**\n\t * Parses a Repo/Project paging cursor into its `cursors` bundle. Guards against valid JSON whose\n\t * `cursors` is a truthy non-array (e.g. `{ \"cursors\": \"...\" }`), which would otherwise bypass the\n\t * `?? []` fallback at call sites and flow into `.map()` downstream, throwing instead of degrading to\n\t * the first page.\n\t */\n\tprivate parseCursorInfo<T>(cursor?: string): { cursors?: T[] } {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(cursor ?? '{}') as { cursors?: T[] };\n\t\t\treturn Array.isArray(parsed?.cursors) ? parsed : {};\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tprotected abstract searchProviderMyPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: T[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the filtered pull-request search. Errors become the soft\n\t * `{ error }` branch so the public facade can preserve an empty account and a failed request as distinct\n\t * outcomes.\n\t */\n\tasync searchPullRequestsPageResult(\n\t\toptions: {\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: PullRequestSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t\t/** See {@link IntegrationManager.searchPullRequestsPage}. */\n\t\t\tsummary?: boolean;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderPullRequestSearchPage | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.searchProviderPullRequestsPage?.(session, options, cancellation);\n\t\t\tawait this.confirmScopedAuthFailures(session, result?.metadata);\n\t\t\tthis.resetRequestExceptionCount('searchPullRequestsPage');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('searchPullRequestsPage', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/** Must agree with `ProviderMetadata.supportedPullRequestSearch`. */\n\tprotected searchProviderPullRequestsPage?(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions: {\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: PullRequestSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t\t/** See the caller's option of the same name on {@link searchPullRequestsPage}. */\n\t\t\tsummary?: boolean;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestSearchPage | undefined>;\n\n\t/** Free-text search across pull requests, optionally narrowed to `repos`. */\n\t@trace()\n\tasync searchPullRequests(\n\t\tsearchQuery: string,\n\t\trepos?: T | T[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions & { connectionId?: string },\n\t): Promise<PullRequest[] | undefined> {\n\t\tconst scope = getScopedLogger();\n\t\tconst { connectionId, ...searchOptions } = options ?? {};\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return undefined;\n\n\t\ttry {\n\t\t\tconst prs = await this.searchProviderPullRequests?.(\n\t\t\t\tsession,\n\t\t\t\tsearchQuery,\n\t\t\t\tensureArray(repos),\n\t\t\t\tcancellation,\n\t\t\t\tsearchOptions,\n\t\t\t);\n\t\t\tthis.resetRequestExceptionCount('searchPullRequests');\n\t\t\treturn prs;\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('searchPullRequests', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tprotected searchProviderPullRequests?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tsearchQuery: string,\n\t\trepos?: T[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the FILTERED issue search — issues matching structured criteria over a\n\t * repository/org scope, with no forced relationship to the current user. Recovers thrown errors into\n\t * `{ error }` so the facade surfaces a warning instead of a silent empty page.\n\t *\n\t * Distinct from every other issue read on this class: {@link searchMyIssuesWithTruncationResult} is bound to\n\t * the current user by construction, and {@link getMyIssuesForReposAsShapesResult} goes through the SDK's\n\t * repo-scoped read (whose over-limit recovery walk can cost up to 128 requests). This one is one request per\n\t * page and carries no relationship it wasn't asked for.\n\t */\n\tasync searchIssuesPageResult(\n\t\toptions: {\n\t\t\t/**\n\t\t\t * Repositories to search, as namespace/name descriptors. NOT repository ids: a search query names\n\t\t\t * repositories by path, so an id-based input can't be expressed and the facade rejects it before here.\n\t\t\t */\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: IssueSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderIssueSearchPage | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.searchProviderIssuesPage?.(session, options, cancellation);\n\t\t\tthis.resetRequestExceptionCount('searchIssuesPage');\n\t\t\treturn { value: result, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('searchIssuesPage', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL, like {@link searchProviderPullRequests}: a provider that can't express the criteria server-side\n\t * doesn't implement it, and the facade refuses the read (warning + `fetchFailed`) rather than serving a list\n\t * that was never narrowed. Whether a provider implements this must agree with what\n\t * `ProviderMetadata.supportedIssueSearch` declares.\n\t */\n\tprotected searchProviderIssuesPage?(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions: {\n\t\t\trepos?: ProviderRepoInput[];\n\t\t\torg?: string;\n\t\t\tcriteria?: IssueSearchCriteria;\n\t\t\tcursor?: string;\n\t\t\tpageSize?: number;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderIssueSearchPage | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the count-only probe: how many issues MATCH each scope, transferring no issues\n\t * at all. Recovers thrown errors into `{ error }` like the reads around it.\n\t *\n\t * Counts come back POSITIONALLY — one per input scope, in order — because a caller's key must never reach the\n\t * provider query. See {@link ProviderSearchCount} for what each slot can hold; `undefined` means the provider\n\t * didn't report a count for it, never zero matches.\n\t */\n\tasync countIssuesResult(\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: IssueSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<ProviderSearchCount[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst counts = await this.countProviderIssues?.(session, scopes, cancellation);\n\t\t\tthis.resetRequestExceptionCount('countIssues');\n\t\t\treturn { value: counts, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('countIssues', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: only a provider that can answer \"how many match\" WITHOUT fetching the matches implements this.\n\t * GitHub's search reports `issueCount` on a zero-node selection, and Azure DevOps Server's WIQL returns the\n\t * matching ids without their details; GitLab's REST exposes a total on some endpoints but not for a\n\t * search-shaped query. A provider that can't answer doesn't implement it and the facade refuses the probe, so a\n\t * consumer hides its count rather than being shown a fabricated one.\n\t */\n\tprotected countProviderIssues?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: IssueSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderSearchCount[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the BATCH issue read: resolves several `(owner, repo, number)` coordinates, plus\n\t * `project` on Azure DevOps, in ONE call to {@link getProviderIssuesBatch}. One settled slot per input\n\t * coordinate: `fulfilled` with `undefined` means the issue does not exist or is not visible to this token;\n\t * `rejected` means that target could not be checked, never that it is absent.\n\t *\n\t * Distinct from every search on this class, and deliberately so. A search answers \"what matches\"; this answers\n\t * \"does this exact issue exist\", which is the question a caller correlating a branch name to an issue is\n\t * actually asking. It has no result ceiling, no ordering and no cursor, and — the property that matters most —\n\t * an absent slot is a PROVEN ABSENCE rather than \"not found within a page budget\", so a caller can cache a\n\t * miss instead of re-walking for it forever.\n\t *\n\t * Results come back POSITIONALLY — one per input coordinate, in order — for the same reason\n\t * {@link countIssuesResult} does: a caller's key must never reach the provider query.\n\t *\n\t * Failure isolation happens PER TARGET, mirroring {@link getPullRequestsBatchResult}: the whole call counts\n\t * as a failure against the integration's request-exception budget only when EVERY slot rejected, and not even\n\t * then when a credential that checks out was refused by each target's own scope (`settleBatchRefusals`).\n\t * Server errors and timeouts on the targets show one notice however many hit one, and cost a strike only as\n\t * part of that whole-call failure (`reportDeferredRequestFailures`), so a call spends at most one. A batch read\n\t * with etags makes up to two such calls (a full read of the targets without an etag, and a full read of the ones\n\t * that changed), so it can spend two; its cheap check ({@link getIssuesEtagFieldsResult}) spends nothing unless\n\t * the credential is refused.\n\t */\n\tasync getIssuesBatchResult(\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<IssueShape | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet slots: PromiseSettledResult<IssueShape | undefined>[] | undefined;\n\t\ttry {\n\t\t\tslots = await this.getProviderIssuesBatch?.(session, coordinates, cancellation);\n\t\t\tif (slots == null) {\n\t\t\t\tthis.resetRequestExceptionCount('getIssuesBatch');\n\t\t\t\treturn { value: undefined, duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, coordinates, slots);\n\n\t\t\tthis.resetRequestExceptionCount('getIssuesBatch');\n\t\t\tthis.reportDeferredRequestFailures(slots, false);\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tconst struck = this.handleProviderException('getIssuesBatch', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\tthis.reportDeferredRequestFailures(slots, !struck);\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: one settled slot per input coordinate, in order, in the same shape the list reads return for this\n\t * provider. `fulfilled` with `undefined` is a PROVEN ABSENCE a caller may cache; `rejected` means that target\n\t * could not be checked — never conflate the two, so a host implements this only where it can tell them apart.\n\t *\n\t * GitHub/GHE alias up to 25 coordinates into one document and so chunk internally; a chunk that throws rejects\n\t * every slot in that chunk, not the ones in other chunks. GitLab and Azure DevOps read one issue per request and\n\t * fan out with `mapSettledBounded`, so one target's failure rejects only its own slot. Bitbucket has no issues.\n\t */\n\tprotected getProviderIssuesBatch?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<IssueShape | undefined>[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the BATCH pull request read: resolves several coordinates, in any state, BY\n\t * IDENTITY, in ONE call to {@link getProviderPullRequestsBatch}. One settled slot per input coordinate:\n\t * `fulfilled` with `undefined` means the pull request does not exist or is not visible to this token;\n\t * `rejected` means that target could not be checked, never that it is absent.\n\t *\n\t * Failure isolation happens PER TARGET, not per call: a hook that reads one pull request per request (every\n\t * host but GitHub/GHE) fans its coordinates out itself and settles each independently, so one bad target\n\t * rejects only its own slot. Mirrors {@link getMyPullRequestsForReposResult}'s per-repo fan-out — the whole\n\t * call counts as a failure against the integration's request-exception budget only when EVERY slot rejected,\n\t * and not even then when a credential that checks out was refused by each target's own scope\n\t * (`settleBatchRefusals`). Server errors and timeouts on the targets show one notice however many hit one, and\n\t * cost a strike only as part of that whole-call failure (`reportDeferredRequestFailures`), so one call spends at\n\t * most one. A batch read with etags makes up to two such calls (a full read of the targets without an etag, and a\n\t * full read of the ones that changed), so it can spend two; its cheap check\n\t * ({@link getPullRequestsEtagFieldsResult}) spends nothing unless the credential is refused.\n\t */\n\tasync getPullRequestsBatchResult(\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions?: { currentAccount?: { id: string; username?: string } },\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<PullRequestShape | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet slots: PromiseSettledResult<PullRequestShape | undefined>[] | undefined;\n\t\ttry {\n\t\t\tslots = await this.getProviderPullRequestsBatch?.(session, coordinates, options, cancellation);\n\t\t\tif (slots == null) {\n\t\t\t\tthis.resetRequestExceptionCount('getPullRequestsBatch');\n\t\t\t\treturn { value: undefined, duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, coordinates, slots);\n\n\t\t\tthis.resetRequestExceptionCount('getPullRequestsBatch');\n\t\t\tthis.reportDeferredRequestFailures(slots, false);\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tconst struck = this.handleProviderException('getPullRequestsBatch', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\tthis.reportDeferredRequestFailures(slots, !struck);\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: resolves several coordinates, returning one settled slot per input coordinate, in order, in the\n\t * same shape the list reads return for this provider. `fulfilled` with `undefined` is a PROVEN ABSENCE a\n\t * caller may cache; `rejected` means that target could not be checked — never conflate the two.\n\t *\n\t * A provider that reads one pull request per upstream request (every host but GitHub/GHE) fans its\n\t * coordinates out with `mapSettledBounded`, so one target's failure rejects only its own slot instead of\n\t * taking the whole call down. GitHub/GHE alias up to 25 coordinates into one document and so chunk\n\t * internally; a chunk that throws rejects every slot in that chunk, not the ones in other chunks.\n\t */\n\tprotected getProviderPullRequestsBatch?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string } } | undefined,\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<PullRequestShape | undefined>[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the cheap check behind the batch issue read's etags: each coordinate's change\n\t * state ({@link IssueEtagFields}), plus the inputs of each of `options.etagIncludes`, in ONE call to\n\t * {@link getProviderIssuesEtagFields}. The slots mean what\n\t * {@link getIssuesBatchResult}'s do — `fulfilled` with `undefined` is a PROVEN ABSENCE, `rejected` means that\n\t * target could not be checked.\n\t *\n\t * Unlike there, failures other than a refused credential are never the call's: every slot comes back as it\n\t * settled, even when none answered, so each failed target is judged by its own reason. Such failures spend no\n\t * strike and show no notice, since the targets they touch fall through to the full read, which does both if the\n\t * host really is failing, or are dropped as rate-limited or without a connection. Refusals are settled as there\n\t * (`settleBatchRefusals` with `keepOtherFailures`), and only a refused credential fails the call, on the auth path\n\t * (`handleEtagCheckException`). The failure budget is reset only when some target answered.\n\t */\n\tasync getIssuesEtagFieldsResult(\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { etagIncludes?: readonly IssueEtagInclude[] },\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<IssueEtagFields | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst slots = await this.getProviderIssuesEtagFields?.(session, coordinates, options, cancellation);\n\t\t\tif (slots == null) return { value: undefined, duration: performance.now() - start };\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, coordinates, slots, { keepOtherFailures: true });\n\n\t\t\tif (slots.some(slot => slot.status === 'fulfilled')) {\n\t\t\t\tthis.resetRequestExceptionCount('getIssuesEtagFields');\n\t\t\t}\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleEtagCheckException('getIssuesEtagFields', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: the cheap check behind the batch issue read's etags — one settled slot per input coordinate, in\n\t * order, holding the issue's change state in the vocabulary {@link getProviderIssuesBatch}'s rows end in, so\n\t * both reads compute the same etag. Each include's inputs are read only when it is listed in\n\t * `options.etagIncludes`, and only where a full row carries them. `fulfilled` with `undefined` is a PROVEN\n\t * ABSENCE, as there. A host implements this only where it is cheaper than the full read.\n\t */\n\tprotected getProviderIssuesEtagFields?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { etagIncludes?: readonly IssueEtagInclude[] },\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<IssueEtagFields | undefined>[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the cheap check behind the batch pull request read's etags: each coordinate's\n\t * change state ({@link PullRequestEtagFields}), plus the inputs of each of `options.etagIncludes`, in ONE call to\n\t * {@link getProviderPullRequestsEtagFields}. The slots mean what {@link getPullRequestsBatchResult}'s do —\n\t * `fulfilled` with `undefined` is a PROVEN ABSENCE, `rejected` means that target could not be checked. Failures\n\t * are judged and budgeted as in {@link getIssuesEtagFieldsResult}: only a refused credential fails the call or\n\t * spends a strike.\n\t */\n\tasync getPullRequestsEtagFieldsResult(\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { etagIncludes?: readonly PullRequestEtagInclude[] },\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<PullRequestEtagFields | undefined>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst slots = await this.getProviderPullRequestsEtagFields?.(session, coordinates, options, cancellation);\n\t\t\tif (slots == null) return { value: undefined, duration: performance.now() - start };\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, coordinates, slots, { keepOtherFailures: true });\n\n\t\t\tif (slots.some(slot => slot.status === 'fulfilled')) {\n\t\t\t\tthis.resetRequestExceptionCount('getPullRequestsEtagFields');\n\t\t\t}\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleEtagCheckException('getPullRequestsEtagFields', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: the cheap check behind the batch pull request read's etags — one settled slot per input coordinate,\n\t * in order, holding the pull request's change state in the vocabulary {@link getProviderPullRequestsBatch}'s\n\t * rows end in, after their WHOLE conversion chain, so both reads compute the same etag. Each include's inputs are\n\t * read only when it is listed in `options.etagIncludes`. `fulfilled` with `undefined` is a PROVEN ABSENCE, as\n\t * there. A host implements this only where it is cheaper than the full read.\n\t */\n\tprotected getProviderPullRequestsEtagFields?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tcoordinates: readonly { owner: string; repo: string; number: number; project?: string }[],\n\t\toptions: { etagIncludes?: readonly PullRequestEtagInclude[] },\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<PullRequestEtagFields | undefined>[] | undefined>;\n\n\t/**\n\t * Result-returning wrapper for the pull-requests-by-branch read: for each target, every pull request whose head\n\t * is that branch, in any state, in ONE call to {@link getProviderPullRequestsForBranches}. One settled slot\n\t * per target: `fulfilled` with an empty list means the host answered and nothing matched; `rejected` means\n\t * that target could not be checked, never that it has no pull requests.\n\t *\n\t * Uncached, and deliberately not built on {@link getPullRequestForBranch}: that read caches through\n\t * `IntegrationCacheProvider.getPullRequestForBranch`, answers one pull request, and on several hosts looks the\n\t * branch ref up, which answers \"none\" once a merged pull request's branch is deleted.\n\t *\n\t * Failure isolation is per target, as in {@link getPullRequestsBatchResult}: the whole call counts against the\n\t * request-exception budget only when EVERY slot rejected, and not when each target's own scope refused a\n\t * credential that checks out. Server errors and timeouts on the targets show one notice however many hit one, and\n\t * cost a strike only as part of that whole-call failure.\n\t */\n\tasync getPullRequestsForBranchesResult(\n\t\ttargets: readonly { owner: string; repo: string; project?: string; branch: string; headOwner?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string }; limit: number },\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<BatchSlot<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\tlet slots: PromiseSettledResult<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined;\n\t\ttry {\n\t\t\tslots = await this.getProviderPullRequestsForBranches?.(session, targets, options, cancellation);\n\t\t\tif (slots == null) {\n\t\t\t\tthis.resetRequestExceptionCount('getPullRequestsForBranches');\n\t\t\t\treturn { value: undefined, duration: performance.now() - start };\n\t\t\t}\n\n\t\t\tconst settled = await this.settleBatchRefusals(session, targets, slots);\n\n\t\t\tthis.resetRequestExceptionCount('getPullRequestsForBranches');\n\t\t\tthis.reportDeferredRequestFailures(slots, false);\n\t\t\treturn { value: settled, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tconst struck = this.handleProviderException('getPullRequestsForBranches', ex, {\n\t\t\t\tscope: scope,\n\t\t\t\tconnectionId: connectionId,\n\t\t\t});\n\t\t\tthis.reportDeferredRequestFailures(slots, !struck);\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL: one settled slot per target, in order. A fulfilled slot lists the matching pull requests, newest\n\t * first and at most `options.limit` of them, in the same shape the list reads return for this provider where\n\t * the host allows it; `truncated` means more may match than were returned.\n\t *\n\t * A row matches only when its head branch is the target's `branch` AND its head repository is the base\n\t * repository itself (`headOwner` omitted) or the fork `headOwner` owns — a same-named branch in some other\n\t * fork is a different branch. A host that reads one target per request fans out with `mapSettledBounded`, so\n\t * one target's failure rejects only its own slot; GitHub/GHE alias up to 25 targets per request, and a request\n\t * that throws rejects only its own targets.\n\t */\n\tprotected getProviderPullRequestsForBranches?(\n\t\tsession: ProviderAuthenticationSession,\n\t\ttargets: readonly { owner: string; repo: string; project?: string; branch: string; headOwner?: string }[],\n\t\toptions: { currentAccount?: { id: string; username?: string }; limit: number },\n\t\tcancellation?: AbortSignal,\n\t): Promise<PromiseSettledResult<{ pullRequests: PullRequestShape[]; truncated: boolean }>[] | undefined>;\n\n\t/**\n\t * The PR twin of {@link countIssuesResult}: counts each scope's pull requests, transferring none where the\n\t * provider has a count query. Each slot is a {@link ProviderPullRequestCount}, so a provider that can only count\n\t * by reading (Bitbucket Data Center) can mark a figure it stopped short of as a floor, or an `Error` refusing only\n\t * that scope (Azure DevOps Server).\n\t */\n\tasync countPullRequestsResult(\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t\tconnectionId?: string,\n\t): Promise<IntegrationResult<(ProviderPullRequestCount | Error)[] | undefined>> {\n\t\tconst scope = getScopedLogger();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSession(connectionId, scope);\n\t\tif (session == null || isReadSessionFailure(session)) return session && { error: session.error };\n\n\t\tconst start = performance.now();\n\t\ttry {\n\t\t\tconst counts = await this.countProviderPullRequests?.(session, scopes, cancellation);\n\t\t\tthis.resetRequestExceptionCount('countPullRequests');\n\t\t\treturn { value: counts, duration: performance.now() - start };\n\t\t} catch (ex) {\n\t\t\tthis.handleProviderException('countPullRequests', ex, { scope: scope, connectionId: connectionId });\n\t\t\treturn { error: toError(ex), duration: performance.now() - start };\n\t\t}\n\t}\n\n\t/**\n\t * OPTIONAL, like {@link countProviderIssues}: only a provider that can answer \"how many match\" implements it —\n\t * GitHub/GHE with a zero-node search, Bitbucket Data Center by reading within a budget and reporting a floor\n\t * past it, Azure DevOps Server from the drain its search reads. Must agree with\n\t * `ProviderMetadata.supportedPullRequestSearch`, which the facade validates against.\n\t */\n\tprotected countProviderPullRequests?(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<(ProviderPullRequestCount | Error)[] | undefined>;\n\n\tgetPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {\n\t\treturn this.getProviderPullRequestIdentityFromMaybeUrl?.(search);\n\t}\n\n\tprotected getProviderPullRequestIdentityFromMaybeUrl?(search: string): PullRequestUrlIdentity | undefined;\n}\n"],"mappings":"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"}
|