Chapter 03

Cordis:一切皆插件的运行时基础

目标不是背 API,而是建立能从顶层设计一路推导到源码细节的心智模型。读完本章,你应该能解释“为什么这样设计”,而不仅是“代码在哪里”。

1. Cordis 的五个核心概念

官方 primer 可以压缩成:Plugin、Context、Service、Typed Event、Reversible Effect。这五个概念解释了 DSH 80% 的架构形状。

Context:能力容器,不是全局变量

ctx.toolsctx.llmctx.sessions 看起来像属性,背后是 service resolver。child context 可以 extend / isolate / intercept,从而在局部改变解析,而不污染父作用域。

Service:稳定接口名

消费者依赖 ctx.shell 而不是 import LocalShell。这样本地、远程沙箱、容器后端都能提供同一个接口。

inject:把启动顺序变成依赖图

插件声明自己需要什么 service,Cordis 在依赖满足时激活;依赖消失时相关插件可被停用。这比手写“先 init A 再 init B”更适合 HMR 与动态替换。

effect:时间可组合性

注册工具、监听事件、增加 prompt section,本质上都改变共享环境。Cordis 要求这些修改带 disposer,因此插件卸载时可逆向清理。

typed event:横切策略的扩展点

DSH 通过 waterfall / serial / parallel / emit 区分“可改写请求”“按序决策”“并行等待”“纯通知”。

源码定位:Cordis Primer · docs/cordis-primer.md
打开官方源码/文档
源码定位:Vendored Cordis · vendor/cordis/README.md
打开官方源码/文档

2. 用 DSH-Lite 先模拟这个模型

type Disposer = () => void;
class Context {
  services = new Map<string, unknown>();
  effects: Disposer[] = [];
  provide(name: string, value: unknown) {
    this.services.set(name, value);
    const undo = () => this.services.delete(name);
    this.effects.push(undo);
    return undo;
  }
  dispose() {
    for (const undo of this.effects.reverse()) undo();
  }
}

真正 Cordis 远比这复杂,但这个最小模型已经解释“注册为什么必须能撤销”。