Path: blob/main/src/vs/sessions/contrib/chat/browser/openInVSCode.contribution.ts
13401 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Codicon } from '../../../../base/common/codicons.js';6import { Schemas } from '../../../../base/common/network.js';7import { URI } from '../../../../base/common/uri.js';8import { ServicesAccessor } from '../../../../editor/browser/editorExtensions.js';9import { localize2 } from '../../../../nls.js';10import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js';11import { AGENT_HOST_SCHEME, fromAgentHostUri } from '../../../../platform/agentHost/common/agentHostUri.js';12import { IRemoteAgentHostService } from '../../../../platform/agentHost/common/remoteAgentHostService.js';13import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';14import { IOpenerService } from '../../../../platform/opener/common/opener.js';15import { IProductService } from '../../../../platform/product/common/productService.js';16import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';17import { IsAuxiliaryWindowContext } from '../../../../workbench/common/contextkeys.js';18import { IsPhoneLayoutContext, SessionsWelcomeVisibleContext } from '../../../common/contextkeys.js';19import { logSessionsInteraction } from '../../../common/sessionsTelemetry.js';20import { Menus } from '../../../browser/menus.js';21import { isWorkspaceAgentSessionType } from '../../../services/sessions/common/session.js';22import { ISessionsManagementService } from '../../../services/sessions/common/sessionsManagement.js';23import { ISessionsProvidersService } from '../../../services/sessions/browser/sessionsProvidersService.js';24import { resolveRemoteAuthority } from './openInVSCodeUtils.js';2526/**27* Opens the host VS Code app from the Agents window via protocol handler.28* On desktop this action is replaced by the electron-browser override that29* uses {@link INativeHostService.launchSiblingApp} instead.30*/31registerAction2(class OpenSessionWorktreeInVSCodeAction extends Action2 {32static readonly ID = 'chat.openSessionWorktreeInVSCode';3334constructor() {35super({36id: OpenSessionWorktreeInVSCodeAction.ID,37title: localize2('openInVSCode', 'Open in VS Code'),38icon: Codicon.vscodeInsiders,39precondition: ContextKeyExpr.and(IsAuxiliaryWindowContext.toNegated(), SessionsWelcomeVisibleContext.toNegated()),40menu: [{41id: Menus.TitleBarSessionMenu,42group: 'navigation',43order: 7,44when: ContextKeyExpr.and(IsAuxiliaryWindowContext.toNegated(), SessionsWelcomeVisibleContext.toNegated(), IsPhoneLayoutContext.negate()),45}]46});47}4849override async run(accessor: ServicesAccessor): Promise<void> {50const telemetryService = accessor.get(ITelemetryService);51logSessionsInteraction(telemetryService, 'openInVSCode');5253const openerService = accessor.get(IOpenerService);54const productService = accessor.get(IProductService);55const sessionsManagementService = accessor.get(ISessionsManagementService);56const sessionsProvidersService = accessor.get(ISessionsProvidersService);57const remoteAgentHostService = accessor.get(IRemoteAgentHostService);5859const scheme = productService.quality === 'stable'60? 'vscode'61: productService.quality === 'exploration'62? 'vscode-exploration'63: productService.quality === 'insider'64? 'vscode-insiders'65: productService.urlProtocol;6667const params = new URLSearchParams();68params.set('windowId', '_blank');6970const activeSession = sessionsManagementService.activeSession.get();71if (!activeSession) {72await openerService.open(URI.from({ scheme, query: params.toString() }), { openExternal: true });73return;74}7576const workspace = activeSession.workspace.get();77const repo = workspace?.repositories[0];78const rawFolderUri = isWorkspaceAgentSessionType(activeSession.sessionType) ? repo?.workingDirectory ?? repo?.uri : undefined;7980if (!rawFolderUri) {81await openerService.open(URI.from({ scheme, query: params.toString() }), { openExternal: true });82return;83}8485const folderUri = rawFolderUri.scheme === AGENT_HOST_SCHEME ? fromAgentHostUri(rawFolderUri) : rawFolderUri;86const remoteAuthority = resolveRemoteAuthority(87activeSession.providerId, sessionsProvidersService, remoteAgentHostService);8889params.set('session', activeSession.resource.toString());9091if (remoteAuthority) {92await openerService.open(URI.from({93scheme,94authority: Schemas.vscodeRemote,95path: `/${remoteAuthority}${folderUri.path}`,96query: params.toString(),97}), { openExternal: true });98} else {99await openerService.open(URI.from({100scheme,101authority: Schemas.file,102path: folderUri.path,103query: params.toString(),104}), { openExternal: true });105}106}107});108109110