1- import { VSCodeCheckbox , VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
1+ import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"
22import { useCallback , useState } from "react"
3- import styled from "styled-components "
3+ import { useExtensionState } from "../../context/ExtensionStateContext "
44
55interface AutoApproveAction {
66 id : string
77 label : string
88 enabled : boolean
9+ shortName : string
910 description : string
1011}
1112
1213interface AutoApproveMenuProps {
1314 style ?: React . CSSProperties
1415}
1516
16- const DEFAULT_MAX_REQUESTS = 50
17-
1817const AutoApproveMenu = ( { style } : AutoApproveMenuProps ) => {
1918 const [ isExpanded , setIsExpanded ] = useState ( false )
20- const [ actions , setActions ] = useState < AutoApproveAction [ ] > ( [
19+ const {
20+ alwaysAllowReadOnly,
21+ setAlwaysAllowReadOnly,
22+ alwaysAllowWrite,
23+ setAlwaysAllowWrite,
24+ alwaysAllowExecute,
25+ setAlwaysAllowExecute,
26+ alwaysAllowBrowser,
27+ setAlwaysAllowBrowser,
28+ alwaysAllowMcp,
29+ setAlwaysAllowMcp,
30+ alwaysApproveResubmit,
31+ setAlwaysApproveResubmit,
32+ autoApprovalEnabled,
33+ setAutoApprovalEnabled,
34+ } = useExtensionState ( )
35+
36+ const actions : AutoApproveAction [ ] = [
2137 {
2238 id : "readFiles" ,
2339 label : "Read files and directories" ,
24- enabled : false ,
40+ shortName : "Read" ,
41+ enabled : alwaysAllowReadOnly ?? false ,
2542 description : "Allows access to read any file on your computer." ,
2643 } ,
2744 {
2845 id : "editFiles" ,
2946 label : "Edit files" ,
30- enabled : false ,
47+ shortName : "Edit" ,
48+ enabled : alwaysAllowWrite ?? false ,
3149 description : "Allows modification of any files on your computer." ,
3250 } ,
3351 {
3452 id : "executeCommands" ,
3553 label : "Execute safe commands" ,
36- enabled : false ,
54+ shortName : "Commands" ,
55+ enabled : alwaysAllowExecute ?? false ,
3756 description :
38- "Allows automatic execution of safe terminal commands. The model will determine if a command is potentially destructive and ask for explicit approval ." ,
57+ "Allows execution of approved terminal commands. You can configure this in the settings panel ." ,
3958 } ,
4059 {
4160 id : "useBrowser" ,
4261 label : "Use the browser" ,
43- enabled : false ,
62+ shortName : "Browser" ,
63+ enabled : alwaysAllowBrowser ?? false ,
4464 description : "Allows ability to launch and interact with any website in a headless browser." ,
4565 } ,
4666 {
4767 id : "useMcp" ,
4868 label : "Use MCP servers" ,
49- enabled : false ,
69+ shortName : "MCP" ,
70+ enabled : alwaysAllowMcp ?? false ,
5071 description : "Allows use of configured MCP servers which may modify filesystem or interact with APIs." ,
5172 } ,
52- ] )
53- const [ maxRequests , setMaxRequests ] = useState ( DEFAULT_MAX_REQUESTS )
54- const [ enableNotifications , setEnableNotifications ] = useState ( false )
73+ {
74+ id : "retryRequests" ,
75+ label : "Retry failed requests" ,
76+ shortName : "Retries" ,
77+ enabled : alwaysApproveResubmit ?? false ,
78+ description : "Automatically retry failed API requests when the provider returns an error response." ,
79+ } ,
80+ ]
5581
5682 const toggleExpanded = useCallback ( ( ) => {
5783 setIsExpanded ( ( prev ) => ! prev )
5884 } , [ ] )
5985
60- const toggleAction = useCallback ( ( actionId : string ) => {
61- setActions ( ( prev ) =>
62- prev . map ( ( action ) => ( action . id === actionId ? { ...action , enabled : ! action . enabled } : action ) ) ,
63- )
64- } , [ ] )
86+ const enabledActionsList = actions
87+ . filter ( ( action ) => action . enabled )
88+ . map ( ( action ) => action . shortName )
89+ . join ( ", " )
6590
66- const enabledActions = actions . filter ( ( action ) => action . enabled )
67- const enabledActionsList = enabledActions . map ( ( action ) => action . label ) . join ( ", " )
91+ // Individual checkbox handlers - each one only updates its own state
92+ const handleReadOnlyChange = useCallback ( ( ) => setAlwaysAllowReadOnly ( ! ( alwaysAllowReadOnly ?? false ) ) , [ alwaysAllowReadOnly , setAlwaysAllowReadOnly ] )
93+ const handleWriteChange = useCallback ( ( ) => setAlwaysAllowWrite ( ! ( alwaysAllowWrite ?? false ) ) , [ alwaysAllowWrite , setAlwaysAllowWrite ] )
94+ const handleExecuteChange = useCallback ( ( ) => setAlwaysAllowExecute ( ! ( alwaysAllowExecute ?? false ) ) , [ alwaysAllowExecute , setAlwaysAllowExecute ] )
95+ const handleBrowserChange = useCallback ( ( ) => setAlwaysAllowBrowser ( ! ( alwaysAllowBrowser ?? false ) ) , [ alwaysAllowBrowser , setAlwaysAllowBrowser ] )
96+ const handleMcpChange = useCallback ( ( ) => setAlwaysAllowMcp ( ! ( alwaysAllowMcp ?? false ) ) , [ alwaysAllowMcp , setAlwaysAllowMcp ] )
97+ const handleRetryChange = useCallback ( ( ) => setAlwaysApproveResubmit ( ! ( alwaysApproveResubmit ?? false ) ) , [ alwaysApproveResubmit , setAlwaysApproveResubmit ] )
98+
99+ // Map action IDs to their specific handlers
100+ const actionHandlers : Record < AutoApproveAction [ 'id' ] , ( ) => void > = {
101+ readFiles : handleReadOnlyChange ,
102+ editFiles : handleWriteChange ,
103+ executeCommands : handleExecuteChange ,
104+ useBrowser : handleBrowserChange ,
105+ useMcp : handleMcpChange ,
106+ retryRequests : handleRetryChange ,
107+ }
68108
69109 return (
70110 < div
@@ -86,39 +126,41 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
86126 cursor : "pointer" ,
87127 } }
88128 onClick = { toggleExpanded } >
89- < VSCodeCheckbox
90- checked = { enabledActions . length > 0 }
91- onChange = { ( e ) => {
92- const checked = ( e . target as HTMLInputElement ) . checked
93- setActions ( ( prev ) =>
94- prev . map ( ( action ) => ( {
95- ...action ,
96- enabled : checked ,
97- } ) ) ,
98- )
99- e . stopPropagation ( )
100- } }
101- onClick = { ( e ) => e . stopPropagation ( ) }
102- />
103- < CollapsibleSection >
104- < span style = { { color : "var(--vscode-foreground)" } } > Auto-approve:</ span >
105- < span
106- style = { {
107- whiteSpace : "nowrap" ,
108- overflow : "hidden" ,
109- textOverflow : "ellipsis" ,
110- } } >
111- { enabledActions . length === 0 ? "None" : enabledActionsList }
129+ < div onClick = { ( e ) => e . stopPropagation ( ) } >
130+ < VSCodeCheckbox
131+ checked = { autoApprovalEnabled ?? false }
132+ onChange = { ( ) => setAutoApprovalEnabled ( ! ( autoApprovalEnabled ?? false ) ) }
133+ />
134+ </ div >
135+ < div style = { {
136+ display : 'flex' ,
137+ alignItems : 'center' ,
138+ gap : '4px' ,
139+ flex : 1 ,
140+ minWidth : 0
141+ } } >
142+ < span style = { {
143+ color : "var(--vscode-foreground)" ,
144+ flexShrink : 0
145+ } } > Auto-approve:</ span >
146+ < span style = { {
147+ color : "var(--vscode-descriptionForeground)" ,
148+ overflow : "hidden" ,
149+ textOverflow : "ellipsis" ,
150+ whiteSpace : "nowrap" ,
151+ flex : 1 ,
152+ minWidth : 0
153+ } } >
154+ { enabledActionsList || "None" }
112155 </ span >
113156 < span
114157 className = { `codicon codicon-chevron-${ isExpanded ? "down" : "right" } ` }
115158 style = { {
116- // fontSize: "14px",
117159 flexShrink : 0 ,
118160 marginLeft : isExpanded ? "2px" : "-2px" ,
119161 } }
120162 />
121- </ CollapsibleSection >
163+ </ div >
122164 </ div >
123165 { isExpanded && (
124166 < div style = { { padding : "0" } } >
@@ -129,13 +171,17 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
129171 fontSize : "12px" ,
130172 } } >
131173 Auto-approve allows Cline to perform actions without asking for permission. Only enable for
132- actions you fully trust, and consider setting a low request limit as a safeguard .
174+ actions you fully trust.
133175 </ div >
134176 { actions . map ( ( action ) => (
135177 < div key = { action . id } style = { { margin : "6px 0" } } >
136- < VSCodeCheckbox checked = { action . enabled } onChange = { ( ) => toggleAction ( action . id ) } >
137- { action . label }
138- </ VSCodeCheckbox >
178+ < div onClick = { ( e ) => e . stopPropagation ( ) } >
179+ < VSCodeCheckbox
180+ checked = { action . enabled }
181+ onChange = { actionHandlers [ action . id ] } >
182+ { action . label }
183+ </ VSCodeCheckbox >
184+ </ div >
139185 < div
140186 style = { {
141187 marginLeft : "28px" ,
@@ -146,76 +192,10 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
146192 </ div >
147193 </ div >
148194 ) ) }
149- < div
150- style = { {
151- height : "0.5px" ,
152- background : "var(--vscode-titleBar-inactiveForeground)" ,
153- margin : "15px 0" ,
154- opacity : 0.2 ,
155- } }
156- />
157- < div
158- style = { {
159- display : "flex" ,
160- alignItems : "center" ,
161- gap : "8px" ,
162- marginTop : "10px" ,
163- marginBottom : "8px" ,
164- color : "var(--vscode-foreground)" ,
165- } } >
166- < span style = { { flexShrink : 1 , minWidth : 0 } } > Max Requests:</ span >
167- < VSCodeTextField
168- value = { maxRequests . toString ( ) }
169- onChange = { ( e ) => {
170- const value = parseInt ( ( e . target as HTMLInputElement ) . value )
171- if ( ! isNaN ( value ) && value > 0 ) {
172- setMaxRequests ( value )
173- }
174- } }
175- style = { { flex : 1 } }
176- />
177- </ div >
178- < div
179- style = { {
180- color : "var(--vscode-descriptionForeground)" ,
181- fontSize : "12px" ,
182- marginBottom : "10px" ,
183- } } >
184- Cline will make this many API requests before asking for approval to proceed with the task.
185- </ div >
186- < div style = { { margin : "6px 0" } } >
187- < VSCodeCheckbox
188- checked = { enableNotifications }
189- onChange = { ( ) => setEnableNotifications ( ( prev ) => ! prev ) } >
190- Enable Notifications
191- </ VSCodeCheckbox >
192- < div
193- style = { {
194- marginLeft : "28px" ,
195- color : "var(--vscode-descriptionForeground)" ,
196- fontSize : "12px" ,
197- } } >
198- Receive system notifications when Cline requires approval to proceed or when a task is
199- completed.
200- </ div >
201- </ div >
202195 </ div >
203196 ) }
204197 </ div >
205198 )
206199}
207200
208- const CollapsibleSection = styled . div `
209- display: flex;
210- align-items: center;
211- gap: 4px;
212- color: var(--vscode-descriptionForeground);
213- flex: 1;
214- min-width: 0;
215-
216- &:hover {
217- color: var(--vscode-foreground);
218- }
219- `
220-
221201export default AutoApproveMenu
0 commit comments