在一次性隔离配置中为 DSH 插件执行安装与冒烟测试,返回结构化的通过/失败记录与批量矩阵,不触碰真实配置。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-test-drive
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:PerryLink/dsh-test-drive
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本。请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
🧪 dsh-test-drive
面向 DeepSeek Harness 插件的隔离式安装冒烟实测。
在一次性 profile 中完成安装、冒烟、验证与清理——绝不触碰你真实的 ~/.dsh。
English · 简体中文 · Español · Português · हिन्दी
Compatibility(兼容性)
| 组件 | 版本 |
|---|---|
| DeepSeek Harness | 0.1.0-rc.6(peer 依赖钉版) |
| Node.js | ^22.19.0 || >=24.0.0 |
| 包管理器 | pnpm@11.7.0 |
| 平台 | Windows / macOS / Linux(纯 host 插件) |
| 外部工具 | PATH 上的 dsh CLI(自动探测,可解析 npm shim)、PATH 上的 pnpm |
What you get(你能得到什么)
test_drive工具 —— 单个目标跑完整流水线:dsh plugin add→--dump-configpatch 校验 → headless 引导冒烟(FAILED 标记扫描 + 可选一句任务)→ 可选能力断言 →dsh plugin remove→ 隔离清理。同步返回结构化记录;传background: true则返回{ kind: 'background', jobId }。/testdrive命令 —— 把空格/逗号分隔的目标列表作为drive-batch后台任务(ctx.jobs)批量跑,产出矩阵报告(JSON + Markdown)。drive_report工具 —— 按 id 取回任意单次记录(tdr_...)、矩阵(tdm_...)或最新矩阵;以 Markdown 渲染。- 能力断言 —— 不止于“启动并退出”:可选的
capability阶段让 agent 调用指定工具(或运行/command),并核对持久会话日志确实记录了调用、观察输出包含expect。干净启动只是冒烟;observed才证明具名能力真实可用。 - 结构化结果 —— 每条记录带判别符
schema: "dsh-test-drive/v1",关键字段均为一级字段:stages.install.status(pass/fail)、stages.smoke.status(pass/fail/boot-ok/skipped)、各阶段durationMs、脱敏后的summary/outputTail以及总判定verdict(pass/fail/partial/unknown)。这是下游评分方(dsh-score)消费的机器可读契约。 - 结构安全 —— 每个临时目录都由本插件以专属前缀
dsh-test-drive-创建、登记在活跃所有权注册表中,且只经「dry-run → 隔离改名 → 删除」阶梯清理。宿主机 profile 永不被读取或写入。
Quick start(快速开始)
git 通道
dsh plugin --profile web add github:PerryLink/dsh-test-drive#<commit-sha>
首次 add 会因 pnpm 拦截该包的 prepare 构建而失败;把 pnpm 打印的精确键复制进 profile 的 pnpm-workspace.yaml 后重跑:
allowBuilds:
'dsh-test-drive': true
npm 通道
dsh plugin --profile web add dsh-test-drive
预构建包无需构建许可。重启 profile 后,即可在会话中使用 test_drive / /testdrive。
Install & uninstall(安装与卸载)
dsh plugin --profile web add dsh-test-drive # 安装(npm)——或上面的 git 形式
dsh plugin --profile web remove dsh-test-drive # 卸载
Configuration(配置)
所有键均可选(下列为默认值);非法值在加载期响亮失败。
| 键 | 默认值 | 说明 |
|---|---|---|
profileName |
headless |
每次一次性 DSH_HOME 内初始化的 profile 模板(base + headless bundles)。 |
dshBin |
"" |
dsh 可执行文件的绝对路径覆盖;为空则自动探测 PATH 上的 dsh。 |
headlessTask |
"Reply with exactly: ok" |
引导冒烟阶段的一句任务;为空则跳过该阶段。 |
forwardEnv |
[] |
转发进测试 profile 子进程的环境变量名(绝不转发值)。 |
allowBuilds |
true |
在测试 profile 中放行被拦截的 git prepare 构建并重试一次安装。 |
installTimeoutMs |
600000 |
dsh plugin add 阶段时限。 |
configTimeoutMs |
60000 |
--dump-config 阶段时限。 |
smokeTimeoutMs |
300000 |
headless 引导冒烟阶段时限。 |
capabilityTimeoutMs |
300000 |
能力断言任务时限。 |
capability.enabled |
false |
运行能力断言阶段(注册 → 调用 → 观察到)。 |
capability.kind |
tool |
断言对象:tool 或 command。 |
capability.name |
"" |
工具或命令名(不带前导 /)。 |
capability.args |
"" |
调用文本:工具参数(JSON 风格)或命令参数。 |
capability.expect |
"" |
期望出现在观察输出中的字面量(不区分大小写子串)。 |
uninstallTimeoutMs |
120000 |
dsh plugin remove 阶段时限。 |
outputTailBytes |
8000 |
每阶段记录的脱敏输出尾部上限(字节)。 |
keepTempDirs |
false |
失败时保留临时目录供取证(所有权被放弃,由你清理)。 |
maxBatchTargets |
20 |
/testdrive 批上限。 |
batchConcurrency |
1 |
批并发度(串行可避免 pnpm-store 争用)。 |
Tools & surfaces(工具与界面)
test_drive
test_drive(target: string, headlessTask?: string, background?: boolean,
capability?: { kind: 'tool' | 'command', name: string,
args: string, expect: string })
target—— git 规格(github:owner/repo#sha、git+https://...)、npm 包名、本地路径或.tgz压缩包。capability—— 冒烟后的断言:agent 以args调用name(tool)或运行/name(command);阶段读取持久会话日志并要求观察输出包含expect。需要DEEPSEEK_API_KEY(宿主环境或forwardEnv);缺失时该阶段为skipped,绝不算失败。- 返回完整结构化记录,样例见下。
background: true启动一个drive-batch任务并返回其 id。
/testdrive <目标...>
启动一个后台批任务;进度经任务输出流式推送,最后一行给出供 drive_report 使用的矩阵 id。
drive_report(id?)
返回单次记录(tdr_...)、矩阵(tdm_...),或不传 id 时返回最新矩阵。
结构化结果样例
{
"schema": "dsh-test-drive/v1",
"run": { "runId": "tdr_9f2c...", "startedAt": "2026-08-16T00:00:00.000Z",
"finishedAt": "2026-08-16T00:00:45.120Z", "durationMs": 45120,
"harnessVersion": "0.1.0-rc.6", "pluginVersion": "0.1.0",
"platform": "win32", "node": "v22.22.3" },
"target": { "kind": "repo", "spec": "github:owner/dsh-click#abc123",
"resolved": { "packageName": "dsh-click", "packageVersion": "0.1.0",
"hasBundleManifest": true } },
"isolation": { "tempDshHome": true, "tempWorkspace": true, "tempStore": true,
"hostHomeTouched": false },
"stages": {
"install": { "status": "pass", "exitCode": 0, "durationMs": 30412, "attempts": 2,
"summary": "install ok after allowBuilds allowance", "outputTail": "",
"allowBuildsNeeded": true },
"config": { "status": "pass", "exitCode": 0, "durationMs": 2310, "attempts": 1,
"summary": "dump ok (exit 0)", "outputTail": "",
"patchEffective": true, "layers": ["dsh-click"] },
"smoke": { "status": "boot-ok", "exitCode": 1, "durationMs": 4123, "attempts": 1,
"summary": "booted without loader failures; headless task did not complete (credentials/model unreachable)",
"outputTail": "", "bootFailed": false, "taskCompleted": false },
"capability": { "status": "observed", "exitCode": 0, "durationMs": 8123, "attempts": 1,
"summary": "tool \"plugin_vet\" called and its result contains the expectation",
"outputTail": "", "capabilityKind": "tool", "name": "plugin_vet",
"expectMatched": true,
"detail": "tool \"plugin_vet\" called and its result contains the expectation" },
"uninstall": { "status": "pass", "exitCode": 0, "durationMs": 5123, "attempts": 1,
"summary": "remove ok (exit 0)", "outputTail": "" },
"cleanup": { "status": "pass", "quarantined": true, "removed": true,
"summary": "owned temp root quarantined and removed" }
},
"verdict": "pass",
"verdictReason": "install, patch, boot, and uninstall verified; headless task inconclusive (see smoke.summary)"
}
判定规则:安装失败、启动失败(smoke.fail)或能力阶段到达 not-registered/failed ⇒ fail;安装通过 + patch 生效 + 启动干净(pass/boot-ok)+ 卸载通过 ⇒ pass(observed 时附能力说明);已安装但后续保证缺失 ⇒ partial;其余 ⇒ unknown。
Permissions & data(权限与数据)
- 只消费公开服务:
ctx.subprocess、ctx.jobs、ctx.storageDomain、ctx.tools、ctx.commands。 - 报告存于
test_drivestorage-domain(表runs、matrices;latest-matrix 指针)。组合中没有storageDomain时(如官方 headless profile),工具照常工作,报告持久化被禁用并记录原因。 - 子进程继承的是已剥离凭据的环境:除非你在
forwardEnv中显式点名,宿主机密钥永远不会进入被测 profile;值永不落日志。 - 所有报告/日志字符串都经纯函数脱敏:令牌字面量、URL 凭据与 bearer 头被涂红,临时根路径被替换为
<testdrive-temp>,输出尾部按字节封顶。
Security boundaries(安全边界)
- 隔离:每次实测在 OS 临时目录下全新
mkdtemp根内进行:一次性DSH_HOME、一次性工作目录、重定向的 pnpm store。被测插件代码只在那个 profile 中运行;宿主机 profile 不受影响。 - 所有权:活跃注册表记录本插件实例创建的每个根目录。清理会拒绝任何「非注册的、不在 OS 临时目录直接子级、不携带
dsh-test-drive-前缀」的路径——不扫%TEMP%全量、不碰他人前缀、不碰真实家目录。 - 清理阶梯:任何变更前先打印完整 dry-run 计划(绝对路径)。删除先把根目录改名为
dsh-test-drive-quarantine-<时间戳>隔离目录,核验后再删;失败则目录保持隔离并如实上报,绝不静默丢弃。成功、失败、超时、中止的所有路径都在finally中执行清理,插件卸载时再次清扫。 allowBuilds是真实权限:放行 git 包的prepare构建意味着在安装时执行该包的代码。放行范围仅限一次性 profile,但仍只测你信任的目标,并固定 commit。- headless 冒烟默认无密钥:启动检查不需要凭据;完成一句任务才需要。要转发凭据请显式配置
forwardEnv,且绝不记录其值。
Known limitations(已知限制)
- 安装 registry/git 目标需要子进程
dsh/pnpm 具备网络访问。 - 冒烟任务需要模型凭据才能到
pass;没有时如实上报boot-ok。 - 没有
storageDomain的组合不持久化报告(drive_report会诚实报错)。 dsh必须能在 PATH 上定位(或配置dshBin);Windows 下自动解析 npm 的.cmd/.batshim,若只解析到.ps1会要求配置dshBin。- 批默认串行执行;提高
batchConcurrency只影响 pnpm-store 磁盘争用,不影响正确性。
Development(开发)
pnpm install
pnpm run typecheck && pnpm run typecheck:ci && pnpm test
pnpm run build && pnpm run verify:self-contained && pnpm run verify:artifacts && pnpm pack
typecheck经本地 harness checkout 解析@deepseek-ai/*;typecheck:ci对照已发布的0.1.0-rc.6类型检查。- 测试使用真实
Context/Session/ToolRuntime/LocalJobRegistry/storage 栈 + 脚本化 subprocess provider。 - 真实 CLI 端到端(需网络 + PATH 上的
dsh):DSH_TESTDRIVE_E2E=1 pnpm run test:e2e—— 用真实安装冒烟循环实测本包自身 checkout。 - 发布:
node scripts/release.mjs <x.y.z>(升版本、CHANGELOG 落日期、重跑门禁、commit + tag;不 push)。
Topics
dsh, dsh-plugin, deepseek-harness, deepseek, cordis, plugin-testing, install-smoke, compatibility-matrix, ci
Contributors(贡献者)
PerryLink —— 设计与实现。
PerryLink DSH Plugin Family
本项目是由 PerryLink 维护的 29 个 DeepSeek Harness 插件之一。如果这个对你有用,其他插件很可能也会:
| Plugin | One-liner |
|---|---|
| dsh-auto-review | 审批链上的第二模型自动审查,默认失败关闭 |
| dsh-background-agents | 持久化后台子代理,带 Web UI 侧边栏、消息与打断 |
| dsh-budget | DeepSeek Harness 的成本治理:预算、碳排与延迟一屏呈现。 |
| dsh-checkpoint-rewind | Claude Code /rewind 等价物:快照、会话分叉、一次性恢复 |
| dsh-claude-move | 将 Claude Code 会话、记忆、技能与 CLAUDE.md 迁入 DSH |
| dsh-click | 跨平台原生桌面控制(DeepSeek Harness),Windows 优先。 |
| dsh-composer-history | Web 输入框的终端式输入历史:方向键、Ctrl+R 搜索 |
| dsh-defend | DeepSeek Harness 的提示注入、越狱与密钥泄露防护。 |
| dsh-doublecheck | 工程纪律门禁:需求质询、测试门禁、对抗式审查 |
| dsh-draw | DeepSeek Harness 的统一静态图像生成路由。 |
| dsh-fast | DeepSeek Harness 的只读性能诊断。 |
| dsh-github | DSH 的 GitHub PR/issue 集成,每次写入都经审批门 |
| dsh-library | DeepSeek Harness 的本地文档知识库。 |
| dsh-local-ai | DeepSeek Harness 的本地模型(Ollama)接入。 |
| dsh-lsp-actions | 经语言服务器的 LSP 诊断、格式化、补全、代码操作与重命名 |
| dsh-mask | DeepSeek Harness 的 PII 脱敏中间件——数据到模型前匿名化,展示层还原。 |
| dsh-mcp-panel | 只读 MCP 运行时面板:/mcp 命令 + 带状态、工具与错误的设置页 |
| dsh-memento | 带审批门的跨会话记忆:ctx.memory 接缝 + SQLite + memory 工具 |
| dsh-observe | DeepSeek Harness 的 OpenTelemetry 与 Langfuse 可观测导出器。 |
| dsh-output-styles | Claude Code outputStyles 等价的运行时样式切换 |
| dsh-permission-rules | Claude Code 风格声明式 allow/deny/ask 权限规则,带审计 |
| dsh-plugin-guide | 按需 agent 技能形式的插件开发知识库 |
| dsh-score | DeepSeek Harness 插件的多指标质量评分。 |
| dsh-session-pin | 在 Web 侧边栏置顶会话,顺序持久化 |
| dsh-session-sync | DeepSeek Harness 的跨设备会话同步——会话存储的专用 git 镜像。 |
| dsh-skill-pack-security | 安全审计技能包:密钥扫描、依赖与供应链审查 |
| dsh-talk | DeepSeek Harness 的语音优先会话闭环:对它说,听它答。 |
| dsh-test-drive | DeepSeek Harness 插件的隔离式安装冒烟实测。 |
| dsh-translate | DeepSeek Harness 的厂商参数翻译与确定性 JSON 修复。 |
License(许可证)
链接
同类插件
strukto-ai/mirage#dsh★ 3502
把文件系统与 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★ 245
社区发行版:TUI、桌面端与 Web UI 统一体验,分层安装、一步到位。
lire1131/dsh-undo-plugin★ 72
DSH 撤销/回退系统:配置变更自动存档,一键撤销/恢复/回退到任意版本,支持 WebUI 与离线 CLI/GUI 工具(DSH 启动失败也能救)。
Jayden-X-L/forkprobe★ 67
同一任务并行试跑多个技能,对比结果选出最优。
forrestchang/dsh-multica-runtime★ 46
让 dsh 运行时跑在 Multica 上。
omdsh-dev/dsh-plugin-check★ 24
插件健康检查:扫描清单协议/patch 格式/构建陷阱,零依赖只读。