DeepSeek Harness Hub
← 返回列表

huiyeo/dsh-plugin-mermaid-preview

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
未验证

DeepSeek Harness 中的 Mermaid 图表,出现在它们该出现的两个地方:

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/12 · 已提供中文文档

为 DeepSeek Harness 右侧边栏文档查看器(.mmd / .mermaid)提供 Mermaid 图表预览,支持按视图缩放,在缩放显示器上保持清晰

综合分
30.3
GitHub 分
30.3
用户评分
★ Stars
1
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add huiyeo/dsh-plugin-mermaid-preview
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-client-ui-primitives
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

dsh-plugin-mermaid-preview

DeepSeek Harness 中的 Mermaid 图表,出现在它们该出现的两个地方:

- .mmd / .mermaid 文件在右侧边栏文档查看器中以图表形式打开,而不是纯文本。
- 聊天消息中的
功能说明

- 通过 harness 公开的 documentPreviews 扩展点,为 mmd 和 mermaid 文件后缀注册文档预览实现。
- 通过 ui-primitives 的围栏注册表认领 mermaid Markdown 围栏语言,因此聊天记录无需聊天包配合即可渲染图表。
- 使用 mermaid 11 进行渲染,已打包进插件自身的客户端产物中。两个界面共享同一套运行时(配置、调色板采样、测量、设备像素尺寸),因此图表不会在一个地方看起来正确而在另一个地方出错。
- 跟随 shell 的浅色/深色配色方案,并在主题变化时重新渲染。
- 每个图表视图可缩放:图表下方的小控件中有 − / 百分比 / + / 重置,另外还支持在其上使用 Ctrl(或 ⌘)+ 滚轮。100% 表示“填满窗格宽度”,记住的缩放是视图偏好而非文档状态,并且每个预览标签页保持自己的缩放,因为状态存在于渲染器实例中。
- 在聊天中,仍在流式传输的围栏会保持其代码块,直到正文完成:半绘制的图表比读者已经能看到的源代码更糟。
- 当图表无法解析时,回退为显示源代码,并在其上方显示解析错误——代理仍在写入的文件是常见情况,因此渲染失败绝不会隐藏内容。
- 通过 shell 的本地化服务提供简体中文和英文文案。

支持的图表类型即 mermaid 自身的类型:流程图、时序图、类图、状态图、实体关系图、甘特图、饼图、Git 图、思维导图、时间线、象限图、需求图、桑基图、块图、架构图等等。

要求

- 带有 web 配置(@deepseek-ai/dsh-web-app)的 DSH,该配置会挂载 @deepseek-ai/dsh-client-ui-sidebar-documentpreview。在该查看器挂载之前,插件会保持停用状态,因为 documentPreviews 正是它所扩展的服务。
- 聊天围栏还需要一个具有 Markdown 围栏注册表的 harness——即导出了 registeredFences 的 ui-primitives。在较旧的 harness 上,.mmd 预览可正常工作,而  mermaid  块会继续渲染为代码块;插件会记录一行日志说明这一点。它不会失败,也不会连带使文件预览失效。

安装

从 npm 安装

dsh plugin --profile web add dsh-plugin-mermaid-preview

发布的 tarball 包含构建产物,并且 prepublishOnly 会在每次发布前重新构建它们。

从检出安装

harness 提供的是构建后的 lib/client.js,从不读取源代码,并且构建输出不会被提交,因此先构建:

sh
git clone https://github.com/huiyeo/dsh-plugin-mermaid-preview
cd dsh-plugin-mermaid-preview
pnpm install
pnpm run build

然后将该目录安装为 profile 层:
sh
dsh plugin --profile web add /path/to/dsh-plugin-mermaid-preview

dsh plugin add 会安装该包,并且由于 manifest 声明了
dsh.bundle.patch,会将其追加到 dsh.profile.bundles。bundle 层在进程启动时读取,
因此重启 dsh web 进程,然后重新加载页面。

若想无需等待重启即可看到效果,带有 patchReload: live 的 profile 也接受
直接在 $DSH_HOME/profiles/web/cordis.patch.yml 中添加该行,保存时会热挂载,
因此只需重新加载页面:
yaml
- insert:
- id: mermaid-preview
name: dsh-plugin-mermaid-preview

仅在迭代期间添加它,并在进程重启后移除:届时 bundle 层会挂载同一行,
而 documentPreviews.register() 会因重复的实现 id 而抛出错误。

验证该层已生效:
sh
node -e "console.log(require('./package.json').dsh.profile.bundles)" \
run in $DSH_HOME/profiles/web  →  should list dsh-plugin-mermaid-preview

