Skip to content

Commit 53f9f28

Browse files
committed
Consolidate checkpoint creation to single location
Addresses @cte's feedback in PR #4840 comment: - Remove existing logic that saves checkpoints AFTER changes in presentAssistantMessage.ts - Consolidate checkpoint creation to askApproval function for file-editing tools - Remove individual checkpoint calls from writeToFileTool, applyDiffTool, insertContentTool, and searchAndReplaceTool - Handle special case for multiApplyDiffTool batch operations - Maintains fix for #4827: checkpoints are created BEFORE file modifications This reduces code duplication and centralizes checkpoint logic in a single place.
1 parent 7bdc7fd commit 53f9f28

File tree

7 files changed

+571
-30
lines changed

7 files changed

+571
-30
lines changed

roo-code-messages.log

Lines changed: 534 additions & 0 deletions
Large diffs are not rendered by default.

src/core/assistant-message/presentAssistantMessage.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,17 @@ export async function presentAssistantMessage(cline: Task) {
289289
pushToolResult(formatResponse.toolResult(formatResponse.toolApprovedWithFeedback(text), images))
290290
}
291291

292+
// Create checkpoint BEFORE file modifications for file-editing tools (fixes #4827)
293+
const isFileEditingTool = [
294+
"write_to_file",
295+
"apply_diff",
296+
"insert_content",
297+
"search_and_replace",
298+
].includes(block.name)
299+
if (isFileEditingTool && cline.enableCheckpoints) {
300+
await cline.checkpointSave()
301+
}
302+
292303
return true
293304
}
294305

@@ -521,15 +532,8 @@ export async function presentAssistantMessage(cline: Task) {
521532
break
522533
}
523534

524-
// Note: Checkpoints are now created BEFORE file modifications in individual tools
525-
// This section is kept for any edge cases where files might be modified outside of tools
526-
const recentlyModifiedFiles = cline.fileContextTracker.getAndClearCheckpointPossibleFile()
527-
528-
if (recentlyModifiedFiles.length > 0) {
529-
// This should rarely be triggered now since checkpoints are created before modifications
530-
console.log("[presentAssistantMessage] Creating checkpoint after file modification (fallback)")
531-
await checkpointSave(cline)
532-
}
535+
// Checkpoints are now created BEFORE file modifications in the askApproval function above
536+
// No longer need to create checkpoints after file modifications
533537

534538
// Seeing out of bounds is fine, it means that the next too call is being
535539
// built up and ready to add to assistantMessageContent to present.

src/core/tools/applyDiffTool.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,7 @@ export async function applyDiffToolLegacy(
165165
return
166166
}
167167

168-
// Create checkpoint BEFORE making changes (fixes #4827)
169-
if (cline.enableCheckpoints) {
170-
await cline.checkpointSave()
171-
}
168+
// Checkpoint is now created in askApproval function before this point (fixes #4827)
172169

173170
// Call saveChanges to update the DiffViewProvider properties
174171
await cline.diffViewProvider.saveChanges()

src/core/tools/insertContentTool.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,7 @@ export async function insertContentTool(
140140
return
141141
}
142142

143-
// Create checkpoint BEFORE making changes (fixes #4827)
144-
if (cline.enableCheckpoints) {
145-
await cline.checkpointSave()
146-
}
143+
// Checkpoint is now created in askApproval function before this point (fixes #4827)
147144

148145
// Call saveChanges to update the DiffViewProvider properties
149146
await cline.diffViewProvider.saveChanges()

src/core/tools/multiApplyDiffTool.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ Original error: ${errorMessage}`
301301
operationsToApprove.forEach((opResult) => {
302302
updateOperationResult(opResult.path, { status: "approved" })
303303
})
304+
305+
// Create checkpoint BEFORE processing batch operations (fixes #4827)
306+
if (cline.enableCheckpoints) {
307+
await cline.checkpointSave()
308+
}
304309
} else if (response === "noButtonClicked") {
305310
// Deny all files
306311
if (text) {
@@ -321,12 +326,14 @@ Original error: ${errorMessage}`
321326
if (parsedResponse.action === "applyDiff" && parsedResponse.approvedFiles) {
322327
const approvedFiles = parsedResponse.approvedFiles
323328
let hasAnyDenial = false
329+
let hasAnyApproval = false
324330

325331
operationsToApprove.forEach((opResult) => {
326332
const approved = approvedFiles[opResult.path] === true
327333

328334
if (approved) {
329335
updateOperationResult(opResult.path, { status: "approved" })
336+
hasAnyApproval = true
330337
} else {
331338
hasAnyDenial = true
332339
updateOperationResult(opResult.path, {
@@ -339,17 +346,24 @@ Original error: ${errorMessage}`
339346
if (hasAnyDenial) {
340347
cline.didRejectTool = true
341348
}
349+
350+
// Create checkpoint BEFORE processing approved operations (fixes #4827)
351+
if (hasAnyApproval && cline.enableCheckpoints) {
352+
await cline.checkpointSave()
353+
}
342354
} else {
343355
// Legacy individual permissions format
344356
const individualPermissions = parsedResponse
345357
let hasAnyDenial = false
358+
let hasAnyApproval = false
346359

347360
batchDiffs.forEach((batchDiff, index) => {
348361
const opResult = operationsToApprove[index]
349362
const approved = individualPermissions[batchDiff.key] === true
350363

351364
if (approved) {
352365
updateOperationResult(opResult.path, { status: "approved" })
366+
hasAnyApproval = true
353367
} else {
354368
hasAnyDenial = true
355369
updateOperationResult(opResult.path, {
@@ -362,6 +376,11 @@ Original error: ${errorMessage}`
362376
if (hasAnyDenial) {
363377
cline.didRejectTool = true
364378
}
379+
380+
// Create checkpoint BEFORE processing approved operations (fixes #4827)
381+
if (hasAnyApproval && cline.enableCheckpoints) {
382+
await cline.checkpointSave()
383+
}
365384
}
366385
} catch (error) {
367386
// Fallback: if JSON parsing fails, deny all files
@@ -381,11 +400,7 @@ Original error: ${errorMessage}`
381400
updateOperationResult(opResult.path, { status: "approved" })
382401
}
383402

384-
// Create checkpoint BEFORE processing any approved operations (fixes #4827)
385-
const approvedOperations = operationResults.filter((op) => op.status === "approved")
386-
if (approvedOperations.length > 0 && cline.enableCheckpoints) {
387-
await cline.checkpointSave()
388-
}
403+
// Checkpoint is now created in askApproval function before this point (fixes #4827)
389404

390405
// Process approved operations
391406
const results: string[] = []

src/core/tools/searchAndReplaceTool.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,7 @@ export async function searchAndReplaceTool(
226226
return
227227
}
228228

229-
// Create checkpoint BEFORE making changes (fixes #4827)
230-
if (cline.enableCheckpoints) {
231-
await cline.checkpointSave()
232-
}
229+
// Checkpoint is now created in askApproval function before this point (fixes #4827)
233230

234231
// Call saveChanges to update the DiffViewProvider properties
235232
await cline.diffViewProvider.saveChanges()

src/core/tools/writeToFileTool.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,7 @@ export async function writeToFileTool(
212212
return
213213
}
214214

215-
// Create checkpoint BEFORE making changes (fixes #4827)
216-
if (cline.enableCheckpoints) {
217-
await cline.checkpointSave()
218-
}
215+
// Checkpoint is now created in askApproval function before this point (fixes #4827)
219216

220217
// Call saveChanges to update the DiffViewProvider properties
221218
await cline.diffViewProvider.saveChanges()

0 commit comments

Comments
 (0)