# 会话彻底删除 DeepSeek Harness(DSH)插件:给会话加上**真正不可逆的删除**,并清理已删除会话遗留的临时文件。 DSH 原本只能归档会话——归档只是把会话从列表里移开,日志仍然留在磁盘上。这个插件提供两处删除入口,以及设置页里的一次性孤儿文件清理。 ## 功能 ### 1. 删除会话 两个入口,行为一致,都会先弹出确认弹窗(复刻系统 Modal 的样式与键盘行为:Esc 关闭、Tab 焦点圈定、打开时焦点进入、关闭后焦点归位): - 会话行右侧 **⋯** 菜单 → **删除会话** - 会话行悬停时的 🗑 快捷按钮(占用原「归档会话」的位置,归档改从菜单进入) 确认后一次性处理: | 对象 | 处理方式 | | --- | --- | | 会话日志目录 | 整个删除,仅保留 `session.lock` | | 子智能体会话 | 按 `parentSession` 递归收集,连同日志与溢出文件一并删除 | | 工具输出溢出文件(spill) | 删除该会话(含子会话)对应的 spill 目录 | | 工作区登记项 | 解除绑定、取消置顶、取消归档 | | 客户端列表 | 广播 `api-session/removed`,列表行立即消失 | 有意**不**处理: - **附件对象**(`$DSH_HOME/attachments/v1/objects`):按内容 sha256 寻址,同一份内容可能被多个会话共享,而 DSH 没有引用计数,跟着一个会话删除会破坏别的会话; - **投影缓存**(`$DSH_HOME/storages/session_projcache`):由日志派生的缓存,读取时带生命周期身份校验,永远不会串到别的会话。 ### 2. 清理临时文件 设置 → 通用设置 → **清理临时文件**,清理 spill 后端留下的**孤儿**目录。判定偏保守: 1. 目录名必须精确等于 `session-`——这是 spill 后端唯一会生成的形状; 2. 该名字不属于任何已知会话(存量会话与内存中正在运行的会话都算); 3. 只在 spill 的 root 内操作(后端当前 root + 系统临时目录下的 `dsh-spill*`); 4. 符号链接一律跳过、不跟随;单项失败只记警告。 结果直接显示在该行(清理了几个目录、几个文件、释放多少空间),可反复点击。 ## 行为与边界 - **仍在运行的会话**无法被插件从内存里移除:它会先被归档并停止,日志与溢出文件在**下次启动 DSH 时**删除(界面会明确提示);在此之前取消归档就会取消这次删除。 - 删除**不可恢复**,但**不是安全擦除**:按普通文件删除处理,底层介质上可能有残留。 - 工作区里的代码文件不受影响。 - 溢出文件被删除后,fork 出来的会话日志里若仍保留指向它的路径文本,那些路径会失效。 ## 安装 DSH 的 **插件 → 添加插件** 里有两个输入,含义不同: - **上面那个输入框**:装什么(包名 / Git 地址 / 本地 tgz 的绝对路径); - **下面的「安装源」**:只决定**按包名安装时**去哪个注册表查。填 Git 地址或 tgz 时它不参与拉取,保持默认(官方源)即可,不必切到「自定义地址」。 ### 1. Git 仓库地址(推荐) 在上面的输入框里填: ```text https://gitea.iwake.top/dsh-plugin/session-delete.git#v1.0.2 ``` `#` 后面可以跟标签或提交,用来锁定版本;不写则取默认分支。仓库是公开的,不需要凭据,也不需要改安装源。 想跟随 1.x 的最新版本,可以把后缀写成 `#semver:^1.0.2`——pnpm 会按仓库里的标签挑最高的 1.x(当前即 v1.0.2 那个提交),以后发了 v1.0.3,移除旧版本再装一次就能拿到。 ### 2. 本地 tgz 把 [session-delete-1.0.2.tgz](https://gitea.iwake.top/api/packages/dsh-plugin/npm/@dsh-plugin%2Fsession-delete/-/1.0.2/session-delete-1.0.2.tgz) 下载到运行 DSH 的机器上,把它的绝对路径填进上面的输入框。 ### 关于「npm 源」这条走不通的路 本插件也发布在自建 Gitea 的 npm 仓库里(安装源填 `https://gitea.iwake.top/api/packages/dsh-plugin/npm/`、包名填 `@dsh-plugin/session-delete`),但**目前不能用它安装**:Gitea 返回包清单时只保留 `name`、`version`、`description`、`author`、`homepage`、`license`、`repository`、`readme`、`dist`、`maintainers`,插件需要的 `dsh`(即 `dsh.bundle.patch`)会被丢掉;而 DSH 的安装预检要求清单里声明 `dsh.bundle`,于是会报: ```text 这个包没有声明组合包,无法作为插件安装:@dsh-plugin/session-delete declares no dsh.bundle ``` Git 地址与 tgz 这两条路没有这个问题——它们是先把包取到本地、再读它自己的 `package.json`,字段完整。若将来把它发到保留自定义字段的注册表(npmjs 等),包名那条路才走得通。 安装或升级后:**宿主半变更需要重启 DSH**(完全退出再打开,仅关闭窗口不一定退出进程);只改浏览器半时刷新页面即可。DSH 暂不支持插件自动更新,升级就是用新标签重装一次(建议先移除旧版本)。 ## 兼容性 基于 **DeepSeek Harness 0.2.0-rc.2** 编写。DSH 仍在演进,其它版本与平台组合未逐一验证。 - 浏览器半不 import 任何 Harness 客户端包(上游规范如此要求:这些包随时可能变化,渲染抛错会让整个插槽条目变空白),而是复刻 `dsh-client-ui-primitives` 的 markup、CSS 声明、图标 path 数据与键盘行为,只保留 `--dsw-*` 主题 token 引用。上游若改动这些内部结构,界面细节可能失配(例如悬停气泡不再出现),但不会导致插件加载失败。 - 宿主半只依赖稳定的服务契约:`sessionPersistence`、`sessionQuery`、`workspaceRegistry`、`sessions`、`agents`、`connection.fetch`,以及 spill 后端的目录规则。 ## License [MIT](LICENSE)