From 68153e22276411abd393a2dda28338d17972ae0a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 12:27:06 +0000 Subject: [PATCH 1/6] Initial plan From 4c8c06e3407c05d2d3a582f49508836dc10f9976 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 12:30:49 +0000 Subject: [PATCH 2/6] Initial plan for issue view copy link fix Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- .../vscode.proposed.chatContextProvider.d.ts | 13 +- ...ode.proposed.chatParticipantAdditions.d.ts | 184 ++++++++++++++- ...scode.proposed.chatParticipantPrivate.d.ts | 89 ++----- .../vscode.proposed.chatSessionsProvider.d.ts | 217 ++++++++++++++++-- 4 files changed, 411 insertions(+), 92 deletions(-) diff --git a/src/@types/vscode.proposed.chatContextProvider.d.ts b/src/@types/vscode.proposed.chatContextProvider.d.ts index ee971b9adb..043e067be1 100644 --- a/src/@types/vscode.proposed.chatContextProvider.d.ts +++ b/src/@types/vscode.proposed.chatContextProvider.d.ts @@ -16,7 +16,10 @@ declare module 'vscode' { * Providers registered without a selector will not be called for resource-based context. * - Explicitly. These context items are shown as options when the user explicitly attaches context. * - * To ensure your extension is activated when chat context is requested, make sure to include the `onChatContextProvider:` activation event in your `package.json`. + * To ensure your extension is activated when chat context is requested, make sure to include the following activations events: + * - If your extension implements `provideWorkspaceChatContext` or `provideChatContextForResource`, find an activation event which is a good signal to activate. + * Ex: `onLanguage:`, `onWebviewPanel:`, etc.` + * - If your extension implements `provideChatContextExplicit`, your extension will be automatically activated when the user requests explicit context. * * @param selector Optional document selector to filter which resources the provider is called for. If omitted, the provider will only be called for explicit context requests. * @param id Unique identifier for the provider. @@ -49,7 +52,7 @@ declare module 'vscode' { value?: string; /** * An optional command that is executed when the context item is clicked. - * The original context item will be passed as an argument to the command. + * The original context item will be passed as the first argument to the command. */ command?: Command; } @@ -62,7 +65,11 @@ declare module 'vscode' { onDidChangeWorkspaceChatContext?: Event; /** - * Provide a list of chat context items to be included as workspace context for all chat sessions. + * TODO @API: should this be a separate provider interface? + * + * Provide a list of chat context items to be included as workspace context for all chat requests. + * This should be used very sparingly to avoid providing useless context and to avoid using up the context window. + * A good example use case is to provide information about which branch the user is working on in a source control context. * * @param token A cancellation token. */ diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index aa7001a3d2..8ef3f9335e 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -65,6 +65,29 @@ declare module 'vscode' { constructor(uri: Uri, edits: NotebookEdit | NotebookEdit[]); } + /** + * Represents a file-level edit (creation, deletion, or rename). + */ + export interface ChatWorkspaceFileEdit { + /** + * The original file URI (undefined for new files). + */ + oldResource?: Uri; + + /** + * The new file URI (undefined for deleted files). + */ + newResource?: Uri; + } + + /** + * Represents a workspace edit containing file-level operations. + */ + export class ChatResponseWorkspaceEditPart { + edits: ChatWorkspaceFileEdit[]; + constructor(edits: ChatWorkspaceFileEdit[]); + } + export class ChatResponseConfirmationPart { title: string; message: string | MarkdownString; @@ -80,9 +103,12 @@ declare module 'vscode' { constructor(value: Uri, license: string, snippet: string); } - export class ChatPrepareToolInvocationPart { - toolName: string; - constructor(toolName: string); + export interface ChatToolInvocationStreamData { + /** + * Partial or not-yet-validated arguments that have streamed from the language model. + * Tools may use this to render interim UI while the full invocation input is collected. + */ + readonly partialInput?: unknown; } export interface ChatTerminalToolInvocationData { @@ -92,6 +118,48 @@ declare module 'vscode' { toolEdited?: string; }; language: string; + + /** + * Terminal command output. Displayed when the terminal is no longer available. + */ + output?: { + /** The raw output text, may include ANSI escape codes. */ + text: string; + }; + + /** + * Command execution state. + */ + state?: { + /** Exit code of the command. */ + exitCode?: number; + /** Duration of execution in milliseconds. */ + duration?: number; + }; + } + + export class McpToolInvocationContentData { + /** + * The mime type which determines how the data property is interpreted. + */ + mimeType: string; + + /** + * The byte data for this part. + */ + data: Uint8Array; + + /** + * Construct a generic data part with the given content. + * @param data The byte data for this part. + * @param mimeType The mime type of the data. + */ + constructor(data: Uint8Array, mimeType: string); + } + + export interface ChatMcpToolInvocationData { + input: string; + output: McpToolInvocationContentData[]; } export class ChatToolInvocationPart { @@ -103,8 +171,8 @@ declare module 'vscode' { pastTenseMessage?: string | MarkdownString; isConfirmed?: boolean; isComplete?: boolean; - toolSpecificData?: ChatTerminalToolInvocationData; - fromSubAgent?: boolean; + toolSpecificData?: ChatTerminalToolInvocationData | ChatMcpToolInvocationData; + subAgentInvocationId?: string; presentation?: 'hidden' | 'hiddenAfterComplete' | undefined; constructor(toolName: string, toolCallId: string, isError?: boolean); @@ -176,7 +244,7 @@ declare module 'vscode' { constructor(uris: Uri[], callback: () => Thenable); } - export type ExtendedChatResponsePart = ChatResponsePart | ChatResponseTextEditPart | ChatResponseNotebookEditPart | ChatResponseConfirmationPart | ChatResponseCodeCitationPart | ChatResponseReferencePart2 | ChatResponseMovePart | ChatResponseExtensionsPart | ChatResponsePullRequestPart | ChatPrepareToolInvocationPart | ChatToolInvocationPart | ChatResponseMultiDiffPart | ChatResponseThinkingProgressPart | ChatResponseExternalEditPart; + export type ExtendedChatResponsePart = ChatResponsePart | ChatResponseTextEditPart | ChatResponseNotebookEditPart | ChatResponseWorkspaceEditPart | ChatResponseConfirmationPart | ChatResponseCodeCitationPart | ChatResponseReferencePart2 | ChatResponseMovePart | ChatResponseExtensionsPart | ChatResponsePullRequestPart | ChatToolInvocationPart | ChatResponseMultiDiffPart | ChatResponseThinkingProgressPart | ChatResponseExternalEditPart; export class ChatResponseWarningPart { value: MarkdownString; constructor(value: string | MarkdownString); @@ -310,6 +378,12 @@ declare module 'vscode' { notebookEdit(target: Uri, isDone: true): void; + /** + * Push a workspace edit containing file-level operations (create, delete, rename). + * @param edits Array of file-level edits to apply + */ + workspaceEdit(edits: ChatWorkspaceFileEdit[]): void; + /** * Makes an external edit to one or more resources. Changes to the * resources made within the `callback` and before it resolves will be @@ -349,7 +423,21 @@ declare module 'vscode' { codeCitation(value: Uri, license: string, snippet: string): void; - prepareToolInvocation(toolName: string): void; + /** + * Begin a tool invocation in streaming mode. This creates a tool invocation that will + * display streaming progress UI until the tool is actually invoked. + * @param toolCallId Unique identifier for this tool call, used to correlate streaming updates and final invocation. + * @param toolName The name of the tool being invoked. + * @param streamData Optional initial streaming data with partial arguments. + */ + beginToolInvocation(toolCallId: string, toolName: string, streamData?: ChatToolInvocationStreamData & { subagentInvocationId?: string }): void; + + /** + * Update the streaming data for a tool invocation that was started with `beginToolInvocation`. + * @param toolCallId The tool call ID that was passed to `beginToolInvocation`. + * @param streamData New streaming data with updated partial arguments. + */ + updateToolInvocation(toolCallId: string, streamData: ChatToolInvocationStreamData): void; push(part: ExtendedChatResponsePart): void; @@ -404,7 +492,7 @@ declare module 'vscode' { /** * A map of all tools that should (`true`) and should not (`false`) be used in this request. */ - readonly tools: Map; + readonly tools: Map; } export namespace lm { @@ -494,6 +582,47 @@ declare module 'vscode' { export type ChatExtendedRequestHandler = (request: ChatRequest, context: ChatContext, response: ChatResponseStream, token: CancellationToken) => ProviderResult; + /** + * Details about the prompt token usage by category and label. + */ + export interface ChatResultPromptTokenDetail { + /** + * The category this token usage belongs to (e.g., "System", "Context", "Conversation"). + */ + readonly category: string; + + /** + * The label for this specific token usage (e.g., "System prompt", "Attached files"). + */ + readonly label: string; + + /** + * The percentage of the total prompt tokens this represents (0-100). + */ + readonly percentageOfPrompt: number; + } + + /** + * Token usage information for a chat request. + */ + export interface ChatResultUsage { + /** + * The number of prompt tokens used in this request. + */ + readonly promptTokens: number; + + /** + * The number of completion tokens generated in this response. + */ + readonly completionTokens: number; + + /** + * Optional breakdown of prompt token usage by category and label. + * If the percentages do not sum to 100%, the remaining will be shown as "Uncategorized". + */ + readonly promptTokenDetails?: readonly ChatResultPromptTokenDetail[]; + } + export interface ChatResult { nextQuestion?: { prompt: string; @@ -504,6 +633,12 @@ declare module 'vscode' { * An optional detail string that will be rendered at the end of the response in certain UI contexts. */ details?: string; + + /** + * Token usage information for this request, if available. + * This is typically provided by the underlying language model. + */ + readonly usage?: ChatResultUsage; } export namespace chat { @@ -668,6 +803,39 @@ declare module 'vscode' { export interface LanguageModelToolInvocationOptions { model?: LanguageModelChat; + chatStreamToolCallId?: string; + } + + export interface LanguageModelToolInvocationStreamOptions { + /** + * Raw argument payload, such as the streamed JSON fragment from the language model. + */ + readonly rawInput?: unknown; + + readonly chatRequestId?: string; + /** @deprecated Use {@link chatSessionResource} instead */ + readonly chatSessionId?: string; + readonly chatSessionResource?: Uri; + readonly chatInteractionId?: string; + } + + export interface LanguageModelToolStreamResult { + /** + * A customized progress message to show while the tool runs. + */ + invocationMessage?: string | MarkdownString; + } + + export interface LanguageModelTool { + /** + * Called zero or more times before {@link LanguageModelTool.prepareInvocation} while the + * language model streams argument data for the invocation. Use this to update progress + * or UI with the partial arguments that have been generated so far. + * + * Implementations must be free of side-effects and should be resilient to receiving + * malformed or incomplete input. + */ + handleToolStream?(options: LanguageModelToolInvocationStreamOptions, token: CancellationToken): ProviderResult; } export interface ChatRequest { diff --git a/src/@types/vscode.proposed.chatParticipantPrivate.d.ts b/src/@types/vscode.proposed.chatParticipantPrivate.d.ts index c4a40a62c0..4ab722c122 100644 --- a/src/@types/vscode.proposed.chatParticipantPrivate.d.ts +++ b/src/@types/vscode.proposed.chatParticipantPrivate.d.ts @@ -61,10 +61,17 @@ declare module 'vscode' { readonly attempt: number; /** - * The session identifier for this chat request + * The session identifier for this chat request. + * + * @deprecated Use {@link chatSessionResource} instead. */ readonly sessionId: string; + /** + * The resource URI for the chat session this request belongs to. + */ + readonly sessionResource: Uri; + /** * If automatic command detection is enabled. */ @@ -93,7 +100,16 @@ declare module 'vscode' { */ readonly editedFileEvents?: ChatRequestEditedFileEvent[]; - readonly isSubagent?: boolean; + /** + * Unique ID for the subagent invocation, used to group tool calls from the same subagent run together. + * Pass this to tool invocations when calling tools from within a subagent context. + */ + readonly subAgentInvocationId?: string; + + /** + * Display name of the subagent that is invoking this request. + */ + readonly subAgentName?: string; } export enum ChatRequestEditedFileEventKind { @@ -230,13 +246,15 @@ declare module 'vscode' { export interface LanguageModelToolInvocationOptions { chatRequestId?: string; + /** @deprecated Use {@link chatSessionResource} instead */ chatSessionId?: string; + chatSessionResource?: Uri; chatInteractionId?: string; terminalCommand?: string; /** - * Lets us add some nicer UI to toolcalls that came from a sub-agent, but in the long run, this should probably just be rendered in a similar way to thinking text + tool call groups + * Unique ID for the subagent invocation, used to group tool calls from the same subagent run together. */ - fromSubAgent?: boolean; + subAgentInvocationId?: string; } export interface LanguageModelToolInvocationPrepareOptions { @@ -245,7 +263,9 @@ declare module 'vscode' { */ input: T; chatRequestId?: string; + /** @deprecated Use {@link chatSessionResource} instead */ chatSessionId?: string; + chatSessionResource?: Uri; chatInteractionId?: string; } @@ -319,65 +339,4 @@ declare module 'vscode' { } // #endregion - - // #region CustomAgentsProvider - - /** - * Represents a custom agent resource file (e.g., .agent.md or .prompt.md) available for a repository. - */ - export interface CustomAgentResource { - /** - * The unique identifier/name of the custom agent resource. - */ - readonly name: string; - - /** - * A description of what the custom agent resource does. - */ - readonly description: string; - - /** - * The URI to the agent or prompt resource file. - */ - readonly uri: Uri; - - /** - * Indicates whether the custom agent resource is editable. Defaults to false. - */ - readonly isEditable?: boolean; - } - - /** - * Options for querying custom agents. - */ - export interface CustomAgentQueryOptions { } - - /** - * A provider that supplies custom agent resources (from .agent.md and .prompt.md files) for repositories. - */ - export interface CustomAgentsProvider { - /** - * An optional event to signal that custom agents have changed. - */ - readonly onDidChangeCustomAgents?: Event; - - /** - * Provide the list of custom agent resources available for a given repository. - * @param options Optional query parameters. - * @param token A cancellation token. - * @returns An array of custom agent resources or a promise that resolves to such. - */ - provideCustomAgents(options: CustomAgentQueryOptions, token: CancellationToken): ProviderResult; - } - - export namespace chat { - /** - * Register a provider for custom agents. - * @param provider The custom agents provider. - * @returns A disposable that unregisters the provider when disposed. - */ - export function registerCustomAgentsProvider(provider: CustomAgentsProvider): Disposable; - } - - // #endregion } diff --git a/src/@types/vscode.proposed.chatSessionsProvider.d.ts b/src/@types/vscode.proposed.chatSessionsProvider.d.ts index 2ec68c1731..84cd547599 100644 --- a/src/@types/vscode.proposed.chatSessionsProvider.d.ts +++ b/src/@types/vscode.proposed.chatSessionsProvider.d.ts @@ -26,6 +26,25 @@ declare module 'vscode' { InProgress = 2 } + export namespace chat { + /** + * Registers a new {@link ChatSessionItemProvider chat session item provider}. + * + * To use this, also make sure to also add `chatSessions` contribution in the `package.json`. + * + * @param chatSessionType The type of chat session the provider is for. + * @param provider The provider to register. + * + * @returns A disposable that unregisters the provider when disposed. + */ + export function registerChatSessionItemProvider(chatSessionType: string, provider: ChatSessionItemProvider): Disposable; + + /** + * Creates a new {@link ChatSessionItemController chat session item controller} with the given unique identifier. + */ + export function createChatSessionItemController(id: string, refreshHandler: () => Thenable): ChatSessionItemController; + } + /** * Provides a list of information about chat sessions. */ @@ -52,6 +71,84 @@ declare module 'vscode' { // #endregion } + /** + * Provides a list of information about chat sessions. + */ + export interface ChatSessionItemController { + readonly id: string; + + /** + * Unregisters the controller, disposing of its associated chat session items. + */ + dispose(): void; + + /** + * Managed collection of chat session items + */ + readonly items: ChatSessionItemCollection; + + /** + * Creates a new managed chat session item that be added to the collection. + */ + createChatSessionItem(resource: Uri, label: string): ChatSessionItem; + + /** + * Handler called to refresh the collection of chat session items. + * + * This is also called on first load to get the initial set of items. + */ + refreshHandler: () => Thenable; + + /** + * Fired when an item's archived state changes. + */ + readonly onDidChangeChatSessionItemState: Event; + } + + /** + * A collection of chat session items. It provides operations for managing and iterating over the items. + */ + export interface ChatSessionItemCollection extends Iterable { + /** + * Gets the number of items in the collection. + */ + readonly size: number; + + /** + * Replaces the items stored by the collection. + * @param items Items to store. + */ + replace(items: readonly ChatSessionItem[]): void; + + /** + * Iterate over each entry in this collection. + * + * @param callback Function to execute for each entry. + * @param thisArg The `this` context used when invoking the handler function. + */ + forEach(callback: (item: ChatSessionItem, collection: ChatSessionItemCollection) => unknown, thisArg?: any): void; + + /** + * Adds the chat session item to the collection. If an item with the same resource URI already + * exists, it'll be replaced. + * @param item Item to add. + */ + add(item: ChatSessionItem): void; + + /** + * Removes a single chat session item from the collection. + * @param resource Item resource to delete. + */ + delete(resource: Uri): void; + + /** + * Efficiently gets a chat session item by resource, if it exists, in the collection. + * @param resource Item resource to get. + * @returns The found item or undefined if it does not exist. + */ + get(resource: Uri): ChatSessionItem | undefined; + } + export interface ChatSessionItem { /** * The resource associated with the chat session. @@ -91,15 +188,42 @@ declare module 'vscode' { tooltip?: string | MarkdownString; /** - * The times at which session started and ended + * Whether the chat session has been archived. + */ + archived?: boolean; + + /** + * Timing information for the chat session */ timing?: { + /** + * Timestamp when the session was created in milliseconds elapsed since January 1, 1970 00:00:00 UTC. + */ + created: number; + + /** + * Timestamp when the most recent request started in milliseconds elapsed since January 1, 1970 00:00:00 UTC. + * + * Should be undefined if no requests have been made yet. + */ + lastRequestStarted?: number; + + /** + * Timestamp when the most recent request completed in milliseconds elapsed since January 1, 1970 00:00:00 UTC. + * + * Should be undefined if the most recent request is still in progress or if no requests have been made yet. + */ + lastRequestEnded?: number; + /** * Session start timestamp in milliseconds elapsed since January 1, 1970 00:00:00 UTC. + * @deprecated Use `created` and `lastRequestStarted` instead. */ - startTime: number; + startTime?: number; + /** * Session end timestamp in milliseconds elapsed since January 1, 1970 00:00:00 UTC. + * @deprecated Use `lastRequestEnded` instead. */ endTime?: number; }; @@ -107,7 +231,7 @@ declare module 'vscode' { /** * Statistics about the chat session. */ - changes?: readonly ChatSessionChangedFile[] | { + changes?: readonly ChatSessionChangedFile[] | readonly ChatSessionChangedFile2[] | { /** * Number of files edited during the session. */ @@ -149,6 +273,35 @@ declare module 'vscode' { constructor(modifiedUri: Uri, insertions: number, deletions: number, originalUri?: Uri); } + export class ChatSessionChangedFile2 { + /** + * URI of the file. + */ + readonly uri: Uri; + + /** + * URI of the original file. Undefined if the file was created. + */ + readonly originalUri: Uri | undefined; + + /** + * URI of the modified file. Undefined if the file was deleted. + */ + readonly modifiedUri: Uri | undefined; + + /** + * Number of insertions made during the session. + */ + insertions: number; + + /** + * Number of deletions made during the session. + */ + deletions: number; + + constructor(uri: Uri, originalUri: Uri | undefined, modifiedUri: Uri | undefined, insertions: number, deletions: number); + } + export interface ChatSession { /** * The full history of the session @@ -252,7 +405,7 @@ declare module 'vscode' { * Called as soon as you register (call me once) * @param token */ - provideChatSessionProviderOptions?(token: CancellationToken): Thenable | ChatSessionProviderOptions; + provideChatSessionProviderOptions?(token: CancellationToken): Thenable; } export interface ChatSessionOptionUpdate { @@ -268,18 +421,6 @@ declare module 'vscode' { } export namespace chat { - /** - * Registers a new {@link ChatSessionItemProvider chat session item provider}. - * - * To use this, also make sure to also add `chatSessions` contribution in the `package.json`. - * - * @param chatSessionType The type of chat session the provider is for. - * @param provider The provider to register. - * - * @returns A disposable that unregisters the provider when disposed. - */ - export function registerChatSessionItemProvider(chatSessionType: string, provider: ChatSessionItemProvider): Disposable; - /** * Registers a new {@link ChatSessionContentProvider chat session content provider}. * @@ -337,6 +478,12 @@ declare module 'vscode' { * An icon for the option item shown in UI. */ readonly icon?: ThemeIcon; + + /** + * Indicates if this option should be selected by default. + * Only one item per option group should be marked as default. + */ + readonly default?: boolean; } /** @@ -362,6 +509,44 @@ declare module 'vscode' { * The selectable items within this option group. */ readonly items: ChatSessionProviderOptionItem[]; + + /** + * A context key expression that controls when this option group picker is visible. + * When specified, the picker is only shown when the expression evaluates to true. + * The expression can reference other option group values via `chatSessionOption.`. + * + * Example: `"chatSessionOption.models == 'gpt-4'"` - only show this picker when + * the 'models' option group has 'gpt-4' selected. + */ + readonly when?: string; + + /** + * When true, displays a searchable QuickPick with a "See more..." option. + * Recommended for option groups with additional async items (e.g., repositories). + */ + readonly searchable?: boolean; + + /** + * An icon for the option group shown in UI. + */ + readonly icon?: ThemeIcon; + + /** + * Handler for dynamic search when `searchable` is true. + * Called when the user types in the searchable QuickPick or clicks "See more..." to load additional items. + * + * @param query The search query entered by the user. Empty string for initial load. + * @param token A cancellation token. + * @returns Additional items to display in the searchable QuickPick. + */ + readonly onSearch?: (query: string, token: CancellationToken) => Thenable; + + /** + * Optional commands. + * + * These commands will be displayed at the bottom of the group. + */ + readonly commands?: Command[]; } export interface ChatSessionProviderOptions { From 8852122917e7064892d8ad37835e779a9e2e0479 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 12:32:08 +0000 Subject: [PATCH 3/6] Add IssueOverview webview to copy link context menu registration Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 16cb91b838..ec8c67c88b 100644 --- a/package.json +++ b/package.json @@ -3552,11 +3552,11 @@ }, { "command": "pr.copyPrLink", - "when": "webviewId == PullRequestOverview && github:copyMenu" + "when": "(webviewId == PullRequestOverview || webviewId == IssueOverview) && github:copyMenu" }, { "command": "pr.copyVscodeDevPrLink", - "when": "webviewId == PullRequestOverview && github:copyMenu" + "when": "(webviewId == PullRequestOverview || webviewId == IssueOverview) && github:copyMenu" }, { "command": "pr.readyForReviewDescription", From 4ff224bf005de71fd6444917891c5379c515886f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 12:34:13 +0000 Subject: [PATCH 4/6] Fix copy link commands to also resolve issues Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- src/commands.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index c59075f7a0..6e31118a3f 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1565,32 +1565,40 @@ ${contents} context.subscriptions.push( vscode.commands.registerCommand('pr.copyVscodeDevPrLink', async (params: OverviewContext | undefined) => { - let pr: PullRequestModel | undefined; + let item: PullRequestModel | IssueModel | undefined; if (params) { - pr = await reposManager.getManagerForRepository(params.owner, params.repo)?.resolvePullRequest(params.owner, params.repo, params.number, true); + const folderManager = reposManager.getManagerForRepository(params.owner, params.repo); + item = await folderManager?.resolvePullRequest(params.owner, params.repo, params.number, true); + if (!item) { + item = await folderManager?.resolveIssue(params.owner, params.repo, params.number); + } } else { const activePullRequests: PullRequestModel[] = reposManager.folderManagers .map(folderManager => folderManager.activePullRequest!) .filter(activePR => !!activePR); - pr = await chooseItem( + item = await chooseItem( activePullRequests, itemValue => ({ label: `${itemValue.number}: ${itemValue.title}` }), { placeHolder: vscode.l10n.t('Pull request to create a link for') }, ); } - if (pr) { - return vscode.env.clipboard.writeText(vscodeDevPrLink(pr)); + if (item) { + return vscode.env.clipboard.writeText(vscodeDevPrLink(item)); } })); context.subscriptions.push( vscode.commands.registerCommand('pr.copyPrLink', async (params: OverviewContext | undefined) => { - let pr: PullRequestModel | undefined; + let item: PullRequestModel | IssueModel | undefined; if (params) { - pr = await reposManager.getManagerForRepository(params.owner, params.repo)?.resolvePullRequest(params.owner, params.repo, params.number, true); + const folderManager = reposManager.getManagerForRepository(params.owner, params.repo); + item = await folderManager?.resolvePullRequest(params.owner, params.repo, params.number, true); + if (!item) { + item = await folderManager?.resolveIssue(params.owner, params.repo, params.number); + } } - if (pr) { - return vscode.env.clipboard.writeText(pr.html_url); + if (item) { + return vscode.env.clipboard.writeText(item.html_url); } })); From 9c5a98ebc64094dd6a6f9a72f86889497114d0f5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:39:23 +0000 Subject: [PATCH 5/6] Remove vscode.dev link option from issue overview context menu Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- package.json | 2 +- src/commands.ts | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index ec8c67c88b..5241f65756 100644 --- a/package.json +++ b/package.json @@ -3556,7 +3556,7 @@ }, { "command": "pr.copyVscodeDevPrLink", - "when": "(webviewId == PullRequestOverview || webviewId == IssueOverview) && github:copyMenu" + "when": "webviewId == PullRequestOverview && github:copyMenu" }, { "command": "pr.readyForReviewDescription", diff --git a/src/commands.ts b/src/commands.ts index 6e31118a3f..575ca9f7fd 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1565,25 +1565,21 @@ ${contents} context.subscriptions.push( vscode.commands.registerCommand('pr.copyVscodeDevPrLink', async (params: OverviewContext | undefined) => { - let item: PullRequestModel | IssueModel | undefined; + let pr: PullRequestModel | undefined; if (params) { - const folderManager = reposManager.getManagerForRepository(params.owner, params.repo); - item = await folderManager?.resolvePullRequest(params.owner, params.repo, params.number, true); - if (!item) { - item = await folderManager?.resolveIssue(params.owner, params.repo, params.number); - } + pr = await reposManager.getManagerForRepository(params.owner, params.repo)?.resolvePullRequest(params.owner, params.repo, params.number, true); } else { const activePullRequests: PullRequestModel[] = reposManager.folderManagers .map(folderManager => folderManager.activePullRequest!) .filter(activePR => !!activePR); - item = await chooseItem( + pr = await chooseItem( activePullRequests, itemValue => ({ label: `${itemValue.number}: ${itemValue.title}` }), { placeHolder: vscode.l10n.t('Pull request to create a link for') }, ); } - if (item) { - return vscode.env.clipboard.writeText(vscodeDevPrLink(item)); + if (pr) { + return vscode.env.clipboard.writeText(vscodeDevPrLink(pr)); } })); From 621e7fbb32d7b64184ab8345b2ce7bf0397573f6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 23 Jan 2026 18:28:58 +0000 Subject: [PATCH 6/6] Rename variable 'item' to 'prOrIssue' for better readability Co-authored-by: rzhao271 <7199958+rzhao271@users.noreply.github.com> --- src/commands.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index 575ca9f7fd..ec59474778 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1585,16 +1585,16 @@ ${contents} context.subscriptions.push( vscode.commands.registerCommand('pr.copyPrLink', async (params: OverviewContext | undefined) => { - let item: PullRequestModel | IssueModel | undefined; + let prOrIssue: PullRequestModel | IssueModel | undefined; if (params) { const folderManager = reposManager.getManagerForRepository(params.owner, params.repo); - item = await folderManager?.resolvePullRequest(params.owner, params.repo, params.number, true); - if (!item) { - item = await folderManager?.resolveIssue(params.owner, params.repo, params.number); + prOrIssue = await folderManager?.resolvePullRequest(params.owner, params.repo, params.number, true); + if (!prOrIssue) { + prOrIssue = await folderManager?.resolveIssue(params.owner, params.repo, params.number); } } - if (item) { - return vscode.env.clipboard.writeText(item.html_url); + if (prOrIssue) { + return vscode.env.clipboard.writeText(prOrIssue.html_url); } }));