Browse Source

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

Daniel 5 months ago
parent
commit
1cc9f15df1

+ 12 - 13
src/core/tools/insertContentTool.ts

@@ -136,6 +136,7 @@ export async function insertContentTool(
 			approvalContent = updatedContent
 			approvalContent = updatedContent
 		}
 		}
 
 
+		// Prepare the approval message (same for both flows)
 		const completeMessage = JSON.stringify({
 		const completeMessage = JSON.stringify({
 			...sharedMessageProps,
 			...sharedMessageProps,
 			diff,
 			diff,
@@ -144,35 +145,33 @@ export async function insertContentTool(
 			isProtected: isWriteProtected,
 			isProtected: isWriteProtected,
 		} satisfies ClineSayTool)
 		} 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
 		const didApprove = await cline
 			.ask("tool", completeMessage, isWriteProtected)
 			.ask("tool", completeMessage, isWriteProtected)
 			.then((response) => response.response === "yesButtonClicked")
 			.then((response) => response.response === "yesButtonClicked")
 
 
 		if (!didApprove) {
 		if (!didApprove) {
+			// Revert changes if diff view was shown
 			if (!isPreventFocusDisruptionEnabled) {
 			if (!isPreventFocusDisruptionEnabled) {
 				await cline.diffViewProvider.revertChanges()
 				await cline.diffViewProvider.revertChanges()
 			}
 			}
 			pushToolResult("Changes were rejected by the user.")
 			pushToolResult("Changes were rejected by the user.")
+			await cline.diffViewProvider.reset()
 			return
 			return
 		}
 		}
 
 
+		// Save the changes
 		if (isPreventFocusDisruptionEnabled) {
 		if (isPreventFocusDisruptionEnabled) {
 			// Direct file write without diff view or opening the file
 			// Direct file write without diff view or opening the file
 			await cline.diffViewProvider.saveDirectly(relPath, updatedContent, false, diagnosticsEnabled, writeDelayMs)
 			await cline.diffViewProvider.saveDirectly(relPath, updatedContent, false, diagnosticsEnabled, writeDelayMs)
 		} else {
 		} 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
 			// Call saveChanges to update the DiffViewProvider properties
 			await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
 			await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
 		}
 		}

+ 59 - 30
src/core/tools/multiApplyDiffTool.ts

@@ -525,9 +525,10 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
 					isProtected: isWriteProtected,
 					isProtected: isWriteProtected,
 				}
 				}
 
 
-				// If single file, ask for approval
+				// If single file, handle based on PREVENT_FOCUS_DISRUPTION setting
 				let didApprove = true
 				let didApprove = true
 				if (operationsToApprove.length === 1) {
 				if (operationsToApprove.length === 1) {
+					// Prepare common data for single file operation
 					const diffContents = diffItems.map((item) => item.content).join("\n\n")
 					const diffContents = diffItems.map((item) => item.content).join("\n\n")
 					const operationMessage = JSON.stringify({
 					const operationMessage = JSON.stringify({
 						...sharedMessageProps,
 						...sharedMessageProps,
@@ -535,7 +536,6 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
 					} satisfies ClineSayTool)
 					} satisfies ClineSayTool)
 
 
 					let toolProgressStatus
 					let toolProgressStatus
-
 					if (cline.diffStrategy && cline.diffStrategy.getProgressStatus) {
 					if (cline.diffStrategy && cline.diffStrategy.getProgressStatus) {
 						toolProgressStatus = 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
 					const isWriteProtected = cline.rooProtectedController?.isWriteProtected(relPath) || false
 					didApprove = await askApproval("tool", operationMessage, toolProgressStatus, isWriteProtected)
 					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 {
 				} 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
 				// Track file edit operation

+ 10 - 13
src/core/tools/searchAndReplaceTool.ts

@@ -210,17 +210,25 @@ export async function searchAndReplaceTool(
 			EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
 			EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
 		)
 		)
 
 
-		// Request user approval for changes
 		const completeMessage = JSON.stringify({
 		const completeMessage = JSON.stringify({
 			...sharedMessageProps,
 			...sharedMessageProps,
 			diff,
 			diff,
 			isProtected: isWriteProtected,
 			isProtected: isWriteProtected,
 		} satisfies ClineSayTool)
 		} 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
 		const didApprove = await cline
 			.ask("tool", completeMessage, isWriteProtected)
 			.ask("tool", completeMessage, isWriteProtected)
 			.then((response) => response.response === "yesButtonClicked")
 			.then((response) => response.response === "yesButtonClicked")
 
 
 		if (!didApprove) {
 		if (!didApprove) {
+			// Revert changes if diff view was shown
 			if (!isPreventFocusDisruptionEnabled) {
 			if (!isPreventFocusDisruptionEnabled) {
 				await cline.diffViewProvider.revertChanges()
 				await cline.diffViewProvider.revertChanges()
 			}
 			}
@@ -229,22 +237,11 @@ export async function searchAndReplaceTool(
 			return
 			return
 		}
 		}
 
 
+		// Save the changes
 		if (isPreventFocusDisruptionEnabled) {
 		if (isPreventFocusDisruptionEnabled) {
 			// Direct file write without diff view or opening the file
 			// Direct file write without diff view or opening the file
 			await cline.diffViewProvider.saveDirectly(validRelPath, newContent, false, diagnosticsEnabled, writeDelayMs)
 			await cline.diffViewProvider.saveDirectly(validRelPath, newContent, false, diagnosticsEnabled, writeDelayMs)
 		} else {
 		} 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
 			// Call saveChanges to update the DiffViewProvider properties
 			await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
 			await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)
 		}
 		}