@gitkraken/core-gitlens 0.10.3 → 0.10.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/dist/git/models/pullRequest.d.ts +37 -0
  3. package/dist/git/models/pullRequest.js.map +1 -1
  4. package/dist/git-cli/providers/graph.js +14 -8
  5. package/dist/git-cli/providers/graph.js.map +1 -1
  6. package/dist/plus/git-github/api/github.d.ts +3 -1
  7. package/dist/plus/git-github/api/github.js.map +1 -1
  8. package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts +2 -1
  9. package/dist/plus/integrations/authentication/configuredIntegrationService.js +11 -6
  10. package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -1
  11. package/dist/plus/integrations/authentication/models.d.ts +11 -0
  12. package/dist/plus/integrations/authentication/models.js.map +1 -1
  13. package/dist/plus/integrations/constants.d.ts +4 -0
  14. package/dist/plus/integrations/constants.js.map +1 -1
  15. package/dist/plus/integrations/integrationService.d.ts +6 -0
  16. package/dist/plus/integrations/integrationService.js +34 -5
  17. package/dist/plus/integrations/integrationService.js.map +1 -1
  18. package/dist/plus/integrations/models/gitHostIntegration.d.ts +5 -1
  19. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  20. package/dist/plus/integrations/models/integration.d.ts +7 -1
  21. package/dist/plus/integrations/models/integration.js +12 -2
  22. package/dist/plus/integrations/models/integration.js.map +1 -1
  23. package/dist/plus/integrations/providers/bitbucket.js +2 -1
  24. package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
  25. package/dist/plus/integrations/providers/github.d.ts +12 -1
  26. package/dist/plus/integrations/providers/github.js +41 -1
  27. package/dist/plus/integrations/providers/github.js.map +1 -1
  28. package/dist/plus/integrations/providers/gitlab.d.ts +1 -1
  29. package/dist/plus/integrations/providers/gitlab.js +3 -2
  30. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  31. package/dist/plus/integrations/providers/linear.d.ts +9 -1
  32. package/dist/plus/integrations/providers/linear.js +34 -11
  33. package/dist/plus/integrations/providers/linear.js.map +1 -1
  34. package/dist/plus/integrations/providers/models.js +1 -0
  35. package/dist/plus/integrations/providers/models.js.map +1 -1
  36. package/dist/utils/cancellation.d.ts +2 -3
  37. package/dist/utils/cancellation.js +2 -3
  38. package/dist/utils/cancellation.js.map +1 -1
  39. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"github.js","names":[],"sources":["../../../../../plus/integrations/src/providers/github.ts"],"sourcesContent":["import { gitHubPullRequestRelationshipQualifiers } from '@gitlens/git-github/api/pullRequestSearchQuery.js';\nimport type { GitHubIssueEtagNode, GitHubPullRequestEtagNode } from '@gitlens/git-github/models.js';\nimport {\n\tfromGitHubIssueOrPullRequestState,\n\tfromGitHubPullRequestMergeableState,\n\tfromGitHubPullRequestReviewDecision,\n\tfromGitHubPullRequestStatusCheckRollupState,\n} from '@gitlens/git-github/models.js';\nimport type { Account, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue, IssueSearchCriteria, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type {\n\tPullRequest,\n\tPullRequestMergeMethod,\n\tPullRequestSearchCriteria,\n\tPullRequestShape,\n\tPullRequestStackInfo,\n\tPullRequestState,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport type { RepositoryDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\nimport { getGitHubNoReplyAddressParts } from '@gitlens/git/remotes/github.js';\nimport type { PullRequestUrlIdentity } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { chunk } from '@gitlens/utils/array.js';\nimport type { Emitter } from '@gitlens/utils/event.js';\nimport { batch, mapBounded, mapSettledBounded } from '@gitlens/utils/promise.js';\nimport type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';\nimport type { IntegrationAuthenticationService } from '../authentication/integrationAuthenticationService.js';\nimport type { ProviderAuthenticationSession } from '../authentication/models.js';\nimport { toTokenWithInfo } from '../authentication/models.js';\nimport type { ProviderRefusal } from '../collectionMetadata.js';\nimport { toCollectionScopeFailure } from '../collectionMetadata.js';\nimport { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId, providerFanOutConcurrency } from '../constants.js';\nimport type { IntegrationServiceContext } from '../context.js';\nimport { AuthenticationError, IntegrationReadUnavailableError, RequestNotFoundError } from '../errors.js';\nimport type { IntegrationConnectionChangeEvent } from '../integrationService.js';\nimport type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';\nimport { GitHostIntegration } from '../models/gitHostIntegration.js';\nimport type {\n\tIssueEtagFields,\n\tIssueEtagInclude,\n\tProviderIssueSearchPage,\n\tProviderPullRequestCount,\n\tProviderPullRequestSearchPage,\n\tPullRequestEtagFields,\n\tPullRequestEtagInclude,\n\tSearchMyIssuesOptions,\n} from '../models/integration.js';\nimport type { ProviderWarningCause } from '../results.js';\nimport type { GitHubIntegrationIds } from './github/github.utils.js';\nimport { getGitHubPullRequestIdentityFromMaybeUrl } from './github/github.utils.js';\nimport type {\n\tProviderApiPagedResult,\n\tProviderHierarchyResult,\n\tProviderOrganization,\n\tProviderRepoInput,\n\tProviderRepository,\n} from './models.js';\nimport {\n\tgetProviderPullRequestIdentity,\n\tIssueFilter,\n\tprovidersMetadata,\n\tPullRequestFilter,\n\tstampNativePullRequest,\n} from './models.js';\nimport type { ProvidersApi } from './providersApi.js';\nimport { resolveBranchPullRequests } from './utils/providerPaging.js';\n\ntype GitHubPullRequestFacetCursor = Record<string, string>;\n\nfunction toPullRequestFacetCursor(value: unknown): GitHubPullRequestFacetCursor {\n\tif (value == null || typeof value !== 'object' || Array.isArray(value)) return {};\n\n\treturn Object.fromEntries(\n\t\tObject.entries(value).filter(\n\t\t\t([key, cursor]) => key.length !== 0 && typeof cursor === 'string' && cursor.length !== 0,\n\t\t),\n\t);\n}\n\nfunction parsePullRequestFacetCursor(cursor: string | undefined): GitHubPullRequestFacetCursor {\n\tif (!cursor) return {};\n\n\ttry {\n\t\tconst parsed = JSON.parse(cursor) as unknown;\n\t\tif (parsed != null && typeof parsed === 'object' && !Array.isArray(parsed) && 'cursors' in parsed) {\n\t\t\tconst wrapped = parsed as { type?: unknown; cursors?: unknown };\n\t\t\tif (wrapped.type === 'cursor') {\n\t\t\t\treturn toPullRequestFacetCursor(wrapped.cursors);\n\t\t\t}\n\t\t}\n\n\t\treturn toPullRequestFacetCursor(parsed);\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nconst metadata = providersMetadata[GitCloudHostIntegrationId.GitHub];\nconst authProvider: IntegrationAuthenticationProviderDescriptor = Object.freeze({\n\tid: metadata.id,\n\tscopes: metadata.scopes,\n});\n\nconst cloudEnterpriseMetadata = providersMetadata[GitSelfManagedHostIntegrationId.CloudGitHubEnterprise];\nconst cloudEnterpriseAuthProvider: IntegrationAuthenticationProviderDescriptor = Object.freeze({\n\tid: cloudEnterpriseMetadata.id,\n\tscopes: cloudEnterpriseMetadata.scopes,\n});\n\nexport type GitHubRepositoryDescriptor = RepositoryDescriptor;\n\n/** How many per-login SSH signing-key lookups to run concurrently, to avoid a request burst that trips rate limiting. */\nconst sshSigningKeyResolveBatchSize = 10;\n\n// One aliased document costs about the same as a single read up to 25 targets; past that, latency climbs.\nconst pullRequestsBatchChunkSize = 25;\n\n/**\n * How many coordinates go into one aliased issue request.\n *\n * Measured rather than inherited from `issueCountChunkSize`, since that one rests on a zero-node selection and\n * this carries the full issue projection per alias. Against the live API on all-resolving coordinates: 10 took\n * 875ms, 25 took 890ms — so up to 25 is effectively free — 50 took 1.3s, and 75 took 2.7s. No complexity refusal\n * appeared up to 100.\n *\n * 25 is where latency is still flat, with room before it degrades. It also puts any realistic correlation batch\n * in ONE request, which is the whole point of the read.\n */\nconst issuesBatchChunkSize = 25;\n\n/**\n * Runs an aliased batch read over `items` in chunks of `chunkSize`, with bounded concurrency, converting each\n * fulfilled slot with `map`. Settled per target throughout: a chunk that throws rejects only its own slots, and a\n * slot whose conversion throws rejects only itself, so one bad row never takes its chunk's siblings down with it.\n */\nasync function readChunked<T, V, R>(\n\titems: readonly T[],\n\tchunkSize: number,\n\tread: (chunk: T[]) => Promise<PromiseSettledResult<V>[]>,\n\tmap: (value: V) => R,\n): Promise<PromiseSettledResult<R>[]> {\n\tconst settledChunks = await mapBounded(\n\t\tchunk([...items], chunkSize),\n\t\tproviderFanOutConcurrency,\n\t\tasync (chunkItems): Promise<PromiseSettledResult<R>[]> => {\n\t\t\tlet slots: PromiseSettledResult<V>[];\n\t\t\ttry {\n\t\t\t\tslots = await read(chunkItems);\n\t\t\t} catch (ex) {\n\t\t\t\treturn chunkItems.map(() => ({ status: 'rejected', reason: ex }));\n\t\t\t}\n\n\t\t\treturn slots.map((slot): PromiseSettledResult<R> => {\n\t\t\t\tif (slot.status === 'rejected') return slot;\n\n\t\t\t\ttry {\n\t\t\t\t\treturn { status: 'fulfilled', value: map(slot.value) };\n\t\t\t\t} catch (ex) {\n\t\t\t\t\treturn { status: 'rejected', reason: ex };\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t);\n\treturn settledChunks.flat();\n}\n\n/**\n * A cheap etag read's pull request, as the fields its full row's etag reads, through `fromGitHubPullRequest`'s own\n * conversions, so a cheap check and a full read of the same pull request compute the same etag.\n */\nfunction toPullRequestEtagFields(\n\tnode: GitHubPullRequestEtagNode,\n\tetagIncludes: readonly PullRequestEtagInclude[],\n): PullRequestEtagFields {\n\tconst fields: PullRequestEtagFields = {\n\t\tstate: fromGitHubIssueOrPullRequestState(node.state),\n\t\tisDraft: node.isDraft,\n\t\tupdatedDate: new Date(node.updatedAt),\n\t\theadSha: node.headRefOid,\n\t};\n\n\tif (etagIncludes.includes('mergeable')) {\n\t\tfields.mergeableState =\n\t\t\tnode.mergeable != null ? fromGitHubPullRequestMergeableState(node.mergeable) : undefined;\n\t}\n\n\tif (etagIncludes.includes('reviewDecision')) {\n\t\t// GitHub's `null` (the repository requires no review) is no decision, even while a review is requested.\n\t\tfields.reviewDecision =\n\t\t\tnode.reviewDecision != null ? fromGitHubPullRequestReviewDecision(node.reviewDecision) : undefined;\n\t}\n\n\tif (etagIncludes.includes('checks')) {\n\t\tfields.statusCheckRollupState = fromGitHubPullRequestStatusCheckRollupState(\n\t\t\tnode.commits?.nodes?.[0]?.commit.statusCheckRollup?.state,\n\t\t);\n\t}\n\n\treturn fields;\n}\n\n/** A cheap etag read's issue, as the fields its full row's etag reads, through `fromGitHubIssue`'s own conversions. */\nfunction toIssueEtagFields(node: GitHubIssueEtagNode, etagIncludes: readonly IssueEtagInclude[]): IssueEtagFields {\n\tconst fields: IssueEtagFields = {\n\t\tstate: fromGitHubIssueOrPullRequestState(node.state),\n\t\tupdatedDate: new Date(node.updatedAt),\n\t};\n\n\tif (etagIncludes.includes('reactions')) {\n\t\tfields.thumbsUpCount = node.reactions?.totalCount;\n\t}\n\n\treturn fields;\n}\n\nabstract class GitHubIntegrationBase<ID extends GitHubIntegrationIds> extends GitHostIntegration<\n\tID,\n\tGitHubRepositoryDescriptor\n> {\n\t/**\n\t * Base URL handed to `@gitkraken/provider-apis`, which derives BOTH the REST and the GraphQL endpoint from it\n\t * by appending GitHub Enterprise's paths. Only a GHE instance base belongs here; cloud passes `undefined`,\n\t * the sole value that selects the cloud endpoints (see the cloud subclass).\n\t */\n\tprotected abstract apiBaseUrlFor(session: ProviderAuthenticationSession): string | undefined;\n\n\tprotected override async getProviderAccountForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\trev: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getAccountForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderAccountForEmail(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\temail: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getAccountForEmail(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\temail,\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderSshSigningKeysForEmails(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\temails: string[],\n\t): Promise<Map<string, string[]>> {\n\t\tconst result = new Map<string, string[]>();\n\n\t\tconst api = await this.authenticationService.apis.github;\n\t\tif (api == null) return result;\n\n\t\tconst token = toTokenWithInfo(this.id, session);\n\n\t\t// Resolve each email to a login: GitHub noreply addresses encode it locally; the rest are resolved in a single\n\t\t// batched GraphQL request rather than one round-trip per email.\n\t\tconst loginByEmail = new Map<string, string>();\n\t\tconst toResolve: string[] = [];\n\t\tfor (const email of emails) {\n\t\t\tconst login = getGitHubNoReplyAddressParts(email)?.login;\n\t\t\tif (login != null) {\n\t\t\t\tloginByEmail.set(email.toLowerCase(), login);\n\t\t\t} else {\n\t\t\t\ttoResolve.push(email);\n\t\t\t}\n\t\t}\n\n\t\tif (toResolve.length) {\n\t\t\tconst resolved = await api.getAccountsForEmails(this, token, toResolve, {\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t});\n\t\t\tfor (const [emailLower, login] of resolved) {\n\t\t\t\tloginByEmail.set(emailLower, login);\n\t\t\t}\n\t\t}\n\n\t\t// Fetch signing keys once per distinct login (REST has no batch endpoint), in bounded batches rather than firing\n\t\t// all lookups at once, to avoid a request burst that could trip secondary rate limiting. Then map keys to each email.\n\t\tconst keysByLogin = new Map<string, string[]>();\n\t\tawait batch([...new Set(loginByEmail.values())], sshSigningKeyResolveBatchSize, async login => {\n\t\t\tconst keys = await api.getUserSshSigningKeys(this, token, login, { baseUrl: this.apiBaseUrlFor(session) });\n\t\t\tkeysByLogin.set(\n\t\t\t\tlogin,\n\t\t\t\tkeys.map(k => k.key),\n\t\t\t);\n\t\t});\n\n\t\tfor (const [emailLower, login] of loginByEmail) {\n\t\t\tresult.set(emailLower, keysByLogin.get(login) ?? []);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprotected override async getProviderDefaultBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t): Promise<DefaultBranch | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getDefaultBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderLinkedIssueOrPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\t{ id }: { id: string; key: string },\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getIssueOrPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tNumber(id),\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderIssue(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<Issue | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getIssue(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tNumber(id),\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tincludeBody: true,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tparseInt(id, 10),\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\tbranch: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t\tinclude?: PullRequestState[];\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\tconst { include, ...opts } = options ?? {};\n\n\t\tconst toGitHubPullRequestState = (await import(/* webpackChunkName: \"integrations\" */ './github/models.js'))\n\t\t\t.toGitHubPullRequestState;\n\t\treturn (await this.authenticationService.apis.github)?.getPullRequestForBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tbranch,\n\t\t\t{\n\t\t\t\t...opts,\n\t\t\t\tinclude: include?.map(s => toGitHubPullRequestState(s)),\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\trev: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getPullRequestForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderRepositoryMetadata(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getRepositoryMetadata(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprotected override async getProviderOrganizationsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst result = await api.getGitHubOrgsForCurrentUser(toTokenWithInfo(this.id, session), {\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t});\n\t\tconst webUrl =\n\t\t\tthis.id === GitSelfManagedHostIntegrationId.CloudGitHubEnterprise\n\t\t\t\t? this.getSelfManagedInstallationUrl(session)\n\t\t\t\t: `https://${this.domain}`;\n\t\treturn {\n\t\t\tvalues: result.values.map(o => ({\n\t\t\t\tid: o.id,\n\t\t\t\tproviderId: this.id,\n\t\t\t\tname: o.username,\n\t\t\t\turl: `${webUrl}/${o.username}`,\n\t\t\t})),\n\t\t\t...(result.truncated ? { truncated: true } : {}),\n\t\t\t...(result.metadata != null ? { metadata: result.metadata } : {}),\n\t\t};\n\t}\n\n\tprotected override async getProviderRepositoriesForOrg(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg: string,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getReposForOrg(toTokenWithInfo(this.id, session), org, {\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\tcursor: options?.cursor,\n\t\t});\n\t}\n\n\tprotected override async getProviderRepositoriesForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\t// `/user/repos` with the full affiliation set: the user's own repos, collaborations, and org-member\n\t\t// repos — matching gkcli's org-less `provider repos github` walk (not every repo of every org).\n\t\treturn api.getReposForCurrentUser(toTokenWithInfo(this.id, session), {\n\t\t\taffiliations: ['owner', 'collaborator', 'organization_member'],\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\tcursor: options?.cursor,\n\t\t});\n\t}\n\n\tpublic override async getRepoInfo(repo: {\n\t\towner: string;\n\t\tname: string;\n\t\tproject?: string;\n\t\tconnectionId?: string;\n\t}): Promise<ProviderRepository | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSessionOrThrow(repo.connectionId, undefined);\n\t\tif (session == null) return undefined;\n\n\t\t// `apiBaseUrlFor` is undefined for cloud (which is what selects the cloud endpoints) and the GHE instance base\n\t\t// for enterprise (inherited override).\n\t\ttry {\n\t\t\treturn await api.getRepo(toTokenWithInfo(this.id, session), repo.owner, repo.name, repo.project, {\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t});\n\t\t} catch (ex) {\n\t\t\tif (!(ex instanceof RequestNotFoundError)) throw ex;\n\n\t\t\t// GraphQL answers a repository its organization hides from this OAuth app (OAuth App access restrictions)\n\t\t\t// exactly as it answers a missing one, so a miss is confirmed over REST, which refuses such a repository\n\t\t\t// with a `403` saying why. Only that refusal replaces the miss: a REST read that cannot confirm either way\n\t\t\t// leaves the answer GraphQL gave.\n\t\t\tconst github = await this.authenticationService.apis.github;\n\t\t\ttry {\n\t\t\t\tawait github?.getRepositoryAccess(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, {\n\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t});\n\t\t\t} catch (refusal) {\n\t\t\t\tif (refusal instanceof AuthenticationError) throw refusal;\n\t\t\t}\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * The profile request that proves the credential; see `IntegrationBase.validateCredential`. Silent: a refusal\n\t * here is rethrown to the read that asked, which reports it as it reports its own failure (or, for\n\t * `resolveRepository`, as the resolution's warning), so the check must not raise a prompt of its own.\n\t */\n\tprotected override async validateCredential(session: ProviderAuthenticationSession): Promise<void> {\n\t\tconst github = await this.authenticationService.apis.github;\n\t\tconst account = await github?.getCurrentAccount(this, toTokenWithInfo(this.id, session), {\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\tsilent: true,\n\t\t});\n\t\tif (account == null) throw new Error('GitHub did not confirm the credential');\n\t}\n\n\t/**\n\t * Names a confirmed credential's refusal from what GitHub said. A `403` whose explanation cites OAuth App access\n\t * restrictions is an organization that has not approved the OAuth app this token belongs to; its remedy page is\n\t * that app's page in the user's authorized apps, where they request an organization's approval, addressed by the\n\t * client id GitHub reports on the refusal. Any other refusal is left unnamed, so the warning keeps GitHub's own\n\t * words.\n\t */\n\tprotected override describeRefusal(\n\t\tsession: ProviderAuthenticationSession,\n\t\trefusal: ProviderRefusal,\n\t): ProviderWarningCause | undefined {\n\t\tif (refusal.status !== 403 || !/\\bOAuth App access restrictions\\b/i.test(refusal.detail ?? '')) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst webUrl =\n\t\t\tthis.id === GitSelfManagedHostIntegrationId.CloudGitHubEnterprise\n\t\t\t\t? this.getSelfManagedInstallationUrl(session)\n\t\t\t\t: `https://${this.domain}`;\n\t\treturn {\n\t\t\treason: 'oauth-app-not-allowed',\n\t\t\t...(refusal.oauthClientId != null\n\t\t\t\t? {\n\t\t\t\t\t\tremedyUrl: `${webUrl}/settings/connections/applications/${encodeURIComponent(refusal.oauthClientId)}`,\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\tprotected override async searchProviderMyPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: GitHubRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.searchMyPullRequests(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\trepos: repos?.map(r => `${r.owner}/${r.name}`),\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tsilent: options?.silent,\n\t\t\t\tstate: options?.state,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprotected override async 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<PullRequest> | undefined> {\n\t\tconst explicitFilters = options?.filters?.length ? [...new Set(options.filters)] : undefined;\n\t\t// Every account-wide read goes through our own facet search — there is deliberately no SDK\n\t\t// `getPullRequestsForUser` fallback. It could express neither a state set, nor exact relationships (its\n\t\t// `involves:` is a different question), nor the full projection, so which reads it could serve depended on\n\t\t// the options, and the two routes disagreed on more than they had to: only this one applies the Launchpad\n\t\t// ignored/included repository and organization qualifiers, so the same read returned different pull\n\t\t// requests depending on options that were supposed to affect only projection or relationship. With no\n\t\t// state and no filters this emits a single facet with no relationship qualifier, which is GitHub's own\n\t\t// `involves:@me` and `is:open` default — the same question the fallback asked, now on one route.\n\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst requestedStates: PullRequestStateFilter[] =\n\t\t\toptions?.state != null && options.state.length > 0 ? [...new Set(options.state)] : ['open'];\n\t\tconst facets =\n\t\t\texplicitFilters?.length != null\n\t\t\t\t? requestedStates.flatMap(state =>\n\t\t\t\t\t\texplicitFilters.map(filter => ({\n\t\t\t\t\t\t\tkey: `${state}:${filter}`,\n\t\t\t\t\t\t\tstate: state,\n\t\t\t\t\t\t\tsearch: gitHubPullRequestRelationshipQualifiers[filter],\n\t\t\t\t\t\t})),\n\t\t\t\t\t)\n\t\t\t\t: requestedStates.flatMap(state => [\n\t\t\t\t\t\t{ key: state, state: state, search: undefined },\n\t\t\t\t\t\t...(options?.includeReviewRequested === true\n\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkey: `${state}:${PullRequestFilter.ReviewRequested}`,\n\t\t\t\t\t\t\t\t\t\tstate: state,\n\t\t\t\t\t\t\t\t\t\tsearch: gitHubPullRequestRelationshipQualifiers[\n\t\t\t\t\t\t\t\t\t\t\tPullRequestFilter.ReviewRequested\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t: []),\n\t\t\t\t\t]);\n\t\tconst cursors = parsePullRequestFacetCursor(options?.cursor);\n\t\tconst hasResumableFacetCursor = Object.keys(cursors).length !== 0;\n\t\tconst facetsWithCursor = facets.filter(facet => cursors[facet.key] != null);\n\t\t// The first call has no cursor, so query every requested state. A continuation only happens after a\n\t\t// prior page reported `more:true`, whose bundle carries a cursor for each facet still in flight;\n\t\t// facets absent from the bundle are exhausted, so re-querying them from scratch would refetch the\n\t\t// same PRs (duplicated by the dedup-free sweep) and waste an API call per page. Query only the\n\t\t// states that still have a cursor, but degrade a malformed/empty cursor bundle, or one that doesn't\n\t\t// apply to the current requested states, to the first page rather than returning an empty page.\n\t\tconst facetsToQuery =\n\t\t\toptions?.cursor != null && hasResumableFacetCursor && facetsWithCursor.length !== 0\n\t\t\t\t? facetsWithCursor\n\t\t\t\t: facets;\n\t\tconst results = await Promise.allSettled(\n\t\t\tfacetsToQuery.map(async facet => ({\n\t\t\t\tkey: facet.key,\n\t\t\t\tresult: await github.searchMyPullRequestsPage(this, toTokenWithInfo(this.id, session), {\n\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t\tstate: facet.state,\n\t\t\t\t\tcursor: cursors[facet.key],\n\t\t\t\t\tsummary: options?.summary,\n\t\t\t\t\t...(facet.search != null ? { search: facet.search, includeDefaultInvolvement: false } : undefined),\n\t\t\t\t}),\n\t\t\t})),\n\t\t);\n\t\tif (results.every(result => result.status === 'rejected')) {\n\t\t\tconst first = results[0];\n\t\t\tif (first?.status === 'rejected') throw first.reason;\n\t\t}\n\n\t\tconst values = new Map<string, PullRequest>();\n\t\tconst nextCursors: GitHubPullRequestFacetCursor = {};\n\t\tconst failures = [];\n\t\tlet hasMore = false;\n\t\tlet truncated = false;\n\t\tlet totalCount: number | undefined;\n\t\tlet structuralIncompleteness = false;\n\t\tlet unkeyedPullRequest = 0;\n\t\tfor (const outcome of results) {\n\t\t\tif (outcome.status === 'rejected') {\n\t\t\t\tfailures.push(toCollectionScopeFailure({ providerId: this.id }, outcome.reason));\n\t\t\t\ttruncated = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst { key, result } = outcome.value;\n\t\t\tfor (const pr of result.values) {\n\t\t\t\tconst identity = getProviderPullRequestIdentity(pr) ?? `unkeyed:${unkeyedPullRequest++}`;\n\t\t\t\tif (!values.has(identity)) {\n\t\t\t\t\tvalues.set(identity, pr);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.hasMore) {\n\t\t\t\tif (result.cursor == null || result.cursor === '{}' || result.cursor === cursors[key]) {\n\t\t\t\t\ttruncated = true;\n\t\t\t\t\tstructuralIncompleteness = true;\n\t\t\t\t} else {\n\t\t\t\t\thasMore = true;\n\t\t\t\t\tnextCursors[key] = result.cursor;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.truncated) {\n\t\t\t\ttruncated = true;\n\t\t\t\tif (result.totalCount != null) {\n\t\t\t\t\ttotalCount = Math.max(totalCount ?? 0, result.totalCount);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tvalues: [...values.values()],\n\t\t\tpaging: {\n\t\t\t\tmore: hasMore,\n\t\t\t\tcursor: hasMore ? JSON.stringify({ type: 'cursor', cursors: nextCursors }) : '{}',\n\t\t\t\ttruncated: truncated || undefined,\n\t\t\t\t...(totalCount != null ? { totalCount: totalCount } : undefined),\n\t\t\t},\n\t\t\t...(failures.length || structuralIncompleteness\n\t\t\t\t? {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tcompleteness: 'partial' as const,\n\t\t\t\t\t\t\t...(failures.length ? { failures: failures } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined),\n\t\t};\n\t}\n\n\tprotected override async searchProviderMyIssues(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: GitHubRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<IssueShape[] | undefined> {\n\t\treturn (await this.searchProviderMyIssuesWithTruncation(session, repos, cancellation))?.values;\n\t}\n\n\t/**\n\t * GitHub's account-wide issue search pages authored/assigned/mentioned independently behind one composite\n\t * cursor. This variant preserves that cursor and the provider's 1,000-result search ceiling signal.\n\t *\n\t * `options.filters` selects which of those three searches run, so a caller can narrow the union to just its\n\t * own slice (e.g. `[Assignee]` ⇒ `assignee:@me`). Omitted keeps GitHub's own definition of \"mine\" (all three).\n\t */\n\tprotected override async searchProviderMyIssuesWithTruncation(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: GitHubRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchMyIssuesOptions,\n\t): Promise<{ values: IssueShape[]; truncated: boolean } | undefined> {\n\t\t// `includeAllAssignees` becomes `assignee:*`, which needs a scope to mean anything — with none it matches\n\t\t// millions of issues across all of GitHub rather than \"assigned to anyone in the user's world\". ANY scope\n\t\t// works (one repo, several, or an org), so this refuses only the genuinely unscoped read; the scoped\n\t\t// \"assigned to anyone over these repos\" request is served by `searchIssuesPage`.\n\t\tif ((repos == null || repos.length === 0) && options?.includeAllAssignees) {\n\t\t\tthrow new IntegrationReadUnavailableError(\n\t\t\t\tthis.name,\n\t\t\t\t'`includeAllAssignees` is not supported for account-wide issue reads; scope the read to repositories instead.',\n\t\t\t);\n\t\t}\n\n\t\treturn (await this.authenticationService.apis.github)?.searchMyIssues(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\trepos: repos?.map(r => `${r.owner}/${r.name}`),\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tincludeBody: true,\n\t\t\t\tincludeAllAssignees: options?.includeAllAssignees,\n\t\t\t\tcursor: options?.cursor,\n\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\tsort: options?.sort,\n\t\t\t\tcategories: options?.filters?.length\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tauthored: options.filters.includes(IssueFilter.Author),\n\t\t\t\t\t\t\tassigned: options.filters.includes(IssueFilter.Assignee),\n\t\t\t\t\t\t\tmentioned: options.filters.includes(IssueFilter.Mention),\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Filtered pull-request search over a repository/organization or explicit current-user relationship scope. The\n\t * API client owns criteria sanitizing, facet unioning, ordering, and the composite cursor that carries GitHub's\n\t * result-ceiling signal across pages.\n\t */\n\tprotected override async 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\tsummary?: boolean;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestSearchPage | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.searchPullRequestsPage(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\trepos: options.repos?.map(r => `${r.namespace}/${r.name}`),\n\t\t\t\torg: options.org,\n\t\t\t\tcriteria: options.criteria,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tcursor: options.cursor,\n\t\t\t\tpageSize: options.pageSize,\n\t\t\t\tsummary: options.summary,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * The filtered issue search: one GraphQL request per page, no forced relationship to the current user, and no\n\t * route through the SDK's repo-scoped read (whose over-limit recovery walk can spend up to 128 requests).\n\t *\n\t * The criteria → qualifier translation and the ordering guarantee live in the API client\n\t * (`GitHubApi.searchIssuesPage`), which is also where user input is sanitized so it can't inject a qualifier.\n\t */\n\tprotected override async 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\t\treturn (await this.authenticationService.apis.github)?.searchIssuesPage(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\t// `namespace` is the owner for GitHub, which is how a `repo:` qualifier names a repository.\n\t\t\t\trepos: options.repos?.map(r => `${r.namespace}/${r.name}`),\n\t\t\t\torg: options.org,\n\t\t\t\tcriteria: options.criteria,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tincludeBody: true,\n\t\t\t\tcursor: options.cursor,\n\t\t\t\tpageSize: options.pageSize,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Counts several scopes in ONE request. GitHub's `search` reports `issueCount` on a zero-node selection, so a\n\t * count preview costs no issue transfer — measured, 30 aliased counts are a single rate-limit point.\n\t */\n\tprotected override async countProviderIssues(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: IssueSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<(number | undefined)[] | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.countIssues(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tscopes.map(s => ({\n\t\t\t\trepos: s.repos?.map(r => `${r.namespace}/${r.name}`),\n\t\t\t\torg: s.org,\n\t\t\t\tcriteria: s.criteria,\n\t\t\t})),\n\t\t\t{ baseUrl: this.apiBaseUrlFor(session) },\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Resolves several issues by `(owner, repo, number)` by aliasing the point read rather than a search — see\n\t * {@link GitHubApi.getIssuesBatch} for why that distinction is the whole design — chunked into requests of up\n\t * to {@link issuesBatchChunkSize} coordinates, run with bounded concurrency. Settled per target already: a\n\t * coordinate whose alias fails on its own (e.g. an org enforcing SAML SSO the token isn't authorized for)\n\t * rejects only that slot, and a chunk that throws rejects only its own slots.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\treturn readChunked(\n\t\t\tcoordinates,\n\t\t\tissuesBatchChunkSize,\n\t\t\tchunkCoordinates =>\n\t\t\t\tgithub.getIssuesBatch(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tchunkCoordinates.map(c => ({ owner: c.owner, repo: c.repo, number: c.number })),\n\t\t\t\t\t{ baseUrl: this.apiBaseUrlFor(session), includeBody: true },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\tissue => issue,\n\t\t);\n\t}\n\n\t/**\n\t * Resolves several pull requests by `(owner, repo, number)` by aliasing the point read — see\n\t * {@link GitHubApi.getPullRequestsBatch} — chunked into requests of up to {@link pullRequestsBatchChunkSize}\n\t * coordinates, run with bounded concurrency. Rows take the same conversion as the account-wide list rows, so a\n\t * pull request reads the same whichever of the two returned it.\n\t *\n\t * A chunk that throws rejects only its own slots, so its sibling chunks still answer.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst currentAccount = options?.currentAccount;\n\t\treturn readChunked(\n\t\t\tcoordinates,\n\t\t\tpullRequestsBatchChunkSize,\n\t\t\tchunkCoordinates =>\n\t\t\t\tgithub.getPullRequestsBatch(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tchunkCoordinates.map(c => ({ owner: c.owner, repo: c.repo, number: c.number })),\n\t\t\t\t\t{ baseUrl: this.apiBaseUrlFor(session) },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t(pr): PullRequestShape | undefined =>\n\t\t\t\tpr != null\n\t\t\t\t\t? stampNativePullRequest(pr, { currentAccount: currentAccount, projection: 'batch' })\n\t\t\t\t\t: undefined,\n\t\t);\n\t}\n\n\t/**\n\t * The cheap check behind the batch issue read's etags: {@link getProviderIssuesBatch}'s chunks and failure\n\t * isolation over {@link GitHubApi.getIssuesEtagFieldsBatch}, which selects only an issue's change state plus the\n\t * selection of each of `options.etagIncludes`.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst etagIncludes = options.etagIncludes ?? [];\n\t\treturn readChunked(\n\t\t\tcoordinates,\n\t\t\tissuesBatchChunkSize,\n\t\t\tchunkCoordinates =>\n\t\t\t\tgithub.getIssuesEtagFieldsBatch(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tchunkCoordinates.map(c => ({ owner: c.owner, repo: c.repo, number: c.number })),\n\t\t\t\t\t{ baseUrl: this.apiBaseUrlFor(session), etagIncludes: etagIncludes },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t(node): IssueEtagFields | undefined => (node != null ? toIssueEtagFields(node, etagIncludes) : undefined),\n\t\t);\n\t}\n\n\t/**\n\t * The cheap check behind the batch pull request read's etags: {@link getProviderPullRequestsBatch}'s chunks and\n\t * failure isolation over {@link GitHubApi.getPullRequestsEtagFieldsBatch}, which selects only a pull request's\n\t * change state plus the selection of each of `options.etagIncludes`.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst etagIncludes = options.etagIncludes ?? [];\n\t\treturn readChunked(\n\t\t\tcoordinates,\n\t\t\tpullRequestsBatchChunkSize,\n\t\t\tchunkCoordinates =>\n\t\t\t\tgithub.getPullRequestsEtagFieldsBatch(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tchunkCoordinates.map(c => ({ owner: c.owner, repo: c.repo, number: c.number })),\n\t\t\t\t\t{ baseUrl: this.apiBaseUrlFor(session), etagIncludes: etagIncludes },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t(node): PullRequestEtagFields | undefined =>\n\t\t\t\tnode != null ? toPullRequestEtagFields(node, etagIncludes) : undefined,\n\t\t);\n\t}\n\n\t/**\n\t * Finds each branch's pull requests by aliasing a head-ref-name query per target — see\n\t * {@link GitHubApi.getPullRequestsForBranches} — chunked and converted exactly as\n\t * {@link getProviderPullRequestsBatch} is, with the same per-target and per-chunk failure isolation.\n\t *\n\t * That query matches the branch NAME across every fork and filters by head repository afterwards, so a name\n\t * many forks share (`main`, `patch-1`) comes back `truncated` whether or not anything it left out could match.\n\t * Only those targets take a second step: {@link GitHubApi.getPullRequestNumbersForBranch} asks REST, which\n\t * filters by head owner on the server, for the numbers that match, and any number the first step didn't return\n\t * is resolved through {@link getProviderPullRequestsBatch}, so its row is identical to the others. The answer\n\t * is the UNION of both steps: REST can't see a pull request from a since-deleted fork, which the first step still\n\t * matches by its owner, so a deleted fork's pull request on the first step's page is kept. One past that page\n\t * can't be found by either step, so on such a target a deleted fork's pull request may be missing from an\n\t * answer that isn't `truncated`. A target whose second step fails is rejected, never answered from the first\n\t * step alone.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\tconst baseUrl = this.apiBaseUrlFor(session);\n\t\tconst currentAccount = options.currentAccount;\n\t\tconst slots = await readChunked(\n\t\t\ttargets,\n\t\t\tpullRequestsBatchChunkSize,\n\t\t\tchunkTargets =>\n\t\t\t\tgithub.getPullRequestsForBranches(\n\t\t\t\t\tthis,\n\t\t\t\t\ttokenWithInfo,\n\t\t\t\t\tchunkTargets.map(t => ({ owner: t.owner, repo: t.repo, branch: t.branch, headOwner: t.headOwner })),\n\t\t\t\t\t{ baseUrl: baseUrl, limit: options.limit },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t(found): { pullRequests: PullRequestShape[]; truncated: boolean } => ({\n\t\t\t\tpullRequests: found.pullRequests.map(pr =>\n\t\t\t\t\tstampNativePullRequest(pr, { currentAccount: currentAccount, projection: 'batch' }),\n\t\t\t\t),\n\t\t\t\ttruncated: found.truncated,\n\t\t\t}),\n\t\t);\n\n\t\tconst ambiguous = slots.flatMap((slot, i) =>\n\t\t\tslot.status === 'fulfilled' && slot.value.truncated ? [{ index: i, found: slot.value.pullRequests }] : [],\n\t\t);\n\t\tif (!ambiguous.length) return slots;\n\n\t\tconst heads = await mapSettledBounded(ambiguous, providerFanOutConcurrency, async a => {\n\t\t\tconst t = targets[a.index];\n\t\t\tconst head = await github.getPullRequestNumbersForBranch(\n\t\t\t\tthis,\n\t\t\t\ttokenWithInfo,\n\t\t\t\tt.owner,\n\t\t\t\tt.repo,\n\t\t\t\tt.branch,\n\t\t\t\t{ baseUrl: baseUrl, headOwner: t.headOwner, limit: options.limit },\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst found = new Set(a.found.map(pr => pr.number));\n\t\t\treturn { numbers: head.numbers.filter(n => !found.has(n)), truncated: head.truncated };\n\t\t});\n\t\tconst extras = await resolveBranchPullRequests(\n\t\t\tambiguous.map(a => targets[a.index]),\n\t\t\theads,\n\t\t\tcoordinates =>\n\t\t\t\tthis.getProviderPullRequestsBatch(\n\t\t\t\t\tsession,\n\t\t\t\t\tcoordinates,\n\t\t\t\t\t{ currentAccount: currentAccount },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t);\n\n\t\tconst settled = [...slots];\n\t\tambiguous.forEach((a, i) => {\n\t\t\tconst extra = extras[i];\n\t\t\tif (extra.status === 'rejected') {\n\t\t\t\tsettled[a.index] = extra;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst pullRequests = [...a.found, ...extra.value.pullRequests].sort(\n\t\t\t\t(x, y) => y.updatedDate.getTime() - x.updatedDate.getTime(),\n\t\t\t);\n\t\t\tsettled[a.index] = {\n\t\t\t\tstatus: 'fulfilled',\n\t\t\t\tvalue: {\n\t\t\t\t\tpullRequests: pullRequests.slice(0, options.limit),\n\t\t\t\t\ttruncated: extra.value.truncated || pullRequests.length > options.limit,\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t\treturn settled;\n\t}\n\n\t/**\n\t * Counts several pull-request scopes in ONE request. Like {@link countProviderIssues}, GitHub's `search`\n\t * reports `issueCount` on a zero-node selection, so a count preview costs no pull-request transfer.\n\t */\n\tprotected override async countProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestCount[] | undefined> {\n\t\tconst counts = await (\n\t\t\tawait this.authenticationService.apis.github\n\t\t)?.countPullRequests(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tscopes.map(s => ({\n\t\t\t\trepos: s.repos?.map(r => `${r.namespace}/${r.name}`),\n\t\t\t\torg: s.org,\n\t\t\t\tcriteria: s.criteria,\n\t\t\t})),\n\t\t\t{ baseUrl: this.apiBaseUrlFor(session) },\n\t\t\tcancellation,\n\t\t);\n\t\t// `issueCount` is the search's own total, never a floor, so no slot is a lower bound.\n\t\treturn counts?.map(count => ({ count: count }));\n\t}\n\n\tprotected override async searchProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tsearchQuery: string,\n\t\trepos?: GitHubRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.searchPullRequests(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\tsearch: searchQuery,\n\t\t\t\trepos: repos?.map(r => `${r.owner}/${r.name}`),\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t...options,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Stack membership for every stacked pull request in the repository, keyed by pull request number.\n\t *\n\t * List surfaces get their pull requests from the shared providers API, whose type carries no stack\n\t * membership, so the `stack`/`stackEntry` fields selected on the native per-pull-request reads never\n\t * reach them. This fills that gap in a single request for the whole repository, rather than a\n\t * per-pull-request enrichment that would scale with the list.\n\t *\n\t * `undefined` means unavailable (not enrolled in the preview, or not connected) as distinct from an\n\t * empty map, which means the repository genuinely has no stacks.\n\t */\n\toverride async getStacksByPullRequestNumber(\n\t\towner: string,\n\t\trepo: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<Map<number, PullRequestStackInfo> | undefined> {\n\t\t// The shared read path: like `getSession()` it refreshes an expired session before use, but it throws a\n\t\t// failed refresh as the failure rather than answering as if not connected.\n\t\tconst session = await this.resolveReadSessionOrThrow(undefined, undefined);\n\t\tif (session == null) return undefined;\n\n\t\tconst stacks = await (\n\t\t\tawait this.authenticationService.apis.github\n\t\t)?.getRepositoryStacks(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\towner,\n\t\t\trepo,\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t\tif (stacks == null) return undefined;\n\n\t\tconst byNumber = new Map<number, PullRequestStackInfo>();\n\t\tfor (const stack of stacks) {\n\t\t\t// Defensive: this is a public-preview payload reaching us through an unvalidated cast, and a\n\t\t\t// malformed entry must cost its own stack's badges, not the whole panel.\n\t\t\tconst members = stack?.pull_requests;\n\t\t\tconst baseRef = stack?.base?.ref;\n\t\t\tif (members == null || baseRef == null) continue;\n\n\t\t\t// `pull_requests` is ordered bottom to top, and `position` is 1-based from the bottom.\n\t\t\tmembers.forEach((pr, i) => {\n\t\t\t\tbyNumber.set(pr.number, {\n\t\t\t\t\tid: stack.id,\n\t\t\t\t\tnumber: stack.number,\n\t\t\t\t\tsize: members.length,\n\t\t\t\t\tposition: i + 1,\n\t\t\t\t\tbaseRef: baseRef,\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\treturn byNumber;\n\t}\n\n\tprotected override async mergeProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tpr: PullRequest,\n\t\toptions?: {\n\t\t\tmergeMethod?: PullRequestMergeMethod;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tconst id = pr.nodeId;\n\t\tconst headRefSha = pr.refs?.head?.sha;\n\t\tif (id == null || headRefSha == null) return false;\n\n\t\tconst api = await this.authenticationService.apis.github;\n\n\t\t// GitHub rejects stacked pull requests on the legacy merge mutation, so they take the\n\t\t// asynchronous merge instead — which also lands every layer below this one.\n\t\tif (pr.stack != null) {\n\t\t\treturn (\n\t\t\t\t(await api?.mergeStackedPullRequest(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tpr.repository.owner,\n\t\t\t\t\tpr.repository.repo,\n\t\t\t\t\tNumber(pr.id),\n\t\t\t\t\theadRefSha,\n\t\t\t\t\t{\n\t\t\t\t\t\tmergeMethod: options?.mergeMethod,\n\t\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t\t},\n\t\t\t\t\tcancellation,\n\t\t\t\t)) ?? false\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\tapi?.mergePullRequest(\n\t\t\t\tthis,\n\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\tid,\n\t\t\t\theadRefSha,\n\t\t\t\t{\n\t\t\t\t\tmergeMethod: options?.mergeMethod,\n\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t},\n\t\t\t\tcancellation,\n\t\t\t) ?? false\n\t\t);\n\t}\n\n\tprotected override async getProviderCurrentAccount(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { avatarSize?: number },\n\t): Promise<Account | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getCurrentAccount(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override getProviderPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {\n\t\treturn getGitHubPullRequestIdentityFromMaybeUrl(search, this.id);\n\t}\n}\n\nexport class GitHubIntegration extends GitHubIntegrationBase<GitCloudHostIntegrationId.GitHub> {\n\treadonly authProvider = authProvider;\n\treadonly id = GitCloudHostIntegrationId.GitHub;\n\tprotected readonly key = this.id;\n\treadonly name: string = 'GitHub';\n\tget domain(): string {\n\t\treturn metadata.domain;\n\t}\n\n\tprotected override apiBaseUrlFor(_session: ProviderAuthenticationSession): string | undefined {\n\t\t// Undefined on purpose, NOT 'https://api.github.com'. `@gitkraken/provider-apis` treats this value as an\n\t\t// *enterprise* base and derives both endpoints from it by appending GitHub Enterprise's paths:\n\t\t// `getRESTBaseUrl` appends `/api/v3` and `getGraphQLEndpoint` appends `/api/graphql` (githubHelpers.ts).\n\t\t// Handing it the cloud host therefore built `https://api.github.com/api/graphql`, which GitHub answers\n\t\t// 404 — every cloud GraphQL read (orgs, repos, PR/issue search) failed as `not-found`. Omitting it is\n\t\t// what selects the cloud endpoints (`GITHUB_API_URL` / `GITHUB_GRAPHQL_API_URL`), so cloud must pass\n\t\t// nothing and only GHE passes its instance base.\n\t\treturn undefined;\n\t}\n\n\toverride access(): Promise<boolean> {\n\t\t// Always allow GitHub cloud integration access\n\t\treturn Promise.resolve(true);\n\t}\n\n\t// This is a special case for GitHub because we use VSCode's GitHub session, and it can be disconnected\n\t// outside of the extension.\n\toverride async refresh(): Promise<void> {\n\t\tconst authProvider = await this.authenticationService.get(this.authProvider.id);\n\t\tconst session = await authProvider.getSession(this.authProviderDescriptor);\n\t\tif (session == null && this.maybeConnected) {\n\t\t\tvoid this.disconnect({ silent: true });\n\t\t} else {\n\t\t\tvoid this.resyncSessionIfTokenChanged(session?.accessToken);\n\t\t}\n\t}\n}\n\nexport class GitHubEnterpriseIntegration extends GitHubIntegrationBase<GitSelfManagedHostIntegrationId.CloudGitHubEnterprise> {\n\treadonly authProvider = cloudEnterpriseAuthProvider;\n\treadonly id = GitSelfManagedHostIntegrationId.CloudGitHubEnterprise;\n\tprotected readonly key;\n\treadonly name = 'GitHub Enterprise';\n\tget domain(): string {\n\t\treturn this._domain;\n\t}\n\n\tprotected override apiBaseUrlFor(session: ProviderAuthenticationSession): string {\n\t\treturn this.getSelfManagedApiBaseUrl(session);\n\t}\n\n\tconstructor(\n\t\tctx: IntegrationServiceContext,\n\t\tauthenticationService: IntegrationAuthenticationService,\n\t\tgetProvidersApi: () => Promise<ProvidersApi>,\n\t\tdidChangeConnection: Emitter<IntegrationConnectionChangeEvent>,\n\t\tprivate readonly _domain: string,\n\t) {\n\t\tsuper(ctx, authenticationService, getProvidersApi, didChangeConnection);\n\t\tthis.key = `${this.id}:${this.domain}` as const;\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"github.js","names":[],"sources":["../../../../../plus/integrations/src/providers/github.ts"],"sourcesContent":["import { gitHubPullRequestRelationshipQualifiers } from '@gitlens/git-github/api/pullRequestSearchQuery.js';\nimport type { GitHubIssueEtagNode, GitHubPullRequestEtagNode } from '@gitlens/git-github/models.js';\nimport {\n\tfromGitHubIssueOrPullRequestState,\n\tfromGitHubPullRequestMergeableState,\n\tfromGitHubPullRequestReviewDecision,\n\tfromGitHubPullRequestStatusCheckRollupState,\n} from '@gitlens/git-github/models.js';\nimport type { Account, UnidentifiedAuthor } from '@gitlens/git/models/author.js';\nimport type { DefaultBranch } from '@gitlens/git/models/defaultBranch.js';\nimport type { Issue, IssueSearchCriteria, IssueShape } from '@gitlens/git/models/issue.js';\nimport type { IssueOrPullRequest } from '@gitlens/git/models/issueOrPullRequest.js';\nimport type {\n\tPullRequest,\n\tPullRequestMergeMethod,\n\tPullRequestSearchCriteria,\n\tPullRequestShape,\n\tPullRequestStackInfo,\n\tPullRequestStackLayer,\n\tPullRequestStackLayers,\n\tPullRequestState,\n\tPullRequestStateFilter,\n} from '@gitlens/git/models/pullRequest.js';\nimport type { RepositoryMetadata } from '@gitlens/git/models/repositoryMetadata.js';\nimport type { RepositoryDescriptor } from '@gitlens/git/models/resourceDescriptor.js';\nimport { getGitHubNoReplyAddressParts } from '@gitlens/git/remotes/github.js';\nimport type { PullRequestUrlIdentity } from '@gitlens/git/utils/pullRequest.utils.js';\nimport { chunk } from '@gitlens/utils/array.js';\nimport type { Emitter } from '@gitlens/utils/event.js';\nimport { batch, mapBounded, mapSettledBounded } from '@gitlens/utils/promise.js';\nimport type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';\nimport type { IntegrationAuthenticationService } from '../authentication/integrationAuthenticationService.js';\nimport type { ProviderAuthenticationSession } from '../authentication/models.js';\nimport { toTokenWithInfo } from '../authentication/models.js';\nimport type { ProviderRefusal } from '../collectionMetadata.js';\nimport { toCollectionScopeFailure } from '../collectionMetadata.js';\nimport { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId, providerFanOutConcurrency } from '../constants.js';\nimport type { IntegrationServiceContext } from '../context.js';\nimport { AuthenticationError, IntegrationReadUnavailableError, RequestNotFoundError } from '../errors.js';\nimport type { IntegrationConnectionChangeEvent } from '../integrationService.js';\nimport type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';\nimport { GitHostIntegration } from '../models/gitHostIntegration.js';\nimport type {\n\tIssueEtagFields,\n\tIssueEtagInclude,\n\tProviderIssueSearchPage,\n\tProviderPullRequestCount,\n\tProviderPullRequestSearchPage,\n\tPullRequestEtagFields,\n\tPullRequestEtagInclude,\n\tSearchMyIssuesOptions,\n} from '../models/integration.js';\nimport type { ProviderWarningCause } from '../results.js';\nimport type { GitHubIntegrationIds } from './github/github.utils.js';\nimport { getGitHubPullRequestIdentityFromMaybeUrl } from './github/github.utils.js';\nimport type {\n\tProviderApiPagedResult,\n\tProviderHierarchyResult,\n\tProviderOrganization,\n\tProviderRepoInput,\n\tProviderRepository,\n} from './models.js';\nimport {\n\tgetProviderPullRequestIdentity,\n\tIssueFilter,\n\tprovidersMetadata,\n\tPullRequestFilter,\n\tstampNativePullRequest,\n} from './models.js';\nimport type { ProvidersApi } from './providersApi.js';\nimport { resolveBranchPullRequests } from './utils/providerPaging.js';\n\ntype GitHubPullRequestFacetCursor = Record<string, string>;\n\nfunction toPullRequestFacetCursor(value: unknown): GitHubPullRequestFacetCursor {\n\tif (value == null || typeof value !== 'object' || Array.isArray(value)) return {};\n\n\treturn Object.fromEntries(\n\t\tObject.entries(value).filter(\n\t\t\t([key, cursor]) => key.length !== 0 && typeof cursor === 'string' && cursor.length !== 0,\n\t\t),\n\t);\n}\n\nfunction parsePullRequestFacetCursor(cursor: string | undefined): GitHubPullRequestFacetCursor {\n\tif (!cursor) return {};\n\n\ttry {\n\t\tconst parsed = JSON.parse(cursor) as unknown;\n\t\tif (parsed != null && typeof parsed === 'object' && !Array.isArray(parsed) && 'cursors' in parsed) {\n\t\t\tconst wrapped = parsed as { type?: unknown; cursors?: unknown };\n\t\t\tif (wrapped.type === 'cursor') {\n\t\t\t\treturn toPullRequestFacetCursor(wrapped.cursors);\n\t\t\t}\n\t\t}\n\n\t\treturn toPullRequestFacetCursor(parsed);\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nconst metadata = providersMetadata[GitCloudHostIntegrationId.GitHub];\nconst authProvider: IntegrationAuthenticationProviderDescriptor = Object.freeze({\n\tid: metadata.id,\n\tscopes: metadata.scopes,\n});\n\nconst cloudEnterpriseMetadata = providersMetadata[GitSelfManagedHostIntegrationId.CloudGitHubEnterprise];\nconst cloudEnterpriseAuthProvider: IntegrationAuthenticationProviderDescriptor = Object.freeze({\n\tid: cloudEnterpriseMetadata.id,\n\tscopes: cloudEnterpriseMetadata.scopes,\n});\n\nexport type GitHubRepositoryDescriptor = RepositoryDescriptor;\n\n/** How many per-login SSH signing-key lookups to run concurrently, to avoid a request burst that trips rate limiting. */\nconst sshSigningKeyResolveBatchSize = 10;\n\n// One aliased document costs about the same as a single read up to 25 targets; past that, latency climbs.\nconst pullRequestsBatchChunkSize = 25;\n\n/**\n * How many coordinates go into one aliased issue request.\n *\n * Measured rather than inherited from `issueCountChunkSize`, since that one rests on a zero-node selection and\n * this carries the full issue projection per alias. Against the live API on all-resolving coordinates: 10 took\n * 875ms, 25 took 890ms — so up to 25 is effectively free — 50 took 1.3s, and 75 took 2.7s. No complexity refusal\n * appeared up to 100.\n *\n * 25 is where latency is still flat, with room before it degrades. It also puts any realistic correlation batch\n * in ONE request, which is the whole point of the read.\n */\nconst issuesBatchChunkSize = 25;\n\n/**\n * Runs an aliased batch read over `items` in chunks of `chunkSize`, with bounded concurrency, converting each\n * fulfilled slot with `map`. Settled per target throughout: a chunk that throws rejects only its own slots, and a\n * slot whose conversion throws rejects only itself, so one bad row never takes its chunk's siblings down with it.\n */\nasync function readChunked<T, V, R>(\n\titems: readonly T[],\n\tchunkSize: number,\n\tread: (chunk: T[]) => Promise<PromiseSettledResult<V>[]>,\n\tmap: (value: V) => R,\n): Promise<PromiseSettledResult<R>[]> {\n\tconst settledChunks = await mapBounded(\n\t\tchunk([...items], chunkSize),\n\t\tproviderFanOutConcurrency,\n\t\tasync (chunkItems): Promise<PromiseSettledResult<R>[]> => {\n\t\t\tlet slots: PromiseSettledResult<V>[];\n\t\t\ttry {\n\t\t\t\tslots = await read(chunkItems);\n\t\t\t} catch (ex) {\n\t\t\t\treturn chunkItems.map(() => ({ status: 'rejected', reason: ex }));\n\t\t\t}\n\n\t\t\treturn slots.map((slot): PromiseSettledResult<R> => {\n\t\t\t\tif (slot.status === 'rejected') return slot;\n\n\t\t\t\ttry {\n\t\t\t\t\treturn { status: 'fulfilled', value: map(slot.value) };\n\t\t\t\t} catch (ex) {\n\t\t\t\t\treturn { status: 'rejected', reason: ex };\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t);\n\treturn settledChunks.flat();\n}\n\n/**\n * A cheap etag read's pull request, as the fields its full row's etag reads, through `fromGitHubPullRequest`'s own\n * conversions, so a cheap check and a full read of the same pull request compute the same etag.\n */\nfunction toPullRequestEtagFields(\n\tnode: GitHubPullRequestEtagNode,\n\tetagIncludes: readonly PullRequestEtagInclude[],\n): PullRequestEtagFields {\n\tconst fields: PullRequestEtagFields = {\n\t\tstate: fromGitHubIssueOrPullRequestState(node.state),\n\t\tisDraft: node.isDraft,\n\t\tupdatedDate: new Date(node.updatedAt),\n\t\theadSha: node.headRefOid,\n\t};\n\n\tif (etagIncludes.includes('mergeable')) {\n\t\tfields.mergeableState =\n\t\t\tnode.mergeable != null ? fromGitHubPullRequestMergeableState(node.mergeable) : undefined;\n\t}\n\n\tif (etagIncludes.includes('reviewDecision')) {\n\t\t// GitHub's `null` (the repository requires no review) is no decision, even while a review is requested.\n\t\tfields.reviewDecision =\n\t\t\tnode.reviewDecision != null ? fromGitHubPullRequestReviewDecision(node.reviewDecision) : undefined;\n\t}\n\n\tif (etagIncludes.includes('checks')) {\n\t\tfields.statusCheckRollupState = fromGitHubPullRequestStatusCheckRollupState(\n\t\t\tnode.commits?.nodes?.[0]?.commit.statusCheckRollup?.state,\n\t\t);\n\t}\n\n\treturn fields;\n}\n\n/** A cheap etag read's issue, as the fields its full row's etag reads, through `fromGitHubIssue`'s own conversions. */\nfunction toIssueEtagFields(node: GitHubIssueEtagNode, etagIncludes: readonly IssueEtagInclude[]): IssueEtagFields {\n\tconst fields: IssueEtagFields = {\n\t\tstate: fromGitHubIssueOrPullRequestState(node.state),\n\t\tupdatedDate: new Date(node.updatedAt),\n\t};\n\n\tif (etagIncludes.includes('reactions')) {\n\t\tfields.thumbsUpCount = node.reactions?.totalCount;\n\t}\n\n\treturn fields;\n}\n\nabstract class GitHubIntegrationBase<ID extends GitHubIntegrationIds> extends GitHostIntegration<\n\tID,\n\tGitHubRepositoryDescriptor\n> {\n\t/**\n\t * Base URL handed to `@gitkraken/provider-apis`, which derives BOTH the REST and the GraphQL endpoint from it\n\t * by appending GitHub Enterprise's paths. Only a GHE instance base belongs here; cloud passes `undefined`,\n\t * the sole value that selects the cloud endpoints (see the cloud subclass).\n\t */\n\tprotected abstract apiBaseUrlFor(session: ProviderAuthenticationSession): string | undefined;\n\n\tprotected override async getProviderAccountForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\trev: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | UnidentifiedAuthor | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getAccountForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderAccountForEmail(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\temail: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t},\n\t): Promise<Account | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getAccountForEmail(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\temail,\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderSshSigningKeysForEmails(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\temails: string[],\n\t): Promise<Map<string, string[]>> {\n\t\tconst result = new Map<string, string[]>();\n\n\t\tconst api = await this.authenticationService.apis.github;\n\t\tif (api == null) return result;\n\n\t\tconst token = toTokenWithInfo(this.id, session);\n\n\t\t// Resolve each email to a login: GitHub noreply addresses encode it locally; the rest are resolved in a single\n\t\t// batched GraphQL request rather than one round-trip per email.\n\t\tconst loginByEmail = new Map<string, string>();\n\t\tconst toResolve: string[] = [];\n\t\tfor (const email of emails) {\n\t\t\tconst login = getGitHubNoReplyAddressParts(email)?.login;\n\t\t\tif (login != null) {\n\t\t\t\tloginByEmail.set(email.toLowerCase(), login);\n\t\t\t} else {\n\t\t\t\ttoResolve.push(email);\n\t\t\t}\n\t\t}\n\n\t\tif (toResolve.length) {\n\t\t\tconst resolved = await api.getAccountsForEmails(this, token, toResolve, {\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t});\n\t\t\tfor (const [emailLower, login] of resolved) {\n\t\t\t\tloginByEmail.set(emailLower, login);\n\t\t\t}\n\t\t}\n\n\t\t// Fetch signing keys once per distinct login (REST has no batch endpoint), in bounded batches rather than firing\n\t\t// all lookups at once, to avoid a request burst that could trip secondary rate limiting. Then map keys to each email.\n\t\tconst keysByLogin = new Map<string, string[]>();\n\t\tawait batch([...new Set(loginByEmail.values())], sshSigningKeyResolveBatchSize, async login => {\n\t\t\tconst keys = await api.getUserSshSigningKeys(this, token, login, { baseUrl: this.apiBaseUrlFor(session) });\n\t\t\tkeysByLogin.set(\n\t\t\t\tlogin,\n\t\t\t\tkeys.map(k => k.key),\n\t\t\t);\n\t\t});\n\n\t\tfor (const [emailLower, login] of loginByEmail) {\n\t\t\tresult.set(emailLower, keysByLogin.get(login) ?? []);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprotected override async getProviderDefaultBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t): Promise<DefaultBranch | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getDefaultBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderLinkedIssueOrPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\t{ id }: { id: string; key: string },\n\t): Promise<IssueOrPullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getIssueOrPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tNumber(id),\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderIssue(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<Issue | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getIssue(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tNumber(id),\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tincludeBody: true,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\tid: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getPullRequest(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tparseInt(id, 10),\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForBranch(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\tbranch: string,\n\t\toptions?: {\n\t\t\tavatarSize?: number;\n\t\t\tinclude?: PullRequestState[];\n\t\t},\n\t): Promise<PullRequest | undefined> {\n\t\tconst { include, ...opts } = options ?? {};\n\n\t\tconst toGitHubPullRequestState = (await import(/* webpackChunkName: \"integrations\" */ './github/models.js'))\n\t\t\t.toGitHubPullRequestState;\n\t\treturn (await this.authenticationService.apis.github)?.getPullRequestForBranch(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\tbranch,\n\t\t\t{\n\t\t\t\t...opts,\n\t\t\t\tinclude: include?.map(s => toGitHubPullRequestState(s)),\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderPullRequestForCommit(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\trev: string,\n\t): Promise<PullRequest | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getPullRequestForCommit(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\trev,\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override async getProviderRepositoryMetadata(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepo: GitHubRepositoryDescriptor,\n\t\tcancellation?: AbortSignal,\n\t): Promise<RepositoryMetadata | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getRepositoryMetadata(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\trepo.owner,\n\t\t\trepo.name,\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprotected override async getProviderOrganizationsForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t): Promise<ProviderHierarchyResult<ProviderOrganization> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\tconst result = await api.getGitHubOrgsForCurrentUser(toTokenWithInfo(this.id, session), {\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t});\n\t\tconst webUrl =\n\t\t\tthis.id === GitSelfManagedHostIntegrationId.CloudGitHubEnterprise\n\t\t\t\t? this.getSelfManagedInstallationUrl(session)\n\t\t\t\t: `https://${this.domain}`;\n\t\treturn {\n\t\t\tvalues: result.values.map(o => ({\n\t\t\t\tid: o.id,\n\t\t\t\tproviderId: this.id,\n\t\t\t\tname: o.username,\n\t\t\t\turl: `${webUrl}/${o.username}`,\n\t\t\t})),\n\t\t\t...(result.truncated ? { truncated: true } : {}),\n\t\t\t...(result.metadata != null ? { metadata: result.metadata } : {}),\n\t\t};\n\t}\n\n\tprotected override async getProviderRepositoriesForOrg(\n\t\tsession: ProviderAuthenticationSession,\n\t\torg: string,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\treturn api.getReposForOrg(toTokenWithInfo(this.id, session), org, {\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\tcursor: options?.cursor,\n\t\t});\n\t}\n\n\tprotected override async getProviderRepositoriesForUser(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { cursor?: string },\n\t): Promise<ProviderHierarchyResult<ProviderRepository> | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\t// `/user/repos` with the full affiliation set: the user's own repos, collaborations, and org-member\n\t\t// repos — matching gkcli's org-less `provider repos github` walk (not every repo of every org).\n\t\treturn api.getReposForCurrentUser(toTokenWithInfo(this.id, session), {\n\t\t\taffiliations: ['owner', 'collaborator', 'organization_member'],\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\tcursor: options?.cursor,\n\t\t});\n\t}\n\n\tpublic override async getRepoInfo(repo: {\n\t\towner: string;\n\t\tname: string;\n\t\tproject?: string;\n\t\tconnectionId?: string;\n\t}): Promise<ProviderRepository | undefined> {\n\t\tconst api = await this.getProvidersApi();\n\t\t// `connectionId` targets a specific account (multi-account); omitted reads the primary.\n\t\tconst session = await this.resolveReadSessionOrThrow(repo.connectionId, undefined);\n\t\tif (session == null) return undefined;\n\n\t\t// `apiBaseUrlFor` is undefined for cloud (which is what selects the cloud endpoints) and the GHE instance base\n\t\t// for enterprise (inherited override).\n\t\ttry {\n\t\t\treturn await api.getRepo(toTokenWithInfo(this.id, session), repo.owner, repo.name, repo.project, {\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t});\n\t\t} catch (ex) {\n\t\t\tif (!(ex instanceof RequestNotFoundError)) throw ex;\n\n\t\t\t// GraphQL answers a repository its organization hides from this OAuth app (OAuth App access restrictions)\n\t\t\t// exactly as it answers a missing one, so a miss is confirmed over REST, which refuses such a repository\n\t\t\t// with a `403` saying why. Only that refusal replaces the miss: a REST read that cannot confirm either way\n\t\t\t// leaves the answer GraphQL gave.\n\t\t\tconst github = await this.authenticationService.apis.github;\n\t\t\ttry {\n\t\t\t\tawait github?.getRepositoryAccess(this, toTokenWithInfo(this.id, session), repo.owner, repo.name, {\n\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t});\n\t\t\t} catch (refusal) {\n\t\t\t\tif (refusal instanceof AuthenticationError) throw refusal;\n\t\t\t}\n\t\t\tthrow ex;\n\t\t}\n\t}\n\n\t/**\n\t * The profile request that proves the credential; see `IntegrationBase.validateCredential`. Silent: a refusal\n\t * here is rethrown to the read that asked, which reports it as it reports its own failure (or, for\n\t * `resolveRepository`, as the resolution's warning), so the check must not raise a prompt of its own.\n\t */\n\tprotected override async validateCredential(session: ProviderAuthenticationSession): Promise<void> {\n\t\tconst github = await this.authenticationService.apis.github;\n\t\tconst account = await github?.getCurrentAccount(this, toTokenWithInfo(this.id, session), {\n\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\tsilent: true,\n\t\t});\n\t\tif (account == null) throw new Error('GitHub did not confirm the credential');\n\t}\n\n\t/**\n\t * Names a confirmed credential's refusal from what GitHub said. A `403` whose explanation cites OAuth App access\n\t * restrictions is an organization that has not approved the OAuth app this token belongs to; its remedy page is\n\t * that app's page in the user's authorized apps, where they request an organization's approval, addressed by the\n\t * client id GitHub reports on the refusal. Any other refusal is left unnamed, so the warning keeps GitHub's own\n\t * words.\n\t */\n\tprotected override describeRefusal(\n\t\tsession: ProviderAuthenticationSession,\n\t\trefusal: ProviderRefusal,\n\t): ProviderWarningCause | undefined {\n\t\tif (refusal.status !== 403 || !/\\bOAuth App access restrictions\\b/i.test(refusal.detail ?? '')) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst webUrl =\n\t\t\tthis.id === GitSelfManagedHostIntegrationId.CloudGitHubEnterprise\n\t\t\t\t? this.getSelfManagedInstallationUrl(session)\n\t\t\t\t: `https://${this.domain}`;\n\t\treturn {\n\t\t\treason: 'oauth-app-not-allowed',\n\t\t\t...(refusal.oauthClientId != null\n\t\t\t\t? {\n\t\t\t\t\t\tremedyUrl: `${webUrl}/settings/connections/applications/${encodeURIComponent(refusal.oauthClientId)}`,\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\tprotected override async searchProviderMyPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: GitHubRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchMyPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.searchMyPullRequests(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\trepos: repos?.map(r => `${r.owner}/${r.name}`),\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tsilent: options?.silent,\n\t\t\t\tstate: options?.state,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\tprotected override async 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<PullRequest> | undefined> {\n\t\tconst explicitFilters = options?.filters?.length ? [...new Set(options.filters)] : undefined;\n\t\t// Every account-wide read goes through our own facet search — there is deliberately no SDK\n\t\t// `getPullRequestsForUser` fallback. It could express neither a state set, nor exact relationships (its\n\t\t// `involves:` is a different question), nor the full projection, so which reads it could serve depended on\n\t\t// the options, and the two routes disagreed on more than they had to: only this one applies the Launchpad\n\t\t// ignored/included repository and organization qualifiers, so the same read returned different pull\n\t\t// requests depending on options that were supposed to affect only projection or relationship. With no\n\t\t// state and no filters this emits a single facet with no relationship qualifier, which is GitHub's own\n\t\t// `involves:@me` and `is:open` default — the same question the fallback asked, now on one route.\n\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst requestedStates: PullRequestStateFilter[] =\n\t\t\toptions?.state != null && options.state.length > 0 ? [...new Set(options.state)] : ['open'];\n\t\tconst facets =\n\t\t\texplicitFilters?.length != null\n\t\t\t\t? requestedStates.flatMap(state =>\n\t\t\t\t\t\texplicitFilters.map(filter => ({\n\t\t\t\t\t\t\tkey: `${state}:${filter}`,\n\t\t\t\t\t\t\tstate: state,\n\t\t\t\t\t\t\tsearch: gitHubPullRequestRelationshipQualifiers[filter],\n\t\t\t\t\t\t})),\n\t\t\t\t\t)\n\t\t\t\t: requestedStates.flatMap(state => [\n\t\t\t\t\t\t{ key: state, state: state, search: undefined },\n\t\t\t\t\t\t...(options?.includeReviewRequested === true\n\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tkey: `${state}:${PullRequestFilter.ReviewRequested}`,\n\t\t\t\t\t\t\t\t\t\tstate: state,\n\t\t\t\t\t\t\t\t\t\tsearch: gitHubPullRequestRelationshipQualifiers[\n\t\t\t\t\t\t\t\t\t\t\tPullRequestFilter.ReviewRequested\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t: []),\n\t\t\t\t\t]);\n\t\tconst cursors = parsePullRequestFacetCursor(options?.cursor);\n\t\tconst hasResumableFacetCursor = Object.keys(cursors).length !== 0;\n\t\tconst facetsWithCursor = facets.filter(facet => cursors[facet.key] != null);\n\t\t// The first call has no cursor, so query every requested state. A continuation only happens after a\n\t\t// prior page reported `more:true`, whose bundle carries a cursor for each facet still in flight;\n\t\t// facets absent from the bundle are exhausted, so re-querying them from scratch would refetch the\n\t\t// same PRs (duplicated by the dedup-free sweep) and waste an API call per page. Query only the\n\t\t// states that still have a cursor, but degrade a malformed/empty cursor bundle, or one that doesn't\n\t\t// apply to the current requested states, to the first page rather than returning an empty page.\n\t\tconst facetsToQuery =\n\t\t\toptions?.cursor != null && hasResumableFacetCursor && facetsWithCursor.length !== 0\n\t\t\t\t? facetsWithCursor\n\t\t\t\t: facets;\n\t\tconst results = await Promise.allSettled(\n\t\t\tfacetsToQuery.map(async facet => ({\n\t\t\t\tkey: facet.key,\n\t\t\t\tresult: await github.searchMyPullRequestsPage(this, toTokenWithInfo(this.id, session), {\n\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t\tstate: facet.state,\n\t\t\t\t\tcursor: cursors[facet.key],\n\t\t\t\t\tsummary: options?.summary,\n\t\t\t\t\t...(facet.search != null ? { search: facet.search, includeDefaultInvolvement: false } : undefined),\n\t\t\t\t}),\n\t\t\t})),\n\t\t);\n\t\tif (results.every(result => result.status === 'rejected')) {\n\t\t\tconst first = results[0];\n\t\t\tif (first?.status === 'rejected') throw first.reason;\n\t\t}\n\n\t\tconst values = new Map<string, PullRequest>();\n\t\tconst nextCursors: GitHubPullRequestFacetCursor = {};\n\t\tconst failures = [];\n\t\tlet hasMore = false;\n\t\tlet truncated = false;\n\t\tlet totalCount: number | undefined;\n\t\tlet structuralIncompleteness = false;\n\t\tlet unkeyedPullRequest = 0;\n\t\tfor (const outcome of results) {\n\t\t\tif (outcome.status === 'rejected') {\n\t\t\t\tfailures.push(toCollectionScopeFailure({ providerId: this.id }, outcome.reason));\n\t\t\t\ttruncated = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst { key, result } = outcome.value;\n\t\t\tfor (const pr of result.values) {\n\t\t\t\tconst identity = getProviderPullRequestIdentity(pr) ?? `unkeyed:${unkeyedPullRequest++}`;\n\t\t\t\tif (!values.has(identity)) {\n\t\t\t\t\tvalues.set(identity, pr);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.hasMore) {\n\t\t\t\tif (result.cursor == null || result.cursor === '{}' || result.cursor === cursors[key]) {\n\t\t\t\t\ttruncated = true;\n\t\t\t\t\tstructuralIncompleteness = true;\n\t\t\t\t} else {\n\t\t\t\t\thasMore = true;\n\t\t\t\t\tnextCursors[key] = result.cursor;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.truncated) {\n\t\t\t\ttruncated = true;\n\t\t\t\tif (result.totalCount != null) {\n\t\t\t\t\ttotalCount = Math.max(totalCount ?? 0, result.totalCount);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tvalues: [...values.values()],\n\t\t\tpaging: {\n\t\t\t\tmore: hasMore,\n\t\t\t\tcursor: hasMore ? JSON.stringify({ type: 'cursor', cursors: nextCursors }) : '{}',\n\t\t\t\ttruncated: truncated || undefined,\n\t\t\t\t...(totalCount != null ? { totalCount: totalCount } : undefined),\n\t\t\t},\n\t\t\t...(failures.length || structuralIncompleteness\n\t\t\t\t? {\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tcompleteness: 'partial' as const,\n\t\t\t\t\t\t\t...(failures.length ? { failures: failures } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined),\n\t\t};\n\t}\n\n\tprotected override async searchProviderMyIssues(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: GitHubRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<IssueShape[] | undefined> {\n\t\treturn (await this.searchProviderMyIssuesWithTruncation(session, repos, cancellation))?.values;\n\t}\n\n\t/**\n\t * GitHub's account-wide issue search pages authored/assigned/mentioned independently behind one composite\n\t * cursor. This variant preserves that cursor and the provider's 1,000-result search ceiling signal.\n\t *\n\t * `options.filters` selects which of those three searches run, so a caller can narrow the union to just its\n\t * own slice (e.g. `[Assignee]` ⇒ `assignee:@me`). Omitted keeps GitHub's own definition of \"mine\" (all three).\n\t */\n\tprotected override async searchProviderMyIssuesWithTruncation(\n\t\tsession: ProviderAuthenticationSession,\n\t\trepos?: GitHubRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchMyIssuesOptions,\n\t): Promise<{ values: IssueShape[]; truncated: boolean } | undefined> {\n\t\t// `includeAllAssignees` becomes `assignee:*`, which needs a scope to mean anything — with none it matches\n\t\t// millions of issues across all of GitHub rather than \"assigned to anyone in the user's world\". ANY scope\n\t\t// works (one repo, several, or an org), so this refuses only the genuinely unscoped read; the scoped\n\t\t// \"assigned to anyone over these repos\" request is served by `searchIssuesPage`.\n\t\tif ((repos == null || repos.length === 0) && options?.includeAllAssignees) {\n\t\t\tthrow new IntegrationReadUnavailableError(\n\t\t\t\tthis.name,\n\t\t\t\t'`includeAllAssignees` is not supported for account-wide issue reads; scope the read to repositories instead.',\n\t\t\t);\n\t\t}\n\n\t\treturn (await this.authenticationService.apis.github)?.searchMyIssues(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\trepos: repos?.map(r => `${r.owner}/${r.name}`),\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tincludeBody: true,\n\t\t\t\tincludeAllAssignees: options?.includeAllAssignees,\n\t\t\t\tcursor: options?.cursor,\n\t\t\t\tpageSize: options?.pageSize,\n\t\t\t\tsort: options?.sort,\n\t\t\t\tcategories: options?.filters?.length\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tauthored: options.filters.includes(IssueFilter.Author),\n\t\t\t\t\t\t\tassigned: options.filters.includes(IssueFilter.Assignee),\n\t\t\t\t\t\t\tmentioned: options.filters.includes(IssueFilter.Mention),\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Filtered pull-request search over a repository/organization or explicit current-user relationship scope. The\n\t * API client owns criteria sanitizing, facet unioning, ordering, and the composite cursor that carries GitHub's\n\t * result-ceiling signal across pages.\n\t */\n\tprotected override async 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\tsummary?: boolean;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestSearchPage | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.searchPullRequestsPage(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\trepos: options.repos?.map(r => `${r.namespace}/${r.name}`),\n\t\t\t\torg: options.org,\n\t\t\t\tcriteria: options.criteria,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tcursor: options.cursor,\n\t\t\t\tpageSize: options.pageSize,\n\t\t\t\tsummary: options.summary,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * The filtered issue search: one GraphQL request per page, no forced relationship to the current user, and no\n\t * route through the SDK's repo-scoped read (whose over-limit recovery walk can spend up to 128 requests).\n\t *\n\t * The criteria → qualifier translation and the ordering guarantee live in the API client\n\t * (`GitHubApi.searchIssuesPage`), which is also where user input is sanitized so it can't inject a qualifier.\n\t */\n\tprotected override async 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\t\treturn (await this.authenticationService.apis.github)?.searchIssuesPage(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\t// `namespace` is the owner for GitHub, which is how a `repo:` qualifier names a repository.\n\t\t\t\trepos: options.repos?.map(r => `${r.namespace}/${r.name}`),\n\t\t\t\torg: options.org,\n\t\t\t\tcriteria: options.criteria,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\tincludeBody: true,\n\t\t\t\tcursor: options.cursor,\n\t\t\t\tpageSize: options.pageSize,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Counts several scopes in ONE request. GitHub's `search` reports `issueCount` on a zero-node selection, so a\n\t * count preview costs no issue transfer — measured, 30 aliased counts are a single rate-limit point.\n\t */\n\tprotected override async countProviderIssues(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: IssueSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<(number | undefined)[] | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.countIssues(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tscopes.map(s => ({\n\t\t\t\trepos: s.repos?.map(r => `${r.namespace}/${r.name}`),\n\t\t\t\torg: s.org,\n\t\t\t\tcriteria: s.criteria,\n\t\t\t})),\n\t\t\t{ baseUrl: this.apiBaseUrlFor(session) },\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Resolves several issues by `(owner, repo, number)` by aliasing the point read rather than a search — see\n\t * {@link GitHubApi.getIssuesBatch} for why that distinction is the whole design — chunked into requests of up\n\t * to {@link issuesBatchChunkSize} coordinates, run with bounded concurrency. Settled per target already: a\n\t * coordinate whose alias fails on its own (e.g. an org enforcing SAML SSO the token isn't authorized for)\n\t * rejects only that slot, and a chunk that throws rejects only its own slots.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\treturn readChunked(\n\t\t\tcoordinates,\n\t\t\tissuesBatchChunkSize,\n\t\t\tchunkCoordinates =>\n\t\t\t\tgithub.getIssuesBatch(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tchunkCoordinates.map(c => ({ owner: c.owner, repo: c.repo, number: c.number })),\n\t\t\t\t\t{ baseUrl: this.apiBaseUrlFor(session), includeBody: true },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\tissue => issue,\n\t\t);\n\t}\n\n\t/**\n\t * Resolves several pull requests by `(owner, repo, number)` by aliasing the point read — see\n\t * {@link GitHubApi.getPullRequestsBatch} — chunked into requests of up to {@link pullRequestsBatchChunkSize}\n\t * coordinates, run with bounded concurrency. Rows take the same conversion as the account-wide list rows, so a\n\t * pull request reads the same whichever of the two returned it.\n\t *\n\t * A chunk that throws rejects only its own slots, so its sibling chunks still answer.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst currentAccount = options?.currentAccount;\n\t\treturn readChunked(\n\t\t\tcoordinates,\n\t\t\tpullRequestsBatchChunkSize,\n\t\t\tchunkCoordinates =>\n\t\t\t\tgithub.getPullRequestsBatch(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tchunkCoordinates.map(c => ({ owner: c.owner, repo: c.repo, number: c.number })),\n\t\t\t\t\t{ baseUrl: this.apiBaseUrlFor(session) },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t(pr): PullRequestShape | undefined =>\n\t\t\t\tpr != null\n\t\t\t\t\t? stampNativePullRequest(pr, { currentAccount: currentAccount, projection: 'batch' })\n\t\t\t\t\t: undefined,\n\t\t);\n\t}\n\n\t/**\n\t * The cheap check behind the batch issue read's etags: {@link getProviderIssuesBatch}'s chunks and failure\n\t * isolation over {@link GitHubApi.getIssuesEtagFieldsBatch}, which selects only an issue's change state plus the\n\t * selection of each of `options.etagIncludes`.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst etagIncludes = options.etagIncludes ?? [];\n\t\treturn readChunked(\n\t\t\tcoordinates,\n\t\t\tissuesBatchChunkSize,\n\t\t\tchunkCoordinates =>\n\t\t\t\tgithub.getIssuesEtagFieldsBatch(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tchunkCoordinates.map(c => ({ owner: c.owner, repo: c.repo, number: c.number })),\n\t\t\t\t\t{ baseUrl: this.apiBaseUrlFor(session), etagIncludes: etagIncludes },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t(node): IssueEtagFields | undefined => (node != null ? toIssueEtagFields(node, etagIncludes) : undefined),\n\t\t);\n\t}\n\n\t/**\n\t * The cheap check behind the batch pull request read's etags: {@link getProviderPullRequestsBatch}'s chunks and\n\t * failure isolation over {@link GitHubApi.getPullRequestsEtagFieldsBatch}, which selects only a pull request's\n\t * change state plus the selection of each of `options.etagIncludes`.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst etagIncludes = options.etagIncludes ?? [];\n\t\treturn readChunked(\n\t\t\tcoordinates,\n\t\t\tpullRequestsBatchChunkSize,\n\t\t\tchunkCoordinates =>\n\t\t\t\tgithub.getPullRequestsEtagFieldsBatch(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tchunkCoordinates.map(c => ({ owner: c.owner, repo: c.repo, number: c.number })),\n\t\t\t\t\t{ baseUrl: this.apiBaseUrlFor(session), etagIncludes: etagIncludes },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t(node): PullRequestEtagFields | undefined =>\n\t\t\t\tnode != null ? toPullRequestEtagFields(node, etagIncludes) : undefined,\n\t\t);\n\t}\n\n\t/**\n\t * Finds each branch's pull requests by aliasing a head-ref-name query per target — see\n\t * {@link GitHubApi.getPullRequestsForBranches} — chunked and converted exactly as\n\t * {@link getProviderPullRequestsBatch} is, with the same per-target and per-chunk failure isolation.\n\t *\n\t * That query matches the branch NAME across every fork and filters by head repository afterwards, so a name\n\t * many forks share (`main`, `patch-1`) comes back `truncated` whether or not anything it left out could match.\n\t * Only those targets take a second step: {@link GitHubApi.getPullRequestNumbersForBranch} asks REST, which\n\t * filters by head owner on the server, for the numbers that match, and any number the first step didn't return\n\t * is resolved through {@link getProviderPullRequestsBatch}, so its row is identical to the others. The answer\n\t * is the UNION of both steps: REST can't see a pull request from a since-deleted fork, which the first step still\n\t * matches by its owner, so a deleted fork's pull request on the first step's page is kept. One past that page\n\t * can't be found by either step, so on such a target a deleted fork's pull request may be missing from an\n\t * answer that isn't `truncated`. A target whose second step fails is rejected, never answered from the first\n\t * step alone.\n\t */\n\tprotected override async 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\t\tconst github = await this.authenticationService.apis.github;\n\t\tif (github == null) return undefined;\n\n\t\tconst tokenWithInfo = toTokenWithInfo(this.id, session);\n\t\tconst baseUrl = this.apiBaseUrlFor(session);\n\t\tconst currentAccount = options.currentAccount;\n\t\tconst slots = await readChunked(\n\t\t\ttargets,\n\t\t\tpullRequestsBatchChunkSize,\n\t\t\tchunkTargets =>\n\t\t\t\tgithub.getPullRequestsForBranches(\n\t\t\t\t\tthis,\n\t\t\t\t\ttokenWithInfo,\n\t\t\t\t\tchunkTargets.map(t => ({ owner: t.owner, repo: t.repo, branch: t.branch, headOwner: t.headOwner })),\n\t\t\t\t\t{ baseUrl: baseUrl, limit: options.limit },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t\t(found): { pullRequests: PullRequestShape[]; truncated: boolean } => ({\n\t\t\t\tpullRequests: found.pullRequests.map(pr =>\n\t\t\t\t\tstampNativePullRequest(pr, { currentAccount: currentAccount, projection: 'batch' }),\n\t\t\t\t),\n\t\t\t\ttruncated: found.truncated,\n\t\t\t}),\n\t\t);\n\n\t\tconst ambiguous = slots.flatMap((slot, i) =>\n\t\t\tslot.status === 'fulfilled' && slot.value.truncated ? [{ index: i, found: slot.value.pullRequests }] : [],\n\t\t);\n\t\tif (!ambiguous.length) return slots;\n\n\t\tconst heads = await mapSettledBounded(ambiguous, providerFanOutConcurrency, async a => {\n\t\t\tconst t = targets[a.index];\n\t\t\tconst head = await github.getPullRequestNumbersForBranch(\n\t\t\t\tthis,\n\t\t\t\ttokenWithInfo,\n\t\t\t\tt.owner,\n\t\t\t\tt.repo,\n\t\t\t\tt.branch,\n\t\t\t\t{ baseUrl: baseUrl, headOwner: t.headOwner, limit: options.limit },\n\t\t\t\tcancellation,\n\t\t\t);\n\t\t\tconst found = new Set(a.found.map(pr => pr.number));\n\t\t\treturn { numbers: head.numbers.filter(n => !found.has(n)), truncated: head.truncated };\n\t\t});\n\t\tconst extras = await resolveBranchPullRequests(\n\t\t\tambiguous.map(a => targets[a.index]),\n\t\t\theads,\n\t\t\tcoordinates =>\n\t\t\t\tthis.getProviderPullRequestsBatch(\n\t\t\t\t\tsession,\n\t\t\t\t\tcoordinates,\n\t\t\t\t\t{ currentAccount: currentAccount },\n\t\t\t\t\tcancellation,\n\t\t\t\t),\n\t\t);\n\n\t\tconst settled = [...slots];\n\t\tambiguous.forEach((a, i) => {\n\t\t\tconst extra = extras[i];\n\t\t\tif (extra.status === 'rejected') {\n\t\t\t\tsettled[a.index] = extra;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst pullRequests = [...a.found, ...extra.value.pullRequests].sort(\n\t\t\t\t(x, y) => y.updatedDate.getTime() - x.updatedDate.getTime(),\n\t\t\t);\n\t\t\tsettled[a.index] = {\n\t\t\t\tstatus: 'fulfilled',\n\t\t\t\tvalue: {\n\t\t\t\t\tpullRequests: pullRequests.slice(0, options.limit),\n\t\t\t\t\ttruncated: extra.value.truncated || pullRequests.length > options.limit,\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t\treturn settled;\n\t}\n\n\t/**\n\t * Counts several pull-request scopes in ONE request. Like {@link countProviderIssues}, GitHub's `search`\n\t * reports `issueCount` on a zero-node selection, so a count preview costs no pull-request transfer.\n\t */\n\tprotected override async countProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tscopes: readonly { repos?: ProviderRepoInput[]; org?: string; criteria?: PullRequestSearchCriteria }[],\n\t\tcancellation?: AbortSignal,\n\t): Promise<ProviderPullRequestCount[] | undefined> {\n\t\tconst counts = await (\n\t\t\tawait this.authenticationService.apis.github\n\t\t)?.countPullRequests(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\tscopes.map(s => ({\n\t\t\t\trepos: s.repos?.map(r => `${r.namespace}/${r.name}`),\n\t\t\t\torg: s.org,\n\t\t\t\tcriteria: s.criteria,\n\t\t\t})),\n\t\t\t{ baseUrl: this.apiBaseUrlFor(session) },\n\t\t\tcancellation,\n\t\t);\n\t\t// `issueCount` is the search's own total, never a floor, so no slot is a lower bound.\n\t\treturn counts?.map(count => ({ count: count }));\n\t}\n\n\tprotected override async searchProviderPullRequests(\n\t\tsession: ProviderAuthenticationSession,\n\t\tsearchQuery: string,\n\t\trepos?: GitHubRepositoryDescriptor[],\n\t\tcancellation?: AbortSignal,\n\t\toptions?: SearchPullRequestsOptions,\n\t): Promise<PullRequest[] | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.searchPullRequests(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\tsearch: searchQuery,\n\t\t\t\trepos: repos?.map(r => `${r.owner}/${r.name}`),\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t...options,\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t}\n\n\t/**\n\t * Stack membership for every stacked pull request in the repository, keyed by pull request number.\n\t *\n\t * List surfaces get their pull requests from the shared providers API, whose type carries no stack\n\t * membership, so the `stack`/`stackEntry` fields selected on the native per-pull-request reads never\n\t * reach them. This fills that gap in a single request for the whole repository, rather than a\n\t * per-pull-request enrichment that would scale with the list.\n\t *\n\t * `undefined` means unavailable (not enrolled in the preview, or not connected) as distinct from an\n\t * empty map, which means the repository genuinely has no stacks.\n\t */\n\toverride async getStacksByPullRequestNumber(\n\t\towner: string,\n\t\trepo: string,\n\t\tcancellation?: AbortSignal,\n\t): Promise<Map<number, PullRequestStackInfo> | undefined> {\n\t\t// The shared read path: like `getSession()` it refreshes an expired session before use, but it throws a\n\t\t// failed refresh as the failure rather than answering as if not connected.\n\t\tconst session = await this.resolveReadSessionOrThrow(undefined, undefined);\n\t\tif (session == null) return undefined;\n\n\t\tconst stacks = await (\n\t\t\tawait this.authenticationService.apis.github\n\t\t)?.getRepositoryStacks(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\towner,\n\t\t\trepo,\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t\tif (stacks == null) return undefined;\n\n\t\tconst byNumber = new Map<number, PullRequestStackInfo>();\n\t\tfor (const stack of stacks) {\n\t\t\t// Defensive: this is a public-preview payload reaching us through an unvalidated cast, and a\n\t\t\t// malformed entry must cost its own stack's badges, not the whole panel.\n\t\t\tconst members = stack?.pull_requests;\n\t\t\tconst baseRef = stack?.base?.ref;\n\t\t\tif (members == null || baseRef == null) continue;\n\n\t\t\t// `pull_requests` is ordered bottom to top, and `position` is 1-based from the bottom.\n\t\t\tmembers.forEach((pr, i) => {\n\t\t\t\tbyNumber.set(pr.number, {\n\t\t\t\t\tid: String(stack.id),\n\t\t\t\t\tnumber: stack.number,\n\t\t\t\t\tsize: members.length,\n\t\t\t\t\tposition: i + 1,\n\t\t\t\t\tbaseRef: baseRef,\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\treturn byNumber;\n\t}\n\n\t/**\n\t * The ordered layers of the stack the given pull request belongs to, bottom to top.\n\t *\n\t * There is no per-pull-request stacks endpoint, so this reuses the same repository-wide stacks read\n\t * as {@link getStacksByPullRequestNumber} and picks out the one stack containing the given pull\n\t * request.\n\t *\n\t * `undefined` when the host has no stacks concept, the repository isn't enrolled in the preview, or\n\t * the pull request isn't stacked.\n\t */\n\toverride async getStackLayersForPullRequest(\n\t\towner: string,\n\t\trepo: string,\n\t\tpullRequestNumber: number,\n\t\tcancellation?: AbortSignal,\n\t): Promise<PullRequestStackLayers | undefined> {\n\t\t// The shared read path: like `getSession()` it refreshes an expired session before use, but it throws a\n\t\t// failed refresh as the failure rather than answering as if not connected.\n\t\tconst session = await this.resolveReadSessionOrThrow(undefined, undefined);\n\t\tif (session == null) return undefined;\n\n\t\tconst stacks = await (\n\t\t\tawait this.authenticationService.apis.github\n\t\t)?.getRepositoryStacks(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\towner,\n\t\t\trepo,\n\t\t\t{\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t\tcancellation,\n\t\t);\n\t\tif (stacks == null) return undefined;\n\n\t\tfor (const stack of stacks) {\n\t\t\t// Defensive: this is a public-preview payload reaching us through an unvalidated cast, and a\n\t\t\t// malformed stack must be skipped, not thrown on.\n\t\t\tconst members = stack?.pull_requests;\n\t\t\tconst baseRef = stack?.base?.ref;\n\t\t\tif (members == null || baseRef == null) continue;\n\n\t\t\tif (!members.some(pr => pr.number === pullRequestNumber)) continue;\n\n\t\t\t// `pull_requests` is already ordered bottom to top.\n\t\t\tconst layers: PullRequestStackLayer[] = [];\n\t\t\tfor (const layer of members) {\n\t\t\t\tconst headRef = layer.head?.ref;\n\t\t\t\tif (headRef == null) continue;\n\n\t\t\t\tlayers.push({\n\t\t\t\t\tnumber: layer.number,\n\t\t\t\t\theadRef: headRef,\n\t\t\t\t\theadSha: layer.head.sha,\n\t\t\t\t\tmerged: layer.merged_at != null,\n\t\t\t\t\tdraft: layer.draft === true,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tid: String(stack.id),\n\t\t\t\tnumber: stack.number,\n\t\t\t\tbaseRef: baseRef,\n\t\t\t\tlayers: layers,\n\t\t\t};\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tprotected override async mergeProviderPullRequest(\n\t\tsession: ProviderAuthenticationSession,\n\t\tpr: PullRequest,\n\t\toptions?: {\n\t\t\tmergeMethod?: PullRequestMergeMethod;\n\t\t},\n\t\tcancellation?: AbortSignal,\n\t): Promise<boolean> {\n\t\tconst id = pr.nodeId;\n\t\tconst headRefSha = pr.refs?.head?.sha;\n\t\tif (id == null || headRefSha == null) return false;\n\n\t\tconst api = await this.authenticationService.apis.github;\n\n\t\t// GitHub rejects stacked pull requests on the legacy merge mutation, so they take the\n\t\t// asynchronous merge instead — which also lands every layer below this one.\n\t\tif (pr.stack != null) {\n\t\t\treturn (\n\t\t\t\t(await api?.mergeStackedPullRequest(\n\t\t\t\t\tthis,\n\t\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\t\tpr.repository.owner,\n\t\t\t\t\tpr.repository.repo,\n\t\t\t\t\tNumber(pr.id),\n\t\t\t\t\theadRefSha,\n\t\t\t\t\t{\n\t\t\t\t\t\tmergeMethod: options?.mergeMethod,\n\t\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t\t},\n\t\t\t\t\tcancellation,\n\t\t\t\t)) ?? false\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\tapi?.mergePullRequest(\n\t\t\t\tthis,\n\t\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t\tid,\n\t\t\t\theadRefSha,\n\t\t\t\t{\n\t\t\t\t\tmergeMethod: options?.mergeMethod,\n\t\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t\t},\n\t\t\t\tcancellation,\n\t\t\t) ?? false\n\t\t);\n\t}\n\n\tprotected override async getProviderCurrentAccount(\n\t\tsession: ProviderAuthenticationSession,\n\t\toptions?: { avatarSize?: number },\n\t): Promise<Account | undefined> {\n\t\treturn (await this.authenticationService.apis.github)?.getCurrentAccount(\n\t\t\tthis,\n\t\t\ttoTokenWithInfo(this.id, session),\n\t\t\t{\n\t\t\t\t...options,\n\t\t\t\tbaseUrl: this.apiBaseUrlFor(session),\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override getProviderPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {\n\t\treturn getGitHubPullRequestIdentityFromMaybeUrl(search, this.id);\n\t}\n}\n\nexport class GitHubIntegration extends GitHubIntegrationBase<GitCloudHostIntegrationId.GitHub> {\n\treadonly authProvider = authProvider;\n\treadonly id = GitCloudHostIntegrationId.GitHub;\n\tprotected readonly key = this.id;\n\treadonly name: string = 'GitHub';\n\tget domain(): string {\n\t\treturn metadata.domain;\n\t}\n\n\tprotected override apiBaseUrlFor(_session: ProviderAuthenticationSession): string | undefined {\n\t\t// Undefined on purpose, NOT 'https://api.github.com'. `@gitkraken/provider-apis` treats this value as an\n\t\t// *enterprise* base and derives both endpoints from it by appending GitHub Enterprise's paths:\n\t\t// `getRESTBaseUrl` appends `/api/v3` and `getGraphQLEndpoint` appends `/api/graphql` (githubHelpers.ts).\n\t\t// Handing it the cloud host therefore built `https://api.github.com/api/graphql`, which GitHub answers\n\t\t// 404 — every cloud GraphQL read (orgs, repos, PR/issue search) failed as `not-found`. Omitting it is\n\t\t// what selects the cloud endpoints (`GITHUB_API_URL` / `GITHUB_GRAPHQL_API_URL`), so cloud must pass\n\t\t// nothing and only GHE passes its instance base.\n\t\treturn undefined;\n\t}\n\n\toverride access(): Promise<boolean> {\n\t\t// Always allow GitHub cloud integration access\n\t\treturn Promise.resolve(true);\n\t}\n\n\t// This is a special case for GitHub because we use VSCode's GitHub session, and it can be disconnected\n\t// outside of the extension.\n\toverride async refresh(): Promise<void> {\n\t\tconst authProvider = await this.authenticationService.get(this.authProvider.id);\n\t\tconst session = await authProvider.getSession(this.authProviderDescriptor);\n\t\tif (session == null && this.maybeConnected) {\n\t\t\tvoid this.disconnect({ silent: true });\n\t\t} else {\n\t\t\tvoid this.resyncSessionIfTokenChanged(session?.accessToken);\n\t\t}\n\t}\n}\n\nexport class GitHubEnterpriseIntegration extends GitHubIntegrationBase<GitSelfManagedHostIntegrationId.CloudGitHubEnterprise> {\n\treadonly authProvider = cloudEnterpriseAuthProvider;\n\treadonly id = GitSelfManagedHostIntegrationId.CloudGitHubEnterprise;\n\tprotected readonly key;\n\treadonly name = 'GitHub Enterprise';\n\tget domain(): string {\n\t\treturn this._domain;\n\t}\n\n\tprotected override apiBaseUrlFor(session: ProviderAuthenticationSession): string {\n\t\treturn this.getSelfManagedApiBaseUrl(session);\n\t}\n\n\tconstructor(\n\t\tctx: IntegrationServiceContext,\n\t\tauthenticationService: IntegrationAuthenticationService,\n\t\tgetProvidersApi: () => Promise<ProvidersApi>,\n\t\tdidChangeConnection: Emitter<IntegrationConnectionChangeEvent>,\n\t\tprivate readonly _domain: string,\n\t) {\n\t\tsuper(ctx, authenticationService, getProvidersApi, didChangeConnection);\n\t\tthis.key = `${this.id}:${this.domain}` as const;\n\t}\n}\n"],"mappings":"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"}
@@ -160,7 +160,7 @@ declare abstract class GitLabIntegrationBase<ID extends GitLabIntegrationIds> ex
160
160
  cursor?: string;
161
161
  filters?: PullRequestFilter[];
162
162
  }): Promise<ProviderApiPagedResult<ProviderPullRequest> | undefined>;
163
- protected searchProviderMyIssues(session: ProviderAuthenticationSession, repos?: GitLabRepositoryDescriptor[]): Promise<IssueShape[] | undefined>;
163
+ protected searchProviderMyIssues(session: ProviderAuthenticationSession, repos?: GitLabRepositoryDescriptor[], cancellation?: AbortSignal): Promise<IssueShape[] | undefined>;
164
164
  /**
165
165
  * Account-wide "my issues" for GitLab. GitLab's repo-scoped issue read bails without repos, and GitLab has
166
166
  * no GraphQL cross-project issue field, so this goes through the SDK's REST `GET /issues` read
@@ -402,10 +402,11 @@ var GitLabIntegrationBase = class extends GitHostIntegration {
402
402
  ...aggregateMetadata != null ? { metadata: aggregateMetadata } : {}
403
403
  };
404
404
  }
405
- async searchProviderMyIssues(session, repos) {
405
+ async searchProviderMyIssues(session, repos, cancellation) {
406
+ if (repos == null || repos.length === 0) return (await this.searchProviderMyIssuesWithTruncation(session, repos, cancellation))?.values;
406
407
  const api = await this.authenticationService.apis.gitlab;
407
408
  const providerApi = await this.getProvidersApi();
408
- if (!api || !repos) return;
409
+ if (!api) return;
409
410
  const repoInput = (await Promise.allSettled(repos.map((r) => api.getProjectId(this, toTokenWithInfo(this.id, session), r.owner, r.name, this.apiBaseUrlFor(session), void 0)) ?? [])).map((result) => result.status === "fulfilled" ? result.value : void 0).filter((r) => r != null);
410
411
  return (await providerApi.getIssuesForRepos(toTokenWithInfo(this.id, session), repoInput, {
411
412
  isPAT: this.isEnterprise,