Skip to content
dsh.fish
Bundle

dsh-plugin-session-rollback

会话回退:在每条用户消息的复制按钮旁提供「回退」按钮,在当前会话内同步回退对话 Surface 和工作区代码(代码自动快照/备份,支持 /rollback-undo 撤销)。

Source
antlordGit
License
MIT
Updated
Updated 2 days ago

Readme

# dsh-plugin-session-rollback · 会话回退

为 DeepSeek Harness(DSH)提供会话与工作区代码同步回退能力。

插件会在每条用户消息旁添加「撤销」按钮。选择某个问题后,页面会移除该问题及之后的所有问题和回答,同时将工作区代码恢复到该问题提交前的状态。

例如,当前有 4 个问题:

```text
问题 1 → 回答 1
问题 2 → 回答 2
问题 3 → 回答 3
问题 4 → 回答 4
```

回退到问题 2 后:

```text
问题 1 → 回答 1
```

代码也会恢复到提交问题 2 之前的检查点。

## 效果展示

### 撤销入口

「撤销」位于用户消息的复制按钮旁,悬浮时立即显示操作提示。

![会话回退撤销按钮](docs/images/session-rollback-action.png)

### 回退确认

确认框会明确说明撤销范围;确认后,对话和工作区代码会一起回退。

![会话与代码回退确认框](docs/images/session-rollback-confirm.png)

## 功能

- 自动为每条真人提问创建工作区代码检查点
- 在用户消息的复制按钮旁提供「撤销」操作
- 同步回退当前页面的聊天记录和工作区代码
- 移除目标问题及之后的全部问题和回答
- 回退前自动备份当前工作区
- 支持使用 `/rollback-undo` 撤销最近一次代码回退
- 快照采用 SHA-256 内容寻址存储,相同文件不会重复保存
- 自动适配 DSH 的明暗主题

## 安装方式

本插件包含 DSH Client bundle 和自挂载补丁。通过下面任一种方式安装后,不需要手动修改 profile 配置。

### 方式一:从 GitHub 在线安装

```bash
dsh plugin --profile web add github:antlordGit/dsh-plugin-session-rollback
```

安装完成后重启 DSH Web:

```bash
dsh web
```

### 方式二:下载源码后安装

打开 [GitHub 仓库](https://github.com/antlordGit/dsh-plugin-session-rollback),点击 `Code` → `Download ZIP`,解压后进入源码目录:

```bash
cd /你的路径/dsh-plugin-session-rollback
npm install
npm run build
dsh plugin --profile web add "$(pwd)"
dsh web
```

## 使用方法

1. 正常与助手对话并修改代码。
2. 找到希望返回的用户问题。
3. 点击该问题下方、复制按钮旁的「撤销」。
4. 确认本次回退。
5. 页面会移除所选问题及后续所有对话;代码恢复到该问题提交前。

回退前的代码会自动备份。如果需要撤销最近一次代码回退,在输入框执行:

```text
/rollback-undo
```

## 回退规则

假设选择第 N 个问题:

| 内容 | 处理方式 |
| --- | --- |
| 第 1 到第 N−1 个问题及回答 | 保留 |
| 第 N 个问题及回答 | 移除 |
| 第 N 个问题之后的问题与回答 | 移除 |
| 工作区代码 | 恢复到第 N 个问题提交前 |
| 原始会话事件 | 保留在 DSH 的追加式日志中,但不再出现在当前对话和后续模型上下文中 |

回退不会创建新会话,当前会话 ID、URL 和侧栏条目保持不变。

## 安全机制

### 精确检查点

每条真人提问提交时,插件会为对应的事件序号保存代码检查点。回退只使用与目标消息精确匹配的检查点,不会使用其他轮次的快照替代。

如果目标消息没有代码检查点,插件会停止操作并提示:

```text
该条消息没有代码检查点,无法安全回退
```

此时聊天记录和代码都不会被修改。

### 自动备份

每次恢复代码前,插件会先保存当前工作区的 safety 快照。因此,即使回退后反悔,也可以通过 `/rollback-undo` 恢复最近一次回退前的代码。

### 串行恢复

检查点写入按会话排队,代码恢复在 Host 内全局串行执行。回退接口会先等待当前会话尚未完成的检查点写入,避免连续操作时误判检查点不存在。

## 存储位置

插件数据保存在:

```text
~/.dsh/plugin-data/session-rollback/
├── blobs/       # SHA-256 内容块
├── sessions/    # 按会话和消息序号保存的检查点清单
└── safety/      # 回退前的自动备份
```

不再需要历史快照时,可以删除该目录。删除后,已有消息将无法再执行安全的代码回退。

## 文件恢复范围

恢复采用确定态还原:

- 检查点中存在的文件会恢复为当时的内容
- 当前存在、但检查点中不存在的新文件会被删除
- 删除文件后产生的空目录会被清理
- 单个文件超过 16 MB 时不会纳入快照,也不会在恢复时被修改
- 符号链接和特殊文件不会纳入快照

以下目录默认排除,不会被读取、删除或恢复:

```text
node_modules  .git  .hg  .svn  .jj
dist  build  out  .next  .nuxt  .output
.cache  coverage  target  vendor
.venv  venv  __pycache__
.idea  .vs  Pods  DerivedData
```

完整列表以 [`src/index.js`](./src/index.js) 中的 `EXCLUDED_DIRS` 为准。

## 工作原理

```text
用户提交问题
    │
    ├─ session/event: user/message
    │      └─ 保存工作区检查点
    │
点击“回退”并确认
    │
    ├─ 等待对应检查点完成写入
    ├─ 保存当前工作区 safety 快照
    ├─ DSH Surface replacement 隐藏目标问题及后续对话
    └─ 从精确检查点恢复工作区代码

/rollback-undo
    └─ 恢复最近一次 safety 快照
```

Client 通过 `/api/plugins/session-rollback/rollback` 请求 Host 执行回退。Host 使用 DSH 原生 Surface replacement 更新当前会话的活动路径,原始事件仍保留在审计日志中。

## 已知限制

- 插件安装或启用之前产生的消息通常没有代码检查点,无法安全回退代码。
- 仅 `source.kind === 'user'` 的真人消息会创建检查点;插件、模型或工具生成的消息不会创建。
- 正在运行的会话不能回退,请先停止或等待当前回答结束。
- 被排除的目录、超限文件、符号链接和特殊文件不会随代码一起回退。
- `/rollback-undo` 恢复的是最近一次自动备份,作用于代码,不会重新显示已从当前 Surface 隐藏的聊天记录。

## 开发

项目结构:

```text
session-rollback/
├── src/index.js             # Host:检查点、恢复、HTTP 路由和撤销命令
├── src/client.js            # Client:回退按钮和确认弹框
├── scripts/build-client.mjs # 构建脚本
├── cordis.patch.yml         # DSH 自挂载补丁
├── lib/                     # 发布用构建产物
└── package.json
```

构建:

```bash
npm run build
```

语法检查:

```bash
node --check src/index.js
node --check src/client.js
```

本插件没有 npm 运行时依赖。客户端使用 DSH 提供的 React 模块,样式使用 `--dsw-alias-*` 主题令牌。

## License

MIT

Install

dsh plugin --profile web add github:antlordGit/dsh-plugin-session-rollback

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source