pi-workspace-history0.5.0
Undo, roll back, and revert code changes made by the Pi coding agent: files and conversation together. One-step /undo and /redo, /tree workspace restore, /diff, and manual checkpoints, with history kept outside your repository.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-workspace-history
Pi 编码代理 的撤销功能。Agent 改坏了东西,输入 /undo,文件和对话一起回到这条提示词之前,一步到位。

快速上手
pi install npm:pi-workspace-history # 所有项目可用
pi install -l npm:pi-workspace-history # 只装到当前项目(.pi/settings.json)
pi -e npm:pi-workspace-history # 不安装,只在本次运行中试用
在项目目录里启动 pi,底栏出现 ⟲ history 就表示已生效。照常使用 Pi,Agent 改坏了就输入 /undo。
要求:Pi 0.84.4 或更高(已在 0.84.4、1.0.4 和 1.1.0 上测试)、Node.js 22.19.0 或更高,并且 PATH 中有 git。项目本身不必是 Git 仓库。
命令
| 命令 | 作用 |
|---|---|
/undo |
回到上一次 Agent 操作之前:文件和对话一起(或只回退对话),并把原提示词放回输入框 |
/redo |
把 /undo 刚撤掉的内容恢复回来 |
/tree / 双击 Esc |
跳到对话中的任意位置,并选择文件是否一起恢复 |
/diff [n] |
查看最近一次 Agent 操作改了什么(/diff 2 看再前一次) |
/checkpoint [label] |
保存当前文件,比如手动修改之前 |
/history-status |
查看历史功能是否生效、存储位置、被跳过的文件和最近的错误 |
/undo 只问一个问题(文件和对话一起,还是只回退对话),其余自动完成,/redo 沿用同一个选择。/diff 是单独的只读命令,查看改动不会给撤销多加一步。
撤销能覆盖什么
- 整次操作。 从你发出提示词到 Agent 结束,算作一个单位:所有工具轮次、自动重试、上下文压缩,以及运行中你追加的消息。一次
/undo全部撤掉。 - 所有文件改动。 Agent 修改、新建、删除、重命名的文件,包括通过 Shell 命令做的改动。
- 你自己的修改不会丢。 两次提示词之间的手动修改,会在下一条提示词发出前保存。如果工作区里有还没保存进历史的修改,恢复文件的操作会被拒绝,而不是覆盖它们。可以先用
/checkpoint保存,或者选择"只回退对话"。 - 不碰你的仓库。 历史保存在项目外的一个私有 Git 仓库里。你的提交、分支、暂存区、stash、refs 以及 Jujutsu 的操作记录都不会被改动;撤销只恢复文件内容,所以
git status会把恢复的文件显示为修改。
不会处理的内容:
- 被你的
.gitignore忽略的路径,以及下面这些路径,它们永远不会被保存或覆盖:.git/、.jj/、node_modules/、dist/、build/、.cache/、.next/、.turbo/、coverage/、.env、.env.*、.pi/workspace-history/。即使.gitignore写了!.env.local这样的反向规则,也不会把它们加回来。 - 超过 10 MB 的新文件。会提示一次,撤销和重做都不会动它们。已经在历史中的文件不受大小限制。
- 嵌套的 Git 仓库(包括 worktree)。每个只提示一次;要管理它的历史,请在那个仓库里打开 Pi。
- 文件权限。在 Linux 和 macOS 上,有可执行权限的文件恢复后仍然可执行;但只改权限的操作(例如
chmod +x)不会被撤销,恢复时重新创建的文件也没有可执行权限。 - 工作区以外的一切:部署、API 调用、数据库。
常见问题
能只撤回对话、保留文件吗?
可以。/undo 和 /tree 都提供"只回退对话(保留当前文件)"。当前文件会先被保存,之后仍然可以回到这个状态。
撤销错了还能恢复吗?
可以,用 /redo。
和 Pi 自带的 /tree 有什么区别?
Pi 自带的 /tree 只移动对话。装了本插件后,/tree 还能把文件恢复到所选位置对应的状态。如果那个位置的文件和现在一样,就不再询问。
/fork 呢?
/fork 会把对话复制到一个新会话,文件保持不变。新会话的历史从空开始:原会话里的操作在新会话中不能撤销,之后的新操作可以撤销。如果要把文件恢复到之前的某个位置,请在原会话里用 /tree 或 /undo。
大仓库或 WSL 上会慢吗?
发送提示词不会等待快照,详见性能。在 WSL 上,建议把项目放在 Linux 文件系统里,不要放在 /mnt/c 下。
在我的目录里没有生效。
运行 /history-status,它会说明原因。默认情况下,当前目录或上级目录里需要有项目标记,例如 .git、.jj、package.json、Cargo.toml、go.mod、pyproject.toml;在用户 home 目录,以及只是放了好几个仓库的文件夹里,插件不会启用。设置 "workspaceHistory": { "enabled": true } 可以强制启用。
底栏显示 snapshot failed。
有一次快照没能保存,之后的操作可能无法撤销。/history-status 会显示具体错误。等下一次操作被成功记录,这个提示就会消失。
配置
设置项放在 ~/.pi/agent/settings.json(全局)或 .pi/settings.json(项目)的 workspaceHistory 下。在 Pi 1.x 上,只有信任了项目文件夹,项目设置才会生效,和 Pi 自己读取项目设置的规则一致。
{
"workspaceHistory": {
"storageDir": "D:\\pi-history",
"maxSessionsPerWorkspace": 3,
"maxWorkspaces": 10
}
}
| 设置项 | 默认值 | 说明 |
|---|---|---|
enabled |
"auto" |
"auto" 在项目里启用(见上面的常见问题);true 总是启用;false 关闭 |
requireProjectMarker |
true |
设为 false 时,"auto" 接受文件系统根目录和用户 home 目录以外的任意目录,并跳过多仓库文件夹的判断 |
allowHomeDirectory |
false |
允许在用户 home 目录启用 |
storageDir |
~/.pi/agent/state/workspace-history |
历史的存储位置。必须在工作区之外,否则插件会自动停用 |
maxSessionsPerWorkspace |
3 |
每个工作区保留的会话数;超出时删除最久未用的非活跃会话 |
maxWorkspaces |
10 |
总共保留的工作区数;超出时删除最久未用的非活跃工作区 |
maxUntrackedFileSizeMB |
10 |
超过这个大小的新文件会被跳过;0 表示不限制 |
showStatus |
true |
在底栏显示 ⟲ history |
gitTimeoutMs |
60000 |
每条内部 Git 命令的超时时间;工作区特别大时可以调高 |
maxScanFiles、maxScanDirs、maxScanMs |
20000、3000、5000 |
恢复时查找排除路径的扫描上限;超过上限时改用 Git 列出这些路径 |
下面这些 Pi 设置是可选的,能让历史导航更快捷:
{
"doubleEscapeAction": "tree",
"treeFilterMode": "user-only"
}
doubleEscapeAction: "tree"(Pi 的默认值)让双击 Esc 打开 /tree。treeFilterMode: "user-only" 让 /tree 只列出你的提示词,选撤销点更快。
性能
测试条件:2000 个文件的工作区,每条提示词写一个文件:
| 环境 | 发送前的等待 | 每条提示词增加的耗时 |
|---|---|---|
| Windows 11 原生 | 2–5 ms | 约 0.5–1 秒 |
WSL2,项目位于 /mnt/g |
约 12 ms | 约 3 秒 |
会话的第一条提示词需要等待初始快照,不过这个快照通常在你打字时就已在后台完成。在 Windows 11 上,2 万个文件的仓库建立初始快照约需 5 秒。复现方法:npm run bench:first-turn -- 2000 256。
在 Windows 11 上,/undo 和 /redo 在 2000 个文件的仓库里约需 0.7 秒,5000 个文件约 1 秒,2 万个文件约 1.5 秒。在 Linux 上(WSL2,项目位于 Linux 文件系统),2000 个文件约 0.1 秒,2 万个文件约 0.6 秒。
工作原理
每条提示词发出前,插件把工作区快照到这个会话专用的私有 Git 仓库;Agent 结束后再快照一次。每个快照都和对话树里的位置关联,所以 /undo 和 /tree 能恢复任意位置对应的文件。恢复时只写插件管理的文件,从不清理工作区里的其他内容。
- 发送不等待。 从第二条提示词起,快照在模型思考时进行,Agent 的第一次工具调用会等它完成。如果快照失败,这次操作不会进入历史,错误会在这一轮结束时报告,底栏也会显示。
- 会话互相隔离。 每个会话有自己的历史和重做状态,新会话不会撤销到旧会话的历史里。
- 只回退对话时,会先保存当前文件,新的分支从这份文件继续。
- Windows 上被占用的文件会短暂重试。如果一直被占用,恢复会取消而不会跳过这个文件,待恢复的状态在重载后仍然保留;恢复失败后你做的修改不会被自动覆盖。
- Git 超时。 超过
gitTimeoutMs的 Git 命令会被跟踪到它结束为止,期间这个工作区不会启动别的 Git 命令,避免两个写入者同时使用索引。来源不明的遗留index.lock会连同路径一起报告,绝不会被删除。 - 损坏的历史会在使用前被发现。损坏的仓库会保留为
repo.git.invalid-<timestamp>-<uuid>,然后新建一个;只存在于损坏仓库里的快照可能无法使用。 - 快照提交从不签名,保存历史不会要求解锁签名密钥。你的 Git 配置保持不变。
存储结构:
~/.pi/agent/state/workspace-history/
workspaces/
<workspaceHash>/
meta.json
sessions/
<sessionId>/
active-session.json
repo.git/
redo.json
meta.json
logs/
timemachine.log
运行中的会话持有租约,清理永远不会删除它们的历史。元数据读不出来的条目也会保留。
给 AI Agent 的安装说明
替用户安装时:
- 检查前置条件:
node --version(22.19.0 或更高)、pi --version(0.84.4 或更高)、git --version。 - 运行
pi install npm:pi-workspace-history(只装到当前项目则用pi install -l npm:pi-workspace-history)。 - 重启 Pi 或运行
/reload。验证:底栏显示⟲ history,且/history-status显示Workspace history: active。如果显示 inactive,会同时给出原因;在没有项目标记的目录里,可在.pi/settings.json中设置"workspaceHistory": { "enabled": true }。
纯文本摘要见 llms.txt。
开发
npm ci
npm test
npm run typecheck
本仓库通过 .pi/settings.json 从 .pi/extensions/workspace-history.ts 加载扩展:在这里启动 pi,改动后运行 /reload 即可。要在别处安装本地代码,运行 pi install /path/to/pi-workspace-history。
开发使用 Pi 1.0.4 和 Node.js 22.19.0。CI 在 Linux 与 Windows 上,分别针对 Pi 1.0.4 和最低支持版本 0.84.4 运行。
版本变更见 CHANGELOG.md。