dsh-session-cleanup
Identified★ 1DSH Session Cleanup · DeepSeek Harness Sidebar Plugin: Sort sessions by size, archive, and delete to an undoable recycle bin (restore in bulk or individually), and clean up orphaned projection caches and invalid archive items. | Sidebar session cleanup panel for DSH: size-sorted sessions, archive, undoable recycle bin, orphan projection-cache cleanup.
dsh-session-cleanup
DSH 会话清理 — DeepSeek Harness 侧边栏插件:按体积排序会话、归档、删除进可撤销回收站、清理孤立投影缓存。
功能 · 为什么需要 · 安全模型 · 安装 · 配置 · 使用 · Host 路由 · 目录结构 · 测试 · FAQ · English
功能
- 按体积排序的会话列表 —— 左栏按工作区导航,右栏列出该工作区会话,显示字节体积、最后更新时间、运行中/活跃徽章,一眼找出最占空间的会话。
- 归档 / 取消归档 —— 走
workspaceRegistry.archiveSession,归档会话从活动列表移出但一个字节都不动。 - 会话记录预览 —— 点会话标题在右栏打开只读记录:最近 12 条用户/助手文本 + 记录数、体积、更新时间,确认内容之后再归档或删除。
- 可撤销删除 —— 删除会把会话目录和它的投影缓存文件一起 移动 到
$DSH_HOME/backups/session-cleanup-<stamp>/,并写一份 manifest。没有东西被销毁。 - 会话行右键删除 —— 侧边栏会话的「…」菜单(
置顶 / 重命名 / 分叉 / 复制 ID / 在文件夹显示 / 归档)末尾多一项 删除会话,与面板走同一条可撤销路径;第一次点击要求确认,再点一次才移入回收站,成功或失败都在菜单下方给出提示。 - 回收站勾选还原 / 永久删除 —— 每条会话可勾选,每批可全选或半选;统一用「还原所选」「永久删除所选」。按批全选等于原来的整批操作。永久删除会确认实际会话数且不可恢复,取消不发请求。清空回收站仍独立,并分开报告批次与会话数。
- 显式 purge —— 唯一真正删除字节的操作,必须按所选会话或按单条显式请求。
- 清空回收站 —— 一次性丢掉所有
session-cleanup-*批次。 - 删除后两侧同步 —— 删除成功后 Host 广播
api-session/removed,面板也刷新客户端会话列表,侧边栏不会再留一条“已经不存在的会话”。 - 孤立缓存清理 —— 删除
session_projcache/sessions/*.json中会话日志已不存在的文件,需二次确认(此操作不可撤销),并报告释放的字节数。 - 失效归档清理 —— 丢掉会话日志已消失的归档/固定(archive/pin)条目。
为什么需要
DSH 没有"删除会话"这个能力。移除一个 Workspace 注册项是故意保留会话历史的,所以用户想清空间时没有出口:历史日志、投影缓存、失效的归档条目只会越积越多。
这个插件把缺失的那几个操作补上,并且坚持一条原则:删除必须可逆。真正不可逆的动作只留一个 purge,且必须显式点名。
安全模型
| 约束 | 行为 |
|---|---|
| 会话仍被 live Agent 持有 | 跳过,不移动 —— 它持有日志写入句柄 |
| 移动范围 | 只动 $DSH_HOME/sessions 下的内容 |
| 删除范围 | 只动 $DSH_HOME/backups 下的内容 |
| 部分失败 | 回滚已移动的条目,并丢弃半成品批次 |
| 跨卷移动 | 回退到 copy-then-remove(EXDEV) |
| 跨站写入 | 两条路由都校验 sec-fetch-site / Origin 对 Host |
| 请求体 | 上限 64 KiB;label 截断到 200 字符 |
| 路径穿越 | 批次名必须匹配 session-cleanup-<stamp>;还原/按条清除还会校验 manifest 里的目录名,相对路径越界即拒绝 |
| 共享批次回滚 | 批量删除中后一条失败时,只回滚该条,不会删掉批次里已经成功的会话 |
| manifest 损坏或写入失败 | 先回滚该条;若目录仍留在回收站,会扫描会话树并允许还原 |
安装
方式一:一条命令装 GitHub 仓库(推荐)
dsh plugin --profile web add https://github.com/mkt-agents/dsh-session-cleanup
--profile 换成你自己的 profile 名(默认 web)。命令会把它写进该 profile 的 dsh.profile.bundles,装完重启 harness,左侧栏出现「会话清理」入口。
方式二:克隆到本地再装(要改代码时用)
git clone https://github.com/mkt-agents/dsh-session-cleanup.git
dsh plugin --profile web add ./dsh-session-cleanup
方式三:作为 bundle patch 手工挂载
把插件目录放进 profile 的插件目录后,在 bundle patch 里加一段 cordis.patch.yml:
- insert:
- id: session-cleanup
name: '@local/dsh-session-cleanup'
inject: [webServer]
config: {}
配置
默认零配置:不需要任何密钥、环境变量或模型账号,装完即用。可调的只有 patch 里的两项:
| 键 | 默认 | 说明 |
|---|---|---|
inject | [webServer] | Host 半边需要的宿主服务;去掉就只剩 Client 半边 |
config | {} | 目前没有必填项,留空即可 |
运行期约定:
DSH_HOME默认%USERPROFILE%\.dsh(Windows)/$HOME/.dsh(其他);换目录只影响会话与回收站的定位。- 回收站目录:
$DSH_HOME/backups/session-cleanup-<YYYYMMDD-HHmmss-mmm>/,同级manifest.json记录批次、会话 id、cwd 分组、标题、体积和删除时间。 - Host 路由只在同源下可用(
/dsh-session-cleanup/state、/dsh-session-cleanup/preview、/dsh-session-cleanup/action),不监听公网、不需要单独端口。 package.json把 Client 半边声明为立即注入的 Web client,依赖react、@deepseek-ai/dsh-client-runtime、@deepseek-ai/dsh-client-locale、@deepseek-ai/dsh-client-ui-slots。
使用
- 打开 Web 界面,左侧栏出现 会话清理 入口。
- 面板是左导航 + 右列表:左栏按工作区切换(含 未分组、已归档、回收站、孤立缓存 四个固定入口),右栏只显示当前工作区的会话,可按体积 / 更新时间 / 标题排序,支持搜索标题、id、路径。
- 勾选会话后:
- 归档 —— 移出活动列表,字节不动。
- 删除 —— 二次确认后移入回收站,可在回收站勾选后还原或永久删除。侧栏菜单删除同样要确认后再移入回收站。
- 点标题(不是勾选框)打开记录预览,只看不选;预览里也能归档/取消归档/删除。
- 切换左侧工作区或固定入口会清空勾选,避免对看不见的会话做批量操作;同一视图里的搜索筛选会保留勾选,并提示有多少项被滤出。
- 回收站可勾选会话或按批全选,用 还原所选 / 永久删除所选(无选择时禁用;永久删除先确认实际会话数,取消零请求)。按条还原/清除仍然可用。清空回收站 独立保留,并分开报告批次与会话数。切换视图会清空回收站勾选。
- 清理类操作各归其位:失效归档 在「已归档」页,孤立缓存 在「孤立缓存」页(会报告释放字节)。
Host 路由
仅同源。
| 方法 | 路径 | 用途 |
|---|---|---|
GET | /dsh-session-cleanup/state | workspaces、归档/固定集合、会话、回收站、统计 |
GET | /dsh-session-cleanup/preview | 只读会话记录预览(?id=) |
POST | /dsh-session-cleanup/action | archive | unarchive | delete | restore | purge | pruneArchived | pruneOrphanCache | emptyTrash |
action 接受 { op, sessionIds?, batch?, labels? }。restore 和 purge 必须带 batch;sessionIds 为空表示作用于整批。一次删除动作 = 一个回收站批次,所以批量删除可以作为一个整体撤销。
目录结构
index.js Host 半边:路由、回收站批次、孤立缓存扫描(1489 行)
client.js Client 半边:main 面板 + sidebar 入口(2445 行)
cordis.patch.yml bundle patch
locale/{en,zh}.json 插件元数据字符串
icon.svg 侧边栏图标
test/host.test.mjs Host 路由测试(83 条断言,含 R1–R5 回归)
test/client.test.mjs Client 渲染测试(141 条断言,含 R4 与回收站勾选及作用域防护)
test/independent-host.mjs 独立 Host 复现集(50 条断言,原样保留)
test/independent-client.mjs 独立 Client 复现集(15 条断言,原样保留)
测试
npm test
npm run test:independent
官方套件与独立复现集都跑在纯 Node 上,零依赖:Host 套件用临时 DSH_HOME 驱动真实路由处理函数,Client 套件用极简 hook 运行时执行组件树。故障注入钩子仅在 DSHSC_TEST_HOOKS=1 时生效。独立 65 条断言未改期望、未跳过。
83/83 passed official host
141/141 passed official client
50/50 passed independent host
14/14 passed independent client
FAQ
删除的会话去哪了?
$DSH_HOME/backups/session-cleanup-<YYYYMMDD-HHmmss-mmm>/,同目录下 manifest.json 记录批次、会话 id、cwd 分组、标题、体积和删除时间。
为什么有些会话删不掉? 它正被 live Agent 持有(已打开或正在运行),日志写入句柄还开着。切到别的会话再删。
回收站会占空间吗? 会,而且和原来一样大 —— 这是可撤销的代价。确认无误后 purge 或清空回收站。
能用在非 Web 端吗?
不能。Client 半边注册在 main 与 sidebar.panellist 两个 Web slot 上。
插件 id 能改吗?
能。@local/dsh-session-cleanup 是本地占位,发布到 npm 时换成你自己的 scope,同时改 cordis.patch.yml 里的 name。
English
A DeepSeek Harness (DSH) Web plugin that adds a session cleanup panel to the sidebar: list sessions by size, archive them, delete them into an undoable recycle bin, and clear orphaned projection cache.
Installation (English)
dsh plugin --profile web add https://github.com/mkt-agents/dsh-session-cleanup
Restart the harness afterwards — a Session Cleanup entry shows up in the sidebar. Pick your own profile name if it is not web. No API key, no environment variable, no extra configuration.
DSH has no session-delete capability (removing a Workspace registration deliberately leaves session histories in place). This plugin owns the missing operations.
- Size-sorted list — sessions grouped by workspace with byte size, last-updated time, and a live/running badge.
- Archive / unarchive — delegates to
workspaceRegistry.archiveSession; archived sessions leave the active list without touching bytes. - Reversible delete — the session directory and its projection-cache file are moved into
$DSH_HOME/backups/session-cleanup-<stamp>/with a manifest. Nothing is destroyed. - Restore per batch or per session — undo a whole delete action, or bring back a single session of it.
- Explicit purge — the only operation that removes bytes, requested per batch or per session.
- Orphan cache cleanup — remove
session_projcache/sessions/*.jsonwhose session log is gone, reporting freed bytes. - Stale archive pruning — drop archive/pin entries whose session log no longer exists.
Safety: a session still attached to a live Agent owns its log writer, so it is skipped rather than moved. Nothing outside $DSH_HOME/sessions is ever moved; nothing outside $DSH_HOME/backups is ever removed. Moves are rollback-safe, cross-volume moves fall back to copy-then-remove, and both routes reject cross-site writes.
License
Comments
Loading…