codex-rewind 的设计与取舍:让 Codex 同时回滚对话和代码

Codex 怎么同时回滚对话和代码?codex-rewind 的设计与取舍

Codex 增强软件使用教程:三个有界分区、独立 ignore 与多端复用架构

codex-rewind 是一个给 Codex 增加文件跟踪与"对话 + 文件同步回滚"的增强软件。

它使用 codexr 命令,可以和原来的 codex 并存;开启文件快照后再开始新会话,

之后回退对话时就能把对应的工作区文件一起恢复。

先用起来:给 Codex 加上文件跟踪

bash 复制代码
npm i -g codex-rewind
codexr --enable file_snapshots

照着下面四步用即可:

  1. 运行 npm i -g codex-rewind 安装。
  2. 运行 codexr --enable file_snapshots,并在这个进程里开始一个新会话
  3. 像平时一样让 Codex 工作;文件快照会在后台随 turn 记录,不需要手动提交。
  4. 需要回退时输入 /rewind,从列表里选择一条之前的提示词;对话和文件会一起
    回到那里。如果改主意,输入 /redo 再走回来。

想长期打开,可以在 /experimental 中启用 file_snapshots。这个开关按会话

生效:对已经运行了一半的旧会话中途开启,不能补录前面的快照。codexr 不替换

codex;不需要文件回滚时仍可照常使用原命令。

下面先说明它解决的具体问题,再拆解为什么文件跟踪采用三个有界分区、为什么要有

独立的 .codexsnapignore,以及同一套底层能力如何面向多个 Codex 界面复用。

Codex CLI 可以回滚对话。双击 Esc,把上下文退回到几轮之前------这个功能一直都在。

但它不回滚文件。回滚之后,磁盘上仍然是最新状态,而模型看到的是一段比磁盘更早的对话。这个错配在 #22100 里被明确记录:模型基于一份先于当前文件的对话继续推理。

一句话概括选择理由:它比只跟踪 edit 工具的方案覆盖更多工作区写入路径,又避开内部 git 整树索引的成本,同时对 Codex 原有会话格式零改动。

这是 Codex issue tracker 上反复出现的一类缺口。#9203 要求把 /undo 加回来,#11626 要求的正是「对话和代码一起回滚」------截至 2026-08-21,两个 issue 都仍然开放。

值得注意的是:这个功能官方做过两次:第一次上线后被整体撤回,第二次至今还活在 Desktop 里、以另一种方式出问题。两次失败的原因是同一个,而且这个原因不是「工程师不够小心」------恰恰相反,两次实现都为了安全做了额外动作,代价出现在别的地方。

我写了一份 RFC,提出第三种做法,并且把它实现出来发到了 npm。这篇文章先讲设计和代价,再讲为什么必须这么设计。


一、先说结论:四个设计决策,以及它们各自的代价

CSDN 的读者习惯先看结论,所以先摆结论。下面每一条都给出「做了什么 / 代价是什么 / 代价换来了什么」。

决策一:快照存在 CODEX_HOME,完全不碰用户的 git

内容寻址的 blob 与 manifest 存放在 CODEX_HOME/file_snapshots/ 下。恢复时只写文件内容,从不调用 git,也从不触碰 .git

复制代码
CODEX_HOME/file_snapshots/
  blobs/<xx>/<hash>          # 内容寻址的文件内容,天然去重
  manifests/<manifest-id>    # 每个检查点一份:[(path, mode, size, mtime, hash)]
  refs/<thread-id>           # thread → (turn_id, manifest-id) 列表 + 引用计数
  turns/<turn-id>            # turn → manifest-id,全局、与分支无关
  restores/<thread-id>       # thread → 它可以消费的 undo 记录

代价 :占用的磁盘没有任何现成工具会替你回收,所以这套子系统必须自己做 GC(引用计数 + mark-and-sweep,生命周期绑定会话)。同时也没有互操作性------你不能 git log 你的会话历史,也不能把一个检查点交给同事。

换来什么 :用户的仓库完全不受影响,前两次尝试所死于的那一整类故障被一次性排除------没有孤儿对象,没有被破坏的第三方客户端,也没有可以被写坏的 index。顺带一提,#29388 里 102 GB 那个案例的报告者,自己提的修法就是「把检查点存到 ~/.codex/ 下一个独立的仓库里」,和这里的存储模型是同一个方向。

决策二:跟踪范围是三个有界分区的并集,不是一次目录树遍历

被跟踪的文件集合 = 以下三部分的并集:

分区 来源 上界 在 codex 仓库上的实测
git-tracked 直接读 .git/index(用 gix,不 fork git ls-files) 项目边界:以 index 认定的项目文件为界,不受整棵工作区树影响 5,996 文件 / 56.4 MB / 265 ms
edit-touched 本次会话中 agent 工具写过的路径 会话动作边界:以 agent 本次会话实际写过的文件为界,不做额外数字截断 与这一轮的改动量成正比
recently modified 前两个分区之外,按 mtime 排序的 residue 硬护栏 :最多补 100 个额外文件,单文件 16 MB,跳过高频变动目录 100 文件 / 2.4 MB / 160 ms

关键不在于三个分区各自是什么,而在于三个分区都由目录树规模之外的证据约束。git-tracked 的自然边界是「项目 index 里有什么」,构建产物恰恰通常不在这里;edit-touched 的自然边界是「agent 在本次会话实际写过什么」;recently modified 是前两者之外的补集,也是唯一可能被大目录淹没的分区,所以再加上数量、单文件大小和 churn 目录三重硬护栏。前两个没有人为数字截断,不等于没有边界。

实测数字(在 codex 仓库上):完整子树遍历是 70,609 个文件 / 116,134 MB / 1.46 s ,几乎全是构建产物;三个分区的并集是 约 6,096 个文件 / 约 59 MB / 425 ms------文件数是 1/11.6,字节数是 1/1,975,耗时是 1/3.4。

但真正说明问题的不是这个比值,而是两次测量之间的漂移 。同一个 checkout,相隔几个小时再测一次:子树遍历从 58,116 文件 / 100,812 MB 涨到了上面那组数字------文件多了 21%,体积多了约 15 GB,纯粹来自这几个小时的编译。而 git 分区一动没动(两次都是 5,996 个文件)。

一个随「这个仓库被工作了多久」增长的开销,是没有人能做预算的开销。这也是为什么「有界」在 RFC 里被写成目标而不是优化项:一个每轮成本会随构建目录膨胀的子系统,用户第一件事就是把它关掉。

这组数字可以在任何目录树上复现:

bash 复制代码
cargo run -p codex-file-snapshots --example scan_bench -- <repo>

比值本身只说明形状、不构成常数;能泛化的结论是:三个分区里有两个在原理上就不随树增长。

代价 :覆盖率不是 100%,这一点必须直说而不是暗示。一个已经脱离 git 跟踪、之后只被 shell 命令改动、并且又掉出了「最近 100 个」窗口的文件,是不被跟踪的。 这是一个真实存在的缺口,虽然它的交集很窄。

换来什么:一个不随目录树增长的成本。这正是上一次尝试用一堆硬编码排除列表去逼近、但没能真正做到的性质。

顺带说一句,「跳过高频变动目录」不是排除列表的回归。target/node_modules/ 这类目录一直在变,按 recency 排序会把它们排在最前面,100 个名额在遍历到第一个源文件之前就用光了。排除它们是让「最近改动过」这个信号可用的前提,而不是在决定「保留什么」。

另外还有一条属性:并集携带该 thread 已经观察过的一切 ,所以会话内跟踪范围只增不减。一个被 git rm 从 index 里移走的文件不会在会话中途从跟踪集里消失------否则就没有任何东西记得它存在过,回滚也就带不回来了。

独立的 .codexsnapignore:版本控制边界不等于回滚边界

