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

演示文档模式 hxql666/dsh-presentation

DeepSeek Harness
hxql66620 天前有提交已提供中文文档扫描:含敏感能力

用结构化页面数据生成 PDF 并回看渲染图自检

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add hxql666/dsh-presentation
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · vision
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 20 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令
查看扫描证据(共 4 处,展示前 4 条)
  • 执行外部命令来自配置/变量
    packages/dsh-presentation/lib/engine.js:95
    probe = spawnSync(file, args, { encoding: 'utf8', timeout: 10000, windowsHide: true })
  • 执行外部命令来自配置/变量
    packages/dsh-presentation/lib/engine.js:124
    located = spawnSync(locator, [command], { encoding: 'utf8', timeout: 10000, windowsHide: true })
  • 执行外部命令来自配置/变量
    packages/dsh-presentation/lib/engine.js:324
    child = spawn(binary, args, { cwd, windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'] })
  • 执行外部命令来自配置/变量
    packages/dsh-presentation/lib/engine.js:379
    child = spawn(binary, args, { cwd, windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'] })
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 的演示文档模式:结构化页面数据经 Typst + Touying 输出 PDF,带可视化自审循环。

README

由 DeepSeek 最新模型翻译生成
@hxql/dsh-presentation DeepSeek Harness(DSH)的演示文档模式:演示文稿用结构化页面数据书写,交给 Typst + Touying 编译成 PDF,再把页面渲染回图片,让智能体亲眼看自己的产出,之后才交付。 English · 贡献指南 · 安全策略 · 变更记录 为什么存在 把排版语言直接交给语言模型,每次产出都不一样:字号、边距、栏比在多次生成之间漂移,第 3 页和第 7 页对留白的处理互相矛盾,而模型看不见这一切。十次生成得到十种视觉风格。 本插件把版式从模型手里拿走: - 模型只发射结构化页面数据 —— 一个页型 id 加槽位内容,从不写 Typst - 16 种版式原语掌握全部排版决策 - 编译后页面渲染成 PNG,模型读回来。重叠、裁切、几乎空掉的页面、一行放不下的句子 ——全都在别人看到之前就可见、可修 成品长什么样 插件渲染的一页要点页 同一页换一套主题 —— 主题与页型是互相独立的选择: 同一页换成 dewdrop 主题 上面是插件自己的输出,不是效果图。它由 node test/readme-demo.mjs 用下面那份 spec 生成,所以图和文字不会脱节。
展开完整文档(README 剩余 1 节)
@hxql/dsh-presentation

DeepSeek Harness(DSH)的演示文档模式:演示文稿用结构化页面数据书写,交给 Typst + Touying 编译成 PDF,再把页面渲染回图片,让智能体亲眼看自己的产出,之后才交付。

English · 贡献指南 · 安全策略 · 变更记录

为什么存在

把排版语言直接交给语言模型,每次产出都不一样:字号、边距、栏比在多次生成之间漂移,第 3 页和第 7 页对留白的处理互相矛盾,而模型看不见这一切。十次生成得到十种视觉风格。

本插件把版式从模型手里拿走:

- 模型只发射结构化页面数据 —— 一个页型 id 加槽位内容,从不写 Typst
- 16 种版式原语掌握全部排版决策
- 编译后页面渲染成 PNG,模型读回来。重叠、裁切、几乎空掉的页面、一行放不下的句子 ——全都在别人看到之前就可见、可修

成品长什么样

插件渲染的一页要点页

同一页换一套主题 —— 主题与页型是互相独立的选择:

同一页换成 dewdrop 主题

上面是插件自己的输出,不是效果图。它由 node test/readme-demo.mjs 用下面那份 spec 生成,所以图和文字不会脱节。

可复现性到什么程度

实测结论,不是断言 —— test/determinism-test.mjs:

| 层次 | 结果 |
| 生成的 Typst 源码 | 同一 spec 逐字节相同 |
| 渲染出的页面 PNG | 同一 spec 逐像素相同 |
| PDF 文件本身 | 不是逐字节相同 —— 内含 /CreationDate 与 /ModDate,两次构建相差约 88 字节,除此以外完全一致 |
| 改一页之后 | 页数不变时,其余每一页逐像素相同 |
| 增删一页之后 | 每一页都变 —— 页脚有页码计数(2 / 4 → 2 / 5) |

所以承诺是窄而可核对的:同一插件版本、同一 Typst 与 Touying 版本、同一字体、同一平台、页数不变。改动其中任何一项,页面都可能不同。「无条件可复现」是假话,上表就是用来替代它的。

最小可用 deck

这份 deck 刻意用中文写:上面两张截图就是它的输出,spec 与图必须一致。
deck_status 列出的 9 种语言里任何一种都可以。

{
"title": "从单体到三个服务", "subtitle": "一次拆分复盘", "author": "示例作者", "locale": "zh", // zh zh-tw en ja ko de fr es ru "theme": "metropolis", // 7 套主题任选;见 deck_status
"slides": [
{ "layout": "cover" },
{ "layout": "section", "title": "为什么要拆" }, { "layout": "bullets", "title": "三个信号", "lead": "我们不是在追时髦,是被三件事逼的",
"items": [
{ "text": "发布互相阻塞", "detail": "一个改动的发布要等另外两个" }, { "text": "故障域重合", "detail": "一处内存泄漏拖垮整站" }, { "text": "团队边界模糊", "detail": "没人说得清哪块代码归谁" } ], "takeaway": "拆分的动机是组织问题,不是技术问题" } ] }

把这份 spec 交给 deck_build。deck_status 才是页型、主题、场景的权威列表;下面的表格只是方便查阅,不是事实来源。

目录

| 路径 | 是什么 |
| packages/dsh-presentation | 唯一的包。它提供协作模式(/deck)与五个 deck 工具,其 bundle patch 声明了 Agent 预设 —— 也就是 设置 → Agent 预设 与新会话模式选择器里的那张卡片。 |
| CHANGELOG.md | 每个版本改了什么、为什么。每条都写明证据,包括试过并被否定的做法。 |
| CONTRIBUTING.md | 怎么构建、测试、新增页型;什么不会被接受,以及为什么。 |
| SECURITY.md | 威胁模型 —— 模型的输出是不可信输入 —— 什么算漏洞,以及插件已经防住了什么。 |
| THIRD-PARTY-NOTICES.md | 所有被重新分发或安装时获取的第三方件的许可与义务。 |
| docs/ | 本文中的图片,由 node test/readme-demo.mjs 按下面的 spec 生成。 |
这两样东西来自同一个包:预设由插件自己的 bundle patch 声明,所以选那张卡片就是挂载这些 deck 工具。没有第二个包要装,插件列表里也没有第二条。

副作用说清楚:选那张卡片挂载的是整个插件;只要插件在 dsh.profile.bundles 里,它的 /deck 命令与五个工具就始终可用,与选不选卡片无关。预设让「新会话默认带这套工具」变成一个可选项,它不是沙箱。

前置条件

| DSH | 任何具备本包所 patch 的插件机制与 Agent 预设机制的版本。bundle patch 只针对一个包:@deepseek-ai/dsh-agent-preset —— 它是 entry group,所以 bundle patch 能向它插入一行;entry group 结构不同的 DSH 不会应用它。只对当前工作区里的 DSH 验证过,不声明任何支持版本范围。 |
| Node | >=18,来自 package.json 的 engines。 |
| 操作系统 | Windows、Linux、macOS。Typst 编译器以六个平台专属可选依赖发布(win32-x64/arm64、linux-x64/arm64、darwin-x64/arm64)。开发与验证至今只在 Windows 上做过 —— 另外五个平台已声明、可解析,但本项目未实测。 |
| Typst | 0.15.1,来自可选依赖,或你自己指定的系统二进制。Touying 0.8.0 要求 0.15.x,大版本不同编译不过。 |
| Touying | 0.8.0,随包 vendored。构建时不下载任何东西。 |
| 字体 | 不捆绑。 三个字体栈要求 Typst 机器上已有这些字族:New Computer Modern、Libertinus Serif、Noto Sans/Serif SC、Microsoft YaHei、SimSun。开发机上这些都有;缺失时 Typst 会静默替换,所以 deck 可能用与栈要求不同的字面渲染。 |
| Profile | 本文一律用 desktop,因为那是开发时用的 profile。插件与 profile 无关 —— 换成你自己的名字即可。 |
| 离线 | 可用。编译器与 Touying 都是本地的,构建期间不抓取任何东西。 |

安装

dsh plugin --profile desktop add @hxql/dsh-presentation

然后重启应用。已安装的插件在启动时加载,而被替换过的包需要新一代模块才会用上新代码。

重启后你从这一个包得到两样东西:

- 设置 → Agent 预设 与新会话模式选择器里的「演示模式」卡片,以及
- 随该预设挂载的 /deck 命令与五个 deck 工具。

从克隆安装则指向目录:

Linux / macOS
git clone https://github.com/hxql666/dsh-presentation
cd dsh-presentation
npm install # 拉取本平台的 Typst 二进制
dsh plugin --profile desktop add "$PWD/packages/dsh-presentation"

Windows PowerShell —— $PWD 的插值方式不同
git clone https://github.com/hxql666/dsh-presentation; cd dsh-presentation
npm install
dsh plugin --profile desktop add "$((Get-Location).Path)\packages\dsh-presentation"

绝对路径两种都行:dsh plugin --profile desktop add /abs/path/to/packages/dsh-presentation。

更新、pin 与卸载

dsh plugin --profile desktop update @hxql/dsh-presentation
dsh plugin --profile desktop add @hxql/dsh-presentation@0.4.2 # 固定版本
dsh plugin --profile desktop remove @hxql/dsh-presentation

每一步之后都要重启。卸载不会动你的 deck 目录 —— spec、生成的源码与 PDF 都留在原处。

把页面图放到你指定的位置

deck_check 默认把 PNG 写到 deck 目录下的 preview/。传 outDir 可以送到别处 ——归档目录、报告的资源目录:

{ "outDir": "01-talk/pages", "pages": [1, 2, 3] }

相对路径相对 deck 目录解析,且必须留在其中。这条限制是刻意的:outDir 由模型给出,属于不可信输入,而 Typst 的 --root 限制的是文档能读什么,不是编译器往哪写 ——已实测:用编译根之外的输出路径渲染,文件确实写到了外面。因此工具层的包含检查是 deck spec 与任意写之间的最后一道硬拒绝防线,它是拒绝而不是警告。

是「最后一道」而非「唯一一道」:这道检查的第一遍单独并不足够,下一段记录了原因。
两层,而第二层存在,是因为实测证明第一层可以被绕过。

这道检查跑两遍,第二遍是被一次实测逃逸逼出来的。第一遍比较路径字符串,能挡住所有文本形式—— ..、..\、嵌套穿越、POSIX 与盘符绝对路径、UNC 共享、以及有根无盘符的路径。它挡不住 deck 目录内部的符号链接或 junction:名字通过了,文件系统把写送到了别处。实测结果:经这样的链接写入返回 exit 0、文件落在目录树外面;而经它读取会被拒绝。所以第二遍把两个路径都 realpath 后比较真实路径,并向上找到最近的存在祖先,使尚不存在的目录仍然可用。
14 种文本向量与链接情形全部断言在 test/escape-vectors-test.mjs。

渲染会清理什么

渲染会删掉它自己上一次渲染写出的页面图,所以一个目录不会混着两次构建的页。
删什么来自 manifest(page.manifest.json,写在图片旁边),不是名字模式。
最初的实现匹配 page.png,比意图更宽 —— 你自己的 page-numbers.png 就会中招,而不是本插件写的文件就不该由它删。从未被渲染过的目录没有 manifest,因此里面一个文件都不会动。
断言在 test/stale-preview-test.mjs。

为什么不能用 git URL

一个携带平台二进制的插件,从 git URL 装并不可靠。实测而非假设:

| 尝试 | 结果 |
| dsh plugin add <本地克隆>/packages/dsh-presentation | 可用,二进制能解析 |
| 打包后的 tarball | 可用,verified=true,deck 能构建 |
| npm install github:hxql666/dsh-presentation | 失败 —— npm 克隆仓库并运行根目录的 prepare |
| npm install <仓库归档>.tar.gz | 装上了,但不会抓取 optionalDependencies,于是没有 Typst 二进制,每次构建都报 binary-unavailable |

如果构建报 binary-unavailable,说明平台包没装上。两种办法修:

在已安装的包目录里
npm install

或者让插件指向你已有的 Typst 0.15.1+ 二进制插件配置:typstBinaryPath: /absolute/path/to/typst

第二种办法也覆盖没有内置二进制的平台:32 位系统、linux-armv7、BSD。

使用

/deck 进入演示文档模式 /deck handout 讲义形态(每个逻辑页只出一帧) /deck theme:stargazer 选主题 /deck scene:academic 设定常驻场景 /deck scene off 清除场景 /deck off 退出

然后描述你要的 deck。预期流程是:deck_status 拿到可用页型、主题、场景 → 规划页序 → deck_build → deck_check 并真的读那些渲染图 → 修 → 交付。

工具

五个工具,只在模式开启时可用。模式关闭时每一个都会带解释地拒绝,且没有一个会写到 deck 目录之外。

| 工具 | 参数 | 返回 | 说明 |
| deck_status | — | 模式状态、16 种页型及其键、主题、场景、引擎版本、Typst 二进制哈希是否已校验 | 只读。先调它 —— 它才是权威列表,本文不是。 |
| deck_build | spec(必需)、scene、outFile、handout | ok、pdf、specFile、pages、bytes、diagnostics、warnings、overflow | 幂等:同一 spec 产出同一文档。写出 build/body.typ、build/deck.typ、build/layout.typ、build/deck-spec.json。必需槽位为空时拒绝构建,那种情况下不编译任何东西。 |
| deck_check | pages、ppi、outDir | ok、images、outDir、density、tooDense、diagnostics | 渲染 PNG 供模型读回。outDir 必须解析到 deck 目录内,越界是拒绝而非警告。只删除它自己上一次渲染记录在 manifest 里的页。 |
| deck_export | what(vector \| handout \| notes)、spec(handout 需要) | ok、file、bytes、pages、diagnostics | vector 与 notes 编译已存在的构建产物,所以不会与审阅过的 deck 产生偏差;handout 从其 spec 重建。 |
| deck_scaffold | spec(必需) | ok、specFile、typFile | 只写出生成的 Typst,不编译。用于查看源码。 |

五个工具的错误语义一致:ok: false 一定带上 message(输入哪里不对)、stderr (编译器说了什么)或 diagnostics 三者之一。没有任何静默失败,也没有工具会因为用户层面的错误而抛异常 —— 抛异常意味着调用方式错了,不是 deck 错了。

页型(16 种)

cover section agenda bullets steps cards kpis timeline
compare quote table code image image-text columns sources

每种页面的键(16 种)

写错键名不会报错 —— 页面照画边框、内容留空。所以 deck_build 现在会校验:缺必需内容直接拒绝构建;写了本页不读的键会作为 warning 返回,构建照常完成。

| layout | 键 |
| cover | 读 deck 级字段:title subtitle author institution date |
| section | title 或 kicker(必需其一) |
| agenda | title, items[{ text }] 或字符串数组 |
| bullets | title, lead?, items[{ text, detail? }], takeaway? |
| steps | 同 bullets,渲染为编号步骤 |
| cards | title, lead?, cards[{ title, eyebrow?, body[], footer? }], perRow?, takeaway? |
| kpis | title, lead?, items[{ value, label, note? }], takeaway? |
| timeline | title, lead?, items[{ when, what? }], takeaway? |
| compare | title、left、right(各为 { title?, items[] })、leftTitle?、rightTitle? |
| quote | quote(必需)、author? |
| table | title、lead?、headers[]、rows[][]、takeaway? |
| code | title、lead?、source(必需)、language?、takeaway? |
| image | title、image(必需)、caption?、credit?、takeaway? |
| image-text | title、body[] 或 image?、caption? |
| columns | title、lead?、columns[{ title?, items[] }]、ratios? |
| sources | title、lead?、items[](编号参考列表)、takeaway? |

每种页型都接受 notes,导出为 pdfpc 演讲者备注。

行内强调:粗体 与 斜体* 渲染为真正的粗体与斜体;其余特殊字符一律转义,写进 deck 的文本无法变成 Typst 语法。timeline 的 label/detail 作为旧拼写仍被接受。

图片必须放在 deck 目录里:image 与 image-text 的 image 是相对 deck 目录的路径,且不能越出该目录 —— Typst 以 deck 目录为 --root 编译,越界路径会被拒绝(would escape the project root)。这条限制同时是一道安全边界:一份 deck 无法被用来读取机器上的其它文件。把图片拷进 deck 目录后按文件名引用即可:

{ "layout": "image", "title": "现场照片", "image": "photo.png", "caption": "照片说明", "credit": "来源:某某" }

场景

场景是某类已知演讲的起点 —— 主题、画幅比例、字体栈、惯用页序,以及幻灯片该用的语域。
它只填充 spec 没写的东西,所以显式选择永远优先。

tech-talk · academic · teaching · product · review · pitch

主题

七套全部来自 Touying:metropolis(默认)simple university dewdrop stargazer aqua default。

发布

发布在 CI 里做,不在笔记本上做。

npm 发布需要交互式两步验证。替代方案要么是每次发布都掏验证器,要么是带 2FA 绕过的
细粒度访问令牌 —— 而 npm 已宣布这类绕过令牌将失去直接发布能力(目标 2027 年 1 月),指向 trusted publishing。

所以 .github/workflows/publish.yml 通过 OIDC 发布:注册表会验证该工作流确实在这个仓库里跑过。不存令牌、没有东西会过期、也不需要从 app 里读码。它先跑整套测试,再打包并检查 tarball 内容,发现不该有的东西就拒绝发布。

从 Actions → Publish to npm → Run workflow 运行,勾上 dry-run 可只构建校验、不发布。

一次性准备:包必须先存在,才能为它注册 trusted publisher,所以首次发布得交互式做一次。
之后在 npmjs.com 上注册 publisher —— 用户 hxql666、仓库 dsh-presentation、工作流 publish.yml。

测试

npm test

它先跑类型检查,然后是 schema 门禁、装配测试、能力扫描、语言与系统 Typst 检查、场景测试、讲义检查,最后是编码审计。先 npm install,让本平台的 Typst 二进制就位。

类型检查是 tsc --checkJs 扫源码与 JSDoc。没有构建步骤:插件直接发布它运行的 JavaScript,所以 index.js 在 tarball 里和栈追踪里都保持可读。这个检查买到的是契约不能悄悄漂移 ——给函数加了参数却没写进文档,或读了一个已不存在的属性,在这里就失败,而不是在激活时。

types/dsh.d.ts 描述本插件用到的宿主部分。DSH 不附带类型声明 —— 已安装的应用里 .d.ts 文件数为零 —— 所以那份文件是照插件自己的调用点手写的。它挡不住对宿主的错误假设, 那是测试的活。

测试套件覆盖的是真正咬过这个项目的失败模式:

- 一个畸形的工具 schema 会杀掉整个会话,不是杀掉一个工具 —— provider 会校验整个目录并拒绝每一个请求。test/schema-gate.mjs 在安装前编译并断言每个工具的 schema。
- 跳过校验的桩件恰好会掩盖这个 bug。 lib/host.js 复刻了宿主的「编译 + 校验」管线,所以一个会在激活时失败的定义,在测试里就失败。
- 编码损坏在你解析它之前是隐形的。 manifest 里一个多余的 BOM 或乱码就是真实缺陷,编码审计同时扫这两样。

为什么不做渲染缓存

一个合理的问题是:deck_check 为什么不只重渲染改动过的页?实测 —— test/perf-measure.mjs:

| deck 规模 | 构建 | 渲染全部 | 重新渲染全部 | 只渲染 1 页 |
| 5 页 | 590 ms | 605 ms | 468 ms | 561 ms |
| 15 页 | 761 ms | 508 ms | 510 ms | 457 ms |
| 40 页 | 763 ms | 802 ms | 734 ms | 779 ms |

关键一行是最后两列:只渲染 1 页和渲染全部几乎一样慢。 耗时来自 Typst 的进程启动与文档编译,光栅化只占小头。所以"只重渲染改动页"的缓存省不下多少。

而它要付出的代价是必须能正确判断"源码没变" —— 判断错了正是 0.2.1 修掉的那个缺陷: deck_check 把旧图留在原处并当成结果报告,于是模型审阅了当前 deck 里不存在的页。
用几百毫秒换一个正确性风险,不划算。测量数据放在这里,下一个人不必重跑这个实验。

许可

本仓库为 MIT —— 见 LICENSE。

被重新分发的第三方代码与那个经过校验的编译器依赖,连同它们的许可与义务,列在 THIRD-PARTY-NOTICES.md。
预览分享卡片长什么样 ↓hxql666/dsh-presentation
分享 · DeepSeek Harness Hub
hxql666/dsh-presentation

用结构化页面数据生成 PDF 并回看渲染图自检

这是你的仓库?认领条目

回到顶部