dsh-md-html-render:把 Markdown 渲染成可以直接发走的单文件 HTML

前言

在 DSH(DeepSeek Harness)里跑任务,经常有一种中间产物不知道往哪放:模型写的迁移方案、对比表、报告草稿。留在对话里就是一大坨 Markdown,复制出去排版就散;丢给别的渲染器又多一步导出。这个插件解决的就是这一步:在 profile 里装一个渲染器,模型那边直接产出一份自包含的 HTML 文件,Web GUI 那边有一个抽屉式的预览与导出入口,两条路背后是同一个渲染器。

插件仓库目录页在 SkillHub 的「客户端」分类下,记录星标 1 个。维护者是 YaoleWu,仓库地址为 https://github.com/YaoleWu/dsh-md-preview 。下面介绍它的能力、安装方式和使用注意点。

这是什么

一句话:md_html_render 是模型可调用的工具,给它 Markdown,返回一份完整的自包含 HTML 文档,可选写入磁盘;同时在 Web 会话头部有一个 MD 抽屉,可以就地浏览工作目录里的 Markdown 文件、渲染、编辑并导出。两者共用 lib/render.js 这一个渲染器,因此模型生成的页面与抽屉导出的页面逐字节一致,作者用测试在语料的每个用例上断言了这一点。

它定位的是“把 Markdown 变成可以发给别人、可以在离线机器上打开的单文件页面”,不是替代已有的 Markdown 查看器。仓库 README 的口号是「Turn Markdown into a page you can send to someone」。包版本为 0.3.0,许可证 MIT。

核心功能

1. md_html_render 工具

md_html_render(markdown, title?, save_path?) -> { html, savedPath?, error? }

回调结构里 html 总是返回,savedPath 与 error 只在涉及写盘时出现。两个可选参数:

  • title:页面 <title>,默认是 Markdown。
  • save_path:目标路径,通过会话的 filesystem service 解析,因此与其他写入一样遵循同一套沙箱策略。

输出是自包含的:样式内嵌,不加载任何 stylesheet、font、script 或图片。从磁盘、U 盘或隔离网机器打开,外观一致;跟随阅读器的深色模式;没有任何外联请求。如果 save_path 被沙箱拒绝,工具仍会返回 HTML 与错误,迭代不会被权限问题打断。

2. Web GUI 的 MD 抽屉

在 Web 会话头部按 MD,抽屉打开在当前工作目录上。功能包括:

  • 就地浏览:点击文件夹进入,↑ 返回,不走系统文件对话框。
  • 渲染:标题、粗体/斜体/删除线、行内代码、围栏代码、引用、有序/无序/任务列表、表格、链接、图片、分割线。
  • 编辑:切换成纯 textarea 做笔记或修一行,再切回来。
  • 导出:在源文件旁写出一份自包含 HTML,与 md_html_render 产出的是同一份文档。
  • 主题感知:读取 harness 的主题变量,亮暗模式无需配置。

3. 安全边界

  • 无运行时依赖。客户端半个是纯脚本加载,不带 bundler,因此 marked / markdown-it 不可用;渲染器是约 150 行手写 JavaScript,需要审计的依赖树只有一个文件。
  • 没有第二条磁盘通道。所有读写都过 harness 的 fs service,继承会话已有的沙箱策略;抽屉的 readFile 只接受 .md、.markdown、.mdx、.txt。
  • 不执行原始 HTML。文档文本先做 HTML 转义再跑行内语法;链接目标只放行 http(s):、#、/、mailto:,其余折叠成 #。含 <script> 或 javascript: 链接的文档会渲染成字面字符。

兼容性:headless / CLI profile 可用 md_html_render;Web GUI 同时有工具和抽屉;profile 没有 fs service 时,插件只打日志保持不激活,不做半加载。需要 Node ^22.19.0 || >=24.0.0。

安装与启用

