Skip to content

Commit 552146d

Browse files
authored
ENG 526/Fix: Versioned Auto Approve settings (RooCodeInc#3014)
* added verisoning for autoApprove settings * removed lines from source branch * rebase * changeset * one small change
1 parent 552054a commit 552146d

File tree

5 files changed

+59
-15
lines changed

5 files changed

+59
-15
lines changed

.changeset/tidy-points-learn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": patch
3+
---
4+
5+
Fixes auto approve settings becoming unset

src/core/controller/index.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ export class Controller {
139139
await this.clearTask() // ensures that an existing task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one
140140
const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } =
141141
await getAllExtensionState(this.context)
142+
143+
if (autoApprovalSettings) {
144+
const updatedAutoApprovalSettings = {
145+
...autoApprovalSettings,
146+
version: (autoApprovalSettings.version ?? 1) + 1,
147+
}
148+
await updateGlobalState(this.context, "autoApprovalSettings", updatedAutoApprovalSettings)
149+
}
142150
this.task = new Task(
143151
this.context,
144152
this.mcpHub,
@@ -288,11 +296,16 @@ export class Controller {
288296
break
289297
case "autoApprovalSettings":
290298
if (message.autoApprovalSettings) {
291-
await updateGlobalState(this.context, "autoApprovalSettings", message.autoApprovalSettings)
292-
if (this.task) {
293-
this.task.autoApprovalSettings = message.autoApprovalSettings
299+
const currentSettings = (await getAllExtensionState(this.context)).autoApprovalSettings
300+
const incomingVersion = message.autoApprovalSettings.version ?? 1
301+
const currentVersion = currentSettings?.version ?? 1
302+
if (incomingVersion > currentVersion) {
303+
await updateGlobalState(this.context, "autoApprovalSettings", message.autoApprovalSettings)
304+
if (this.task) {
305+
this.task.autoApprovalSettings = message.autoApprovalSettings
306+
}
307+
await this.postStateToWebview()
294308
}
295-
await this.postStateToWebview()
296309
}
297310
break
298311
case "browserSettings":

src/shared/AutoApprovalSettings.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export interface AutoApprovalSettings {
2+
// Version for race condition prevention (incremented on every change)
3+
version: number
24
// Whether auto-approval is enabled
35
enabled: boolean
46
// Individual action permissions
@@ -18,6 +20,7 @@ export interface AutoApprovalSettings {
1820
}
1921

2022
export const DEFAULT_AUTO_APPROVAL_SETTINGS: AutoApprovalSettings = {
23+
version: 1,
2124
enabled: false,
2225
actions: {
2326
readFiles: false,

webview-ui/src/components/chat/AutoApproveMenu.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,24 +153,30 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
153153
return enabledActionsCount > 0
154154
}, [enabledActions, autoApprovalSettings.actions])
155155

156+
// Get the full extension state to ensure we have the most up-to-date settings
157+
const extensionState = useExtensionState()
158+
156159
const updateEnabled = useCallback(
157160
(enabled: boolean) => {
161+
const currentSettings = extensionState.autoApprovalSettings
158162
vscode.postMessage({
159163
type: "autoApprovalSettings",
160164
autoApprovalSettings: {
161-
...autoApprovalSettings,
165+
...currentSettings,
166+
version: (currentSettings.version ?? 1) + 1,
162167
enabled,
163168
},
164169
})
165170
},
166-
[autoApprovalSettings],
171+
[extensionState.autoApprovalSettings],
167172
)
168173

169174
const updateAction = useCallback(
170175
(actionId: keyof AutoApprovalSettings["actions"], value: boolean) => {
176+
const currentSettings = extensionState.autoApprovalSettings
171177
// Calculate what the new actions state will be
172178
const newActions = {
173-
...autoApprovalSettings.actions,
179+
...currentSettings.actions,
174180
[actionId]: value,
175181
}
176182

@@ -180,40 +186,45 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
180186
vscode.postMessage({
181187
type: "autoApprovalSettings",
182188
autoApprovalSettings: {
183-
...autoApprovalSettings,
189+
...currentSettings,
190+
version: (currentSettings.version ?? 1) + 1,
184191
actions: newActions,
185192
// If no actions will be enabled, ensure the main toggle is off
186-
enabled: willHaveEnabledActions ? autoApprovalSettings.enabled : false,
193+
enabled: willHaveEnabledActions ? currentSettings.enabled : false,
187194
},
188195
})
189196
},
190-
[autoApprovalSettings],
197+
[extensionState.autoApprovalSettings],
191198
)
192199

193200
const updateMaxRequests = useCallback(
194201
(maxRequests: number) => {
202+
const currentSettings = extensionState.autoApprovalSettings
195203
vscode.postMessage({
196204
type: "autoApprovalSettings",
197205
autoApprovalSettings: {
198-
...autoApprovalSettings,
206+
...currentSettings,
207+
version: (currentSettings.version ?? 1) + 1,
199208
maxRequests,
200209
},
201210
})
202211
},
203-
[autoApprovalSettings],
212+
[extensionState.autoApprovalSettings],
204213
)
205214

206215
const updateNotifications = useCallback(
207216
(enableNotifications: boolean) => {
217+
const currentSettings = extensionState.autoApprovalSettings
208218
vscode.postMessage({
209219
type: "autoApprovalSettings",
210220
autoApprovalSettings: {
211-
...autoApprovalSettings,
221+
...currentSettings,
222+
version: (currentSettings.version ?? 1) + 1,
212223
enableNotifications,
213224
},
214225
})
215226
},
216-
[autoApprovalSettings],
227+
[extensionState.autoApprovalSettings],
217228
)
218229

219230
return (

webview-ui/src/context/ExtensionStateContext.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,19 @@ export const ExtensionStateContextProvider: React.FC<{
7575
const message: ExtensionMessage = event.data
7676
switch (message.type) {
7777
case "state": {
78-
setState(message.state!)
78+
setState((prevState) => {
79+
const incoming = message.state!
80+
// Versioning logic for autoApprovalSettings
81+
const incomingVersion = incoming.autoApprovalSettings?.version ?? 1
82+
const currentVersion = prevState.autoApprovalSettings?.version ?? 1
83+
const shouldUpdateAutoApproval = incomingVersion > currentVersion
84+
return {
85+
...incoming,
86+
autoApprovalSettings: shouldUpdateAutoApproval
87+
? incoming.autoApprovalSettings
88+
: prevState.autoApprovalSettings,
89+
}
90+
})
7991
const config = message.state?.apiConfiguration
8092
const hasKey = config
8193
? [

0 commit comments

Comments
 (0)