# 会话清道夫（dsh-session-sweeper / Session Sweeper）

[English](./README.md)

在 DSH Web 界面（设置 → *会话清道夫*）中扫描、查看并安全清理本机
AI 终端会话历史——支持 **Claude Code、Codex CLI、WorkBuddy 以及 DSH 自身**。

## 截图

| 会话列表 | 消息预览 |
|---|---|
| <img src="assets/1-sessions.png" width="400"> | <img src="assets/4-preview.png" width="400"> |
| **回收站** | **设置** |
| <img src="assets/2-recycle.png" width="400"> | <img src="assets/3-settings.png" width="400"> |

## 功能

- **扫描**：遍历用户目录下所有受支持来源，列出会话的标题、项目、消息数、
  大小与最后活跃时间。
- **查看**：分页预览会话内容（用户/助手消息、工具调用）——包括以 zstd
  拼接帧存储的 DSH 日志。
- **清理**：默认动作是*隔离*——整个工件（单文件，DSH 为整个会话目录）移入
  回收目录，manifest 记录原路径与每个文件的 SHA-256，一键整批恢复、逐字节
  校验。
- **永久删除**：需要输入确认短语 `DELETE`，仅保留审计墓碑记录。

## 数据安全模型

| 防线 | 行为 |
|---|---|
| 隔离优先 | 默认清理移入 `~/.hist-sweeper/recycle/<batchId>/`，随时可恢复 |
| 活跃保护 | `guardHours`（默认 24 小时）内有修改的会话默认跳过，需显式勾选才纳入 |
| 当前会话 | 正在运行的 DSH 进程所服务的会话永不可清理 |
| 锁检测 | 无法独占打开的文件跳过，不中断整批 |
| 审计日志 | 所有操作追加写入 `~/.hist-sweeper/recycle/log.jsonl`，回收站页签可查 |
| 边界 | 只动会话工件——绝不碰配置、凭据、memory、todos |

## 安装

tarball（`lib/` 已预构建并提交，无需任何构建脚本）：

```sh
dsh plugin --profile web add ./dsh-session-sweeper-1.0.0.tgz
```

git 安装（`lib/` 已提交，因此无需 pnpm 构建授权）：

```sh
dsh plugin --profile web add github:HrxSpace/dsh-session-sweeper
```

安装后重启 `dsh web`，打开 **设置 → Session Sweeper 会话清扫**。

## 配置

在 profile 的 `cordis.patch.yml` 里覆盖插件行的 `config:` 即可：

| 选项 | 默认值 | 含义 |
|---|---|---|
| `guardHours` | `24` | 活跃保护窗口（小时） |
| `recycleDir` | `~/.hist-sweeper/recycle` | 隔离回收目录 |

测试钩子（日常勿用）：`DSH_SWEEPER_HOME` / `DSH_SWEEPER_RECYCLE` 重定向
扫描根与回收根——测试套件用它们跑合成目录树。

## 卸载

```sh
dsh plugin --profile web remove dsh-session-sweeper
```

回收目录与审计日志在卸载后保留（那是你的恢复通道）；确认不再需要后手动删除
`~/.hist-sweeper` 即可。

## 权限与网络

- 读取：`~/.claude/projects/**`、`~/.codex/sessions/**`（含
  `archived_sessions`）、`~/.workbuddy/projects/**`、`~/.dsh/sessions/**`
- 写入：仅回收目录
- 在 DSH web 服务器上提供仅限同源的 JSON API（`/sweeper/api/*`），跨源请求一律拒绝
- 无网络访问、无生命周期脚本、除 node 内建外零运行时依赖（react 由 DSH
  client 运行时提供）

## 开发

```sh
# 构建（tsdown ≥0.22 均可；lib/ 产物提交入库）
npx tsdown

# 测试（node:test + tsx，无需安装任何依赖）
node --import tsx/esm --test tests/sweeper.test.ts

# 用本地构建起一个开发实例
pnpm dsh --profile web --patch ./cordis.dev.yml --port 3180 --no-open
```

## 许可

MIT
