dsh-slice-bench
把插件放进一台真起来的最小 DSH 机器,让 harness 自己说它站不站得住 · Runtime bench for DSH plugin version conflicts — the harness gives the verdict, not us
- Stars
- 1
- Language
- JavaScript
- Created
- Aug 30, 2026
- Updated
- Aug 30, 2026
Introduction
DSH Plugin Slice Bench
DSH 插件的版本兼容检测工具与 agent skill,结论由 DSH 自己的启动审计给出。
DSH(DeepSeek Harness) 是「一切皆插件」的 agent harness。换一个 harness 版本,插件可能就加载不起来。本仓库把插件单独放进一棵最小的 Cordis 树里启动,用启动审计的结论回答「这一版还能不能加载」。
特色
- 不内置「哪些 API 变了」的结论清单 — 那种清单会过期。换一个版本重新运行,得到的就是那一版的结论。仓库里的
baselines/是工具运行的结果,为了展示程序效果(不是只能跑特定版本) - 逐个插件隔离启动 — 每个插件单独放进空的 Cordis 树,缺哪个服务由启动审计点名。不修改源码,不打补丁
- 区分「通过」与「绿但没测全」 — 启动审计只审配置里列出的条目,看不见条目内部用
ctx.inject([...], cb)建的可选依赖:那段回调可以一直等下去,而整棵树照报通过。本工具把这些等待单独列出并给出退出码3,因为它正是下一个版本把该依赖变成必需时会崩的地方 - 结论不经过模型判断 — 判定来自启动审计。同一版本连跑两次,全部包的启动状态、依赖集合、服务调用记录逐条比对,零差异
- 零依赖、零密钥 — 只需 Node 20。不读取凭据,不发起网络请求,不修改
~/.dsh;每次运行使用临时目录,结束即删除
快速开始
# 目标版本安装到独立目录
mkdir dsh-0.1.2 && cd dsh-0.1.2 && npm init -y
npm install @deepseek-ai/dsh@0.1.2-alpha.2 @deepseek-ai/dsh-base@0.1.2-alpha.2 @deepseek-ai/dsh-web-app@0.1.2-alpha.2
cd ..
git clone https://github.com/33moren33/dsh-slice-bench.git
cd dsh-slice-bench/skills/dsh-slice-bench # 命令在这一层,不在仓库根
# 一、插件声明的 SDK 包在新版本是否存在(不启动,秒级)
node bin/manifest.js --engine ../../../dsh-0.1.2 --plugin ../../../你的插件
# 二、加载并运行一个回合,新旧版本各一次
node bin/talk.js --engine ../../../dsh-0.1.1 --plugin ../../../你的插件
node bin/talk.js --engine ../../../dsh-0.1.2 --plugin ../../../你的插件
# 三、插件自带 cordis.patch.yml 时,那棵树必须单独测——上一步测不到它
node bin/slice.js --engine ../../../dsh-0.1.1 --plugin ../../../你的插件
node bin/slice.js --engine ../../../dsh-0.1.2 --plugin ../../../你的插件
# 四、启动审计说「等某个服务」时,问谁提供它、以及它这一版要哪些服务
node bin/provider.js --engine ../../../dsh-0.1.2 --service <服务名>
node bin/provider.js --engine ../../../dsh-0.1.2 --package <包名>
退出码有四档:0 通过/1 被测对象判定为失败/2 没能给出答案(引擎路径错、参数错,或本工具自己出错)/3 跑起来了但结论不完整。3 不是失败也不是通过,屏幕上的绿灯之下还有没测到的部分。
⭐ 1 和 2 的分工是这套工具的地基:1 才是关于被测插件的结论,2 是本工具没能给出结论。每条命令 --help 会印出这四档的完整措辞。
已发布的插件先装到一个空目录:npm install <包名> --legacy-peer-deps --omit=peer(第三方插件用 peerDependencies 声明宿主 SDK,直接装会拖来整棵 SDK 并覆盖被测版本),然后把 node_modules/<包名>/ 交给 --plugin。
⚠️ --omit=peer 只挡 peer 那一类。插件若把某个 SDK 包写在真 dependencies 里,它照样会被装进来,node_modules/@deepseek-ai/ 仍会出现——这不影响结论,--plugin 会在搭临时环境时剔掉插件自带的这些副本,测的仍是 --engine 指的那一份。
--engine 支持两种形态:npm 安装目录,或包含 pnpm-workspace.yaml 的源码检出。
装成 skill
skills CLI(推荐)
npx skills add 33moren33/dsh-slice-bench
Claude Code
/plugin marketplace add 33moren33/dsh-slice-bench
/plugin install dsh-slice-bench
本地开发模式:
git clone https://github.com/33moren33/dsh-slice-bench.git
claude --plugin-dir /path/to/dsh-slice-bench
Codex
codex plugin add 33moren33/dsh-slice-bench
Gemini CLI
gemini skills install https://github.com/33moren33/dsh-slice-bench.git --path skills
Cursor
git clone https://github.com/33moren33/dsh-slice-bench.git
cp -r dsh-slice-bench/skills/* .cursor/skills/
DSH 本体
把 skills/dsh-slice-bench/ 复制到项目的 .agents/skills/,或让 Skill provider 加载本仓库的 skills/ 目录。该目录是自足的,包含 skill 与它调用的全部命令。
Skill 索引
| Skill | 说明 | 版本覆盖 |
|---|---|---|
| dsh-slice-bench | 三种模式(兼容体检/升级后回归/版本差异)、每步执行什么、输出如何判读、报告格式;细节在 references/ 按需加载 | 任意两个版本之间 |
命令
命令位于 skills/dsh-slice-bench/,相对路径以该目录为工作目录。
| 命令 | 用途 |
|---|---|
bin/manifest.js | 插件声明的 SDK 包(含自带组合补丁里的)在目标版本是否存在 |
bin/talk.js | 加载插件并运行一个对话回合:能否启动、回合是否完成、有无异常 |
bin/provider.js | 某个服务由哪个包提供(声明与运行时确认分开报);某个包在这一版是否还在、官方 bundle 给它的条目 id 与 config、它要求哪些服务 |
bin/flow.js | 单个包隔离启动,记录它对每个服务的属性访问与方法调用 |
bin/survey.js | 逐包隔离启动,统计能否独立激活 |
bin/closure.js | 不动点迭代,求每个包能够启动的最小包集合 |
bin/bundles.js | 从官方 bundle 提取条目与 config,建立索引 |
bin/slice.js | 指定若干包、或直接用插件自带的 cordis.patch.yml 组成一棵树并启动 |
matrix/run.js | 同一份会话产物,新旧版本能否互相读取 |
官方函数
本工具不依赖任何官方插件包(package.json 无 dependencies),运行时从被测版本解析下列接口,逻辑写在本工具内。
| 接口 | 来源 | 用途 |
|---|---|---|
boot(name, configPath) | @deepseek-ai/dsh-app-boot | 由一份条目清单启动完整的树,不经过 profile 机制 |
assertEntriesActivated / assertEntriesLoaded | 同上 | 判定来源:点名未激活的条目及其等待的服务 |
loadOverlayPatches | 同上 | 解析 bundle 的 cordis.patch.yml |
installFailLoud | 同上 | 使静默失败显式化 |
ctx.registry / ctx.reflect / fiber.state | @deepseek-ai/cordis | 遍历运行实例、读取服务表 |
ctx.reflect.provide(name, value) | 同上 | 记录用的桩服务由它注册 |
isolate | 基座原语,cordis.yml 声明式配置 | 使桩服务优先于真实服务被解析 |
实现思路参考官方文档与源码:教程第 6 章「组合与 HMR」的 diagnose.ts 示例(遍历插件注册表定位 PENDING 实例)、第 3 章「服务」(插件如何提供服务)、同第 6 章的服务隔离声明;以及官方自省工具按 Symbol 枚举服务、官方沙箱包装注入服务的写法。条目与 config 一律取自各 bundle 随包发布的 cordis.patch.yml。
模型适配器:对话用的是一个 22 行的确定性适配器(移植自官方测试夹具),不使用官方 dsh-llm-replay——后者属于 test-support,不在安装集内,基于它的工具无法在用户实际安装的版本上运行。
基线
条目索引存入 skills/dsh-slice-bench/baselines/,下一个版本可直接 diff。逐包服务调用记录体积较大,作为 Release 附件提供。
| 版本 | 形态 | 包数 | 条目索引 | 服务调用记录 |
|---|---|---|---|---|
| 0.1.1-rc.2 | npm 安装 | 197 | 仓库内 | Release |
| 0.1.2-alpha.1 | 源码检出 | 263 | 仓库内 | — |
| 0.1.2-alpha.2 | npm 安装 | 224 | 仓库内 | Release |
⛔ **这三份不能随便互相 diff。**源码检出含仓库里全部的包(包括没发布的),npm 安装只含装得到的,两者比「包在不在」两个方向都会错。上面 0.1.1-rc.2 → 0.1.2-alpha.2 那组结论之所以成立,是因为两边同为 npm 安装。⚠️ 0.1.2-alpha.1 没有发布到 npm,所以它只有源码检出这一种形态。工具在做这种比较时会自己把「包在不在」降进「判不了」那一档。
0.1.1-rc.2 → 0.1.2-alpha.2 的运行结果:移除 2 个包;21 处依赖声明变化,其中 17 个包将 sessionProjections 从作用域注入改为条目级 inject(.d.ts 未变化,导出 diff 无法发现);会话日志存储形式变化而格式版本号未变。
适用范围
已在 0.1.1-rc.2、0.1.2-alpha.2(均为 npm 安装)与 0.1.2-alpha.1(源码检出)上运行;测试样本包含 npm 上的 5 个第三方插件。
当前限制:浏览器侧只检查声明的包名,不检查实际加载;服务调用记录覆盖启动阶段;已验证平台为 Windows + Node 24。
目录
skills/dsh-slice-bench/ 自足的 skill,复制这一个目录即可使用
├── SKILL.md agent 操作规程
├── references/ 命令详解、方法说明
├── bin/ 命令
├── lib/ 引擎识别、临时环境、驱动
├── workload/ 对话组合、模型适配器、桩服务
├── matrix/ 跨版本产物检查
└── baselines/ 各版本条目索引
参考资源
- 官方仓库 — DSH 本体
- Discussion #5120 — 插件升级 skill 的社区征集