Skip to content

Copilot CLI Controller API#4828

Merged
DonJayamanne merged 7 commits intomainfrom
don/controller-dropdowns-alone-centipede
Mar 30, 2026
Merged

Copilot CLI Controller API#4828
DonJayamanne merged 7 commits intomainfrom
don/controller-dropdowns-alone-centipede

Conversation

@DonJayamanne
Copy link
Copy Markdown
Collaborator

@DonJayamanne DonJayamanne commented Mar 30, 2026

@DonJayamanne DonJayamanne self-assigned this Mar 30, 2026
@DonJayamanne DonJayamanne force-pushed the don/controller-dropdowns-alone-centipede branch from ceda65f to 4c2ae0c Compare March 30, 2026 17:29
@DonJayamanne DonJayamanne marked this pull request as ready for review March 30, 2026 19:16
Copilot AI review requested due to automatic review settings March 30, 2026 19:16
@DonJayamanne DonJayamanne enabled auto-merge March 30, 2026 19:18
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Copilot CLI chat sessions integration to align with a newer VS Code chat sessions controller API, introducing an inputState-based options model (replacing the legacy sessionOptions flow) and adapting the CLI sessions provider accordingly.

Changes:

  • Updates proposed VS Code typings for chat sessions to introduce ChatSessionInputState, getChatSessionInputState, and selected option items (and deprecates legacy option APIs).
  • Refactors CopilotCLIChatSessionContentProvider to provide option groups via input state and to build “existing session” input state groups.
  • Adjusts folder/repository initialization logic and updates affected unit tests; bumps the pinned vscodeCommit.

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/extension/vscode.proposed.chatSessionsProvider.d.ts Adds ChatSessionInputState + controller input-state APIs; deprecates legacy session options plumbing.
src/extension/vscode.proposed.chatParticipantAdditions.d.ts Removes a legacy ChatResultFeedback shape from proposed typings.
src/extension/chatSessions/vscode-node/test/copilotCLIChatSessions.spec.ts Updates provider construction to match the refactored CLI chat sessions provider dependencies.
src/extension/chatSessions/vscode-node/folderRepositoryManagerImpl.ts Uses an explicitly selected folder when initializing a new session; simplifies uncommitted-changes prompt condition.
src/extension/chatSessions/vscode-node/copilotCLIChatSessions.ts Migrates CLI sessions provider to the new controller/input-state option model and reshapes option group building.
package.json Updates the pinned vscodeCommit.
Comments suppressed due to low confidence (7)

src/extension/chatSessions/vscode-node/copilotCLIChatSessions.ts:643

  • In the welcome view, this option group sets selected: previouslySelected which is commonly undefined on first open, leaving no default selection even when items is non-empty. That can lead to session creation with no folder/repo selected. Consider defaulting selected to a valid entry (MRU/last-used) and ensuring selected always matches an item in items.
			optionGroups.push({
				id: REPOSITORY_OPTION_ID,
				name: l10n.t('Folder'),
				description: l10n.t('Pick Folder'),
				items,
				selected: previouslySelected,
				commands
			});

