Merge pull request #1232 from RooVetGit/enable_checkpoints

Graduate checkpoints out of beta
This commit is contained in:
Matt Rubens 2025-02-27 09:37:52 -05:00 committed by GitHub
commit 2e9c808e63
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 80 additions and 79 deletions

View file

@ -0,0 +1,5 @@
---
"roo-cline": patch
---
Graduate checkpoints out of beta

View file

@ -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
}
}
}

View file

@ -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<string[] | undefined>,
this.getGlobalState("soundEnabled") as Promise<boolean | undefined>,
this.getGlobalState("diffEnabled") as Promise<boolean | undefined>,
this.getGlobalState("checkpointsEnabled") as Promise<boolean | undefined>,
this.getGlobalState("enableCheckpoints") as Promise<boolean | undefined>,
this.getGlobalState("soundVolume") as Promise<number | undefined>,
this.getGlobalState("browserViewportSize") as Promise<string | undefined>,
this.getGlobalState("fuzzyMatchThreshold") as Promise<number | undefined>,
@ -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,

View file

@ -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)

View file

@ -111,7 +111,7 @@ export interface ExtensionState {
soundEnabled?: boolean
soundVolume?: number
diffEnabled?: boolean
checkpointsEnabled: boolean
enableCheckpoints: boolean
browserViewportSize?: string
screenshotQuality?: number
fuzzyMatchThreshold?: number

View file

@ -52,7 +52,7 @@ export interface WebviewMessage {
| "soundEnabled"
| "soundVolume"
| "diffEnabled"
| "checkpointsEnabled"
| "enableCheckpoints"
| "browserViewportSize"
| "screenshotQuality"
| "openMcpSettings"

View file

@ -53,7 +53,7 @@ export type GlobalStateKey =
| "soundEnabled"
| "soundVolume"
| "diffEnabled"
| "checkpointsEnabled"
| "enableCheckpoints"
| "browserViewportSize"
| "screenshotQuality"
| "fuzzyMatchThreshold"

View file

@ -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" }}>
<span className="codicon codicon-close"></span>
</VSCodeButton>
<h2 style={{ margin: "0 0 8px" }}>🎉{" "}Introducing Roo Code 3.2</h2>
<h2 style={{ margin: "0 0 8px" }}>🎉{" "}Automatic Checkpoints Now Enabled</h2>
<p style={{ margin: "5px 0px" }}>
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.
</p>
<h3 style={{ margin: "12px 0 8px" }}>Custom Modes: Celebrating Our New Identity</h3>
<h3 style={{ margin: "12px 0 8px" }}>What's New</h3>
<p style={{ margin: "5px 0px" }}>
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:
<ul style={{ margin: "4px 0 6px 20px", padding: 0 }}>
<li>QA Engineers who write thorough test cases and catch edge cases</li>
<li>Product Managers who excel at user stories and feature prioritization</li>
<li>UI/UX Designers who craft beautiful, accessible interfaces</li>
<li>Code Reviewers who ensure quality and maintainability</li>
<li>Peace of mind when making significant changes</li>
<li>Ability to visually inspect changes between steps</li>
<li>Easy rollback if you're not satisfied with certain code modifications</li>
<li>Improved navigation through complex task execution</li>
</ul>
Just click the <span className="codicon codicon-notebook" style={{ fontSize: "10px" }}></span> icon to
get started with Custom Modes!
</p>
<h3 style={{ margin: "12px 0 8px" }}>Join Us for the Next Chapter</h3>
<h3 style={{ margin: "12px 0 8px" }}>Customize Your Experience</h3>
<p style={{ margin: "5px 0px" }}>
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{" "}
<VSCodeLink href="https://www.reddit.com/r/RooCode" style={{ display: "inline" }}>
reddit.com/r/RooCode
</VSCodeLink>
.
While we recommend keeping this feature enabled, you can disable it if needed.{" "}
<VSCodeLink
href="#"
onClick={(e) => {
e.preventDefault()
window.postMessage({ type: "action", action: "settingsButtonClicked" }, "*")
}}
style={{ display: "inline", padding: "0 2px" }}>
Open Settings
</VSCodeLink>{" "}
and look for the "Enable automatic checkpoints" option in the Advanced Settings section.
</p>
</div>
)

View file

@ -52,7 +52,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone },
alwaysAllowWrite,
alwaysApproveResubmit,
browserViewportSize,
checkpointsEnabled,
enableCheckpoints,
diffEnabled,
experiments,
fuzzyMatchThreshold,
@ -143,7 +143,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ 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<SettingsViewRef, SettingsViewProps>(({ onDone },
</p>
</div>
<div style={{ marginBottom: 15 }}>
<VSCodeCheckbox
checked={enableCheckpoints}
onChange={(e: any) => {
setCachedStateField("enableCheckpoints", e.target.checked)
}}>
<span style={{ fontWeight: "500" }}>Enable automatic checkpoints</span>
</VSCodeCheckbox>
<p
style={{
fontSize: "12px",
marginTop: "5px",
color: "var(--vscode-descriptionForeground)",
}}>
When enabled, Roo will automatically create checkpoints during task execution, making it
easy to review changes or revert to earlier states.
</p>
</div>
<div style={{ marginBottom: 15 }}>
<VSCodeCheckbox
checked={diffEnabled}
@ -779,28 +798,6 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone },
</div>
)}
<div style={{ marginBottom: 15 }}>
<div style={{ display: "flex", alignItems: "center", gap: "5px" }}>
<span style={{ color: "var(--vscode-errorForeground)" }}></span>
<VSCodeCheckbox
checked={checkpointsEnabled}
onChange={(e: any) => {
setCachedStateField("checkpointsEnabled", e.target.checked)
}}>
<span style={{ fontWeight: "500" }}>Enable experimental checkpoints</span>
</VSCodeCheckbox>
</div>
<p
style={{
fontSize: "12px",
marginTop: "5px",
color: "var(--vscode-descriptionForeground)",
}}>
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.
</p>
</div>
{Object.entries(experimentConfigsMap)
.filter((config) => config[0] !== "DIFF_STRATEGY")
.map((config) => (

View file

@ -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 })),