diff --git a/src/core/tools/insertContentTool.ts b/src/core/tools/insertContentTool.ts index a42eb6f6f9..b5e85dea30 100644 --- a/src/core/tools/insertContentTool.ts +++ b/src/core/tools/insertContentTool.ts @@ -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) } diff --git a/src/core/tools/multiApplyDiffTool.ts b/src/core/tools/multiApplyDiffTool.ts index 80f4c9a054..db514d2b64 100644 --- a/src/core/tools/multiApplyDiffTool.ts +++ b/src/core/tools/multiApplyDiffTool.ts @@ -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() - - // Call saveChanges to update the DiffViewProvider properties - await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs) + // 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) + } } // Track file edit operation diff --git a/src/core/tools/searchAndReplaceTool.ts b/src/core/tools/searchAndReplaceTool.ts index 09b644f931..50f4868b50 100644 --- a/src/core/tools/searchAndReplaceTool.ts +++ b/src/core/tools/searchAndReplaceTool.ts @@ -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) }