前言¶
在 DeepSeek Harness(DSH)里装插件,常见信号只有「装上了」:市场能搜到、profile 里 bundle 列上了、进程也起来了。真正麻烦的是三类静默故障——不报错、不打日志,功能却像没装过;或者装第二个插件后整段能力消失;又或者明明在 patch 里关了某插件,行为却还在。现有手段很难把「谁和谁撞了、该改哪一行」说清楚。
下面介绍社区插件 dsh-conflict-doctor(维护者 ven314,分类:工作流)。它把运行期 Loader 图谱与磁盘上的 patch 层对齐,输出带证据的结论,并在能修时给出可粘贴的 YAML patch。
这是什么¶
dsh-conflict-doctor 的定位是 DSH 插件冲突治理:诊断静默冲突,并为每条 finding 提供至少一条修复建议(含可粘贴 patch)。npm 包名 dsh-conflict-doctor,当前资料中版本为 0.2.0。
与同名的另一类工具不同:npm 上的 dsh-plugin-doctor 侧重兼容性、安全性、隔离安装与回滚;本插件专注冲突诊断与修复——重复 tool id、fiber 永久 PENDING、层覆盖 disable 等。安装时注意包名,避免装错。
它解决哪三类静默问题¶
资料里用表格归纳了典型现象与根因,概括如下:
- 装完插件,功能不出现 — fiber 停在
PENDING,等待一个无人提供的服务,不报错。 - 再装一个插件后整段功能没了 — tool id 重复导致后注册者抛错,整行加载失败;错误往往只写「already registered」,不指向另一个 owner。
- 关了插件仍生效 — 后一层 patch 把前一层的
disabled或config整段替换掉(DSH 层语义:最后一层胜出)。
本插件把这些情况对应到具体 code、refs、evidence 和 fix,而不是笼统提示「检查配置」。
核心功能:运行期与 profile 两套检测¶
使用时可指定 scope:live(仅运行中进程)、profile(仅磁盘组合)、all(默认,两者兼有)。
运行期(live)¶
| code | 严重度 | 含义(摘要) |
|---|---|---|
live/tool-id-conflict |
critical | 两插件注册同一 tool id;从失败 fiber 错误中识别冲突名 |
live/failed-fiber |
critical | 启动失败的 fiber,带原始错误首行 |
live/pending-missing-service |
critical | fiber 停在 PENDING,inject 的服务无人提供 |
live/duplicate-entry-id |
critical | 两模块占用同一 Loader entry id |
live/unprovided-inject |
warning | 声明依赖的服务在进程中不存在 |
live/pending-self-dependent |
critical | fiber 等待的服务正是它自己要提供的(自锁) |
live/outbound-tool-collision |
warning | 两已加载插件声明同一 tool id,尚未进注册表(时序掩盖) |
磁盘组合(profile)¶
结构类检查不依赖版本,任何时候都会跑,例如:同一层 row id 重复(profile/duplicate-row-in-layer)、同一模块重复挂载(profile/module-under-multiple-ids)、停用后又被插入(profile/disable-then-reinsert)、缺失 patch 文件(profile/missing-patch-file)、编译产物里 tool id 碰撞(profile/tool-id-collision)、同名服务碰撞(profile/service-collision,按 realm 过滤客户端包)等。
版本敏感项(peer 范围、host-import、Node engines)仅在版本权威性已确认时运行:插件启动会向 pluginManager 询问运行中真实版本;磁盘与运行不一致时标记为 stale-disk 并跳过三类检查,避免用错误基准误报。结构类检查不受影响。
每条 finding 包含 refs、evidence、impact 和至少一条 fix;能用 patch 修的会直接给出可粘贴 YAML。
主动播报¶
存在 critical 冲突时,插件会把结论与第一条修复写入系统提示(systemPrompt.context,order 50),而不是等你主动问。无冲突时贡献空字符串,不额外占用 token;并明确要求模型在用户提出相关问题前不要擅自改配置。
设计取向(与使用相关)¶
- 默认只读 — 不注册服务、不改配置、不碰注册表。修复侧提供
--dry-run、--fix-out(写到 profile 旁惰性文件);--apply资料标明尚未实现。 - 硬依赖仅
tools— 其余能力用时ctx.get,注册包在ctx.effect()内,卸载可干净撤销。 - CLI — 包内提供
conflict-doctor可执行入口(pnpm audit等脚本在仓库内用于自检)。
安装与启用¶
从 DSH 设置里的 Plugin Market 搜索安装,或使用资料中的命令:
dsh plugin --profile web add dsh-conflict-doctor
将该包名加入对应 profile 的 package.json 的 dsh.profile.bundles:
{
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-conflict-doctor"]
}
}
}
不安装到 profile 时,可用 overlay 验证组合层(路径换成你本地的插件目录):
dsh --profile web --patch <path-to>/conflict-doctor/cordis.patch.yml --dump-config
社区插件目录页:https://www.skillhub.cn/plugins/ven314/dsh-conflict-doctor(独立站点,与 DeepSeek / 幻方无官方从属关系)。
典型用法¶
模型侧工具(参数见 README):
conflict_doctor { scope: "all" | "live" | "profile", profilePath?: string, format?: "markdown" | "json" }
用户侧命令:
/conflict-doctor
建议排查顺序:
- 功能「像没装」或刚加插件后整段失效 → 先用
scope: "all"或/conflict-doctor看 critical 项。 - 仅怀疑 patch 层叠、disable 被覆盖 →
scope: "profile"。 - 仅怀疑当前进程 fiber / 服务 / tool 注册表 →
scope: "live"。 - 需要机器可读结果时设
format: "json";给人看用默认 markdown。
修复建议以报告中的 fix 与 YAML 为准;需要试修时用修复引擎的 --dry-run 或 --fix-out,不要假设 --apply 已可用。
适用场景与注意¶
适合谁
- 维护含多个社区插件的 web(或其他)profile 的开发者。
- 遇到「装上了但不生效」、tool 重复导致整行加载失败、层覆盖导致 disable 无效等问题,需要可执行结论而非猜测。
能力边界(资料原文要点)
- 运行期 tool id 归属无法 100% 归因;跨插件归属部分依赖静态扫描
defineTool({ name: '...' })字面量,动态拼出的 tool 名不在静态视野内。 profile/row-config-replaced只能报多层替换症状,无法判断被替换的 config 是否业务上必需。- 名称类静态提取只认字面量(如
provide('name')),报告措辞是「声明于编译产物」而非「运行期已注册」。
安全与权限
插件在当前 DSH 进程权限下读取 Loader、profile、编译产物与运行态信息。安装前请自行查看 GitHub 仓库 源码与许可证(资料未在此重复许可证全文),确认符合你的环境与合规要求。
结尾¶
DSH 生态强调「一切皆插件」;插件越多,静默冲突的概率越高。dsh-conflict-doctor 的价值是把「没在工作」收敛成「谁和谁撞了 + 改哪一行」,并尽量用运行宿主的真实版本做版本敏感判断,减少误报。
- 目录页:https://www.skillhub.cn/plugins/ven314/dsh-conflict-doctor
- 源码与完整检测项说明:https://github.com/ven314/dsh-conflict-doctor