终端用户
直接使用者
插件开发者
ctx.plugin() ctx.effect()
插件--apply
插件导出
插件将作为模块的导出,它可以是 默认导出 或 导出整体。
插件通信靠 ctx.emit,服务注入靠 ctx.xxx 属性访问
Cordis 风格(filter + map + Reflect.apply)
启动 Web UI,并且把我这个 cordis.yml 文件作为最高优先级的配置补丁打进去
插件配置只通过 --patch 临时加载,不会影响 DSH 的核心配置或你常用的 profile
覆盖层
01. SKILL插件
skill-filesystem 插件负责加载 SKILL.md
02.代码插件
反应式 coeffect :依赖满足就激活,不满足就停用,无关的变化不动它
依赖不满足时,组件是静默不激活的,不报错。所以「插件装了但没反应」的时候,第一个要怀疑的就是依赖没满足
发现和安装插件
开发和打包
01.插件开发 (Development) 在DSH源码环境中编写和测试插件
02.插件打包 (Packaging)
03.插件发布 (Publishing)
04.插件加载与使用 (Loading & Using)
二次开发Framework
cordis + dsh
cordis:
plugin 插件系统 (Registry)
service context
inject 示例 export const inject = ['database']
event ctx.on() 或 ctx.waterfall()
effect fibre 作用域 (EffectScope)
生命周期 : fork.dispose() 可以停用一个插件
具名隔离域 服务拦截
dash
profile = 配置
web
headless
自定义
bundle--插件--npm 插件
dash-bash-- cordis.patch.yml
一个 seam 是完整的能力:
Service Definition/Service Provider/Consumer
约定(这项能力是什么)、实现(它如何运行)、消费方 API(模型和其他插件面向什么编程)
源码-开创
开发语言和框架 TypeScript Node.js
packages
Monorepo(单一仓库)将多个相关项目放在同一个代码仓库中,便于代码共享和协调开发。
package.json
namespace 来声明插件的配置
js 模块化 --导入和导出
Koishi 加载
### 默认导出 是一个插件(default export) 模块用 export default 导出一个插件对象 / 函数
加载时import plugin from './plugin'(即 module.default / module.exports)
### 整体导出 是一个插件(namespace export) export const name + export function apply
Node.js 内置实现了 CommonJS 规范,所以你在 Node.js 里能直接用 require() 和 module.exports
loader:group
历史经验
01.语言层面
技术比较- YAML 作为配置文件格式
Rust - 所有权机制 (语言层) - 内存安全 (强制保证)
Cordis - 上下文机制 (应用层) - 资源安全 (非强制)
02.系统层面
概念模型层面 发布-订阅”模式--发后即忘”(Fire-and-forget)或“请求-响应”
Kafak系统 topic message 路由
Ros : channel service topic message 为了“数据广播”
03.垂直域层面
同类别
开创性
“拦截管道”--带广播能力的钩子(Hook)
EventEmitter
监听事件 (on) 触发事件 (emit) 只监听一次 (once) 移除监听 (off)
Cordis 中的具体体现:它们如何对应到 API。
core 的运行时依赖只有两个:
cosmokit (基础工具库)和
@standard-schema/spec(配置校验的标准接口)
ctx.on() -> 纯粹的监听器(通知)。
ctx.waterfall() / ctx.bail() -> 钩子(流程控制
钩子 = EventEmitter 的 on() + emit() + 一套额外的调度逻辑(Cordis 在 emit 之后,额外实现了对返回值、next 回调、并发和短路的管理
vendor/cordis/src/events.ts
前端和后端
术语
01.前端
前端的响应式框架 Web 框架-UI 框架
前端应用一样对依赖变化做出反应-异步数据流和变化传播的编程范式。其核心思想是定义数据之间的联动关系
Observable (可观察对象) **:数据的“生产者”或“发布者”
Observer (观察者) / Watcher (监听器) **:数据的“消费者”或“订阅者
派发更新 (Dispatching Updates)
02.Node.js 应用: 从"通知"到"拦截"的全部协作语义
Cordis 假设服务可以随时出现和消失,被依赖的服务发生热替换,Cordis 可以自动重启依赖它的插
03.后端: 后端服务思维:服务是稳定的、预先注册的、启动后不再变化的
web后端 -- 消息-channle -topic
消息后端
服务后端
Cordis
核心层由五个服务组成,全部挂在同一个 Context 对象上:
Fiber :effect 生命周期状态机 + effect 副作用回收,一个插件实例对应一个 Fiber;
Registry : 插件注册表,负责插件去重与 @Inject 依赖声明;
Reflect :服务注册表,同时也是 Context 这个 Proxy 的陷阱处理器;
Events :事件系统,提供五种分派模式;
Logger :日志缓冲与 exporter 机制。
值得注意的是 core 的零 I/O 原则:日志输出、配置加载、热更新,
这些真正跟环境打交道的能力全部以插件形式存在(@cordisjs/plugin-logger-console、@cordisjs/plugin-loader、@cordisjs/plugin-hmr
消息语义
serial(串行) parallel(并行) emit(广播
协作语义
waterfall(瀑布/中间件)
链式决策。这是最智慧的协作方式
:任务沿着链条传递,每个环节(监听器)都可以审查、修改任务指令,然后调用 next() 传给下游;
如果某个环节发现问题,可以直接短路返回(不调用 next),不再向下传达
git wiki的进一步发展
可逆副作用 (Reversible Side Effects):这是 Cordis 最核心的安全机制
提供了一定的透明度 inject
钩子 (Hook) 与拦截机制
主动的安全防线
协作范围
协作
目标、责权与流程、沟通环境和协作工具
流程--谁该做什么,先做什么、后做什么,怎么处理依赖关系
安全的沟通环境
WIki
开放与免费, 开放编辑的模式
允许多人协作编辑并保留所有历史版本--快速简单--技术手段
组织规范
参考
https://www.iceyao.com.cn/2026/08/14/cordis-source-code-read/
Hello DSH:从零开始,看懂「万物皆可插件」 https://github.com/pingfanfan/hello-dsh/blob/main/docs/hello-dsh.md
浙公网安备 33010602011771号