From f543112f1c0f22d37a7dd3872fe99bc6260f4f7a 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:06 +0000 Subject: [PATCH 1/8] Initial plan From 7454f1928cce4de93f8dcc7e3eccb72d7fb28535 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:17:26 +0000 Subject: [PATCH 2/8] Initial exploration complete - planning to add "Create in Browser" button 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 534c04fd8b82537cc03e50ee6ea70f9c958cc913 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:27:26 +0000 Subject: [PATCH 3/8] Add "Create in Browser" button to PR creation view Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/github/createPRViewProvider.ts | 28 ++++++++++++++++++++++- webviews/common/createContextNew.ts | 4 ++++ webviews/createPullRequestViewNew/app.tsx | 4 ++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/github/createPRViewProvider.ts b/src/github/createPRViewProvider.ts index 40763443bb..308b9ab277 100644 --- a/src/github/createPRViewProvider.ts +++ b/src/github/createPRViewProvider.ts @@ -505,6 +505,29 @@ export abstract class BaseCreatePullRequestViewProvider { + // Get the base repository info + const baseRepo = this.getBaseGitHubRepo(); + if (!baseRepo) { + vscode.window.showErrorMessage(vscode.l10n.t('Unable to find repository to create pull request in.')); + return; + } + + // Get the compare branch name - this is the branch we want to create a PR from + const compareBranch = this._defaultCompareBranch; + if (!compareBranch) { + vscode.window.showErrorMessage(vscode.l10n.t('Unable to determine branch to create pull request from.')); + return; + } + + // Construct the GitHub URL for creating a PR + // Format: https://github.com/{owner}/{repo}/pull/new/{branch} + // or https://github.com/{owner}/{repo}/compare/{base}...{head} for cross-repo PRs + const url = `${baseRepo.remote.url}/pull/new/${compareBranch}`; + + await vscode.env.openExternal(vscode.Uri.parse(url)); + } + protected override async _onDidReceiveMessage(message: IRequestMessage) { const result = await super._onDidReceiveMessage(message); if (result !== this.MESSAGE_UNHANDLED) { @@ -539,6 +562,9 @@ export abstract class BaseCreatePullRequestViewProvider => { + return this.postMessage({ command: 'pr.openCreateInBrowser' }); + }; + public updateState = (params: Partial, reset: boolean = false): void => { this.createParams = reset ? { ...defaultCreateParams, ...params } : { ...this.createParams, ...params }; vscode.setState(this.createParams); diff --git a/webviews/createPullRequestViewNew/app.tsx b/webviews/createPullRequestViewNew/app.tsx index d762585360..3c9d2dc4c5 100644 --- a/webviews/createPullRequestViewNew/app.tsx +++ b/webviews/createPullRequestViewNew/app.tsx @@ -354,6 +354,10 @@ export function main() { Cancel + + makeCreateMenuContext(params)} defaultAction={onCreateButton} defaultOptionLabel={() => createMethodLabel(ctx.createParams.isDraft, ctx.createParams.autoMerge, ctx.createParams.autoMergeMethod, ctx.createParams.baseHasMergeQueue).label} From 14f043d14ecd488c36e752c3b9023f2a7edc3f3f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 11:29:16 +0000 Subject: [PATCH 4/8] Fix URL construction to use normalized host Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/github/createPRViewProvider.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/github/createPRViewProvider.ts b/src/github/createPRViewProvider.ts index 308b9ab277..30af38ea7b 100644 --- a/src/github/createPRViewProvider.ts +++ b/src/github/createPRViewProvider.ts @@ -522,8 +522,7 @@ export abstract class BaseCreatePullRequestViewProvider Date: Tue, 9 Dec 2025 11:32:35 +0000 Subject: [PATCH 5/8] URL-encode branch name for safety Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/github/createPRViewProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/github/createPRViewProvider.ts b/src/github/createPRViewProvider.ts index 30af38ea7b..310b3950eb 100644 --- a/src/github/createPRViewProvider.ts +++ b/src/github/createPRViewProvider.ts @@ -522,7 +522,7 @@ export abstract class BaseCreatePullRequestViewProvider Date: Fri, 12 Dec 2025 10:14:49 +0000 Subject: [PATCH 6/8] Change approach: Add createInBrowser setting instead of UI button Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- package.json | 5 ++++ src/common/settingKeys.ts | 1 + src/view/reviewManager.ts | 49 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/package.json b/package.json index 121adffe67..261a71aebd 100644 --- a/package.json +++ b/package.json @@ -349,6 +349,11 @@ "default": "ask", "description": "%githubPullRequests.createOnPublishBranch.description%" }, + "githubPullRequests.createInBrowser": { + "type": "boolean", + "default": false, + "description": "When true, the 'Create Pull Request' command opens GitHub in the browser instead of showing the create view in VS Code." + }, "githubPullRequests.commentExpandState": { "type": "string", "enum": [ diff --git a/src/common/settingKeys.ts b/src/common/settingKeys.ts index 1376c4c7bc..9d26fc0010 100644 --- a/src/common/settingKeys.ts +++ b/src/common/settingKeys.ts @@ -39,6 +39,7 @@ export type PullPRBranchVariants = 'never' | 'pull' | 'pullAndMergeBase' | 'pull export const UPSTREAM_REMOTE = 'upstreamRemote'; export const DEFAULT_CREATE_OPTION = 'defaultCreateOption'; export const CREATE_BASE_BRANCH = 'createDefaultBaseBranch'; +export const CREATE_IN_BROWSER = 'createInBrowser'; export const ISSUES_SETTINGS_NAMESPACE = 'githubIssues'; export const ASSIGN_WHEN_WORKING = 'assignWhenWorking'; diff --git a/src/view/reviewManager.ts b/src/view/reviewManager.ts index b9c31fac14..58376b89c9 100644 --- a/src/view/reviewManager.ts +++ b/src/view/reviewManager.ts @@ -1170,6 +1170,15 @@ export class ReviewManager extends Disposable { } public async createPullRequest(compareBranch?: string): Promise { + // Check if user wants to create PR in browser + const createInBrowser = vscode.workspace.getConfiguration(PR_SETTINGS_NAMESPACE).get('createInBrowser', false); + + if (createInBrowser) { + // Open browser to create PR instead of showing the create view + await this.openCreatePullRequestInBrowser(compareBranch); + return; + } + const postCreate = async (createdPR: PullRequestModel | undefined) => { if (!createdPR) { return; @@ -1208,6 +1217,46 @@ export class ReviewManager extends Disposable { return this._createPullRequestHelper.create(this._telemetry, this._context.extensionUri, this._folderRepoManager, compareBranch, postCreate); } + private async openCreatePullRequestInBrowser(compareBranch?: string): Promise { + try { + // Get the current branch + const branch = compareBranch + ? await this._folderRepoManager.repository.getBranch(compareBranch) + : this._folderRepoManager.repository.state.HEAD; + + if (!branch?.name) { + vscode.window.showErrorMessage(vscode.l10n.t('Unable to determine the current branch.')); + return; + } + + // Get pull request defaults which includes the base branch + const pullRequestDefaults = await this._folderRepoManager.getPullRequestDefaults(branch); + + // Get the origin to determine the repository + const compareOrigin = await this._folderRepoManager.getOrigin(branch); + + // Find the GitHub repository for the base + const baseRepo = this._folderRepoManager.gitHubRepositories.find( + repo => repo.remote.owner === pullRequestDefaults.owner && + repo.remote.repositoryName === compareOrigin.remote.repositoryName + ); + + if (!baseRepo) { + vscode.window.showErrorMessage(vscode.l10n.t('Unable to find repository to create pull request in.')); + return; + } + + // Construct the GitHub URL + // Format: https://github.com/{owner}/{repo}/compare/{base}...{head} + const url = `${baseRepo.remote.normalizedHost}/${pullRequestDefaults.owner}/${compareOrigin.remote.repositoryName}/compare/${pullRequestDefaults.base}...${encodeURIComponent(branch.name)}`; + + await vscode.env.openExternal(vscode.Uri.parse(url)); + } catch (error) { + Logger.error(`Failed to open create pull request in browser: ${error}`, 'ReviewManager'); + vscode.window.showErrorMessage(vscode.l10n.t('Failed to open create pull request in browser: {0}', formatError(error))); + } + } + public async openDescription(): Promise { const pullRequest = this._folderRepoManager.activePullRequest; if (!pullRequest) { From 940b826f4fbfc82741db72f2e0eb9df81617c0df Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:17:30 +0000 Subject: [PATCH 7/8] Address code review feedback: Use constant and add clarifying comment Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/view/reviewManager.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/view/reviewManager.ts b/src/view/reviewManager.ts index 58376b89c9..c183f0bd47 100644 --- a/src/view/reviewManager.ts +++ b/src/view/reviewManager.ts @@ -24,6 +24,7 @@ import Logger from '../common/logger'; import { parseRepositoryRemotes, Remote } from '../common/remote'; import { COMMENTS, + CREATE_IN_BROWSER, FOCUSED_MODE, IGNORE_PR_BRANCHES, NEVER_IGNORE_DEFAULT_BRANCH, @@ -1171,7 +1172,7 @@ export class ReviewManager extends Disposable { public async createPullRequest(compareBranch?: string): Promise { // Check if user wants to create PR in browser - const createInBrowser = vscode.workspace.getConfiguration(PR_SETTINGS_NAMESPACE).get('createInBrowser', false); + const createInBrowser = vscode.workspace.getConfiguration(PR_SETTINGS_NAMESPACE).get(CREATE_IN_BROWSER, false); if (createInBrowser) { // Open browser to create PR instead of showing the create view @@ -1236,6 +1237,8 @@ export class ReviewManager extends Disposable { const compareOrigin = await this._folderRepoManager.getOrigin(branch); // Find the GitHub repository for the base + // Note: pullRequestDefaults.owner is the target owner (may differ from current fork) + // compareOrigin.remote.repositoryName is the repository we're working in const baseRepo = this._folderRepoManager.gitHubRepositories.find( repo => repo.remote.owner === pullRequestDefaults.owner && repo.remote.repositoryName === compareOrigin.remote.repositoryName From d72d7ab17e5d026d418269732e03f0b8d4c65ba3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Dec 2025 16:57:27 +0000 Subject: [PATCH 8/8] Revert create view related changes Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/github/createPRViewProvider.ts | 27 +---------------------- webviews/common/createContextNew.ts | 4 ---- webviews/createPullRequestViewNew/app.tsx | 4 ---- 3 files changed, 1 insertion(+), 34 deletions(-) diff --git a/src/github/createPRViewProvider.ts b/src/github/createPRViewProvider.ts index 310b3950eb..40763443bb 100644 --- a/src/github/createPRViewProvider.ts +++ b/src/github/createPRViewProvider.ts @@ -505,28 +505,6 @@ export abstract class BaseCreatePullRequestViewProvider { - // Get the base repository info - const baseRepo = this.getBaseGitHubRepo(); - if (!baseRepo) { - vscode.window.showErrorMessage(vscode.l10n.t('Unable to find repository to create pull request in.')); - return; - } - - // Get the compare branch name - this is the branch we want to create a PR from - const compareBranch = this._defaultCompareBranch; - if (!compareBranch) { - vscode.window.showErrorMessage(vscode.l10n.t('Unable to determine branch to create pull request from.')); - return; - } - - // Construct the GitHub URL for creating a PR - // Format: https://github.com/{owner}/{repo}/pull/new/{branch} - const url = `${baseRepo.remote.normalizedHost}/${baseRepo.remote.owner}/${baseRepo.remote.repositoryName}/pull/new/${encodeURIComponent(compareBranch)}`; - - await vscode.env.openExternal(vscode.Uri.parse(url)); - } - protected override async _onDidReceiveMessage(message: IRequestMessage) { const result = await super._onDidReceiveMessage(message); if (result !== this.MESSAGE_UNHANDLED) { @@ -561,9 +539,6 @@ export abstract class BaseCreatePullRequestViewProvider => { - return this.postMessage({ command: 'pr.openCreateInBrowser' }); - }; - public updateState = (params: Partial, reset: boolean = false): void => { this.createParams = reset ? { ...defaultCreateParams, ...params } : { ...this.createParams, ...params }; vscode.setState(this.createParams); diff --git a/webviews/createPullRequestViewNew/app.tsx b/webviews/createPullRequestViewNew/app.tsx index 3c9d2dc4c5..d762585360 100644 --- a/webviews/createPullRequestViewNew/app.tsx +++ b/webviews/createPullRequestViewNew/app.tsx @@ -354,10 +354,6 @@ export function main() { Cancel - - makeCreateMenuContext(params)} defaultAction={onCreateButton} defaultOptionLabel={() => createMethodLabel(ctx.createParams.isDraft, ctx.createParams.autoMerge, ctx.createParams.autoMergeMethod, ctx.createParams.baseHasMergeQueue).label}