Skip to content

Commit b4b307e

Browse files
canvrnosaoudrizwanellipsis-dev[bot]
authored
fix: use new branching strategy to reduce checkpoints size (RooCodeInc#2048)
* rebased to main * Added files from patch * restored ClineProvider call to Migration deletes, added try try catch * Restored changes to Cline.ts * Updated tests * Updated tests, prettier * Optimize commit operation * Fixed branch deletion, cleanup * Cleanup * minor cleanuop * changeset * Fix checkpoint tracker initial commit not tracking any files * Ensure we are getting hash from branch and not main * Revert first commit logic * Change to get the correct hash for 'See new changes' on new and resumed tasks * Make checkpoints commits async * Update .changeset/cold-beers-laugh.md Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> --------- Co-authored-by: Saoud Rizwan <[email protected]> Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
1 parent 8900df7 commit b4b307e

File tree

11 files changed

+830
-976
lines changed

11 files changed

+830
-976
lines changed

.changeset/cold-beers-laugh.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": patch
3+
---
4+
5+
Removed legacy support from checkpoints, optimized checkpoint operations

src/core/Cline.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,10 @@ export class Cline {
295295
case "workspace":
296296
if (!this.checkpointTracker) {
297297
try {
298-
this.checkpointTracker = await CheckpointTracker.create(this.taskId, this.providerRef.deref())
298+
this.checkpointTracker = await CheckpointTracker.create(
299+
this.taskId,
300+
this.providerRef.deref()?.context.globalStorageUri.fsPath,
301+
)
299302
this.checkpointTrackerErrorMessage = undefined
300303
} catch (error) {
301304
const errorMessage = error instanceof Error ? error.message : "Unknown error"
@@ -408,7 +411,10 @@ export class Cline {
408411
// TODO: handle if this is called from outside original workspace, in which case we need to show user error message we cant show diff outside of workspace?
409412
if (!this.checkpointTracker) {
410413
try {
411-
this.checkpointTracker = await CheckpointTracker.create(this.taskId, this.providerRef.deref())
414+
this.checkpointTracker = await CheckpointTracker.create(
415+
this.taskId,
416+
this.providerRef.deref()?.context.globalStorageUri.fsPath,
417+
)
412418
this.checkpointTrackerErrorMessage = undefined
413419
} catch (error) {
414420
const errorMessage = error instanceof Error ? error.message : "Unknown error"
@@ -512,7 +518,10 @@ export class Cline {
512518

513519
if (!this.checkpointTracker) {
514520
try {
515-
this.checkpointTracker = await CheckpointTracker.create(this.taskId, this.providerRef.deref())
521+
this.checkpointTracker = await CheckpointTracker.create(
522+
this.taskId,
523+
this.providerRef.deref()?.context.globalStorageUri.fsPath,
524+
)
516525
this.checkpointTrackerErrorMessage = undefined
517526
} catch (error) {
518527
const errorMessage = error instanceof Error ? error.message : "Unknown error"
@@ -798,7 +807,8 @@ export class Cline {
798807
}
799808

800809
private async resumeTaskFromHistory() {
801-
// TODO: right now we let users init checkpoints for old tasks, assuming they're continuing them from the same workspace (which we never tied to tasks, so no way for us to know if it's opened in the right workspace)
810+
// UPDATE: we don't need this anymore since most tasks are now created with checkpoints enabled
811+
// right now we let users init checkpoints for old tasks, assuming they're continuing them from the same workspace (which we never tied to tasks, so no way for us to know if it's opened in the right workspace)
802812
// const doesShadowGitExist = await CheckpointTracker.doesShadowGitExist(this.taskId, this.providerRef.deref())
803813
// if (!doesShadowGitExist) {
804814
// this.checkpointTrackerErrorMessage = "Checkpoints are only available for new tasks"
@@ -3031,7 +3041,10 @@ export class Cline {
30313041
// isNewTask &&
30323042
if (!this.checkpointTracker) {
30333043
try {
3034-
this.checkpointTracker = await CheckpointTracker.create(this.taskId, this.providerRef.deref())
3044+
this.checkpointTracker = await CheckpointTracker.create(
3045+
this.taskId,
3046+
this.providerRef.deref()?.context.globalStorageUri.fsPath,
3047+
)
30353048
this.checkpointTrackerErrorMessage = undefined
30363049
} catch (error) {
30373050
const errorMessage = error instanceof Error ? error.message : "Unknown error"

src/core/webview/ClineProvider.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import { getUri } from "./getUri"
3535
import { telemetryService } from "../../services/telemetry/TelemetryService"
3636
import { TelemetrySetting } from "../../shared/TelemetrySetting"
3737
import { validateThinkingBudget } from "../../utils/validation"
38+
import { cleanupLegacyCheckpoints } from "../../integrations/checkpoints/CheckpointMigration"
39+
import CheckpointTracker from "../../integrations/checkpoints/CheckpointTracker"
3840

3941
/*
4042
https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts
@@ -134,6 +136,11 @@ export class ClineProvider implements vscode.WebviewViewProvider {
134136
this.workspaceTracker = new WorkspaceTracker(this)
135137
this.mcpHub = new McpHub(this)
136138
this.authManager = new FirebaseAuthManager(this)
139+
140+
// Clean up legacy checkpoints
141+
cleanupLegacyCheckpoints(this.context.globalStorageUri.fsPath, this.outputChannel).catch((error) => {
142+
console.error("Failed to cleanup legacy checkpoints:", error)
143+
})
137144
}
138145

139146
/*
@@ -1711,6 +1718,19 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
17111718

17121719
const { taskDirPath, apiConversationHistoryFilePath, uiMessagesFilePath } = await this.getTaskWithId(id)
17131720

1721+
// Delete checkpoints
1722+
console.info("deleting checkpoints")
1723+
const taskHistory = ((await this.getGlobalState("taskHistory")) as HistoryItem[] | undefined) || []
1724+
const historyItem = taskHistory.find((item) => item.id === id)
1725+
//console.log("historyItem: ", historyItem)
1726+
if (historyItem) {
1727+
try {
1728+
await CheckpointTracker.deleteCheckpoints(id, historyItem, this.context.globalStorageUri.fsPath)
1729+
} catch (error) {
1730+
console.error(`Failed to delete checkpoints for task ${id}:`, error)
1731+
}
1732+
}
1733+
17141734
await this.deleteTaskFromState(id)
17151735

17161736
// Delete the task files
@@ -1727,17 +1747,6 @@ Here is the project's README to help you get started:\n\n${mcpDetails.readmeCont
17271747
await fs.unlink(legacyMessagesFilePath)
17281748
}
17291749

1730-
// Delete the checkpoints directory if it exists
1731-
const checkpointsDir = path.join(taskDirPath, "checkpoints")
1732-
if (await fileExistsAtPath(checkpointsDir)) {
1733-
try {
1734-
await fs.rm(checkpointsDir, { recursive: true, force: true })
1735-
} catch (error) {
1736-
console.error(`Failed to delete checkpoints directory for task ${id}:`, error)
1737-
// Continue with deletion of task directory - don't throw since this is a cleanup operation
1738-
}
1739-
}
1740-
17411750
await fs.rmdir(taskDirPath) // succeeds if the dir is empty
17421751
}
17431752

src/integrations/checkpoints/CheckpointCommit.test.ts.bak

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ describe("Checkpoint Commit Operations", () => {
7575
expect(sortedDiffs[1].relativePath).to.equal("src/test2.txt")
7676

7777
// Verify file contents
78-
expect(sortedDiffs[0].before).to.equal("file1 initial\nfile2 initial\n")
79-
expect(sortedDiffs[0].after).to.equal("file1 modified\nfile2 modified\n")
78+
expect(sortedDiffs[0].before).to.equal("file1 initial\n")
79+
expect(sortedDiffs[0].after).to.equal("file1 modified\n")
80+
expect(sortedDiffs[1].before).to.equal("file2 initial\n")
81+
expect(sortedDiffs[1].after).to.equal("file2 modified\n")
8082
})
8183

8284
it("should create commit when files are deleted", async () => {

src/integrations/checkpoints/CheckpointExclusions.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,6 @@ import { GIT_DISABLED_SUFFIX } from "./CheckpointGitOperations"
3030
* and organized checkpoint history.
3131
*/
3232

33-
/**
34-
* Interface representing the result of a file exclusion check
35-
*/
36-
interface ExclusionResult {
37-
/** Whether the file should be excluded */
38-
excluded: boolean
39-
/** Optional reason for exclusion */
40-
reason?: string
41-
}
42-
4333
/**
4434
* Returns the default list of file and directory patterns to exclude from checkpoints.
4535
* Combines built-in patterns with workspace-specific LFS patterns.
@@ -129,7 +119,7 @@ function getMediaFilePatterns(): string[] {
129119
"*.webp",
130120
"*.tiff",
131121
"*.tif",
132-
"*.svg",
122+
// "*.svg",
133123
"*.raw",
134124
"*.heic",
135125
"*.avif",

0 commit comments

Comments
 (0)