dsh-boot-failsafe v2
> Boot failsafe for the DeepSeek Harness web GUI — pure client, zero disk writes, zero host logic, passive. If a client plugin crashes while loading (template defects like exports is not defined / received object, or any factory throw), it is skipped with a visible banner instead of breaking the UI; missing-bundle 404s are reported, not auto-"fixed". You can always get in, even when a plugin is broken. > > WebUI 加载容错(对抗审查修订版)。纯 client、零磁盘写入、零 host 逻辑、被动响应——坏插件加载失败时自动跳过 + 横幅提示,绝不破坏页面与服务端。
---
English
Safety contract (v2 hard rules)
- ❌ No disk writes of any kind (node_modules / patch / anything)
- ❌ No server routes, no loader service access, no manifest modification
- ❌ No probing, no "is it uninstalled" guessing
- ✅ The only persistence is browser localStorage
- Worst possible outcome: a plugin is skipped (recoverable). The server is never touched.
> History (v0.1): a host-side auto-patch that wrote no-op packages into profile node_modules once misclassified 128 official packages → crash loop (NRestarts=65) → 502. v2's host half is explicitly a no-op.
Capabilities
1. Factory failsafe: wraps window.__ModuleLoader__.load — installed at module top level (during the arrive phase, long before the host EntryTree imports plugins; polls ≤30s if __ModuleLoader__ is not ready). A factory that throws or does not return apply is replaced with a no-op placeholder and listed in a banner (plugin name + reason + disable button). The wrapper itself is fully try/catch-guarded — it can never break the registration chain. - Honest note: ordering is best-effort (script phase ≪ import phase), not a hard guarantee. 2. Missing-bundle reporting: strict 404 detection — error event (capture) + SCRIPT target + /plugins/ src + id resolved from the boot manifest (read-only). Reports only, never auto-fixes. 3. Blacklist (localStorage dsh.bootFailsafe.blocked.v2): - Entries are {id, rev}; when the manifest rev changes the entry auto-clears (the plugin may have been fixed) - Self-protection: refuses to disable dsh-boot-failsafe itself or @deepseek-ai/dsh-client-modules - "全部解除" escape-hatch button clears the whole blacklist - After fixing a plugin: refresh the page to restore (fresh loadCache, no stale no-op)
Coverage boundaries (honest)
| Scenario | Behavior |
|---|---|
Factory template defect (no apply / factory throw) | ✅ skipped + banner + disable |
Top-level transpile error (exports is not defined at module top) | ⚠️ script-error path: banner + manifest id lookup, not skipped |
| Bundle 404 (uninstalled, not restarted) | ⚠️ reported only ("refresh / restart the service") |
Runtime apply half-crash | ❌ not covered (runtime error) |
Install
dsh plugin --profile web add github:fengs2021/dsh-boot-failsafe
systemctl restart dsh-web # or hot-mount via dev tools (no restart)Hard-refresh the page afterwards (the browser must load the new client bundle).
中文
安全契约(v2 铁律)
- ❌ 不写任何磁盘文件(node_modules / patch / 任何路径)
- ❌ 不注册服务端路由、不访问 loader 服务、不修改
__DSH_BOOT__ - ❌ 不探测、不判定「已卸载」
- ✅ 唯一持久状态 = 浏览器 localStorage
- 最坏结果 = 某个插件被跳过(可恢复);服务端零影响
> 历史教训(v0.1):host 半自动补写 no-op 包曾把 128 个官方包误判替换成占位 → crash loop(NRestarts=65)→ 502。v2 host 半显式为 no-op。
能力
1. factory 容错:包装 window.__ModuleLoader__.load(模块顶层安装,早于 EntryTree import 阶段;__ModuleLoader__ 未就绪则 ≤30s 轮询等待)。factory 抛错 / 未返回 apply → no-op 占位 + 横幅(插件名+原因+禁用按钮)。包装自身异常全兜底回退原始 load,绝不破坏注册链。 - 诚实声明:时序为尽力而为(script 阶段远早于 import 阶段),非硬保证。 2. 资源缺失提示:严格 404 检测——error 事件(capture)+ SCRIPT target + /plugins/ 前缀 + manifest(只读)id 反查。只提示不自动修。 3. 黑名单(localStorage dsh.bootFailsafe.blocked.v2): - 条目 {id, rev};manifest rev 变化 → 自动解除(可能已修复) - 自我保护:禁止禁用 dsh-boot-failsafe 自身与 @deepseek-ai/dsh-client-modules - 横幅「全部解除」逃生按钮 - 修复插件后:刷新页面即可恢复(loadCache 全新,无残留 no-op)
覆盖边界(诚实)
| 场景 | 行为 |
|---|---|
| factory 模板缺陷(未返回 apply / factory throw) | ✅ 跳过 + 横幅 + 禁用 |
顶层转译错误(exports is not defined 在模块顶层) | ⚠️ script-error 路径:横幅提示 + manifest 反查 id,不跳过 |
| bundle 404(已卸载未重启) | ⚠️ 只提示「刷新/重启」,不自动修 |
| apply 运行期半崩 | ❌ 不覆盖(运行时错误) |
安装
dsh plugin --profile web add github:fengs2021/dsh-boot-failsafe
systemctl restart dsh-web # 或 dev 工具热装配(免重启)安装后硬刷新页面(浏览器需加载新版 client bundle)。
License
MIT