动态插件
运行时动态插件模型:Host 与 Client 两半、不可变包版本、define/run/stop/undefine 生命周期与审批流程
动态插件临时扩展正在运行的 Harness 进程:不改动仓库源码、不重启即可挂载新能力。它适合临时界面、一次性工具或快速验证。它只存在于当前进程——定义不会写入磁盘配置,也不会在进程重启后保留。
Host 与 Client 两半
一个动态插件由两半组成,各自运行在不同平台:
运行在 DSH 的 Node.js 进程侧。适合文件、网络、命令、Agent/Session 访问、Host 事件、服务、模型工具,以及可供 Client 调用的 JSON 方法。
两半通过包内私有 JSON 方法通信,方向是 Client → Host,只有无损 JSON 能跨越这条边界。选择 Host 还是 Client 是实现细节:需要可见页面行为时用 Client,其余用 Host。
不可变的包版本
一个动态插件由稳定 id 标识,可长期修改;每次修改都追加一个新的不可变包(Package),而不是覆盖旧版本。
- pluginId:稳定标识一个插件,可随时间修改。
- packageId:该插件下某个不可变的 Host/Client 源码版本。
- currentPackageId:最近一次完全成功的版本。
- nextPackageId:等待审批、正在尝试、等待 Client 激活或最近失败的目标版本。
因为旧版本不被覆盖,你可以在版本之间更新或回滚。
生命周期
- define(定义):记录源码,不运行它。定义只校验参数与语法。
- run(运行):激活一个确切版本。首次运行、重启当前版本或回滚用 run;切换到不同版本用 update。
- update(更新):停止旧版本,再启动目标版本。更新失败不会自动重启旧版本。
- stop(停止):停止当前运行并取消未完成的审批/激活请求,但保留定义、版本与授权。
- undefine(永久删除):停止并删除插件及其所有版本。
审批流程
激活一个未授权的 Client 包会创建审批请求;获得授权后才会继续。一次勾选只授权当前版本,两次勾选授权同一插件的后续版本。授权在技术失败后仍然有效;用户拒绝后不应再次请求。
异步结果
run 返回「starting」只表示请求已进入异步流程,不等于成功。成功、拒绝或技术失败都会通过运行时状态上报;失败后应读取诊断并修正同一插件,而不是静默另建一个。
每个副作用都可逆
插件的服务、事件、工具、处理器、定时器、Slot、样式与主题覆盖都必须属于当前 fiber 的生命周期。用 ctx.effect()、ctx.on() 或官方 API 返回 disposer(资源释放函数),使 stop、update、undefine 能撤销每个副作用。
下一步
- 在 Host 侧读写服务与事件,见 Host 服务与事件。
- 在浏览器侧注册 Slot UI,见 Client UI 与 Slot。