这不是把 .gitignore 换一个名字。两份规则回答的是两个不同问题:

  • .gitignore 决定什么不进入版本控制;
  • .codexsnapignore 决定文件回滚子系统绝不能快照、恢复或删除什么。

它们都使用 gitignore 语法,但规则集合刻意互相独立。比如本地调研笔记、生成的

文档可以因为不适合提交而写进 .gitignore,同时 写进

.codexsnapignore,于是它仍能通过 edit-touched 或 recently-modified 分区进入

回滚历史。反过来,密钥、数据库和缓存目录可以只写进 .codexsnapignore,即使

版本控制规则另有安排,回滚也不会碰它们。

实现不会读取 .gitignore;只有 git-tracked 分区因直接读取 index 而间接受它

影响。.codexsnapignore 则直接作用于三个分区,而且语义对称:匹配的路径从不被

快照、恢复或删除。这种"不重叠也没关系"正是独立 ignore 文件的价值。

决策三:删除只依据「见证过的创建」,不依据「完整性声明」

早期方案里每个 manifest 带一个 complete 标志,含义是「我枚举了全部」。删除一个文件是否安全,依赖这个标志为真。

现在这个标志没有了。删除只在有正面证据时发生,而正面证据只有一种:目标 manifest 里为该路径留有一个 tombstone,意味着那次捕获确实去找过这个路径、并且没找到。 「不在 manifest 里」什么都不能推出------一次捕获只看得见它被要求看的东西。

同时还有两条兜底:

  • 每次恢复前,先对当前状态做一次安全检查点。 所以恢复本身是可撤销的,/redo 就是「恢复那份安全 manifest」。
  • ignore 是对称的 :被忽略的路径永远不会被快照、不会被恢复、也不会被删除 。忽略在两个方向上都意味着不可见。这一条规则替掉了旧设计里一整类 preexisting_untracked 簿记。

代价:簿记本身。每一次被观察到的创建都要记录,所以存储里会带着一批「文件已经不在了、而且再也不会回来」的 tombstone。

换来什么 :complete 是一个声明,而一旦承认跟踪在所有路径上都是有界的,这个声明就永久为假,依赖它的删除规则也就成了死代码。tombstone 是观察而不是声明------恢复只删除那些系统真正看着它被创建出来的文件。加上「恢复前先做安全检查点」,删除规则偶尔判断错的代价是一次往返,而不是一个文件。第一次尝试的恢复路径底下没有这层网------判断错了就是真的没了。

决策四:开关是会话级的,不是每次调用级的

这个开关只回答一个问题:新会话是否跟踪? 打开它不影响已经在跑的会话,关掉它也不会让正在跟踪的会话停下来。因此一个会话的快照链要么从第 1 轮起完整,要么根本不存在,不存在中途开始的部分状态。

代价:你必须比你希望的更早做决定。会话中途打开,救不了你刚刚后悔的那一轮。

换来什么 :没有半跟踪状态。一个能中途切换的会话会存在没有快照的时间区间,而跨越这种区间的恢复无从知道自己缺了什么------那是一类静默的错误答案,比响亮的失败要糟糕得多。

和 Claude Code、OpenCode 相比,具体差在哪

这不是「谁全面胜过谁」的排名,而是三种机制选择了不同的覆盖边界。

  • Claude Code 的官方文档说明,checkpoint 跟踪的是内置文件编辑工具造成的改动,Bash 命令改动的文件不在恢复范围内。codex-rewind 保留了这类 edit-touched 跟踪,再加入 git-tracked 与 recently-modified 两个分区,所以工作区内由 shell/MCP 造成的改动可以在下一次检查点进入快照;代价是 recently-modified 分区有上限,覆盖仍然不是 100%。
  • OpenCode 的官方文档说明,它用内部 git 仓库跟踪项目,并特别提示大型仓库或多 submodule 项目可能出现索引变慢和明显的磁盘占用。codex-rewind 不调用 git,也不做无上限的整树快照,而是用内容寻址存储、持久 stat cache 和三个有界分区把成本约束在项目与本次会话上。

