前言¶
在 DeepSeek Harness(DSH)的 Web GUI 里,模型经常在回复里输出 Markdown 代码围栏。若语言标记是 mermaid,开发者通常希望看到流程图、时序图等 SVG 图,而不是一长段源码。社区里已有插件负责懒加载、缩放、全屏查看等能力;若你更关心「模型输出不可信」场景下渲染结果能否少留可联网元素,并希望在流式输出结束后再解析、失败时仍保留源码,可以了解本文介绍的客户端插件。
这是什么¶
dsh-mermaid-fence 由维护者 XiaoBinGan 发布,分类为客户端,面向 DSH Web GUI 聊天界面。它会把已定格(turn 已结束、消息根节点不再带 data-streaming)的 ```mermaid 围栏渲染为 SVG;流式输出中的围栏保持为普通代码块,不做 speculative 解析。
插件 README 明确说明:这是通过改写已渲染的对话 DOM 工作的社区包,不是上游内置能力;DeepSeek Harness 不接受外部 PR,分发路径是带 dsh-plugin 主题的 GitHub 仓库与社区目录。
与同类插件的定位对比(均来自 README):
| 插件 | README 中强调的能力 |
|---|---|
| AKS1st/dsh-mermaid | 懒加载、视口驱动、全屏缩放、报错回环等 |
| timedomain1/dsh-mermaid-renderer | 图/源码切换、缩放、独立查看器 |
| dsh-mermaid-fence(本文) | 在 mermaid 渲染完成后对 SVG 再加固,并配合「仅定格后渲染、失败保留代码块」等行为 |
需要前两者那类交互与查看器时,README 建议优先安装它们;本包侧重加固与安全边界说明。
核心功能¶
仅对已定格围栏渲染¶
宿主 AssistantMarkdown 在 token 仍在到达时为消息根加上 data-streaming,turn 结束后移除。插件只扫描没有 [data-streaming] 祖先的围栏,流式中的围栏与宿主渲染结果字节级一致,避免半写完的图闪烁、逐 chunk 重解析或在模型尚未写完时弹出 parse error。
四种围栏状态(README 行为表)¶
| 围栏状态 | 界面表现 |
|---|---|
| 已定格且源码合法 | SVG 图;可切换显示原始源码;宿主复制按钮仍可用 |
| 已定格但源码非法 | 保留原代码块,并附加可读的 mermaid 解析错误(role="status") |
| 仍在流式输出 | 原代码块,不改动 |
声明为 mermaid 但非图语法 |
原代码块(mermaid 拒绝,错误可见) |
解析失败时源码不会丢失,异常不会抛到宿主控制台;失败围栏会被标记,后续扫描不会反复重试。
安全:securityLevel: 'strict' 与 SVG 加固¶
渲染器在 src/render.js 中硬编码 securityLevel: 'strict',README 写明不可配置——围栏内容是模型输出,视为不可信输入。公开面没有 securityLevel、htmlLabels 开关或独立调色板;主题色从宿主 CSS 变量(--dsw-*)推导,导出方法仅为 render 与 refreshTheme。
strict 仍不足时,mermaid 返回的 SVG 会经 src/harden.js 再处理:移除 script、iframe、object、embed、img、image、audio、video、source、track;剥离所有 on* 属性;丢弃非同文档片段(#id)且非 data:image/ 的 href/xlink:href/src/srcset/data/poster/action/formaction。
README 在 Chromium 上对 mermaid 11.17.2 有实测说明:例如标签 <img src=x onerror=alert(1)> 在 strict 下仍可能留下 <img src="x">,加固后图中不再保留 img/image 元素;click 外链在加固后会去掉 xlink:href,锚点变为惰性。
必须理解的边界:加固发生在 mermaid.render() 完成之后,而 mermaid 构建输出时会向 live document 插入 markup。README 实测表明,含 off-origin img 的标签可能在渲染调用期间就发起一次请求,加固无法阻止 mermaid 在渲染阶段的这一次 transient fetch;它能做的是让最终留在页面 DOM 里的 SVG 不再保留那些可联网元素,并对同一段 markup 的再次插入避免重复拉取。
主题与源码切换¶
颜色绑定宿主 <body> 的 --dsw-* 与暗色模式属性 data-ds-dark-theme;主题切换时会重读 token 并重渲染已挂载图。每张图保留宿主代码块 banner(复制按钮可达),并增加切换以查看原始围栏文本。
卸载与清理¶
插件在 apply 内通过 ctx.effect 注册资源(如 MutationObserver、防抖定时器等),各自带 cleanup,便于随 profile 移除时释放。
安装与启用¶
包未发布到 npm 公共 registry(README 称对 dsh-mermaid-fence 会 404),需从 Git 安装;安装无构建步骤,仓库已提交预构建的 client.js。
在任意环境验证包内容时,可使用:
npm install github:XiaoBinGan/dsh-mermaid-fence
在 DSH profile 中,宿主安装器会把同一 specifier 加入 profile 的 layer 列表:
dsh plugin --profile web add github:XiaoBinGan/dsh-mermaid-fence
安装后的文件树(README 实测)为:
LICENSE README.md client.js cordis.patch.yml index.js package.json
package.json 声明 dsh.bundle.patch: ./cordis.patch.yml,向 bundle 插入条目 dsh-mermaid-fence;客户端注入目标为 @deepseek-ai/dsh-client-ui-chat,平台为 web。当前 package 版本为 0.1.0,许可证 MIT。
插件以当前 DSH 进程及其 Web 客户端的权限运行;安装前请自行阅读仓库源码与 LICENSE,确认符合你的安全与合规要求。
典型用法¶
在 Web GUI 对话中,让模型(或你在消息里)输出标准 mermaid 围栏。turn 结束且语法合法后,界面会显示 SVG。README 示例:
graph TD
A[Start] --> B{Choice}
B -->|yes| C[Done]
B -->|no| D[Stop]
流式生成过程中你会一直看到上述源码块;定格后才会变成图。若需要复制源码,使用宿主 banner 上的复制按钮,或通过插件提供的源码切换查看原文。
适用场景与注意¶
更适合:已在用 DSH Web GUI、需要在聊天里看 mermaid 图,且你接受「功能面较窄、但 README 对安全加固与限制写得较细」的客户端插件;与社区里功能更全的 mermaid 插件相比,你主要需要渲染后 SVG 加固与定格后再解析语义。
需要注意:
- 不 hook 宿主内部渲染接缝,依赖 DOM 结构,宿主大版本变更可能导致脆弱性(README「Known limitations」方向)。
- 无法通过配置放宽安全级别;若标签在 mermaid 渲染阶段触发网络行为,加固不能回溯阻止那一次请求。
- 社区插件目录 SkillHub 上的条目 与 GitHub 仓库独立维护,与 DeepSeek / 幻方无官方从属关系;DSH 生态强调「一切皆插件」,安装来源以你信任的 registry 或 git specifier 为准。
结尾¶
dsh-mermaid-fence 把 DSH Web 聊天里已定格的 mermaid 围栏渲染为 SVG,流式阶段保持代码块,失败时保留源码并展示错误;其差异化在于 mermaid 输出上的 SVG 加固与 README 中对安全边界的实测说明。若你需要懒加载、全屏查看器等完整体验,请先评估 README 提到的另外两个社区插件。