SherlockGougou
dsh-plugins-fix
DSH 的插件(cordis.patch.yml 补丁层中的条目)一旦配置损坏、插件包缺失或初始化崩溃,会导致 DSH 无法启动。dsh-fix 是一个独立于 DSH 运行的命令行工具:诊断问题、一键进入安全模式、精准禁用元凶插件、二分定位故障源,并且所有操作都可回滚。
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 15, 2026
- Updated
- Aug 15, 2026
Introduction
dsh-fix
独立的 DSH(DeepSeek Harness)插件故障诊断与修复工具 —— 不依赖 DSH,也不需要任何 npm 依赖。
DSH 的插件(cordis.patch.yml 补丁层中的条目)一旦配置损坏、插件包缺失或初始化崩溃,会导致 DSH 无法启动。dsh-fix 是一个独立于 DSH 运行的命令行工具:诊断问题、一键进入安全模式、精准禁用元凶插件、二分定位故障源,并且所有操作都可回滚。
- 零依赖:纯 Node.js 标准库 + 内置(vendor)的 js-yaml,无
node_modules - 跨平台:Windows / macOS / Linux 通用(DSH 用户必然有 Node ≥ 18)
- 非破坏性:每次修改前自动备份,
restore一键回滚 - 双语输出:自动跟随系统语言(zh / en),可用
--lang指定
何时使用
DSH 出现以下情况时使用:
- 启动即失败,报错形如
plugin(s) failed to load/failed to parse patches/ 补丁解析失败 - 刚安装/更新了插件后 DSH 无法启动
- 启动失败但不确定是哪个插件引起的
快速开始
不需要安装任何东西,下载本仓库后直接运行:
# 方式一:直接运行(不需要安装)
git clone https://github.com/SherlockGougou/dsh-plugins-fix.git
cd dsh-plugins-fix
node bin/dsh-fix.mjs doctor
# 方式二:全局安装(提供 dsh-fix 命令)
npm install -g dsh-fix
dsh-fix doctor
# 方式三:临时使用(不安装)
npx dsh-fix doctor
默认操作
$DSH_HOME(未设置时是~/.dsh),可用--home <path>指定其他位置。
典型故障处理流程
1. 诊断
dsh-fix doctor
只读检查:补丁文件语法(与 DSH 完全一致的 YAML 方言,支持 !!js 表达式)、条目结构、插件包是否已安装(模拟 Node 模块解析)、重复 id、损坏的 node_modules 符号链接、依赖缺失等。发现错误时退出码为 1。
输出采用 flutter doctor 风格:每个检查项一行 [✓] / [!] / [✗] 状态标记,问题明细缩进显示,结尾是汇总与处理建议:
Doctor summary (to see all details, run dsh-fix doctor -v):
[✓] DSH home: ~/.dsh
[✓] Home patch layer: absent (optional)
[✗] profile web (1 entry)
✗ plugin "plugin-nowhere" (entry "alpha") is NOT installed: not found. ...
! profile web lists dependency "plugin-c"@^1.0.0 ...
1 error, 1 warning, 0 notes across 1 profile and 1 plugin entry.
✗ Doctor found issues: 1 error, 1 warning.
Tip: run "dsh-fix safe" ...
dsh-fix doctor -v(或 --verbose)会追加逐项检查清单——package.json、node_modules、补丁条目数量、每个插件的模块解析结果,以及 info 级提示(默认隐藏)。
2. 一键安全模式 —— 先让 DSH 跑起来
dsh-fix safe
把所有用户插件条目(含 id 定向补丁的目标)追加 disabled: true 禁用补丁,DSH 即可用内置功能正常启动。禁用补丁带 # dsh-fix: 标记,随时可撤销。
3. 二分定位元凶
dsh-fix bisect
交互式二分:每轮禁用一半候选插件,你启动一次 DSH 回答 y/n,通常几轮内锁定元凶。锁定的插件保持禁用,其余自动恢复。
4. 精确控制与回滚
dsh-fix list # 列出各 profile 的插件条目
dsh-fix disable <id> # 禁用指定插件
dsh-fix enable <id> # 恢复被 dsh-fix 禁用的插件
dsh-fix clear # 移除全部 dsh-fix 禁用块(整体回滚 safe/bisect)
dsh-fix backups # 列出备份
dsh-fix restore [序号] # 从备份恢复(默认最新)
命令一览
| 命令 | 说明 | 是否修改文件 |
|---|---|---|
doctor | 只读诊断,输出错误/警告/提示与退出码 | 否 |
list | 列出各 profile 的插件条目与缺失依赖 | 否 |
safe | 安全模式:禁用全部用户插件条目 | 是(自动备份) |
disable <id> | 禁用单个插件条目 | 是(自动备份) |
enable <id> | 恢复被 dsh-fix 禁用的条目 | 是(自动备份) |
clear | 移除所有 dsh-fix 禁用块 | 是(自动备份) |
restore [序号] | 从备份恢复补丁文件 | 是(自动备份) |
backups | 列出补丁文件备份 | 否 |
bisect | 交互式二分定位故障插件 | 是(自动备份) |
version / help | 版本 / 帮助 | 否 |
通用选项:--home <path>、--profile <name>、--lang zh|en、--json(doctor/list 输出 JSON,便于脚本化)、-v(doctor 逐项详细输出)。
工作原理
DSH 的每个 profile($DSH_HOME/profiles/<name>/)是一个 Cordis 组合:启动时按顺序应用各 bundle 补丁层,然后是用户补丁层 cordis.patch.yml(顶层 YAML 数组),最后是命令行覆盖层。用户安装的插件就是补丁里的 - insert: 条目,配合 profile 的 package.json 依赖安装 npm 包。
启动失败的三类根因(dsh-fix doctor 全覆盖):
- 补丁文件语法/结构错误 —— 解析失败时 DSH 直接拒绝启动(
failed to parse patches) - 插件包未安装或损坏 —— loader 无法解析
name模块(plugin(s) failed to load) - 插件初始化崩溃 —— 代码抛错或依赖的 Service 不存在
dsh-fix 的修复手段只有一种:在补丁文件末尾追加带标记的禁用补丁:
# dsh-fix: disabled entry "mcp-figma" at 2026-08-15T00:44:49.804Z
- id: "mcp-figma"
disabled: true
这正是 DSH 官方补丁语义(后置补丁可作用于同层先前的条目),所以:
- 不删除、不改写任何原始内容,
enable可逐字节还原 - 每次写入前自动生成
cordis.patch.yml.bak-<时间戳>快照(与 DSH 自身的备份命名一致),restore可回滚到任意备份(最多保留 10 份) - 与 DSH 的 YAML 解析完全一致(js-yaml JSON_SCHEMA +
!!js标签),诊断即启动时所见
跨平台说明
- 需要 Node.js ≥ 18(DSH 本身要求 ≥ 22,所以所有 DSH 用户都满足)
- Windows 下在 CMD / PowerShell 中运行:
node bin\dsh-fix.mjs doctor - 路径、换行符(CRLF/LF)均已处理;
bisect支持交互终端与管道输入 - CI 在 Ubuntu / Windows / macOS 三平台自动跑完整测试(见
.github/workflows/ci.yml)
开发与测试
npm test # node:test 测试套件
npm run check # 语法检查
测试覆盖:YAML 方言、条目校验、模块解析模拟、禁用/恢复/安全模式/二分/备份/回滚、CLI 行为与退出码。
常见问题
Q: doctor 报 @deepseek-ai/* 插件无法解析?
DSH 内置插件从安装目录解析,dsh-fix 看不到安装目录,所以这类报错是警告级。若该包确实未安装,提示同样适用。
Q: 修改前需要关闭 DSH 吗? 建议关闭。DSH 的热重载会监听补丁文件,修改时若 DSH 在运行可能触发重载。
Q: 支持 DSH_HOME 自定义位置吗?
支持,--home 或环境变量 $DSH_HOME 均可。
License
MIT · js-yaml (vendored) 同样为 MIT 协议,见 vendor/LICENSE.js-yaml