# shell-patch · 修掉桌面外壳「任务一开始就弹完成通知」 这个目录解决的是**桌面外壳**的问题,和邮件插件本身无关:它的"任务完成"通知有 85% 是误报。 ## 问题是什么 外壳 `main.js` 里的 `injectTaskCompletionBridge()` 会往页面注入一段脚本,扫描左侧会话列表的 DOM, 用「稳定 id + **标题** + 同名序号」当 key 建一张状态表。这就埋了两个雷: 1. **标题一变,key 就变**。会话标题是在回合开始后一两秒才生成的,于是"运行中"的那条旧 key 从表里消失, 而它消失前的状态是 running —— 被当成"任务完成",弹出通知。用户看到的现象就是"任务一开始就通知我"。 2. **侧栏整块不可见时(比如打开了设置页)一行都扫不到**,代码会把"扫不到"推断成"正在跑的任务都结束了", 于是一次性弹好几条假通知。 量化证据:`node tools/analyze-desktop-notifications.mjs` 把外壳日志(每条通知)和会话日志 (每个回合的 `turn/start` / `turn/end`)按时间对齐,结果是 **191 条通知里 163 条(85%)发生在回合还没结束的时候**, 不少就在回合开始后 0.1~3 秒。 ## 修了什么 把那段注入脚本换成「**只按稳定行标识建键**」的版本(标题只用于显示),并给"行消失"分支加两道保险: | 保险 | 作用 | | --- | --- | | 一行都扫不到时直接跳出 | 侧栏被卸载/切换页面时不再误判 | | 元素仍在文档里 → 只当作"换了 key" | 重渲染、换 id 不再误判 | | 元素真消失也要跑够 4 秒才算结束 | 刚开几秒就消失的多半是列表重排 | 行为自检(`node shell-patch/test-completion-bridge.mjs`)把原版与修补版放进同一个假 DOM 里对照, 7 个场景全过,其中包括:**同一场景下原版误报、修补版不报**,以及**真完成两版都照常报**。 ## 怎么用 **先完全退出 DSH**(脚本会检查,检测到 `DeepSeekHarness.exe` 在运行会直接拒绝,避免写坏程序)。 ```bash node shell-patch/patch-completion-notify.mjs --dry # 先看看能不能打(不写盘) node shell-patch/patch-completion-notify.mjs # 打补丁 node shell-patch/patch-completion-notify.mjs --revert # 撤销 ``` Windows 上双击 `修复桌面误报通知.cmd` 也行(它先打补丁,再让你确认结果)。 `app.asar` 的位置会自动找:先看常见安装目录,再从注册表的卸载项里推断(不写死任何路径)。 找不到就用 `--asar "D:\...\resources\app.asar"` 指定。 > 在仓库根目录执行 `node scripts/update-all.mjs` 可以**一次做完**"同步插件 + 打这个补丁"两件事 > (双击 `更新并修复.cmd` 亦可)。 ## 安全措施 - **拒绝在 DSH 运行时动手**:`app.asar` 被占用,硬写会写坏程序。 更关键的是**连"查不出进程"也拒绝**(fail-closed)——`spawnSync` 遇到权限拒绝不会抛异常, 若把"查不到"当成"没在运行",就会去写一个被占用的文件。确实已确认退出但查询被拒时, 用 `--force` 显式跳过这一步。 - **三重校验**:整份 `main.js` 通过语法检查、注入的那段脚本单独通过语法检查、 重新打包后**除 `main.js` 外每个文件与原文件逐字节一致** —— 任何一项不过就不替换。 - **写完读回核对**:读回来与预期不一致就自动用备份还原并报错;写入失败(文件被占用)时 原文件保持不动并给出明确提示。 - **一个固定名字的备份**:原文件备份成同目录的 `app.asar.bak`(已存在则不动)。 - **可逆**:补丁是精确的文本替换,`--revert` 不依赖备份就能还原; 实测"打补丁 → 撤销"后整个 `app.asar` 的 SHA256 与原文件**完全相同**。 - **失败即不动手**:DSH 更新后 `main.js` 结构若变了,脚本会明确报错并保持原样, 不会写入半个补丁。 ## 注意 DSH 桌面程序**自动更新会覆盖 `app.asar`**,补丁随之消失 —— 届时重跑一次本脚本即可 (备份与撤销都不受影响)。修好后可以再用 `tools/analyze-desktop-notifications.mjs` 看新通知的误报比例是否归零。 ## 文件 | 文件 | 作用 | | --- | --- | | `patch-completion-notify.mjs` | 打补丁/撤销(含自带的 asar 读写、三重校验与读回核对) | | `bridge-snippets.mjs` | 原版与修补版两段函数文本(补丁与自检共用一份) | | `dsh-process.mjs` | "DSH 是否在运行"的三态查询(供补丁与一键更新共用,fail-closed) | | `test-completion-bridge.mjs` | 假 DOM 行为自检(原版 vs 修补版对照) | | `修复桌面误报通知.cmd` | Windows 双击入口 |