因此这里真正的优势不是一句泛泛的「也能回滚」,而是:比纯 edit-tool 跟踪覆盖更多写入路径,比整树 shadow-git 更少受目录树和构建产物牵制,同时明确承认自己的覆盖缺口。

对 Codex 会话格式是零改动

快照子系统对 Codex 现有会话存储格式是零改动 :不新增字段,不新增 rollout item,也不改变序列化格式。它把 {turn_id, manifest_id} 写在自己的独立日志里,只反向引用 Codex 已有的 turn id;rollout 从不引用快照库。因此 codexr 里开始的会话可以用官方 codex resume 接着跑,官方 codex 里开始的会话也可以用 codexr resume 接着跑。

这里要把两件事分开:会话格式确实完全没有被触碰;但官方 Codex 不写 file snapshot,所以在官方版里发生的轮次,切回 codexr 后也不能追溯回滚。后者是快照覆盖不连续,不是会话格式的兼容性问题。

不是只给 TUI 打补丁:同一套能力可以跨 Codex 界面复用

这一点和"会话格式双向兼容"不是一回事。快照的捕获 放在 codex-rscore------只有这里同时看得见工具执行和 turn 边界;恢复能力则放进 app-server协议。这样 CLI/TUI、IDE 扩展和 Desktop 客户端可以接到同一个快照库、同一套删除规则和安全检查点上,而不是每个界面再发明一种 checkpoint 格式。

当前 codex-rewind 直接提供的是 CLI/TUI 用户流程;这段话说的是 core +app-server 的架构可以被 Desktop/IDE 复用。可复用不等于已接入:Desktop 当前还没有采用这套实现。

这也是上游公开贡献指南强调的系统级问题。截至 2026-08-21,Codex 的贡献指南已经改为不接受外部代码贡献或 PR,而是鼓励通过 issue、复现、根因分析和设计讨论提供输入。指南给出的理由是:有效改动需要完整架构背景、系统级约束和 roadmap 视野。

"跨所有 Codex 界面的一致性"不再是当前指南里的逐字评审条件,所以不能继续这样引用;但它仍是这里最具体的系统级约束:一个只改 TUI 的 rewind 实现会继续留下多套机制,在 core 做一次、通过 app-server 给各端复用,才解决了底层缺口。


二、这四个决策是从哪来的:两次尸检

上面四条都是从具体的失败里反推出来的。下面是那两次失败。

2.1 第一次:Feature::GhostCommit(配置键 undo)

它把游离(dangling)的 commit 对象写进用户的真实仓库,恢复路径会动用户的 index。这个组合在 #8214 里造成了数据丢失。修复之后两天 ,这个功能就在 PR #8424 里被整体下线了。

这里最值得注意的是第二个死因,因为它说明「更小心地用 git」不是答案。

每次快照要跑一次 git status --untracked-files=all(完整树遍历),再加上一个一次性的临时 index 。用临时 index 是故意的安全设计------为了不碰用户自己的 index。但代价是:临时 index 每次都是新的,于是 git 的 stat cache 完全失效,每次快照都要从头重新哈希改动过的文件。

git status 之所以快,靠的就是 stat cache。为了安全放弃它,快照就慢了下来;慢下来之后,就被迫加上异步执行、一道针对写操作工具的就绪门(readiness gate)、一个 240 秒的 watchdog ,以及一串硬编码的排除列表(超过 10 MiB 的文件、超过 200 个条目的目录、node_modules.venv 等等)。

这是一条很清楚的因果链:为了安全避开用户的 index → 失去 stat cache → 慢 → 一层层复杂度。人一点都不马虎,地基不对。

