agentsclimarketplace

Html to editable pptx

Skill Hasasasa/html-to-editable-pptx

Convert HTML slide decks to truly editable PPT / .pptx - text stays native PowerPoint textboxes, not screenshots. Agent Skill (Claude Code / Cursor / Codex / opencode) + plain Python CLI.

Install
npx -y skills add Hasasasa/html-to-editable-pptx

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

当用户想把 HTML 幻灯片转成 .pptx 时触发——"HTML 转 PPT"、"网页幻灯片转 pptx"、"把这个 deck 转成 ppt"、"给同事一份 ppt 副本"、"汇报不方便放浏览器"、给了 .html 路径 + 提到 ppt/pptx/演示/幻灯片。保留矢量文字可编辑、字体按需嵌入、复杂装饰自动走截图兜底;不依赖 reveal.js / 自写 deck 等具体框架。

SKILL.md

26.0 KB, as published. Nobody here has run it

html-to-pptx

何时触发

用户说出下列任一意图:

  • "把这个 HTML / 网页 deck 转成 PPT / pptx"
  • "做了 HTML 幻灯片,要给同事一份 ppt"
  • "汇报现场不方便放浏览器,想要 ppt 文件"
  • 已有 HTML 文件路径 + 提到 ppt / pptx / 演示 / 幻灯片

调用

<skill_dir> 是这个 skill 安装路径(通常 ~/.claude/skills/html-to-pptx/,Windows 上是 %USERPROFILE%\.claude\skills\html-to-pptx\)。下面命令里的 <skill_dir> 替换成实际路径,或者先 cd <skill_dir> 再直接 python convert.py …

python <skill_dir>/convert.py <input.html>
  • 默认输出到与输入同目录的 <input>.pptx
  • 字体完全按需:HTML 用到的字体在 convert 时从 Google Fonts 拉取并 subset 嵌入,缓存到 %LOCALAPPDATA%\html-to-pptx\fonts\~/.cache/html-to-pptx/fonts/,下次同名字体秒复用
  • HTML 含 CJK 字符会自动种子 Noto Sans SC + Noto Serif SC(首次约 40 MB / ~30s 下载并 instance 静态 Regular/Bold,之后命中 cache)
  • GF 没有的家族会回退到 viewer 系统字体并打印 warning
选项含义
--out <path>自定义输出 .pptx 路径
--keep-screenshots同时保留每页 HTML 参考截图 + preflight.json
--no-embed-fonts跳过字体嵌入。文件更小但换机会回退到系统字体
--no-preflight关闭 Stage 1 风险预扫
--no-verify关闭 Stage 5a 结构化自检
--no-visual-audit关闭 Stage 5b 视觉 audit 物料产出。日常不要关
--install-user-fonts把自动解析到的非 CJK 字体装到用户字体目录(让 WPS 能正确渲染)。Win/macOS/Linux 都支持。必须先问用户,见下方"配置确认"章节
--only-slides N,N,N增量重跑。逗号分隔的页号(1-based)。measure 只跑指定页 + 与上轮 cached measurement 合并;assemble/embed 仍全量;Stage 5a 只渲指定页;Stage 5b 只重建指定页的 compare 图——其它页全部复用上轮缓存。audit 迭代轮专用,详见下方"增量重跑"章节
--cleanup不做转换。删 input.pptx 旁的 audit / measurement / preflight 工作物,只保留 .pptx 和 audited.html。最终交付前用,见下方"工作流"末步

工作副本(原 HTML 不动)

第一次 python convert.py <input>.html 跑完,convert.py 自动 cp 一份 <input>.audited.html 到源 HTML 同目录。机制:

  • 所有 audit 修复改 audited.html,不改源 HTML
  • 后续轮 convert(含 --only-slides)input 用 <input>.audited.html,输出仍是 <input>.pptx(自动去掉 .audited 后缀)
  • audited.html 已存在 → 复用,不覆盖(保留上轮修复)
  • agent 误传源 HTML 当 input → convert.py 内部检测后切到 audited.html 兜底
  • cleanup 不删 audited.html(视为可交付副产物,跟 .pptx 一组交付)
  • 想从头开始 → 手动删 audited.html 后重跑

