Path: blob/main/extensions/copilot/src/extension/onboardDebug/vscode-node/copilotDebugCommandSession.ts
13399 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 * as l10n from '@vscode/l10n';6import * as vscode from 'vscode';7import { DisposableStore } from '../../../util/vs/base/common/lifecycle';8import { generateUuid } from '../../../util/vs/base/common/uuid';9import { ILaunchConfigService } from '../common/launchConfigService';10import { IStartOptions } from '../node/copilotDebugWorker/shared';11import { CopilotDebugCommandHandle } from './copilotDebugCommandHandle';1213const TRACKED_SESSION_KEY = '__copilotTrackedSession';1415export const handleDebugSession = (16launchConfigService: ILaunchConfigService,17workspaceFolder: vscode.WorkspaceFolder | undefined,18config: vscode.DebugConfiguration,19handle: CopilotDebugCommandHandle,20once: boolean,21startAgain: (opts: Partial<IStartOptions>) => Promise<void>,22) => {23const trackedId = generateUuid();24const store = new DisposableStore();2526let gotRoot = false;27const sessions = new Set<vscode.DebugSession>();2829async function ended(code: number, message?: string) {30if (store.isDisposed) {31return;32}3334let color: 'red' | 'blue';3536if (code !== 0) {37color = 'red';38message ??= l10n.t('Debug session errored');39} else {40color = 'blue';41message ??= l10n.t('Session ended');42}4344handle.printLabel(color, message);45store.dispose();46followup();47}4849async function followup() {50switch (once ? 'Q' : await handle.getFollowupKeys(CopilotDebugCommandHandle.COPILOT_LABEL.length + 3)) {51case 'Enter':52handleDebugSession(launchConfigService, workspaceFolder, config, handle, once, startAgain);53break;54case 'R':55startAgain({ forceNew: true });56break;57case 'S':58await launchConfigService.add(workspaceFolder?.uri, { configurations: [config] });59if (workspaceFolder) {60await launchConfigService.show(workspaceFolder.uri, config.name);61}62handle.exit(0);63break;64case 'V':65await handle.printJson(config);66followup();67break;68case 'Q':69default:70handle.exit(0);71}72}7374handle.ended.then(() => {75if (!store.isDisposed) {76sessions.forEach(s => vscode.debug.stopDebugging(s));77}78});7980store.add(vscode.debug.registerDebugAdapterTrackerFactory('*', {81createDebugAdapterTracker(session) {82if (session.configuration[TRACKED_SESSION_KEY] !== trackedId && (!session.parentSession || !sessions.has(session.parentSession))) {83return;84}8586// handle nested sessions:87const isRoot = !gotRoot;88gotRoot = true;89sessions.add(session);9091return {92onWillStartSession() {93if (isRoot) {94handle.printLabel('blue', l10n.t('Debug session starting...'));95}96},97onDidSendMessage(message) {98if (message.type === 'event' && message.event === 'output' && message.body.output) {99handle.output(message.body.category, message.body.output);100}101},102onExit(code, signal) {103if (isRoot) {104ended(code ?? 0, signal);105}106},107onWillStopSession() {108if (isRoot) {109ended(0);110}111},112};113},114}));115116vscode.debug.startDebugging(workspaceFolder, { ...config, [TRACKED_SESSION_KEY]: trackedId }).then(ok => {117if (!ok) {118// error will be displayed to user by vscode119ended(1);120}121});122};123124125