fix: show diff view before approval when PREVENT_FOCUS_DISRUPTION is disabled (#6386)

This commit is contained in:
Daniel 2025-07-29 16:52:30 -05:00 committed by GitHub
parent 7b0a7e544d
commit 1cc9f15df1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 80 additions and 55 deletions

View file

@ -136,6 +136,7 @@ export async function insertContentTool(
approvalContent = updatedContent
}
// Prepare the approval message (same for both flows)
const completeMessage = JSON.stringify({
...sharedMessageProps,
diff,
@ -144,35 +145,33 @@ export async function insertContentTool(
isProtected: isWriteProtected,
} satisfies ClineSayTool)
// Show diff view if focus disruption prevention is disabled
if (!isPreventFocusDisruptionEnabled) {
await cline.diffViewProvider.open(relPath)
await cline.diffViewProvider.update(updatedContent, true)
cline.diffViewProvider.scrollToFirstDiff()
}
// Ask for approval (same for both flows)
const didApprove = await cline
.ask("tool", completeMessage, isWriteProtected)
.then((response) => response.response === "yesButtonClicked")
if (!didApprove) {
// Revert changes if diff view was shown
if (!isPreventFocusDisruptionEnabled) {
await cline.diffViewProvider.revertChanges()
}
pushToolResult("Changes were rejected by the user.")
await cline.diffViewProvider.reset()
return
}
// Save the changes
if (isPreventFocusDisruptionEnabled) {
// Direct file write without diff view or opening the file
await cline.diffViewProvider.saveDirectly(relPath, updatedContent, false, diagnosticsEnabled, writeDelayMs)
} else {
// Original behavior with diff view
// Show changes in diff view
if (!cline.diffViewProvider.isEditing) {
await cline.ask("tool", JSON.stringify(sharedMessageProps), true).catch(() => {})
// First open with original content
await cline.diffViewProvider.open(relPath)
await cline.diffViewProvider.update(fileContent, false)
cline.diffViewProvider.scrollToFirstDiff()
await delay(200)
}
await cline.diffViewProvider.update(updatedContent, true)
// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
}

View file

@ -525,9 +525,10 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
isProtected: isWriteProtected,
}
// If single file, ask for approval
// If single file, handle based on PREVENT_FOCUS_DISRUPTION setting
let didApprove = true
if (operationsToApprove.length === 1) {
// Prepare common data for single file operation
const diffContents = diffItems.map((item) => item.content).join("\n\n")
const operationMessage = JSON.stringify({
...sharedMessageProps,
@ -535,7 +536,6 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
} satisfies ClineSayTool)
let toolProgressStatus
if (cline.diffStrategy && cline.diffStrategy.getProgressStatus) {
toolProgressStatus = cline.diffStrategy.getProgressStatus(
{
@ -546,40 +546,69 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
)
}
// Check if file is write-protected
// Set up diff view
cline.diffViewProvider.editType = "modify"
// Show diff view if focus disruption prevention is disabled
if (!isPreventFocusDisruptionEnabled) {
await cline.diffViewProvider.open(relPath)
await cline.diffViewProvider.update(originalContent!, true)
cline.diffViewProvider.scrollToFirstDiff()
} else {
// For direct save, we still need to set originalContent
cline.diffViewProvider.originalContent = await fs.readFile(absolutePath, "utf-8")
}
// Ask for approval (same for both flows)
const isWriteProtected = cline.rooProtectedController?.isWriteProtected(relPath) || false
didApprove = await askApproval("tool", operationMessage, toolProgressStatus, isWriteProtected)
}
if (!didApprove) {
if (!isPreventFocusDisruptionEnabled) {
await cline.diffViewProvider.revertChanges()
if (!didApprove) {
// Revert changes if diff view was shown
if (!isPreventFocusDisruptionEnabled) {
await cline.diffViewProvider.revertChanges()
}
results.push(`Changes to ${relPath} were not approved by user`)
continue
}
results.push(`Changes to ${relPath} were not approved by user`)
continue
}
if (isPreventFocusDisruptionEnabled) {
// Direct file write without diff view or opening the file
cline.diffViewProvider.editType = "modify"
cline.diffViewProvider.originalContent = await fs.readFile(absolutePath, "utf-8")
await cline.diffViewProvider.saveDirectly(
relPath,
originalContent!,
false,
diagnosticsEnabled,
writeDelayMs,
)
// Save the changes
if (isPreventFocusDisruptionEnabled) {
// Direct file write without diff view or opening the file
await cline.diffViewProvider.saveDirectly(
relPath,
originalContent!,
false,
diagnosticsEnabled,
writeDelayMs,
)
} else {
// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
}
} else {
// Original behavior with diff view
// Show diff view before asking for approval (only for single file or after batch approval)
cline.diffViewProvider.editType = "modify"
await cline.diffViewProvider.open(relPath)
await cline.diffViewProvider.update(originalContent!, true)
cline.diffViewProvider.scrollToFirstDiff()
// Batch operations - already approved above
if (isPreventFocusDisruptionEnabled) {
// Direct file write without diff view or opening the file
cline.diffViewProvider.editType = "modify"
cline.diffViewProvider.originalContent = await fs.readFile(absolutePath, "utf-8")
await cline.diffViewProvider.saveDirectly(
relPath,
originalContent!,
false,
diagnosticsEnabled,
writeDelayMs,
)
} else {
// Original behavior with diff view
cline.diffViewProvider.editType = "modify"
await cline.diffViewProvider.open(relPath)
await cline.diffViewProvider.update(originalContent!, true)
cline.diffViewProvider.scrollToFirstDiff()
// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
}
}
// Track file edit operation

View file

@ -210,17 +210,25 @@ export async function searchAndReplaceTool(
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
)
// Request user approval for changes
const completeMessage = JSON.stringify({
...sharedMessageProps,
diff,
isProtected: isWriteProtected,
} satisfies ClineSayTool)
// Show diff view if focus disruption prevention is disabled
if (!isPreventFocusDisruptionEnabled) {
await cline.diffViewProvider.open(validRelPath)
await cline.diffViewProvider.update(newContent, true)
cline.diffViewProvider.scrollToFirstDiff()
}
const didApprove = await cline
.ask("tool", completeMessage, isWriteProtected)
.then((response) => response.response === "yesButtonClicked")
if (!didApprove) {
// Revert changes if diff view was shown
if (!isPreventFocusDisruptionEnabled) {
await cline.diffViewProvider.revertChanges()
}
@ -229,22 +237,11 @@ export async function searchAndReplaceTool(
return
}
// Save the changes
if (isPreventFocusDisruptionEnabled) {
// Direct file write without diff view or opening the file
await cline.diffViewProvider.saveDirectly(validRelPath, newContent, false, diagnosticsEnabled, writeDelayMs)
} else {
// Original behavior with diff view
// Show changes in diff view
if (!cline.diffViewProvider.isEditing) {
await cline.ask("tool", JSON.stringify(sharedMessageProps), true).catch(() => {})
await cline.diffViewProvider.open(validRelPath)
await cline.diffViewProvider.update(fileContent, false)
cline.diffViewProvider.scrollToFirstDiff()
await delay(200)
}
await cline.diffViewProvider.update(newContent, true)
// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
}