插件注册机制
dsh 有两套"插件注册":
- 静态注册:
cordis.patch.yml→ Loader →ctx.plugin→ RegistryService。仓库自带、profile 装的、bundle 层叠的插件走这条路。 - 动态注册:agent 在运行时通过
cordis_define工具往进程里注入代码。会话级、不持久化,重启即失。
静态注册:PluginInventoryGateway
packages/host/plugin-inventory/src/index.ts:43-70 的 class PluginInventoryGateway:inject=['loader']@Remote('list')直接遍历loader.entries()- 把
entry.fiber.state映射成pending/loading/active/failed/disposed/unloading字符串 - 读时不缓存,靠 Cordis 自身事件维持一致性
PluginInventoryGateway.list() 只暴露非 group entry 的 entryId/moduleName/enabled/fiberPhase——刻意不暴露 config,因为 config 可能含 secret。
动态注册:DynamicCordisRegistry
Registry 结构
packages/extensions/cordis-host-runner/src/registry.ts:141-184 的 class DynamicCordisRegistry:ts
plugins: Map<…, DynamicCordisPlugin>
nextPlugin / nextPackage / nextRun / nextApproval // 四个计数器四个计数器分别 mint prefix-N/pkg-N/run-N/approval-N ID。
DynamicCordisPlugin 结构
packages/extensions/cordis-host-runner/src/registry.ts:36-70 的 DynamicCordisPlugin:packages: Map<…, DynamicCordisDefinition>— 版本历史approvedClientPackages/clientVersionUpdatesApproved— 用户授权门currentPackageId/nextPackageId/run/latestRun— 当前与目标版本
Runner 服务
packages/extensions/cordis-host-runner/src/index.ts:124-145 的 class DynamicCordisRunnerService extends TypertRemoteService:static inject = ['tools']- 持有
DynamicCordisRegistry+CordisInspectRegistryService+startingMap(防并发激活)
define:定义不执行
packages/extensions/cordis-host-runner/src/index.ts:151-202 的 define(request):- 校验 name/purpose
precheckCode沙箱预解析- mint plugin/package ID
- 写
definition.hostCode/clientCode
定义不执行——这是动态注册的安全边界,代码先存下来,激活走单独的 run。
动态插件的不可变 Package 版本
改代码 = cordis_define 追加新 packageId,激活即 cordis_run 切版本:
currentPackageId只在成功后前进- 失败不回滚到旧版(由调用方显式
run回滚)
这让动态插件的版本演进有审计轨迹,失败状态可被 inspect 工具观察到。
两种身份模型
| 静态插件 | 动态插件 | |
|---|---|---|
| 身份 | Loader entry id | plugin-{prefix}-{N} |
| 持久化 | cordis.patch.yml / profile | 进程内 mint,重启即失 |
| 来源 | npm 包 / 本地路径 | agent 运行时生成 |
文档与工具同源
packages/typert/generator/src/cordis-catalog.ts:136-200 的 class CordisCatalogProjector 从 Typert 模型投影出 Service/Event catalog。packages/typert/generator/src/cordis-catalog.ts:403-413 的 collectEvents/collectServices:扫 interface Events/interface Context 块,解析 @mode 标签 + JSDoc。cordis-catalog.ts 既是文档生成器也是 cordis_inspect_list 工具的数据源(tool-cordis/src/api-catalog.ts 由 scripts/gen-cordis-api.ts 用同一次 AST walk 生成),保证"文档"与"模型可见 API"同源。
审批与取消
DynamicCordisRegistry 的 pendingRequests 索引支持"用户审批中"的激活请求被取消/认领(claimRequest first-answer-wins)。这是动态插件的人机协作门——agent 定义代码,用户在 UI 上批准,系统才激活。