对应的答案是决策一和决策二里没细讲的第三件事:这套子系统拥有自己的持久化 stat cache 。manifest 记录 (path, size, mtime, content_hash),检查点只对跟踪集做 stat,只对指纹发生变化的条目重新哈希。这正是让 git status 快起来的那个机制,在没有「不能碰用户 index」这个安全冲突的前提下被重新拿了回来。配上有界的跟踪集,检查点就是一次快速的 stat 遍历,可以同步执行------就绪门和 watchdog 这一整套复杂度直接不需要了。

细节上有一处必须处理:写入之后过快记录的指纹是不可信的。第二次写入如果落在「上一次读取」的同一个时间戳 tick 内,(size, mtime) 此后就永远不变,缓存会一直复用一个描述旧字节的哈希。git 把这种情况叫 racily clean;在 agent 场景下它不是罕见情况而是常态------一次 agent 编辑和紧随其后的检查点相差只有几毫秒。做法和 git 一致:在捕获时一次性判定,落在自身 mtime racy 窗口内的文件写入一个永远不会命中的零指纹,直到某次更晚的捕获发现它已经稳定下来。

2.2 第二次:Desktop 的 refs/codex/turn-diffs/

这一次还活着。Codex Desktop 至今在用户自己的仓库里refs/codex/turn-diffs/ 下保存整棵树的 git-object 检查点。

  • #29388:一个 5.7 GB 的项目里出现了 102 GB 的孤儿对象,没有 GC。
  • #28241:这些非标准的 refs 曾让基于 libgit2 的客户端出问题(该 issue 现已关闭)。

注意它的形状和第一次不同,但根子一样:第一次写的是对象并动了 index,这一次写的是 refs 和对象------写进去的仍然是用户自己的仓库。代价从数据丢失换成了磁盘和第三方工具的兼容性。

同样是小心的人,同样的地基。

2.3 还有第三条线:CLI/TUI 与 IDE 扩展

这个能力的缺失不止一处:

