薄控制台扩展:统一管理 UI 插件(dsh.client 包)
August 12, 2026 · View on GitHub
状态:已实现(0809→0810 交付,面板分三区管理两类插件,0810 验证站端到端通过)。本文为设计记录:薄控制台让「插件管理 = 薄控制台」职责完整。面板结构与三类插件对比见 console README 与 插件类型对比。
设计要点
两类插件写不同层:repository 操作 home 级 $DSH_HOME/cordis.patch.yml 的 repositories 列表(增删行 = 装/卸),UI(bundle)插件启停写 profile 级 $DSH_HOME/profiles/web/cordis.patch.yml 的 disabled 标记(官方 vendor/include 支持 disabled?: boolean)。
扩展动机:薄控制台给 profile 插件安装态一个浏览器管理入口——0811 起外部插件统一经 web profile 安装,面板分三区(安装插件统一入口 / 已加载插件启停 / insert 插件实时挂载)统一管理。
Node half
/api/plugin-console 路由(与面板写同一安装态):
GET/POST /repositories:读/写 home 级 repository 源列表(结构化行:解析 + 插件名 + 版本 + 挂载态)GET /installed+POST /installed/<id>:已加载插件(loader 树 + repository 合并枚举)/ bundle 启停GET /updates+POST /updates:repository 远端 commit 检查 / 固定 refGET /versions+POST /versions/refresh:bundle npm 版本检查(缓存)POST /bundles:bundle 安装 / 更新 / 移除
实施记录
- Node half:上述路由(
GET /installed合并 repository 插件、GET /repositories结构化) - client half:面板三区(统一行渲染 + 源行 + 安装表单)
- 验证:0810 验证站挂载 console → 面板显示已加载插件(含 repository 行)→ boot graph 含
plugin-console/client.js→ 读写路由正常
待实现:bundle 实时展开(消除「装 bundle 需重启」的反直觉)
状态:设计定稿,未实现(2026-08-11 记录)。 实现时机见 ROADMAP「下一轮候选」。
问题
官方 bundle 安装路径(dsh plugin --profile web add / 面板 bundle 区)要求重启 web:bundle 的挂载指令在包内 cordis.patch.yml,层栈列表在 package.json——两者都不在配置 HMR 的 watch 名单里(HMR 只 watch profile 级 + home 级两个用户 patch 文件),且层栈是 boot 时一次性合成的。用户侧「装个插件还要重启」非常反直觉。
这不是技术限制,是官方没接这条线。 已实测(0811):写 profile patch 的 insert 行 → 配置 HMR 实时重放 → 插件即时挂载(web 日志 [HMR-PROBE] applied,零重启)。实时通道存在。
方案:bundle 行「展开」进用户 patch
bundle 包内的 patch 行格式与用户 patch 完全一致(- id: / - insert:,支持 !!js)。安装 bundle 时:
pnpm add <bundle包> ← 装进 node_modules(秒级,无重启)
→ 读包内 cordis.patch.yml 的全部行
→ 展开写入用户 profile patch(被 HMR watch 的那层)
→ 配置 HMR 实时重放 → 整个 bundle 实时生效
要点:
- 零重启:走配置 HMR 实时通道,与 insert 插件一致
- 持久化:展开写入用户 patch,重启后依然生效
- 语义完整:包内所有行都展开(不只主插件),不丢 config/disabled/其余 insert
- 可覆盖:用户已有同名行按 id 合并,用户 patch 内顺序决定覆盖
边界与代价
| 场景 | 处理 |
|---|---|
| 小 bundle(一层一行挂自己,如 console) | insert 行完全等效,实时(当前已如此) |
| 中 bundle(挂自己 + 几行 config) | 展开全部行 → 实时 |
| 大 bundle(web-app 40 行) | 展开会撑大用户 patch;但此类属于官方随 profile 装的(base/web-app 走 profile 模板层栈),不经过 console 安装流程,实际碰不到 |
| bundle 更新 | 重新展开(diff 旧行换新行) |
| 用户已有同名行 | 按 id 合并,用户 patch 顺序决定覆盖 |
| 层栈关系 | 可选:不进层栈(纯靠用户 patch 展开);层栈留给官方模板 bundle(base/web-app) |
原理注释
「insert(配置 HMR)是底层原语、bundle 层栈只是 boot 批量应用包内行的封装」的推论:用户侧要「装即用」,console 可以把用户装的 bundle 转成展开的 insert 行,走实时通道;官方层栈保留给 profile 模板组合(稳定优先)。
相关
- 迁移记录:官方 0809 覆盖度(转向决策)、示例迁移(dsh-task-status/dsh-loop/dsh-navbar)