dsh-plugin-hot-toggle
在 DeepSeek Harness Web 设置页的「插件 → 启停管理」标签页中,对所有已安装插件一键热启用/停用——点击立即生效,无需重启 DSH,状态自动持久化。
English | 中文文档
<p align="center"> <a href="https://github.com/topics/dsh-plugin"><img alt="dsh-plugin topic" src="https://img.shields.io/badge/topic-dsh--plugin-1f6feb?style=flat-square&logo=github"></a> <a href="https://www.npmjs.com/package/dsh-plugin-hot-toggle"><img alt="npm" src="https://img.shields.io/npm/v/dsh-plugin-hot-toggle?style=flat-square"></a> <a href="https://github.com/5102a/dsh-plugin-hot-toggle/actions"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/5102a/dsh-plugin-hot-toggle/ci.yml?style=flat-square"></a> <a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square"></a> </p>
功能特性
设置页中的「启停管理」标签页:

- 热启停:调用 Cordis Loader 官方
Entry.update({ disabled })——停用即 dispose 插件 fiber,启用即重新 import 启动,进程内立即生效,无需重启 DSH。 - 持久化:启停状态写入当前 profile 的用户 patch 层(
$DSH_HOME/profiles/<profile>/cordis.patch.yml),由官方 HMR watcher 保存即热应用,重启后保持。 - 安全保护:
include、cordis:*、loader/hmr/timer、动态插件宿主等系统核心条目禁止启停(标红「系统核心」)。 - 多维筛选(可叠加):
- 状态:全部 / 已启用 / 已停用 - 来源:全部 / 官方 / 核心 / 非官方(非官方 = $DSH_HOME/plugins 下存在同名目录) - 类型:内置框架 / 客户端 UI / 模型与推理 / 工具集 / 会话与存储 / 沙箱与执行 / 代理与规划 / 服务与集成 / 其他 - 搜索 + 计数显示(过滤数 / 总数)
- 排序:最近安装优先(非官方插件在前)或按名称。
- 多语言:界面跟随 DSH 语言偏好(中文/English),通过官方 locale 服务注册(namespace
pluginHotToggle,39 键双语)。
安装
从本地 checkout(开发)
dsh plugin --profile web add ./dsh-plugin-hot-toggle从 npm(发布后)
dsh plugin --profile web add dsh-plugin-hot-toggle从 git(发布后)
dsh plugin --profile web add github:5102a/dsh-plugin-hot-toggle安装后启动 DSH(或由 HMR 热应用),打开 设置 → 插件 → 启停管理 即可使用。
跨平台支持
插件支持 Windows、macOS、Linux 三大平台(与 DeepSeek Harness 官方支持范围一致)。
| 关注点 | 保证 |
|---|---|
| Node half | 所有文件系统路径均通过 node:path(join/dirname)与 fileURLToPath,无硬编码分隔符 |
| 持久化 | patch 层写入使用 readFileSync/writeFileSync(…, 'utf8'),路径由 Loader include 推导 |
| HTTP API | /plugin-hot-toggle/api/* 是 URL 路由,与平台无关 |
| Web half | 纯浏览器 fetch + React,无 process.platform/navigator.platform 分支 |
| 构建 | scripts/build.mjs 通过 import.meta.url + fileURLToPath + join 解析路径 |
| 开发工具 | Chrome/Edge 发现支持 CHROME_PATH/CHROME_BIN 环境变量或跨平台候选列表;DSH_URL 可覆盖目标地址 |
| CI | GitHub Actions 矩阵:ubuntu + windows + macos × Node 18/20/22 |
工作原理
┌─────────────────────────────┐ ┌──────────────────────────────┐
│ Web (client half) │ fetch │ Node (host half) │
│ settings.plugins.tab │ ──────► │ /plugin-hot-toggle/api/* │
│ 「启停管理」tab │ JSON │ ┌──────────────────────────┐ │
│ - 列表 + 筛选 + 排序 │ ◄────── │ │ ctx.loader.entries() │ │
│ - 启停按钮 │ │ │ entry.update({disabled}) │ │
└─────────────────────────────┘ │ │ → fiber dispose / start │ │
│ └──────────────────────────┘ │
│ ┌──────────────────────────┐ │
│ │ 持久化:写 cordis.patch │ │
│ │ .yml → HMR 热应用 │ │
│ └──────────────────────────┘ │
└──────────────────────────────┘- Node half 只使用公开 seam(
loader、webServer、dshHomePath),零 DSH 核心改动;webServer动态注入,TUI/headless 表面不会 pending。 - Web half 通过同源 HTTP API 与 Node half 通信;写操作带 same-origin 校验(缺 Origin / 跨域拒绝 403)。
- Client bundle 由
src/client.js经零依赖构建脚本生成(node scripts/build.mjs),构建产物提交进仓库,git/npm 安装无需构建权限。
目录结构
dsh-plugin-hot-toggle/
├── package.json # dsh.bundle 声明 + peerDependencies + exports
├── index.d.ts # Host half 类型声明
├── index.js # Node half:Loader 列表/启停 + webServer HTTP API
├── cordis.patch.yml # bundle 层:插入自身插件行
├── src/client.js # Web half 源码(React)
├── lib/client.js # Web half 构建产物(生成,勿手改)
├── scripts/build.mjs # 零依赖 client bundle 构建
├── scripts/screenshot.mjs # headless-Chrome 截图(CDP,零依赖)
├── scripts/verify-render.mjs # 验证「启停管理」标签页已渲染
├── scripts/debug-dom.mjs # DOM/slot 调试辅助
├── tests/patch.test.js # 单元测试(node:test)
├── docs/DSH-PLUGIN-DEVELOPMENT-SOP.md # DSH 插件开发端到端 SOP(双语)
├── .dsh/skills/dsh-plugin-hot-toggle/SKILL.md # 项目 skill:开发/构建/发布 SOP
└── .github/workflows/ci.yml # CI:构建 + 产物新鲜度检查 + 测试API
| Method | Path | Body | Returns |
|---|---|---|---|
| GET | /plugin-hot-toggle/api/list | — | { entries: PluginEntry[] } |
| POST | /plugin-hot-toggle/api/setEnabled | { entryId, enabled } | SetEnabledResponse |
PluginEntry / SetEnabledResponse 见 [index.d.ts](./index.d.ts)。
开发
npm run build # 由 src/client.js 生成 lib/client.js
npm test # node:test 单元测试
npm run check # build + test 一步到位发布
发布已通过 OIDC trusted publishing 完全自动化——推送版本 tag 即触发 Release 工作流:构建、测试、打包、发布 npm(含 provenance 供应链证明)、创建 GitHub Release。无需 npm token,无需手动 2FA。
npm version 0.1.5 --no-git-tag-version # 升级版本
git commit -am "chore: release v0.1.5"
git tag v0.1.5
git push origin master --tags # 触发 CI + Release 工作流 + npm 发布(OIDC)> 包名 dsh-plugin-hot-toggle 发布前已用 npm view 确认可用。
> 关于 peer 依赖警告:本包声明了 @deepseek-ai/cordis 与 react 作为 peer 依赖(与官方 @deepseek-ai/* 插件相同的模式)。DSH 通过 profile 的 flat fallback 从自身安装目录解析这些依赖,因此 dsh plugin add 时出现 "unmet peer" 警告属于预期且无害。
许可证
MIT — 见 [LICENSE](./LICENSE)。