# pi-tree-undo

Pi 扩展：**基于 session tree 导航的文件 undo/redo**。不需要任何命令——在 `/tree` 里前后切换节点，文件修改就会自动撤销或重做。

```
  打开 /tree
      │
      ▼
  ├── 之前的节点 ◀── 选中并回车 = 撤销（文件回到那时的状态）
  │
  └── 之后的节点 ◀── 选中并回车 = 重做（文件恢复到那时的状态）
```

## 功能

- **导航即撤销/重做**：`/tree` 里往上游走 = undo，往下游走 = redo，跨分支自动处理（放弃旧分支、应用新分支）。
- **多轮精确回退**：一次回退多个节点，撤销所有经过 turn 的文件变更。
- **变更提示 widget**：导航后编辑器上方显示每个文件的变更结果，带增删行数：

  ```
  1 file(s) changed
  Modified:
    /path/src/a.ts (+12 -3)          ← +增行数 -删行数
  Added:
    /path/new.ts
  Deleted:
    /path/old.ts
  ```

- **外部修改保护**：文件被手动改过时，先把当前内容备份到 `<path>.pi-undo-conflict-<时间戳>`，再覆盖为目标状态，并用警示色标注备份路径。
- **按 session 隔离**：每个 session 的快照独立存储，互不影响。

## 安装

需要已安装 [pi](https://pi.dev)。

### 临时体验（不安装，直接跑）

```bash
pi -e ./src/index.ts
```

### 安装为包（之后直接 `pi` 使用）

```bash
pnpm install
pnpm build          # 编译到 dist/
pi install ./       # 注册到 pi
```

卸载：`pi uninstall ./`

## 快速上手

1. 启动 pi 并加载扩展，看到 `File undo ready` 提示即就绪。
2. 让模型编辑文件（`write` / `edit`）。
3. 输入 `/tree` 打开会话树，用方向键选择节点，回车确认：
   - 选**之前的节点** → 撤销该次改动
   - 选**之后的节点** → 重做
4. 编辑器上方的 widget 会显示每个文件的变更（改了什么、增删几行）。
5. 想再看某一步的细节，就导航到那个节点；想回到当前，继续往下游选即可。

## 典型使用场景

**1. 撤销误改**

模型改错了文件或改了不该改的地方，`/tree` 选到改动之前的节点回车，文件立刻还原。再选回来就是重做，随时反悔。

**2. 定位"是哪一次改动引入的问题"**

连续几轮编辑后项目坏了，`/tree` 逐级往回退，每退一级看 widget 的变更提示，很快定位到出问题的那一轮，然后停在修复前的节点。

**3. 在分支之间切换对比**

在某个节点分叉出两条思路，分别改文件。用 `/tree` 在两个分支之间来回切换，扩展会自动撤销当前分支的改动、应用目标分支的改动，文件状态跟着切换。

**4. 多轮撤销看总账**

一次回退多轮时，widget 显示的是从当前状态到目标状态的**精确净变化**（同一行被反复改只计一次），比如 `(+5 -2)` 表示这个文件净增 5 行、净删 2 行。

## 工作原理（简述）

- 每个完成的 turn，对每个用 `edit`/`write` 修改的文件记录一个**快照**（unified diff，`before` 存全量旧内容）。
- 快照存放在 `~/.pi/agent/sessions/<项目>/<sessionId>.undo-snapshots.json`，随 session 存续。
- 导航时扩展计算旧节点 → 新节点的共同祖先，撤销被抛弃段、应用目标段。
- 应用前会校验磁盘内容是否与快照一致，不一致就备份后覆盖，避免静默丢数据。

## 边界

- **只跟踪 `edit` / `write`**：模型用 `bash`（如 `echo >> file`）改的文件不会被记录，也无法撤销。
- **删除操作不可直接撤销**：pi 没有独立的删除工具，删除通常走 `bash rm`，不在跟踪范围；只有该文件此前由 `write` 创建过（有快照），重做时才可能"复活"。
- 手动编辑过的文件被覆盖前会**自动备份**，需要找回旧内容时查看备份文件即可。

## 开发

```bash
pnpm dev          # 用 pi 加载扩展：pi -e ./src/index.ts
pnpm typecheck    # 类型检查
pnpm test         # 运行测试
pnpm build        # 编译到 dist/
```

更详细的开发说明见 `AGENTS.md`。
