dsh-plugin-installer:带备份与回滚的 DSH 插件安装助手

前言

DSH 的理念是「一切皆插件」,功能扩展基本都落在装插件上。但安装插件这件事本身还是手工活:手动跑安装命令、改配置、重启进程。重启之后当前对话就断了,模型要么从头再来,要么你手动把上下文贴回去。更麻烦的是,如果新装的插件破坏了启动,dsh 直接起不来,删依赖、还原配置全靠自己排查。

dsh-plugin-installer 把「备份 → 安装/卸载 → 重启 → 自动继续对话」整条链路封装成模型工具,交给模型来执行,失败或启动异常时自动回滚。下面介绍它的功能、用法和注意事项。

这是什么

dsh-plugin-installer 是 Quophic 维护的 DSH 插件(当前版本 0.4.1,MIT 许可证),提供 install_pluginuninstall_pluginrestart_dsh 三个模型工具,覆盖插件的安装、卸载和重启。它自身是 host 半区插件,不需要浏览器 UI。engines 要求 Node ^22.19.0 || >=24.0.0

三个模型工具

install_plugin

安装持久化插件(bundle)到指定 profile,流程是固定的:

1、备份:安装前自动把 profile 的 package.jsoncordis.patch.ymlcordis.ymlsettings.yaml 备份到 $DSH_HOME/backups/plugin-install-<时间戳>/,含 manifest 清单。
2、安装:调用官方 dsh plugin --profile <名> add <包>,与 pnpm add 加 bundles reconcile 是同一路径。
3、成功:记录当前运行中的会话 → 自动重启 dsh → 重启完成后向会话注入「继续」提示词,对话无缝接续。
4、安装命令失败:自动回滚备份 → 重启 dsh → 把问题写入会话,让 agent 分析并解决。
5、重启后 dsh 起不来:由一个独立的 detached helper 探测端口,起不来则自动回滚备份并再次重启,随后把回滚结果写入会话。

uninstall_plugin

卸载已安装的插件,保护与安装对等:先备份,再调用官方 dsh plugin --profile <名> remove <包>,成功后重启并续接对话。区别在于回滚动作——卸载命令失败、卸载后启动失败或工具健康异常时,回滚备份之外还会重新安装该插件,把包装回去,还原卸载前的状态(比如卸掉了被其他配置引用的包)。

restart_dsh

只重启 dsh,不安装、卸载、修改任何插件或配置。记录当前会话 → 以隐藏控制台方式重启(无窗口闪出)→ 重启后自动恢复对话。适合让新加载的插件或最新配置生效、恢复正常进程状态。注意它没有安装流程那套备份、回滚和工具健康验证保护。

工具健康验证:端口能起来不等于一切正常

这是这个插件比较关键的一层保护。有一类损坏写法——比如工具的 parameters: {} 空对象、或把原始属性映射直接传给 ctx.tools.register(不经 defineTool 编译)——注册时不会报错,但 dsh 把工具投影给 LLM 时 API 会拒绝,表现为每次对话都报 Invalid schema for function 'X',完全没法聊。

所以端口起来后并不算完:新进程里的本插件会审计所有已注册工具的参数 schema(要求顶层 type: 'object')。审计发现这类损坏,同样自动回滚备份并再次重启,并把问题详情写入会话。

更新插件与自更新

install_plugin 对任何已安装的包(不限于本插件自己)都会自动「先卸后装」强制刷新。之所以要先 remove 再 add,是因为 pnpm 对 file: 依赖在版本号不变时会复用陈旧副本,直接 add 不会刷新。日常更新开发中的本地插件:

{
  "package": "file:E:/GitHub/dsh-plugins/xxx",
  "profile": "web",
  "restart": true
}

版本号没变也没关系,会从最新源码重新安装。更新本插件自己(self-upgrade)同理:

{
  "package": "file:E:/GitHub/dsh-portal/dsh-plugin-installer",
  "profile": "web",
  "restart": true
}

两个注意事项:

  • file: 路径要用正斜杠(file:E:/...),反斜杠会被 shell 当转义吃掉,导致找不到包。file: 源自带版本号,version 参数只对 npm 包名生效。
  • 本地源码更新的完整流程:改 src/npm run build → 调用工具 → 重启后新逻辑生效。

更新操作同样受单次提权审批(非 danger-full-access 会话会请求主人批准)与 allowProfiles 白名单约束。

权限控制