配置(.config.local.toml

skill 根目录下可选的本机偏好文件,gitignored,每用户一份。当前有三类偏好:

[fonts]
auto_install = "ask"   # "yes" 自动装、"no" 永不装、"ask" 由 agent 询问

[cleanup]
default = "clean"      # "clean" 工作流末步自动 cleanup、"keep" 保留 audit 产物

[audit]
mode = "ask"           # "triage" / "page" / "manual" / "ask" 由 agent 询问
  • 文件 / key 缺失 → 走默认(同上)
  • 模板:<skill_dir>/.config.local.toml.example
  • fonts.auto_install 由 convert.py 强制读取并应用(=yes 自动加 --install-user-fonts、=no 自动忽略)
  • cleanup.default 由 agent 在工作流末步读取决定行为
  • audit.mode 由 agent 在第一次 convert 前确认;Stage 5b 后按该值执行审查:
    • "triage" → 主 agent 自己看 audit_contact_*.png 总览分流,再派 sub-agent 看入围页单图,节省 token
    • "page" → 每个目标页都派 sub-agent 看单页 slide_NN_compare.png,覆盖最严
    • "manual" → 只生成审查物料,交给用户人工核查;用户反馈问题后再修
    • "ask" 或缺失 → agent 通过 AskUserQuestion 收集偏好后改写此项(默认)
  • 首次使用:agent 通过 AskUserQuestion 收集 fonts.auto_installaudit.mode自己 Write 这个文件——用户不用手动建

配置确认(第一次 convert 之前完成)

两条偏好要在第一次 convert 之前确认:fonts.auto_installaudit.mode。流程相同,差别只在触发条件和问法。

通用流程

每条偏好独立按下面顺序判定:

  1. Read <skill_dir>/.config.local.toml,看对应字段:
    • 合法非 ask 值 → 按该值走,会话内不再问
    • ask 或文件 / 字段缺失 → 走"触发判定 + ask"
  2. CLAUDE.md / 全局指令写明了等同值的,按写明值走,并补写 config(保持单一事实源)

触发后 AskUserQuestion 问一次,两条都要做

  • 写入 <skill_dir>/.config.local.toml 对应字段为用户答复(不写 ask,否则下次会话还会再问)
  • 本次会话同时按答复走

写 config 时:文件不存在 → Write 整文件落盘([fonts] [cleanup] [audit] 三段模板);文件已存在 → 用 Edit 做单行 replace(只改这一个字段),不要 Write 重写整文件,否则会吞掉用户其它自定义 key。

同一会话两条都触发 → 合并到同一条 AskUserQuestion 里一次问完。

fonts.auto_install —— 字体安装

PowerPoint COM slide.Export() 和 WPS Office 都不读 pptx 内嵌的裸 TTF——audit 渲染和 WPS 都回退到系统字体。装到用户字体目录后两者都按系统字体走。目录(均为用户级,可手工删):

  • Windows: %LOCALAPPDATA%\Microsoft\Windows\Fonts\ + HKCU 注册
  • macOS: ~/Library/Fonts/
  • Linux: ~/.local/share/fonts/ + fc-cache -f

触发判定:看 HTML <head><link href="...fonts.googleapis.com/..."> / @import url(https://fonts.googleapis.com/...) / <style>font-family: 出现的字体名:

  • 触发:任何 GF / 自托管字体(Bricolage Grotesque、DM Sans、Inter、Space Grotesk、Caveat 等)
  • 不触发:只用系统字体白名单(Arial、Times New Roman、Helvetica、Helvetica Neue、Courier、system-ui、-apple-system、BlinkMacSystemFont、SF Pro、Microsoft YaHei、SimSun、PingFang、Hiragino)

按答复:同意 → 加 --install-user-fonts;拒绝 → 不加。

audit.mode —— 视觉审查模式

三种模式 triage / page / manual(含义见上方 "配置" 章节)。每次会话第一次 convert 之前都判定(不依赖 HTML 内容触发)。AskUserQuestion 用单选题,选项即三种模式。

工作流(强制)

convert.py 跑完不等于交付完成。完整流程:

convert.py(首轮自动 cp <input>.audited.html,所有修复改这个副本)
  → Stage 5a 结构化自检(OOXML 扫描,给提示)
  → Stage 5b 视觉 audit 物料 — 需要 PowerPoint COM 或 LibreOffice 渲染器
  → 读 `audit.mode` 决定审查方式:triage / page / manual
  → 【agent audit】
        triage 模式:主 agent 读 contact sheet 分流 → sub-agent 看入围页单图 → 合并写 audit_findings.md
        page 模式:全量 sub-agent 看单页 → 合并写 audit_findings.md
        manual 模式:把 audit 物料交给用户,等待用户人工反馈
  → 按 finding 逐项做最小局部修改,目标是 audited.html(见下"修复纪律")
  → 一批 finding 改完后 `convert.py <input>.audited.html --only-slides <被改页号>` + 只对 fresh 页重审(见下"增量重跑")
  → 所有页 OK 或仅剩 LOW
  → 【若撞到 HTML 反模式 / 新 OOXML 边界】沉淀到 lessons-learned,见下方"沉淀 HTML 问题与 OOXML 边界"
  → 读 `<skill_dir>/.config.local.toml` 的 `cleanup.default`:
        "clean"(缺省)→ 直接 `python convert.py <out>.pptx --cleanup`,不问用户
                          清完目录剩:<input>.html(源,未动)+ <input>.audited.html(修复版)+ <out>.pptx
        "keep"        → 跳过 cleanup,audit 产物全部保留
  → 把 .pptx 路径交付给用户(audited.html 作为修复版 HTML 一同交付)

矢量优先原则(强制)

能用 PPT 原生 text / shape / line 表达的内容,优先保持可编辑:普通背景色、普通四边框、单边线、简单矩形/椭圆、简单 ::before / ::after 线框都应走 PPT shape。

deco_snapshot 只兜底 OOXML 难表达的装饰(命中条件 + 完整档位定义 + 截图/矢量层协同机制见 references/supported-css.md)。不要为了省事把普通线条、图表轴线、简单边框统一截图——这会牺牲 PPT 可编辑性,也会让后续局部修复变难。

渲染器要求(Stage 5b 前置条件)

Stage 5b 视觉 audit 需要把 .pptx 渲染成 PNG,依赖:

  • PowerPoint COM(Windows + Office + pywin32),或
  • LibreOffice(跨平台,配 pip install pdf2image

任一可用就能跑 audit。convert 输出里看到 [self-check] 跳过:找不到可用的 pptx 渲染器,说明两个都没装——此时 audit 不会产出 compare 图,Stage 5b 直接跳过。

这种情况下 agent 必须 ask 用户(不要静默交付未审计的 pptx):

"你机器上没装 PowerPoint 也没装 LibreOffice,视觉 audit 跑不了,PPT 可能有看不出的视觉 bug。三个选择:

  1. 装 LibreOffice(推荐,跨平台,2-3 分钟):winget install LibreOffice.LibreOffice(Windows)/ brew install --cask libreoffice(mac)/ apt install libreoffice(Linux),然后 pip install pdf2image,重跑 convert
  2. 跳过 audit 直接交付(接受 PPT 可能有视觉 bug 的风险)
  3. 在已经装了 Office 的另一台机器上重跑"

用户选 1 → 等他装完重跑;选 2 → 加 --no-visual-audit 跑一遍,把告知风险后交付;选 3 → 把当前目录 + HTML 发给他。

视觉 audit 模式(config,前提:5b 跑起来了)

执行视觉审查前读取 <skill_dir>/.config.local.toml[audit].mode。正常应在第一次 convert 前通过上方 "配置确认" 完成询问;如果到这里 mode 还是 "ask"(说明 agent 漏问了),立刻按 "配置确认" 章节询问用户再继续。

每个 mode 的具体含义见上方 "配置" 章节;这里只列适用场景:

mode适用
triage默认,节省 token
page最终交付前、关键客户、用户要求最严
manual用户想自己看

triage 的分工很明确:第 1 轮 contact pass = 主 agent 自己看缩略图分流(廉价,上下文已含源 HTML / Stage 5a / preflight)第 2 轮 detail pass = 把入围页派 sub-agent 看单页 compare 图。不能只凭缩略图判 HIGH/MID finding;要报 finding 必须经第 2 轮 sub-agent 单页确认。

audit 分发与 compare 图读取规则

page 模式所有页都走 Claude Agent(...) sub-agent 并行 dispatch。triage 模式只有第 2 轮入围页走 sub-agent;第 1 轮 contact sheet 由主 agent 自己 Read,不派 sub-agent。

主 agent 主动读 compare 图的场景仅限以下五种:

  • triage 第 1 轮读 audit_contact_*.png 总览分流
  • 针对性修复的验证轮:本轮 fresh 页 ≤ 2 且改动未涉及全局 CSS → 主 agent 直读 fresh 页单图复核已知 finding + 扫该页新回归,不派 sub-agent(sub-agent 一轮 2-3 分钟,直读只要几秒)。fresh 页更多或有全局变更仍走 sub-agent
  • finding 描述含糊 / 与源代码冲突无法定位时,读对应单页 slide_NN_compare.png
  • sticky 命中前确认读单页
  • 用户点名反馈某一页读单页

除此之外不逐页 Read compare 图。

batch 按 wall-clock 优化拆小并行(sub-agent 串行读大图是延迟主因,多个小 batch 并行发满比一个大 batch 快一倍以上):

slide 数策略
≤ 21 个 batch
3-20每 batch 2 页,全部并行发
> 20每 batch 3 页(控制 agent 总数)

完整 sub-agent 调用模板 + 检查清单 + findings 格式见 <out>_audit/audit_prompt.md。多个 Agent(..., run_in_background: true, subagent_type: "general-purpose") 调用塞在主 agent 同一条 message 里才并行。

sub-agent 只返回 findings 文本(page 模式含每个目标页的 ## page NN 块;triage 细看批次含每个被放大复核页的块),主 agent 统一合并写 audit_findings.md——并发写会互相覆盖。

每条 finding 必须点名稳定元素短名,并描述"HTML 半图实际状态;PPT 半图差异"。只报告 PPT 相对 HTML 新增或放大的视觉问题;HTML 半图本身已有的问题不算转换 finding。

与 sub-agent 并行的主 agent 准备(强制)

发起 page 模式或 triage 第 2 轮 detail sub-agent 时,Agent 调用用 run_in_background: true,并在同一条 message 里同时发:

Agent(run_in_background: true, subagent_type: "general-purpose", description: "Audit slides 1-4", prompt: ...)
Agent(run_in_background: true, subagent_type: "general-purpose", description: "Audit slides 5-9", prompt: ...)
Read(file_path: "<deck>/template.html")
Read(file_path: "<skill_dir>/references/lessons-learned.md")
Grep(pattern: "class=\"slide |data-slide=", path: "<deck>/template.html",
     output_mode: "content", -n: true)

每个 sub-agent prompt 里必须直接写入本批 slide_NN_compare.png 绝对路径、deck HTML 路径、lessons-learned.md 路径(适用范围见上方"视觉 audit 模式"章节);不要假设主 agent 的 Read / Grep 输出会自动传给 sub-agent。

只发"无论 findings 是什么都用得上"的准备——不要预测 findings 提前改 HTML。

修复纪律(针对 finding,不追根因)

收到 audit_findings.md 之后,一轮里把本轮所有 finding 都改完,再一次性重跑 convert + audit——不是改一个跑一次。一轮 = 一批 HTML 编辑 + 一次 convert + 一次 audit。

拿到 findings 之后:

  • 常规自己 Read compare 图(findings 已经把症状写明);三种例外读单页复核见上方 "audit 分发与 compare 图读取规则" 章节
  • measure.py / assemble.py / 任何 skill 内代码找根因
  • 直接打开 audited.html 按 finding 逐条改

每个 finding 内部做最小局部 HTML 修改:

  • 每个 finding 只改"让它消失"的那一处,改完进下一个 finding(继续改 HTML,不是重跑 convert)

  • 追溯"为什么字体回退 / 为什么布局偏移"的深层根因

  • 做"我顺手把 .footer 也改成绝对定位"这种 finding 列表外的优化

  • 跨 finding 做结构性重构("统一把所有 slide 的 font-family 显式声明"≠ 单个 finding 的最小修复)

  • 同一 finding 在连续两轮(上一轮 + 本轮)都出现 → sticky 命中,停下来告诉用户,不要继续扩大改动面。判定 key = (页号, 视觉元素短名)

    • 措辞 / 严重度 / HIGH↔MID 切换都不重置判定。例:(page 5, take 字号) 在 round 6 被描述成"偏小"、round 7 被描述成"严重不足" → 同一 sticky key,round 7 即命中
    • 只有"页号 + 元素"都不重合才算新 sticky key
    • 隔轮恢复:若 round 6 出现、round 7 消失、round 8 又出现 → 不算 sticky(round 7 缺席视为问题已修,round 8 是新回归)
    • 命中 = 本轮不修该 finding、列入 skill 边界候选告诉用户,本轮其他 finding 照修

    实施:每轮合并完 audit_findings.md、动 Edit 之前,必须先 Read 上一轮 audit_findings.md(首轮无)做两两比对——本轮和上轮出现的 key 即命中。命中的 finding 单独列出来交给用户判断,不再进本轮编辑队列。

本批 finding 改完一次性 python convert.py <input>.audited.html --only-slides <被改过的页号>

判定标准:你的 diff 行数 ≤ findings 数 × 3 行。超过这个量级说明在"乱发挥"。

增量重跑(--only-slides

audit 第 2 轮起用,首轮全量。

python convert.py <input>.audited.html --only-slides 2,7,12

增量覆盖 measure / Stage 5a 渲染 / Stage 5b compare 图,仅对列出的页 + 缓存缺失的页执行;assemble / embed_fonts 仍全量。audit_index.jsonincremental_mode: truefresh_indicescached_indices、每页 fresh: true/false

增量轮的 audit 目标页只取 fresh_indicespage 模式直接分发这些页;triage 模式先在这些页范围内分流,再把入围页发给 sub-agent。

前提:上轮的 <out>_audit/ 目录还在。cache 缺失自动回退全量;HTML 页数变化自动检测并回退全量 measure。

不能用 --only-slides 的情况(视觉溢出列出的页,缓存假阴性):

  • 全局 CSS(<style>、根选择器、.slide 通用样式)变更
  • 新增 / 删除字体(@import、font-family 声明变更)
  • deck-level token(背景、主题色、间距)变更
  • 任何影响其它页布局的全局变量变更

这几类不带 flag 全量重跑。判断不准 → 全量重跑总是安全的。

沉淀 HTML 问题与 OOXML 边界(强制)

你的角色是调用 + 用法沉淀,不是修 skill。发现 skill 内部 bug 时不要原地改 measure.py / assemble.py

只沉淀两类:

1. HTML 写法问题(用户的 HTML 让转换失真)

类别判定做什么
单次 case(只在这 deck 出现,改一两行 HTML 就好)单页特例直接改 HTML 源;不沉,不通报
通用 HTML 反模式(任何人写类似 HTML 都会踩)跨 deck改 HTML + 沉到 references/lessons-learned.md 的 "HTML 写法规避" 区

2. OOXML 表达力边界(PowerPoint / OOXML 天然不支持)

绝大多数装饰类 CSS(backdrop-filter / filter / mix-blend-mode / skew / box-shadow / gradient / ::before ::after 装饰用法——空 content + bg-image / box-shadow 等)已经被"覆盖策略"里的 hasComplexDecoration 自动捕获走 deco_snapshot——HTML 不用改::before ::after string contentcontent: "↑" 等)走文字通道,详见 references/supported-css.md 第 1 档。

仍需 HTML workaround 的真边界(OOXML 文字层原生表达不了的):

边界替代通路
彩色 emoji(COLR/CPAL 字体)Twemoji SVG <img>,走 img 通道嵌入
background-clip: text 文字渐变inline <svg><text fill="url(#grad)">,走 SVG 通道

撞到这两类 → 改 HTML 走替代通路 + 沉到 references/lessons-learned.md 的 "OOXML 边界" 区。

撞到不在上表的新 CSS 不支持 → 先看 hasComplexDecoration 是不是漏触发(加一行触发条件即可),而不是改 HTML。详见 references/supported-css.md 的"加新支持的标准做法"。

看似 skill 内 bug 怎么处理(不修不沉

发现某症状用同种 CSS 模式换 deck 还会撞、且不在已知 OOXML 边界内 → 这是 skill 抽象不到位。不要原地改 skill 代码。做这两件事:

  1. 当前 deck 走 HTML 端 workaround 把 finding 修掉,让用户拿到能交付的 PPT
  2. 明确告知用户:"发现一个看起来是 skill 内的通用 bug:[症状 + 触发 CSS 模式 + 当前 workaround]。建议作者按 issue 收录,让 skill 在 measure/assemble 里更通用地处理这种模式"

沉淀写到哪:本地副本 + 上游模板

references/lessons-learned.md每用户独立的本地工作副本(gitignored)。首次跑 convert.pylocal_config.seed_lessons_learned() 自动从模板 lessons-learned.md.example(committed)拷贝一份。机制和 .config.local.toml 一样。

  • agent 排查 / 沉淀都读写本地 lessons-learned.md——自由加 / 改 / 整理,无 git 噪声
  • 本地副本永不被上游覆盖——git pull 拉的是 .example 模板,不动你的工作副本
  • 想把某条沉淀上游:作者手动把 entry 复制回 lessons-learned.md.example 再 commit;选择性 curate,不是全推
  • 本地业务 / 特定客户专有写法 → 直接写在本地副本里就行,不会上游
  • lessons 条目只写可复用的症状、触发模式、规避规则;不要写具体本地文件名、模板名、页面号、客户名或源码文件名。具体实现位置、命令和代码细节留在 commit / issue / 主 skill 文档里

触发:撞到通用 HTML 反模式 / OOXML 边界 → 加到本地 lessons-learned.md 对应表。每次 convert 都重读,立即生效。

覆盖策略(一句话)

skill 内部把所有 CSS 翻译成四档输出:矢量文字 → 矢量形状 → 栅格装饰(deco_snapshot)→ 媒体直传。简单 bg-color / border / border-radius 走前两档(可编辑可搜索),box-shadow / gradient / filter / backdrop-filter / mix-blend-mode / 非对称圆角 / 裁切容器 + 旋转子 等命中 hasComplexDecoration 走第三档(栅格只截装饰像素,文字始终保留矢量画在截图之上)。

完整档位定义 / 触发条件 / 加新支持指南(矢量优先 → 截图兜底)→ references/supported-css.md

流水线

[1 输入识别/预扫] → [2 测量] → [3 组装] → [4 字体嵌入] → [5a 结构化自检] → [5b 视觉 audit]
   preflight.py    measure.py   assemble.py   embed_fonts.py  self_check.py    visual_audit.py

各阶段动作 / 反假设规则 / 退出断言 / 新模板 checklist → references/methodology.md

Stage 5b 产出 <out>_audit/(compare 图 + contact sheet + audit_index.json + audit_prompt.md)。不做像素 diff — 数字对局部 bug 不敏感、给假信心;视觉判断按 audit.mode 走 triage / page / manual。无渲染器时 5b 跳过,按上面"渲染器要求"小节 ask 用户。

调用前确认

  1. 输入是单文件 HTML,含若干 slide 元素(<section class="slide"> / <div class="slide"> / <deck-stage> 子节点等都支持)
  2. 不需要为用户配置切页机制 —— skill 自动识别
  3. 用户已写好 HTML 才来调用,按要求转就行

报告

用户反馈处理
想加页 / 改文字改源 <input>.html(不是 audited.html,那是 audit 修复版)→ 删 audited.html → 重跑 convert
排版问题 / 字溢出 / 撑出框先看 HTML 参考图是否也溢出;若 HTML 正常、PPT 异常,按 references/lessons-learned.md 排查
装饰显示成方块看 compare 图判断是几何、画面捕获还是渲染器差异,查 lessons-learned.md 的 OOXML 边界表
字体不对(PowerPoint 里看)lessons-learned.md "已知 regression checkpoint" 的 GF 字体名归一 / weight 槽分配两条;撞到了 HTML 端绕开(换字体名 / 调权重)+ 告知作者提 issue
字体不对(WPS 里看)99% 是 WPS 不读裸 TTF 嵌入字体。问用户是否同意装到用户字体目录后用 --install-user-fonts 重转
中文显示方框 □□□检查 OOXML rPr 的 <a:ea> 是否走了 CJK 字体
居中文字位置偏下 / 偏出容器lessons-learned.md "已知 regression checkpoint" 的 flex + align-items:center 条目;撞到了 HTML 端绕开(拆容器 / 改对齐)+ 告知作者提 issue

不要

  • 不向用户解释完整管线(除非问),只报告转换结果与告警
  • 不在未看 audit compare 图前就归因
  • 不承诺 1:1 视觉还原 —— OOXML 表达力有限

排查路径

先判档位:80% 的 finding 不是档位内 bug,是档位选错了。看 <out>_preflight.json<out>_measurements.json 里这个元素走了 text / shape / deco_snapshot / svg 哪条路径,对照症状:

症状大概率原因
deco_snapshot 但视觉缺装饰截图前的 hide JS 漏掉了什么;或 deco 区域比预期小
text 但样式没对上(颜色 / 字号 / 行距)measure 抓 style 字段不全 / assemble 翻译漏字段
shape 但圆角 / border 不对border-radius 数值或 _round_kind 阈值
视觉效果(gradient / shadow / filter)完全丢该走 deco_snapshot 但没走hasComplexDecoration 漏触发,加一行
文字消失走了截图档但没发对应 text 记录;或 hide JS 把不该 hide 的也 hide 了

然后再走通常流程:

  1. 看 Stage 5a 自检报告:哪几页被告警
  2. 看 Stage 5b audit 结果:按 audit.mode 获取 findings 或人工反馈;只有用户反馈 / 告警对应页需要人工复核时,才用 Read 看那一页 compare 图
  3. references/lessons-learned.md 已知症状(HTML 反模式 / OOXML 边界)
  4. HTML 正常、PPT 异常且不符合已知边界 → 看是不是 skill 抽象不到位(按"看似 skill 内 bug 怎么处理"流程:HTML workaround 修当前 deck + 告知用户提 issue)

引用

  • 五步反假设流水线 + 每步反假设规则 + 退出断言 + 新模板 checklist → references/methodology.md(作者扩展 skill 时读,agent 调用不必读)
  • CSS 覆盖范围(四档详表)+ hasComplexDecoration 完整触发清单 + 加新支持的标准做法 → references/supported-css.md(agent 想理解某 CSS 走哪档时读,作者扩展必读)
  • 历史踩坑修复 + HTML 反模式 + OOXML 边界 → references/lessons-learned.md(agent 排查必读)。本地工作副本(gitignored,首次 convert 自动从 lessons-learned.md.example seed),自由加 / 改 / 整理;想上游某条 → 作者手动复制回 .example 再 commit

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.