检查点(Checkpoints)
概述
检查点(Checkpoint)功能允许用户保存 AI 对话状态的快照,并在对话历史中向前/向后导航。这是一个强大的版本控制机制,让用户能够在任意时刻保存工作状态,并在需要时恢复到之前的检查点。
v3.53.0 新功能:Previous checkpoint navigation controls in chat — 在聊天界面中新增了检查点导航控制按钮。
核心概念
检查点(Checkpoint)
检查点是工作区文件状态的快照。每次保存检查点时,系统使用 Git 在后台创建一个提交,记录当前所有文件的状态。这允许用户:
- 在任意时刻保存对话快照
- 在对话中向前/向后导航
- 恢复到之前的检查点状态
- 查看任意两个检查点之间的文件差异
核心技术
检查点功能基于 Shadow Git 实现:
- 每个任务有独立的 Git 仓库(存储在全局存储目录中)
- 工作区目录作为 Git 工作树
- 每次保存检查点创建一个 Git 提交
主要文件结构
src/core/checkpoints/
└── index.ts # 检查点核心模块
src/services/checkpoints/
├── index.ts # 服务入口
├── RepoPerTaskCheckpointService.ts # 按任务隔离的检查点服务
├── ShadowCheckpointService.ts # 底层 Git 操作服务
├── types.ts # 类型定义
└── excludes.ts # 文件排除规则
src/core/webview/
└── checkpointRestoreHandler.ts # 检查点恢复处理器API 参考
src/core/checkpoints/index.ts
getCheckpointService(task, options)
获取或创建任务的检查点服务。
typescript
async function getCheckpointService(
task: Task,
{ interval = 250 }: { interval?: number } = {}
): Promise<RepoPerTaskCheckpointService | undefined>参数:
task- 任务实例interval- 轮询间隔(毫秒)
返回:检查点服务实例或 undefined(当检查点被禁用时)
前置条件:
- 需要安装 Git
- 需要有工作区目录
- 需要有全局存储目录
checkpointSave(task, force?, suppressMessage?)
保存当前工作区状态为检查点。
typescript
async function checkpointSave(
task: Task,
force = false,
suppressMessage = false
): Promise<void>参数:
force- 是否允许空提交suppressMessage- 是否在聊天中隐藏检查点消息
checkpointRestore(task, options)
恢复到指定检查点。
typescript
async function checkpointRestore(
task: Task,
{ ts, commitHash, mode, operation }: CheckpointRestoreOptions
): Promise<void>
type CheckpointRestoreOptions = {
ts: number // 消息时间戳
commitHash: string // Git 提交哈希
mode: "preview" | "restore"
operation?: "delete" | "edit"
}模式:
preview- 仅预览,不修改消息restore- 实际恢复,会删除/编辑消息
操作:
delete- 删除检查点之后的对话edit- 编辑检查点处的消息
checkpointDiff(task, options)
查看检查点之间的文件差异。
typescript
async function checkpointDiff(
task: Task,
{ ts, previousCommitHash, commitHash, mode }: CheckpointDiffOptions
): Promise<void>
type CheckpointDiffOptions = {
ts?: number
previousCommitHash?: string
commitHash: string
mode: "from-init" | "checkpoint" | "to-current" | "full"
}差异模式:
from-init- 从初始检查点到当前检查点checkpoint- 从当前检查点到下一个检查点to-current- 从检查点到当前工作区full- 从初始检查点到当前工作区
src/services/checkpoints/types.ts
CheckpointResult
typescript
type CheckpointResult = Partial<CommitResult> & Pick<CommitResult, "commit">
// 包含 commit 属性的 Git 提交结果CheckpointDiff
typescript
type CheckpointDiff = {
paths: {
relative: string // 相对路径
absolute: string // 绝对路径
}
content: {
before: string // 变更前内容
after: string // 变更后内容
}
}CheckpointServiceOptions
typescript
interface CheckpointServiceOptions {
taskId: string // 任务 ID
workspaceDir: string // 工作区目录
shadowDir: string // 阴影目录(全局存储)
log?: (message: string) => void
}CheckpointEventMap
typescript
interface CheckpointEventMap {
initialize: {
type: "initialize"
workspaceDir: string
baseHash: string
created: boolean
duration: number
}
checkpoint: {
type: "checkpoint"
fromHash: string
toHash: string
duration: number
suppressMessage?: boolean
}
restore: {
type: "restore"
commitHash: string
duration: number
}
error: {
type: "error"
error: Error
}
}src/core/webview/checkpointRestoreHandler.ts
handleCheckpointRestoreOperation(config)
处理检查点恢复操作(删除或编辑)。
typescript
async function handleCheckpointRestoreOperation(
config: CheckpointRestoreConfig
): Promise<void>
interface CheckpointRestoreConfig {
provider: ClineProvider
currentCline: Task
messageTs: number
messageIndex: number
checkpoint: { hash: string }
operation: "delete" | "edit"
editData?: {
editedContent: string
images?: string[]
apiConversationHistoryIndex: number
}
}waitForClineInitialization(provider, timeoutMs?)
等待 Cline 初始化完成。
typescript
async function waitForClineInitialization(
provider: ClineProvider,
timeoutMs: number = 3000
): Promise<boolean>工作流程
保存检查点
- 调用
checkpointSave(task)保存当前工作区状态 - 检查点服务创建 Git 提交
- 通过
checkpoint事件通知 Webview 更新当前检查点哈希 - 在聊天中显示检查点保存消息
恢复检查点
- 用户选择要恢复的检查点
- 调用
handleCheckpointRestoreOperation()处理恢复 - 调用
checkpointRestore()执行实际恢复:- 在工作区执行
git checkout <commit> - 使用
MessageManager.rewindToTimestamp()回滚对话消息 - 取消当前任务并重新初始化
- 在工作区执行
- 对于删除操作:保存更新后的消息并重新创建任务
- 对于编辑操作:处理待处理的编辑数据
查看差异
- 用户选择比较模式
- 调用
checkpointDiff()获取变更列表 - 使用 VS Code 的
vscode.changes命令显示差异视图
事件流
[检查点服务] --checkpoint--> [Task] --postMessage--> [Webview]
|
v
[用户界面更新]错误处理
- Git 未安装:显示警告消息并禁用检查点
- 工作区路径不存在:禁用检查点
- 初始化超时:发送警告消息给用户
- 恢复失败:禁用该任务的检查点并记录日志
配置选项
检查点功能可通过以下任务配置控制:
enableCheckpoints- 是否启用检查点checkpointTimeout- 初始化超时时间(秒)checkpointServiceInitializing- 服务是否正在初始化