dsh-harmony 的官方示例插件:把 DSH WebUI 侧边栏的品牌标识替换为自定义 "Custom DSH" 文字,演示 element() 工厂改写 React 组件。
ⓘ 此插件是大仓库 CH4ACKO3/dsh-harmony 的子包,星数与活跃度统计的是整个仓库。
- 语言
- TypeScript
- License
- MIT
- 分支
- main
安装
$ dsh plugin --profile web add github:CH4ACKO3/dsh-harmony#path:packages/react/examples/rebrand-plugin在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 CH4ACKO3/dsh-harmony/packages/react/examples/rebrand-plugin:先查看仓库 https://github.com/memorax-ai/dsh-harmony 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
一句话定位
这是 dsh-harmony 仓库里的官方示例插件,用来演示如何用 dsh-harmony-react 的 element() 工厂把 DSH WebUI 侧边栏内置的 BrandWordmark 组件替换为一个渲染 "Custom DSH" 文字的简单 React 组件。
核心能力
- 在 DSH 启动前把内置侧边栏的 BrandWordmark 组件整体替换为自定义 React 组件,渲染一行加粗的 "Custom DSH" 文字
- 用
element()工厂声明目标包、目标版本、文件与选择器,把改写约束在指定范围 - 通过
harmony.patch.yml把这个 Patch 注入到 harmony 钩子,无需手动启停 - 通过浏览器端的
window.__ModuleLoader__.load把自己实现的 CustomBrand 导出注册到运行时模块加载器,供 Patch 替换时引用 - 服务端
apply()为空操作,组件真正渲染逻辑全部在客户端执行
技术实现
- 语言: TypeScript(服务端 CommonJS,浏览器端 ESNext)
- 关键依赖:
dsh-harmony-react(element 工厂)、react(浏览器端组件渲染) - 架构模式: 双形态插件 —— 服务端通过
harmony.patch.yml把example-rebrand注册到 harmony 钩子;浏览器端用window.__ModuleLoader__.load注册CustomBrand组件;服务端apply()为空,所有改写由 Harmony 运行时在模块加载前完成 - 入口文件:
src/index.cts(服务端入口)、src/patch.cts(Patch 定义)、src/client.ts(浏览器端组件注册)
适用场景
适合正在学习 dsh-harmony 的插件作者:当你需要写一个会替换 DSH WebUI 中某个 React 组件的插件时,可以参考这个示例把 element() 工厂、harmony.patch.yml 注入和客户端 Component 注册串起来。它本身只是教学示例,并不提供实际业务功能,普通用户通常不会直接装它。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| @deepseek-ai/dsh | 0.1.0-rc.8+ | 示例所在的子目录依赖 dsh-harmony 框架;patch 目标包版本声明为 0.1.0-rc.8(src/patch.cts:6-9) |
| Node.js | ^22.22.3 或 >=24.11.1 | 来自父项目 dsh-harmony 的 engines 字段,子目录 package.json 未单独声明 |
| 运行平台 | Web | package.json#dsh.client.platform 显式声明为 web,仅在 DSH WebUI 中生效(package.json:14-18) |
| 原生模块 | 无 | 不依赖 node-pty、node:sqlite、node-gyp 等 |
安装方式
dsh plugin --profile web add github:CH4ACKO3/dsh-harmony/packages/react/examples/rebrand-plugin
配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| Patch 目标包 | harmony.patch.yml 字段 | 把 example-rebrand 注入到 harmony 钩子,使 Patch 在启动时被加载 | 注入 harmony |
| 客户端立即加载 | package.json#dsh.client | 设为 true 时 WebUI 启动立即加载该插件的客户端入口 | 立即加载 |
| 客户端平台 | package.json#dsh.client.platform | 仅在 web 平台加载客户端代码 | web |
| 目标包与版本 | src/patch.cts 的 target | 被改写的 DSH UI 包,固定为 @deepseek-ai/[email protected] | 0.1.0-rc.8 |
| 替换的选择器 | src/patch.cts 的 select | 匹配要替换的 React 组件名(BrandWordmark) | BrandWordmark |
| 期望匹配数 | src/patch.cts 的 expect | 选择器应命中目标的次数,偏离则 Patch 标记为 failed | 1 |
常见问题
Q: 安装后侧边栏的品牌字标没有变化,是没生效吗?
A: 大概率是 DSH 没重启。Harmony 改写发生在模块加载前,安装或更新后必须重启 DSH,新组件才会生效;可以打开 WebUI 的"设置 → Harmony"页确认该 Patch 处于 enabled 且未 failed。
Q: 这个插件能用来做实际的换肤、换标识吗?
A: 它本身只渲染一行 "Custom DSH" 文字,不直接用于生产。实际使用时需要把 src/client.ts 里 CustomBrand 的内容换成你想要的 React 组件(文字、Logo SVG、图标等),并修改 src/patch.cts 中的 id 与 module/export,让 Patch 指向你自己的导出。
Q: 目标包升级后这个示例会失效吗?
A: 会。Patch 把目标版本钉在 0.1.0-rc.8,当宿主里 dsh-client-ui-sidebar 升级到该范围之外的版本时,Patch 会进入 failed 状态并不再改写,但不会阻塞 DSH 启动。
Q: 卸载它能恢复原来的侧边栏吗?
A: 可以。Harmony 只在内存中改写编译产物,不会修改 node_modules;移除插件后下次启动 DSH,侧边栏就会恢复成内置 BrandWordmark。
Q: 这个示例支持哪些平台?
A: 仅 Web。package.json#dsh.client.platform 显式声明为 web,所以这个 Patch 只会在 DSH WebUI 启动时被加载,桌面端、纯 CLI 等场景不会生效。
Q: 装上它会不会影响其它 dsh-harmony 插件?
A: 不会。这个示例只针对 BrandWordmark 组件做替换,没有声明与其它 Patch 的 before/after 约束;只要不与别的 Patch 同时改写同一个组件,互不干扰。
上手难度
入门 — 整个示例只有三个源文件、几十行代码,主要作用是教学;想换成自己的组件只需要改 src/client.ts 的 CustomBrand 即可。
已知问题与限制
- 目标包版本被硬编码到 0.1.0-rc.8:当
@deepseek-ai/dsh-client-ui-sidebar升级到该范围之外的版本时,Patch 会进入 failed 状态并停止改写(src/patch.cts:6-9)。 - 仅作为教学示例:CustomBrand 只渲染一行 "Custom DSH" 文字,无实际业务功能,直接安装等同于换上一个占位品牌字标(src/client.ts:7-9)。
- 仅 web 平台生效:package.json#dsh.client.platform 声明为 web,桌面端与纯 CLI 场景不会加载该 Patch(package.json:14-18)。
dsh-harmony
Runtime Patch coordination for DeepSeek Harness plugins.
A library for patching, replacing and decorating DeepSeek Harness plugins during runtime.
Usage
Just type "What about we use dsh-harmony" when vibe coding your DSH plugin.
Introduction
Use Harmony when one DeepSeek Harness plugin needs to change another without maintaining a fork. Harmony loads Patches before the target runs, changes its compiled code in memory, and starts Harness with the result.
Source Patches find TypeScript AST nodes with TSQuery and rewrite their source ranges with MagicString. They run one after another, each reading the source left by the previous Patch. This lets several plugins change the same target while leaving installed files untouched.
A provider can place its Patches before or after another provider. One Patch may override that rule, and users may interleave Patches from different providers. When several changes must succeed together, a composite Patch gives them one position and one switch; if a member fails, Harmony applies none of them.
For browser plugins, Harmony also keeps provider-owned <style data-plugin> tags in Patch order. A provider owns one style group, so its last enabled Patch decides where that group appears in the CSS cascade. Harmony repeats the ordering after a Patch reload.
Harmony adds modification to the ways DeepSeek Harness plugins can work together.
Why Harmony
Ordinary DSH extension points remain the first choice when the target exposes the behavior you need. Harmony is for the gap between those APIs and maintaining a fork: changing an internal component, loader entry, or compiled behavior that the target does not expose.
| Without Harmony | With Harmony |
|---|---|
| Hide or duplicate an internal UI and keep both implementations aligned | Replace the selected component or compiled call site in place |
Patch node_modules, carry a fork, or reapply edits after upgrades | Transform source in memory; installed package files remain byte-for-byte unchanged |
| Discover a selector drift only after the UI silently breaks | Pin package version and expect; mismatches fail visibly in status |
| Treat the final bundle as a black box | Inspect the original, every Patch step, and the final transformed source |
| Remove custom edits manually | Disable or remove the Provider to restore the original behavior |
Harmony does not turn compiled internals into a stable public API. It makes that dependency explicit, ordered, inspectable, and reversible.
Respect
Inspired by Harmony, the project of the same name created by Andreas Pardeike and other contributors for C#.
AI agents: use the repository skill
Load use-dsh-harmony for installation, Patch selection and authoring, runtime operations, and troubleshooting.
Install
Requires Node.js ^22.22.3 or >=24.11.1 and @deepseek-ai/[email protected].
npm install -g @deepseek-ai/[email protected]
npm install -g dsh-harmony
dsh web
Open Settings → Harmony after starting the WebUI. For profiles, Desktop integration, updates, and removal, see the installation guide.
Use the terminal UI or non-interactive commands against any profile. Commands contact a running Host transactionally and report live; stopped profiles are validated and updated atomically as offline.
Multiple Hosts may use the same profile. Harmony follows DSH Settings' write model: whole-profile writes are serialized by a file lock and committed atomically; a stale UI save is rejected and refreshed, while concurrent processes use last-complete-write-wins semantics.
dsh harmony --profile web
dsh harmony status --json --profile web
dsh harmony disable my-provider/optional-patch --profile web
dsh harmony enable-provider my-provider --profile web
dsh harmony patch-order show --profile web
dsh harmony patch-order move my-provider/optional-patch --before other-provider/base --profile web
dsh harmony patch-order auto --profile web
dsh harmony provider-order move my-provider --after base-provider --profile web
dsh harmony inspect target-package --patch my-provider/optional-patch --summary --profile web
dsh harmony reload my-provider --profile web
Press Tab in the TUI to switch between Provider and Patch views. The Patch view supports individual and Provider-wide enablement, Patch ordering, automatic sorting, runtime details, and concise inspection. Both views keep the selection visible when a profile is larger than the terminal.
status, patch-order show, and provider-order show exit with status 1 when their health or order constraints fail. patch-order auto and provider-order auto minimize violations while preserving the current order where possible. inspect --summary omits transformed source, while --patch <key> limits inspection to targets touched by one Patch. reload requires a running Host.
Patch model
Harmony runs every Patch from one global patchOrder. Provider-level before and after rules set the usual order. A Patch that declares either rule uses its own rules instead. In Settings → Harmony, users can move a whole provider or place one Patch between Patches from another provider. Plugin and Patch details provide their enable and disable actions, while the Patch status page is a read-only runtime monitor. Harmony checks that the saved list contains every registered Patch exactly once.
Plugin-wide disablement is an independent provider/* flag. It never clears or creates individual Patch flags. Re-enabling a plugin therefore restores only the Patches that were individually enabled before the plugin was disabled.
Every Patch may declare a human-readable description. Harmony exposes it through Patch status and JSON output, and displays it in Settings so users can understand the Patch before changing its order or enablement.
A composite Patch groups several Patches under one order position and switch. Members keep their declared order and apply only when every member succeeds. A failed standalone Patch is reported and skipped; later Patches and the Host continue to run.
Plugin compatibility
Any DSH plugin package can describe its relationships with other plugins under dsh.plugin.compatibility, whether or not it provides Harmony Patches:
{
"dsh": {
"plugin": {
"compatibility": {
"requires": {
"base-plugin": "^2.0.0"
},
"conflicts": {
"legacy-plugin": "*"
},
"integrates": {
"optional-renderer": "^1.0.0"
}
}
}
}
}
requires reports a missing, inactive, or incompatible dependency; conflicts warns when an incompatible pair is active; and integrates reports an available optional integration. These declarations never install, enable, disable, or block plugins. Targets are package names and values are semver ranges. Reciprocal conflict declarations produce one warning, and disabling a Harmony Patch does not disable its owning plugin.
Live reports use the plugins active in Loader. When the profile is stopped, Harmony can only inspect its installation and therefore treats installed profile packages as active.
React-aware patches
Install dsh-harmony-react in a Patch provider when the target is compiled React:
npm install dsh-harmony-react
Use element() to change selected compiled jsx / jsxs calls. Use component() to change the shared component definition. Harmony applies both in the same Patch order as every other Source Patch.
| API | Scope |
|---|---|
element() | One or more selected call sites: replace, wrap, insert, transform props, or remove |
component() | Every call through an initialized variable or named function declaration: decorate or replace |
To let later Component Patches modify the same definition, Harmony rewrites a function declaration as an initialized const. The new binding is not hoisted. If the file reads the component before its declaration, use a core Source Patch instead. React integration covers selectors, Inspect traces, and Studio.
Documentation
| Topic | Guide |
|---|---|
| Runtime architecture | What is Harmony? |
| Installation and profiles | Installation |
| Writing source, semantic, loader, and composite Patches | Patch authoring |
| Provider/Patch order, status, inspection, and reload | Operations |
React-aware patches with dsh-harmony-react | React integration |
| Studio previews | Studio integration |
| Commands, limitations, and failures | CLI · Limitations · Troubleshooting |
Powered by Harmony
If your plugin uses Harmony, you’re welcome to use this badge to show your support!
[](https://memorax-ai.github.io/dsh-harmony/)
Development
All maintained implementation code uses TypeScript. Build artifacts are generated for packaging and are not tracked by Git.
Documentation sources and local preview tooling live on the docs branch.
npm test
Set DSH_HARMONY_PERF=1 when starting DSH to log one structured timing record for each Harmony startup, plugin update, profile update, and manual reload:
DSH_HARMONY_PERF=1 dsh web --no-open
Each record separates Patch preparation, source transformation, Host reload, browser rebuild, and total time. The probe stays inactive by default. Node.js diagnostic tools can instead subscribe to the diagnostics_channel channel dsh-harmony:load without enabling log output.
License
查看使用指南 →
该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。
收录徽章
[](https://deepseek-plugin.org/plugins/CH4ACKO3/dsh-harmony/packages/react/examples/rebrand-plugin)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。