@@ -9,11 +9,16 @@ import { IConfigurationService } from '../../../../../platform/configuration/com
9
9
import { TerminalChatAgentToolsSettingId } from '../common/terminalChatAgentToolsConfiguration.js' ;
10
10
import { isPowerShell } from './runInTerminalHelpers.js' ;
11
11
12
+ interface IAutoApproveRule {
13
+ regex : RegExp ;
14
+ sourceText : string ;
15
+ }
16
+
12
17
export class CommandLineAutoApprover extends Disposable {
13
- private _denyListRegexes : RegExp [ ] = [ ] ;
14
- private _allowListRegexes : RegExp [ ] = [ ] ;
15
- private _allowListCommandLineRegexes : RegExp [ ] = [ ] ;
16
- private _denyListCommandLineRegexes : RegExp [ ] = [ ] ;
18
+ private _denyListRules : IAutoApproveRule [ ] = [ ] ;
19
+ private _allowListRules : IAutoApproveRule [ ] = [ ] ;
20
+ private _allowListCommandLineRules : IAutoApproveRule [ ] = [ ] ;
21
+ private _denyListCommandLineRules : IAutoApproveRule [ ] = [ ] ;
17
22
18
23
constructor (
19
24
@IConfigurationService private readonly _configurationService : IConfigurationService ,
@@ -28,25 +33,25 @@ export class CommandLineAutoApprover extends Disposable {
28
33
}
29
34
30
35
updateConfiguration ( ) {
31
- const { denyList , allowList , allowListCommandLine , denyListCommandLine } = this . _mapAutoApproveConfigToRegexList ( this . _configurationService . getValue ( TerminalChatAgentToolsSettingId . AutoApprove ) ) ;
32
- this . _allowListRegexes = allowList ;
33
- this . _denyListRegexes = denyList ;
34
- this . _allowListCommandLineRegexes = allowListCommandLine ;
35
- this . _denyListCommandLineRegexes = denyListCommandLine ;
36
+ const { denyListRules , allowListRules , allowListCommandLineRules , denyListCommandLineRules } = this . _mapAutoApproveConfigToRules ( this . _configurationService . getValue ( TerminalChatAgentToolsSettingId . AutoApprove ) ) ;
37
+ this . _allowListRules = allowListRules ;
38
+ this . _denyListRules = denyListRules ;
39
+ this . _allowListCommandLineRules = allowListCommandLineRules ;
40
+ this . _denyListCommandLineRules = denyListCommandLineRules ;
36
41
}
37
42
38
43
isCommandAutoApproved ( command : string , shell : string , os : OperatingSystem ) : { isAutoApproved : boolean ; reason : string } {
39
44
// Check the deny list to see if this command requires explicit approval
40
- for ( const regex of this . _denyListRegexes ) {
41
- if ( this . _commandMatchesRegex ( regex , command , shell , os ) ) {
42
- return { isAutoApproved : false , reason : `Command '${ command } ' is denied by deny list rule: ${ regex . source } ` } ;
45
+ for ( const rule of this . _denyListRules ) {
46
+ if ( this . _commandMatchesRegex ( rule . regex , command , shell , os ) ) {
47
+ return { isAutoApproved : false , reason : `Command '${ command } ' is denied by deny list rule: ${ rule . sourceText } ` } ;
43
48
}
44
49
}
45
50
46
51
// Check the allow list to see if the command is allowed to run without explicit approval
47
- for ( const regex of this . _allowListRegexes ) {
48
- if ( this . _commandMatchesRegex ( regex , command , shell , os ) ) {
49
- return { isAutoApproved : true , reason : `Command '${ command } ' is approved by allow list rule: ${ regex . source } ` } ;
52
+ for ( const rule of this . _allowListRules ) {
53
+ if ( this . _commandMatchesRegex ( rule . regex , command , shell , os ) ) {
54
+ return { isAutoApproved : true , reason : `Command '${ command } ' is approved by allow list rule: ${ rule . sourceText } ` } ;
50
55
}
51
56
}
52
57
@@ -58,16 +63,16 @@ export class CommandLineAutoApprover extends Disposable {
58
63
59
64
isCommandLineAutoApproved ( commandLine : string ) : { isAutoApproved : boolean ; reason : string } {
60
65
// Check the deny list first to see if this command line requires explicit approval
61
- for ( const regex of this . _denyListCommandLineRegexes ) {
62
- if ( regex . test ( commandLine ) ) {
63
- return { isAutoApproved : false , reason : `Command line '${ commandLine } ' is denied by deny list rule: ${ regex . source } ` } ;
66
+ for ( const rule of this . _denyListCommandLineRules ) {
67
+ if ( rule . regex . test ( commandLine ) ) {
68
+ return { isAutoApproved : false , reason : `Command line '${ commandLine } ' is denied by deny list rule: ${ rule . sourceText } ` } ;
64
69
}
65
70
}
66
71
67
72
// Check if the full command line matches any of the allow list command line regexes
68
- for ( const regex of this . _allowListCommandLineRegexes ) {
69
- if ( regex . test ( commandLine ) ) {
70
- return { isAutoApproved : true , reason : `Command line '${ commandLine } ' is approved by allow list rule: ${ regex . source } ` } ;
73
+ for ( const rule of this . _allowListCommandLineRules ) {
74
+ if ( rule . regex . test ( commandLine ) ) {
75
+ return { isAutoApproved : true , reason : `Command line '${ commandLine } ' is approved by allow list rule: ${ rule . sourceText } ` } ;
71
76
}
72
77
}
73
78
return { isAutoApproved : false , reason : `Command line '${ commandLine } ' has no matching auto approve entries` } ;
@@ -86,24 +91,34 @@ export class CommandLineAutoApprover extends Disposable {
86
91
return false ;
87
92
}
88
93
89
- private _mapAutoApproveConfigToRegexList ( config : unknown ) : { denyList : RegExp [ ] ; allowList : RegExp [ ] ; allowListCommandLine : RegExp [ ] ; denyListCommandLine : RegExp [ ] } {
94
+ private _mapAutoApproveConfigToRules ( config : unknown ) : {
95
+ denyListRules : IAutoApproveRule [ ] ;
96
+ allowListRules : IAutoApproveRule [ ] ;
97
+ allowListCommandLineRules : IAutoApproveRule [ ] ;
98
+ denyListCommandLineRules : IAutoApproveRule [ ] ;
99
+ } {
90
100
if ( ! config || typeof config !== 'object' ) {
91
- return { denyList : [ ] , allowList : [ ] , allowListCommandLine : [ ] , denyListCommandLine : [ ] } ;
101
+ return {
102
+ denyListRules : [ ] ,
103
+ allowListRules : [ ] ,
104
+ allowListCommandLineRules : [ ] ,
105
+ denyListCommandLineRules : [ ]
106
+ } ;
92
107
}
93
108
94
- const denyList : RegExp [ ] = [ ] ;
95
- const allowList : RegExp [ ] = [ ] ;
96
- const allowListCommandLine : RegExp [ ] = [ ] ;
97
- const denyListCommandLine : RegExp [ ] = [ ] ;
109
+ const denyListRules : IAutoApproveRule [ ] = [ ] ;
110
+ const allowListRules : IAutoApproveRule [ ] = [ ] ;
111
+ const allowListCommandLineRules : IAutoApproveRule [ ] = [ ] ;
112
+ const denyListCommandLineRules : IAutoApproveRule [ ] = [ ] ;
98
113
99
114
Object . entries ( config ) . forEach ( ( [ key , value ] ) => {
100
115
if ( typeof value === 'boolean' ) {
101
116
const regex = this . _convertAutoApproveEntryToRegex ( key ) ;
102
117
// IMPORTANT: Only true and false are used, null entries need to be ignored
103
118
if ( value === true ) {
104
- allowList . push ( regex ) ;
119
+ allowListRules . push ( { regex, sourceText : key } ) ;
105
120
} else if ( value === false ) {
106
- denyList . push ( regex ) ;
121
+ denyListRules . push ( { regex, sourceText : key } ) ;
107
122
}
108
123
} else if ( typeof value === 'object' && value !== null ) {
109
124
// Handle object format like { approve: true/false, matchCommandLine: true/false }
@@ -112,22 +127,27 @@ export class CommandLineAutoApprover extends Disposable {
112
127
const regex = this . _convertAutoApproveEntryToRegex ( key ) ;
113
128
if ( objectValue . approve === true ) {
114
129
if ( objectValue . matchCommandLine === true ) {
115
- allowListCommandLine . push ( regex ) ;
130
+ allowListCommandLineRules . push ( { regex, sourceText : key } ) ;
116
131
} else {
117
- allowList . push ( regex ) ;
132
+ allowListRules . push ( { regex, sourceText : key } ) ;
118
133
}
119
134
} else if ( objectValue . approve === false ) {
120
135
if ( objectValue . matchCommandLine === true ) {
121
- denyListCommandLine . push ( regex ) ;
136
+ denyListCommandLineRules . push ( { regex, sourceText : key } ) ;
122
137
} else {
123
- denyList . push ( regex ) ;
138
+ denyListRules . push ( { regex, sourceText : key } ) ;
124
139
}
125
140
}
126
141
}
127
142
}
128
143
} ) ;
129
144
130
- return { denyList, allowList, allowListCommandLine, denyListCommandLine } ;
145
+ return {
146
+ denyListRules,
147
+ allowListRules,
148
+ allowListCommandLineRules,
149
+ denyListCommandLineRules
150
+ } ;
131
151
}
132
152
133
153
private _convertAutoApproveEntryToRegex ( value : string ) : RegExp {
0 commit comments