在 Docker 隔离的真实宿主中测试 DSH 插件的安装、启动、工具注册、更新、卸载、重装与恢复生命周期,并输出结构化证据。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-testkit
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:iiwish/dsh-testkit
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。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
DSH Testkit
DeepSeek Harness 插件的真实宿主发布门禁。
一个插件可能已经通过编译和单元测试,发布后却因为 tarball 缺文件、bundle 没有在 DSH 注册,或卸载后破坏 profile 而失败。DSH Testkit 补上这段验证空白:用用户实际安装的制品,对精确版本的真实 DSH 宿主执行生命周期,并保留维护者可以复核的证据。
整个过程不调用模型,也不需要模型 API Key。
一眼看懂
| 发布问题 | 一次隔离运行提供的证据 |
|---|---|
| 可发布制品能否安装并注册? | npm pack、精确 DSH 安装、bundle assemble、配置 row、service 和 tool schema |
| 对外承诺的行为是否可用? | 确定性 runtime probe、声明的 tool 调用、可选 loopback HTTP route 和显式 browser smoke |
| 用户能否干净移除它? | 卸载、同 profile 重启、能力检查、归属路径残留、进程和端口 |
DSH Testkit 适合插件维护者、release PR 审核者、插件模板维护者,以及需要可复现宿主级故障报告的协作者。它的定位是发布门禁,不是另一套单元测试框架、静态 linter、模型输出评测或安全认证。
快速开始
运行要求:Node.js 22 或更高版本,以及 Docker。
pnpm add -D dsh-testkit
pnpm dsh-test init
pnpm dsh-test
如果 bundle 位于仓库子目录:
pnpm dsh-test init plugin/
pnpm dsh-test --config plugin/dsh-testkit.yaml
dsh-test init 离线运行,识别最近的 Git worktree,并生成三个可审核文件:
<plugin-root>/dsh-testkit.yaml:固定精确 DSH 版本和自动识别的 row 预期<repository-root>/.github/workflows/dsh-lifecycle.yml:默认使用只读 token,并引用正确的嵌套路径<repository-root>/.agents/skills/dsh-testkit/SKILL.md:让兼容的 coding agent 使用同一发布门禁
导出的源码树没有 .git 时,请显式传入 --repo-root .。生成过程字节幂等,并在写入前检查全部目标;除非显式使用 --force,任一冲突都会停止全部写入。请审核检测到的 row,只添加插件契约明确承诺的 service、tool、exercise 和 update 行为。
Docker 是默认 runner。报告写入 .dsh-testkit/runs/,包括规范 report.json、CI 可消费的 junit.xml、便于阅读的 report.md、脱敏命令日志和有大小边界的阶段证据。
它在工具链中的位置
DSH 质量需要多种互补检查:
| 需求 | 合适的工具 |
|---|---|
| 作者侧 manifest、patch、build 和 pack 预检 | dsh-plugin-doctor |
| 用户侧 profile、session 和环境离线诊断 | moonquake2004/dsh-doctor |
| 多个 bundle 在 composition 阶段发生冲突 | dsh-composition-check |
| 插件自身逻辑 | 你的单元和集成测试框架 |
| 打包制品在真实宿主上的安装、启动、行为、移除、恢复和残留 | DSH Testkit |
实用的流水线会在每次提交运行低成本静态检查,在 release PR 和 tag 上运行 DSH Testkit。Testkit 每个隔离生命周期只测试一个目标插件;多插件的状态归属和更新顺序仍属于 composition 问题。
生命周期
resolve -> install-dsh -> package -> install-plugin -> assemble -> boot -> register
-> exercise -> update? -> uninstall -> reboot -> recover? -> cleanup
DSH Testkit 0.4.4 接受精确的 @deepseek-ai/dsh 版本:0.1.1-rc.2(默认)、0.1.5-rc.1、0.1.2-rc.1、0.1.0-rc.8、0.1.0-rc.7 和 0.1.0-rc.6。请使用 npm dsh-testkit@0.4.4 或 Action v0.4.4 获得此六宿主支持矩阵。未知版本会在创建 runner 前以退出码 4 停止,避免把宿主漂移误报成插件故障。
一次性 canary 矩阵按精确 npm 制品和不可变上游 release 跟踪候选版本,与正式支持范围分离。Release Watch 只选择高于被测试 checkout 中最高支持版本的候选。0.1.3-alpha.2、0.1.5-alpha.1 和 0.1.5-alpha.2 等 alpha 宿主不会仅因 canary 通过而获得正式支持。验证证据与转正式支持条件见宿主兼容性。
通过意味着什么
- 报告中标识的同一个打包制品完成了所有必需阶段。
- row 来自 DSH
--dump-config;service 和 tool schema 来自进程内 Cordis probe。 - 声明的 exercise 通过真实 tool runtime 执行,不依赖模型选择。
- 卸载后同一 profile 能重启,并且不存在目标 bundle、能力或可归属残留。
- 必需 observer 均可用;缺少必需覆盖时返回
unsupported,不会伪造通过。
通过不能证明任意可执行代码安全、模型输出质量良好,也不能证明未声明的行为有效。
场景即代码
dsh-test init 会生成一个小而明确的起始场景:
schemaVersion: 1
name: my-plugin-quick
subject:
source: .
dsh:
version: 0.1.1-rc.2
expect:
boot: success
rows: [tool-my-plugin]
services: [myService]
tools: [my_tool]
exercise:
- tool: my_tool
arguments:
value: smoke
observers:
filesystem: required
process: preferred
ports: preferred
network: off
canary: preferred
本地目录类型的目标以只读方式挂载,复制到 runner 自己的可写根目录后再打包。存在 prepare、prepack 或 postpack 时,Testkit 会在副本中按照 packageManager 和 lockfile 恢复依赖,再执行 npm pack;原始 checkout 不会被修改。
检查公开 DSH web route 时,请设置 profile: web 并添加仅 Docker 可用的断言:
profile: web
http:
routes:
- id: health
path: /health
expect:
status: 200
json:
status: ok
version: $subject.packageVersion
场景参考包含 http.routes、update 目标、预期失败和恢复、阶段重跑、observer 策略、覆盖整次尝试的 watchdog,以及显式 dsh web TurnStatus browser smoke。HTTP 和浏览器流量只访问 runner 分配的 127.0.0.1。缺少 Chromium 时返回 unsupported;已经存活但永久无响应的 DSH web 宿主或 watchdog 到期属于 host/infrastructure,不归为插件失败。
最小权限 CI
生成的 workflow 默认只需要只读 token,并显式写出该契约:
permissions:
contents: read
steps:
- uses: iiwish/dsh-testkit/.github/actions/dsh-test@v0
with:
plugin: .
dsh-version: 0.1.1-rc.2
config: dsh-testkit.yaml
publish-junit-check: 'false'
默认模式会把 JUnit annotation 写入 job,并输出 artifact ID、URL、digest、报告路径和稳定退出码;它不会调用 Checks API。v0.4.4 Action 在两个发布出口前执行统一证据检查,只上传附带哈希清单的全新暂存副本。不安全证据会使 job 失败且不会发布。实现见发布版本的 Action 源码。
受信任的 push 或 release workflow 可以选择发布命名 JUnit Check:
permissions:
contents: read
checks: write
steps:
- uses: iiwish/dsh-testkit/.github/actions/dsh-test@v0
with:
plugin: .
dsh-version: 0.1.1-rc.2
publish-junit-check: 'true'
不要在不受信任的 fork pull request 上启用该选项。项目引用的外部 Action 全部固定到不可变 commit;滚动 v0 tag 是消费者兼容通道。GitHub Enterprise Server 和其他 CI 可以直接调用 CLI。
稳定退出码为:0 通过、1 生命周期失败、2 输入无效、3 基础设施错误、4 不支持、5 结果不稳定。已发布 schema 位于 dsh-testkit/schemas/report-v1.json 和 dsh-testkit/schemas/scenario-v1.json。
原生入口与 Agent Skill
项目级 Skill 和导出的 dsh-testkit/skills/dsh-testkit/SKILL.md 会告诉兼容 Agent 如何选择覆盖、解释证据并守住 Docker 边界。Skill 只指导使用,不授予信任,也不替代审核。
DSH Testkit 还提供可选的、由社区维护的 DSH Profile Bundle:
dsh plugin --profile web add dsh-testkit@0.4.4
dsh --profile web --dump-config
它注册 dsh_test,作为同一引擎的需确认、仅 Docker adapter。外部 CLI 或 CI Action 仍是独立恢复门禁,因为宿主内工具无法诊断发生在 tool 注册之前的宿主故障。
安全与信任边界
插件是可执行代码:生命周期会运行 package script 和 runtime 代码。Docker 通过只读根文件系统和源码挂载、一次性可写状态、移除 capabilities、资源限制和证据大小边界来缩小默认影响范围,但它不是经过强化的恶意代码沙箱。
测试未知代码时请使用一次性基础设施。绝不能对不受信任的插件使用 --runner local --unsafe-local。原生工具需要访问 Docker daemon,确认执行是一项信任决策,不是认证。私有插件源码始终留在 runner 上;DSH Testkit 不依赖 SaaS,只上传 CI workflow 明确配置的证据。
社区
社区验证协议定义了无凭证、精确版本的 cohort 运行和仅聚合公开报告。dsh-shelf 案例说明为什么“安装成功”不足以证明真实宿主注册成功。设计伙伴复测门禁记录不可变包基线,避免把只存在于源码的修复写成 package 复测结论。
有效的故障报告应包含精确插件版本、DSH 版本、失败阶段、report.json 和脱敏日志。请从贡献指南开始,或加入 DeepSeek Harness 官方 Show & Tell 讨论。
DSH Testkit 是独立、非官方的社区项目,采用 MIT License 发布。
链接
同类插件
yjh051108/dsh-routing-suite★ 7003
一个仓库三件套:DSH 插件包的运行时注入器(注入、热重载、卸载、开发侧挂区一键转正、路由自愈,外带设置页插件管理:列出、卸载、拖入文件夹内化)、任务感知的思维模式路由 agent 预设(router-standard / router-spec / router-react)、以及分级两级任务协议(commit_star / lock_stage / revise_do / edit_plan / mark_task / redteam_verdict 六个工具,任务状态落盘)。注入器实现直接在库内,安装的是它自己的行为而不是一份依赖清单。
strukto-ai/mirage#dsh★ 3666
把文件系统与 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★ 325
社区发行版:TUI、桌面端与 Web UI 统一体验,分层安装、一步到位。
weijiafu14/pi2dsh★ 206
Pi Host ABI 兼容引擎:装一次之后,npm 上的 Pi 扩展原包经 `dsh plugin add <pi-package>` 直接作为 DSH 原生插件挂载。已在官方 DSH 上端到端验证 pi-mcp-adapter(完整 MCP 管理面:OAuth、resources、prompts、MCP Apps、elicitation、sampling)、@tintinweb/pi-subagents、pi-code、pi-hermes-memory、pi-background-tasks;`pi2dsh inspect` 在安装前报告一个包的兼容情况。
lire1131/dsh-undo-savepoint★ 166
DSH 撤销/回退系统:配置变更自动存档,一键撤销/恢复/回退到任意版本,支持 WebUI 与离线 CLI/GUI 工具(DSH 启动失败也能救)。
Fishquito7/dsh-skill-mcp-panel★ 155
在 DSH Web 设置中管理技能与 MCP 服务器:技能卡片热启停、工作区作用域、分组、批量迁移与拖拽导入,以及 stdio/HTTP MCP 增删改查、连接测试、密钥脱敏,并附带统一 dsh-panel 命令行。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。