首页 / DeepSeek Harness 入门教程 / 插件配置与发布

DeepSeek Harness 入门教程

插件配置与发布

本教程共 32 篇 · 第 24 篇 · 更新于 2026-08-15 · 约 5 分钟阅读

插件配置Schemastery校验组合包bundle发布npmdsh-plugin

本节目标:让插件接受配置并校验,再把插件打包成组合包发布,最后能被 dsh plugin 安装进 profile。

配置从哪来

cordis.yml 里每个 Cordis 配置项都可以携带 config 块。插件声明一个 schema,在运行 apply 前验证这个块。错误配置会导致加载失败,并给出准确的错误——插件绝不会在配置不完整时启动。

Config 类型与同名 schema

import type { Context } from '@deepseek-ai/cordis'
import Schema from '@deepseek-ai/schemastery'

export const name = 'my-plugin'

export interface Config {
  greeting: string
  maxRetries: number
  verbose?: boolean
}

export const Config: Schema<Config> = Schema.object({
  greeting: Schema.string().default('Hello'),
  maxRetries: Schema.number().default(3),
  verbose: Schema.boolean().default(false),
})

export function apply(ctx: Context, config: Config) {
  console.log(config.greeting)  // 用户传入的值或 schema 默认值
}

导出的 Config 既是 TypeScript 接口,又是同名的运行时 schema:消费方获得类型,Cordis 获得验证器。默认值直接写在 schema 里,apply 收到的永远是完整且经过验证的配置。

Warning

不要导出普通对象作为 Config。Cordis 接受任意 Standard Schema 验证器(仓库用 Schemastery 定义),普通对象不满足接口,加载会失败。

配置校验

传入不合法配置,比如 targets: 'not-an-array',框架输出类似:

ValidationError: invalid config:
  - $.targets expected array but got not-an-array (at targets)

插件的 fiber 进入 FAILED 状态,加载失败明确报错。schema 校验发生在插件加载时,不是运行时。需要严格约束时用 Schemastery 表达:Schema.string().required() 必填、Schema.union(['fast', 'accurate']) 枚举取值。

loader 还支持 !!js 标签计算配置值,适合注入密钥:

- name: './config-demo.ts'
  config:
    greeting: !!js process.env.DEMO_GREETING ?? 'Hello'

设计原则

  • 无硬编码可调参数:不同部署可能取不同值的参数,都必须定义为配置字段。检验标准一句话:能不能在 cordis.yml 里改这个值而不动代码?
  • 配置错误要响亮:在 schema 里表达自身完备的约束,让无效配置在加载时失败,而不是运行时静默行为异常。
  • HMR 自动生效:修改 cordis.yml 中某个插件的 config 后,框架卸载旧实例、加载新实例。注册都是 effect,替换后不留旧注册,不用重启进程。

打包为组合包(bundle)

本地插件用 --patch 加载;交付给别人的插件打包成组合包——附带一个配置层的 npm 包。目录结构:

hello-plugin/
├── package.json       # 声明 dsh.bundle
├── cordis.patch.yml   # 配置层
└── index.js           # 插件模块
{
  "name": "dsh-hello-plugin",
  "version": "0.1.0",
  "type": "module",
  "main": "index.js",
  "files": ["index.js", "cordis.patch.yml"],
  "dsh": { "bundle": { "patch": "./cordis.patch.yml" } }
}
- insert:
    - id: hello
      name: dsh-hello-plugin   # 用包名,不用文件路径

dsh.bundle 回答「这个包贡献什么」;profile 的 dsh.profile manifest 回答「由哪些组合包按什么顺序组成」。两者都由 package.json 描述,但没有任何东西同时是两者。没有 dsh.bundle 声明的包仍可安装,只作普通依赖,不激活任何层。

安装进 profile

dsh plugin --profile demo add ./hello-plugin

首次使用会初始化 profile(@deepseek-ai/dsh-base 自动成为第一个组合包),pnpm 链接该包,并把它追加进 dsh.profile.bundles。先验证再启动:

dsh --profile demo --dump-config   # 输出里应有 "# == dsh-hello-plugin" 层
dsh --profile demo

移除同样简单:dsh plugin --profile demo remove dsh-hello-plugin,依赖和层一起删。

三种分发方式

方式用户安装命令装到什么需要构建授权
npm 发布dsh plugin add your-package预构建的 lib/
tarballdsh plugin add ./pkg-0.1.0.tgzpnpm pack 产物
Git 安装dsh plugin add github:you/repo源码

Git 安装拉的是源码,没有任何环节运行 build 脚本,TypeScript 包到手没有 lib/ 输出,加载会失败。作者要提供自包含的 prepare 脚本(直接转译 src/,不依赖 monorepo checkout);用户要在该 profile 的 pnpm-workspace.yaml 里加 allowBuilds 授权,然后重新 add。

Warning

构建授权允许该包的代码在安装时于你的机器上执行,且不在任何沙箱之内。只对源码可信的包授权,并锁定 commit:github:you/hello-plugin#<sha>

发布、版本与发现

面向普通用户优先发布 npm:pnpm build && pnpm publish,用户装到的就是预构建代码,零授权。版本管理遵循语义化版本;项目处于 rc 阶段(基线 @deepseek-ai/dsh 0.1.0-rc.6),依赖的 harness API 可能破坏性变更,升级插件前对照 changelog。

发布后把 GitHub 仓库打上 dsh-plugin topic,插件就能被社区列表检索到——这是官方约定的插件发现方式。

小结

  • 配置由 schema 校验,默认值写在 schema 里,apply 收到完整配置。
  • 校验失败 fiber 进 FAILED,配置错误在加载时响亮报错。
  • 打包成 bundle:声明 dsh.bundle + cordis.patch.yml + 插件模块。
  • 安装:dsh plugin --profile <name> add <包>;npm / tarball / Git 三种分发。
  • Git 安装要构建授权,只对源码可信的包授权并锁定 commit。