??????,????????????????,???????????????????
安装
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:limochaishang/crash-guard-dsh
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
DeepSeek Harness / PawWork 插件崩溃保护插件:当某个插件导致启动崩溃或卡死时,自动隔离该插件,避免反复崩溃(crash loop)。
功能特性
- 崩溃自动隔离:加载期崩溃后,下次启动自动禁用导致崩溃的插件
- 卡死自动恢复:独立看门狗进程检测完全卡死(hang),自动杀进程、禁用可疑插件、重启
- 三层自愈架构:同进程监控 → 独立看门狗 → 手动恢复,层层兜底
- 零配置:安装即用,无需额外配置
- 安全护栏:不误伤正常插件、不隔离自身和核心包、防重入误判
工作原理
三层自愈架构
┌─────────────────────────────────────────────────┐
│ 第一层:同进程监控(index.mjs) │
│ - 每 50ms 跟踪正在加载的插件 │
│ - 15 秒 hang 超时检测 │
│ - 状态机:booting → ready → clean │
│ - 崩溃后下次启动自动隔离 │
├─────────────────────────────────────────────────┤
│ 第二层:独立看门狗(watchdog.mjs) │
│ - detached 独立进程,不加载任何插件 │
│ - 每 5 秒检查心跳文件 │
│ - 30 秒无心跳判定完全卡死 │
│ - 自动:禁用可疑插件 → 杀进程 → 重启 │
├─────────────────────────────────────────────────┤
│ 第三层:手动恢复 │
│ - 删除 cordis.patch.yml 中的禁用条目 │
│ - 重启即可恢复 │
└─────────────────────────────────────────────────┘
崩溃检测流程
类似 Chrome 扩展的安全启动(safe mode):
| 阶段 | 动作 |
|---|---|
| 每次启动 | crash-guard 作为 profile bundles 第一位加载,最先执行 apply |
| 启动中 | 每 50ms 跟踪正在加载的插件,同步写盘记录 lastLoading |
| 加载完成 | 状态标记 ready;正常退出标记 clean |
| 检测崩溃 | 下次启动发现上次状态停在 booting(没走完也没正常退出)→ 判定加载期崩溃 |
| 自动隔离 | 把崩溃前正在加载的那个插件写进用户层 cordis.patch.yml(disabled: true),不再加载 |
独立看门狗机制
同进程监控有一个根本局限:如果插件导致完全阻塞事件循环(如无限循环、同步阻塞),crash-guard 自身的 50ms 轮询也会被冻住,无法检测卡死。
独立看门狗解决这个问题:
- crash-guard 启动时用
child_process.spawn启动watchdog.mjs(detached: true) - 主进程每 2 秒写心跳文件
heartbeat.json - 看门狗每 5 秒检查心跳文件的修改时间
- 超过 30 秒没更新 → 判定完全卡死
- 自动执行:禁用可疑插件 → 杀掉所有 PawWork 进程(排除自己)→ 重启 PawWork
安全护栏(不误伤)
- 只处理加载期崩溃/卡死:运行期崩溃/强杀只记日志不自动禁用——无法可靠归因
- 永不隔离 guard 自身和核心包:
id: crash-guard和@deepseek-ai/*永远不会被禁用 - 每次只禁一个:每次崩溃只禁用最后一个被跟踪的插件,其余保持原样
- 防重入锁:模块顶层全局锁,live-reload 热重载时清理上一个实例,避免残留积累
- 新鲜度校验:60 秒状态文件新鲜度窗口 + 进程标记双重保险,防 live-reload 误判
- 看门狗锁文件:防止多个看门狗实例同时运行
文件布局
crash-guard-dsh/
├── index.mjs # 插件主体(崩溃检测 + hang 检测 + 看门狗启动 + 心跳写入)
├── watchdog.mjs # 独立看门狗进程(detached,监控心跳、自动恢复)
├── cordis.patch.yml # bundle 补丁:以第一位插入 crash-guard 条目
├── package.json # 插件声明
├── install.ps1 # Windows 安装脚本
├── uninstall.ps1 # Windows 卸载脚本
├── README.md # 本文档
├── LICENSE # MIT 许可证
└── test/
├── simulate.mjs # 崩溃恢复流程模拟测试
└── verify-install.mjs # 安装验证测试
运行时状态目录(默认):
- 状态:
$DSH_HOME/crash-guard/state.json - 心跳:
$DSH_HOME/crash-guard/heartbeat.json - 看门狗锁:
$DSH_HOME/crash-guard/watchdog.lock - 看门狗日志:
$DSH_HOME/crash-guard/watchdog.log - 隔离日志:
$DSH_HOME/crash-guard/quarantine.log(JSONL,含每次禁用记录)
$DSH_HOME默认为~/.pawwork/dsh,可用DSH_HOME环境变量覆盖。
安装
前置要求
- DeepSeek Harness / PawWork 已安装
- Node.js 18+(DSH 自带运行时即可)
Windows(PowerShell)
# 克隆或下载本仓库
git clone https://github.com/limochaishang/crash-guard-dsh.git
cd crash-guard-dsh
# 运行安装脚本
.\install.ps1
脚本会:
- 复制
crash-guard-dsh到目标 profile 的node_modules/ - 把
crash-guard-dsh插入目标 profilepackage.json的dsh.profile.bundles第一位 - 加入
dependencies - 备份被修改的文件为
.crash-guard.bak
安装后重启 DSH / PawWork 生效。
手动安装
- 复制本目录到 profile 的
node_modules/crash-guard-dsh/ - 在 profile 的
package.json中,把crash-guard-dsh加入dsh.profile.bundles第一位 - 加入
dependencies - 重启 DSH / PawWork
卸载
.\uninstall.ps1
从 bundles / dependencies 移除并删除 node_modules 里的包目录;state.json、heartbeat.json、quarantine.log 会保留(可选删除)。
使用方法
安装后无需任何操作,crash-guard 自动工作:
- 正常启动:crash-guard 跟踪加载过程,记录状态,启动完成后进入 ready 状态
- 插件崩溃:下次启动自动隔离导致崩溃的插件,PawWork 可以正常启动
- 插件卡死:看门狗检测到无心跳,自动杀进程、禁用可疑插件、重启
- 查看日志:检查
$DSH_HOME/crash-guard/quarantine.log查看被禁用的插件记录
手动恢复被禁用的插件
崩溃/卡死后 crash-guard 会在用户层 cordis.patch.yml(如 profiles/web/cordis.patch.yml)追加类似内容:
# [crash-guard] 自动禁用:插件 "xxx" (yyy) 在最近一次启动时导致崩溃。
# 如需恢复,删除下面两行即可。
- id: yyy
disabled: true
删除这两行并重启即可重新启用该插件。
配置选项
crash-guard 零配置即可使用。如需自定义,可通过 patch 配置以下参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
stateDir |
$DSH_HOME/crash-guard |
状态文件目录 |
patchFile |
profile 下的 cordis.patch.yml |
禁用插件写入的补丁文件 |
freshWindowMs |
60000 | 状态文件新鲜度窗口(毫秒) |
readyTimeoutMs |
30000 | 启动超时时间(毫秒) |
hangTimeoutMs |
15000 | 单插件加载 hang 超时(毫秒) |
heartbeatIntervalMs |
2000 | 心跳写入间隔(毫秒) |
watchdogCheckIntervalMs |
5000 | 看门狗检查间隔(毫秒) |
watchdogTimeoutMs |
30000 | 看门狗心跳超时(毫秒) |
测试
模拟崩溃测试
node test/simulate.mjs
测试覆盖:
- 正常启动 → clean 状态
- 崩溃残留 → 下次自动禁用
- 幂等不重复禁用
真实环境测试
- 安装一个会导致崩溃的插件(如已知不兼容的插件)
- 重启 PawWork,观察是否崩溃
- 再次重启,观察 crash-guard 是否自动隔离该插件
- 检查
quarantine.log确认禁用记录
看门狗测试
- 安装一个会导致完全卡死的插件(如无限循环、同步阻塞)
- 重启 PawWork,观察是否卡死
- 等待约 30 秒,观察看门狗是否自动杀进程、禁用插件、重启
- 检查
watchdog.log确认看门狗动作记录
常见问题(FAQ)
Q: crash-guard 会影响正常插件的加载吗?
A: 不会。crash-guard 只在启动时跟踪加载过程,不修改其他插件的代码或配置。正常启动后,crash-guard 进入 ready 状态,不再干预。
Q: 为什么是"下次启动"才生效?
A: 崩溃发生在加载过程中,guard 自身来不及写禁用指令;只有等下一次启动、由 guard 首先执行检测并落盘禁用,才能阻止坏插件再次加载。这与 Chrome 安全启动的设计一致。
Q: 看门狗会不会误杀正常进程?
A: 概率极低。看门狗只在心跳超过 30 秒没更新时才触发,而正常运行时主进程每 2 秒写一次心跳。只有完全卡死(事件循环被阻塞)才会导致心跳停止。
Q: 两个进程(主进程 + 看门狗)会不会都崩溃?
A: 理论上可能但概率极低。看门狗代码极简(约 100 行),不加载任何插件,不依赖 DSH 运行时,作为 detached 独立进程运行。主要风险来自系统级故障(如操作系统崩溃、断电)。
Q: 归因不准确怎么办?
A: 当前归因是启发式的——记录崩溃前正在加载的插件。在某些情况下(如插件 A 阻塞导致 loader 认为插件 B 还在加载),可能归因到错误的插件。这是已知局限,已列为未来工作方向。如果发现误禁,手动删除 cordis.patch.yml 中的禁用条目即可恢复。
Q: crash-guard 自身崩溃了怎么办?
A: crash-guard 有防重入锁和异常处理。如果 crash-guard 自身崩溃,它不会写入崩溃状态(因为还没完成 booting→ready 的转换),下次启动会重新尝试。crash-guard 代码经过严格测试,自身崩溃概率极低。
局限性
- 崩溃发生在 crash-guard 加载之前(如 base bundle 自身问题)时无法归因——设计边界,与主流 safe-mode 一致
- 只针对「加载期崩溃/卡死」;运行期崩溃不自动禁用
- 归因是启发式的,极端情况下可能不准确
- 本插件不参与 UI,无配置项(如需自定义可通过 patch 配置)
未来工作
- 精确归因:通过插件加载时序分析更准确地定位崩溃元凶
- 三层监控架构:同进程 → 独立看门狗 → 操作系统级服务监控
- 崩溃报告:收集崩溃堆栈,生成更详细的诊断报告
- 插件兼容性评分:基于历史崩溃数据评估插件稳定性
- 批量测试工具:自动化测试插件市场中插件的兼容性
贡献
欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
许可证
本项目采用 MIT 许可证 开源。
致谢
- DeepSeek Harness 团队提供的插件架构
- Chrome 扩展安全启动机制的设计灵感
- 所有贡献者和用户的反馈
如果你觉得这个插件有用,欢迎给个 Star ⭐
链接
同类插件
yjh051108/dsh-routing-suite★ 7176
一个仓库三件套:DSH 插件包的运行时注入器(注入、热重载、卸载、开发侧挂区一键转正、路由自愈,外带设置页插件管理:列出、卸载、拖入文件夹内化)、任务感知的思维模式路由 agent 预设(router-standard / router-spec / router-react)、以及分级两级任务协议(commit_star / lock_stage / revise_do / edit_plan / mark_task / redteam_verdict 六个工具,任务状态落盘)。注入器实现直接在库内,安装的是它自己的行为而不是一份依赖清单。
strukto-ai/mirage#dsh★ 3626
把文件系统与 bash 提供者换成 mirage 虚拟工作区:文件工具与 shell 命令作用于挂载的资源(RAM、S3、Redis、Slack、Gmail、Notion、Postgres)而非宿主磁盘,支持按挂载点设置读/写/执行模式、按命令选择沙箱(进程内 monty、pyodide、quickjs;远程 docker、e2b、daytona),并可在虚拟终端中安装 CLI(git、gh、slack、linear、ntn、gws,或自行注册的程序树)作为命令头词。
hust-open-atom-club/oh-dsh★ 312
社区发行版:TUI、桌面端与 Web UI 统一体验,分层安装、一步到位。
lire1131/dsh-undo-savepoint★ 154
DSH 撤销/回退系统:配置变更自动存档,一键撤销/恢复/回退到任意版本,支持 WebUI 与离线 CLI/GUI 工具(DSH 启动失败也能救)。
Fishquito7/dsh-skill-mcp-panel★ 124
在 DSH Web 设置中管理技能与 MCP 服务器:技能卡片热启停、工作区作用域、分组、批量迁移与拖拽导入,以及 stdio/HTTP MCP 增删改查、连接测试、密钥脱敏,并附带统一 dsh-panel 命令行。
kanneiren/dsh-network-settings★ 109
可视化 DSH 进程在 Windows 或 WSL 上的网络链路(DNS/TCP/TLS/HTTP 分层探测),检测失效的代理配置,并提供带快照回滚的安全修复。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。