dsh-plugin-dev-skills/examples/hello-plugin

38Star1Fork0Issue0Watching

DSH 插件开发技能包中的最小生命周期示例,演示插件加载与 ctx.effect 自动清理的标准写法。

License
MIT
分支
master
agentagent-skillagent-skillsaiai-agentawesome-dsh-pluginclaude-codecodex

安装

$ dsh plugin --profile web add github:zimodzh/dsh-plugin-dev-skills/examples/hello-plugin

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

一句话定位

这是 dsh-plugin-dev-skills 仓库自带的一个最小可运行示例,向 DSH 注册一个名为 hello-plugin 的占位插件,用于演示插件加载与 ctx.effect 自动清理的标准写法。它不提供任何业务功能,只是给想学习 DSH 插件开发的用户的参考样板。

核心能力

  • 加载时在宿主日志输出一行 [hello-plugin] plugin loaded!,作为插件层被正确加载的视觉信号
  • 通过 ctx.effect 注册一个 5 秒一次的心跳定时器,持续输出 [hello-plugin] heartbeat
  • 演示 Cordis 插件模型的标准入口:export nameapply(ctx),无需任何构建步骤
  • 演示 package.json 通过 dsh.bundle.patch 指向 cordis.patch.yml 的组合包声明方式
  • 演示 cordis.patch.ymlinsert 写法:声明 idname,让 Node 模块解析找到已安装的插件代码
  • 作为 dsh-plugin-dev 技能 references/plugin-anatomy.md 文档配套的可复制运行示例

技术实现

  • 语言: JavaScript(ESM,"type": "module"
  • 关键依赖: 无任何运行时依赖,仅依赖宿主 Cordis 容器提供的 ctx.effect(来自 @deepseek-ai/dsh 或其运行包)
  • 架构模式: Cordis 插件模型,apply(ctx) 中通过 ctx.effect 注册可清理的副作用;返回的清理函数在插件卸载时由宿主自动调用
  • 入口文件: examples/hello-plugin/index.js

适用场景

适合正在学习 DSH 插件开发、想跑通"插件加载与生命周期清理"完整链路的开发者。当你读完 references/plugin-anatomy.md 文档想要一份能直接 dsh plugin add 跑起来的最小例子时,装上这个示例并观察终端日志里出现的 [hello-plugin] plugin loaded! 与每 5 秒一次的 heartbeat,就能直观确认 plugin 层是否被正确加载,以及 ctx.effect 的清理是否生效。生产场景请基于该示例自行扩展。

前置依赖与兼容性

依赖最低版本说明
DSH未声明仅依赖宿主自带的 Cordis 容器与 ctx.effect 接口,未在 package.json 中声明 engines
Node未声明仅使用 ESM 语法,未在 package.json 中声明 engines
平台跨平台纯 JavaScript 实现,无原生模块
原生模块package.json 中无 native 依赖

安装方式

dsh plugin --profile web add github:zimodzh/dsh-plugin-dev-skills/examples/hello-plugin

配置项

本插件无需额外配置。所有行为(启动日志、心跳间隔、清理时机)都直接写在 index.js 源码里,没有暴露任何配置项。

常见问题

Q: 安装后这个插件能做什么实际功能?

A: 没有业务功能。它只在加载时打印一行日志,然后每 5 秒打印一次心跳。它的全部价值在于演示 DSH 插件的最小骨架与生命周期清理机制,让你用肉眼观察到 plugin 层是否被正确加载。

Q: 这个插件需要构建步骤吗?

A: 不需要。index.js 是纯 ESM JavaScript,宿主直接当 Node 模块加载;package.jsonfiles 字段也只发布 index.jscordis.patch.yml 两个文件,没有 TypeScript 编译或打包步骤。

Q: 安装后看到 [hello-plugin] plugin loaded! 之后要等多久会看到心跳?

A: 5 秒。setInterval 间隔在 index.js:11 写死为 5000 毫秒,从插件加载完成时刻开始每 5 秒打印一次 [hello-plugin] heartbeat

Q: 卸载插件后心跳会立即停止吗?

A: 是的。ctx.effect 返回的清理函数会在插件卸载时被宿主自动调用,里面的 clearInterval 会清掉这个定时器,停止继续输出心跳。这也是这个示例想强调的标准范式:所有需要清理的副作用都必须放进 ctx.effect,否则卸载时会泄漏。

Q: 这个示例和同仓库的 greet-tool 示例有什么区别?

A: hello-plugin 是最简生命周期示例,只演示插件加载与 ctx.effect 自动清理;greet-tool 是模型可调用的工具示例,演示 defineToolparametersexecuteoutput 三段式写法。两者侧重点不同,建议一起读。

Q: 为什么 cordis.patch.ymlid 写成 hello 而不是 hello-plugin

A: 这是 Cordis 层 id 的命名选择,与 index.js 里 export 的 name 字段没有强制对应关系。id 是配置图里的层标识,name 是插件在运行时的逻辑名,二者可以不同。

Q: 看 hello-plugin 源码能学到的核心知识点是什么?

A: 三个:package.jsondsh.bundle.patch 必须指向 cordis.patch.ymlindex.js 只需要 export nameapply(ctx);任何通过 ctx 注册的副作用(这里是 setInterval)必须放进 ctx.effect,卸载时才不会被泄漏。

上手难度

入门 — 示例本身只有 15 行代码,一个 setInterval 调用加一个 cordis.patch.yml,跑通即代表已经掌握了 DSH 插件加载与生命周期清理的标准骨架。

已知问题与限制

  • 心跳间隔 5000 毫秒与心跳文案 '[hello-plugin] heartbeat' 都直接写在 index.jssetInterval 回调里,源码中没有读取任何配置或环境变量分支,想要修改间隔或文案只能改源码(evidence: examples/hello-plugin/index.js:11-13)
  • cordis.patch.ymlid: helloname: dsh-hello-plugin 都是硬编码字符串,如果用户环境里已有同名插件 id 会产生命名冲突(evidence: examples/hello-plugin/cordis.patch.yml:2-3)
  • 源码中未声明任何 enginespeerDependenciesoscpu 字段,DSH 版本兼容性需由宿主侧校验(evidence: examples/hello-plugin/package.json:1-8)
dsh-plugin-dev-skills/examples/hello-plugin — DeepSeek Harness 插件 | deepseek-plugin.org