@liziy/session-queue
pi 扩展:线性队列会话管理 + 文件变更记忆回滚
Package details
Install @liziy/session-queue from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@liziy/session-queue- Package
@liziy/session-queue- Version
0.3.0- Published
- Jul 13, 2026
- Downloads
- 573/mo · 160/wk
- Author
- liziy
- License
- MIT
- Types
- extension
- Size
- 58.7 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@liziy/session-queue
把 pi 的会话从「树」改为「队列」:每个 turn 自动记录修改的文件,回滚时一键还原。
安装
pi install npm:@liziy/session-queue
快速上手
# 1. 进入项目目录,首次启用记录
/rollback
# → 主菜单 → 选 "✅ 启用当前工作区"(第二行)
# 2. 正常使用 pi;每个 turn 结束时自动写入一个检查点
# 状态栏出现 "● 记录"(青)或 "● 同步"(绿)
# 3. 想撤回某一步?唤起回滚选择器
/rollback
# → 主菜单 → 选 "📋 回滚历史"
# → 选要回滚到的检查点 → 确认 → 文件还原
# 4. 想关闭记录(暂时不监听文件变更,但保留在列表里)
/rollback
# → 主菜单 → "📂 管理工作区" → 选当前工作区 → "⏸ 停用工作区"
# 5. 想彻底从列表移除(可选清数据)
/rollback
# → 主菜单 → "📂 管理工作区" → 选工作区 → "🗑️ 删除工作区"
主菜单(/rollback)
📋 回滚历史 (N 个变更点) ← 唤起检查点选择器
✅ 启用当前工作区 ← 仅未启用时显示
📂 管理工作区 ← 工作区增/启/停/删
⚙️ 全局配置 ← 保留数 / 删除策略 / Session Tree 跟随
🗑️ 清空当前队列 ← 清空当前 session 的 entries
⏸ 停用工作区 ← 仅启用时显示(主菜单里没有,已合并到子菜单)
🧹 回收孤儿快照 ← 手动 GC
❌ 退出菜单
注:v2 起主菜单不再有独立的"⏸ 删除并清空"入口,所有改变工作区状态的操作都收敛到"📂 管理工作区"。
📂 管理工作区
点 📂 管理工作区 后进入二级菜单:
已启用的工作区 (N)
E:/work/project-a (3 queue) ← 当前
E:/work/project-b (11 queue)
← 返回
选一个工作区后进入三级操作菜单:
工作区: E:/work/project-a
⏸ 停用工作区 ← 已启用时显示:仅清 activeWorkspace,保留在列表
✅ 启用此工作区 ← 未启用时显示
🗑️ 删除工作区 ← 从 config 移除,根据全局配置决定是否清数据
← 返回
"停用" vs "删除" 的区别
| 操作 | 工作区目录 | 数据文件 | 可重新启用 |
|---|---|---|---|
| ⏸ 停用 | 保留在 config | 保留 | ✅ 直接点"✅ 启用此工作区" |
| 🗑️ 删除 | 从 config 移除 | 视配置清/留 | ❌ 需重新 /rollback enable |
⚙️ 全局配置
全局配置
📊 每工作区保留队列数: 10 ← 可选 5 / 10 / 20 / 50
🗑️ 删除工作区时清除数据: 是 ← 是/否
🔗 跟随 Session Tree: 开 ← 开/关
← 返回
| 项 | 默认 | 说明 |
|---|---|---|
| 每工作区保留队列数 | 10 | GC 时每个工作区目录最多保留 N 个最近 queue 文件;超出按 mtime 淘汰 |
| 删除工作区时清除数据 | 是 | 🗑️ 删除工作区 时是否同时 rm -rf 该工作区目录;选"否"则数据留在 workspaces/{id}/ 里 |
| 跟随 Session Tree | 开 | 在 pi 的 Session Tree 选旧 user 消息时,队列自动回滚到对应检查点 |
状态栏
| 指示 | 含义 |
|---|---|
| (无) | 未启用工作区 |
● 记录(青色) |
已启用,但未开启 Session Tree 跟随 |
● 同步(绿色) |
已启用 + 跟随 Session Tree |
回滚语义(重要)
v2 采用 Option C 语义:每个 entry 是一个检查点,代表"该 entry 修改之前的文件状态"。
- 回滚到检查点 T = 撤销 T 及之后所有 entry 的修改
- 文件 = 取被丢弃 turns 中最早那条修改的
beforeHash还原(不是中间快照) - 队列 =
entries.slice(0, targetIdx)—— 丢弃目标及之后 - 冲突处理:被跳过的文件保留为
residualentry,下次回滚可重试 - 安全保证:快照丢失 = 跳过 + 告警,绝不盲目删除文件
示例:依次修改了 A → B → C → A
| 检查点 | 文件状态 | 还原目标 |
|---|---|---|
| T0 | A | (起点) |
| T1 | B | B |
| T2 | C | C |
| T3 | A | A(重新变回 A) |
→ "回滚到 T0" = 还原成 A(取最早 beforeHash) → "回滚到 T2" = 还原成 C
存储结构(v2)
~/.pi/agent/extensions/session-queue/
├── config.json # 全局配置 + 工作区列表
├── workspaces/ # 按工作区分目录
│ ├── {wsId1}/ # wsId = base64(绝对路径)
│ │ ├── queue-{sessionId1}.json
│ │ └── queue-{sessionId2}.json
│ └── {wsId2}/
│ ├── queue-{sessionId3}.json
│ └── ...
└── snapshots/ # 全局共享内容寻址快照
└── {hash}.content
多个工作区可能修改相同文件 → sha256 相同 → 只存一份 snapshot。 删除工作区后,孤儿 snapshot 由 GC 在下次启动时清理。
Session Tree 同步
开启"🔗 跟随 Session Tree"后,在 pi 的 Session Tree 里点击旧的 user 消息并输入新问题:
- 插件检测到导航动作
- 自动定位队列中对应的检查点
- 静默回滚(不弹确认)+ 还原文件
- 状态栏提示"↩️ Session Tree 导航 → 自动回滚到..."
Session Tree 同步的冲突处理是强制覆盖(与手动回滚的"询问用户"不同)。
手动 GC(回收孤儿)
主菜单 → 🧹 回收孤儿快照:
🧹 扫描 29 个快照,删除 0 个孤儿,存活 29 个
- Phase 1 标记:扫
workspaces/*/queue-*.json,收集所有引用的 hash - Phase 2 扫描:删
snapshots/中未被引用的.content文件 - Phase 3 限额:按 ws 分桶,每桶按 mtime 保留最近 N 个 queue(N 来自全局配置)
GC 默认 5 分钟节流;每次
turn_end都会跑一次(节流内复用结果)。回滚、删除工作区等场景会强制跑一次。
限制
- 追踪范围:
edit/write工具 +bash的rm/del/mv/>/>>(含简单 glob) - 追踪不到:
sed -i、npm install、子 shell 内的文件操作 - 目录:目录的创建/删除无法还原(仅文件层面)
- 会话树:插件不修改 pi 的会话树本身,只在自己维护的队列里截断;用
/tree查看完整历史 - 跨设备:snapshot 文件路径基于绝对路径,工作区改路径后会"失联"
卸载
# 1. 卸载插件
pi uninstall npm:@liziy/session-queue
# 2. (可选)清除全部数据
# Windows
rmdir /s /q "%USERPROFILE%\.pi\agent\extensions\session-queue"
# Linux / macOS
rm -rf ~/.pi/agent/extensions/session-queue
故障排除
Q: 状态栏不显示?
A: 当前目录不在已启用工作区下。/rollback → ✅ 启用当前工作区。
Q: 回滚时显示"冲突"? A: 你(或别的工具)在记录后手动改过该文件。选项有:
✅ 强制覆盖并回滚— 覆盖你手动改的内容⏭ 跳过冲突,回滚其他— 只回滚没冲突的❌ 取消— 不回滚
Q: GC 一直显示"删除 0 个孤儿"? A: 正常——说明所有 snapshot 都被 queue 引用着。要让孤儿出现,需先让某些 queue 被淘汰(每工作区 N 个限额)或被删除。
Q: 想要更多 queue 配额?
A: /rollback → ⚙️ 全局配置 → 📊 每工作区保留队列数,可选 5/10/20/50。
Q: 怎么彻底关闭插件(不卸载)?
A: /rollback → 📂 管理工作区 → 选工作区 → ⏸ 停用工作区。再次启用只需点 ✅ 启用此工作区。
更新日志
0.3.0
- 存储结构改为按工作区分目录(
workspaces/{wsId}/queue-{sid}.json) - 新增全局配置:每工作区保留队列数(默认 10)、删除工作区时是否清除数据(默认是)
- 工作区管理拆为"停用"和"删除"两个动作:停用保留在列表可重启用,删除从列表移除
- "⏸ 删除并清空"从主菜单下沉到"📂 管理工作区"子菜单
- GC 按工作区分桶限额,跨工作区互不挤占
- 移除旧的 v1 兼容代码(如有旧数据需手动清理)
0.2.x
- 初始公开版本