使用 dsh plugin --profile web remove dsh-plugin-mermaid-preview 将其移除。

开发
sh
pnpm install
pnpm run build          # lib/index.js (host half) + lib/client.js (browser half)
pnpm test               # load the built artifact the way the module system does

tests/browser-smoke.mjs 还会在无头 Chrome 中渲染一个图表,
并对生成的 SVG 进行断言。它需要一个能够真正启动的浏览器——
受限沙箱会阻止 Chrome 自身的 IPC,因此请在不受限的环境中运行:
sh
CHROME_PATH=/path/to/chrome pnpm run test:browser

两半如何协同工作

lib/index.js 是宿主半部分,并且有意不贡献任何内容:只有当包作为宿主行挂载时,
才会扫描其浏览器半部分,因此该行的存在是为了让浏览器半部分可被发现。

lib/client.js 是一个单一的传统脚本,它使用 CommonJS 风格的工厂函数调用
window.__ModuleLoader__.load({ id, factory })。
该格式是 harness 自有的客户端 bundle 契约;@deepseek-ai/dsh-client-modules
的浏览器半部分负责提供该文件并驱动它。有两个后果塑造了构建方式:

- 只有 harness 浏览器平台的模块表词汇可以保持外部
(react、react/jsx-runtime、UI 注册表)。其他所有内容——包括 mermaid——都必须内联,
因为模块表无法应答的 require() 会在 bundle 实体化时抛出错误。
- 产物必须是单个文件。 mermaid 通过动态 import() 加载每个图表语法;
插件加载器每个包只提供一个文件,并且没有动态导入钩子,
因此 codeSplitting: false 会将所有语法折叠进工厂函数。
结果是未压缩约 7 MB,只获取一次并按修订版本缓存。

文档正文接收 loading: 'bytes-complete' 内容,因此它会得到
整个文件一次读完,永远不需要分页——分页模式会交给它一个累积的前缀,却无法请求剩余部分。

缩放必须对齐到设备像素网格

渲染器通过自身的 width/height 属性而非 CSS 来调整 SVG 大小,因此浏览器会在目标尺寸上重新栅格化矢量图,而不是重采样位图。它写入的尺寸经过对齐处理,使得 width × devicePixelRatio 为整数:
ts
devicePixels / devicePixelRatio   // 不是 Math.round(cssPixels)

整数个 CSS 像素并不等于整数个 设备 像素。在 125% 缩放的 Windows 显示器上(devicePixelRatio === 1.25),一个 326 px 的盒子覆盖 407.5 个设备像素——偏离网格半个像素——浏览器通过重采样来解决这个问题,看起来就是模糊。它只在某些缩放级别出现:50% 时发虚,而 100% 恰好落在整数上。对 CSS 像素取整解决不了这个问题;对齐设备像素才能解决。tests/ 捕捉不到这一点,因为 jsdom 没有栅格化器。

如果需要重新检查,这些数字可以从页面本身看到——对 SVG 调用 getBoundingClientRect() 再乘以 devicePixelRatio,在每个缩放级别都必须是整数。要从 agent 会话访问真实浏览器,当沙箱禁止启动浏览器时,DSH Browser Control 扩展(Chrome MV3 + 位于 127.0.0.1:9777 的本地 WebSocket 桥接)可以派上用场:该扩展作为客户端向外拨号,因此 agent 只需接受该 socket,然后就能在标签页中 eval。

布局

src/index.js                 宿主部分(设计上为空)
src/client/index.ts          插件主体:文件预览注册 + 聊天围栏声明
src/client/MermaidBody.tsx   文档预览渲染器(拥有自己的缩放)
src/client/MermaidFence.tsx  聊天围栏渲染器(回退到代码块)
src/client/mermaid-runtime.ts  两者共享:配置、调色板、测量、尺寸计算
src/client/theme.ts          外壳调色板采样 + 深色模式订阅
src/client/locales.ts        zh/en 文案
src/client/styles.ts         插件自有的样式表,通过带标记的标签注入
src/client/types.ts          本包编译所依据的最小环境契约
cordis.patch.yml             挂载该行的 profile 补丁
tests/load-artifact.mjs      加载产物;断言共享注册表契约
tests/load-artifact-legacy.mjs  断言在没有围栏注册表时的干净降级
tests/browser-smoke.mjs      无头渲染检查(需要不受限制的浏览器)
tests/zoom.html              双实例测试装置,证明缩放是按视图独立的

许可证

MIT

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群