dsh-plugin-session-delete
Verified@coder02lq/dsh-plugin-session-delete · v1.0.2 · MIT · Web UI
Permanently delete DeepSeek Harness Sessions from the sidebar, with confirmation, subagent cascade, and honest failure when files survive.
Install
dsh plugin add @coder02lq/dsh-plugin-session-delete Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
@coder02lq/dsh-plugin-session-delete
给 DeepSeek Harness 补上「删除会话」:侧边栏 ⋯ 菜单里的一个删除项,二次确认,真正从磁盘上清干净。
DSH 出于设计只提供归档,不提供删除——会话能隐藏,但日志会永远堆在磁盘上。 这个插件把删除能力补回来,作为一个可随时卸载的 bundle,不改官方任何代码。
订阅会话 ⋯ → 删除会话 → 确认 → 日志、投影缓存、工作区登记一并清除
功能
- 侧边栏菜单项:会话行的
⋯菜单新增「删除会话」,排在「归档会话」与「会话 ID」之后,带分隔线,用危险色标注。 - 二次确认弹窗:删之前告诉你到底会删掉什么,并说明子代理会话会被连带删除;Esc、点击遮罩均可取消,焦点会归还到触发按钮。
- 子代理级联:连同该会话的全部子代理子孙一起删除。子代理会话在侧边栏是被隐藏的,且打开它必须经由父会话,父会话一删就再也无法访问——所以留着只是占磁盘的孤儿。fork 出来的会话不受影响,它们有自己独立的侧边栏行和生命周期。
- 彻底清理:对话日志、投影缓存、工作区登记、归档/置顶集合,一处不留。
- 诚实失败:文件删不掉时不会假装成功,会明确告诉你「登记已移除但文件还在」,让你重试或手动清理。
- Agent 工具:同时暴露
session_delete工具,附带「不得删除自己所在会话」的护栏。
安装
桌面端(DeepSeek Harness App)
设置 → 插件 → 添加插件,输入包名:
@coder02lq/dsh-plugin-session-delete
装完完全退出并重开 App,侧边栏会话的 ⋯ 菜单里就会出现「删除会话」。
⚠️ 桌面端的 profile 不能用 CLI 安装(DSH 对
desktopprofile 做了排他保护),请走上面的「设置 → 插件」。
Web / CLI profile
dsh plugin --profile <profile> add @coder02lq/dsh-plugin-session-delete
装完重启该 profile。
也可以直接从 GitHub 装(会锁定到具体 commit):
dsh plugin --profile <profile> add github:Heaven-y/dsh-plugin-session-delete
一次删除到底做了什么
| # | 步骤 | 为什么 |
|---|---|---|
| 1 | 归档并停止该会话的工作 | 先写归档集合再派发停止,停止过程唤醒的任务因此已被拦截 |
| 2 | 等待运行中的 turn 结束(≤8 秒) | 正在跑的 turn 会继续往日志里追加,必须等它停下再删文件 |
| 3 | 从工作区行、归档集合、置顶集合摘除 id | 三处独立持有这个 id |
| 4 | 删除投影缓存行 | 派生数据,必须等第 2 步之后,否则会被写回来 |
| 5 | 删除会话目录 | 当前日志代、历史日志代、POSIX 租约文件在同一目录;附件是内容寻址共享的,不动 |
| 6 | 重建内存中的 header 索引 | 不做的话进程会一直「记得」这个已删会话,直到重启 |
| 7 | 向客户端发 api-session/removed |
侧边栏只在这个事件上撤行 |
第 2 步只看 Agent 自己的状态(agent.status === 'running'),不看会话是否被打开。宿主会把界面加载过的会话都 attach 在内存里,若把它当作「正在使用」,删除空闲会话会一直等到超时——这是 1.0.1 修掉的缺陷。
第 7 步是 1.0.2 修掉的缺陷:宿主只在会话被 dispose 时发 api-session/removed,而删文件并不会让已打开的会话 detach,于是侧边栏会留下一行属于「未分组」的幽灵条目,再删一次还会报 session/not-found。现在删完主动通知客户端,并把「仍挂在内存里」也算作存在,重复删除因此幂等。
子代理级联发生在第 1 步之前:先读出整棵子代理血缘(父在子前),删完父会话后再逐个清理,已消失的子会话会被跳过而不是报错。
换台电脑、换个系统
跨操作系统可用。 代码里没有平台分支,不读 process.platform,不拼盘符或路径分隔符,只用 node:fs/promises 和 node:path。会话文件在哪是问持久化层的(locate(header)),所以 Windows 的 C:\Users\…\.dsh\sessions\… 和 macOS 的 ~/.dsh/sessions/… 都不需要插件知道区别。
唯一的系统差异是删除被占用的文件:Windows 会让 unlink 失败,macOS 会「成功」但持有者能重建路径把会话复活。所以这里先等宿主写入方退出,再短暂重试,最后如实报 session/locked。
跨 DSH 版本不保证。 插件必须碰一些非公开的内部接口(replaceHeaderIndex、session_projcache 表、locate、api-session/removed 事件)。风险最高的几处做了防御式解析,但 Workspace 注册表若改变形状就需要更新代码。
已验证 / 未验证
已验证:
- Host 侧 13 项测试:七步顺序、已归档会话不重复归档、运行中的 turn 会等待、空闲但已打开的会话立即删除、卡住的 turn 快速失败并回滚归档、拒绝操作零副作用、日志已丢但仍有登记的 id 会被清理、删不掉的目录报
session/locked、两层级联且 fork 存活、移除事件覆盖根与每个级联 id、重复删除已删会话幂等、工具拒绝删除自身会话。 - 处理函数实测:空闲会话删除耗时 1.9 ms(旧版会等满 15 秒)。
- Client 侧 7 项测试:工厂导出、挂载的 descriptor 与 Host 签名一致、两个 slot 注册、中英词典、样式仅用主题 token、确认后经由 delete hop 转发、缺少 namespace 时不产生未处理拒绝。
- 真机:多次创建一次性会话并删除,日志目录、投影缓存、工作区引用均干净;删除后侧边栏行消失、弹窗即时关闭、结果以提示条呈现。
未验证: 本机没有浏览器控制权(页面需要浏览器自身的会话令牌),所以浅色/深色主题下的像素级观感没有逐帧确认,只确认了交互行为与行消失。标记与样式照搬宿主自己的 Modal/MenuItemButton/Button 实现。
许可
MIT