From 10c6f8fb67bc358a8a57e16a103205f113ec6687 Mon Sep 17 00:00:00 2001
From: Matt Rubens
Date: Thu, 27 Feb 2025 01:31:30 -0500
Subject: [PATCH] Graduate checkpoints out of beta
---
.changeset/eighty-cheetahs-fetch.md | 5 +++
src/core/Cline.ts | 18 ++++----
src/core/webview/ClineProvider.ts | 30 ++++++-------
.../webview/__tests__/ClineProvider.test.ts | 4 +-
src/shared/ExtensionMessage.ts | 2 +-
src/shared/WebviewMessage.ts | 2 +-
src/shared/globalState.ts | 2 +-
.../src/components/chat/Announcement.tsx | 45 +++++++++----------
.../src/components/settings/SettingsView.tsx | 45 +++++++++----------
.../src/context/ExtensionStateContext.tsx | 6 +--
10 files changed, 80 insertions(+), 79 deletions(-)
create mode 100644 .changeset/eighty-cheetahs-fetch.md
diff --git a/.changeset/eighty-cheetahs-fetch.md b/.changeset/eighty-cheetahs-fetch.md
new file mode 100644
index 0000000000..ca103880c8
--- /dev/null
+++ b/.changeset/eighty-cheetahs-fetch.md
@@ -0,0 +1,5 @@
+---
+"roo-cline": patch
+---
+
+Graduate checkpoints out of beta
diff --git a/src/core/Cline.ts b/src/core/Cline.ts
index 532b9cbe99..00897eecf4 100644
--- a/src/core/Cline.ts
+++ b/src/core/Cline.ts
@@ -115,7 +115,7 @@ export class Cline {
isInitialized = false
// checkpoints
- checkpointsEnabled: boolean = false
+ enableCheckpoints: boolean = false
private checkpointService?: CheckpointService
// streaming
@@ -159,7 +159,7 @@ export class Cline {
this.fuzzyMatchThreshold = fuzzyMatchThreshold ?? 1.0
this.providerRef = new WeakRef(provider)
this.diffViewProvider = new DiffViewProvider(cwd)
- this.checkpointsEnabled = enableCheckpoints ?? false
+ this.enableCheckpoints = enableCheckpoints ?? false
if (historyItem) {
this.taskId = historyItem.id
@@ -3337,7 +3337,7 @@ export class Cline {
// Checkpoints
private async getCheckpointService() {
- if (!this.checkpointsEnabled) {
+ if (!this.enableCheckpoints) {
throw new Error("Checkpoints are disabled")
}
@@ -3378,7 +3378,7 @@ export class Cline {
commitHash: string
mode: "full" | "checkpoint"
}) {
- if (!this.checkpointsEnabled) {
+ if (!this.enableCheckpoints) {
return
}
@@ -3417,12 +3417,12 @@ export class Cline {
)
} catch (err) {
this.providerRef.deref()?.log("[checkpointDiff] disabling checkpoints for this task")
- this.checkpointsEnabled = false
+ this.enableCheckpoints = false
}
}
public async checkpointSave({ isFirst }: { isFirst: boolean }) {
- if (!this.checkpointsEnabled) {
+ if (!this.enableCheckpoints) {
return
}
@@ -3443,7 +3443,7 @@ export class Cline {
}
} catch (err) {
this.providerRef.deref()?.log("[checkpointSave] disabling checkpoints for this task")
- this.checkpointsEnabled = false
+ this.enableCheckpoints = false
}
}
@@ -3456,7 +3456,7 @@ export class Cline {
commitHash: string
mode: "preview" | "restore"
}) {
- if (!this.checkpointsEnabled) {
+ if (!this.enableCheckpoints) {
return
}
@@ -3511,7 +3511,7 @@ export class Cline {
this.providerRef.deref()?.cancelTask()
} catch (err) {
this.providerRef.deref()?.log("[checkpointRestore] disabling checkpoints for this task")
- this.checkpointsEnabled = false
+ this.enableCheckpoints = false
}
}
}
diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts
index 5e6170e2ee..633c7d7293 100644
--- a/src/core/webview/ClineProvider.ts
+++ b/src/core/webview/ClineProvider.ts
@@ -64,7 +64,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
private cline?: Cline
private workspaceTracker?: WorkspaceTracker
protected mcpHub?: McpHub // Change from private to protected
- private latestAnnouncementId = "jan-21-2025-custom-modes" // update to some unique identifier when we add a new announcement
+ private latestAnnouncementId = "feb-27-2025-automatic-checkpoints" // update to some unique identifier when we add a new announcement
configManager: ConfigManager
customModesManager: CustomModesManager
@@ -317,7 +317,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
apiConfiguration,
customModePrompts,
diffEnabled,
- checkpointsEnabled,
+ enableCheckpoints,
fuzzyMatchThreshold,
mode,
customInstructions: globalInstructions,
@@ -332,7 +332,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
apiConfiguration,
customInstructions: effectiveInstructions,
enableDiff: diffEnabled,
- enableCheckpoints: checkpointsEnabled,
+ enableCheckpoints,
fuzzyMatchThreshold,
task,
images,
@@ -347,7 +347,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
apiConfiguration,
customModePrompts,
diffEnabled,
- checkpointsEnabled,
+ enableCheckpoints,
fuzzyMatchThreshold,
mode,
customInstructions: globalInstructions,
@@ -362,7 +362,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
apiConfiguration,
customInstructions: effectiveInstructions,
enableDiff: diffEnabled,
- enableCheckpoints: checkpointsEnabled,
+ enableCheckpoints,
fuzzyMatchThreshold,
historyItem,
experiments,
@@ -1017,9 +1017,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await this.updateGlobalState("diffEnabled", diffEnabled)
await this.postStateToWebview()
break
- case "checkpointsEnabled":
- const checkpointsEnabled = message.bool ?? false
- await this.updateGlobalState("checkpointsEnabled", checkpointsEnabled)
+ case "enableCheckpoints":
+ const enableCheckpoints = message.bool ?? true
+ await this.updateGlobalState("enableCheckpoints", enableCheckpoints)
await this.postStateToWebview()
break
case "browserViewportSize":
@@ -1939,11 +1939,11 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await fs.unlink(legacyMessagesFilePath)
}
- const { checkpointsEnabled } = await this.getState()
+ const { enableCheckpoints } = await this.getState()
const baseDir = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0)
// Delete checkpoints branch.
- if (checkpointsEnabled && baseDir) {
+ if (enableCheckpoints && baseDir) {
const branchSummary = await simpleGit(baseDir)
.branch(["-D", `roo-code-checkpoints-${id}`])
.catch(() => undefined)
@@ -1999,7 +1999,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
alwaysAllowModeSwitch,
soundEnabled,
diffEnabled,
- checkpointsEnabled,
+ enableCheckpoints,
taskHistory,
soundVolume,
browserViewportSize,
@@ -2048,7 +2048,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
.sort((a: HistoryItem, b: HistoryItem) => b.ts - a.ts),
soundEnabled: soundEnabled ?? false,
diffEnabled: diffEnabled ?? true,
- checkpointsEnabled: checkpointsEnabled ?? false,
+ enableCheckpoints: enableCheckpoints ?? true,
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
allowedCommands,
soundVolume: soundVolume ?? 0.5,
@@ -2181,7 +2181,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
allowedCommands,
soundEnabled,
diffEnabled,
- checkpointsEnabled,
+ enableCheckpoints,
soundVolume,
browserViewportSize,
fuzzyMatchThreshold,
@@ -2265,7 +2265,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.getGlobalState("allowedCommands") as Promise,
this.getGlobalState("soundEnabled") as Promise,
this.getGlobalState("diffEnabled") as Promise,
- this.getGlobalState("checkpointsEnabled") as Promise,
+ this.getGlobalState("enableCheckpoints") as Promise,
this.getGlobalState("soundVolume") as Promise,
this.getGlobalState("browserViewportSize") as Promise,
this.getGlobalState("fuzzyMatchThreshold") as Promise,
@@ -2376,7 +2376,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
allowedCommands,
soundEnabled: soundEnabled ?? false,
diffEnabled: diffEnabled ?? true,
- checkpointsEnabled: checkpointsEnabled ?? false,
+ enableCheckpoints: enableCheckpoints ?? true,
soundVolume,
browserViewportSize: browserViewportSize ?? "900x600",
screenshotQuality: screenshotQuality ?? 75,
diff --git a/src/core/webview/__tests__/ClineProvider.test.ts b/src/core/webview/__tests__/ClineProvider.test.ts
index 6449cc93be..c8742cd3f4 100644
--- a/src/core/webview/__tests__/ClineProvider.test.ts
+++ b/src/core/webview/__tests__/ClineProvider.test.ts
@@ -369,7 +369,7 @@ describe("ClineProvider", () => {
uriScheme: "vscode",
soundEnabled: false,
diffEnabled: false,
- checkpointsEnabled: false,
+ enableCheckpoints: false,
writeDelayMs: 1000,
browserViewportSize: "900x600",
fuzzyMatchThreshold: 1.0,
@@ -677,7 +677,7 @@ describe("ClineProvider", () => {
},
mode: "code",
diffEnabled: true,
- checkpointsEnabled: false,
+ enableCheckpoints: false,
fuzzyMatchThreshold: 1.0,
experiments: experimentDefault,
} as any)
diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts
index e87edffed1..34abd38dbf 100644
--- a/src/shared/ExtensionMessage.ts
+++ b/src/shared/ExtensionMessage.ts
@@ -111,7 +111,7 @@ export interface ExtensionState {
soundEnabled?: boolean
soundVolume?: number
diffEnabled?: boolean
- checkpointsEnabled: boolean
+ enableCheckpoints: boolean
browserViewportSize?: string
screenshotQuality?: number
fuzzyMatchThreshold?: number
diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts
index fde7442cc1..8d3a114e65 100644
--- a/src/shared/WebviewMessage.ts
+++ b/src/shared/WebviewMessage.ts
@@ -52,7 +52,7 @@ export interface WebviewMessage {
| "soundEnabled"
| "soundVolume"
| "diffEnabled"
- | "checkpointsEnabled"
+ | "enableCheckpoints"
| "browserViewportSize"
| "screenshotQuality"
| "openMcpSettings"
diff --git a/src/shared/globalState.ts b/src/shared/globalState.ts
index 2cc90456a7..0863b34db2 100644
--- a/src/shared/globalState.ts
+++ b/src/shared/globalState.ts
@@ -53,7 +53,7 @@ export type GlobalStateKey =
| "soundEnabled"
| "soundVolume"
| "diffEnabled"
- | "checkpointsEnabled"
+ | "enableCheckpoints"
| "browserViewportSize"
| "screenshotQuality"
| "fuzzyMatchThreshold"
diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx
index a2e96606ef..13c77fe442 100644
--- a/webview-ui/src/components/chat/Announcement.tsx
+++ b/webview-ui/src/components/chat/Announcement.tsx
@@ -1,8 +1,5 @@
import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { memo } from "react"
-// import VSCodeButtonLink from "./VSCodeButtonLink"
-// import { getOpenRouterAuthUrl } from "./ApiOptions"
-// import { vscode } from "../utils/vscode"
interface AnnouncementProps {
version: string
@@ -28,36 +25,38 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {
style={{ position: "absolute", top: "8px", right: "8px" }}>
- 🎉{" "}Introducing Roo Code 3.2
+ 🎉{" "}Automatic Checkpoints Now Enabled
- Our biggest update yet is here - we're officially changing our name from Roo Cline to Roo Code! After
- growing beyond 50,000 installations, we're ready to chart our own course. Our heartfelt thanks to
- everyone in the Cline community who helped us reach this milestone.
+ We're thrilled to announce that our experimental Checkpoints feature is now enabled by default for all
+ users. This powerful feature automatically tracks your project changes during a task, allowing you to
+ quickly review or revert to earlier states if needed.
- Custom Modes: Celebrating Our New Identity
+ What's New
- To mark this new chapter, we're introducing the power to shape Roo Code into any role you need! Create
- specialized personas and create an entire team of agents with deeply customized prompts:
+ Automatic Checkpoints provide you with:
- - QA Engineers who write thorough test cases and catch edge cases
- - Product Managers who excel at user stories and feature prioritization
- - UI/UX Designers who craft beautiful, accessible interfaces
- - Code Reviewers who ensure quality and maintainability
+ - Peace of mind when making significant changes
+ - Ability to visually inspect changes between steps
+ - Easy rollback if you're not satisfied with certain code modifications
+ - Improved navigation through complex task execution
- Just click the icon to
- get started with Custom Modes!
- Join Us for the Next Chapter
+ Customize Your Experience
- We can't wait to see how you'll push Roo Code's potential even further! Share your custom modes and join
- the discussion at{" "}
-
- reddit.com/r/RooCode
-
- .
+ While we recommend keeping this feature enabled, you can disable it if needed.{" "}
+ {
+ e.preventDefault()
+ window.postMessage({ type: "action", action: "settingsButtonClicked" }, "*")
+ }}
+ style={{ display: "inline", padding: "0 2px" }}>
+ Open Settings
+ {" "}
+ and look for the "Enable automatic checkpoints" option in the Advanced Settings section.
)
diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx
index d3e65a99ea..51ef4fe81d 100644
--- a/webview-ui/src/components/settings/SettingsView.tsx
+++ b/webview-ui/src/components/settings/SettingsView.tsx
@@ -52,7 +52,7 @@ const SettingsView = forwardRef(({ onDone },
alwaysAllowWrite,
alwaysApproveResubmit,
browserViewportSize,
- checkpointsEnabled,
+ enableCheckpoints,
diffEnabled,
experiments,
fuzzyMatchThreshold,
@@ -143,7 +143,7 @@ const SettingsView = forwardRef(({ onDone },
vscode.postMessage({ type: "soundEnabled", bool: soundEnabled })
vscode.postMessage({ type: "soundVolume", value: soundVolume })
vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
- vscode.postMessage({ type: "checkpointsEnabled", bool: checkpointsEnabled })
+ vscode.postMessage({ type: "enableCheckpoints", bool: enableCheckpoints })
vscode.postMessage({ type: "browserViewportSize", text: browserViewportSize })
vscode.postMessage({ type: "fuzzyMatchThreshold", value: fuzzyMatchThreshold ?? 1.0 })
vscode.postMessage({ type: "writeDelayMs", value: writeDelayMs })
@@ -706,6 +706,25 @@ const SettingsView = forwardRef(({ onDone },
+
+
{
+ setCachedStateField("enableCheckpoints", e.target.checked)
+ }}>
+ Enable automatic checkpoints
+
+
+ When enabled, Roo will automatically create checkpoints during task execution, making it
+ easy to review changes or revert to earlier states.
+
+
+
(({ onDone },
)}
-
-
- ⚠️
- {
- setCachedStateField("checkpointsEnabled", e.target.checked)
- }}>
- Enable experimental checkpoints
-
-
-
- When enabled, Roo will save a checkpoint whenever a file in the workspace is modified,
- added or deleted, letting you easily revert to a previous state.
-
-
-
{Object.entries(experimentConfigsMap)
.filter((config) => config[0] !== "DIFF_STRATEGY")
.map((config) => (
diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx
index ae5c5b9539..3dfc87de75 100644
--- a/webview-ui/src/context/ExtensionStateContext.tsx
+++ b/webview-ui/src/context/ExtensionStateContext.tsx
@@ -32,7 +32,7 @@ export interface ExtensionStateContextType extends ExtensionState {
setSoundEnabled: (value: boolean) => void
setSoundVolume: (value: number) => void
setDiffEnabled: (value: boolean) => void
- setCheckpointsEnabled: (value: boolean) => void
+ setEnableCheckpoints: (value: boolean) => void
setBrowserViewportSize: (value: string) => void
setFuzzyMatchThreshold: (value: number) => void
preferredLanguage: string
@@ -79,7 +79,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
soundEnabled: false,
soundVolume: 0.5,
diffEnabled: false,
- checkpointsEnabled: false,
+ enableCheckpoints: true,
fuzzyMatchThreshold: 1.0,
preferredLanguage: "English",
writeDelayMs: 1000,
@@ -219,7 +219,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setSoundEnabled: (value) => setState((prevState) => ({ ...prevState, soundEnabled: value })),
setSoundVolume: (value) => setState((prevState) => ({ ...prevState, soundVolume: value })),
setDiffEnabled: (value) => setState((prevState) => ({ ...prevState, diffEnabled: value })),
- setCheckpointsEnabled: (value) => setState((prevState) => ({ ...prevState, checkpointsEnabled: value })),
+ setEnableCheckpoints: (value) => setState((prevState) => ({ ...prevState, enableCheckpoints: value })),
setBrowserViewportSize: (value: string) =>
setState((prevState) => ({ ...prevState, browserViewportSize: value })),
setFuzzyMatchThreshold: (value) => setState((prevState) => ({ ...prevState, fuzzyMatchThreshold: value })),