dsh-session-recycler: Permanently deleting and reclaiming sessions in the DSH Web UI

前言

在 DeepSeek Harness(DSH)里用 Web UI 管会话时,官方列表通常只能「归档」:条目从界面消失,磁盘上的会话目录和日志仍在。试过后端、项目目录里会堆很多「点了新会话但没聊几句」的空白记录,或想彻底清掉某次对话时,归档并不能满足需求。

下面介绍社区插件 dsh-session-recycler(维护者 iamwuzhanglin),它在 Web UI 侧提供「删除会话」入口,并把删除的数据放进带恢复/彻底删除能力的回收站。插件归类为 DSH 生态里的「记忆」相关能力;可在 SkillHub 目录页 查看条目,源码与说明见 GitHub 仓库。

这是什么

dsh-session-recycler 当前 npm 包版本为 0.2.2(MIT 许可),描述为:在 DeepSeek Harness 中实现「真正的会话删除」——从 Web UI 删除指定会话记录,并通过回收站支持恢复或永久清除。

插件由 Host 半(lib/index.js,6 个 JSON 路由)和 Browser 半(lib/client.js,侧边栏底部「删除会话」弹窗)组成。DSH 生态一贯是「一切皆插件」;SkillHub 等社区目录是独立站点,与 DeepSeek / 幻方无官方从属关系,安装前建议自行阅读源码与许可证。

核心功能

Host 侧 API

宿主注册以下路由(路径前缀均为 /x-dsh-session-recycler/):

方法 路径 作用
GET list 会话清单(标题、时间、大小、cwd、空白/运行中/被占用标记)
POST delete 删除选中会话
GET trash 回收站清单
POST trash/restore 从回收站恢复
POST trash/purge 彻底删除(不可逆)
GET ping 自检

Web UI

Browser 半在侧边栏底部提供「删除会话」入口。弹窗内两个 tab:会话 / 回收站。工具栏仅有一个「全选」开关:全部选中时文案变为「取消全选」,不再单独提供重复的「清空」按钮。

删除与会话状态

删除流程在 README 中有逐步说明,要点包括:

  1. 正在运行的会话(agent.status === 'running')会拒绝删除,需先停掉对话。
  2. 仍在内存里(某标签页打开过)的会话:先 archiveSession({ stopActivity: true }),再搬走磁盘数据。
  3. 冷会话会探测 session.lock 的 flock;若被其他进程占用则拒绝。
  4. 会话目录 rename 到回收站 $DSH_HOME/.session-recycler-trash/<ISO时间戳>-<会话ID>/,并写入 sidecar .dsh-session-recycler.json(标题、cwd、删除时间)。
  5. 从 workspaceRegistry 的工作区记账与 pin 集合中 detach/unpin;投影缓存会随条目进入回收站内的 .projcache/。
  6. 广播 api-session/removed,已连接页面即时移除列表行。

live 会话删除后,宿主内存里可能仍保留一条不可见的 ghost 行,直到 systemctl restart dsh-web。插件通过保留归档标记隐藏列表并阻断 agent/pre-step;删除接口返回里 liveGhost: true 表示遇到该情况。磁盘与回收站侧数据仍按上述流程处理。

回收站

回收站目录为 $DSH_HOME/.session-recycler-trash/(可在 cordis.patch.yml 里用 trashDir 配置,默认 .session-recycler-trash,相对 $DSH_HOME)。每次删除对应一个子目录,内含会话日志(如 session.v4.jsonl.zstd)、session.lock 与 .dsh-session-recycler.json。

回收站 tab 支持勾选后「恢复」或「彻底删除」(rm -rf)。恢复时会 unarchiveSession、还原投影缓存、重新 attachSession 并广播 api-session/added;一般不需要重启 dsh。也可在终端 ls 该目录并手工 mv 回去。

弹窗列表中的状态含义(来自 README):

  • 空白:点了「新会话」但未发消息;删掉无实质损失。
  • 被占用:其他进程持有 session.lock;插件只对冷会话检查。
  • 运行中:正在跑一轮对话,唯一会阻止勾选删除的状态。

安装与启用

推荐从 npm 安装到 web profile;bundle 层变更后需重启 dsh-web,并刷新浏览器(client bundle 的 rev 会变):

# 从 npm(推荐)
dsh plugin --profile web add dsh-session-recycler

# 或直接从 GitHub 源码
dsh plugin --profile web add github:iamwuzhanglin/dsh-session-recycler

systemctl restart dsh-web      # bundle 层变更不走 HMR

也可在 dsh-market 插件市场搜索 dsh-session-recycler 一键安装。

可选配置(cordis.patch.yml 片段):

- id: dsh-session-recycler
  name: dsh-session-recycler
  config:
    trashDir: .session-recycler-trash   # 相对 $DSH_HOME

运行环境要求 Node >= 20(见 package.json 的 engines)。

典型用法

  1. 安装并重启 dsh-web 后,刷新 DSH Web 页面。
  2. 在侧边栏底部打开「删除会话」。
  3. 在 会话 tab 勾选要清理的条目(注意运行中、被占用、空白等标记),执行删除。
  4. 误删时在 回收站 tab 勾选并「恢复」;确认不再需要时选「彻底删除」。

安全边界上,插件对会话 ID 做白名单与 realpath 前缀校验,仅在 $DSH_HOME/sessions/<project>/<session-id> 形态下操作,删除采用先 rename 进回收站再清索引的两阶段方式。

适用场景与注意

适合:长期在 DSH Web UI 里开发智能体、需要清理空白会话或彻底移除某次对话记录、又希望误删可恢复的用户。

务必知晓的限制(README「已知限制」):

  • 运行中的会话必须先停再删。
  • live 会话删不掉内存副本,需重启 dsh-web 才能去掉 ghost 行(功能上已由归档封死可见性与运行)。
  • 插件自己的 deleted.json 账本只影响弹窗列表,主 Web UI 会话列表不读它。
  • 不删除 attachments/ 里被引用的附件字节。
  • 插件以当前 dsh 进程权限运行;安装前应检查源码与 MIT 许可证,再决定是否用于生产环境。

仓库提供测试命令,可在本地验证宿主、路由与 client 行为:

node test/host.test.mjs
node test/routes.test.mjs
node test/client.test.mjs

结尾

dsh-session-recycler 补上了 DSH 官方 UI「只归档、不删除」的缺口:删除走回收站与索引清理,恢复可走 UI 或文件系统。进一步了解可访问 SkillHub 插件页 与 GitHub:iamwuzhanglin/dsh-session-recycler。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye