🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

视觉通感渲染 plolpl789/dsh-raw-html

DeepSeek 客户端
plolpl78967 天前有提交已提供中文文档扫描:含敏感能力兼容 / 相关生态

DeepSeek Harness 的 VCP 视觉联觉协议插件:把智能体输出的 HTML 渲染成真正的 UI(卡片 / KaTeX 公式 / Mermaid 图表 / 内置书法字体 / 零 JS 交互),任何 DSH 环境即插即用

52/100
综合分
65
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/plolpl789/dsh-raw-html.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 67 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-raw-html(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 11:45:59

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 104 处,展示前 97 条)
  • 执行外部命令来自配置/变量
    lib/index.js:130
    const child = spawn(cmd, args, { detached: true, stdio: 'ignore' })
  • 读取本地文件
    lib/index.js:429
    if (file.startsWith(base) && statSync(file).isFile()) return true
  • 发起网络请求
    lib/client.js:600
    katexPromise = window.fetch('/vendor/katex-vd.css')
  • 发起网络请求
    lib/client.js:616
    return window.fetch(u)
  • 读取本地文件
    patch/apply-onfilter.cjs:22
    if (arg) return fs.existsSync(arg) ? arg : null
  • 读取本地文件
    patch/apply-onfilter.cjs:25
    if (!d || !fs.existsSync(d)) return
  • 读取本地文件
    patch/apply-onfilter.cjs:27
    if (!fs.existsSync(assets)) return
  • 读取本地文件
    patch/apply-onfilter.cjs:28
    for (const f of fs.readdirSync(assets)) {
  • 读取本地文件
    patch/apply-onfilter.cjs:44
    let t = fs.readFileSync(file, 'utf8')
  • 读取本地文件
    patch/apply-onfilter.cjs:64
    const newInject = fs.readFileSync(path.join(__dirname, 'v6-inject.js'), 'utf8')
  • 写入本地文件
    patch/apply-onfilter.cjs:93
    fs.copyFileSync(file, bak)
  • 写入本地文件
    patch/apply-onfilter.cjs:94
    fs.writeFileSync(file, t, 'utf8')
  • 执行外部命令来自配置/变量
    patch/apply-onfilter.cjs:98
    execFileSync(process.execPath, ['--check', file], { stdio: 'pipe' })
  • 写入本地文件
    patch/apply-onfilter.cjs:101
    fs.copyFileSync(bak, file)
  • 写入本地文件
    patch/apply-onfilter.cjs:121
    fs.copyFileSync(bak, file)
  • 执行外部命令来自配置/变量
    patch/install-all.cjs:48
    const r = spawnSync(process.execPath, args, { stdio: 'inherit' })
  • 读取本地文件
    patch/install-v6.cjs:48
    if (arg) return fs.existsSync(arg) ? arg : null
  • 读取本地文件
    patch/install-v6.cjs:52
    if (fs.existsSync(p)) return p
  • 读取本地文件
    patch/install-v6.cjs:57
    if (!d || !fs.existsSync(d)) return
  • 读取本地文件
    patch/install-v6.cjs:60
    if (!fs.existsSync(assets)) return
  • 读取本地文件
    patch/install-v6.cjs:61
    for (const f of fs.readdirSync(assets)) {
  • 读取本地文件
    patch/install-v6.cjs:169
    let t = fs.readFileSync(file, 'utf8')
  • 写入本地文件
    patch/install-v6.cjs:202
    fs.copyFileSync(file, bak2)
  • 写入本地文件
    patch/install-v6.cjs:204
    fs.writeFileSync(file, hardened, 'utf8')
  • 执行外部命令来自配置/变量
    patch/install-v6.cjs:206
    execFileSync(process.execPath, ['--check', file], { stdio: 'inherit' })
  • 写入本地文件
    patch/install-v6.cjs:209
    fs.copyFileSync(bak2, file)
  • 写入本地文件
    patch/install-v6.cjs:220
    fs.copyFileSync(file, bak)
  • 写入本地文件
    patch/install-v6.cjs:308
    fs.writeFileSync(file, next, 'utf8')
  • 执行外部命令来自配置/变量
    patch/install-v6.cjs:313
    execFileSync(process.execPath, ['--check', file], { stdio: 'inherit' })
  • 写入本地文件
    patch/install-v6.cjs:347
    fs.copyFileSync(bak, file)
  • 读取本地文件
    patch/install.cjs:49
    if (arg) return fs.existsSync(arg) ? arg : null
  • 读取本地文件
    patch/install.cjs:53
    if (fs.existsSync(p)) return p
  • 读取本地文件
    patch/install.cjs:58
    if (!d || !fs.existsSync(d)) return
  • 读取本地文件
    patch/install.cjs:61
    if (!fs.existsSync(assets)) return
  • 读取本地文件
    patch/install.cjs:62
    for (const f of fs.readdirSync(assets)) {
  • 读取本地文件
    patch/install.cjs:105
    const t = fs.readFileSync(file, 'utf8')
  • 写入本地文件
    patch/install.cjs:125
    fs.copyFileSync(file, bak)
  • 写入本地文件
    patch/install.cjs:140
    fs.copyFileSync(bak, file)
  • 写入本地文件
    patch/install.cjs:153
    fs.copyFileSync(bak, file)
  • 写入本地文件
    patch/install.cjs:164
    fs.copyFileSync(bak, file)
  • 写入本地文件
    patch/install.cjs:169
    fs.writeFileSync(file, next, 'utf8')
  • 写入本地文件
    patch/install.cjs:173
    fs.copyFileSync(bak, file)
  • 读取本地文件
    patch/patch-frontend.cjs:55
    if (arg) return fs.existsSync(arg) ? arg : null
  • 读取本地文件
    patch/patch-frontend.cjs:60
    if (fs.existsSync(p)) return p
  • 读取本地文件
    patch/patch-frontend.cjs:66
    if (!d || !fs.existsSync(d)) return
  • 读取本地文件
    patch/patch-frontend.cjs:69
    if (!fs.existsSync(assets)) return
  • 读取本地文件
    patch/patch-frontend.cjs:70
    for (const f of fs.readdirSync(assets)) {
  • 读取本地文件
    patch/patch-frontend.cjs:93
    let t = fs.readFileSync(file, 'utf8')
  • 写入本地文件
    patch/patch-frontend.cjs:301
    fs.copyFileSync(file, bak)
  • 写入本地文件
    patch/patch-frontend.cjs:302
    fs.writeFileSync(file, t, 'utf8')
  • 执行外部命令来自配置/变量
    patch/patch-frontend.cjs:310
    execFileSync(process.execPath, ['--check', file], { stdio: 'pipe' })
  • 写入本地文件
    patch/patch-frontend.cjs:314
    fs.copyFileSync(bak, file)
  • 读取本地文件
    patch/trusted-patch.cjs:35
    if (arg) return fs.existsSync(arg) ? arg : null
  • 读取本地文件
    patch/trusted-patch.cjs:38
    if (!d || !fs.existsSync(d)) return
  • 读取本地文件
    patch/trusted-patch.cjs:40
    if (!fs.existsSync(assets)) return
  • 读取本地文件
    patch/trusted-patch.cjs:41
    for (const f of fs.readdirSync(assets)) {
  • 读取本地文件
    patch/trusted-patch.cjs:56
    let t = fs.readFileSync(file, 'utf8')
  • 写入本地文件
    patch/trusted-patch.cjs:88
    fs.copyFileSync(file, bak)
  • 写入本地文件
    patch/trusted-patch.cjs:91
    fs.writeFileSync(file, t, 'utf8')
  • 执行外部命令来自配置/变量
    patch/trusted-patch.cjs:95
    execFileSync(process.execPath, ['--check', file], { stdio: 'pipe' })
  • 写入本地文件
    patch/trusted-patch.cjs:98
    fs.copyFileSync(bak, file)
  • 读取本地文件
    patch/update-v6-inject.cjs:23
    if (arg) return fs.existsSync(arg) ? arg : null
  • 读取本地文件
    patch/update-v6-inject.cjs:26
    if (!d || !fs.existsSync(d)) return
  • 读取本地文件
    patch/update-v6-inject.cjs:28
    if (!fs.existsSync(assets)) return
  • 读取本地文件
    patch/update-v6-inject.cjs:29
    for (const f of fs.readdirSync(assets)) {
  • 读取本地文件
    patch/update-v6-inject.cjs:44
    let t = fs.readFileSync(file, 'utf8')
  • 读取本地文件
    patch/update-v6-inject.cjs:49
    newInject = fs.readFileSync(path.join(__dirname, 'v6-inject.js'), 'utf8')
  • 写入本地文件
    patch/update-v6-inject.cjs:87
    fs.copyFileSync(file, bak)
  • 写入本地文件
    patch/update-v6-inject.cjs:88
    fs.writeFileSync(file, newT, 'utf8')
  • 执行外部命令来自配置/变量
    patch/update-v6-inject.cjs:95
    execFileSync(process.execPath, ['--check', file], { stdio: 'pipe' })
  • 写入本地文件
    patch/update-v6-inject.cjs:98
    fs.copyFileSync(bak, file)
  • 读取本地文件
    patch/upgrade-patch.cjs:38
    if (arg) return fs.existsSync(arg) ? arg : null
  • 读取本地文件
    patch/upgrade-patch.cjs:42
    if (fs.existsSync(p)) return p
  • 读取本地文件
    patch/upgrade-patch.cjs:47
    if (!d || !fs.existsSync(d)) return
  • 读取本地文件
    patch/upgrade-patch.cjs:50
    if (!fs.existsSync(assets)) return
  • 读取本地文件
    patch/upgrade-patch.cjs:51
    for (const f of fs.readdirSync(assets)) {
  • 读取本地文件
    patch/upgrade-patch.cjs:86
    const t = fs.readFileSync(file, 'utf8')
  • 写入本地文件
    patch/upgrade-patch.cjs:140
    fs.copyFileSync(file, bak)
  • 写入本地文件
    patch/upgrade-patch.cjs:141
    fs.writeFileSync(file, next, 'utf8')
  • 写入本地文件
    patch/upgrade-patch.cjs:149
    fs.copyFileSync(bak, file)
  • 发起网络请求
    patch/vcp-fast-bench.cjs:33
    https.get(url, { headers: { 'User-Agent': 'vcp-bench' } }, (r) => {
  • 写入本地文件
    patch/vcp-fast-bench.cjs:50
    fs.mkdirSync(path.dirname(p), { recursive: true })
  • 写入本地文件
    patch/vcp-fast-bench.cjs:51
    fs.writeFileSync(p, data)
  • 读取本地文件
    patch/vcp-fast-bench.cjs:59
    if (fs.existsSync(entry)) return entry
  • 写入本地文件
    patch/vcp-fast-bench.cjs:60
    fs.mkdirSync(dominoDir, { recursive: true })
  • 读取本地文件
    patch/vcp-fast-bench.cjs:69
    if (!bundlePath || !fs.existsSync(bundlePath)) {
  • 读取本地文件
    patch/vcp-fast-bench.cjs:73
    const bundle = fs.readFileSync(bundlePath, 'utf8')
  • 写入本地文件
    patch/vcp-fast-bench.cjs:206
    fs.writeFileSync(modPath, moduleSrc, 'utf8')
  • 读取本地文件
    patch/vcp-fast-sim.cjs:29
    const t = fs.readFileSync(bundlePath, 'utf8')
  • 读取本地文件
    patch/vcp-safe.cjs:23
    if (arg) return fs.existsSync(arg) ? arg : null
  • 读取本地文件
    patch/vcp-safe.cjs:26
    if (fs.existsSync(p)) return p
  • 读取本地文件
    patch/vcp-safe.cjs:30
    if (!d || !fs.existsSync(d)) return
  • 读取本地文件
    patch/vcp-safe.cjs:33
    if (!fs.existsSync(assets)) return
  • 读取本地文件
    patch/vcp-safe.cjs:34
    for (const f of fs.readdirSync(assets)) {
  • 读取本地文件
    patch/vcp-safe.cjs:62
    let t = fs.readFileSync(file, 'utf8')
  • 写入本地文件
    patch/vcp-safe.cjs:84
    fs.copyFileSync(file, bak)
  • 写入本地文件
    patch/vcp-safe.cjs:85
    fs.writeFileSync(file, next, 'utf8')
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 渲染HTML为UI
  • 支持KaTeX公式
  • 支持Mermaid图表

README

由 DeepSeek 最新模型翻译生成
dsh-raw-html · VCP 视觉通感协议规范插件 在 DeepSeek Harness Web GUI 中实现 VCP(Visual-Synesthesia,视觉通感)协议:消息里的 HTML 从「一坨源码」变成真正渲染的界面,并让智能体按一套可维护的设计规范输出。 即插即用:任何电脑、任何智能体 —— 跑一次一键安装器补丁(node patch/install-all.cjs,渲染能力+可信模式全到位) + 安装本插件 + 打开浏览器「</>」开关(渲染/美学双开关)→ 浏览器开始渲染 HTML(含 SVG 卡片 / Mermaid 图表 / KaTeX 公式),智能体开始按规范输出(设计原则 / 中文排版 / 字体搭配)。 渲染能力(HTML/SVG/图表/公式)由补丁注入前端 bundle,插件负责开关与协议注入——详细步骤见下方「安装」章节。
展开完整文档(README 剩余 1 节)
dsh-raw-html · VCP 视觉通感协议规范插件

在 DeepSeek Harness Web GUI 中实现 VCP(Visual-Synesthesia,视觉通感)协议:消息里的 HTML 从「一坨源码」变成真正渲染的界面,并让智能体按一套可维护的设计规范输出。

即插即用:任何电脑、任何智能体 —— 跑一次一键安装器补丁(node patch/install-all.cjs,渲染能力+可信模式全到位)
+ 安装本插件 + 打开浏览器「</>」开关(渲染/美学双开关)→ 浏览器开始渲染 HTML(含 SVG 卡片 / Mermaid 图表 / KaTeX 公式),智能体开始按规范输出(设计原则 / 中文排版 / 字体搭配)。

渲染能力(HTML/SVG/图表/公式)由补丁注入前端 bundle,插件负责开关与协议注入——详细步骤见下方「安装」章节。

English README · 更新记录

✨ 效果展示(Gallery)

真实会话中的 VCP 卡片渲染效果(宣传图 5 张):

效果图 1 效果图 2 效果图 3 效果图 4 效果图 5

📣 近期更新(v0.6.0 · 补丁 v6.38)

- 自愈层 v6.37/v6.38(2026-08-29):卡片渲染撕裂根治——CommonMark 块级标签不能打断段落(文字+换行+ 撕裂)与卡片内部空行拆分问题,fixVcpBlank 补空行/压缩空行,整卡回归单一 htmlFlow(稳定测试 105 断言全绿)。
- 消息主体渲染器 VCP 接管(2026-08-29):主 markdown 渲染器接入 VCP 渲染,消息卡片从此真正渲染为界面(此前官方策略是当源码文本显示)。
- 早期更新(v0.3.0 · 2026-08-24):

- 修复(2026-08-24):适配新版前端 0.1.0-rc.8 / 0.1.1-rc.x(压缩器改名 Xu/jd 的新锚点组,自动探测、旧版兼容);消除 schemastery 静态依赖导致的启动「模块找不到」故障(动态加载 + 降级,缺依赖也能正常启动)。
- 新能力(2026-08-24):声明式配色 data-vcp-preset(内置 VCPColorEngine 确定性生成整套色板,对比度/色域闭环保证);流式锚定锁 + ref 闭包缓存(流式更稳不抖)。
- 协议(2026-08-24):渲染/美学双开关分层;主动视觉通感(不再被动等指令);心流纪律常驻(实测输出 −4.6K token/轮、费用 −¥0.056)。
- 安全(P0):修复 on 事件属性透传缺口(只放行 onclick 桥接);性能计时器诊断修复;文档引用对齐。
- 性能(P1):正则快速守卫、mermaid 监听器泄漏修复、协议文本瘦身约 74%。
- 字体(P2):内置 12 款商业字库 → 7 款开源字体(全 OFL 授权)。
- 增强:prefers-reduced-motion 无障碍、键盘焦点态、魔数收拢。
- 完整变更见 CHANGELOG.md。

版本

- 插件版本:package.json 的 version(当前 0.6.0),随 dsh plugin 升级。
- 补丁代号:patch/ 注入模块的演进代号(当前 v6 · 子版本 v6.38),由 install-v6.cjs 应用到前端 bundle,二者独立演进。前端兼容 0.0.1-rc.5 ~ 0.1.0-rc.7 与 0.1.0-rc.8 / 0.1.1-rc.x 两代压缩形态(vc/hp 与 Xu/jd 自动探测适配)。
- 详细变更见 CHANGELOG.md。

组成

| 部件 | 位置 | 作用 |
| 一键安装器 | patch/install-all.cjs | 推荐:一条命令 = install-v6.cjs(渲染能力)+ trusted-patch.cjs(可信模式 vc 放行);幂等 + 备份回滚 + node --check 健康检查,锚点不匹配安全中止 |
| 万能安装器 | patch/install-v6.cjs | 渲染能力 v6 全量补丁(install-all 的组件①):自动探测 dist bundle,任意历史状态 → v6(幂等 + 备份回滚) |
| 稳定区渲染模块 | patch/v6-inject.js | 注入 dist bundle 的增量渲染引擎:容器感知块级缓存、流式尾巴占位、KaTeX 公式、Mermaid 查看器;onclick="input('...')" 桥接为真实交互;安全过滤 script/iframe/object/embed、on 事件与 javascript: 协议 |
| vcp-fast 加速引擎 | patch/v6-inject.js | 容器感知块级增量:已闭合块缓存(元素引用跨帧不变 → React 跳过 diff → 动画真循环),只重渲染尾巴;实测缓存命中 1200~6800 倍、增量 12 倍 提速 |
| 插件(Host 半侧) | lib/index.js | 渲染/美学双开关状态(落盘持久化)+ 系统提示词分层注入(结构铁律必注入 + 美学工具包可选)+ /fonts 字体服务(内置精选 + 外置大库双源)+ 知识层共享(协议附带本机 DESIGN.md 路径,任何智能体可读) |
| 插件(浏览器半侧) | lib/client.js | composer 发送按钮旁注入「</>」按钮(点击弹出设置面板,渲染/美学双开关,主题令牌适配深/浅色)+ 暴露 window.__dshInput(VCP 按钮 → 填框发送) |
| 内置精选字体 | assets/fonts/ | 7 款开源字体(woff2 子集,共约 7.6MB)随插件分发——文楷/文楷细/马善政楷书/思源黑/思源细黑/思源粗黑/GreatVibes 花体,全部 OFL 授权,任何电脑装上即可用,无需任何配置 |
| 设计系统文档 | DESIGN.md | 完整规范库:字体清单 / 色板 / 中文排版 / 安全铁律(知识层,智能体可按需读取) |
| 回归测试 | tests/ | 六套断言(stable 47 + security 43 + bundle + smoke + math + mermaid,共 200+ 项):帧序列 / 安全过滤 / bundle 完整性(改引擎后必跑) |
| 性能基准 | patch/vcp-fast-bench.cjs | domino 真实 DOM 解析环境对比新旧路径耗时与提速倍数(自动下载依赖,零安装) |
| 子集化工具 | tools/subset_fonts.py | 维护者用:把新字体裁剪为常用字子集 + woff2 压缩(需 Python + fonttools + brotli) |

文档地图(一规则一权威)

每份规范只在一处权威声明,其余位置挂指针。改规则前先找到它的权威源:

| 文档 | 唯一权威职责 | 读者 |
| DESIGN.md | 「怎么不崩、怎么不丑」的硬规则:字体库 / 色板 / 中文排版 / 安全铁律 §4(落笔后唯一确认点) | 智能体按需读 |
| EDITORIAL.md | 「编辑感 / 数据可视化语法」:四色系 / 卡片四件套 / 明度契约 / 视觉词汇库 / 动效 / 非图表迁移 | 智能体按需读 |
| BREATH.md | 「为什么而画」:三步呼吸法 / 规则三层 / 破规时机 / 动笔前三问 | 智能体先读 |
| FRAMING.md | 「封面怎么实现」:SVG 顶栏技术要点 / 骨架 / 风格示例 | 智能体按需读 |
| VCP-INTERACTIONS.md | 「交互元素 + 渲染层安全白名单」 | 智能体按需读 |
| PROGRESS.md | 会话交接快照(进度 / 血泪教训 / 路线图) | 维护者 |
| CHANGELOG.md | 变更流水(插件版本 + 补丁代号) | 维护者 |

铁律定位:vcp-root 禁止空行 权威在 DESIGN.md §4;交互 / 安全白名单权威在 VCP-INTERACTIONS.md。新增规则先判断归属,只写进权威源,别处挂指针。

安装(任意 DSH 环境 · 人 & 智能体通用)

推荐:一键安装器 patch/install-all.cjs——一条命令把「渲染能力 + 可信模式」全部装好(内部依次执行 install-v6.cjs 全量渲染补丁 + trusted-patch.cjs 可信模式 vc 放行;幂等可重复运行,每一步自动备份 + node --check 健康检查,锚点不匹配安全中止不写坏文件):

1. 一键打补丁(HTML 渲染 / SVG 卡片 / Mermaid 图表 / KaTeX 公式 / 可信模式,全部就位)
node "本插件路径\patch\install-all.cjs"

2. 安装插件(卸载用 dsh plugin --profile web remove dsh-raw-html)
dsh plugin --profile web add "本插件路径"

3. 重启 dsh 服务,然后刷新浏览器页面(缓存较旧时 Ctrl+F5)
4. 打开「</>」开关(渲染/美学);需要脚本能力时点右下角「可信模式」徽章

智能体安装指引(其他用户让自家智能体代为安装时,可把以上 4 步原样交给它执行): ① 确认本机有 Node.js(node -v);② 运行一键安装器 install-all.cjs(自动探测 dist bundle,失败时把 <bundle路径> 作为参数传入);③ 注册插件到 web profile;④ 提醒用户重启 dsh 并强刷。
补丁全部幂等——重复安装、dsh 升级后重跑都不会产生副作用。

探测失败时手动指定 bundle 路径:

node "...\patch\install-all.cjs" "C:\...\dsh-web-frontend\dist\assets\index-.js"

单独执行亦可:install-v6.cjs(渲染能力)/ trusted-patch.cjs(可信模式 vc 放行);历史脚本(v1/v2 时代)patch/install.cjs、patch/patch-frontend.cjs、patch/upgrade-patch.cjs 仍保留在源仓库供参考,日常安装请使用 install-all.cjs。

vcp-fast 加速引擎

在 v1 渲染补丁基础上新增的「缓存 + 增量」双引擎(window.__vcpFast):

- 精确缓存:HTML 字符串未变时,直接返回缓存的 React 元素引用——React 对引用相同的元素跳过整个子树 reconciliation。历史消息滚动 / 切会话 / React 重渲染 → 零重建。
- 增量追加:内容 = 旧内容 + 追加段,且旧内容以闭合标签结尾时,稳定部分引用不变,只解析渲染新增段。
- 安全边界:仅非流式 + 开关开启时生效;旧值未闭合或内容重写时自动回退全量;缓存上限 200 条自动清理;onclick 桥接与 script/iframe 过滤能力不变。
- 验证:DevTools console 可见 [vcp-fast] HIT/BUILD 日志(每 2 秒节流);基准数字见 patch/vcp-fast-bench.cjs(真实 DOM 解析环境实测:缓存命中约 1200~6800 倍、增量约 12 倍提速)。

⚠️ 常见坑:vcp-root 内部禁止空行(重要!)

markdown 的 HTML 块遇到空行(\n\n)就结束——如果 内部出现连续两个换行,卡片会被解析成多个独立节点:开头部分被 DOMParser 自动补全成「只有顶部一条背景」的小卡片,其余内容全部溢出到背景外面。症状:深蓝背景只包顶部一条横框,下方内容没有背景(2026-08-19 实测确认)。

铁律:
- vcp-root 内所有子元素用单个换行或单行排列,任何地方不要出现 \n\n;
- 需要视觉分组时用 margin,不要用空行;
- 写完检查:卡片 HTML 字符串中 \n\n 出现次数必须为 0。

此铁律的唯一权威源见 DESIGN.md §4 安全铁律(含根因与完整修正),本节仅作运维速查。

配置

- 内置精选字体(推荐):7 款开源字体随插件分发(全部 OFL 授权),装上即用,零配置。
- 外置大库(可选):默认 I:\字体。其他电脑可把字体库目录配置到「设置 → 插件 → raw-html → fontsRoot」(或直接修改 lib/index.js 里的默认值)。
没有外置大库也能用:内置 7 款开源字体 + 系统字体兜底。
- 开关状态:渲染 HTML 与 美学注入 两个独立开关,持久化在 ~/.dsh/dsh-raw-html-state.json,服务重启后自动恢复;渲染关闭时美学自动强制关闭。

使用

- 输入框(composer)发送按钮旁点 「</>」按钮 弹出设置面板,可分别开关「渲染 HTML」与「美学注入」;按钮三态:</> OFF(关)/ </> 渲染(仅渲染)/ </> ON(渲染+美学);
- 开启后新消息中的 HTML 即时渲染;历史消息刷新页面后按新状态重渲染;
- agent 收到注入的 VCP 协议 → 自动按规范输出 #vcp-root 视觉容器;关闭时协议撤回 → agent 自动回到普通 Markdown(降级)。
- VCP 按钮 onclick="input('回复内容')" 点击后把内容填入输入框并发送。

维护 / 升级

- 每次修改后:node --check lib/client.js && node --check lib/index.js 验语法;
client 改动刷新即生效;host 改动需重启 dsh 服务。
- dsh 升级会覆盖被打补丁的 dist 文件 → 重跑 patch/install-all.cjs 即可(幂等;锚点找不到会中止且不写坏文件;备份在 .bak-installv6-<时间戳>)。
- 依赖声明铁律(2026-08-19 崩溃事件教训):import 的每一个第三方包 必须显式声明在 package.json(dependencies 或 peerDependencies)——依赖解析靠运行环境存量 node_modules 碰运气 = 把生命线交给风浪。
每次改动后运行 node tools/check-deps.cjs 核对;目录重构/移动 node_modules/ 打包资源后,务必验证 import('@deepseek-ai/schemastery') 可解析。
- 想改进设计规范 → 编辑 DESIGN.md(agent 会在需要时读取)+ 同步协议文本(lib/index.js 的 buildProtocolText)。
- 想扩充内置字体 → 编辑 tools/subset_fonts.py 的 FONTS 清单 + 跑一次(需 Python + fonttools + brotli),自动输出 woff2 子集到 assets/fonts/。

恢复(撤销补丁)

把补丁自动生成的备份改回原名(如 index-.js.bak-xxx → index-.js),再移除插件:
dsh plugin --profile web remove dsh-raw-html

安全提示

开启后,模型输出中的 HTML 会被渲染为界面。补丁做了脚本/事件/危险协议过滤(React 元素渲染天然不执行 script;事件只放开 onclick="input('...')" 受控通道; script/iframe/object/embed 与 javascript: 协议丢弃),但样式与外部图片仍然可达——请只对可信模型开启。

可信模式(Trusted Mode · v7.2 插件化)

先生定调 2026-08-29:本会话为双人私密会话,内容由双方共同产出、双方可信——公共论坛的存储型 XSS 威胁模型不适用。因此为「正文可执行脚本」提供显式开关。

- 默认关闭(安全默认):未开启时行为与旧版完全一致(script 截断、白名单严格)。
- 开启方式:页面右下角「盾锁 SVG 徽章 · 可信模式·关」一键开启(写入 localStorage['raw-html.trusted']='1' 并刷新);或 DevTools 设置 localStorage.setItem('raw-html.trusted','1');或 window.__DSH_TRUSTED__=true。
徽章图标为内联 SVG 盾锁(先生 2026-08-29 定稿方案 A):关态=盾+锁孔,开态=盾+对勾。
- 开启后放行:消息正文 被提取并在渲染完成后执行(WebGL/Shader/fetch 由此解锁); iframe/object/embed 放行;on* 事件属性放行;href/src 白名单放宽(blob: 可用)。
仍拒绝:javascript: 协议。
- 机制:闭合 在解析阶段被提取出 vdom(不依赖 React 对 script 元素的行为),消息渲染完成后统一执行一次;流式中未闭合的脚本不执行(等完整闭合)。
- v7.2 插件化(先生定调):可信模式的状态与开关 UI 全部迁入插件 client 层
(lib/client.js)——isTrusted()、window.__vcpTrusted 定义、右下角徽章。
主 bundle 渲染层(v6-inject 的 isTrusted / vc 条件过滤)对 window.__vcpTrusted 一律防御式调用:插件未加载(停用)→ 自动 false → 行为与旧版一致(安全默认)。
因此:安装插件 = 可信模式可用;停用插件 = 徽章消失、放行全部回收。
其他用户安装本插件后同样即插即用(可信模式开关层不依赖手工补丁)。
- 注意:可信模式的执行载体(脚本提取 extractTrustedScripts / 执行 flushTrustedScripts / vc 放行)位于主 bundle 的 v6 渲染模块中,仍由一次性 install-all.cjs 注入——即「HTML 渲染能力」本身需要补丁安装;开关与状态层随插件。未跑补丁的用户装插件只有开关 UI,渲染能力不生效(详见「安装」章节)。
- 测试:tests/trusted.test.mjs(21 项断言,覆盖默认关闭回归、插件层状态、徽章切换、渲染层防御式调用与联动)。
- 回退:再点一次徽章即可关闭;也可以执行 localStorage.setItem('raw-html.trusted','0')。
预览分享卡片长什么样 ↓plolpl789/dsh-raw-html
分享 · DeepSeek Harness Hub
plolpl789/dsh-raw-html

DeepSeek Harness 的 VCP 视觉联觉协议插件:把智能体输出的 HTML 渲染成真正的 UI(卡片 / KaTeX 公式 / Mermaid 图表 / 内置书法字体 / 零 JS 交互),任何 DSH 环境即插即用

这是你的仓库?认领条目

回到顶部