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 93d0c9d750..031e801628 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 @@ -29,36 +26,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 })),