From 426d3de2f6b648fe333bd59c76c50501df05cc8e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:13:23 +0000 Subject: [PATCH 01/12] Initial plan From 9d0857c2ec53d1e2ad0b2796357597054f33984c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:19:42 +0000 Subject: [PATCH 02/12] Initial plan for checkout PR improvements Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/@types/vscode.proposed.chatParticipantAdditions.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index 71520fa1ec..aa7001a3d2 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -105,6 +105,7 @@ declare module 'vscode' { isComplete?: boolean; toolSpecificData?: ChatTerminalToolInvocationData; fromSubAgent?: boolean; + presentation?: 'hidden' | 'hiddenAfterComplete' | undefined; constructor(toolName: string, toolCallId: string, isError?: boolean); } From bfd57e579bc44b4a0c0f7054bc761e7c3cdac3db Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:24:50 +0000 Subject: [PATCH 03/12] Implement PR picker for checkout command - Added QuickPick to show all open PRs when checking out - Allow filtering by number, title, or author in the picker - Support typing custom PR number or URL - Renamed command to "Checkout Pull Request..." - Import PRType for fetching all PRs Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- package.nls.json | 2 +- src/commands.ts | 80 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/package.nls.json b/package.nls.json index 73c02b7684..a04ff1055a 100644 --- a/package.nls.json +++ b/package.nls.json @@ -210,7 +210,7 @@ "command.pr.focusDescriptionInput.title": "Focus Pull Request Description Review Input", "command.pr.showDiffSinceLastReview.title": "Show Changes Since Last Review", "command.pr.showDiffAll.title": "Show All Changes", - "command.pr.checkoutByNumber.title": "Checkout Pull Request by Number", + "command.pr.checkoutByNumber.title": "Checkout Pull Request...", "command.review.openFile.title": "Open File", "command.review.openLocalFile.title": "Open File", "command.review.approve.title": "Approve", diff --git a/src/commands.ts b/src/commands.ts index ddb34e8736..0530784f42 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -23,7 +23,7 @@ import { ChatSessionWithPR, CrossChatSessionWithPR } from './github/copilotApi'; import { CopilotRemoteAgentManager, SessionIdForPr } from './github/copilotRemoteAgent'; import { FolderRepositoryManager } from './github/folderRepositoryManager'; import { GitHubRepository } from './github/githubRepository'; -import { Issue } from './github/interface'; +import { Issue, PRType } from './github/interface'; import { IssueModel } from './github/issueModel'; import { IssueOverviewPanel } from './github/issueOverview'; import { GHPRComment, GHPRCommentThread, TemporaryComment } from './github/prComment'; @@ -1604,26 +1604,70 @@ ${contents} if (!githubRepo) { return; } - const prNumber = await vscode.window.showInputBox({ - ignoreFocusOut: true, prompt: vscode.l10n.t('Enter the pull request number or URL'), - validateInput: (input: string) => { - const result = validateAndParseInput(input, githubRepo.repo.remote.owner, githubRepo.repo.remote.repositoryName); - return result.isValid ? undefined : result.errorMessage; + + // Create QuickPick to show all PRs + const quickPick = vscode.window.createQuickPick(); + quickPick.placeholder = vscode.l10n.t('Select a pull request or enter a pull request number/URL'); + quickPick.matchOnDescription = true; + quickPick.matchOnDetail = true; + quickPick.show(); + quickPick.busy = true; + + // Fetch all open PRs + try { + const prs = await githubRepo.manager.getPullRequests(PRType.All, { fetchNextPage: false }); + const prItems: (vscode.QuickPickItem & { pr: PullRequestModel })[] = prs.items.map(pr => ({ + label: `#${pr.number}`, + description: pr.title, + detail: `by @${pr.author.login}`, + pr + })); + + quickPick.items = prItems; + quickPick.busy = false; + + // Handle selection + const selected = await new Promise<(vscode.QuickPickItem & { pr?: PullRequestModel }) | string | undefined>((resolve) => { + quickPick.onDidAccept(() => { + if (quickPick.selectedItems.length > 0) { + resolve(quickPick.selectedItems[0]); + } else if (quickPick.value) { + // User typed something but didn't select from list + resolve(quickPick.value); + } + }); + quickPick.onDidHide(() => resolve(undefined)); + }); + + quickPick.hide(); + quickPick.dispose(); + + if (!selected) { + return; } - }); - if ((prNumber === undefined) || prNumber === '#') { - return; - } - // Extract PR number from input (either direct number or URL) - const parseResult = validateAndParseInput(prNumber, githubRepo.repo.remote.owner, githubRepo.repo.remote.repositoryName); - if (!parseResult.isValid) { - return vscode.window.showErrorMessage(parseResult.errorMessage || vscode.l10n.t('Invalid pull request number or URL')); - } + let prModel: PullRequestModel | undefined; - const prModel = await githubRepo.manager.fetchById(githubRepo.repo, parseResult.prNumber); - if (prModel) { - return ReviewManager.getReviewManagerForFolderManager(reviewsManager.reviewManagers, githubRepo.manager)?.switch(prModel); + // Check if user selected from the list or typed a custom value + if (typeof selected === 'string') { + // User typed a PR number or URL + const parseResult = validateAndParseInput(selected, githubRepo.repo.remote.owner, githubRepo.repo.remote.repositoryName); + if (!parseResult.isValid) { + return vscode.window.showErrorMessage(parseResult.errorMessage || vscode.l10n.t('Invalid pull request number or URL')); + } + prModel = await githubRepo.manager.fetchById(githubRepo.repo, parseResult.prNumber); + } else if (selected.pr) { + // User selected from the list + prModel = selected.pr; + } + + if (prModel) { + return ReviewManager.getReviewManagerForFolderManager(reviewsManager.reviewManagers, githubRepo.manager)?.switch(prModel); + } + } catch (e) { + quickPick.hide(); + quickPick.dispose(); + return vscode.window.showErrorMessage(vscode.l10n.t('Failed to fetch pull requests: {0}', formatError(e))); } })); From d26960216c610c55e9a096a6e28c1ba8584e44eb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:26:15 +0000 Subject: [PATCH 04/12] Sort PRs by number descending in picker Show most recent PRs first for better usability Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/commands.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/commands.ts b/src/commands.ts index 0530784f42..45029002cf 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1616,7 +1616,9 @@ ${contents} // Fetch all open PRs try { const prs = await githubRepo.manager.getPullRequests(PRType.All, { fetchNextPage: false }); - const prItems: (vscode.QuickPickItem & { pr: PullRequestModel })[] = prs.items.map(pr => ({ + // Sort PRs by number in descending order (most recent first) + const sortedPRs = prs.items.sort((a, b) => b.number - a.number); + const prItems: (vscode.QuickPickItem & { pr: PullRequestModel })[] = sortedPRs.map(pr => ({ label: `#${pr.number}`, description: pr.title, detail: `by @${pr.author.login}`, From ba37f00b0dafba0889ea731c8cbc75b74fed8596 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:30:44 +0000 Subject: [PATCH 05/12] Fix memory leak with event listeners - Properly dispose event listeners after promise resolves - Remove unrelated changes to proposed API file Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/commands.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index 45029002cf..9e697ac744 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1629,8 +1629,10 @@ ${contents} quickPick.busy = false; // Handle selection + let acceptDisposable: vscode.Disposable; + let hideDisposable: vscode.Disposable; const selected = await new Promise<(vscode.QuickPickItem & { pr?: PullRequestModel }) | string | undefined>((resolve) => { - quickPick.onDidAccept(() => { + acceptDisposable = quickPick.onDidAccept(() => { if (quickPick.selectedItems.length > 0) { resolve(quickPick.selectedItems[0]); } else if (quickPick.value) { @@ -1638,9 +1640,13 @@ ${contents} resolve(quickPick.value); } }); - quickPick.onDidHide(() => resolve(undefined)); + hideDisposable = quickPick.onDidHide(() => resolve(undefined)); }); + // Clean up event listeners + acceptDisposable.dispose(); + hideDisposable.dispose(); + quickPick.hide(); quickPick.dispose(); From 7bb0a5372f6e654bee4c77550a176afbd0a6822b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:31:39 +0000 Subject: [PATCH 06/12] Revert unrelated proposed API changes --- src/@types/vscode.proposed.chatParticipantAdditions.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index aa7001a3d2..71520fa1ec 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -105,7 +105,6 @@ declare module 'vscode' { isComplete?: boolean; toolSpecificData?: ChatTerminalToolInvocationData; fromSubAgent?: boolean; - presentation?: 'hidden' | 'hiddenAfterComplete' | undefined; constructor(toolName: string, toolCallId: string, isError?: boolean); } From 5748015697058e7429ff58365d54a255837d473f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:33:55 +0000 Subject: [PATCH 07/12] Fix promise resolution edge cases - Handle case when user presses Enter with no selection - Make disposables optional to prevent undefined access Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/commands.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index 9e697ac744..551aefcb7b 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1629,8 +1629,8 @@ ${contents} quickPick.busy = false; // Handle selection - let acceptDisposable: vscode.Disposable; - let hideDisposable: vscode.Disposable; + let acceptDisposable: vscode.Disposable | undefined; + let hideDisposable: vscode.Disposable | undefined; const selected = await new Promise<(vscode.QuickPickItem & { pr?: PullRequestModel }) | string | undefined>((resolve) => { acceptDisposable = quickPick.onDidAccept(() => { if (quickPick.selectedItems.length > 0) { @@ -1638,14 +1638,17 @@ ${contents} } else if (quickPick.value) { // User typed something but didn't select from list resolve(quickPick.value); + } else { + // User pressed Enter with no selection and no input + resolve(undefined); } }); hideDisposable = quickPick.onDidHide(() => resolve(undefined)); }); // Clean up event listeners - acceptDisposable.dispose(); - hideDisposable.dispose(); + acceptDisposable?.dispose(); + hideDisposable?.dispose(); quickPick.hide(); quickPick.dispose(); From cec928c77484d2617bed83beb489bf928227ba66 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:36:08 +0000 Subject: [PATCH 08/12] Use finally block for cleanup to eliminate duplication Move QuickPick and event listener cleanup to finally block Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/commands.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index 551aefcb7b..08cbd2e485 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1613,6 +1613,9 @@ ${contents} quickPick.show(); quickPick.busy = true; + let acceptDisposable: vscode.Disposable | undefined; + let hideDisposable: vscode.Disposable | undefined; + // Fetch all open PRs try { const prs = await githubRepo.manager.getPullRequests(PRType.All, { fetchNextPage: false }); @@ -1629,8 +1632,6 @@ ${contents} quickPick.busy = false; // Handle selection - let acceptDisposable: vscode.Disposable | undefined; - let hideDisposable: vscode.Disposable | undefined; const selected = await new Promise<(vscode.QuickPickItem & { pr?: PullRequestModel }) | string | undefined>((resolve) => { acceptDisposable = quickPick.onDidAccept(() => { if (quickPick.selectedItems.length > 0) { @@ -1646,13 +1647,6 @@ ${contents} hideDisposable = quickPick.onDidHide(() => resolve(undefined)); }); - // Clean up event listeners - acceptDisposable?.dispose(); - hideDisposable?.dispose(); - - quickPick.hide(); - quickPick.dispose(); - if (!selected) { return; } @@ -1676,9 +1670,13 @@ ${contents} return ReviewManager.getReviewManagerForFolderManager(reviewsManager.reviewManagers, githubRepo.manager)?.switch(prModel); } } catch (e) { + vscode.window.showErrorMessage(vscode.l10n.t('Failed to fetch pull requests: {0}', formatError(e))); + } finally { + // Clean up event listeners and QuickPick + acceptDisposable?.dispose(); + hideDisposable?.dispose(); quickPick.hide(); quickPick.dispose(); - return vscode.window.showErrorMessage(vscode.l10n.t('Failed to fetch pull requests: {0}', formatError(e))); } })); From fffb33abcb1a08d4c3336b34f753d60025570b8d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:19:57 +0000 Subject: [PATCH 09/12] Add lightweight GraphQL query for PR numbers - Created PullRequestNumbers query that fetches only number, title, and author - Added getPullRequestNumbers() method to GitHubRepository - Updated checkout command to use new lightweight query - Reverted title change in package.nls.json per feedback Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- package.nls.json | 2 +- ...ode.proposed.chatParticipantAdditions.d.ts | 1 + src/commands.ts | 21 ++++++----- src/github/githubRepository.ts | 35 +++++++++++++++++++ src/github/graphql.ts | 14 ++++++++ src/github/queries.gql | 21 +++++++++++ 6 files changed, 84 insertions(+), 10 deletions(-) diff --git a/package.nls.json b/package.nls.json index a04ff1055a..73c02b7684 100644 --- a/package.nls.json +++ b/package.nls.json @@ -210,7 +210,7 @@ "command.pr.focusDescriptionInput.title": "Focus Pull Request Description Review Input", "command.pr.showDiffSinceLastReview.title": "Show Changes Since Last Review", "command.pr.showDiffAll.title": "Show All Changes", - "command.pr.checkoutByNumber.title": "Checkout Pull Request...", + "command.pr.checkoutByNumber.title": "Checkout Pull Request by Number", "command.review.openFile.title": "Open File", "command.review.openLocalFile.title": "Open File", "command.review.approve.title": "Approve", diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index 71520fa1ec..aa7001a3d2 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -105,6 +105,7 @@ declare module 'vscode' { isComplete?: boolean; toolSpecificData?: ChatTerminalToolInvocationData; fromSubAgent?: boolean; + presentation?: 'hidden' | 'hiddenAfterComplete' | undefined; constructor(toolName: string, toolCallId: string, isError?: boolean); } diff --git a/src/commands.ts b/src/commands.ts index 08cbd2e485..ee48481b58 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -23,7 +23,7 @@ import { ChatSessionWithPR, CrossChatSessionWithPR } from './github/copilotApi'; import { CopilotRemoteAgentManager, SessionIdForPr } from './github/copilotRemoteAgent'; import { FolderRepositoryManager } from './github/folderRepositoryManager'; import { GitHubRepository } from './github/githubRepository'; -import { Issue, PRType } from './github/interface'; +import { Issue } from './github/interface'; import { IssueModel } from './github/issueModel'; import { IssueOverviewPanel } from './github/issueOverview'; import { GHPRComment, GHPRCommentThread, TemporaryComment } from './github/prComment'; @@ -1616,23 +1616,26 @@ ${contents} let acceptDisposable: vscode.Disposable | undefined; let hideDisposable: vscode.Disposable | undefined; - // Fetch all open PRs + // Fetch all open PRs (lightweight query) try { - const prs = await githubRepo.manager.getPullRequests(PRType.All, { fetchNextPage: false }); + const prs = await githubRepo.repo.getPullRequestNumbers(); + if (!prs) { + return vscode.window.showErrorMessage(vscode.l10n.t('Failed to fetch pull requests')); + } // Sort PRs by number in descending order (most recent first) - const sortedPRs = prs.items.sort((a, b) => b.number - a.number); - const prItems: (vscode.QuickPickItem & { pr: PullRequestModel })[] = sortedPRs.map(pr => ({ + const sortedPRs = prs.sort((a, b) => b.number - a.number); + const prItems: (vscode.QuickPickItem & { prNumber: number })[] = sortedPRs.map(pr => ({ label: `#${pr.number}`, description: pr.title, detail: `by @${pr.author.login}`, - pr + prNumber: pr.number })); quickPick.items = prItems; quickPick.busy = false; // Handle selection - const selected = await new Promise<(vscode.QuickPickItem & { pr?: PullRequestModel }) | string | undefined>((resolve) => { + const selected = await new Promise<(vscode.QuickPickItem & { prNumber?: number }) | string | undefined>((resolve) => { acceptDisposable = quickPick.onDidAccept(() => { if (quickPick.selectedItems.length > 0) { resolve(quickPick.selectedItems[0]); @@ -1661,9 +1664,9 @@ ${contents} return vscode.window.showErrorMessage(parseResult.errorMessage || vscode.l10n.t('Invalid pull request number or URL')); } prModel = await githubRepo.manager.fetchById(githubRepo.repo, parseResult.prNumber); - } else if (selected.pr) { + } else if (selected.prNumber) { // User selected from the list - prModel = selected.pr; + prModel = await githubRepo.manager.fetchById(githubRepo.repo, selected.prNumber); } if (prModel) { diff --git a/src/github/githubRepository.ts b/src/github/githubRepository.ts index a08bd61e93..c644cd4431 100644 --- a/src/github/githubRepository.ts +++ b/src/github/githubRepository.ts @@ -27,6 +27,7 @@ import { OrganizationTeamsCountResponse, OrganizationTeamsResponse, OrgProjectsResponse, + PullRequestNumbersResponse, PullRequestParticipantsResponse, PullRequestResponse, PullRequestsResponse, @@ -668,6 +669,40 @@ export class GitHubRepository extends Disposable { return undefined; } + async getPullRequestNumbers(): Promise<{ number: number; title: string; author: { login: string } }[] | undefined> { + let remote: GitHubRemote | undefined; + try { + Logger.debug(`Fetch pull request numbers - enter`, this.id); + const ensured = await this.ensure(); + remote = ensured.remote; + const { query, schema } = ensured; + const { data } = await query({ + query: schema.PullRequestNumbers, + variables: { + owner: remote.owner, + name: remote.repositoryName, + first: 100, + }, + }); + Logger.debug(`Fetch pull request numbers - done`, this.id); + + if (data?.repository?.pullRequests) { + return data.repository.pullRequests.nodes; + } + } catch (e) { + Logger.error(`Fetching pull request numbers failed: ${e}`, this.id); + if (e.status === 404) { + // not found + vscode.window.showWarningMessage( + `Fetching pull request numbers for remote '${remote?.remoteName}' failed, please check if the repository ${remote?.owner}/${remote?.repositoryName} is valid.`, + ); + } else { + throw e; + } + } + return undefined; + } + async getPullRequestForBranch(branch: string, headOwner: string): Promise { let remote: GitHubRemote | undefined; try { diff --git a/src/github/graphql.ts b/src/github/graphql.ts index 68f41b1ded..b57ac6d1ec 100644 --- a/src/github/graphql.ts +++ b/src/github/graphql.ts @@ -844,6 +844,20 @@ export interface PullRequestsResponse { } | null; } +export interface PullRequestNumbersResponse { + repository: { + pullRequests: { + nodes: { + number: number; + title: string; + author: { + login: string; + }; + }[] + } + } | null; +} + export interface MaxIssueResponse { repository: { issues: { diff --git a/src/github/queries.gql b/src/github/queries.gql index 524ed6f65c..b456786e3e 100644 --- a/src/github/queries.gql +++ b/src/github/queries.gql @@ -763,4 +763,25 @@ mutation ReplaceActorsForAssignable($input: ReplaceActorsForAssignableInput!) { } } } +} + +fragment PullRequestNumberFragment on PullRequest { + number + title + author { + login + } +} + +query PullRequestNumbers($owner: String!, $name: String!, $first: Int!) { + repository(owner: $owner, name: $name) { + pullRequests(first: $first, states: OPEN, orderBy: { field: CREATED_AT, direction: DESC }) { + nodes { + ...PullRequestNumberFragment + } + } + } + rateLimit { + ...RateLimit + } } \ No newline at end of file From a39962218f0e04578c2632f2d7d51c27b045a84a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:20:51 +0000 Subject: [PATCH 10/12] Remove unrelated proposed API changes --- src/@types/vscode.proposed.chatParticipantAdditions.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index aa7001a3d2..71520fa1ec 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -105,7 +105,6 @@ declare module 'vscode' { isComplete?: boolean; toolSpecificData?: ChatTerminalToolInvocationData; fromSubAgent?: boolean; - presentation?: 'hidden' | 'hiddenAfterComplete' | undefined; constructor(toolName: string, toolCallId: string, isError?: boolean); } From a5da5f72371994cbeb98135b5edf08e73dd94b6e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:25:41 +0000 Subject: [PATCH 11/12] Changes before error encountered Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/github/githubRepository.ts | 3 ++- src/github/graphql.ts | 17 ++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/github/githubRepository.ts b/src/github/githubRepository.ts index c644cd4431..5cee1a10c7 100644 --- a/src/github/githubRepository.ts +++ b/src/github/githubRepository.ts @@ -27,6 +27,7 @@ import { OrganizationTeamsCountResponse, OrganizationTeamsResponse, OrgProjectsResponse, + PullRequestNumberData, PullRequestNumbersResponse, PullRequestParticipantsResponse, PullRequestResponse, @@ -669,7 +670,7 @@ export class GitHubRepository extends Disposable { return undefined; } - async getPullRequestNumbers(): Promise<{ number: number; title: string; author: { login: string } }[] | undefined> { + async getPullRequestNumbers(): Promise { let remote: GitHubRemote | undefined; try { Logger.debug(`Fetch pull request numbers - enter`, this.id); diff --git a/src/github/graphql.ts b/src/github/graphql.ts index b57ac6d1ec..23c3cdcc9a 100644 --- a/src/github/graphql.ts +++ b/src/github/graphql.ts @@ -847,15 +847,18 @@ export interface PullRequestsResponse { export interface PullRequestNumbersResponse { repository: { pullRequests: { - nodes: { - number: number; - title: string; - author: { - login: string; - }; - }[] + nodes: PullRequestNumberData[] } } | null; + rateLimit: RateLimit; +} + +export interface PullRequestNumberData { + number: number; + title: string; + author: { + login: string; + }; } export interface MaxIssueResponse { From d35ae538ebffab82c88e3f9b4444886f915c6bea Mon Sep 17 00:00:00 2001 From: Alex Ross <38270282+alexr00@users.noreply.github.com> Date: Fri, 19 Dec 2025 11:48:39 +0100 Subject: [PATCH 12/12] Clean up --- src/commands.ts | 9 ++++----- src/github/queries.gql | 21 --------------------- src/github/queriesShared.gql | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index ee48481b58..067066ac4c 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1607,7 +1607,7 @@ ${contents} // Create QuickPick to show all PRs const quickPick = vscode.window.createQuickPick(); - quickPick.placeholder = vscode.l10n.t('Select a pull request or enter a pull request number/URL'); + quickPick.placeholder = vscode.l10n.t('Enter a pull request number/URL or select from the list'); quickPick.matchOnDescription = true; quickPick.matchOnDetail = true; quickPick.show(); @@ -1625,9 +1625,8 @@ ${contents} // Sort PRs by number in descending order (most recent first) const sortedPRs = prs.sort((a, b) => b.number - a.number); const prItems: (vscode.QuickPickItem & { prNumber: number })[] = sortedPRs.map(pr => ({ - label: `#${pr.number}`, - description: pr.title, - detail: `by @${pr.author.login}`, + label: `#${pr.number} ${pr.title}`, + description: `by @${pr.author.login}`, prNumber: pr.number })); @@ -1653,7 +1652,7 @@ ${contents} if (!selected) { return; } - + quickPick.busy = true; let prModel: PullRequestModel | undefined; // Check if user selected from the list or typed a custom value diff --git a/src/github/queries.gql b/src/github/queries.gql index b456786e3e..524ed6f65c 100644 --- a/src/github/queries.gql +++ b/src/github/queries.gql @@ -763,25 +763,4 @@ mutation ReplaceActorsForAssignable($input: ReplaceActorsForAssignableInput!) { } } } -} - -fragment PullRequestNumberFragment on PullRequest { - number - title - author { - login - } -} - -query PullRequestNumbers($owner: String!, $name: String!, $first: Int!) { - repository(owner: $owner, name: $name) { - pullRequests(first: $first, states: OPEN, orderBy: { field: CREATED_AT, direction: DESC }) { - nodes { - ...PullRequestNumberFragment - } - } - } - rateLimit { - ...RateLimit - } } \ No newline at end of file diff --git a/src/github/queriesShared.gql b/src/github/queriesShared.gql index 473841f0a1..c525b763f2 100644 --- a/src/github/queriesShared.gql +++ b/src/github/queriesShared.gql @@ -686,6 +686,27 @@ query PullRequestTemplates($owner: String!, $name: String!) { } } +fragment PullRequestNumberFragment on PullRequest { + number + title + author { + login + } +} + +query PullRequestNumbers($owner: String!, $name: String!, $first: Int!) { + repository(owner: $owner, name: $name) { + pullRequests(first: $first, states: OPEN, orderBy: { field: CREATED_AT, direction: DESC }) { + nodes { + ...PullRequestNumberFragment + } + } + } + rateLimit { + ...RateLimit + } +} + mutation AddComment($input: AddPullRequestReviewCommentInput!) { addPullRequestReviewComment(input: $input) { comment {