src/extension/chatSessions/vscode-node/copilotCLIChatSessions.ts:655

  • previousInputState’s repository selection is used directly. If that repo is no longer present in repositories, the selected value will not be one of items (which conflicts with the new selected contract and can confuse the UI). Resolve selected by id against repositories and fall back when missing.
			if (repositories.length > 1) {
				const previouslySelected = previousInputState?.groups.find(g => g.id === REPOSITORY_OPTION_ID)?.selected ?? repositories[0];
				defaultRepoUri = previouslySelected?.id ? vscode.Uri.file(previouslySelected.id) : defaultRepoUri;
				optionGroups.push({
					id: REPOSITORY_OPTION_ID,
					name: l10n.t('Folder'),
					description: l10n.t('Pick Folder'),
					items: repositories,
					selected: previouslySelected ?? repositories[0]
				});

src/extension/chatSessions/vscode-node/copilotCLIChatSessions.ts:670

  • selectedItem for the branch option group can end up coming from previousInputState even when it’s not present in the newly computed branches list (e.g. branch deleted/renamed). Ensure selected is either an element of branches or cleared so it always matches items.
			const repo = defaultRepoUri ? await this.gitService.getRepository(defaultRepoUri) : undefined;
			const branches = repo ? await this.getBranchOptionItemsForRepository(repo.rootUri, repo.headBranchName) : [];
			const previouslySelectedBranchItem = previousInputState?.groups.find(g => g.id === BRANCH_OPTION_ID)?.selected;
			const activeBranch = repo?.headBranchName ? branches.find(branch => branch.id === repo.headBranchName) : undefined;
			const selectedBranch = previouslySelectedBranchItem?.id || activeBranch?.id;
			const selectedItem = (selectedBranch ? branches.find(branch => branch.id === selectedBranch) : undefined) ?? previouslySelectedBranchItem;
			if (branches.length > 0) {

src/extension/chatSessions/vscode-node/copilotCLIChatSessions.ts:592

  • LAST_USED_ISOLATION_OPTION_KEY is used to pick a default isolation option, but this file no longer updates that key when the user changes isolation. That means the default can become stale across sessions/restarts. Persist the selected isolation mode when input state changes (e.g. via inputState.onDidChange or a command handler).
		const previouslySelectedIsolationOption = previousInputState?.groups.find(g => g.id === ISOLATION_OPTION_ID)?.selected;
		if (isIsolationOptionFeatureEnabled(this.configurationService)) {
			const lastUsed = this.context.globalState.get<IsolationMode>(LAST_USED_ISOLATION_OPTION_KEY, IsolationMode.Workspace);
			const defaultSelection = lastUsed === IsolationMode.Workspace ?
				{ id: IsolationMode.Workspace, name: l10n.t('Workspace'), icon: new vscode.ThemeIcon('folder') } :
				{ id: IsolationMode.Worktree, name: l10n.t('Worktree'), icon: new vscode.ThemeIcon('worktree') };

src/extension/chatSessions/vscode-node/copilotCLIChatSessions.ts:317

  • The provider now relies on controller.getChatSessionInputState + provideChatSessionProviderOptionGroups(previousInputState) for session configuration (folder/isolation/branch), but the spec only covers PR detection. Add Vitest coverage for input-state group construction (defaulting + selection validity) and for the "Browse folders..." command updating inputState so the chosen folder is actually used when creating a session.
		controller.getChatSessionInputState = async (sessionResource, context, token) => {
			const groups = sessionResource ? await this.buildExistingSessionInputStateGroups(sessionResource, token) : await this.provideChatSessionProviderOptionGroups(context.previousInputState);
			return controller.createChatSessionInputState(groups);
		};

src/extension/chatSessions/vscode-node/copilotCLIChatSessions.ts:1903

  • This handler still assumes it’s invoked with a vscode.Uri (it calls SessionIdForCLI.parse(sessionItemResource)), but with the new ChatSessionInputState API, option-group commands are invoked with a context object (e.g. { inputState, sessionResource }). As-is, this will mis-handle the command payload and can crash at runtime; it also doesn’t update inputState.groups to apply the selected folder back into the UI/session options.

		const sessionId = SessionIdForCLI.parse(sessionItemResource);
		if (copilotCLISessionService.isNewSessionId(sessionId)) {
			await contentProvider.trackLastUsedFolderInWelcomeView(selectedFolderUri);
		}
	}));

src/extension/chatSessions/vscode-node/copilotCLIChatSessions.ts:228

  • The CopilotCLIChatSessionContentProvider constructor signature changed (removed ICopilotCLIAgents / IFileSystemService, added IAgentSessionsWorkspace), but not all instantiations appear updated. For example, src/extension/chatSessions/vscode-node/test/copilotCLIChatSessionParticipant.spec.ts still calls new CopilotCLIChatSessionContentProvider(itemProvider, new NullCopilotCLIAgents(), ..., new MockFileSystemService(), ...), which will fail to compile/run tests.
	constructor(
		@ICopilotCLISessionService private readonly sessionService: ICopilotCLISessionService,
		@IChatSessionMetadataStore private readonly chatSessionMetadataStore: IChatSessionMetadataStore,
		@IChatSessionWorktreeService private readonly copilotCLIWorktreeManagerService: IChatSessionWorktreeService,
		@IWorkspaceService private readonly workspaceService: IWorkspaceService,
		@IGitService private readonly gitService: IGitService,
		@IFolderRepositoryManager private readonly folderRepositoryManager: IFolderRepositoryManager,
		@IConfigurationService private readonly configurationService: IConfigurationService,

@DonJayamanne DonJayamanne added this pull request to the merge queue Mar 30, 2026
Merged via the queue into main with commit 4495675 Mar 30, 2026
23 checks passed
@DonJayamanne DonJayamanne deleted the don/controller-dropdowns-alone-centipede branch March 30, 2026 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants