From 5c9a7c6e04cacba148d0fc271a45bd1e8de0b5ae Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 19 Mar 2026 13:23:18 +0100 Subject: [PATCH] Adding chat debug view in Sessions window (#303172) show chat debug view in sessions app --- build/lib/i18n.resources.json | 4 + .../browser/chatDebug.contribution.ts | 88 +++++++++++++++++++ src/vs/sessions/sessions.desktop.main.ts | 1 + 3 files changed, 93 insertions(+) create mode 100644 src/vs/sessions/contrib/chatDebug/browser/chatDebug.contribution.ts diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index 26e1e273027..76c1462e389 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -679,6 +679,10 @@ { "name": "vs/sessions/contrib/welcome", "project": "vscode-sessions" + }, + { + "name": "vs/sessions/contrib/chatDebug", + "project": "vscode-sessions" } ] } diff --git a/src/vs/sessions/contrib/chatDebug/browser/chatDebug.contribution.ts b/src/vs/sessions/contrib/chatDebug/browser/chatDebug.contribution.ts new file mode 100644 index 00000000000..dbb92718c71 --- /dev/null +++ b/src/vs/sessions/contrib/chatDebug/browser/chatDebug.contribution.ts @@ -0,0 +1,88 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Codicon } from '../../../../base/common/codicons.js'; +import { Disposable } from '../../../../base/common/lifecycle.js'; +import { localize, localize2 } from '../../../../nls.js'; +import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js'; +import { Registry } from '../../../../platform/registry/common/platform.js'; +import { registerIcon } from '../../../../platform/theme/common/iconRegistry.js'; +import { ViewPaneContainer } from '../../../../workbench/browser/parts/views/viewPaneContainer.js'; +import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../../workbench/common/contributions.js'; +import { IViewContainersRegistry, IViewDescriptor, IViewsRegistry, ViewContainerLocation, Extensions as ViewContainerExtensions, WindowVisibility } from '../../../../workbench/common/views.js'; + +const COPILOT_CHAT_VIEW_CONTAINER_ID = 'workbench.view.extension.copilot-chat'; +const COPILOT_CHAT_VIEW_ID = 'copilot-chat'; +const SESSIONS_CHAT_DEBUG_CONTAINER_ID = 'workbench.sessions.panel.chatDebugContainer'; + +const chatDebugViewIcon = registerIcon('sessions-chat-debug-view-icon', Codicon.debug, localize('sessionsChatDebugViewIcon', 'View icon of the chat debug view in the sessions window.')); + +class RegisterChatDebugViewContribution extends Disposable implements IWorkbenchContribution { + + static readonly ID = 'sessions.registerChatDebugView'; + + constructor() { + super(); + + const viewContainerRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); + const viewsRegistry = Registry.as(ViewContainerExtensions.ViewsRegistry); + + // The copilot-chat view is contributed by the Copilot Chat extension, + // which may register after this contribution runs. Handle both cases. + if (!this.tryMoveView(viewContainerRegistry, viewsRegistry)) { + const listener = viewsRegistry.onViewsRegistered(e => { + for (const { views } of e) { + if (views.some(v => v.id === COPILOT_CHAT_VIEW_ID)) { + if (this.tryMoveView(viewContainerRegistry, viewsRegistry)) { + listener.dispose(); + } + break; + } + } + }); + this._register(listener); + } + } + + private tryMoveView(viewContainerRegistry: IViewContainersRegistry, viewsRegistry: IViewsRegistry): boolean { + const viewContainer = viewContainerRegistry.get(COPILOT_CHAT_VIEW_CONTAINER_ID); + if (!viewContainer) { + return false; + } + + const view = viewsRegistry.getView(COPILOT_CHAT_VIEW_ID); + if (!view) { + return false; + } + + // Deregister the view from its original extension container + viewsRegistry.deregisterViews([view], viewContainer); + viewContainerRegistry.deregisterViewContainer(viewContainer); + + // Register a new chat debug view container in the Panel for the sessions window + const chatDebugViewContainer = viewContainerRegistry.registerViewContainer({ + id: SESSIONS_CHAT_DEBUG_CONTAINER_ID, + title: localize2('chatDebug', "Chat Debug"), + icon: chatDebugViewIcon, + order: 3, + ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [SESSIONS_CHAT_DEBUG_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true }]), + storageId: SESSIONS_CHAT_DEBUG_CONTAINER_ID, + hideIfEmpty: true, + windowVisibility: WindowVisibility.Sessions, + }, ViewContainerLocation.Panel, { doNotRegisterOpenCommand: true }); + + // Re-register the view inside the new sessions container + const sessionsView: IViewDescriptor = { + ...view, + canMoveView: false, + windowVisibility: WindowVisibility.Sessions, + }; + viewsRegistry.registerViews([sessionsView], chatDebugViewContainer); + + return true; + } +} + +registerWorkbenchContribution2(RegisterChatDebugViewContribution.ID, RegisterChatDebugViewContribution, WorkbenchPhase.BlockRestore); diff --git a/src/vs/sessions/sessions.desktop.main.ts b/src/vs/sessions/sessions.desktop.main.ts index fbcad6fa0ca..ffcc3b6c194 100644 --- a/src/vs/sessions/sessions.desktop.main.ts +++ b/src/vs/sessions/sessions.desktop.main.ts @@ -216,6 +216,7 @@ import './contrib/configuration/browser/configuration.contribution.js'; import './contrib/terminal/browser/sessionsTerminalContribution.js'; import './contrib/logs/browser/logs.contribution.js'; +import './contrib/chatDebug/browser/chatDebug.contribution.js'; import './contrib/workspace/browser/workspace.contribution.js'; import './contrib/welcome/browser/welcome.contribution.js';