安装、卸载、重启都是敏感动作,插件内置了两层约束:

  • 提示词层:插件注入一段 systemPrompt section,明确告诉模型「安装/升级持久化插件必须调用 install_plugin、卸载必须调用 uninstall_plugin,不要直接跑 pnpm/dsh 命令」。
  • 审批层:默认开启单次提权审批。若调用会话不是 danger-full-access 沙箱模式,工具不硬拒,而是通过 approval seam(ctx.approval.request)向主人发起单次提权审批——批准(allowed-once)后本次调用放行;拒绝、取消或审批通道不可用则 fail closed。这与沙箱 bash 工具的 sandbox_permissions 升权是同一套机制。

配置写在 profile 的 cordis.patch.yml 本插件行上:

requireApproval: false   # 关闭审批(任何模式都可直接调用)
allowAuto: true          # 完全放行 LLM 自动调用(跳过审批)
allowProfiles: ['web']   # 只允许安装/卸载到这些 profile;空数组 = 不限

即使放行,execute 内仍有 allowProfiles 白名单二次校验。

重启与回滚的实现

了解机制有助于排查问题:

  • 重启采用 Node 原生方式:spawn 一个 detached helper,等待旧进程退出并释放端口后,以相同 argv/cwd 重新拉起 dsh,输出追加到 %TEMP%/dsh-install-*.log
  • helper 轮询 web 端口(DSH_WEB_URL 或默认 3080),120 秒内起不来判定为启动失败,自动回滚备份文件并再拉起一次。
  • 工具健康验证协议:端口起来后 helper 继续等待 $DSH_HOME/dsh-install-verify.json(最多 60 秒)。新进程里的本插件通过 ctx.tools.schemas() 枚举全部已注册工具逐个校验;tools/change 事件会触发防抖复查加最多 6 次重试,覆盖加载晚的插件。结论写入 verify 文件,ok: false 则回滚后再拉起。
  • 自动继续对话:重启前把运行中的会话 id 写入 $DSH_HOME/dsh-install-resume.json,重启后对恢复的会话注入 followup(安装成功是继续提示,回滚则是问题详情加解决指引)。
  • 所有操作写入 $DSH_HOME/dsh-install.log,便于排查。

安装与启用

README 给出的安装命令是本地 file: 源的形式:

dsh plugin --profile web add file:E:/GitHub/dsh-portal/dsh-plugin-installer

装完重启一次 dsh,bundle 补丁层在启动时加载,之后三个模型工具即可使用。

典型用法

三个工具的参数都比较短。安装:

{
  "package": "dsh-xxx",
  "profile": "web",
  "version": "0.1.0",
  "restart": true,
  "delayMs": 2000
}

package 支持 npm 包名、file: 路径、git URL;profile 默认 web;version 是可选版本号;restart 默认 true;delayMs 是重启前等待(结果回传时间),默认 2000。

卸载:

{
  "package": "dsh-xxx",
  "profile": "web",
  "restart": true,
  "delayMs": 2000
}

直接重启:

{
  "profile": "web",
  "delayMs": 2000
}

restart_dshprofile 仅作记录,重启不针对单个 profile。需要伴随安装/更新(含备份回滚保护)时,用 install_plugin 并把 restart 留默认 true;只是让改动生效时用 restart_dsh

适用场景与注意

适合经常折腾 DSH 插件的人:维护自己的插件需要反复刷新本地 file: 源,或者希望把装插件的备份、回滚、续聊流程交给模型托管。

几点使用上的注意:

  • restart: false 时不会重启,也就无法做工具健康验证(响应里会注明),新插件要等下次重启才生效。
  • 回滚时会恢复 settings.yaml 等插件配置类文件,安装失败不会留下半修改的配置。
  • 备份目录会累积在 $DSH_HOME/backups/ 下,可定期清理。
  • 插件以当前 dsh 进程的权限运行,能改动你的 profile 配置和已装插件。安装或更新任何插件前,应先检查其源码与许可证(本插件为 MIT)。
  • 引擎要求 Node ^22.19.0 || >=24.0.0

结尾

经过上面的步骤,装插件从手工操作变成一次带备份、回滚和续聊的工具调用,装坏了 dsh 也能自己恢复回来。插件目录页见 https://www.skillhub.cn/plugins/Quophic/dsh-plugin-installer ,源码见 https://github.com/Quophic/dsh-plugin-installer 。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye