Files
session-delete/README.md
T
pyh 1a9165fa4f
publish / npm (push) Successful in 5s
release: 1.0.2, and learn whether the built-in job token can publish
The publish step now tries the built-in Gitea job token first, prints which user it belongs to, falls back to NPM_TOKEN when the registry rejects it, and reports which token actually published. A 409 keeps meaning 'already published', so a re-run stays harmless.
2026-09-30 14:29:02 +08:00

94 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 会话彻底删除
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-<sha256(会话 id) 前 12 位>`——这是 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)