DSHDeepSeek Harness的子代理条目/会话/孤儿投影缓存清理工具。
29.6/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/25 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add PolitaryMonicy/dsh-agent-clean该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:待复验
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 21 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 111 处,展示前 29 条)
- 写入本地文件plugin/index.js:81
appendFileSync(HOST_LOG, `${new Date().toISOString()} ${message}\n`) - 执行外部命令来自配置/变量plugin/index.js:251
const child = spawn(process.execPath, [join(PKG_ROOT, 'clean.mjs'), 'autowait', '--pid', String(process.pid)], { - 读取本地文件plugin/index.js:286
workspaces = readdirSync(SESS_ROOT, { withFileTypes: true }) - 读取本地文件plugin/index.js:293
for (const entry of readdirSync(join(SESS_ROOT, ws.name), { withFileTypes: true })) { - 写入剪贴板plugin/client.js:125
navigator.clipboard.writeText(text).then(done, () => fallback()) - 发起网络请求plugin/client.js:154
fetch(SCAN_ROUTE, { headers: { accept: 'application/json' }, cache: 'no-store' }) - 发起网络请求plugin/client.js:179
return fetch(SETTINGS_ROUTE, { - 写入本地文件clean.mjs:71
mkdirSync(d, { recursive: true }); - 写入本地文件clean.mjs:73
writeFileSync(probe, ''); - 删除本地文件clean.mjs:74
rmSync(probe); - 读取本地文件clean.mjs:85
const VERSION = (() => { try { return JSON.parse(readFileSync(join(TOOL_DIR, 'package.json'), 'utf8')).version || '0.0.0'; } catch { return '0.0.0'; } - 读取本地文件clean.mjs:179
if (!existsSync(cachePath)) return { exists: false }; - 读取本地文件clean.mjs:181
const j = JSON.parse(readFileSync(cachePath, 'utf8')); - 读取本地文件clean.mjs:217
const j = JSON.parse(readFileSync(SCAN_CACHE_FILE, 'utf8')); - 读取本地文件clean.mjs:252
const buf = readFileSync(logPath); - 读取本地文件clean.mjs:284
if (!existsSync(SESS_ROOT)) return out; - 写入本地文件clean.mjs:328
try { writeFileSync(OUT_TARGET, text, 'utf8'); } catch { } - 写入本地文件clean.mjs:419
mkdirSync(bak, { recursive: true }); - 写入本地文件clean.mjs:424
copyFileSync(p.path, join(bak, base)); - 写入本地文件clean.mjs:428
copyFileSync(cachePlan[0].path, join(bak, 'projcache.json')); - 删除本地文件clean.mjs:604
rmSync(outFile, { force: true }); - 执行外部命令来自配置/变量clean.mjs:606
const r = spawnSync(useApp ? app.exe : process.execPath, argv, { - 删除本地文件递归clean.mjs:674
rmSync(MIRROR_ROOT, { recursive: true, force: true }); - 删除本地文件clean.mjs:770
for (const o of orphans) { copyFileSync(o.path, join(bak, o.name)); manifest.files.push({ backup: o.name, original: o.path }); rmSync(o.path); } - 删除本地文件递归clean.mjs:827
rmSync(s.dir, { recursive: true, force: true }); - 删除本地文件clean.mjs:828
if (s.cachePath) rmSync(s.cachePath, { force: true }); - 执行外部命令固定命令clean.mjs:1210
const r = spawnSync('tasklist', ['/FI', 'IMAGENAME eq DeepSeek Harness.exe', '/FO', 'CSV', '/NH'], { - 执行外部命令来自配置/变量clean.mjs:1258
const r = spawnSync(ps, ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', script], { - 执行外部命令固定命令clean.mjs:1274
const r = spawnSync('ps', ['-Ao', 'pid=,ppid=,command='], { encoding: 'utf8', timeout: 10000 });
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 清理子代理记录
- 清除孤立投影缓存
- 清空会话
从 DeepSeek Harness 会话日志里删掉子代理记录又不弄坏日志,清掉孤立的投影缓存,还能整个清空会话——永远先 dry-run,永远留备份。
README
由 DeepSeek 最新模型翻译生成dsh-agent-clean
DSH(DeepSeek Harness)的子代理条目/会话/孤儿投影缓存清理工具。
零依赖:只用 Node.js 内置模块(node:zlib 的 zstd、node:fs、node:child_process)。
这个工具产生于一次真实事故:一个会话的子代理(subagent)入口卡住/损坏,删不掉。经反查 DSH 的会话日志格式与加载器源码,找到了不破坏日志的正确改法,做成命令行工具并附完整回归测试。
两半,任选其一。 命令行是独立的:它只对 DSH 的磁盘文件动手,由你在 DSH 之外用终端运行,什么都不用安装 —— git clone(第二节)或网页上的 Code → Download ZIP 即可。同一个包还带一个可选的 DSH 插件半:一条宿主路由 + 「设置 → 会话清理诊断」里的页面,告诉你该清什么、把命令复制给你,还带一个默认启用的开关:下次退出 DSH 时自动把无用子代理条目清掉(见第 2.2 小节)。装不装都行,不影响命令行。插件市场收录的是声明了 dsh 字段的 npm 包,所以本包一旦发到 npm 就可能出现在那里。
展开完整文档(README 剩余 1 节)
dsh-agent-clean
DSH(DeepSeek Harness)的子代理条目/会话/孤儿投影缓存清理工具。
零依赖:只用 Node.js 内置模块(node:zlib 的 zstd、node:fs、node:child_process)。
这个工具产生于一次真实事故:一个会话的子代理(subagent)入口卡住/损坏,删不掉。经反查 DSH 的会话日志格式与加载器源码,找到了不破坏日志的正确改法,做成命令行工具并附完整回归测试。
两半,任选其一。 命令行是独立的:它只对 DSH 的磁盘文件动手,由你在 DSH 之外用终端运行,什么都不用安装 —— git clone(第二节)或网页上的 Code → Download ZIP 即可。同一个包还带一个可选的 DSH 插件半:一条宿主路由 + 「设置 → 会话清理诊断」里的页面,告诉你该清什么、把命令复制给你,还带一个默认启用的开关:下次退出 DSH 时自动把无用子代理条目清掉(见第 2.2 小节)。装不装都行,不影响命令行。插件市场收录的是声明了 dsh 字段的 npm 包,所以本包一旦发到 npm 就可能出现在那里。
- 不删任何日志行、不改 seq(v4 格式要求 seq 稠密,删行会让整个会话报 format v4 event N is not dense)
- 只把「自己的」子代理目录行改成 subagent/catalog-dismissed + ignorable: true
- 顺手把投影缓存里的 subagentCatalog 改成合法空状态(DSH 的 dsh-chat-manager 删会话目录时不会清这个缓存,会留下孤儿)
- 每次写入前整份备份,可用 restore 逐字节还原
一、运行需求
| 项目 | 要求 |
| Node.js | ≥ 22(需要内置 zlib 的 zstd;脚本会在启动时检查并给出明确提示) |
| 系统 | Windows / macOS / Linux |
| DSH | 桌面版(可选但强烈建议,用于「真实加载器自检」);也可用 --modules 指向含 @deepseek-ai 的 node_modules |
DSH 根目录默认 ~/.dsh(Windows 为 C:\Users\<你>\.dsh),可用环境变量 DSH_HOME 覆盖。
里面的相关路径:
$DSH_HOME/sessions/<转义工作区名>/<session-id>/session.v4.jsonl.zstd ← 会话日志 $DSH_HOME/storages/session_projcache/sessions/<session-id>.json ← 投影缓存(子代理条目就在这里)
二、获取、安装与启动
git clone https://github.com/PolitaryMonicy/dsh-agent-clean.git
cd dsh-agent-clean
(也可在 GitHub 页面点 Code → Download ZIP 下载解压。)无需 npm install(没有任何第三方依赖)。三种启动方式,任选:
:: Windows:把整个目录放到任意位置,双击或在终端里用
clean.cmd list
macOS / Linux
chmod +x clean.sh
./clean.sh list
任何平台:直接调 node
node clean.mjs list
包装脚本会自己找 Node:%DSH_NODE% / $DSH_NODE → PATH 上的 node → 常见安装路径。
2.1 可选:DSH 插件半
同一个包也是一个 DSH 插件(声明了 dsh.bundle.patch 与 dsh.client),所以桌面版的插件管理器能装它:
dsh plugin --profile desktop add dsh-agent-clean # 从 npm
dsh plugin --profile desktop add github:PolitaryMonicy/dsh-agent-clean # 直接从 GitHub
dsh plugin --profile desktop add /本仓库/路径 # 本地检出
装完完全退出 DSH 再启动。设置 → 会话清理诊断里会多出一个页面(旧版本右下角那个 🧹 浮标已删除)。
这个页面扫描 $DSH_HOME(跑的就是 list + orphans 同一份代码),列出每个会话的子代理条目数、日志大小、缓存标题,以及孤儿投影缓存,并把 dismiss / purge / orphans 命令复制给你 —— 其中包括一条命令清掉所有会话的子代理条目。若页面报 宿主返回 HTTP 404,说明宿主半没加载:用 dsh --profile desktop --dump-config 看组合树里有没有这个条目,再看 %TEMP%\dsh-agent-clean-host.log 里的原因。
页面还带一个开关(见 2.2)。无论是页面还是开关,都不在 DSH 运行中碰会话存储:DSH 的契约不允许运行中改写已提交事件(seq 必须稠密、单写者),投影缓存也没有失效 API,所以运行中即便写盘成功,进程内存里仍是旧值。
真正改动会话的动作一律发生在 DSH 退出之后,走的就是你手敲 clean.mjs 的同一条管线(逐会话整份备份 → 结构自检 → 真实加载器复核)。
卸载:dsh plugin --profile desktop remove dsh-agent-clean。
2.2 退出时自动清理(默认启用)
既然清完也必须重启 DSH 才看得见效果,那干脆让插件在这个重启窗口里替你做掉。开关打开(默认)时,DSH 每次启动会:
1. 把开关写进本包状态目录的 auto-arm.json;
2. 启动一个脱离的助手进程(clean.mjs autowait --pid <本次 DSH 进程>)——它不随 DSH 退出而消失,只等那个 pid 消失。
等 DSH 真的退出后,助手就跑与 dismiss --all --apply 完全相同的管线(每个会话先整份备份 → 结构自检 → 真实加载器复核),处理所有还有子代理条目的会话,并把结果写进 auto-report.json(auto.log 留一小段历史)。
下次启动 DSH 时你就能在页面上看到结果。关掉开关不需要重启:还在等的助手会重新读一遍开关,看到 enabled: false 就原样退出;若那一刻还有第二个 DSH 实例在跑,助手不会跳过,而是继续等到真的没有任何 DSH 在跑为止(只有等到 72 小时上限才记一条「本次跳过」)。
想让它真的跑一次:把 DSH 完全退出(关窗口不算 —— 它可能会问你是否退到后台),等一两分钟让助手做完(页面上「上次自动清理」会刷新成这一次的结果),再打开。原因是清理一个会话要几十秒,而「关掉就马上重开」两次启动之间只有一两秒空档:助手要连续确认几轮才敢动手,一旦发现新实例已经起来就当场停手,把剩下的留给下一次。
别的方式也行:完全退出 DSH 之后,直接照第三节的命令手动跑一次。
开关为什么不放进 DSH 的 settings 服务:脱离的助手读不到另一个进程内存里的设置;而且本插件必须保持 零依赖(不 import @deepseek-ai/schemastery)才能在本地 link: 安装下继续工作。
想自己动手?把开关关掉,用页面里那几条命令 —— 它们做的事完全一样。
三、命令
| 命令 | 作用 |
| list [--workspace <片段>] | 列出各会话、标题、日志大小、自己的子代理条目数 |
| dismiss --session <id\|前缀> [--apply] | 去掉子代理条目(非破坏:保留全部行与 seq) |
| dismiss --all [--workspace <片段>] [--apply] | 对多个会话执行 |
| purge --session <id\|前缀> [--apply] | 彻底删除会话目录 + 全部 generation 日志 + 投影缓存(先整份备份) |
| orphans [--apply] | 列出/删除「会话目录已经不在、缓存还在」的孤儿缓存 |
| restore --backup <备份目录> | 从备份还原(dismiss/purge/orphans 的备份都认) |
| autowait --pid <DSH 进程号> | 等这个 DSH 进程退出,然后清掉所有还有子代理条目的会话(插件开关在启动时架设的就是它;它看 auto-arm.json 的脸色) |
| version / help | 版本/帮助 |
公共开关
| 开关 | 说明 |
| --apply | 不加=只试演(默认)。加=真正写入 |
| --force | 日志在最近 5 分钟内被写过时,必须显式加这个(防呆,避免削弱正在运行的会话) |
| --workspace <片段> | 只处理工作区名里含该片段的会话 |
| --no-verify | 跳过「找不到复核途径」这一关;真实加载器一旦报失败,仍会拒绝写入 |
| --no-app | 不使用桌面版,改用纯 Node + --modules |
| --app <exe> / --asar <app.asar> | 手动指定 DSH 应用 |
| --modules <node_modules> | 手动指定含 @deepseek-ai/* 的目录 |
退出码:0 成功(dismiss 后投影条目应为 0);1 出错(含真实加载器自检失败、参数错误);2 自检通过但条目数不为 0。
流程建议:先 list 看现状 → dismiss --session <前8位>(试演)看它要改什么 → 加 --apply → 完全退出并重启 DSH。
四、为什么必须这样做(机制)
v4 会话日志是 zstd 多帧拼接的 JSONL:第 0 行是 header(无 seq),其后每行一个事件,seq 必须 0,1,2,… 稠密。
DSH 客户端只读投影缓存里的 projectionsBySession[].values.subagentCatalog 来画子代理入口,没有「摘要回退」——所以只改日志不改缓存,界面上条目会照旧出现。
要让一个子代理条目消失,四个条件同时成立才行(都是实测出来的):
1. 改名:把该条目的 subagent/catalog 事件改成 subagent/catalog-dismissed,并加 ignorable: true(未知类型必须可忽略,否则加载器报错)。
2. header 一字不动:日志里 session-log-deepseek/delivery-accepted 的 data.sessionId 必须等于 header 的 id。只改 header 的 id 会得到: SessionFormatError: current-generation delivery marker names the wrong Session
3. 缓存改合法空状态:投影里 subagentCatalog 的值改成 {"inheritedEventCount": <继承数>}(不能写成 head.values: [],schema 会报 too_small)。
4. 必须完全重启 DSH:运行中的进程内存里还留着旧值。
另外两条实测约束(工具已处理):
- 不能删行:删行会让后面的 seq 不稠密 → format v4 event N is not dense(这是当初「删行方案」失败的原因)。
- 加载器还会校验 header.id 与日志路径推出的身份一致,所以「镜像上先跑一次真实加载器」时,镜像必须放在同名的转义工作区目录下;否则即使变换正确也会报 header id "…" and cwd identify "…"。
五、安全设计
- 默认试演,--apply 才写入;每次写入前把原文件整份复制到 backups/<ISO时间>_<命令>_<短id>/,并写 manifest.json(含原始路径),供 restore 使用。
- 写入前先在镜像上跑一次真实加载器(桌面版 Electron 当 node 跑 verify_loader.mjs),通过才动真文件;写入后再复核一次(盘上 + 真实加载器)。
- 重压日志帧时固定 ZSTD_c_checksumFlag = 1,与原格式一致。
- 写盘是原子的:改会话日志与写缓存都先写成同目录的 dsac-write.tmp,再 rename 覆盖目标。助手若在写盘中途被杀(关机、菜单「重启」的连带清理、任务管理器结束进程),盘上只会是「改前的完整版」或「改后的完整版」,不会留下半截日志;临时文件名刻意不含 session.v,免得被会话扫描(只认 session.v<数字>.jsonl(.zstd))当成一份代际日志。
- orphans 只动 storages/session_projcache/sessions/ 下的缓存文件,不碰会话目录。
- purge 会备份全部 generation 日志(session.v3/v4…)与缓存,然后删除会话目录;restore 会重建目录。
- 自动清理助手(2.2)只被架设、绝不在本进程里动手:它等 DSH 的 pid 消失,用「pid + 时间戳」的锁保证同时只有一个助手在跑(若那会儿确有另一个助手在收尾,本次助手最多等 3 分钟再决定,不会一见锁就白跑一轮)。若那一刻还有别的 DSH 实例在运行,它不放弃、继续等 —— 等到机器上真的没有任何 DSH 了再动手,只有等到 72 小时上限仍没等到才记一条「本次跳过」。判定「另一个实例」必须按命令行分角色:一个 DSH 实例同时有五六个同名进程(Electron 主进程、GPU、网络、渲染、host),工具 runner 与助手自己也是同一个 exe,只按镜像名数会把一个实例报成五个;所以只有主进程与 host 进程(会话存储的属主,也是被等的那个 pid)算实例,助手自己、被等的 pid、Electron 子进程与 runner 一律不算。
「零实例」还要连续确认 3 轮(≈4.5 秒)才动手:清理一次要几十秒,若中途新实例的 host 打开了会话存储,就正好撞上我们写盘。然后走与 dismiss --all --apply 一模一样的备份 → 镜像自检 → 真实加载器复核流程。开关在会话中途关掉也不需要杀进程:还在等的助手会重读 auto-arm.json 后原样退出;宿主进程重启过、而上一轮那个助手还在等同一个 pid 时不会再架第二个。若这一轮已经被更新的一轮接手(auto-armed.json 指向另一个被等的 pid、且它的助手还活着),旧助手会让位退出 —— 新一轮助手会在真正的退出窗口动手,清理的是同一批会话,不会漏活。
(实测教训:DSH 应用菜单里的「重启」是 app.relaunch(); quitWithoutConfirmation() —— 新实例先起来、旧实例后退出,两者重叠一两秒;旧版助手宽限 10 秒后看见新实例就跳过,于是每一次重启都跳过,一整轮退出窗口白丢。
这种重启链里根本不存在「没有实例」的空档,所以真正的清理只会发生在你完全关掉 DSH 的那一刻。)
- 动手之后每一步都留痕:say() 的输出对脱离进程是丢弃的(stdio=ignore),1.3.6 及以前「开始动手」与「完成」之间一行日志都没有 —— 助手若在这中间被杀,事后完全看不出它走到哪一步。1.3.7 起清理过程逐步写进 auto.log(开始动手+ 待处理会话数、每个会话的 id 与大小、每个会话的结果、完成汇总),设置页也把最后 8 行直接摆出来(「助手日志最后几行」)。
同一个版本还修了两处:①每处理一个会话前重判一次实例,一旦发现新实例已经起来就当场停手(已改的保留,报告标 aborted: "new-instance",剩下的留给下一次)—— 宁可不做,也不在别人可能已经打开的会话上继续写;②所有退出路径(让位、开关关掉、跳过、完成)都交还锁,不再把死锁留在盘上让下一个助手空等 3 分钟。
- 静默失败必须能被看见:宿主半每次架设助手都会把「谁在等谁」写进 auto-armed.json,助手等待期间每 60 秒把「最后活着的时刻」写进 auto-heartbeat.json;下次启动时如果发现那个助手已经不在了、却没有比架设时间更新的报告,设置页就会写明「上一轮退出窗口里的助手没留下任何报告」,并只在真的还有待清理条目时才标红(没有活可干时跳过这轮没有实际影响)。文案不再声称「在 X 之后就消失了」——那是架设时间,不是消失时间;有心跳时会写「最后一次心跳…,现已不在」。每个终局都会留一份报告:成功、超时、另一个实例在跑、开关关闭、抢不到锁,外加 1.3.4 新增的助手自身崩溃(helper-crash)与列会话失败(list-failed)——助手外壳挂了 uncaughtException / unhandledRejection,所以下一轮永远能分辨「它崩了(附错误原文)」和「它被连带杀了(心跳停在某刻)」。
(实测教训:手动架设的助手会随宿主工具的进程树一起被杀 —— 退出窗口里什么都没发生,盘上也没有痕迹。)
- 分叉会话(fork):这类日志前半段是父会话的继承区(identity.inheritedEventCount),里面可能也有父会话的 subagent/catalog 行。它们不归本会话,清理时逐字节保留,自检也不能把它们算作「剩余 catalog」——否则只要日志里有继承来的 catalog 行就会恒判自检失败、一个分叉会话也清不掉。清理后投影缓存写成 {"inheritedEventCount":N}(不继承父会话的目录,父会话自己那份照旧)。
六、怎么证明它是对的
- 自带回归测试(不碰真实数据):node test/selftest.mjs → 57/57 通过(假 DSH_HOME,覆盖 list/orphans/purge+restore/dismiss 安全闸/离线变换/restore 回滚,自动清理的「是不是还有另一个 DSH 实例」判定——它不能把助手自己算进去、也不能把 GPU/渲染子进程与工具 runner 算成实例,也不能把「本实例主进程还没退完」说成「另一个实例」,分叉会话:继承区里的 catalog 行必须逐字节保留、自己那几条必须改掉、缓存写成带 fence 的空状态,「上一轮助手没跑完就不能静默」的判定,助手心跳只在属于那个助手时才被采信,重启链里的让位规则:只有更新的一轮的助手还活着时旧助手才让位,新助手已经不在了就留下来当备胎,写盘原子性:字节原样落盘、不留临时文件、dismiss 之后会话目录里也没有残留,以及退出前交还锁:自己的锁删掉、别人的锁一律不动);带真实日志 fixture 时 63/63 通过(见下条)。
- 两半插件各自的离线探针(不启动 DSH、不碰会话存储):
- npm run probe:client → VERDICT A=PASS B=PASS C=PASS:伪造 window.__ModuleLoader__ 与极简 React,证明设置页座位只注册一次、slots 服务迟到时靠 internal/service 补挂且幂等、宿主没有 slots 时也不抛。
- npm run probe:host → VERDICT PASS:用假请求驱动宿主半的两条路由 —— 栅栏 403/405、scan 返回体形状、POST /settings 的全部分支(坏体、无可写字段、关、开、不重复架设)。它会先备份再还原 auto-arm.json,并以 DSAC_ARM_DRYRUN=1 干跑,不开真进程、不跑任何清理。
- 自动清理助手实跑:开关关闭时 clean.mjs autowait 打印「开关关闭,未做任何改动。」(exit 0);被等的 pid 一直不消失时写出 {"ran":false,"why":"timeout",…} 到 auto-report.json —— 两次都没碰任何会话日志。1.3.7 的端到端实跑(假 DSH_HOME + 假状态目录,拿真实日志当素材、--no-app 跳过真实加载器):助手把 11443 行 / 12,622,844 B 的会话里 22 条 catalog 全部改写(catalog 0 / dismissed 22,行数不变),auto.log 留下「开始动手,待处理 1 个会话 → 处理第 1/1 个会话 …(12327 KB)→ 改写 22 条 → 完成,处理 1,改写 1,失败 0」,报告 processed:1, cleaned:1,退出码 0,auto.lock 不残留。
- 真实日志逐字节一致:用一份真实会话日志(11443 行 / 12,622,844 B)跑 node test/selftest.mjs --fixture <日志> --expect-sha256 B51E6D96F3B4CF922282ECA1BBD11BE175EB9D64EAC676F37F746DAB619C3EBA → 产物 sha256 与人工验证过的修复结果完全相同。
- 完整端到端(真实桌面版 + 假 home):dismiss 后 12,622,844 → 12,624,094 B(sha B51E6D96…),镜像与实时两处真实加载器均 OK 投影条目=0,缓存 117,693 → 111,544 B;restore 后回到 12,622,844 B(sha 2140EFC1…)与原始缓存,逐字节相同。
- 语法检查:node --check clean.mjs。
七、注意
- 改完必须完全退出并重启 DSH,否则界面上看不到效果。
- 不要把备份目录放进 $DSH_HOME/sessions/ 里(会被当成会话目录)。
- 想少踩这个坑:少派长命的 continuable 子代理,批量任务优先用 workflow。
- DSH 升级后会话格式可能变化,届时请重新核对本文的「机制」一节。
八、许可
MIT,见 LICENSE。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
PolitaryMonicy/dsh-agent-clean
DSHDeepSeek Harness的子代理条目/会话/孤儿投影缓存清理工具。
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,489已汉化DSH
73.1
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,918已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,453已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
Download DS Bot for Windows 10/11 64-bit / 下载 Windows…
★ 5,293已汉化DSH
71.2
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,797已汉化DSH
71.1
这是你的仓库?认领条目