dsh-session-delete:为 DSH 补上可恢复的会话删除

前言

DeepSeek Harness(DSH)侧栏里,会话可以归档,但官方持久化层没有「删除」接口。dsh-client-ui-workspace 文档写得很清楚:没有 Session 删除——会话可以归档但绝不会被删除。归档会话仍占磁盘、仍可能出现在检索与列表逻辑里;想真正从侧栏和搜索里清掉某条会话(连同子代理会话),只能自己补一层能力。

下面介绍社区插件 dsh-session-delete(维护者 xiaoxingyuemiao,分类:客户端)。它在会话行「…」菜单里增加浅红色「删除」,二次确认后把目标会话及其全部子会话移入 $DSH_HOME/.dsh-session-trash/ 回收站,并清理工作区注册表与投影缓存;删除可逆,字节不变,可按 API 或手工目录移回恢复。

这是什么

dsh-session-delete 是 DSH 的客户端插件:Host 半边注册 HTTP 路由负责定位会话目录、移入回收站、清理四处注册表/缓存;Client 半边挂载侧栏菜单项与确认弹窗,删除后会话行立即从 UI 消失。与官方「归档」不同,删除后会话从侧栏与搜索索引对账逻辑中彻底消失,文件落在 DSH 主目录外的回收站,避免被 sessions 根扫描成合法项目目录。

核心功能

入口与交互

  • 入口:侧栏会话行悬停 →「…」菜单 → 最后一个分组里的「删除」(排在官方「归档」之后,带垃圾桶图标)。
  • 样式:浅红色,取主题次级错误色,浅色主题下比官方 danger 更浅。
  • 二次确认:弹窗展示会话标题,并说明子会话(子代理)会一并删除、文件移入回收站;默认聚焦「确认删除」,Esc、点遮罩或「取消」可退出。
  • 删除后:侧栏即时隐藏该行;提示形如「已删除会话「xxx」,连同 N 个子会话,已移入回收站」。

级联删除与四处清理

插件读取全部会话的 parentSessionId 建依赖树,递归收集目标会话的全部后代(任意深度),先叶后根逐个处理,并带 visited 集合抵御环形引用。

每个被删会话都会做四处清理(缺一处容易留下幽灵行或脏数据):

  1. 会话目录 → $DSH_HOME/.dsh-session-trash/<trashId>/session(同卷 rename,跨卷则复制后删原目录);
  2. storages/workspace.json:从 sessionIds、global.pinnedSessionIds、global.archivedSessionIds 摘除;
  3. storages/session_projcache/sessions/<id>.json 删除;
  4. storages/session_projcache.json 中 tables.sessions[<id>] 条目删除。

Client 侧对会话行打隐藏标记,并用 MutationObserver 在 DSH 重渲染后补标记,避免行「复活」。会话搜索依赖的 dsh-session-query-sqlite 会在搜索前对账,无需插件单独改索引。

回收站与恢复

每个被删会话在回收站里是独立记录,trash.json 记录原始路径、所属工作区、删除前的归档状态。恢复时会话回到原工作区,并还原删除前的归档状态。

安全边界(摘要)

场景 行为
会话或子树内有正在运行的会话 拒绝删除,需先停止
算不出子会话(花名册读不到) 中止,不静默只删父会话
部分后代删除失败 其余继续;返回 partial: true 与 failed[]
sessionId 含路径分隔符或 .. 拒绝(白名单 [A-Za-z0-9._~-])
会话目录不在 sessions 根内 拒绝
恢复时原位置已被占用 拒绝,不覆盖
移动失败 回滚回收站目录,原会话保持原样

回收站必须放在 sessions 根之外(.dsh-session-trash/),否则 DSH 仍会把其下目录当成合法会话扫出。

安装与启用

DSH 网页端与桌面端是两个独立 profile,插件需各装一次。安装命令以仓库 README 为准;装完后必须重启 DSH(浏览器半边 bundle 在启动时扫描进启动图,不重启 Client 半边不会加载)。

网页端

dsh plugin --profile web add link:<本目录绝对路径>
# 例如:
dsh plugin --profile web add link:D:\DSH插件\dsh-session-delete

桌面端(Electron)

桌面端 profile 由应用独占管理,须用安装目录自带的 CLI:

& "<DSH 安装目录>\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add link:D:\DSH插件\dsh-session-delete

卸载

dsh plugin --profile web remove dsh-session-delete

卸载只移除插件;回收站里的会话文件仍在,需手动恢复或删除目录。

插件包版本 1.0.0,许可 MIT,运行环境要求 Node >= 20(见 package.json)。

典型用法

侧栏删除

在 DSH 侧栏对目标会话打开「…」→「删除」→ 确认即可。若有子代理会话,会一并移入回收站。

查看回收站与恢复

Host 路由在本地 DSH 进程上监听,将 <port> 换为当前实例端口:

# 查看回收站
Invoke-RestMethod http://127.0.0.1:<port>/dsh-session-delete/api/list

# 恢复(一次一个)
Invoke-RestMethod -Method Post -Uri http://127.0.0.1:<port>/dsh-session-delete/api/restore `
  -ContentType 'application/json' -Body '{"trashId":"<列表里的 trashId>"}'

也可手工恢复:把 .dsh-session-trash/<trashId>/session 移回清单中的 originalDir。

删除后行仍在时的诊断

Invoke-RestMethod 'http://127.0.0.1:<port>/dsh-session-delete/api/probe?sessionId=<会话id>'

关注 onDisk(目录是否还在 sessions 根下)、inHostList(宿主列表是否仍包含)、inTrash(是否在回收站)。典型「删成功但行还在」为 onDisk=false / inTrash=true / inHostList=true,问题在列表快照收敛而非删除本身。

适用场景与注意

适合谁:长期在 DSH 里开大量会话与子代理、归档已无法满足「从列表和磁盘布局上清掉」需求的开发者;需要可恢复删除而非永久抹除的场景。

使用前请注意:

  • 插件以当前 dsh 进程权限读写 $DSH_HOME 与会话目录;安装前应阅读 GitHub 源码 与 MIT 许可证,确认行为符合预期。
  • 正在运行的会话删不掉(含子树内有运行中会话时整棵拒绝);需先停止再删。
  • 回收站无自动清理;级联删除产生多条独立记录,恢复需逐个 API 或手工操作。
  • 删除不会清理会话引用的图片/附件(内容寻址,可能与其他会话共用)。
  • 即时隐藏依赖 data-row-key="session:<id>" 等 DOM 约定;DSH 若变更需同步改插件。

本地验证可在插件目录执行 node scripts/check.mjs(临时 DSH_HOME 上跑删除/恢复全流程,README 称共 40 项断言)。

结尾

DSH 生态强调「一切皆插件」;SkillHub 目录页 与 DeepSeek / 幻方无官方从属关系,社区插件需自行评估后再装。dsh-session-delete 在官方仅支持归档的前提下,用回收站 + 注册表/缓存清理补上「真删除」路径,并保留恢复与 probe 诊断,适合需要可控清理会话树的 DSH 用户。

  • 目录页:https://www.skillhub.cn/plugins/xiaoxingyuemiao/dsh-session-delete
  • GitHub:https://github.com/xiaoxingyuemiao/dsh-session-delete
羽毛球分组比赛记分
小程序二维码

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

小夜