墨图 MoTu — 把对话里的代码块渲染成真正的图。DSH 可视化套件:Mermaid / Graphviz /…
32.9/100
综合分
4
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/23 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/molanxuan-del/DSH-MOTU.git状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
是什么
生态插件
可安装,未声明 dsh 能力
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 11 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
⚠︎ 实装验证未通过(unknown · 2026/10/27) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-visual-kit(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/18 00:25:41
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 63 处,展示前 56 条)
- 读取本地文件lib/index.js:216
const parsed = JSON.parse(readFileSync(INTEGRITY_FILE, 'utf8')) - 读取本地文件lib/index.js:247
const info = statSync(file) - 读取本地文件lib/index.js:258
const bytes = readFileSync(file) - 读取本地文件lib/index.js:609
skillBodyCache = readFileSync(SKILL_FILE, 'utf8') - 写入本地文件lib/index.js:905
mkdirSync(join(homedir(), '.dsh', 'visual-kit'), { recursive: true }) - 写入本地文件lib/index.js:906
appendFileSync(file, `${JSON.stringify(record)}\n`, 'utf8') - 读取本地文件lib/index.js:969
const info = statSync(file) - 读取本地文件lib/index.js:977
const bytes = readFileSync(file) - 发起网络请求lib/client.js:342
const response = await fetch(CATALOGUE_URL, { credentials: 'same-origin' }) - 发起网络请求lib/client.js:386
const response = await fetch(CONFIG_URL, { credentials: 'same-origin' }) - 发起网络请求lib/client.js:1878
const response = await fetch(REPORTS_URL, { - 写入剪贴板lib/client.js:4459
await navigator.clipboard.writeText(text) - 发起网络请求lib/client.js:4538
const response = await fetch(DIAG_URL, { - 发起网络请求lib/client.js:4558
const response = await fetch(REPAIR_URL, { - 发起网络请求lib/client.js:5869
await fetch(DIAG_URL, { - 读取本地文件scripts/vendor.mjs:113
const bytes = readFileSync(path) - 读取本地文件scripts/vendor.mjs:125
return JSON.parse(readFileSync(join(modules, name, 'package.json'), 'utf8')).version - 写入本地文件scripts/vendor.mjs:135
mkdirSync(vendorDir, { recursive: true }) - 写入本地文件scripts/vendor.mjs:152
mkdirSync(dirname(target), { recursive: true }) - 写入本地文件scripts/vendor.mjs:153
copyFileSync(source, target) - 写入本地文件scripts/vendor.mjs:168
writeFileSync( - 写入本地文件scripts/vendor.mjs:180
mkdirSync(join(skillDir, 'references'), { recursive: true }) - 写入本地文件scripts/vendor.mjs:320
writeFileSync( - 写入本地文件lib/reports.js:75
await mkdir(dirname(file), { recursive: true }) - 写入本地文件lib/reports.js:77
await writeFile(temp, text, 'utf8') - 写入本地文件lib/reports.js:78
await rename(temp, file) - 读取本地文件lib/reports.js:89
return JSON.parse(await readFile(file, 'utf8')) - 读取本地文件lib/reports.js:189
names = await readdir(root, { withFileTypes: true }) - 写入本地文件lib/reports.js:216
await mkdir(dir, { recursive: true }) - 写入本地文件lib/reports.js:217
await writeFile(join(dir, 'report.html'), input.html, 'utf8') - 写入本地文件lib/reports.js:218
await writeFile(join(dir, 'report.json'), `${JSON.stringify(input.spec, null, 2)}\n`, 'utf8') - 读取本地文件lib/reports.js:251
await stat(join(existing.dir, 'report.html')) - 读取本地文件lib/reports.js:294
await stat(join(entry.dir, 'report.html')) - 读取本地文件lib/reports.js:316
return { entry, html: await readFile(join(entry.dir, 'report.html'), 'utf8') } - 删除本地文件递归lib/reports.js:335
await rm(entry.dir, { recursive: true, force: true }) - 读取本地文件scripts/check-renderers.mjs:42
window.eval(readFileSync(join(root, 'lib', 'client.js'), 'utf8')) - 读取本地文件scripts/check-svg-xml.mjs:11
for (const name of readdirSync(dir).filter((n) => n.endsWith('.svg')).sort()) { - 读取本地文件scripts/check-svg-xml.mjs:12
const text = readFileSync(join(dir, name), 'utf8') - 写入本地文件scripts/check-ui.mjs:10
await mkdir(out, { recursive: true }) - 发起网络请求scripts/check-ui.mjs:22
const catalogue = await (await fetch('/dsh-visual-kit/renderers.json')).json() - 发起网络请求scripts/check-ui.mjs:102
const catalogue = await (await fetch('/dsh-visual-kit/renderers.json')).json() - 写入本地文件scripts/check-ui.mjs:376
await writeFile(join(out, 'results.json'), JSON.stringify({ checks, errors }, null, 2)) - 读取本地文件scripts/demo-overflow.mjs:86
window.eval(readFileSync(join(root, 'lib', 'client.js'), 'utf8')) - 写入本地文件scripts/demo-overflow.mjs:104
mkdirSync(join(root, '.scratch', 'preview'), { recursive: true }) - 写入本地文件scripts/demo-overflow.mjs:134
writeFileSync(join(root, '.scratch', 'preview', 'demo-arch-before.svg'), beforeSvg, 'utf8') - 写入本地文件scripts/demo-overflow.mjs:135
writeFileSync(join(root, '.scratch', 'preview', 'demo-arch-after.svg'), after.markup, 'utf8') - 写入本地文件scripts/design-showcase.mjs:18
mkdirSync(outDir, { recursive: true }) - 写入本地文件scripts/design-showcase.mjs:85
writeFileSync(join(outDir, name), svg, 'utf8') - 读取本地文件scripts/dom-env.mjs:217
const source = readFileSync(file, 'utf8') - 读取本地文件scripts/preview.mjs:35
window.eval(readFileSync(join(root, 'lib', 'client.js'), 'utf8')) - 写入本地文件scripts/preview.mjs:54
mkdirSync(outDir, { recursive: true }) - 写入本地文件scripts/preview.mjs:83
writeFileSync(file, String(result.markup), 'utf8') - 写入本地文件scripts/showcase.mjs:390
mkdirSync(outDir, { recursive: true }) - 写入本地文件scripts/showcase.mjs:450
writeFileSync(join(outDir, `${example.id}.svg`), result.markup, 'utf8') - 写入本地文件scripts/showcase.mjs:459
writeFileSync(join(outDir, 'index.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf8') - 读取本地文件scripts/ui-fixture.mjs:54
if (path === '/client.js') { res.setHeader('content-type', 'text/javascript'); res.end(readFileSync(clientPath)); return }
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
展开完整介绍(119 字)↓
墨图 MoTu — 把对话里的代码块渲染成真正的图。DSH 可视化套件:Mermaid / Graphviz / nomnoml / ECharts(含交互)/ Vega-Lite / 手写 SVG,六引擎本地伺服、离线可用、完整性校验。
README
由 DeepSeek 最新模型翻译生成墨图 · MoTu
把对话里的代码块变成真正的图。
墨图(MoTu) 是 DeepSeek Harness 的可视化套件:模型在回复里写一段带语言的代码块,浏览器端就把它渲染成图。十一种渲染方式全部随插件本地伺服——不联网、不走 CDN,使用本机随包引擎;每个引擎按需懒加载,只画流程图的会话不会下载图表库。
三个名字,一处对应:仓库 DSH-MOTU · 品牌 墨图 / MoTu · npm 包名 dsh-visual-kit(也是插件 id 与路由前缀 /dsh-visual-kit/*)。
设计取向一句话:一张清楚的图胜过三段文字。所以插件不只是"能渲染图",它还会要求模型在讲解结构、流程、对比、方案时主动配图,并给出成图规范。
效果
以下都是本仓库产出的真实图形(npm run showcase 生成,走对话里同一条渲染管线)。每个渲染器给一到两个有代表性的用法。
Mermaid ·
流程图、时序图、状态图、甘特图、饼图、脑图——覆盖面最广的一个。
Mermaid 流程图:带子图的分层调用
Mermaid 时序图:一次支付交互
Graphviz · dot /
节点多、关系杂时交给它自动布局;支持子图(cluster)分组。
展开完整文档(README 剩余 1 节)
墨图 · MoTu
把对话里的代码块变成真正的图。
墨图(MoTu) 是 DeepSeek Harness 的可视化套件:模型在回复里写一段带语言的代码块,浏览器端就把它渲染成图。十一种渲染方式全部随插件本地伺服——不联网、不走 CDN,使用本机随包引擎;每个引擎按需懒加载,只画流程图的会话不会下载图表库。
三个名字,一处对应:仓库 DSH-MOTU · 品牌 墨图 / MoTu · npm 包名 dsh-visual-kit(也是插件 id 与路由前缀 /dsh-visual-kit/*)。
设计取向一句话:一张清楚的图胜过三段文字。所以插件不只是"能渲染图",它还会要求模型在讲解结构、流程、对比、方案时主动配图,并给出成图规范。
效果
以下都是本仓库产出的真实图形(npm run showcase 生成,走对话里同一条渲染管线)。每个渲染器给一到两个有代表性的用法。
Mermaid ·
流程图、时序图、状态图、甘特图、饼图、脑图——覆盖面最广的一个。
Mermaid 流程图:带子图的分层调用
Mermaid 时序图:一次支付交互
Graphviz · dot /
节点多、关系杂时交给它自动布局;支持子图(cluster)分组。
Graphviz 依赖图:应用与存储的依赖关系
nomnoml · nomnoml
语法极短,适合画小而清楚的框线图与状态机。
nomnoml 状态机:订单状态流转
ECharts ·
数据图表首选:中文排版友好,双轴、图例、标签都开箱可用。
ECharts 组合图:柱状与折线双轴
ECharts 环形图:流量来源占比
Vega-Lite · vega-lite
写规格而不是写配置:分层、分面、统计变换是它的强项。
Vega-Lite 分层图:柱状与趋势线
手写 SVG ·
语义图(对照、时间线、路线图、闭环、架构)优先用它:无需专用图表语法,成图效果也最可控。下面这张是其中一种版式,另外九种见 preview/design/。
手写 SVG:单体与拆分的对照
手写 SVG:工程师四级成长
手写 SVG 没有语法解析风险,但结构、文字溢出与留白仍要自己检查 —— 这与引擎图不同,引擎会自己排版。
等距剖面 · isometric
把结构关系、层次和"切开看内部"画成展示柜里的一件东西。投影与取景由引擎计算,模型只描述有什么、在哪、什么颜色 —— 不用(也没法可靠地)自己算等距坐标。
等距剖面:中空星球展示柜
需要转动或切开看内部时用 json { "cut": 0.7, "case": 2.2,
"objects": [
{ "type": "shell", "r": 1.34, "thickness": 0.17, "color": "amber", "label": "碎裂岩壳" }, { "type": "ball", "r": 0.44, "color": "ink", "label": "黑洞" }, { "type": "ring", "at": [0, 0, 0.12], "r": 0.88, "count": 7, "size": [0.24, 0.24, 0.18], "color": "purple", "label": "悬空城" } ] }
零件配方:图元是积木,配方是成品件。写一行 { "type": "part", "part": "stack", "layers": 3 } 比一个个摆板子省得多,也更不容易摆歪。
| 配方 | 是什么 | 参数 |
| base | 底座 + 四角支脚 | size, thickness, footHeight, feet |
| stack | 分层堆叠(分层架构图的主力) | layers, size, gap, thickness, colors[] |
| rack | 机架:四柱 + 顶底 + 槽位 | size, height, slots, post |
| grid | 阵列:集群 / 机柜排 / 节点网格 | count[列,行], size, spacing |
| tower | 塔楼:角柱 + 楼板 | size, floors, floorHeight, slab |
| dial | 表盘:盘面 + 表圈 + 指针 | r, height, needle(0..1), needleColor |
| rail | 导轨 + 滑台 + 两端限位 | length, gauge, carriageAt(0..1), carriageColor |
| post | 立柱 + 底座法兰 + 卡箍 | height, r, clampAt(0..1), clampColor |
零件配方:分层部署
case 是展示柜:数字表示半边长(立方体),[宽, 深, 高] 表示全尺寸(扁柜子——宽而矮的场景塞进立方体会浪费大半画幅)。
什么时候不该用它:一次性的空间插图,手写 svg 更灵活(引擎只能画它图元允许的东西)。引擎的价值在要交互、或同一张图会反复改角度改配色时 —— 那时手写每次都要重付约 1.3 万字符,引擎是 0。
体素模型 ·
同一套投影引擎,另一种形态:几何来自体素网格而不是图元,产物是方块。用 shapes 程序化生成(shell / ball / box / cluster / collapse),或直接用 layers 写 ASCII 图层 —— 后者最省 token。
体素剖面:方块化的空间关系 json { "grid": 17, "cut": true, "palette": { "#": "amber", "o": "purple" },
"shapes": [{ "shape": "shell", "r": 7, "thickness": 1.6, "fill": "#" }] }
颜色写语义令牌(amber/blue/green/purple/red/ink/muted)就自动跟随浅深主题。grid 上限 32,方块越密产物越大。
两个条目共用一个引擎(客户端半的 isoAdapter 按 kind 参数化),但栅栏、开关、语法行与设置页预览各自独立 —— 想要体素的人不必先猜它藏在「等距展示」里。交叉使用会被点名:在 voxel 里写 objects 会提示那是
视觉风格(用户可选)
在「可视化套件 → 生成风格」中比较整图预览并点选,自动保存。风格指导后续生成图的构图、信息层级、排版、配色与标注;绘图方式单独选择。
已有引擎图会按其支持的外观参数重绘,无法保证各引擎完全相同的版式。已有手写 SVG 保留作者的布局与颜色,不会自动转换;需要换风格时,请让模型按新风格重新生成该图。
| 风格 | 特征 | 适合 |
| 墨图默认 | 暖中性纸感底、颜色即含义(新增/推荐/问题/部分/进阶)、0.5px 发丝边框、开放箭头 | 讲解、方案对照、成长路线 |
| 简洁风 | 冷灰蓝底、规整留白、主副标题、克制配色、清楚的连线与图例;红电力/蓝数据仅用于电气内容 | 架构、流程、原理说明、对照与剖面插图 |
选择会同步到模型提示段、按需加载的风格规范和引擎支持的浅深主题外观。模型读取完整规范时只收到当前选中的一套,避免其他风格的规则干扰;图中的数据与事实关系保持不变。
十一种渲染方式
| 渲染器 | 栅栏 | 擅长 |
| Mermaid | mermaid | 流程、时序、状态、甘特、饼图、脑图 |
| Graphviz | | nomnoml | nomnoml | 小而清楚的框线图 |
| ECharts | | Vega-Lite | vega-lite / | 手写 SVG | svg | 概念对照、时间线、路线图、闭环、架构图 |
| 等距剖面 | | 体素模型 | voxel / | 指标卡 | metrics | 一排读数:阈值色 + 可选迷你趋势(表格顶替不了时用它) |
| 用例矩阵 | | 任务报告 | report | 一轮任务的交付档案:结论、改动、验证与风险;下载得独立网页并自动归档 |
没有语言的代码块会按内容识别(首行是 flowchart TD 的 mermaid、以 digraph 开头的 Graphviz、以 <svg 开头的 SVG……)。
交互图表
普通 echarts 代码块继续输出静态 SVG。需要悬停查看数值、图例筛选或区间缩放时,使用新语言:
{"legend":{},"tooltip":{"trigger":"axis"},"xAxis":{"type":"category","data":["周一","周二","周三"]},"yAxis":{"type":"value"},"series":[{"name":"访问量","type":"bar","data":[120,180,150]}]}
工具栏提供重置、复制配置、导出当前 SVG 和反馈;图例与 dataZoom 必须在 JSON 中声明。主题改变会重建实例,源码更新会完整替换配置。交互模式默认开启,可以在能力页或配置 renderers.echarts.interactive 中关闭;关闭后新语法以静态图显示并说明原因,ECharts 总开关和自动渲染总开关继续生效。
输入只接受 JSON 和内联数据,最多 256 KiB、10,000 个数据点。不执行配置中的函数或 HTML,提示框强制使用 richText;不允许图片、URL 或其他外部资源引用。交互初始化失败后仅尝试一次静态渲染;两次都失败时保留源码与错误卡片。每次初始化最多等待 15 秒,第三方库的同步计算不能被取消信号强行中断。
本轮建立展示句柄与生命周期基础,图片继续使用 DSH 原生能力,网页截图、三维与视频尚未接入。
等距与体素图的交互
这些操作全部在浏览器本地重算——投影是纯数学、零依赖,所以转一个角度不需要重新请求模型,也不产生任何 token。同一份 spec 的静态图与交互图走同一条渲染管线,两者不会画得不一样。
放大展示
密集的图在 360px 画布里会缩到看不清。图框工具栏的「放大」把图铺满窗口,操作方式与看图一致:
打开后进入完全不透明的暖深色看图界面,聊天、侧边栏和文件列表不会透出。插件热更新时会同步刷新样式,不会因旧样式残留而把图叠进正文。
看图控件集中在窗口底部,避开 DSH 右上角的最小化、最大化和关闭按钮;窄屏下仍可完整操作。
- 点图形区域任意处关闭(拖动过就不算点击,不会误关);
- 滚轮连续缩放,一格约 15%(触控板的细碎位移更小),且光标下的细节留在光标下;
- 双击在「适应窗口」与「原始尺寸」之间切换;
- 拖拽平移,触屏支持双指捏合缩放;
- 控件 + / − / 适应 / 1:1 / 关闭;键盘 Esc 关闭、0 适应窗口、1 原始尺寸、方向键平移、Tab 焦点不逃出面板。
它展示的是快照 SVG(与「下载」写出的同一份字节),而不是搬动活的图表实例——原图继续在正文里渲染,矢量快照放到多大都清晰,静态图与交互图走同一条路径。关闭后焦点回到触发按钮、页面滚动恢复原状;插件卸载时遮罩层一并收掉。
任务报告与报告库
任务收尾时,模型可以附一段 report ,对话里显示一张摘要卡;点「查看」直接在应用内打开完整报告页,点「下载」导出同一份自包含 HTML:结论、徽章、改动表、验证与未测范围、风险与来源。报告页跟随当前「墨图 / 简洁风」的配色与版式,离线、可打印、带深浅色。
- 只在改过文件或运行过命令的任务后生成;纯问答不生成。设置页「可视化套件 → 任务报告」有总开关(默认开),关掉后不再提示、不再自动归档;手动写的 report 仍可渲染、查看和下载。
- 报告里能画流程图:sections[].flow 用 2–6 个节点、最多 10 条边描述流程,报告页把它渲染成内联 SVG(深浅色跟随页面),不是贴一张外部图。
- 查看进右侧栏:报告卡片「查看」在 DSH 右侧栏新增的「报告」标签页里打开这一份(同源 iframe 加载归档页);卡片另有「复制链接」(原「复制」改名「复制源码」)与「下载」。老宿主没有右侧栏服务时,退回左侧「报告」面板,再退应用内查看层。
- 反馈在后台修复:点「反馈并修复」后宿主跑一个后台子代理(subagents,不新建可见会话、不占本会话上下文),结论直接回卡片;不支持时给「复制修复提示词」兜底,绝不自动开新会话。
- 自动归档:报告写入项目的 .dsh/visual-kit/reports/<id>/(report.html / report.json / meta.json);没有工作区或项目不可写时回退到 ~/.dsh/visual-kit/reports/。索引在 ~/.dsh/visual-kit/reports/index.json。
- 左侧「报告」:DSH 左侧入口,列出所有报告,可按状态/项目筛选、搜索、删除。「打开」在应用内用同源 iframe 预览;预览条可复制链接、下载 HTML,或直接删除当前这一份。它只读本地文件,不上传任何内容。
- 不想把报告提交进仓库,就把 .dsh/visual-kit/ 加进项目的 .gitignore;插件不会自动改它。
- 报告由模型填写,插件无法核实「有没有改文件/跑命令」;这是提示级规则,漏写时说「补一份报告」即可。
字段:title / round / status / verdict / badges / facts / meta / notice / sections(items / table / details / notice)/ sources / footer。语法与正反例见 skill/references/report.md。
安装
git clone https://github.com/molanxuan-del/DSH-MOTU.git
cd DSH-MOTU
npm install # 安装依赖并自动执行 prepare → 生成本地引擎产物
dsh plugin --profile <name> add link:$PWD
npm install 会通过 prepare 脚本自动运行 npm run vendor:把引擎产物拷进 vendor/、写入哈希清单、生成技能文件。vendor/ 不入库(6.6 MB 第三方产物),克隆后一次 npm install 即可得到。
安装后在 DSH 设置里会出现本插件的配置页与「可视化套件」能力页,全部改动即时生效。
给模型用
插件在模型侧做了三件事:
1. 一行常驻提示:要求模型讲解结构、流程、对比、方案或数据时主动画一张图(不必等用户要求),并说明各栅栏的选型与成本纪律;
2. dsh-visualization 技能:按需加载的完整参考——选型表、各引擎语法要点、手写 SVG 设计系统(配色令牌、发丝线、开放箭头、字号层级、/<desc> 无障碍);
3. 能力与宣传一致:关掉某个渲染器后,它的栅栏恢复成普通代码,模型也不再被告知它能用。
设置面板
绘图偏好
「可视化套件」设置页中的「绘图方式」提供三个选项,点选后自动保存:
- 自动选择(默认):不确定时选这个。模型按内容选择适合的画法。
- 常规图表优先:适合流程图、复杂架构和数据图表,由 Mermaid、Graphviz 等引擎负责布局。
- 手写 SVG 优先:普通流程图、架构图、对照图和路线图默认由模型直接编写 SVG,更依赖模型的设计能力。只有明确指定其他画法、需要真实交互或统计图表引擎、节点密集难以手写排布时才使用其他引擎。
原理是把选型建议同时写入模型的常驻提示与按需技能,不代表精确概率,也不保证模型一定采用某种画法。用户明确指定的画法和渲染器开关优先。例如你可以直接说「这张用 Mermaid」或「这张用手写 SVG」。它影响后续生成,不转换已有图表,也不会因为保存偏好而重置现有交互图表。关闭模型提示与技能后,或关闭自动渲染时,偏好暂不发送给模型。旧版数值配置仍可读取,会对应到这三种模式。
当前画法同时出现在技能摘要、技能正文和常驻提示中,优先于通用选型表与省 token 建议;手写优先时 SVG 排在选型表首位,其他引擎标为备选。设置保存后用于后续请求,不会改写已生成的回复或正在生成中的请求。
设置里的「可视化套件」页把能力摆在明面上:
- 成本价签:渲染器卡片与开关都显示预估 token。模型侧提示段按实际内容计(关掉即整段不再发送)、技能摘要按需、绘图方式三档每图、非默认风格每轮 +47;任务收尾报告另有一条固定提示行,价签显示在开关上。每张渲染器卡片显示预估 token——「每图 ≈N tokens」与「常驻 ≈M tokens/轮」。两者含义不同:常驻部分每轮都要付(栅栏、选型条目、语法补句),图源只在生成时付一次。悬停可看到精确字符数与估算口径。实测:Mermaid 每图约 40 tokens,等距剖面约 232,手写 SVG 约 3,500(示例是最小可用,所以手写 SVG 按一份真实插图实测值计)。
- 总开关:自动渲染 / 模型侧提示段 / 技能 / 反馈后在后台新会话里修 / 反馈时让 agent 直接修;
- ECharts 交互模式开关:保留静态语法,按需启用新语法;
- 任务收尾报告开关:默认开;只在改过文件或运行过命令后要求模型附 report,并自动归档到项目;
- 十一个渲染器各一个滑动开关,每张卡片带实时预览——预览走的是对话里同一条渲染管线,所以面板不会和实际出图不一致;
- 开关写入的是插件的真实配置行(经宿主 configEditor 持久化),不是页面上的一层影子状态,因此配置页、提示段、技能、渲染目录始终同步。
出错时
渲染失败不会破坏对话:原代码块保留,下面出现一张错误卡片,写明哪个渲染器、什么原因、怎么改,并附该渲染器的最小可用示例(可折叠)。
静态错误卡片可以「反馈并修复」,交互图表与交互错误卡片提供「反馈」:
1. 把诊断写入本地日志 ~/.dsh/visual-kit/reports.jsonl;交互反馈保留原始失败阶段和模式,源码按 UTF-8 截断为最多 16 KiB,不发送给作者;
2. 静态错误在开启自修时,默认开一个新会话去修(复制本会话作为上下文,所以修复的 agent 能看到那张出错的图),本会话的历史与上下文都不受影响。新会话会出现在工作区里,你可以打开看、也可以不管。
3. 想要旧的「直接投给本会话」也行:设置页关掉「反馈后在后台新会话里修」即可,但那会往本会话追加一个回合、消耗本会话 token。
4. 失败不会静默回退:新会话拉不起来时只报告失败,绝不偷偷把请求投进本会话——那正是这个开关要避免的事。
交互反馈仅记录和复制诊断,不自动修改插件。反馈、复制、会话投递分别显示真实结果。
完整性校验
vendor/integrity.json 记录每个引擎文件的 SHA-256、字节数与版本。三层校验:
1. 启动时校验所有已启用渲染器的引擎文件;
2. 伺服时每个文件首次读取再校验一次;
3. GET /dsh-visual-kit/health 随时可查逐文件结果。
strict 模式下校验失败的渲染器自动禁用(并在图的位置给出可读原因),而不是加载一半诡异失败。
路由
| 路由 | 用途 |
| GET /dsh-visual-kit/config | 有效配置、启用集合、提示文本、开关快照 |
| POST /dsh-visual-kit/config | 写入配置(字段按配置 Schema 校验,未知字段丢弃) |
| GET /dsh-visual-kit/renderers.json | 浏览器渲染用的渲染器目录(含示例源码,供面板预览) |
| GET /dsh-visual-kit/assets/<id>/<file> | 引擎产物(白名单伺服,长缓存,哈希不符返回 503) |
| GET /dsh-visual-kit/health | 完整性报告 |
| GET/POST /dsh-visual-kit/diag | 诊断信标与反馈落点 |
| POST /dsh-visual-kit/reports | 保存一份任务报告(spec + HTML),按内容哈希去重 |
| GET /dsh-visual-kit/reports | 列出本地报告(项目内与用户目录) |
| GET/DELETE /dsh-visual-kit/reports/<id> | 打开/删除一份报告;页面带 CSP、不走外部资源 |
开发
npm install # 依赖 + prepare 自动生成 vendor/
npm test # 宿主、十一个适配器、展示生命周期、报告库与交互回归测试
npm run check:renderers # 无头渲染十一个渲染器,产出真实产物并校验
npx playwright install chromium
npm run check:ui # 真实 Chromium:悬停/图例/区间缩放/导出/主题/取消/失败注入
npm run showcase # 重新生成上面那组展示图(真实浏览器渲染,几何异常会失败)
node scripts/design-showcase.mjs # 重新生成手写 SVG 那十张设计示例
关于两种"生成图"的脚本:scripts/showcase.mjs 在真实浏览器里渲染并写入 preview/showcase/(README 用图),带几何守卫——产物尺寸不合理就报错,因为无头环境测不了文字宽度,mermaid 流程图会算出错误高度。scripts/preview.mjs 是快速冒烟,写进 .scratch/preview/、不入库,几何不作为依据。
Chromium 夹具使用真实引擎与插件路由,结果与浅深色窄屏截图写入 .scratch/ui-check/。夹具不替代 DSH 宿主验收;宿主需提供 configEditor 才能持久化开关。本地支持基线为 DSH 0.2.0-rc.2。
本轮已用桌面版随附的 DSH 0.2.0-rc.2 启动隔离宿主,验证了原生设置页保存、刷新与重启后持久化、原生助手回复中的交互栅栏、跨会话切换、SVG 导出及本地反馈。测试消息通过宿主会话接口创建,没有调用付费模型。旧版 CLI 0.1.5-rc.1 缺少设置写入服务,会显示可读错误。
部分宿主会隐藏未知语言的标签;客户端通过宿主公开的会话聊天快照恢复原始栅栏语言,并按同源码出现顺序区分静态图与交互图,不依赖 React 内部字段。
新增一种可视化(5 步)
1. npm i <引擎>(devDependency);
2. lib/renderers/manifest.js 加一条记录(id / languages / label / output / assets / defaults / syntaxHint / 能力标志);
3. lib/client.js 的 ADAPTERS 里加一个适配器(loadEngine + render,30–80 行);
4. npm run vendor(拷贝产物、更新哈希、重新生成技能文件);
5. npm test && npm run check:renderers。
配置界面、设置面板、提示段、技能、健康检查由清单派生。新增交互模式还需声明可选 modes 与实际能力,并实现 mount:返回带 dispose() 的展示句柄,可选提供 resize()、reset()、scale()、snapshot()。原有 render() 返回 { markup } 的适配器继续通过兼容包装显示。工具栏按实际句柄能力显示操作。
目录结构
lib/index.js 宿主半:配置 Schema、路由、完整性校验、报告归档、提示段与技能生成 lib/client.js 客户端半:扫描管线、十一个适配器、图框、设置面板、报告库面板 lib/reports.js 报告库:文件布局、索引、路径校验、去重与重建 lib/renderers/manifest.js 单一事实来源:渲染器清单(配置界面/提示/技能/面板都由它派生) scripts/vendor.mjs 拷贝引擎产物、写 integrity.json、生成 skill/ scripts/design-showcase.mjs README 里的十张设计示例 scripts/check-ui.mjs Playwright Chromium 行为与故障检查 scripts/ui-fixture.mjs 本机可复现的真实引擎夹具 test/ 宿主半与客户端半的单测 vendor/ 引擎产物(不入库,npm install 生成)
呈现规范
图内字体沿用宿主应用字体栈,字号 13px(与正文同尺度),画布居中、16px 内边距、最高 360px,随主题切换底色;自适应缩放同时受宽度与高度约束(纵向超出会直接看不到内容,因此高度下限比宽度下限更松)。渲染失败显示错误卡片,主题变化自动重渲染。交互图表用真实容器与 ResizeObserver 更新尺寸,容器零宽度时等待可见;源码、会话、主题变化或关闭开关时取消旧任务,释放实例与监听,迟到结果不回写。静态引擎仍串行执行,每次使用独立临时容器。
手写 SVG 的设计令牌(暖中性基色 + 语义色、stroke-width="0.5" 发丝线、rx=8 圆角、开放式箭头、11/12/13/14 四级字号、+<desc> 无障碍)整理自 WorkBuddy 对话产物中实际使用的规范——本项目按同一套规范生成示例图(见 preview/design/)。
许可
本插件为 MIT。
各引擎许可见其包:mermaid、Graphviz-wasm(@viz-js/viz)、nomnoml、graphre、DOMPurify 为 MIT;ECharts 为 Apache-2.0;Vega / Vega-Lite 为 BSD-3-Clause。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
molanxuan-del/DSH-MOTU
墨图 MoTu — 把对话里的代码块渲染成真正的图。DSH 可视化套件:Mermaid / Graphviz /…
相关插件 · 其他
模型破甲清洗YuJunZhiXue/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 16,148已汉化DeepSeek 客户端
73
女娲蒸馏alchaincyf/nuwa-skill
输入名人名字,提炼其思维模型与决策方式供你调用
★ 37,308已汉化DSH
72
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 888已汉化DSH
71.6
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,266已汉化DSH
70.7
这是你的仓库?认领条目