包在 0.3.0 改名了:此前包名是 dsh-md-preview,npm 上这个名字在 2026-08-17 被另一个作者的项目注册走,本包因此改发布名为 dsh-md-html-render(即它一直提供的那工具名)。从 npm 装 dsh-md-preview 拿到的不是本包。仓库路径未变,但依赖键必须匹配新包名。

目前还没上 npm,直接从 GitHub 装。编辑 profile 的 package.json:

// ~/.dsh/profiles/<profile>/package.json
{
  "dependencies": {
    "dsh-md-html-render": "github:YaoleWu/dsh-md-preview#v0.3.0"
  },
  "dsh": {
    "profile": {
      "bundles": ["dsh-md-html-render"]
    }
  }
}

README 原文写作 github:LeslieWylie/dsh-md-preview#v0.3.0(该仓库先前的归属名)。GitHub API 返回的 full_name 现在是 YaoleWu/dsh-md-preview,旧归属名重定向到同一仓库,两种写法都指向同一个仓库;按当前归属名引用更稳妥。

然后重装并重启 profile:

cd ~/.dsh/profiles/<profile> && pnpm install
dsh --profile <profile>

去掉 #v0.3.0 就跟踪默认分支而不是固定版本。

不想改 profile 也可以临时 patch:

dsh --profile web --patch <(printf -- "- insert:\n    - id: md-preview\n      name: dsh-md-html-render\n")

包仍须能从 profile 的 node_modules 解析,所以要先跑上面的 pnpm install。

典型用法

模型侧直接下指令,例如:

Render this migration plan to ~/Desktop/plan.html

适合把报告、方案、对比表这类本来会整段堆在对话里的内容变成可以直接打开或发走的 HTML 文件。

GUI 侧:在会话头部按 MD,浏览工作目录,点一个 .md 文件就地渲染;需要改一行时切到纯文本编辑,改完切回;要分发时点导出,源文件旁多出一份单文件 HTML。

仓库自带的测试有四个可执行套件,分别覆盖客户端渲染器、host 渲染器与二者一致性(含工具形状、RPC 端点、沙箱拒绝路径)、抽屉路径渲染、以及真实 Context 引导加载后向真实工具注册表取 md_html_render 并对真实磁盘执行:

npm test

最后一项的意义在于:DSH 插件可以 import 干净、单元测试全过,却在 Context 实际引导时什么都没注册,而且不报错,单元测试看不到这一点。harness 相关包被声明为普通 devDependencies 而不是可选 peer,所以全新 clone 上直接 npm install && npm test 就能真跑。日志里出现 SKIPPED 时,按未验证对待。XSS 相关断言是结构性不变量:产出的标签不会出现未终结的属性或 on*= 处理器,套件里还包含让检查器在真正不安全标记上转红的用例,防止安全断言悄悄退化成恒真。

适用场景与注意

适合:在 DSH 里用模型产出文档类产物、希望结果是一个能离线打开和转发的文件的人;Web GUI 用户想要不需要开新标签、不需要第二个编辑器的就地预览。装了 headless profile 只拿到工具,GUI 用户两样都有。

注意几点:

  • 插件以当前 dsh 进程的权限运行,写入路径仍由会话沙箱决定;安装前应检查源码与许可证(本包许可证为 MIT)。
  • 工具依赖 fs service;没有它的 profile 上插件只打警告保持惰性,功能不可用。
  • 包名 dsh-md-preview 在 npm 上指向别的项目,别按旧名装。
  • SkillHub 目录是独立的社区站点,与 DeepSeek / 幻方没有官方从属关系,插件需自行评估后使用。

结尾

这个插件的价值在于把「Markdown 渲染」这一步收敛到 harness 内部:同一个渲染器,既是模型工具,也是 GUI 的预览与导出按钮;零运行时依赖、无第二条磁盘通道、不执行原始 HTML,审计面很小。目录页在 https://www.skillhub.cn/plugins/YaoleWu/dsh-md-preview ,源码在 https://github.com/YaoleWu/dsh-md-preview 。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