microsoft/vscode · #334554

sessions: move unified workspace picker setting

meganrogge · merged Sep 4, 202611 files · 92 + / 24
src/vs/sessions/contrib/chat/browser/chat.contribution.ts21 + / 2
@@ -15,6 +15,9 @@ import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextke import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationRegistry } from '../../../../platform/configuration/common/configurationRegistry.js'; import { IFileDialogService } from '../../../../platform/dialogs/common/dialogs.js'; import { IQuickInputService, IQuickPickItem, QuickPickInput } from '../../../../platform/quickinput/common/quickInput.js';+import product from '../../../../platform/product/common/product.js';+import { Registry } from '../../../../platform/registry/common/platform.js';+import { Extensions as WorkbenchConfigurationExtensions, IConfigurationMigrationRegistry } from '../../../../workbench/common/configuration.js'; import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../../workbench/common/contributions.js'; import { ISessionsService } from '../../../services/sessions/browser/sessionsService.js'; import { ISessionsManagementService, inheritableSessionTarget } from '../../../services/sessions/common/sessionsManagement.js';@@ -45,16 +48,16 @@ import { OpenSessionLinkOpenerContribution } from './openSessionLinkOpener.contr import { WorktreeCreatedTaskDispatcher, AGENT_HOST_RUN_WORKTREE_CREATED_TASKS_SETTING } from './worktreeCreatedTaskDispatcher.js'; import { AGENT_SESSIONS_SCOPED_INPUT_HISTORY_SETTING } from './sessionsChatHistory.js'; import '../../sessions/browser/mobile/mobileOverlayContribution.js';-import { Registry } from '../../../../platform/registry/common/platform.js'; import { EditorAreaFocusContext, IsSessionsWindowContext, SideBarVisibleContext } from '../../../../workbench/common/contextkeys.js';-import { NEW_SESSION_ACTION_ID } from '../common/constants.js';+import { NEW_SESSION_ACTION_ID, UNIFIED_WORKSPACE_PICKER_SETTING } from '../common/constants.js'; import { SessionsChatBackgroundAvailableContext, SessionsChatBackgroundImageConfiguredContext, SessionsTitleBarNewSessionEnabledContext, SessionsWelcomeVisibleContext } from '../../../common/contextkeys.js'; import { Menus } from '../../../browser/menus.js'; import { ISessionsChatViewStateService, SessionsChatViewStateService } from './chatViewStateService.js'; import { SessionsChatResponseFileChangesService } from './sessionTurnChanges.js'; import { IChatResponseFileChangesService } from '../../../../workbench/contrib/chat/browser/chatResponseFileChangesService.js'; import { SessionsChatPetAchievementContribution } from './chatPetAchievements.js'; import { AGENT_SESSIONS_CHAT_BACKGROUND_CODICONS_PRESET, AGENT_SESSIONS_PREFERRED_DARK_CHAT_BACKGROUND_IMAGE_LAYOUT_SETTING, AGENT_SESSIONS_PREFERRED_DARK_CHAT_BACKGROUND_IMAGE_SETTING, AGENT_SESSIONS_PREFERRED_LIGHT_CHAT_BACKGROUND_IMAGE_LAYOUT_SETTING, AGENT_SESSIONS_PREFERRED_LIGHT_CHAT_BACKGROUND_IMAGE_SETTING, chatBackgroundImageLayoutValues, ChatBackgroundImageLayout, ISessionsChatBackgroundService, SessionsChatBackgroundService } from '../../../services/chatBackground/browser/chatBackgroundService.js';+import { LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, unifiedWorkspacePickerConfigurationMigration } from './unifiedWorkspacePickerConfiguration.js';  const CHANGE_AGENT_SESSIONS_CHAT_BACKGROUND_COMMAND_ID = 'workbench.action.chat.changeAgentSessionsBackground'; const CHANGE_AGENT_SESSIONS_CHAT_BACKGROUND_LAYOUT_COMMAND_ID = 'workbench.action.chat.changeAgentSessionsBackgroundLayout';@@ -368,6 +371,20 @@ AccessibleViewRegistry.register(new SessionsChatAccessibilityHelp()); // register configuration Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).registerConfiguration({ 	properties: {+		[LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING]: {+			type: 'boolean',+			default: product.quality !== 'stable',+			scope: ConfigurationScope.APPLICATION,+			deprecationMessage: localize('chat.agentSessions.consolidatedRemoteWorkspaces.deprecated', "Deprecated. Use the unified workspace picker setting instead."),+		},+		[UNIFIED_WORKSPACE_PICKER_SETTING]: {+			type: 'boolean',+			default: product.quality !== 'stable',+			scope: ConfigurationScope.APPLICATION,+			description: localize('sessions.chat.unifiedWorkspacePicker.enabled', "Controls whether the Agents Window uses the unified workspace picker, which combines GitHub and remote workspaces, provides search, and, when supported, allows creating sessions with no workspace."),+			tags: ['experimental'],+			experiment: { mode: 'auto' },+		}, 		[AGENT_HOST_RUN_WORKTREE_CREATED_TASKS_SETTING]: { 			type: 'boolean', 			default: true,@@ -418,3 +435,5 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis 		}, 	}, });++Registry.as<IConfigurationMigrationRegistry>(WorkbenchConfigurationExtensions.ConfigurationMigration).registerConfigurationMigrations([unifiedWorkspacePickerConfigurationMigration]);
src/vs/sessions/contrib/chat/browser/newChatWidget.ts4 + / 3
@@ -48,13 +48,14 @@ import { chatInputStackClass, ChatInputStackSlot, setChatInputStackSlot } from ' import { IChatPetService } from '../../../../workbench/contrib/chat/browser/chatPetService.js'; import { IChatTipService } from '../../../../workbench/contrib/chat/browser/chatTipService.js'; import { ChatContextKeys } from '../../../../workbench/contrib/chat/common/actions/chatContextKeys.js';-import { ChatConfiguration, ChatModeKind } from '../../../../workbench/contrib/chat/common/constants.js';+import { ChatModeKind } from '../../../../workbench/contrib/chat/common/constants.js'; import { IOpenerService } from '../../../../platform/opener/common/opener.js'; import { IStorageService, StorageScope } from '../../../../platform/storage/common/storage.js'; import { TOTAL_SESSIONS_KEY } from '../../sessions/browser/sessionsLifecycleTracker.js'; import { INewSessionComposerService, NewSessionWorkspacePreselectionSource } from './newSessionComposerService.js'; import { Menus } from '../../../browser/menus.js'; import { getAdditionalFolderContextId, getAdditionalRepositoryContextId } from '../common/newChatContextIds.js';+import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../common/constants.js';  // #region --- New Chat Widget --- @@ -151,8 +152,8 @@ export class NewChatWidget extends Disposable { 		}); 		this._useConsolidatedRemoteWorkspaces = observableFromEvent( 			this,-			Event.filter(this.configurationService.onDidChangeConfiguration, event => event.affectsConfiguration(ChatConfiguration.ConsolidatedRemoteWorkspaces)),-			() => this.configurationService.getValue<boolean>(ChatConfiguration.ConsolidatedRemoteWorkspaces),+			Event.filter(this.configurationService.onDidChangeConfiguration, event => event.affectsConfiguration(UNIFIED_WORKSPACE_PICKER_SETTING)),+			() => this.configurationService.getValue<boolean>(UNIFIED_WORKSPACE_PICKER_SETTING), 		); 		this._isWorkspacePickerQuickChat = derived(this, reader => { 			const session = this._session.read(reader);
src/vs/sessions/contrib/chat/browser/sessionWorkspacePicker.ts2 + / 4
@@ -47,15 +47,13 @@ import { markOnboardingTarget } from '../../../../workbench/contrib/onboarding/b import { NewSessionWorkspacePreselectionSource } from './newSessionComposerService.js'; import { type IResolvedFolderWorkspace, SessionWorkspaceFallback } from './sessionWorkspaceFallback.js'; import { IChatRequestVariableEntry } from '../../../../workbench/contrib/chat/common/attachments/chatVariableEntries.js';-import { ChatConfiguration } from '../../../../workbench/contrib/chat/common/constants.js'; import { ADDITIONAL_FOLDER_CONTEXT_ID_PREFIX, ADDITIONAL_REPOSITORY_CONTEXT_ID_PREFIX, getAdditionalFolderContextId, getAdditionalRepositoryContextId } from '../common/newChatContextIds.js';+import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../common/constants.js';  export type { IResolvedFolderWorkspace } from './sessionWorkspaceFallback.js';  const FILTER_THRESHOLD = 10; -export const AGENT_SESSIONS_CONSOLIDATED_REMOTE_WORKSPACES_SETTING = ChatConfiguration.ConsolidatedRemoteWorkspaces;- /**  * Fixed picker width when the categorical tab bar is shown. Keeps the tab  * row and the list aligned and prevents horizontal jitter when switching@@ -1254,7 +1252,7 @@ export class WorkspacePicker extends Disposable { 	}  	protected _useConsolidatedRemoteWorkspaces(): boolean {-		return this.configurationService.getValue<boolean>(AGENT_SESSIONS_CONSOLIDATED_REMOTE_WORKSPACES_SETTING);+		return this.configurationService.getValue<boolean>(UNIFIED_WORKSPACE_PICKER_SETTING); 	}  	private _getTabGroup(group: string | undefined): string | undefined {
src/vs/sessions/contrib/chat/browser/unifiedWorkspacePickerConfiguration.tsadded21 + / 0
@@ -0,0 +1,21 @@+/*---------------------------------------------------------------------------------------------+ *  Copyright (c) Microsoft Corporation. All rights reserved.+ *  Licensed under the MIT License. See License.txt in the project root for license information.+ *--------------------------------------------------------------------------------------------*/++import { ConfigurationKeyValuePairs, ConfigurationMigration } from '../../../../workbench/common/configuration.js';+import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../common/constants.js';++export const LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING = 'chat.agentSessions.consolidatedRemoteWorkspaces';++export const unifiedWorkspacePickerConfigurationMigration: ConfigurationMigration = {+	key: LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING,+	includeApplication: true,+	migrateFn: (value, accessor) => {+		const pairs: ConfigurationKeyValuePairs = [[LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, { value: undefined }]];+		if (accessor(UNIFIED_WORKSPACE_PICKER_SETTING) === undefined) {+			pairs.push([UNIFIED_WORKSPACE_PICKER_SETTING, { value }]);+		}+		return pairs;+	},+};
src/vs/sessions/contrib/chat/common/constants.ts1 + / 0
@@ -4,3 +4,4 @@  *--------------------------------------------------------------------------------------------*/  export const NEW_SESSION_ACTION_ID = 'workbench.action.sessions.newChat';+export const UNIFIED_WORKSPACE_PICKER_SETTING = 'sessions.chat.unifiedWorkspacePicker.enabled';
src/vs/sessions/contrib/chat/test/browser/sessionWorkspacePicker.test.ts3 + / 2
@@ -34,7 +34,8 @@ import { ISendRequestOptions, ISessionChangeEvent, ISessionsProvider } from '../ import { AgentHostFilterConnectionStatus, IAgentHostFilterEntry } from '../../../../services/agentHostFilter/common/agentHostFilter.js'; import { IAgentHostSessionsProvider } from '../../../../common/agentHostSessionsProvider.js'; import { ISession, ISessionWorkspace, ISessionWorkspaceBrowseAction, SessionStatus, SESSION_WORKSPACE_GROUP_GITHUB, SESSION_WORKSPACE_GROUP_LOCAL, SESSION_WORKSPACE_GROUP_REMOTE } from '../../../../services/sessions/common/session.js';-import { AGENT_SESSIONS_CONSOLIDATED_REMOTE_WORKSPACES_SETTING, IWorkspacePickerItem, IWorkspacePickerOptions, WorkspacePicker } from '../../browser/sessionWorkspacePicker.js';+import { IWorkspacePickerItem, IWorkspacePickerOptions, WorkspacePicker } from '../../browser/sessionWorkspacePicker.js';+import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../../common/constants.js'; import { WebWorkspacePicker } from '../../browser/webWorkspacePicker.js'; import { NewSessionWorkspacePreselectionSource } from '../../browser/newSessionComposerService.js'; import { ISessionsRecentWorkspacesService, SessionsRecentWorkspacesService } from '../../../../services/sessions/browser/sessionsRecentWorkspacesService.js';@@ -3050,7 +3051,7 @@ function createTestablePicker( 	instantiationService.stub(IOutputService, {}); 	instantiationService.stub(IConfigurationService, new TestConfigurationService({ 		[RemoteAgentHostsEnabledSettingId]: remoteAgentHostsEnabled,-		[AGENT_SESSIONS_CONSOLIDATED_REMOTE_WORKSPACES_SETTING]: consolidatedRemoteWorkspaces,+		[UNIFIED_WORKSPACE_PICKER_SETTING]: consolidatedRemoteWorkspaces, 	})); 	instantiationService.stub(ICommandService, commandService); 	instantiationService.stub(IFileDialogService, {});
src/vs/sessions/contrib/chat/test/browser/unifiedWorkspacePickerConfiguration.test.tsadded36 + / 0
@@ -0,0 +1,36 @@+/*---------------------------------------------------------------------------------------------+ *  Copyright (c) Microsoft Corporation. All rights reserved.+ *  Licensed under the MIT License. See License.txt in the project root for license information.+ *--------------------------------------------------------------------------------------------*/++import assert from 'assert';+import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';+import { LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, unifiedWorkspacePickerConfigurationMigration } from '../../browser/unifiedWorkspacePickerConfiguration.js';+import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../../common/constants.js';++suite('UnifiedWorkspacePickerConfiguration', () => {++	ensureNoDisposablesAreLeakedInTestSuite();++	test('migrates application values without overwriting the new setting', async () => {+		const copiedValue = await unifiedWorkspacePickerConfigurationMigration.migrateFn(true, () => undefined);+		const preservedValue = await unifiedWorkspacePickerConfigurationMigration.migrateFn(false, key => key === UNIFIED_WORKSPACE_PICKER_SETTING ? true : undefined);++		assert.deepStrictEqual({+			key: unifiedWorkspacePickerConfigurationMigration.key,+			includeApplication: unifiedWorkspacePickerConfigurationMigration.includeApplication,+			copiedValue,+			preservedValue,+		}, {+			key: LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING,+			includeApplication: true,+			copiedValue: [+				[LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, { value: undefined }],+				[UNIFIED_WORKSPACE_PICKER_SETTING, { value: true }],+			],+			preservedValue: [+				[LEGACY_UNIFIED_WORKSPACE_PICKER_SETTING, { value: undefined }],+			],+		});+	});+});
src/vs/sessions/contrib/sessions/browser/views/sessionsViewActions.ts2 + / 2
@@ -43,8 +43,8 @@ import { registerExternalSessionsFilterMenu } from '../../../../../workbench/con import { ICustomViewService } from '../../../../services/customView/browser/customViewService.js'; import { IAutomationService } from '../../../../../workbench/contrib/chat/common/automations/automationService.js'; import { ChatAutomationsEnabledContext } from '../../../../../workbench/contrib/chat/common/automations/automationsEnabled.js';-import { ChatConfiguration } from '../../../../../workbench/contrib/chat/common/constants.js'; import { AUTOMATIONS_CUSTOM_VIEW_ID } from '../automationsConstants.js';+import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../../../chat/common/constants.js';  const CLOSE_SESSION_COMMAND_ID = 'sessionsViewPane.closeSession'; registerAction2(class CloseSessionAction extends Action2 {@@ -546,7 +546,7 @@ registerAction2(class NewQuickChatAction extends Action2 { 		const sessionsService = accessor.get(ISessionsService); 		const sessionsPartService = accessor.get(ISessionsPartService); 		let activeSession;-		if (accessor.get(IConfigurationService).getValue<boolean>(ChatConfiguration.ConsolidatedRemoteWorkspaces)) {+		if (accessor.get(IConfigurationService).getValue<boolean>(UNIFIED_WORKSPACE_PICKER_SETTING)) { 			if (accessor.get(ISessionsManagementService).isQuickChatTargetAvailable()) { 				sessionsService.unsetNewSession(); 				sessionsPartService.getSessionView(undefined)?.selectNoWorkspace();
src/vs/sessions/contrib/sessions/test/browser/sessionsActions.test.ts2 + / 2
@@ -13,7 +13,6 @@ import { IConfigurationService } from '../../../../../platform/configuration/com import { TestConfigurationService } from '../../../../../platform/configuration/test/common/testConfigurationService.js'; import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js'; import { workbenchInstantiationService } from '../../../../../workbench/test/browser/workbenchTestServices.js';-import { ChatConfiguration } from '../../../../../workbench/contrib/chat/common/constants.js'; import { Menus } from '../../../../browser/menus.js'; import { SESSION_CONVERSATION_SIDE_CHATS_GROUP } from '../../../../browser/sessionConversationGroups.js'; import { SessionView } from '../../../../browser/parts/sessionView.js';@@ -26,6 +25,7 @@ import { mock, upcastPartial } from '../../../../../base/test/common/mock.js'; import { SessionConversationActionsContribution } from '../../browser/sessionsActions.js'; import '../../browser/views/sessionsViewActions.js'; import { createTestSession } from './sessionsListTestUtils.js';+import { UNIFIED_WORKSPACE_PICKER_SETTING } from '../../../chat/common/constants.js';  suite('Sessions - Actions', () => { @@ -136,7 +136,7 @@ suite('Sessions - Actions', () => { 			let focusedSessionId: string | undefined;  			instantiationService.stub(IConfigurationService, new TestConfigurationService({-				[ChatConfiguration.ConsolidatedRemoteWorkspaces]: consolidatedRemoteWorkspaces,+				[UNIFIED_WORKSPACE_PICKER_SETTING]: consolidatedRemoteWorkspaces, 			})); 			instantiationService.stub(ISessionsManagementService, new class extends mock<ISessionsManagementService>() { 				override isQuickChatTargetAvailable(): boolean {
src/vs/workbench/contrib/chat/browser/chat.shared.contribution.ts0 + / 8
@@ -482,14 +482,6 @@ configurationRegistry.registerConfiguration({ 			experiment: { mode: 'auto' }, 			agentHost: { key: AgentHostShowExternalSessionsConfigKey }, 		},-		[ChatConfiguration.ConsolidatedRemoteWorkspaces]: {-			type: 'boolean',-			default: product.quality !== 'stable',-			scope: ConfigurationScope.APPLICATION,-			description: nls.localize('chat.agentSessions.consolidatedRemoteWorkspaces', "Controls whether GitHub and remote workspaces are combined under Remote in the Agents Window workspace picker, with search always available and, when supported, a No workspace option."),-			tags: ['experimental'],-			experiment: { mode: 'auto' },-		}, 		[ChatConfiguration.SaveBeforeSend]: { 			type: 'boolean', 			description: nls.localize('chat.saveBeforeSend', "Controls whether all dirty editors except untitled editors are saved before sending a chat message."),
src/vs/workbench/contrib/chat/common/constants.ts0 + / 1
@@ -53,7 +53,6 @@ export enum ChatConfiguration { 	AgentSessionProjectionEnabled = 'chat.agentSessionProjection.enabled', 	MigrateLegacyCopilotCliSessions = 'chat.agentSessions.migrateLegacyCopilotCli', 	ShowExternalAgentSessions = 'chat.agentSessions.showExternal',-	ConsolidatedRemoteWorkspaces = 'chat.agentSessions.consolidatedRemoteWorkspaces', 	ExtensionToolsEnabled = 'chat.extensionTools.enabled', 	RepoInfoEnabled = 'chat.repoInfo.enabled', 	EditRequests = 'chat.editRequests',