Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2612,6 +2612,12 @@
"title": "%github.copilot.command.checkoutPullRequestReroute.title%",
"icon": "$(git-pull-request)",
"category": "GitHub Pull Request"
},
{
"command": "github.copilot.chat.cloudSessions.openRepository",
"title": "%github.copilot.command.cloudSessions.openRepository.title%",
"icon": "$(repo)",
"category": "GitHub Copilot"
}
],
"configuration": [
Expand Down Expand Up @@ -4497,6 +4503,10 @@
"command": "github.copilot.chat.checkoutPullRequestReroute",
"when": "false"
},
{
"command": "github.copilot.chat.cloudSessions.openRepository",
"when": "false"
},
{
"command": "github.copilot.nes.captureExpected.start",
"when": "github.copilot.inlineEditsEnabled"
Expand Down
1 change: 1 addition & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@
"github.copilot.command.installPRExtension.title": "Install GitHub Pull Request Extension",
"github.copilot.chat.applyCopilotCLIAgentSessionChanges.apply": "Apply",
"github.copilot.command.checkoutPullRequestReroute.title": "Checkout",
"github.copilot.command.cloudSessions.openRepository.title": "Browse repositories...",
"github.copilot.command.applyCopilotCLIAgentSessionChanges": "Apply Changes to Workspace",
"github.copilot.config.githubMcpServer.enabled": "Enable built-in support for the GitHub MCP Server.",
"github.copilot.config.githubMcpServer.toolsets": "Specify toolsets to use from the GitHub MCP Server. [Learn more](https://aka.ms/vscode-gh-mcp-toolsets).",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const DEFAULT_REPOSITORY_ID = '___vscode_repository_default___';

const ACTIVE_SESSION_POLL_INTERVAL_MS = 5 * 1000; // 5 seconds
const SEEN_DELEGATION_PROMPT_KEY = 'seenDelegationPromptBefore';
const OPEN_REPOSITORY_COMMAND_ID = 'github.copilot.chat.cloudSessions.openRepository';

// TODO: No API from GH yet.
const HARDCODED_PARTNER_AGENTS: { id: string; name: string; at?: string; assignableActorLogin?: string }[] = [
Expand Down Expand Up @@ -144,6 +145,8 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C
public readonly onDidCommitChatSessionItem = this._onDidCommitChatSessionItem.event;
private readonly _onDidChangeChatSessionProviderOptions = this._register(new vscode.EventEmitter<void>());
public readonly onDidChangeChatSessionProviderOptions = this._onDidChangeChatSessionProviderOptions.event;
private readonly _onDidChangeChatSessionOptions = this._register(new vscode.EventEmitter<vscode.ChatSessionOptionChangeEvent>());
public readonly onDidChangeChatSessionOptions = this._onDidChangeChatSessionOptions.event;
private chatSessions: Map<number, PullRequestSearchItem> = new Map();
private chatSessionItemsPromise: Promise<vscode.ChatSessionItem[]> | undefined;
private readonly sessionCustomAgentMap = new ResourceMap<string>();
Expand Down Expand Up @@ -295,6 +298,68 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C
}
};
this._register(vscode.commands.registerCommand('github.copilot.chat.checkoutPullRequestReroute', checkoutPullRequestReroute));

// Command for browsing repositories in the repository picker
const openRepositoryCommand = async (sessionItemResource?: vscode.Uri) => {
const quickPick = vscode.window.createQuickPick();
quickPick.placeholder = l10n.t('Search for a repository...');
quickPick.matchOnDescription = true;
quickPick.matchOnDetail = true;
quickPick.busy = true;
quickPick.show();

// Load initial repositories
try {
const repos = await this.fetchAllRepositoriesFromGitHub();
quickPick.items = repos.map(repo => ({ label: repo.name }));
} catch (error) {
this.logService.error(`Error fetching initial repositories: ${error}`);
} finally {
quickPick.busy = false;
}

// Handle dynamic search
let searchTimeout: ReturnType<typeof setTimeout> | undefined;
const onDidChangeValueDisposable = quickPick.onDidChangeValue(async (value) => {
if (searchTimeout) {
clearTimeout(searchTimeout);
}
searchTimeout = setTimeout(async () => {
quickPick.busy = true;
try {
const searchResults = await this.fetchAllRepositoriesFromGitHub(value);
quickPick.items = searchResults.map(repo => ({ label: repo.name }));
} finally {
quickPick.busy = false;
}
}, 300);
});

const onDidAcceptDisposable = quickPick.onDidAccept(() => {
const selected = quickPick.selectedItems[0];
if (selected && sessionItemResource) {
this.sessionRepositoryMap.set(sessionItemResource, selected.label);
this._onDidChangeChatSessionOptions.fire({
resource: sessionItemResource,
updates: [{
optionId: REPOSITORIES_OPTION_GROUP_ID,
value: { id: selected.label, name: selected.label, icon: new vscode.ThemeIcon('repo') }
}]
});
}
quickPick.hide();
});

quickPick.onDidHide(() => {
if (searchTimeout) {
clearTimeout(searchTimeout);
}
onDidChangeValueDisposable.dispose();
onDidAcceptDisposable.dispose();
quickPick.dispose();
});
};
this._register(vscode.commands.registerCommand(OPEN_REPOSITORY_COMMAND_ID, openRepositoryCommand));
}

private getRefreshIntervalTime(hasHistoricalSessions: boolean): number {
Expand Down Expand Up @@ -514,12 +579,13 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C
optionGroups.push({
id: REPOSITORIES_OPTION_GROUP_ID,
name: vscode.l10n.t('Repository'),
description: vscode.l10n.t('Select repository'),
icon: new vscode.ThemeIcon('repo'),
items,
onSearch: async (query, token) => {
return await this.fetchAllRepositoriesFromGitHub(query);
},
searchable: true
commands: [{
command: OPEN_REPOSITORY_COMMAND_ID,
title: vscode.l10n.t('Browse repositories...'),
}]
});
}

Expand All @@ -546,6 +612,7 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C
id: `${repoId.org}/${repoId.repo}`,
name: `${repoId.org}/${repoId.repo}`,
default: index === 0,
icon: new vscode.ThemeIcon('repo'),
});
});
} else {
Expand All @@ -557,6 +624,7 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C
items.push({
id: nwo,
name: nwo,
icon: new vscode.ThemeIcon('repo'),
});
}
} catch (error) {
Expand Down
6 changes: 6 additions & 0 deletions src/extension/vscode.proposed.chatSessionsProvider.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,12 @@ declare module 'vscode' {
* @returns Additional items to display in the searchable QuickPick.
*/
readonly onSearch?: (query: string, token: CancellationToken) => Thenable<ChatSessionProviderOptionItem[]>;

/**
* Commands to display as actions in the option group dropdown.
* These commands are shown as clickable options in the picker UI.
*/
readonly commands?: Command[];
}

export interface ChatSessionProviderOptions {
Expand Down