前言¶
DSH 的会话散落在 $DSH_HOME/sessions/<工作区编码>/<会话 id>/ 下,官方只提供了归档能力,没有真正删除。想清理掉某个旧会话,只能手动上去删目录;更麻烦的是,只要这个会话还被宿主加载在内存里,删了文件它也会被写回来,重启后照样出现。
full626/dsh-session-trash-90d 就是来填这个缺口的:一个 DSH 客户端组合包,在 Web GUI 里给出会话列表、回收站、恢复、彻底清除,以及官方缺失的「取消归档」。下文按「它解决什么 → 怎么用 → 哪里要注意」来讲。
这是什么¶
一句话定位:DSH Web GUI 的会话管理插件,提供列表、归档 / 取消归档,以及真正删除(可恢复的回收站先接住,再做不可恢复的彻底清除)。
- 维护者:Full626
- 分类:客户端(DSH 组合包 bundle,不是独立应用)
- 星标:0
- 许可证:MIT
- 适用宿主:DSH
>=0.2.0 <0.3.0,Node>=22
它的入口是「设置 → 会话管理」,不新增独立界面。
为什么不能直接删文件¶
DSH 0.2.x 的 sessionPersistence 只有 create/open/stat/list/flush,sessions 只有 create/prepare/enter/announce/flush/get/list/fork,没有删除会话的 API。所以「真删」只能直接删磁盘上的工件。
而以前的「真删」插件在这里踩坑:它们只跳过 agent.status === 'running'(正在生成回复),但 running 和 live(已加载进内存)是两回事。于是「idle 但 live」的会话被删掉文件后,宿主会把它写回来,重启后等于没删。
这个插件的做法是墓碑 + 启动重放:
删除请求
├─ 非 live → 直接删文件(干净)
└─ live → 记一条墓碑 + 尝试释放 + 删文件,并如实标记 pending
宿主每次启动(+5 秒后补一次)→ 重放墓碑:此时没人打开它们,删了就真没了
确认消失且不再 live 后,墓碑才被清掉
每次删除会同时清理:会话目录、投影缓存、归档集合、workspace 记账。
设计上有一个取舍值得记一笔:host 半侧只依赖文件系统,加上两个可选服务——workspaceRegistry 管归档集合,sessions 做 liveness 探测——不碰任何私有 API。将来 DSH 重构时,这个插件的表现是降级(列表变空)而不是崩掉。
核心功能¶
| 功能 | 说明 |
|---|---|
| 会话列表 | 标题、工作区、最近修改、大小,以及 内存中 / 已归档 标记 |
| 移入回收站 | 不直接抹掉:会话目录带投影缓存一起搬进 sessions-trash,保留 90 天 |
| 恢复 | 放回原来的工作区,缓存一并还原 |
| 彻底清除 / 清理过期 | 手动清单个,或清掉超过 90 天的;列回收站时也会自动清 |
| 空会话折叠 | 只开过没用过、只有头部记录的会话默认隐藏,可展开 |
| 归档 / 取消归档 | 官方只有归档没有取消,这里补上 |
| 墓碑状态 | 界面提示还有几个待下次启动处理 |
导出没有做,官方 /export 已经够用,不重复造。
回收站的目录结构¶
$DSH_HOME/sessions-trash/<删除时间戳>-<会话 id>/
├─ meta.json 原工作区、标题、大小、删除时间
├─ session/ 会话目录(原样搬过来)
└─ cache.json 投影缓存(原样搬过来)
每个条目自带元数据,没有全局清单,所以不会出现清单和实际文件对不上的情况。目录名以时间戳开头,天然按时间排序;恢复就是原路搬回去。过期清理在两个时机触发:宿主启动时,以及每次打开回收站时。
安装与启用¶
本包是 DSH 组合包(bundle):profile 只要把包名选进 dsh.profile.bundles,加载器就会应用自带的 cordis.patch.yml。
仓库里的 install.ps1 脚本支持三种干跑方式:
cd dsh-session-trash-90d
.\install.ps1 -Profile desktop # 默认就是 desktop
.\install.ps1 -Profile desktop -DryRun # 只看将要做的改动
.\install.ps1 -Profile desktop -Uninstall
第一步,先 DryRun。 它会打印将要改哪些 profile 文件,确认无误再真正执行。
也可以走 profile 自己的插件管理器(设置里的「插件」页),填仓库地址:
https://github.com/Full626/dsh-session-trash-90d
或命令行:
dsh plugin --profile desktop add 'github:Full626/dsh-session-trash-90d'
第二步,重启应用。 新组合层要下次组合才生效,装完不重启看不到变化。
第三步,打开设置 → 会话管理。
典型用法¶
装完重启后,日常操作都在「设置 → 会话管理」里完成:
1、会话列表里看到所有已存储会话及其元信息,区分 内存中 和 已归档。
2、要清理某个会话,点「移入回收站」——它连目录带缓存一起搬走,不是直接抹掉。
3、需要找回时,在回收站里点「恢复」,它会回到原来那个工作区。
4、确认不要了,才用「彻底清除」,或把超过 90 天的交给「清理过期」。
宿主内存里正活着、又没能释放的会话,删除后不会立即消失。界面上会提示「还有 N 个待下次启动处理」,这是刻意的诚实:下次宿主启动时重放墓碑,确认消失且不再 live,墓碑才会被清掉。
命令行侧也有一组接口可用于自动化:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /list |
会话列表 + 待处理墓碑 + 保留天数 |
| GET | /trash |
回收站条目(顺带清理过期项) |
| GET | /state |
墓碑、home、两个根目录、保留天数 |
| POST | /delete |
body {"ids":[...]} —— 移入回收站 |
| POST | /restore |
/purge |
| POST | /archive |
/unarchive |
验证时怎么跑¶
主机半侧有一套不碰真实数据的测试:在临时 $DSH_HOME 里造假会话,用最小 fake ctx 驱动真实插件代码,专门覆盖那个回归——假造「内存回写」,再验证启动重放把它清掉。
node scripts/test-host.mjs # 27 项:列表/删除/墓碑/重放/归档/错误处理
跑在真实桌面端上的检查,默认只读:
# 只读:列出会话、墓碑状态
node scripts/check-api.mjs --url http://127.0.0.1:19387
# 真要删几个(谨慎)
node scripts/check-api.mjs --url http://127.0.0.1:19387 --delete session-xxxx
适用场景与注意¶
适合这些人:
- 在 DSH 0.2.x 上做开发,受够了「会话删不掉 / 删了又回来」。
- 需要批量清理旧会话,又不希望误删后无法找回。
- 需要取消归档这项官方没提供的能力。
需要留意的几点:
1、删除默认保留 90 天;「彻底清除」和过期清理才是不可恢复的。所以别把回收站当成无限期保险箱,也别把彻底清除当常规操作。
2、回收站占用磁盘,删得多了记得清,或让它自己过期。
3、宿主正在运行某个会话时不会删它(会跳过并告知),这是刻意设计,不是 bug。
4、插件以当前 DSH 进程权限运行,装的是就直接改 profile 文件——安装前先读源码和 MIT 许可证,install.ps1 先加 -DryRun 看一遍。
5、会话正文是 JSONL + 多帧 zstd,本插件只做管理,不解析正文内容,拿不到「这会话讲了什么」的语义。
6、路径布局按 DSH 0.2.x 的 $DSH_HOME/sessions/<工作区编码>/<会话 id>/ 解析;将来若改布局,表现是列表变空而不是误删。
7、本插件是社区第三方包,目录页与仓库都是独立站点项目,与 DeepSeek / 幻方没有官方从属关系。
小结¶
dsh-session-trash-90d 的价值在于它承认了「会话删了会复活」这个真实约束,并给出一个可验证的解法:墓碑 + 启动重放,加上 90 天回收站、原工作区恢复、取消归档。如果你正在 DSH 0.2.x 上做会话治理,值得先 node scripts/test-host.mjs 看那 27 项测试跑通,再装到 profile 上。
目录页:https://www.skillhub.cn/plugins/Full626/dsh-session-trash-90d
仓库:https://github.com/Full626/dsh-session-trash-90d