dsh-reload:不重启 DSH 热重载插件与 Skill

前言

在 DeepSeek Harness(DSH)里做插件或 Skill 开发时,改完 lib/index.js 或磁盘上的 Skill 文件,往往还要重启应用才能看到效果。DSH 自带 HMR,但在实际主机上测下来,用户安装在 profile node_modules 里的第三方插件通常不会被自动重载;Skill 注册表也不会按 TTL 自行刷新。下面介绍的 dsh-reload(维护者 louisyeaaah)用两个工具、两条斜杠命令,把「改代码 → 立刻重载 → 失败回滚」和「强制 Skill 再发现 + 不可见诊断」收进一个工作流类插件。

这是什么

dsh-reload 是 DSH 社区插件,分类为工作流。它提供:

工具 / 命令 作用
reload_plugin 对已加载插件:清模块缓存 → 释放旧 fiber → 重新 entry.init();任一步失败则回滚到旧模块。也可激活「已注册但未运行」的行。
reload_skill 强制 Skill 再发现(清注册表缓存并广播 skills/change),报告增删改,并诊断指定 Skill 为何不可见。
/reload-plugin 与 reload_plugin 相同,在 Composer 里手动输入。
/reload-skill 与 reload_skill 相同。

插件还 bundled 一份 Skill(skills/dsh-reload/SKILL.md),apply() 时通过 ctx.skills.register() 注册;另含备用 filesystem skill provider,用于缓解部分环境下 Skill 列表异常的问题(设计细节见仓库 DESIGN.md)。

为何需要它(与内置 HMR 的差距)

README 归纳了三类缺口(在 live host 上测量,证据见 DESIGN.md §6):

  1. 插件源码未被 watch:profile 的 HMR 配置里 root: [],编辑插件文件不会触发监视。
  2. HMR 自动重载跳过 node_modules:loadDependencies() 对 URL 含 /node_modules/ 的模块直接返回,用户装在 <profile>/node_modules/<pkg>/ 的插件依赖集为空,不会被 partial reload。 monorepo 内通过 symlink 指向 packages/* 的官方插件则不同。
  3. Skill 注册表无 TTL:只有 provider 主动 invalidate() 才会清目录;filesystem provider 若在某个 root 上 list() 抛错,可能整批 Skill 不可见。

reload_plugin 针对前两类;reload_skill 针对第三类并带诊断。

环境与限制

  • DSH:面向 0.2.0-rc.2 主机内部 API(cordis 4.0.4、@deepseek-ai/dsh-tools / dsh-commands 0.2.0-rc.2)。package.json 声明 peer:>=0.2.0-rc.1 <0.3.0-0。
  • Node:engines.node 为 >=22.0.0;作者在 Node 24.18.1 / Electron 44.0.0 上验证。
  • 仅主机侧:浏览器端插件代码不会被重载(见仓库 Limitations)。

安装或启用前,请自行查看 GitHub 源码 与 MIT 许可证;插件以当前 DSH 进程权限运行。

安装

dsh plugin --profile <profile> <args> 会把参数转给 profile 目录下的 pnpm,以下命令均来自官方 README。

1. 从 GitHub 安装

dsh plugin --profile <profile> add github:louisyeaaah/dsh-reload

2. 从发布 tarball 安装(无需构建,URL 钉在 tag)

dsh plugin --profile <profile> add "https://github.com/louisyeaaah/dsh-reload/releases/download/v0.1.4/dsh-reload-0.1.4.tgz"

3. 从 npm(发布后)

dsh plugin --profile <profile> add dsh-reload

4. 在应用内:打开 Plugin Manager / dsh-market,安装 dsh-reload。包内 dsh.bundle.patch 指向 cordis.patch.yml,其中 id: tool-reload 的 insert 行注册上述工具与命令。

本地开发可用仓库 scripts/install.sh [profile](默认 profile:desktop),拷贝产物并合并 patch;文档称无需重启即可热组装新 patch 行(约 4s),可用 reload_plugin({}) 自检。

典型用法

在会话或工具调用里可按 README 示例操作:

reload_plugin({})                                     # 列出插件行:包名、entry id、是否运行
reload_plugin({ name: 'dsh-video' })                  # 按包名重载(也可用 entry id,如 'tool-video')
reload_plugin({ name: 'dsh-video', dryRun: true })    # 预览将清除的模块,不改动
reload_skill({ name: 'my-skill' })                    # 强制再发现并诊断该 Skill

补充行为:

  • reload_plugin({ filter: '@deepseek-ai/' }) 可列出更广范围(默认可视第三方、本地及未运行行)。
  • reload_skill() 不带 name 仅刷新;reload_skill({ cwd: '/path/to/repo' }) 用绝对路径解析项目 Skill 根(不支持 ~ 展开)。
  • 人工输入:/reload-plugin dsh-video、/reload-skill my-skill。

重载成功时报告会列出被清缓存并重新求值的模块 URL、耗时,以及工具列表是否变化;失败则恢复缓存并重新初始化旧模块,避免半加载状态。仅目标插件包根下的自有模块会被清除(不含嵌套 node_modules),共享依赖仍留在缓存中。

适用场景

  • 正在开发或调试 profile 内第三方 DSH 插件,希望改 lib/*.js 后立刻验证 tools / services / commands / prompt,而不重启 Electron 应用。
  • Skill 在磁盘存在但会话目录里看不到,需要 强制刷新注册表 并查看诊断信息。
  • 需要 激活已安装但未成功启动 的插件行。

不适合期望「浏览器 UI 插件热更新」的场景;也不应替代对上游 DSH 版本与 peer 依赖的兼容性检查。

参考链接

dsh-reload 把插件热重载与 Skill 再发现做成可重复调用的工作流,适合在 DSH「一切皆插件」的生态里缩短本地迭代闭环。

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

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

Xiaoye