DSH 插件怎么开发?从最小插件到打包安装

插件开发发布于 2026-08-19作者: DSH-Plugin 插件中心
DSH pluginDeepSeek Harness插件开发Cordisbundle
DSH 插件是一个导出 apply 函数的 TypeScript 模块,基于 Cordis:通过 name 命名、inject 声明依赖、ctx 注册能力、Config schema 接受配置。本文从最小插件写起,讲清打包成 bundle、用 dsh plugin add 装进 profile 的完整流程。

DSH 插件是一个导出 apply 函数的 TypeScript 模块:框架加载时调用 apply 并传入 ctx 上下文,你通过 ctx 注册能力,用 inject 声明依赖,用 Config schema 接受配置。

插件是什么

在 DSH 里,插件就是导出 apply 的模块。 框架加载时调用 apply,传给你一个 ctx(上下文对象),一切能力都通过它注册(来源):

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

export const name = 'my-plugin'

export function apply(ctx: Context) {
  // 在这里注册能力。
}

这就已经是完整的最小插件了。name 是插件的唯一标识,apply 是入口,ctx 提供注册接口。

最小可运行插件

一个会打日志的插件就三行核心代码。 创建 src/my-plugin.ts

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

export const name = 'hello-plugin'

export function apply(ctx: Context) {
  console.log('[hello-plugin] plugin loaded!')
}

--patch 覆盖层把它挂进 Web UI,启动时终端会打印 [hello-plugin] plugin loaded!来源)。

自动清理

通过 ctx 注册的任何东西——事件监听、工具、定时器——在插件卸载时都会自动清理。 有需要手动清理的资源(比如网络连接),用 ctx.effect() 告诉框架怎么清理:

ts
export function apply(ctx: Context) {
  ctx.effect(() => {
    const timer = setInterval(() => console.log('heartbeat'), 5000)
    // 返回的函数在插件卸载时执行。
    return () => clearInterval(timer)
  })
}

声明依赖

插件要用别的服务(如 toolsllm),就导出 inject 声明依赖。 框架会确保依赖的服务就绪后才加载你的插件:

ts
export const name = 'my-tool-plugin'
export const inject = ['tools']

export function apply(ctx: Context) {
  // 到这里 ctx.tools 已经就绪。
  ctx.tools.register(/* ... */)
}

让插件接受配置

导出 Config 类型和同名的 Schemastery schema,默认值直接写在 schema 里。 插件加载时框架用 schema 校验配置并补默认值(来源):

ts
import Schema from '@deepseek-ai/schemastery'

export interface Config {
  greeting: string
  maxRetries: number
}

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

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

约定:凡是不同部署可能要改的参数都定义成配置字段,别硬编码;无效配置要在加载时响亮报错。

打包成 bundle

分发的插件包叫「组合包」(bundle),由一份 package.json 声明 dsh.bundle 目录结构:

hello-plugin/
├── package.json       # 声明 dsh.bundle
├── cordis.patch.yml   # 该组合包贡献的配置层
└── index.js           # patch 行引用的插件模块

package.json 长这样(来源):

json
{
  "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" } }
}

cordis.patch.yml 按包名引用这个包:

yaml
- insert:
  - id: hello
    name: dsh-hello-plugin

安装进 profile

打好包就用 dsh plugin add 装进 profile。 命令转发给 profile 目录里的 pnpm(来源):

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

因为包声明了 dsh.bundle,DSH 会把它追加进 dsh.profile.bundles。启动前先用 dsh --profile demo --dump-config 验证层生效,再 dsh --profile demo 启动。

从 GitHub 安装的坑

git 安装拉的是源码,不会跑你的 build 脚本。 所以 TypeScript 包需要作者提供一个 prepare 脚本,在 pnpm 安装后构建出发布入口;用户侧第一次 add 会被 pnpm 的 allowBuilds 拦住,按报错把允许 key 写进 profile 的 pnpm-workspace.yaml 再重试(来源)。不想让用户做这项授权,就发布到 npm 或交付 pnpm pack 出来的 tarball。

用脚手架快速起步

不想手写就一键生成。 官方社区脚手架 create-dsh-plugin 支持 tool / events / webui 三种模板,并锁定了正确的 @deepseek-ai/dsh-tools 版本:

bash
npx create-dsh-plugin my-plugin -t tool

生成的工程自带 package.jsontsconfig.jsondsh.bundle manifest 和 cordis.patch.yml,加 --verify 还会自动构建并装进临时 profile 验证加载。开发完回到《DSH plugin 怎么安装》把成品装起来试用。

来源:官方「第一个插件」官方「打包与安装插件」dsh CLI README

常见问题

DSH 插件是什么?

是一个导出 apply 函数的 TypeScript 模块,框架加载时调用 apply 并传入 ctx 上下文,你通过 ctx 注册能力。

开发 DSH 插件需要从哪开始?

最快用脚手架:npx create-dsh-plugin my-plugin -t tool,一键生成 tool / events / webui 模板。想手动写就从导出 apply 的最小插件开始。

DSH 插件怎么声明依赖其他服务?

导出 inject 数组,比如 export const inject = ['tools'],框架会等依赖的服务就绪后再加载插件。

DSH 插件怎么打包安装?

在 package.json 里声明 dsh.bundle.patch 指向 cordis.patch.yml,然后用 dsh plugin --profile <name> add <包> 装进 profile。

从 GitHub 安装 DSH 插件报 allowBuilds 错误怎么办?

pnpm 默认不放行 git 依赖的构建脚本,按报错提示把允许 key 写进 profile 的 pnpm-workspace.yaml,重新 add 即可。

来源