DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-fixture-bad-plugin

d

dsh-fixture-bad-plugin

Manifest valid

Negative test fixture for DSH plugin contract checks (intentionally bad plugin, do not use as a real plugin)

hasBundlePatch

dsh-fixture-bad-plugin(测试夹具,不要当真插件用)

用途:验证 dsh-contract-check 能不能在加载时发现违规的 render 契约。

它故意注册了两个工具:

工具行为期望判定
fixture_bad_renderrender 返回裸字符串(就是当年 dsh-ssh-ops 那个 bug)🔴 violation → 角标变黄
fixture_unknown_renderrender 委托给辅助函数,静态判不出形态见下(初版预期写错了)

✅ 实机验证结果(2026-09-20,第一次真正走通黄灯)

颜色:   yellow
状态条: 无耗 · 检查 23 个插件 · 违规 2 · 不可判定 1
  [violation] fixture_bad_render     返回字符串,违反 render(): ContentBlock[] 契约
  [violation] fixture_unknown_render 实测返回对象(不是数组),违反契约(实测)
  [unknown]   doublecheck_report     静态判不准,实测又抛异常

两点值得记下来:

  1. fixture_unknown_render 被判成 violation 而不是 unknown,这是对的。 我原本以为"静态判不准 = unknown",但实测探针把它抓出来了: 它的 render 返回传进去的值,而它声明的输出 schema 是对象 → 真调用时返回的一定不是数组。 这正好说明实测探针的价值:静态看不透的东西,跑一次就清楚了。
  2. doublecheck_report 仍是 unknown:实测时 render 抛了 Cannot read properties of null (reading 'length') —— 假数据不合形状,归 unknown (抛异常绝不判违规,这是零误报原则的一部分)。

⚠️ 先读:这个夹具造成过一次事故(2026-09-19)

症状:把它加进 profile 的 bundles 后,DSH 起不来 —— 整个插件树加载失败。

根因:上一版源码里有 import { defineTool } from "@deepseek-ai/dsh-tools", 而夹具目录没有 node_modules。pnpm 的 link: 让 Node 按真实路径解析 → 找不到包 → ERR_MODULE_NOT_FOUND → 插件树整体失败。

两个教训:

  1. "扫源码 OK" ≠ "能加载"。离线扫描只看文件存不存在、形态对不对, 完全不涉及模块解析 —— 所以它当时报了 ok,然后 DSH 挂了。
  2. 把测试夹具装进运行环境的 profile 之前,必须先证明它能被加载。

已修:夹具改成零外部 import(直接用裸定义对象调 ctx.tools.register()), 从根上不可能再因解析失败拖垮启动。

已加闸门:scripts/preflight.mjs —— 装之前必须先跑;它自己也有自测(selftest.mjs)。


⚠️ 第二个坑:pnpm install 不会补建新加的 link: 依赖

2026-09-20 实测:把夹具加进 dependencies(link: 形式)后跑 pnpm install, 它回一句 "Already up to date" 就结束了 —— lockfile 更新了,但 node_modules 里的链接没建。 此时直接重启,DSH 解析不到这个包,又是"整个插件树起不来"(跟上次症状一样,根因不同)。

pnpm install --force 也一样跳过。

判据(装完必查):

Test-Path 'D:\tool\dsh_data\profiles\web\node_modules\dsh-fixture-bad-plugin'

补建(就是 pnpm 给其它 link: 依赖建的那种 Junction):

cd D:\tool\dsh_data\profiles\web
New-Item -ItemType Junction -Path node_modules\dsh-fixture-bad-plugin `
         -Target D:\tool\claude_code\dsh-fixture-bad-plugin

使用流程(顺序不能换)

# ① 预检:证明它能被加载(不通过就别装)
node D:\tool\claude_code\dsh-fixture-bad-plugin\scripts\preflight.mjs

# ② 装进 profile(脚本会备份配置、写完校验)
node D:\tool\claude_code\dsh-fixture-bad-plugin\scripts\profile-link.mjs --apply

# ③ 确认 node_modules 里有链接(见上面那个 pnpm 坑;没有就手工建 Junction)
Test-Path D:\tool\dsh_data\profiles\web\node_modules\dsh-fixture-bad-plugin

# ④ 重启 DSH(你重启,不是我)

期望看到

  • 会话头部圆点变 🟡 黄
  • 悬停状态条出现 违规 2
  • /contract-check/status 的 findings 里点名 fixture_bad_render
  • 绿灯 → 黄灯的颜色变化就是这条链路走通的证据

⏹ 验证完立刻移除

一键(双击即可,不需要 AI 在场):

D:\tool\claude_code\dsh-fixture-bad-plugin\紧急回滚.bat

或命令行:

node D:\tool\claude_code\dsh-fixture-bad-plugin\scripts\profile-link.mjs --remove
# 然后重启 DSH

卸载脚本删链接时用的是 rmdir 而不是递归删除: 在 Junction 上递归删除会跟进目标目录,把夹具源码本身删光。 (2026-09-20 卸完已核对:夹具源文件全部完好。)

上一次就是忘在这一步:夹具留在 profile 里,于是任何原因导致的加载失败 都会先被怀疑到它头上(而且它确实就是凶手)。

Comments

Loading…