dsh-file-undo:为 Agent 的 write/edit 提供可审查的撤销时间线

前言

在 DSH 里让模型改代码,常见路径是 write 和 edit 工具直接落盘。一旦连续多轮改动,单靠 Git 或手动对照聊天,很难快速回答「这一轮到底动了哪几个文件、撤一步会不会盖掉我后来手改的内容」。社区插件 dsh-file-undo(维护者 QinLuza,分类:记忆)针对的就是这一类问题:在每次文件写入/编辑前抓全文快照,用侧栏红绿 diff 逐条审查,并支持 /undo 与两阶段确认撤销。当前版本 0.2.0,许可证 MIT。

这是什么

dsh-file-undo 是 DSH 插件,定位是撤销 agent 对文件的 write / edit 操作。实现上不存反向补丁,而是在落盘前保存 before 全文,撤销时整文件写回;diff 在现场计算,与存储解耦。除聊天命令外,还提供 Web 侧栏「撤销」面板(带未撤销计数徽章),并可在同一项目树下切换会话、自动跟随当前查看的会话。

核心功能

可视化审查面板

侧栏底部进入审查面板后,大致包含:

  • 历史列表:时间、工具类型(write / edit / create)、文件名、恢复/移除行数、模型轮次;失败调用也会留痕。
  • 撤销视角 diff:绿行表示撤销将恢复的内容,红行表示将移除的当前内容;超长内容默认截断,约 800 行后可「显示全部」。
  • 自动预检:打开条目即判断能否安全撤销,并给出分类原因(见下文安全模型)。
  • 两阶段确认:首次点击为武装(约 3 秒自动解除),再次点击才执行。
  • 会话切换器:列出当前目录及其父子目录下的会话,默认跟随当前查看会话;headless 等环境下可静默降级。

安全模型

Host 侧裁决能否改文件,UI 只展示结果。预检(preview)为只读分类,常见原因包括:file_creation(撤销创建类操作会删文件,需内容与 hash 双闸及确认)、external_modified(快照后文件被手工改过,避免吞掉人工编辑)、superseded_by_later_ops(其后还有同文件的编辑,引导「回退到此状态」)、already_reverted、file_missing、stale 等。提交(apply)携带 expectedCurrentHash 乐观锁,预览后文件再变则拒绝。还支持 RewindTo(选中历史条目原子写回,并明示将丢弃的后续步数)以及级联恢复/重做,状态在 recorded → reverted → reapplied 间闭环。聊天里的 /undo 不做 external_modified 拦截,保留强制撤销语义。

命令

命令 作用
/undo 撤销最近一次文件写入/编辑
/undo list 查看当前会话已记录的操作历史
/undo <n> 撤销指定索引的操作
/undo sessions 列出同项目树会话(与面板切换器同源 API)
/undo prune [days] 清理 N 天前的快照(默认 7),只缩回退深度,不动当前文件
/undo git [n] 从 git 归档恢复第 n 个快照(0 = 最新)
/undo git-status git 归档健康状态

快照存储与归档

快照目录结构(用户主目录下):

~/.dsh/file-undo/
  <workspace-key>/          # 由会话 cwd 规范化派生
    <chat-key>/             # 会话 id
      snapshots.jsonl       # append-only
      git-archive/          # 每条快照一个 commit,可静默降级

插件加载时按 7 天惰性清理;也可用 /undo prune 手动清理。路径写法不同但指向同一目录时,会规范化为同一 workspace 键。

安装与启用

插件以当前 DSH 进程权限运行,安装前建议阅读 GitHub 仓库 源码与 MIT 许可证。社区目录页:skillhub 插件页(独立站点,与 DeepSeek / 幻方无官方从属关系)。

方式一:本地构建(link)——在仓库目录执行 pnpm install && pnpm build,在 profile 的 package.json 中加入 link: 依赖后,于 profile 目录 pnpm install 并重启 DSH。README 中的完整步骤含 git clone 获取源码,见官方文档。

方式二:npm(发布后):

dsh plugin --profile web add dsh-file-undo

纯 client 侧改动在 link 模式下通常只需浏览器硬刷新;host 侧变更需重启 DSH。

典型用法

  1. 安装并重启 DSH(或按 link 方式配置 profile)。
  2. 在 Web 界面让 agent 通过 write / edit 修改文件;每次落盘前会自动进入时间线。
  3. 打开侧栏底部「撤销」图标,在历史列表中选一条,查看预检结果与红绿 diff,两阶段确认后撤销;或于聊天输入 /undo、/undo list、/undo 2 等。
  4. 若预检提示 superseded_by_later_ops,按面板引导使用「回退到此状态」,并确认将丢弃的后续步数。
  5. 定期或按需执行 /undo prune 7 清理旧快照;需要时可用 /undo git-status 与 /undo git [n] 查看或从 git 归档恢复。

适用场景与限制

适合:频繁让 agent 改同一仓库、需要按轮次审查 diff、希望在误改后快速整文件回滚,且主要改动来自 DSH 的 write / edit 的场景。

注意:

  • 只覆盖 write / edit;在 shell 里直接改文件(重定向、Set-Content 等)不会进入时间线。
  • 「回退到此状态」会丢弃其后改动,不做旧基线重放。
  • 面板与会话跟随依赖 Web 界面;headless 下聊天命令仍可用。
  • HTTP API 为 POST /file-undo/api/*,带 Host 头与 Origin 等信任围栏,仅供本地/受信环境使用。

结尾

dsh-file-undo 把 agent 文件改动做成可审查的时间线:全文快照、侧栏 diff、预检加乐观锁提交,以及 /undo 与回退/重做闭环。若要试用或贡献代码,可从目录页与仓库入手:

  • 目录页:https://www.skillhub.cn/plugins/QinLuza/dsh-file-undo
  • GitHub:https://github.com/QinLuza/dsh-file-undo
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye