Skip to content

Commit 2615e26

Browse files
daniel-lxsutarn
authored andcommitted
fix: show diff view before approval when PREVENT_FOCUS_DISRUPTION is disabled (RooCodeInc#6386)
1 parent e42601c commit 2615e26

File tree

3 files changed

+81
-56
lines changed

3 files changed

+81
-56
lines changed

src/core/tools/insertContentTool.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export async function insertContentTool(
136136
approvalContent = updatedContent
137137
}
138138

139+
// Prepare the approval message (same for both flows)
139140
const completeMessage = JSON.stringify({
140141
...sharedMessageProps,
141142
diff,
@@ -144,35 +145,33 @@ export async function insertContentTool(
144145
isProtected: isWriteProtected,
145146
} satisfies ClineSayTool)
146147

148+
// Show diff view if focus disruption prevention is disabled
149+
if (!isPreventFocusDisruptionEnabled) {
150+
await cline.diffViewProvider.open(relPath)
151+
await cline.diffViewProvider.update(updatedContent, true)
152+
cline.diffViewProvider.scrollToFirstDiff()
153+
}
154+
155+
// Ask for approval (same for both flows)
147156
const didApprove = await cline
148157
.ask("tool", completeMessage, isWriteProtected)
149158
.then((response) => response.response === "yesButtonClicked")
150159

151160
if (!didApprove) {
161+
// Revert changes if diff view was shown
152162
if (!isPreventFocusDisruptionEnabled) {
153163
await cline.diffViewProvider.revertChanges()
154164
}
155165
pushToolResult("Changes were rejected by the user.")
166+
await cline.diffViewProvider.reset()
156167
return
157168
}
158169

170+
// Save the changes
159171
if (isPreventFocusDisruptionEnabled) {
160172
// Direct file write without diff view or opening the file
161173
await cline.diffViewProvider.saveDirectly(relPath, updatedContent, false, diagnosticsEnabled, writeDelayMs)
162174
} else {
163-
// Original behavior with diff view
164-
// Show changes in diff view
165-
if (!cline.diffViewProvider.isEditing) {
166-
await cline.ask("tool", JSON.stringify(sharedMessageProps), true).catch(() => {})
167-
// First open with original content
168-
await cline.diffViewProvider.open(relPath)
169-
await cline.diffViewProvider.update(fileContent, false)
170-
cline.diffViewProvider.scrollToFirstDiff()
171-
await delay(200)
172-
}
173-
174-
await cline.diffViewProvider.update(updatedContent, true)
175-
176175
// Call saveChanges to update the DiffViewProvider properties
177176
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
178177
}

src/core/tools/multiApplyDiffTool.ts

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -525,17 +525,17 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
525525
isProtected: isWriteProtected,
526526
}
527527

528-
// If single file, ask for approval
528+
// If single file, handle based on PREVENT_FOCUS_DISRUPTION setting
529529
let didApprove = true
530530
if (operationsToApprove.length === 1) {
531+
// Prepare common data for single file operation
531532
const diffContents = diffItems.map((item) => item.content).join("\n\n")
532533
const operationMessage = JSON.stringify({
533534
...sharedMessageProps,
534535
diff: diffContents,
535536
} satisfies ClineSayTool)
536537

537538
let toolProgressStatus
538-
539539
if (cline.diffStrategy && cline.diffStrategy.getProgressStatus) {
540540
toolProgressStatus = cline.diffStrategy.getProgressStatus(
541541
{
@@ -546,40 +546,69 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
546546
)
547547
}
548548

549-
// Check if file is write-protected
549+
// Set up diff view
550+
cline.diffViewProvider.editType = "modify"
551+
552+
// Show diff view if focus disruption prevention is disabled
553+
if (!isPreventFocusDisruptionEnabled) {
554+
await cline.diffViewProvider.open(relPath)
555+
await cline.diffViewProvider.update(originalContent!, true)
556+
cline.diffViewProvider.scrollToFirstDiff()
557+
} else {
558+
// For direct save, we still need to set originalContent
559+
cline.diffViewProvider.originalContent = await fs.readFile(absolutePath, "utf-8")
560+
}
561+
562+
// Ask for approval (same for both flows)
550563
const isWriteProtected = cline.rooProtectedController?.isWriteProtected(relPath) || false
551564
didApprove = await askApproval("tool", operationMessage, toolProgressStatus, isWriteProtected)
552-
}
553565

554-
if (!didApprove) {
555-
if (!isPreventFocusDisruptionEnabled) {
556-
await cline.diffViewProvider.revertChanges()
566+
if (!didApprove) {
567+
// Revert changes if diff view was shown
568+
if (!isPreventFocusDisruptionEnabled) {
569+
await cline.diffViewProvider.revertChanges()
570+
}
571+
results.push(`Changes to ${relPath} were not approved by user`)
572+
continue
557573
}
558-
results.push(`Changes to ${relPath} were not approved by user`)
559-
continue
560-
}
561574

562-
if (isPreventFocusDisruptionEnabled) {
563-
// Direct file write without diff view or opening the file
564-
cline.diffViewProvider.editType = "modify"
565-
cline.diffViewProvider.originalContent = await fs.readFile(absolutePath, "utf-8")
566-
await cline.diffViewProvider.saveDirectly(
567-
relPath,
568-
originalContent!,
569-
false,
570-
diagnosticsEnabled,
571-
writeDelayMs,
572-
)
575+
// Save the changes
576+
if (isPreventFocusDisruptionEnabled) {
577+
// Direct file write without diff view or opening the file
578+
await cline.diffViewProvider.saveDirectly(
579+
relPath,
580+
originalContent!,
581+
false,
582+
diagnosticsEnabled,
583+
writeDelayMs,
584+
)
585+
} else {
586+
// Call saveChanges to update the DiffViewProvider properties
587+
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
588+
}
573589
} else {
574-
// Original behavior with diff view
575-
// Show diff view before asking for approval (only for single file or after batch approval)
576-
cline.diffViewProvider.editType = "modify"
577-
await cline.diffViewProvider.open(relPath)
578-
await cline.diffViewProvider.update(originalContent!, true)
579-
cline.diffViewProvider.scrollToFirstDiff()
580-
581-
// Call saveChanges to update the DiffViewProvider properties
582-
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
590+
// Batch operations - already approved above
591+
if (isPreventFocusDisruptionEnabled) {
592+
// Direct file write without diff view or opening the file
593+
cline.diffViewProvider.editType = "modify"
594+
cline.diffViewProvider.originalContent = await fs.readFile(absolutePath, "utf-8")
595+
await cline.diffViewProvider.saveDirectly(
596+
relPath,
597+
originalContent!,
598+
false,
599+
diagnosticsEnabled,
600+
writeDelayMs,
601+
)
602+
} else {
603+
// Original behavior with diff view
604+
cline.diffViewProvider.editType = "modify"
605+
await cline.diffViewProvider.open(relPath)
606+
await cline.diffViewProvider.update(originalContent!, true)
607+
cline.diffViewProvider.scrollToFirstDiff()
608+
609+
// Call saveChanges to update the DiffViewProvider properties
610+
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
611+
}
583612
}
584613

585614
// Track file edit operation

src/core/tools/searchAndReplaceTool.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,25 @@ export async function searchAndReplaceTool(
210210
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
211211
)
212212

213-
// Request user approval for changes
214213
const completeMessage = JSON.stringify({
215214
...sharedMessageProps,
216215
diff,
217216
isProtected: isWriteProtected,
218217
} satisfies ClineSayTool)
218+
219+
// Show diff view if focus disruption prevention is disabled
220+
if (!isPreventFocusDisruptionEnabled) {
221+
await cline.diffViewProvider.open(validRelPath)
222+
await cline.diffViewProvider.update(newContent, true)
223+
cline.diffViewProvider.scrollToFirstDiff()
224+
}
225+
219226
const didApprove = await cline
220227
.ask("tool", completeMessage, isWriteProtected)
221228
.then((response) => response.response === "yesButtonClicked")
222229

223230
if (!didApprove) {
231+
// Revert changes if diff view was shown
224232
if (!isPreventFocusDisruptionEnabled) {
225233
await cline.diffViewProvider.revertChanges()
226234
}
@@ -229,22 +237,11 @@ export async function searchAndReplaceTool(
229237
return
230238
}
231239

240+
// Save the changes
232241
if (isPreventFocusDisruptionEnabled) {
233242
// Direct file write without diff view or opening the file
234243
await cline.diffViewProvider.saveDirectly(validRelPath, newContent, false, diagnosticsEnabled, writeDelayMs)
235244
} else {
236-
// Original behavior with diff view
237-
// Show changes in diff view
238-
if (!cline.diffViewProvider.isEditing) {
239-
await cline.ask("tool", JSON.stringify(sharedMessageProps), true).catch(() => {})
240-
await cline.diffViewProvider.open(validRelPath)
241-
await cline.diffViewProvider.update(fileContent, false)
242-
cline.diffViewProvider.scrollToFirstDiff()
243-
await delay(200)
244-
}
245-
246-
await cline.diffViewProvider.update(newContent, true)
247-
248245
// Call saveChanges to update the DiffViewProvider properties
249246
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
250247
}

0 commit comments

Comments
 (0)