@@ -28,7 +28,7 @@ import type { XtermTerminal } from '../../../../terminal/browser/xterm/xtermTerm
28
28
import { ITerminalProfileResolverService } from '../../../../terminal/common/terminal.js' ;
29
29
import { getRecommendedToolsOverRunInTerminal } from '../alternativeRecommendation.js' ;
30
30
import { getOutput } from '../bufferOutputPolling.js' ;
31
- import { CommandLineAutoApprover , type ICommandApprovalResultWithReason } from '../commandLineAutoApprover.js' ;
31
+ import { CommandLineAutoApprover , type IAutoApproveRule , type ICommandApprovalResult , type ICommandApprovalResultWithReason } from '../commandLineAutoApprover.js' ;
32
32
import { BasicExecuteStrategy } from '../executeStrategy/basicExecuteStrategy.js' ;
33
33
import type { ITerminalExecuteStrategy } from '../executeStrategy/executeStrategy.js' ;
34
34
import { NoneExecuteStrategy } from '../executeStrategy/noneExecuteStrategy.js' ;
@@ -40,6 +40,8 @@ import { Codicon } from '../../../../../../base/common/codicons.js';
40
40
import { OutputMonitor } from '../outputMonitor.js' ;
41
41
import type { TerminalNewAutoApproveButtonData } from '../../../../chat/browser/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.js' ;
42
42
import { basename } from '../../../../../../base/common/path.js' ;
43
+ import type { SingleOrMany } from '../../../../../../base/common/types.js' ;
44
+ import { asArray } from '../../../../../../base/common/arrays.js' ;
43
45
44
46
const TERMINAL_SESSION_STORAGE_KEY = 'chat.terminalSessions' ;
45
47
@@ -255,20 +257,25 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
255
257
}
256
258
}
257
259
260
+ function formatRuleLinks ( result : SingleOrMany < { result : ICommandApprovalResult ; rule ?: IAutoApproveRule ; reason : string } > ) : string {
261
+ return asArray ( result ) . map ( e => {
262
+ return `[\`${ e . rule ! . sourceText } \`](settings_${ e . rule ! . sourceTarget } "${ localize ( 'ruleTooltip' , 'View rule in settings' ) } ")` ;
263
+ } ) . join ( ', ' ) ;
264
+ }
258
265
if ( isAutoApproved ) {
259
266
switch ( autoApproveReason ) {
260
267
case 'commandLine' : {
261
268
if ( commandLineResult . rule ) {
262
- autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApprove.rule' , 'Auto approved by rule {0}' , `[\` ${ commandLineResult . rule . sourceText } \`](settings_ ${ commandLineResult . rule . sourceTarget } )` ) } _` ) ;
269
+ autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApprove.rule' , 'Auto approved by rule {0}' , formatRuleLinks ( commandLineResult ) ) } _` ) ;
263
270
}
264
271
break ;
265
272
}
266
273
case 'subCommand' : {
267
- const uniqueRules = Array . from ( new Set ( subCommandResults . map ( e => `[\` ${ e . rule ! . sourceText } \`](settings_ ${ e . rule ! . sourceTarget } )` ) ) ) ;
274
+ const uniqueRules = Array . from ( new Set ( subCommandResults ) ) ;
268
275
if ( uniqueRules . length === 1 ) {
269
- autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApprove.rule' , 'Auto approved by rule {0}' , uniqueRules [ 0 ] ) } _` ) ;
276
+ autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApprove.rule' , 'Auto approved by rule {0}' , formatRuleLinks ( uniqueRules ) ) } _` ) ;
270
277
} else if ( uniqueRules . length > 1 ) {
271
- autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApprove.rules' , 'Auto approved by rules {0}' , uniqueRules . join ( ', ' ) ) } _` ) ;
278
+ autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApprove.rules' , 'Auto approved by rules {0}' , formatRuleLinks ( uniqueRules ) ) } _` ) ;
272
279
}
273
280
break ;
274
281
}
@@ -277,24 +284,24 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
277
284
switch ( autoApproveReason ) {
278
285
case 'commandLine' : {
279
286
if ( commandLineResult . rule ) {
280
- autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApproveDenied.rule' , 'Auto approval denied by rule {0}' , `[\` ${ commandLineResult . rule . sourceText } \`](settings_ ${ commandLineResult . rule . sourceTarget } )` ) } _` ) ;
287
+ autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApproveDenied.rule' , 'Auto approval denied by rule {0}' , formatRuleLinks ( commandLineResult ) ) } _` ) ;
281
288
}
282
289
break ;
283
290
}
284
291
case 'subCommand' : {
285
292
const deniedRules = subCommandResults . filter ( e => e . result === 'denied' ) ;
286
- const uniqueRules = Array . from ( new Set ( deniedRules . map ( e => `[\` ${ e . rule ! . sourceText } \`](settings_ ${ e . rule ! . sourceTarget } )` ) ) ) ;
293
+ const uniqueRules = Array . from ( new Set ( deniedRules ) ) ;
287
294
if ( uniqueRules . length === 1 ) {
288
- autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApproveDenied.rule' , 'Auto approval denied by rule {0}' , uniqueRules [ 0 ] ) } _` ) ;
295
+ autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApproveDenied.rule' , 'Auto approval denied by rule {0}' , formatRuleLinks ( uniqueRules ) ) } _` ) ;
289
296
} else if ( uniqueRules . length > 1 ) {
290
- autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApproveDenied.rules' , 'Auto approval denied by rules {0}' , uniqueRules . join ( ', ' ) ) } _` ) ;
297
+ autoApproveInfo = new MarkdownString ( `_${ localize ( 'autoApproveDenied.rules' , 'Auto approval denied by rules {0}' , formatRuleLinks ( uniqueRules ) ) } _` ) ;
291
298
}
292
299
break ;
293
300
}
294
301
}
295
302
}
296
303
297
- // TODO: Surface reason on tool part https://github.com/microsoft/vscode/issues/256780
304
+ // Log detailed auto approval reasoning
298
305
for ( const reason of autoApproveReasons ) {
299
306
this . _logService . info ( `- ${ reason } ` ) ;
300
307
}
0 commit comments