mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-04 07:15:54 +01:00
move registering of actions/kbs out of progress part (#278844)
This commit is contained in:
@@ -13,6 +13,7 @@ import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contex
|
||||
import { IKeybindingService } from '../../../../../platform/keybinding/common/keybinding.js';
|
||||
import { AccessibilityVerbositySettingId } from '../../../accessibility/browser/accessibilityConfiguration.js';
|
||||
import { INLINE_CHAT_ID } from '../../../inlineChat/common/inlineChat.js';
|
||||
import { TerminalContribCommandId } from '../../../terminal/terminalContribExports.js';
|
||||
import { ChatContextKeyExprs, ChatContextKeys } from '../../common/chatContextKeys.js';
|
||||
import { ChatAgentLocation, ChatConfiguration, ChatModeKind } from '../../common/constants.js';
|
||||
import { IChatWidgetService } from '../chat.js';
|
||||
@@ -81,8 +82,8 @@ export function getAccessibilityHelpText(type: 'panelChat' | 'inlineChat' | 'age
|
||||
content.push(localize('workbench.action.chat.previousUserPrompt', 'To navigate to the previous user prompt in the conversation, invoke the Previous User Prompt command{0}.', '<keybinding:workbench.action.chat.previousUserPrompt>'));
|
||||
content.push(localize('workbench.action.chat.announceConfirmation', 'To focus pending chat confirmation dialogs, invoke the Focus Chat Confirmation Status command{0}.', '<keybinding:workbench.action.chat.focusConfirmation>'));
|
||||
content.push(localize('chat.showHiddenTerminals', 'If there are any hidden chat terminals, you can view them by invoking the View Hidden Chat Terminals command{0}.', '<keybinding:workbench.action.terminal.chat.viewHiddenChatTerminals>'));
|
||||
content.push(localize('chat.focusMostRecentTerminal', 'To focus the last chat terminal that ran a tool, invoke the Focus Most Recent Chat Terminal command{0}.', '<keybinding:workbench.action.chat.focusMostRecentChatTerminal>'));
|
||||
content.push(localize('chat.focusMostRecentTerminalOutput', 'To focus the output from the last chat terminal tool, invoke the Focus Most Recent Chat Terminal Output command{0}.', '<keybinding:workbench.action.chat.focusMostRecentChatTerminalOutput>'));
|
||||
content.push(localize('chat.focusMostRecentTerminal', 'To focus the last chat terminal that ran a tool, invoke the Focus Most Recent Chat Terminal command{0}.', `<keybinding:${TerminalContribCommandId.FocusMostRecentChatTerminal}>`));
|
||||
content.push(localize('chat.focusMostRecentTerminalOutput', 'To focus the output from the last chat terminal tool, invoke the Focus Most Recent Chat Terminal Output command{0}.', `<keybinding:${TerminalContribCommandId.FocusMostRecentChatTerminalOutput}>`));
|
||||
if (type === 'panelChat') {
|
||||
content.push(localize('workbench.action.chat.newChat', 'To create a new chat session, invoke the New Chat command{0}.', '<keybinding:workbench.action.chat.new>'));
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import { IMarkdownRenderer } from '../../../../../../platform/markdown/browser/m
|
||||
import { IStorageService, StorageScope, StorageTarget } from '../../../../../../platform/storage/common/storage.js';
|
||||
import { IPreferencesService } from '../../../../../services/preferences/common/preferences.js';
|
||||
import { ITerminalChatService } from '../../../../terminal/browser/terminal.js';
|
||||
import { TerminalContribSettingId } from '../../../../terminal/terminalContribExports.js';
|
||||
import { TerminalContribCommandId, TerminalContribSettingId } from '../../../../terminal/terminalContribExports.js';
|
||||
import { migrateLegacyTerminalToolSpecificData } from '../../../common/chat.js';
|
||||
import { ChatContextKeys } from '../../../common/chatContextKeys.js';
|
||||
import { IChatToolInvocation, ToolConfirmKind, type IChatTerminalToolInvocationData, type ILegacyChatTerminalToolInvocationData } from '../../../common/chatService.js';
|
||||
@@ -43,7 +43,6 @@ import { ChatCustomConfirmationWidget, IChatConfirmationButton } from '../chatCo
|
||||
import { EditorPool } from '../chatContentCodePools.js';
|
||||
import { IChatContentPartRenderContext } from '../chatContentParts.js';
|
||||
import { ChatMarkdownContentPart } from '../chatMarkdownContentPart.js';
|
||||
import { disableSessionAutoApprovalCommandId, openTerminalSettingsLinkCommandId } from './chatTerminalToolProgressPart.js';
|
||||
import { BaseChatToolInvocationSubPart } from './chatToolInvocationSubPart.js';
|
||||
|
||||
export const enum TerminalToolConfirmationStorageKeys {
|
||||
@@ -280,13 +279,13 @@ export class ChatTerminalToolConfirmationSubPart extends BaseChatToolInvocationS
|
||||
await this.configurationService.updateValue(TerminalContribSettingId.AutoApprove, newValue, ConfigurationTarget.USER);
|
||||
function formatRuleLinks(newRules: ITerminalNewAutoApproveRule[]): string {
|
||||
return newRules.map(e => {
|
||||
const settingsUri = createCommandUri(openTerminalSettingsLinkCommandId, ConfigurationTarget.USER);
|
||||
const settingsUri = createCommandUri(TerminalContribCommandId.OpenTerminalSettingsLink, ConfigurationTarget.USER);
|
||||
return `[\`${e.key}\`](${settingsUri.toString()} "${localize('ruleTooltip', 'View rule in settings')}")`;
|
||||
}).join(', ');
|
||||
}
|
||||
const mdTrustSettings = {
|
||||
isTrusted: {
|
||||
enabledCommands: [openTerminalSettingsLinkCommandId]
|
||||
enabledCommands: [TerminalContribCommandId.OpenTerminalSettingsLink]
|
||||
}
|
||||
};
|
||||
if (newRules.length === 1) {
|
||||
@@ -308,10 +307,10 @@ export class ChatTerminalToolConfirmationSubPart extends BaseChatToolInvocationS
|
||||
case 'sessionApproval': {
|
||||
const sessionId = this.context.element.sessionId;
|
||||
this.terminalChatService.setChatSessionAutoApproval(sessionId, true);
|
||||
const disableUri = createCommandUri(disableSessionAutoApprovalCommandId, sessionId);
|
||||
const disableUri = createCommandUri(TerminalContribCommandId.DisableSessionAutoApproval, sessionId);
|
||||
const mdTrustSettings = {
|
||||
isTrusted: {
|
||||
enabledCommands: [disableSessionAutoApprovalCommandId]
|
||||
enabledCommands: [TerminalContribCommandId.DisableSessionAutoApproval]
|
||||
}
|
||||
};
|
||||
terminalData.autoApproveInfo = new MarkdownString(`${localize('sessionApproval', 'All commands will be auto approved for this session')} ([${localize('sessionApproval.disable', 'Disable')}](${disableUri.toString()}))`, mdTrustSettings);
|
||||
|
||||
@@ -5,11 +5,8 @@
|
||||
|
||||
import { h } from '../../../../../../base/browser/dom.js';
|
||||
import { ActionBar } from '../../../../../../base/browser/ui/actionbar/actionbar.js';
|
||||
import { Codicon } from '../../../../../../base/common/codicons.js';
|
||||
import { KeyCode, KeyMod } from '../../../../../../base/common/keyCodes.js';
|
||||
import { isMarkdownString, MarkdownString } from '../../../../../../base/common/htmlContent.js';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IPreferencesService, type IOpenSettingsOptions } from '../../../../../services/preferences/common/preferences.js';
|
||||
import { IInstantiationService } from '../../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { migrateLegacyTerminalToolSpecificData } from '../../../common/chat.js';
|
||||
import { IChatToolInvocation, IChatToolInvocationSerialized, type IChatMarkdownContent, type IChatTerminalToolInvocationData, type ILegacyChatTerminalToolInvocationData } from '../../../common/chatService.js';
|
||||
import { CodeBlockModelCollection } from '../../../common/codeBlockModelCollection.js';
|
||||
@@ -20,14 +17,9 @@ import { ChatMarkdownContentPart, type IChatMarkdownContentPartOptions } from '.
|
||||
import { ChatProgressSubPart } from '../chatProgressContentPart.js';
|
||||
import { BaseChatToolInvocationSubPart } from './chatToolInvocationSubPart.js';
|
||||
import '../media/chatTerminalToolProgressPart.css';
|
||||
import { TerminalContribSettingId } from '../../../../terminal/terminalContribExports.js';
|
||||
import { ConfigurationTarget } from '../../../../../../platform/configuration/common/configuration.js';
|
||||
import type { ICodeBlockRenderOptions } from '../../codeBlockPart.js';
|
||||
import { ChatConfiguration, CHAT_TERMINAL_OUTPUT_MAX_PREVIEW_LINES } from '../../../common/constants.js';
|
||||
import { CommandsRegistry } from '../../../../../../platform/commands/common/commands.js';
|
||||
import { MenuId, MenuRegistry } from '../../../../../../platform/actions/common/actions.js';
|
||||
import { CHAT_TERMINAL_OUTPUT_MAX_PREVIEW_LINES } from '../../../common/constants.js';
|
||||
import { IChatTerminalToolProgressPart, ITerminalChatService, ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalService } from '../../../../terminal/browser/terminal.js';
|
||||
import { Action, IAction } from '../../../../../../base/common/actions.js';
|
||||
import { Disposable, MutableDisposable, toDisposable, type IDisposable } from '../../../../../../base/common/lifecycle.js';
|
||||
import { Emitter, Event } from '../../../../../../base/common/event.js';
|
||||
import { ThemeIcon } from '../../../../../../base/common/themables.js';
|
||||
@@ -36,7 +28,6 @@ import * as dom from '../../../../../../base/browser/dom.js';
|
||||
import { DomScrollableElement } from '../../../../../../base/browser/ui/scrollbar/scrollableElement.js';
|
||||
import { ScrollbarVisibility } from '../../../../../../base/common/scrollable.js';
|
||||
import { localize } from '../../../../../../nls.js';
|
||||
import { TerminalLocation } from '../../../../../../platform/terminal/common/terminal.js';
|
||||
import { ITerminalCommand, TerminalCapability, type ICommandDetectionCapability } from '../../../../../../platform/terminal/common/capabilities/capabilities.js';
|
||||
import { IMarkdownRenderer } from '../../../../../../platform/markdown/browser/markdownRenderer.js';
|
||||
import { IHoverService } from '../../../../../../platform/hover/browser/hover.js';
|
||||
@@ -50,8 +41,13 @@ import { IContextKey, IContextKeyService } from '../../../../../../platform/cont
|
||||
import { AccessibilityVerbositySettingId } from '../../../../accessibility/browser/accessibilityConfiguration.js';
|
||||
import { ChatContextKeys } from '../../../common/chatContextKeys.js';
|
||||
import { EditorPool } from '../chatContentCodePools.js';
|
||||
import { KeybindingWeight, KeybindingsRegistry } from '../../../../../../platform/keybinding/common/keybindingsRegistry.js';
|
||||
import { IKeybindingService } from '../../../../../../platform/keybinding/common/keybinding.js';
|
||||
import { TerminalLocation } from '../../../../../../platform/terminal/common/terminal.js';
|
||||
import { Action, IAction } from '../../../../../../base/common/actions.js';
|
||||
import { Codicon } from '../../../../../../base/common/codicons.js';
|
||||
import { TerminalContribCommandId } from '../../../../terminal/terminalContribExports.js';
|
||||
import { ITelemetryService } from '../../../../../../platform/telemetry/common/telemetry.js';
|
||||
|
||||
|
||||
const MAX_TERMINAL_OUTPUT_PREVIEW_HEIGHT = 200;
|
||||
|
||||
@@ -969,108 +965,16 @@ class ChatTerminalToolOutputSection extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
export const focusMostRecentChatTerminalCommandId = 'workbench.action.chat.focusMostRecentChatTerminal';
|
||||
export const focusMostRecentChatTerminalOutputCommandId = 'workbench.action.chat.focusMostRecentChatTerminalOutput';
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: focusMostRecentChatTerminalCommandId,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: ChatContextKeys.inChatSession,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KeyT,
|
||||
handler: async (accessor: ServicesAccessor) => {
|
||||
const terminalChatService = accessor.get(ITerminalChatService);
|
||||
const part = terminalChatService.getMostRecentProgressPart();
|
||||
if (!part) {
|
||||
return;
|
||||
}
|
||||
await part.focusTerminal();
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: focusMostRecentChatTerminalOutputCommandId,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: ChatContextKeys.inChatSession,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KeyO,
|
||||
handler: async (accessor: ServicesAccessor) => {
|
||||
const terminalChatService = accessor.get(ITerminalChatService);
|
||||
const part = terminalChatService.getMostRecentProgressPart();
|
||||
if (!part) {
|
||||
return;
|
||||
}
|
||||
await part.toggleOutputFromKeyboard();
|
||||
}
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: focusMostRecentChatTerminalCommandId,
|
||||
title: localize('chat.focusMostRecentTerminal', 'Chat: Focus Most Recent Terminal'),
|
||||
},
|
||||
when: ChatContextKeys.inChatSession
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: focusMostRecentChatTerminalOutputCommandId,
|
||||
title: localize('chat.focusMostRecentTerminalOutput', 'Chat: Focus Most Recent Terminal Output'),
|
||||
},
|
||||
when: ChatContextKeys.inChatSession
|
||||
});
|
||||
|
||||
export const openTerminalSettingsLinkCommandId = '_chat.openTerminalSettingsLink';
|
||||
export const disableSessionAutoApprovalCommandId = '_chat.disableSessionAutoApproval';
|
||||
|
||||
CommandsRegistry.registerCommand(openTerminalSettingsLinkCommandId, async (accessor, scopeRaw: string) => {
|
||||
const preferencesService = accessor.get(IPreferencesService);
|
||||
|
||||
if (scopeRaw === 'global') {
|
||||
preferencesService.openSettings({
|
||||
query: `@id:${ChatConfiguration.GlobalAutoApprove}`
|
||||
});
|
||||
} else {
|
||||
const scope = parseInt(scopeRaw);
|
||||
const target = !isNaN(scope) ? scope as ConfigurationTarget : undefined;
|
||||
const options: IOpenSettingsOptions = {
|
||||
jsonEditor: true,
|
||||
revealSetting: {
|
||||
key: TerminalContribSettingId.AutoApprove
|
||||
}
|
||||
};
|
||||
switch (target) {
|
||||
case ConfigurationTarget.APPLICATION: preferencesService.openApplicationSettings(options); break;
|
||||
case ConfigurationTarget.USER:
|
||||
case ConfigurationTarget.USER_LOCAL: preferencesService.openUserSettings(options); break;
|
||||
case ConfigurationTarget.USER_REMOTE: preferencesService.openRemoteSettings(options); break;
|
||||
case ConfigurationTarget.WORKSPACE:
|
||||
case ConfigurationTarget.WORKSPACE_FOLDER: preferencesService.openWorkspaceSettings(options); break;
|
||||
default: {
|
||||
// Fallback if something goes wrong
|
||||
preferencesService.openSettings({
|
||||
target: ConfigurationTarget.USER,
|
||||
query: `@id:${TerminalContribSettingId.AutoApprove}`,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand(disableSessionAutoApprovalCommandId, async (accessor, chatSessionId: string) => {
|
||||
const terminalChatService = accessor.get(ITerminalChatService);
|
||||
terminalChatService.setChatSessionAutoApproval(chatSessionId, false);
|
||||
});
|
||||
|
||||
|
||||
class ToggleChatTerminalOutputAction extends Action implements IAction {
|
||||
export class ToggleChatTerminalOutputAction extends Action implements IAction {
|
||||
private _expanded = false;
|
||||
|
||||
constructor(
|
||||
private readonly _toggle: () => Promise<void>,
|
||||
@IKeybindingService private readonly _keybindingService: IKeybindingService,
|
||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
||||
) {
|
||||
super(
|
||||
'chat.showTerminalOutput',
|
||||
TerminalContribCommandId.ToggleChatTerminalOutput,
|
||||
localize('showTerminalOutput', 'Show Output'),
|
||||
ThemeIcon.asClassName(Codicon.chevronRight),
|
||||
true,
|
||||
@@ -1079,6 +983,18 @@ class ToggleChatTerminalOutputAction extends Action implements IAction {
|
||||
}
|
||||
|
||||
public override async run(): Promise<void> {
|
||||
type ToggleChatTerminalOutputTelemetryEvent = {
|
||||
previousExpanded: boolean;
|
||||
};
|
||||
|
||||
type ToggleChatTerminalOutputTelemetryClassification = {
|
||||
owner: 'meganrogge';
|
||||
comment: 'Track usage of the toggle chat terminal output action.';
|
||||
previousExpanded: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Whether the terminal output was expanded before the toggle.' };
|
||||
};
|
||||
this._telemetryService.publicLog2<ToggleChatTerminalOutputTelemetryEvent, ToggleChatTerminalOutputTelemetryClassification>('terminal/chatToggleOutput', {
|
||||
previousExpanded: this._expanded
|
||||
});
|
||||
await this._toggle();
|
||||
}
|
||||
|
||||
@@ -1103,7 +1019,7 @@ class ToggleChatTerminalOutputAction extends Action implements IAction {
|
||||
}
|
||||
|
||||
private _updateTooltip(): void {
|
||||
const keybinding = this._keybindingService.lookupKeybinding(focusMostRecentChatTerminalOutputCommandId);
|
||||
const keybinding = this._keybindingService.lookupKeybinding(TerminalContribCommandId.FocusMostRecentChatTerminalOutput);
|
||||
const label = keybinding?.getLabel();
|
||||
this.tooltip = label ? `${this.label} (${label})` : this.label;
|
||||
}
|
||||
@@ -1120,9 +1036,10 @@ export class FocusChatInstanceAction extends Action implements IAction {
|
||||
@ITerminalEditorService private readonly _terminalEditorService: ITerminalEditorService,
|
||||
@ITerminalGroupService private readonly _terminalGroupService: ITerminalGroupService,
|
||||
@IKeybindingService private readonly _keybindingService: IKeybindingService,
|
||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
||||
) {
|
||||
super(
|
||||
'chat.focusTerminalInstance',
|
||||
TerminalContribCommandId.FocusChatInstanceAction,
|
||||
isTerminalHidden ? localize('showTerminal', 'Show and Focus Terminal') : localize('focusTerminal', 'Focus Terminal'),
|
||||
ThemeIcon.asClassName(Codicon.openInProduct),
|
||||
true,
|
||||
@@ -1133,6 +1050,32 @@ export class FocusChatInstanceAction extends Action implements IAction {
|
||||
public override async run() {
|
||||
this.label = localize('focusTerminal', 'Focus Terminal');
|
||||
this._updateTooltip();
|
||||
|
||||
let target: FocusChatInstanceTelemetryEvent['target'] = 'none';
|
||||
let location: FocusChatInstanceTelemetryEvent['location'] = 'panel';
|
||||
if (this._instance) {
|
||||
target = 'instance';
|
||||
location = this._instance.target === TerminalLocation.Editor ? 'editor' : 'panel';
|
||||
} else if (this._commandUri) {
|
||||
target = 'commandUri';
|
||||
}
|
||||
|
||||
type FocusChatInstanceTelemetryEvent = {
|
||||
target: 'instance' | 'commandUri' | 'none';
|
||||
location: 'panel' | 'editor';
|
||||
};
|
||||
|
||||
type FocusChatInstanceTelemetryClassification = {
|
||||
owner: 'meganrogge';
|
||||
comment: 'Track usage of the focus chat terminal action.';
|
||||
target: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Whether focusing targeted an existing instance or opened a command URI.' };
|
||||
location: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Location of the terminal instance when focusing.' };
|
||||
};
|
||||
this._telemetryService.publicLog2<FocusChatInstanceTelemetryEvent, FocusChatInstanceTelemetryClassification>('terminal/chatFocusInstance', {
|
||||
target,
|
||||
location
|
||||
});
|
||||
|
||||
if (this._instance) {
|
||||
this._terminalService.setActiveInstance(this._instance);
|
||||
if (this._instance.target === TerminalLocation.Editor) {
|
||||
@@ -1174,7 +1117,7 @@ export class FocusChatInstanceAction extends Action implements IAction {
|
||||
}
|
||||
|
||||
private _updateTooltip(): void {
|
||||
const keybinding = this._keybindingService.lookupKeybinding(focusMostRecentChatTerminalCommandId);
|
||||
const keybinding = this._keybindingService.lookupKeybinding(TerminalContribCommandId.FocusMostRecentChatTerminal);
|
||||
const label = keybinding?.getLabel();
|
||||
this.tooltip = label ? `${this.label} (${label})` : this.label;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import type { IConfigurationNode } from '../../../platform/configuration/common/
|
||||
import { TerminalAccessibilityCommandId, defaultTerminalAccessibilityCommandsToSkipShell } from '../terminalContrib/accessibility/common/terminal.accessibility.js';
|
||||
import { terminalAccessibilityConfiguration } from '../terminalContrib/accessibility/common/terminalAccessibilityConfiguration.js';
|
||||
import { terminalAutoRepliesConfiguration } from '../terminalContrib/autoReplies/common/terminalAutoRepliesConfiguration.js';
|
||||
import { TerminalChatCommandId } from '../terminalContrib/chat/browser/terminalChat.js';
|
||||
import { terminalInitialHintConfiguration } from '../terminalContrib/chat/common/terminalInitialHintConfiguration.js';
|
||||
import { terminalChatAgentToolsConfiguration, TerminalChatAgentToolsSettingId } from '../terminalContrib/chatAgentTools/common/terminalChatAgentToolsConfiguration.js';
|
||||
import { terminalCommandGuideConfiguration } from '../terminalContrib/commandGuide/common/terminalCommandGuideConfiguration.js';
|
||||
@@ -25,6 +26,12 @@ import { terminalZoomConfiguration } from '../terminalContrib/zoom/common/termin
|
||||
export const enum TerminalContribCommandId {
|
||||
A11yFocusAccessibleBuffer = TerminalAccessibilityCommandId.FocusAccessibleBuffer,
|
||||
DeveloperRestartPtyHost = TerminalDeveloperCommandId.RestartPtyHost,
|
||||
OpenTerminalSettingsLink = TerminalChatCommandId.OpenTerminalSettingsLink,
|
||||
DisableSessionAutoApproval = TerminalChatCommandId.DisableSessionAutoApproval,
|
||||
FocusMostRecentChatTerminalOutput = TerminalChatCommandId.FocusMostRecentChatTerminalOutput,
|
||||
FocusMostRecentChatTerminal = TerminalChatCommandId.FocusMostRecentChatTerminal,
|
||||
ToggleChatTerminalOutput = TerminalChatCommandId.ToggleChatTerminalOutput,
|
||||
FocusChatInstanceAction = TerminalChatCommandId.FocusChatInstanceAction,
|
||||
}
|
||||
|
||||
// HACK: Export some settings from `terminalContrib/` that are depended upon elsewhere. These are
|
||||
|
||||
@@ -19,6 +19,12 @@ export const enum TerminalChatCommandId {
|
||||
ViewInChat = 'workbench.action.terminal.chat.viewInChat',
|
||||
RerunRequest = 'workbench.action.terminal.chat.rerunRequest',
|
||||
ViewHiddenChatTerminals = 'workbench.action.terminal.chat.viewHiddenChatTerminals',
|
||||
OpenTerminalSettingsLink = 'workbench.action.terminal.chat.openTerminalSettingsLink',
|
||||
DisableSessionAutoApproval = 'workbench.action.terminal.chat.disableSessionAutoApproval',
|
||||
FocusMostRecentChatTerminalOutput = 'workbench.action.terminal.chat.focusMostRecentChatTerminalOutput',
|
||||
FocusMostRecentChatTerminal = 'workbench.action.terminal.chat.focusMostRecentChatTerminal',
|
||||
ToggleChatTerminalOutput = 'workbench.action.terminal.chat.toggleChatTerminalOutput',
|
||||
FocusChatInstanceAction = 'workbench.action.terminal.chat.focusChatInstance',
|
||||
}
|
||||
|
||||
export const MENU_TERMINAL_CHAT_WIDGET_INPUT_SIDE_TOOLBAR = MenuId.for('terminalChatWidget');
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
|
||||
import { Codicon } from '../../../../../base/common/codicons.js';
|
||||
import { KeyCode, KeyMod } from '../../../../../base/common/keyCodes.js';
|
||||
import { localize2 } from '../../../../../nls.js';
|
||||
import { Action2, MenuId, registerAction2 } from '../../../../../platform/actions/common/actions.js';
|
||||
import { localize, localize2 } from '../../../../../nls.js';
|
||||
import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../../../../platform/actions/common/actions.js';
|
||||
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
|
||||
import { KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';
|
||||
import { ChatViewId, IChatWidgetService } from '../../../chat/browser/chat.js';
|
||||
import { ChatContextKeys } from '../../../chat/common/chatContextKeys.js';
|
||||
import { IChatService } from '../../../chat/common/chatService.js';
|
||||
import { LocalChatSessionUri } from '../../../chat/common/chatUri.js';
|
||||
import { ChatAgentLocation } from '../../../chat/common/constants.js';
|
||||
import { ChatAgentLocation, ChatConfiguration } from '../../../chat/common/constants.js';
|
||||
import { AbstractInline1ChatAction } from '../../../inlineChat/browser/inlineChatActions.js';
|
||||
import { isDetachedTerminalInstance, ITerminalChatService, ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalService } from '../../../terminal/browser/terminal.js';
|
||||
import { registerActiveXtermAction } from '../../../terminal/browser/terminalActions.js';
|
||||
@@ -26,6 +26,10 @@ import { getIconId } from '../../../terminal/browser/terminalIcon.js';
|
||||
import { TerminalChatController } from './terminalChatController.js';
|
||||
import { TerminalCapability } from '../../../../../platform/terminal/common/capabilities/capabilities.js';
|
||||
import { isString } from '../../../../../base/common/types.js';
|
||||
import { CommandsRegistry } from '../../../../../platform/commands/common/commands.js';
|
||||
import { IPreferencesService, IOpenSettingsOptions } from '../../../../services/preferences/common/preferences.js';
|
||||
import { ConfigurationTarget } from '../../../../../platform/configuration/common/configuration.js';
|
||||
import { TerminalChatAgentToolsSettingId } from '../../chatAgentTools/common/terminalChatAgentToolsConfiguration.js';
|
||||
|
||||
registerActiveXtermAction({
|
||||
id: TerminalChatCommandId.Start,
|
||||
@@ -425,3 +429,94 @@ registerAction2(class ShowChatTerminalsAction extends Action2 {
|
||||
qp.show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: TerminalChatCommandId.FocusMostRecentChatTerminal,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: ChatContextKeys.inChatSession,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KeyT,
|
||||
handler: async (accessor: ServicesAccessor) => {
|
||||
const terminalChatService = accessor.get(ITerminalChatService);
|
||||
const part = terminalChatService.getMostRecentProgressPart();
|
||||
if (!part) {
|
||||
return;
|
||||
}
|
||||
await part.focusTerminal();
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: TerminalChatCommandId.FocusMostRecentChatTerminalOutput,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: ChatContextKeys.inChatSession,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KeyO,
|
||||
handler: async (accessor: ServicesAccessor) => {
|
||||
const terminalChatService = accessor.get(ITerminalChatService);
|
||||
const part = terminalChatService.getMostRecentProgressPart();
|
||||
if (!part) {
|
||||
return;
|
||||
}
|
||||
await part.toggleOutputFromKeyboard();
|
||||
}
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: TerminalChatCommandId.FocusMostRecentChatTerminal,
|
||||
title: localize('chat.focusMostRecentTerminal', 'Chat: Focus Most Recent Terminal'),
|
||||
},
|
||||
when: ChatContextKeys.inChatSession
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: TerminalChatCommandId.FocusMostRecentChatTerminalOutput,
|
||||
title: localize('chat.focusMostRecentTerminalOutput', 'Chat: Focus Most Recent Terminal Output'),
|
||||
},
|
||||
when: ChatContextKeys.inChatSession
|
||||
});
|
||||
|
||||
|
||||
CommandsRegistry.registerCommand(TerminalChatCommandId.OpenTerminalSettingsLink, async (accessor, scopeRaw: string) => {
|
||||
const preferencesService = accessor.get(IPreferencesService);
|
||||
|
||||
if (scopeRaw === 'global') {
|
||||
preferencesService.openSettings({
|
||||
query: `@id:${ChatConfiguration.GlobalAutoApprove}`
|
||||
});
|
||||
} else {
|
||||
const scope = parseInt(scopeRaw);
|
||||
const target = !isNaN(scope) ? scope as ConfigurationTarget : undefined;
|
||||
const options: IOpenSettingsOptions = {
|
||||
jsonEditor: true,
|
||||
revealSetting: {
|
||||
key: TerminalChatAgentToolsSettingId.AutoApprove,
|
||||
}
|
||||
};
|
||||
switch (target) {
|
||||
case ConfigurationTarget.APPLICATION: preferencesService.openApplicationSettings(options); break;
|
||||
case ConfigurationTarget.USER:
|
||||
case ConfigurationTarget.USER_LOCAL: preferencesService.openUserSettings(options); break;
|
||||
case ConfigurationTarget.USER_REMOTE: preferencesService.openRemoteSettings(options); break;
|
||||
case ConfigurationTarget.WORKSPACE:
|
||||
case ConfigurationTarget.WORKSPACE_FOLDER: preferencesService.openWorkspaceSettings(options); break;
|
||||
default: {
|
||||
// Fallback if something goes wrong
|
||||
preferencesService.openSettings({
|
||||
target: ConfigurationTarget.USER,
|
||||
query: `@id:${TerminalChatAgentToolsSettingId.AutoApprove}`,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand(TerminalChatCommandId.DisableSessionAutoApproval, async (accessor, chatSessionId: string) => {
|
||||
const terminalChatService = accessor.get(ITerminalChatService);
|
||||
terminalChatService.setChatSessionAutoApproval(chatSessionId, false);
|
||||
});
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import { IInstantiationService } from '../../../../../../../platform/instantiati
|
||||
import { ITerminalChatService } from '../../../../../terminal/browser/terminal.js';
|
||||
import { IStorageService, StorageScope } from '../../../../../../../platform/storage/common/storage.js';
|
||||
import { TerminalToolConfirmationStorageKeys } from '../../../../../chat/browser/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.js';
|
||||
import { openTerminalSettingsLinkCommandId } from '../../../../../chat/browser/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.js';
|
||||
import { ChatConfiguration } from '../../../../../chat/common/constants.js';
|
||||
import type { ToolConfirmationAction } from '../../../../../chat/common/languageModelToolsService.js';
|
||||
import { TerminalChatAgentToolsSettingId } from '../../../common/terminalChatAgentToolsConfiguration.js';
|
||||
@@ -22,6 +21,7 @@ import { dedupeRules, generateAutoApproveActions, isPowerShell } from '../../run
|
||||
import type { RunInTerminalToolTelemetry } from '../../runInTerminalToolTelemetry.js';
|
||||
import { type TreeSitterCommandParser } from '../../treeSitterCommandParser.js';
|
||||
import type { ICommandLineAnalyzer, ICommandLineAnalyzerOptions, ICommandLineAnalyzerResult } from './commandLineAnalyzer.js';
|
||||
import { TerminalChatCommandId } from '../../../../chat/browser/terminalChat.js';
|
||||
|
||||
const promptInjectionWarningCommandsLower = [
|
||||
'curl',
|
||||
@@ -53,10 +53,10 @@ export class CommandLineAutoApproveAnalyzer extends Disposable implements IComma
|
||||
async analyze(options: ICommandLineAnalyzerOptions): Promise<ICommandLineAnalyzerResult> {
|
||||
if (options.chatSessionId && this._terminalChatService.hasChatSessionAutoApproval(options.chatSessionId)) {
|
||||
this._log('Session has auto approval enabled, auto approving command');
|
||||
const disableUri = createCommandUri('_chat.disableSessionAutoApproval', options.chatSessionId);
|
||||
const disableUri = createCommandUri(TerminalChatCommandId.DisableSessionAutoApproval, options.chatSessionId);
|
||||
const mdTrustSettings = {
|
||||
isTrusted: {
|
||||
enabledCommands: ['_chat.disableSessionAutoApproval']
|
||||
enabledCommands: [TerminalChatCommandId.DisableSessionAutoApproval]
|
||||
}
|
||||
};
|
||||
return {
|
||||
@@ -191,21 +191,21 @@ export class CommandLineAutoApproveAnalyzer extends Disposable implements IComma
|
||||
): IMarkdownString | undefined {
|
||||
const formatRuleLinks = (result: SingleOrMany<{ result: ICommandApprovalResult; rule?: IAutoApproveRule; reason: string }>): string => {
|
||||
return asArray(result).map(e => {
|
||||
const settingsUri = createCommandUri(openTerminalSettingsLinkCommandId, e.rule!.sourceTarget);
|
||||
const settingsUri = createCommandUri(TerminalChatCommandId.OpenTerminalSettingsLink, e.rule!.sourceTarget);
|
||||
return `[\`${e.rule!.sourceText}\`](${settingsUri.toString()} "${localize('ruleTooltip', 'View rule in settings')}")`;
|
||||
}).join(', ');
|
||||
};
|
||||
|
||||
const mdTrustSettings = {
|
||||
isTrusted: {
|
||||
enabledCommands: [openTerminalSettingsLinkCommandId]
|
||||
enabledCommands: [TerminalChatCommandId.OpenTerminalSettingsLink]
|
||||
}
|
||||
};
|
||||
|
||||
const config = this._configurationService.inspect<boolean | Record<string, boolean>>(ChatConfiguration.GlobalAutoApprove);
|
||||
const isGlobalAutoApproved = config?.value ?? config.defaultValue;
|
||||
if (isGlobalAutoApproved) {
|
||||
const settingsUri = createCommandUri(openTerminalSettingsLinkCommandId, 'global');
|
||||
const settingsUri = createCommandUri(TerminalChatCommandId.OpenTerminalSettingsLink, 'global');
|
||||
return new MarkdownString(`${localize('autoApprove.global', 'Auto approved by setting {0}', `[\`${ChatConfiguration.GlobalAutoApprove}\`](${settingsUri.toString()} "${localize('ruleTooltip.global', 'View settings')}")`)}`, mdTrustSettings);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user