前言¶
在 DSH(DeepSeek Harness)工作流中,随着长期运行,工作区与 DSH_HOME 会累积大量临时文件、系统噪声和可再生缓存。这些垃圾既占用磁盘空间,又会干扰后续任务的上下文识别。手动清理往往漫无目的,要么漏删,要么误删配置或源码。
file-cleanup 插件通过「白名单」机制与严格的范围围栏,在预览确认后才执行删除,将误删风险降到最低。下面介绍它的安装与用法。
这是什么¶
这是一个 DSH 插件,提供左上角「文件清理」按钮,用于扫描并删除白名单内的垃圾文件与空目录,删除范围严格限定在「所有工作区」或「DSH_HOME」内。
- 插件名:file-cleanup
- 维护者:DEVVE-1
- 版本:v1.3.0
- 分类:工作流
核心功能¶
清理范围¶
插件提供两种清理范围:
- 所有工作区:对每个已登记工作区的
path递归清理,跳过.git、.hg、.svn、node_modules。 - DSH_HOME:清理 DSH_HOME 内的白名单垃圾,额外回收
$DSH_HOME/cache的内容(可再生),但保留cache目录本身;跳过sessions、storages、profiles、attachments、dsh-runtimes、llm-deepseek。
删除规则(白名单)¶
| 类别 | 规则 |
|---|---|
| 临时文件 | *.tmp、*.temp、*.part、*.partial、*.crdownload、*.download、*.swp、*.swo、*.swn、*.stackdump、*.$$$、foo.txt~、~$report.docx、hs_err_pid*.log |
| 系统噪声 | Thumbs.db、ehthumbs.db、desktop.ini、.DS_Store、._*、npm-debug.log*、yarn-error.log*、pnpm-debug.log*、*.orig、*.rej、core.<pid>、.eslintcache、.stylelintcache |
| 可再生缓存目录 | __pycache__、.pytest_cache、.mypy_cache、.ruff_cache、.pytype、.hypothesis、.ipynb_checkpoints、.cache、.parcel-cache、.turbo、.sass-cache、.nyc_output(整棵删) |
| 空目录 | 只回收「因为本次删除才变空」的目录,从被删项往上收,碰到选中根就停。原本就存在的空目录不动。 |
交互流程¶
- 点左上角「文件清理」(Windows 桌面:接在 preload 的标题栏菜单条「编辑」右边)。
- 选区域:
所有工作区(列出每个工作区路径)或DSH_HOME(显示实际路径)。此步只调describe,不读不删。 - 扫描:Host 侧遍历一遍,统计可清理项的数量与体积,并把全部候选路径一起带回来。此步不删除任何东西。
- 确认弹窗:写明本次清理区域(根目录绝对路径)、风险提示四条、将删除的文件/目录数量与预计释放体积,以及本次要删的清单(按体积降序)。
- 清单一次性全部渲染进一个固定高度、可滚动的框里——条目多就自己滑动看,没有展开 / 收起这类二次交互。框的可视区固定为五行半(115px = 5 × 18px 行高 + 半行 + 上下 8px 内边距),露出的那半行就是「下面还有」的提示。整体也只列到 2000 条,超出时框下面会写明「只列出体积最大的 N 项」。 - 点「开始清理」才真正删除——删的就是第 4 步里那份清单(浏览器半边把它原样回传,Host 只删这些、不会再自己重扫一遍)。结束后给出结果,并支持「复制清单」。
- 扫完发现没有垃圾:确认弹窗里不再出现「开始清理」,只留一个绿色的「完成」按钮把界面关掉;风险提示与清单也一并隐藏(没东西可删,列风险只是噪声)。
扫描与清理之间可以随便取消;取消只是关掉界面,不会留下半截状态。唯一例外是点下「开始清理」之后:删除已经交给 Host 跑起来了,这时标题栏按钮与弹窗的 × 都不再响应,直到结果回来。
安全边界¶
插件从多个层面确保删除操作不会越界:
- 范围围栏:每个待删路径在删除前都断言「严格位于某个选中根目录之内」,且不等于根目录本身。三个粒度都查:
resolve()后的规范路径、path.relative相对路径判定、Windows 大小写不敏感比较。 - 真实路径对齐:选中根先过
realpath,目录联接 / 符号链接当根时,围栏落在真实目标上。 - 卷根拒收:选中根不能是
D:\//这种卷根。DSH_HOME区域下如果 HOME 退化成卷根,直接报no-dsh-home。 - 工作区与 DSH_HOME 不得重叠:相等、工作区在 DSH_HOME 里面、工作区把 DSH_HOME 包住,三种都整条跳过并记警告。
- 不跟随链接:遍历时符号链接与目录联接一律跳过——既不进入它的内部,也不删链接本身。
- 白名单而非黑名单:只有规则表命中的文件才进候选;没命中就永远不动。误判方向永远是「少删」。
- 确认的就是删除的:清理只删确认框里出现过的那份清单。扫完之后才冒出来的文件不会被「顺手」带走。
- 二次确认:前端有确认弹窗,Host 侧还要求请求体显式带
confirm: true。 - 接口只对本机同源开放:路由固定为
/file-cleanup,要求POST+application/json,且Host必须是回环地址(localhost/127.x/::1)、Sec-Fetch-Site不能是cross-site。 - 单任务互斥:同一时刻只跑一个清理任务,第二个请求拿 409。
- 删除不可逆:不进回收站。被占用删不掉的文件会被跳过并计入
failures。
接口¶
Host 侧提供一条固定路由:
POST /file-cleanup
content-type: application/json
支持以下 action:
describe→ 返回dshHome、workspaces[]、scopes[]、busy。scan,scope为workspaces或dsh-home→ 返回预览(数量 / 体积 / 分类 / 完整清单 / 警告)。clean,scope、confirm: true、items(清单)→ 实际删除结果。
返回 200 表示成功,4xx/5xx 表示失败,具体错误码见 README。
安装与启用¶
插件包已经是一个可直接加载的 bundle(package.json 的 dsh.bundle.patch + dsh.client),Host 半边 lib/index.js / lib/core.js、浏览器半边 lib/client.js 都是最终产物,无需构建。
cd <本目录的绝对路径>
$node = "$env:DSH_HOME\dsh-runtimes\dsh-primary-runtime\dependencies\node\bin\node.exe"
& $node .\install.mjs --dry-run
& $node .\install.mjs # 默认 desktop profile,可加 --profile <name>
脚本会:用运行时自带的 pnpm 把本目录作为 file: 依赖装进 profile → 把包名追加到 dsh.profile.bundles → 按 SHA-256 把包内容同步进安装目录 → 复查。
装好后刷新一次页面,浏览器半边才会进入模块表。
典型用法¶
- 安装后刷新页面,左上角「编辑」右边会出现「文件清理」按钮。
- 点击按钮,选择清理范围:
所有工作区或DSH_HOME。 - 等待扫描完成,弹窗会列出本次要删除的文件/目录清单与预计释放体积。
- 检查清单无误后,点「开始清理」。
- 清理完成后,结果会显示删除的文件/目录数量、释放体积、失败项(如有)。
- 若清单过长,可滚动查看或点击「复制清单」。
适用场景与注意¶
- 适合需要定期清理临时文件、缓存目录的 DSH 工作流场景。
- 插件以当前 dsh 进程权限运行,安装前建议检查源码与许可证(MIT)。
- 删除操作不可逆,不进回收站;被占用的文件会被跳过并计入
failures。
结尾¶
file-cleanup 插件通过白名单规则与严格范围围栏,在预览确认后才执行删除,将误删风险降到最低。适合需要定期清理临时文件、缓存目录的 DSH 工作流场景。
- 插件目录页:https://www.skillhub.cn/plugins/DEVVE-1/dsh-plugin-file-cleanup
- GitHub:https://github.com/DEVVE-1/dsh-plugin-file-cleanup