Skip to content

Commit 4a0e4ec

Browse files
authored
Merge branch 'main' into copilot/fix-256710
2 parents 38b9b3c + 02eb425 commit 4a0e4ec

File tree

9 files changed

+348
-56
lines changed

9 files changed

+348
-56
lines changed

src/vs/workbench/contrib/chat/browser/actions/chatActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ export function registerChatActions() {
576576
const menuActions = getContextMenuActions(actions, 'navigation');
577577
ckey.reset();
578578

579-
const buttons = menuActions.secondary.map(action => ({
579+
const buttons = menuActions.primary.map(action => ({
580580
id: action.id,
581581
tooltip: action.tooltip,
582582
iconClass: action.class || ThemeIcon.asClassName(Codicon.symbolClass),

src/vs/workbench/contrib/chat/browser/chatContentParts/toolInvocationParts/chatTerminalToolSubPart.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import * as dom from '../../../../../../base/browser/dom.js';
77
import { MarkdownString } from '../../../../../../base/common/htmlContent.js';
88
import { thenIfNotDisposed } from '../../../../../../base/common/lifecycle.js';
9+
import { Schemas } from '../../../../../../base/common/network.js';
10+
import { URI } from '../../../../../../base/common/uri.js';
11+
import { generateUuid } from '../../../../../../base/common/uuid.js';
912
import { MarkdownRenderer } from '../../../../../../editor/browser/widget/markdownRenderer/browser/markdownRenderer.js';
1013
import { ILanguageService } from '../../../../../../editor/common/languages/language.js';
1114
import { IModelService } from '../../../../../../editor/common/services/model.js';
@@ -86,7 +89,12 @@ export class TerminalConfirmationWidgetSubPart extends BaseChatToolInvocationSub
8689
}
8790
};
8891
const langId = this.languageService.getLanguageIdByLanguageName(terminalData.language ?? 'sh') ?? 'shellscript';
89-
const model = this.modelService.createModel(terminalData.kind === 'terminal' ? terminalData.command : terminalData.commandLine.toolEdited ?? terminalData.commandLine.original, this.languageService.createById(langId), undefined, true);
92+
const model = this.modelService.createModel(
93+
terminalData.kind === 'terminal' ? terminalData.command : terminalData.commandLine.toolEdited ?? terminalData.commandLine.original,
94+
this.languageService.createById(langId),
95+
this._getUniqueCodeBlockUri(),
96+
true
97+
);
9098
const editor = this._register(this.editorPool.get());
9199
const renderPromise = editor.object.render({
92100
codeBlockIndex: this.codeBlockStartIndex,
@@ -144,4 +152,11 @@ export class TerminalConfirmationWidgetSubPart extends BaseChatToolInvocationSub
144152
});
145153
this.domNode = confirmWidget.domNode;
146154
}
155+
156+
private _getUniqueCodeBlockUri() {
157+
return URI.from({
158+
scheme: Schemas.vscodeChatCodeBlock,
159+
path: generateUuid(),
160+
});
161+
}
147162
}

src/vs/workbench/contrib/terminal/browser/terminalActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ const category = terminalStrings.actionCategory;
6969

7070
// Some terminal context keys get complicated. Since normalizing and/or context keys can be
7171
// expensive this is done once per context key and shared.
72-
const sharedWhenClause = (() => {
72+
export const sharedWhenClause = (() => {
7373
const terminalAvailable = ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated);
7474
return {
7575
terminalAvailable,

src/vs/workbench/contrib/terminal/terminal.all.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ import '../terminalContrib/sendSignal/browser/terminal.sendSignal.contribution.j
3333
import '../terminalContrib/suggest/browser/terminal.suggest.contribution.js';
3434
import '../terminalContrib/chat/browser/terminal.initialHint.contribution.js';
3535
import '../terminalContrib/wslRecommendation/browser/terminal.wslRecommendation.contribution.js';
36+
import '../terminalContrib/voice/browser/terminal.voice.contribution.js';

src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalTool.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
186186
}
187187

188188
const instance = context.chatSessionId ? this._sessionTerminalAssociations.get(context.chatSessionId)?.instance : undefined;
189-
let toolEditedCommand: string | undefined = await this._rewriteCommandIfNeeded(context, args, instance, shell);
189+
let toolEditedCommand: string | undefined = await this._rewriteCommandIfNeeded(args, instance, shell);
190190
if (toolEditedCommand === args.command) {
191191
toolEditedCommand = undefined;
192192
}
@@ -211,9 +211,30 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
211211
}
212212

213213
const args = invocation.parameters as IRunInTerminalInputParams;
214-
const toolSpecificData = invocation.toolSpecificData as IChatTerminalToolInvocationData | IChatTerminalToolInvocationData2 | undefined;
214+
215+
// Tool specific data is not provided when the invocation is auto-approved. Re-calculate it
216+
// if needed
217+
let toolSpecificData = invocation.toolSpecificData as IChatTerminalToolInvocationData | IChatTerminalToolInvocationData2 | undefined;
215218
if (toolSpecificData === undefined) {
216-
throw new Error('Tool specific data must be provided');
219+
const os = await this._osBackend;
220+
const shell = await this._terminalProfileResolverService.getDefaultShell({
221+
os,
222+
remoteAuthority: this._remoteAgentService.getConnection()?.remoteAuthority
223+
});
224+
const language = os === OperatingSystem.Windows ? 'pwsh' : 'sh';
225+
const instance = invocation.context?.sessionId ? this._sessionTerminalAssociations.get(invocation.context!.sessionId)?.instance : undefined;
226+
let toolEditedCommand: string | undefined = await this._rewriteCommandIfNeeded(args, instance, shell);
227+
if (toolEditedCommand === args.command) {
228+
toolEditedCommand = undefined;
229+
}
230+
toolSpecificData = {
231+
kind: 'terminal2',
232+
commandLine: {
233+
original: args.command,
234+
toolEdited: toolEditedCommand
235+
},
236+
language
237+
};
217238
}
218239

219240
this._logService.debug(`RunInTerminalTool: Invoking with options ${JSON.stringify(args)}`);
@@ -397,7 +418,7 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
397418
}
398419
}
399420

400-
protected async _rewriteCommandIfNeeded(context: IToolInvocationPreparationContext, args: IRunInTerminalInputParams, instance: Pick<ITerminalInstance, 'getCwdResource'> | undefined, shell: string): Promise<string> {
421+
protected async _rewriteCommandIfNeeded(args: IRunInTerminalInputParams, instance: Pick<ITerminalInstance, 'getCwdResource'> | undefined, shell: string): Promise<string> {
401422
const commandLine = args.command;
402423
const os = await this._osBackend;
403424

@@ -604,7 +625,7 @@ class BackgroundTerminalExecution extends Disposable {
604625
super();
605626

606627
this._startMarker = this._register(this._xterm.raw.registerMarker());
607-
this._instance.runCommand(this._commandLine);
628+
this._instance.runCommand(this._commandLine, true);
608629
}
609630

610631
getOutput(): string {

0 commit comments

Comments
 (0)