界面 现状 失败形态
CLI/TUI 只回滚对话的 backtrack(fork) 文件停在最新状态 → 旧上下文/新文件错配(#22100)
Desktop 用户仓库内的整树 git-object 检查点 无范围控制、无 GC(#29388);非标准 refs 曾破坏 libgit2 客户端(#28241,已关闭)
IDE 扩展 作用域限于 edit 工具的「View changes / Undo」工具条 模型改用 shell 而不是 edit 工具时,工具条会直接消失(#4535);可靠性反馈见 #3567#15367

三个界面各自长出了一套局部的、互不一致的替代品------因为它们缺的是同一个底层能力。这本身就是「应该在 core 里做一次」的论据。

2.4 共同的结论

两次实现都伸手去拿 git,而且这非常好理解:检查点问题看上去和 git 解决的问题一模一样------目录树的内容寻址快照,未改动的文件不重复存储。Codex 是开发者工具,git 本来就在,对象模型也是现成的。这不是判断失误,这是显而易见的一步。

两次实现随后发现的是同一件事:用户的仓库不是 Codex 该往里写东西的地方。

结论不是「更小心地用 git」。两边都很小心 ------ghost commits 特意绕开用户的 index,代价是丢掉 stat cache,慢到需要 240 秒的 watchdog;Desktop 同样绕开 index,代价是磁盘和客户端兼容性。结论是:会话历史是 Codex 自己的状态,不是项目的状态,它应该待在 Codex 自己的目录里。


三、「直接用 git 不就行了?」

这个反驳在每一个相关讨论串里都会出现,所以值得认真回答,而不是挥手带过。原话(openai/codex#11626):

Aren't folks using this in a git tracked repo? Adding features like these just bloat the product.

------ @rrajpuro

一个前提下 ,这话是对的。如果你是开发者、在一个仓库里、工作区是干净的,那么 git diff 告诉你改了什么,git checkout 就能还原。确实不需要造轮子。

那个前提是:开着 agent 的人是开发者,而且在仓库里。 这个前提正在悄悄变成假的。同一个讨论串里已经有人把话说清楚了:

I am not using codex just to code. I am using it for EVERYTHING... Suggesting that I git track every folder in my PC is ridiculous.

------ @sanskar-tiwari-surepass

这话是对的。现在很多人把这类工具指向的是文案、表格、报税材料、研究笔记、合同草稿------在这些目录里 git init 不是一套工作流,是一件戏服。安全网不能以「工作内容是代码」为条件,因为越来越多的工作内容不是代码。

但这个反驳在它自己的主场里也站不住,有三条理由和「非代码工作」无关。

第一,「用 git 就行了」的每一种版本,落到最后都是手工活。 把它当 undo buffer 用,你只能在几件事里挑一件:每轮都提交------这正是很多人在做而且很烦的事:

Since switching from Claude Code to Codex, I have to commit to Git after every single turn in the conversation, which is a huge hassle.

------ @zzy-life

或者用 stash(有它自己的尖角),或者干脆手工搭一套检查点机制------也就是这整篇文章在讨论的东西。

第二,它把簿记搬进了 agent 的上下文。 让模型记得去打检查点,是在把上下文花在任务之外的事情上,而且它和任何「需要模型记住」的事情一样不可靠。检查点应该在模型有没有想到它的情况下都发生。

第三,「让 agent 自己撤销」撑不过和真实编辑方式的接触。 这个建议默认 agent 有一份自己改了什么的持久记录。它没有:shell、unified_exec 和 MCP 工具调用都会改文件,但不会留下结构化的、持久的变更记录------这一点是 @postmelee 在读 rollback 路径时在同一个讨论串里指出的。让 agent 撤销,等于让它从一段对话记录里重建现场,这和让它凭记忆复原一个文件的旧内容是同一类操作。

而「git 不够用」最强的证据根本不是论证:OpenAI 把这个功能做了两次。 如果干净的工作区加 git checkout 就能覆盖,第一次就不会上线,第二次也不会至今还留在 Desktop 里。


四、做不到什么

这一节是这篇文章里最不该被删掉的部分。

  • 只回滚代码、不回滚对话------做不到。 机制上很容易,但我没有一个好答案来回答「然后呢」:模型会开始基于一段描述着「磁盘上已经不存在的编辑」的对话继续推理,也就是 #22100 那个错配的镜像版本。所以回滚是通过 backtrack(Esc)和 /rewind 提供的,两者都会同时给对话开一个分支。
  • 落在跟踪集之外的文件。 就是决策二里那个缺口:已经脱离 git 跟踪、之后只被 shell 改动、又掉出了最近 100 个窗口的文件。
  • 默认不管隐藏文件。 dot-file 和 dot-directory 默认跳过------.env、虚拟环境、编辑器状态。跟着一轮对话把这些回滚掉,偶尔是破坏性的。有 track_hidden_files 这个开关可以打开;.git 无论如何都排除在外。工作产物如果恰好是隐藏路径,仍然能通过 edit hook 覆盖到:agent 改过的 .github/workflows/ci.yml,从那次编辑起就被跟踪。
  • 工作区之外、由 shell/MCP 造成的改动。 不可观测(所有同类工具都一样)。UI 上必须说明恢复是有范围的。
  • 文件系统以外的一切。 回滚恢复文件。它不会把已经 push 的分支收回来,不会撤回一个已经发出去的请求,也不会把 drop 掉的表变回来。

五、项目地址与安装速查

这套增强能力发布为 codex-rewind 。命令名是 codexr,所以它和官方版并存,不会替换掉你已经装好的 codex,并且跟随上游发布。

按截至 2026-08-21 的公开规则,RFC 和相关 issue 讨论属于设计输入,不是一条已承诺的外部 PR路径。在上游提供同类能力之前,可以直接使用 codex-rewind。

bash 复制代码
npm i -g codex-rewind
codexr --enable file_snapshots

功能是 experimental 阶段的特性键 file_snapshots,会自动出现在 /experimental 菜单里;/status 会显示存储当前占用的磁盘大小。

许可证:Apache-2.0。

如果你手上正好有一个构建过很多次的仓库,scan_bench 那条命令跑一下大概只要一秒,得到的两个数字比这篇文章里的任何一段论证都直观。

六、如果你要的不是一整个 Codex 分发版

上面讲的这套机制,现在拆出来独立发布了两个项目 ------ 你不必为了用它而换掉自己的 CLI。

filesnap:只要引擎,不要 agent

filesnap 是快照与还原那一半,单独拿出来,外面不裹任何 agent。Rust 写的内容寻址存储,把一个目录还原成它先前某一刻的样子 ------

本文第一节讲的「不碰 git、有界扫描、没见证过就不删」那些规则,全都在这里。

bash 复制代码
cargo install filesnap-cli    # 装 filesnap 二进制
cargo add filesnap            # 或者当库用

任何语言都能接。 它是一个 4 MB 静态二进制,不需要运行时;每条命令往 stdout 写带版本号的JSON Lines,给人看的文字走 stderr ------ 所以集成就是「起个子进程 + 按行解析」。

实测(page cache 热态):

捕获文件数 首次 之后每次
小仓库 84 20 ms 8 ms
一个 70,918 文件的 checkout 捕获 7,995 个 1.75 s 268 ms

第二行就是本文第二节那个论点的另一个证据:7 万个文件的 checkout 不会付出 7 万个文件的代价,因为一次快照覆盖的是「这一轮有可能改到」的范围,不是根目录下的一切。

dsh-filesnap:DeepSeek Harness 上的同一套

dsh-filesnap 把同样的 /rewind/redo做成了 DeepSeek Harness 的插件。每轮一次工作区快照,浏览器 UI 里有回退控件,同样不碰你的 git。

bash 复制代码
dsh plugin --profile web add dsh-filesnap

⚠️ 装之前先知道一件事 :插件把回退点记为 session 事件,而 harness 目前没有给仓库外的插件提供声明事件类型的正式接口 ------ 它是在加载时改一个 harness 常量来声明的。能工作,但有个用户可见的后果:卸载插件之后,被它抓过快照的对话会打不开(读取端会拒绝含未知类型的日志)。磁盘上的数据完好,重装即可恢复访问。细节见仓库的「已知限制」一节。

想给自己的 agent 加 rewind 的话

dsh-filesnap 那个仓库本身就是一个可抄的样例,而且代价是可量的:src/cli.ts116 行(不含注释)就是全部的引擎接口 ------ 起进程、解析 JSONL、映射退出码,里面没有一行是 dsh 专有的。

真正需要你自己想清楚的是那个仓库里另外约 1,100 行:哪一轮值得捕获、对话可以 fork 之后一个回退点还意味着什么、对话和文件按什么顺序落地才能让中间崩溃仍可恢复。filesnap 刻意不替你做这些决定 ------ 每个 agent 都不一样,一个靠猜的库会以你无法覆盖的方式猜错。

相关推荐
小酒星小杜13 小时前
如何简单地创建你的第一部漫画?从一个“可见变化”开始
人工智能·python·产品
努力的小Qin17 小时前
从一句「想省点写周报的时间」开始,我用 Trae 迭代出了「工作日迹」
ai编程·trae·vibecoding
星期一研究室19 小时前
同样是写文档,为什么别人图文清爽?
微服务·产品·设计
知了一笑20 小时前
没有项目经理的半年
程序员·产品·项目
星期一研究室2 天前
用《颜色》管理项目,混乱现场快速变清晰
微服务·产品·设计
一点一木2 天前
豆包工作发布:飞书,才是它真正的底牌
人工智能·ai编程·产品
温暖的苹果2 天前
opencode 配置完全指南:配置文件、目录与字段详解
ai·llm·agent·vibecoding·opencode
怕浪猫3 天前
CLI、Web、桌面端全制霸:DeepSeek Harness 的多端架构是怎么设计的
aigc·agent·产品
程序员柒叔3 天前
luna 的内心独白:我把一个本该暂停的任务,跑成了几十轮空转
agent·ai编程·vibecoding