1 line
58 KiB
JSON
1 line
58 KiB
JSON
{"repo": "caciniep/ppt-skills", "files": {"README.zh-CN.md": {"5986d74ae9292b4868f4bc6bf8a63abf289b1fb2": {"t": 1785674629.5340843, "n": 11048, "h": "fbe2442726a490c2", "c": "# PPT 技能合集\n\n[English](README.md) | **简体中文**\n\n<p align=\"center\">\n <img src=\"docs/img/hero-demos.png\" alt=\"ppt-skills 演示 deck —— miku、editorial-grid、dark-launch\" width=\"820\" />\n</p>\n\n<p align=\"center\">\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/github/license/CacinieP/ppt-skills?style=flat-square\" alt=\"License\" /></a>\n <a href=\"https://github.com/CacinieP/ppt-skills/actions/workflows/ci.yml\"><img src=\"https://img.shields.io/github/actions/workflow/status/CacinieP/ppt-skills/ci.yml?branch=main&label=CI&style=flat-square\" alt=\"CI\" /></a>\n <img src=\"https://img.shields.io/badge/skills-1%20released-39c5bb?style=flat-square\" alt=\"Skills\" />\n <img src=\"https://img.shields.io/badge/output-editable%20.pptx-0A7CFF?style=flat-square\" alt=\"PPTX\" />\n <img src=\"https://img.shields.io/badge/node-%E2%89%A5%2020-339933?style=flat-square\" alt=\"Node\" />\n</p>\n\n用 PptxGenJS 生成并**验收**真实、**可编辑、适配中文排版的 PPTX** 的开源技能合集 —— 由一道确定性 QA 门禁把关,而非肉眼。\n\n首个技能 [`themed-cn-pptx`](skills/themed-cn-pptx/) 内置两套**锁定审美 recipe**(editorial-grid、dark-launch)、provider 感知的 AI 配图层(StepFun / MiniMax),以及三个 QA 工具(渲染 QA、CJK 溢出、可编辑性检查)。\n\n---\n\n## 🎬 演示画廊\n\n三套锁定 demo,全部本仓库生成,**无需任何 API key**(纯色/发丝线占位回退)。下图用 LibreOffice 150 DPI 渲染。\n\n| 演示 | 页数 | 配方 | 风格 |\n| --- | --- | --- | --- |\n| **Miku** | 3 | `miku`(技能展示) | 青粉撞色,明暗交替 |\n| **Editorial Grid** | 6 | `recipe-editorial-grid.mjs` | Nord 中性色,发丝线报告风 |\n| **Dark Launch** | 5 | `recipe-dark-launch.mjs` | 深底大字,白框二维码收尾 |\n\n### Miku —— 技能展示\n\n<p align=\"center\">\n <a href=\"docs/img/demos/miku/miku-slide-1.jpg\"><img src=\"docs/img/demos/miku/miku-slide-1.jpg\" width=\"280\" alt=\"miku 封面\" /></a>\n \n <a href=\"docs/img/demos/miku/miku-slide-2.jpg\"><img src=\"docs/img/demos/miku/miku-slide-2.jpg\" width=\"280\" alt=\"miku 内容\" /></a>\n \n <a href=\"docs/img/demos/miku/miku-slide-3.jpg\"><img src=\"docs/img/demos/miku/miku-slide-3.jpg\" width=\"280\" alt=\"miku 总结\" /></a>\n</p>\n\n### Editorial Grid —— 编辑报告风\n\n<p align=\"center\">\n <a href=\"docs/img/demos/editorial/editorial-slide-1.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-1.jpg\" width=\"195\" alt=\"editorial 第1页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-2.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-2.jpg\" width=\"195\" alt=\"editorial 第2页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-3.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-3.jpg\" width=\"195\" alt=\"editorial 第3页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-4.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-4.jpg\" width=\"195\" alt=\"editorial 第4页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-5.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-5.jpg\" width=\"195\" alt=\"editorial 第5页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-6.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-6.jpg\" width=\"195\" alt=\"editorial 第6页\" /></a>\n</p>\n\n### Dark Launch —— 发布收尾风\n\n<p align=\"center\">\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-1.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-1.jpg\" width=\"232\" alt=\"darklaunch 第1页\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-2.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-2.jpg\" width=\"232\" alt=\"darklaunch 第2页\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-3.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-3.jpg\" width=\"232\" alt=\"darklaunch 第3页\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-4.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-4.jpg\" width=\"232\" alt=\"darklaunch 第4页\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-5.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-5.jpg\" width=\"232\" alt=\"darklaunch 第5页\" /></a>\n</p>\n\n> `.pptx` 源文件已提交在 `examples/slides/output/`,可直接用 PowerPoint 打开编辑。\n\n---\n\n## ✨ 核心亮点\n\n- **可编辑 PPTX** —— 输出真实 `.pptx`,非整页图片;由 `pptx-editable-check.py` 验证。\n- **中文排版优先** —— 字体回退、全角符号、保守字号;溢出在渲染前预测。\n- **渲染 QA 门禁** —— `render-qa.mjs` 捕捉溢出、遮挡、越界、比例错误、缺页码 badge。\n- **锁定配方** —— 两套锁定 recipe(editorial-grid、dark-launch),不用每次重新决定。\n- **供应商感知 AI 配图** —— StepFun(推荐)/ MiniMax,国内/国际版,PPT 友好尺寸预设。\n- **WCAG 色彩 QA** —— sRGB 亮度对比,非肉眼;CI 门禁遇 P0 即失败。\n- **优雅降级** —— 没有 API key?纯色占位继续生成,绝不崩溃。\n\n---\n\n## 🚀 快速开始\n\n```bash\ngit clone https://github.com/CacinieP/ppt-skills.git\ncd ppt-skills\nnpm ci # 安装锁定依赖\nnpm test # smoke + 预置色板对比度 QA\nnpm run demos # 一次构建全部三套 demo(无需 key)\n```\n\n然后把下面这段发给有 shell 权限的 Agent:\n\n```text\n帮我把这份 README 做成可编辑中文 PPTX,约 8 页,editorial-grid 配方。\n```\n\n**或直接安装技能:**\n\n```bash\nnpx skills add https://github.com/CacinieP/ppt-skills --skill themed-cn-pptx\n```\n\n---\n\n## 📋 命令\n\n### 生成\n\n| 命令 | 作用 |\n| --- | --- |\n| `npm run demo` | 3 页 **Miku** demo(无需 key) |\n| `npm run demo:editorial` | 6 页 **editorial-grid** recipe demo |\n| `npm run demo:darklaunch` | 5 页 **dark-launch** recipe demo |\n| `npm run demos` | 一次构建全部三套 |\n\n### QA 门禁\n\n| 命令 | 作用 |\n| --- | --- |\n| `npm test` | 导入/供应商/尺寸 **+** 预置色板对比度 QA |\n| `npm run qa:render -- deck.pptx` | **PPTX 渲染 + 启发式 QA** —— 溢出、遮挡、越界、图文比例、页码 badge。P0 即退出码 1 |\n| `npm run qa:render -- deck.pptx --render --out ./qa` | 上述 **+** 在装了 LibreOffice + poppler 时额外驱动 `soffice → pdf → jpg` |\n| `npm run qa:cjk -- --text \"标题\" --font-size 44 --box-width 9` | **免渲染 CJK 溢出估算**,生成前先用 |\n| `npm run qa:editable -- deck.pptx` | **可编辑性 / CJK 字体 / 宏 / 主题检查**(Python;无 python-pptx 时 zip 回退) |\n| `npm run color:qa -- --palette 0F2233,F1FBFA,39C5BB,FF77AA --role body` | 调色板 WCAG 对比 |\n| `npm run color:qa:presets` | 全部预置色板(CI 门禁,P0 即退出码 1) |\n\n---\n\n## 🛠️ 工作流\n\n**A. 改已有 PPT** —— 读 deck / `build_*.js`,明确改动范围(颜色、页数、配图、文案、二维码、版式),编辑 + 重新生成,然后跑渲染 QA 修到干净。\n\n**B. 从文稿生成** —— 提取源内容 → 拆成页级信息 → 定义主题 token + 配图需求 → 选可复用版式 → 生成 AI 配图、嵌入、跑渲染 QA。\n\n---\n\n## 🎨 AI 配图\n\n用 [`skills/themed-cn-pptx/lib/ai-image.js`](skills/themed-cn-pptx/lib/ai-image.js)。没有 key → 返回 `null`,构建回退到占位图。\n\n```js\nimport { generateSlideImage, addImageToSlide, addImageOverlay } from \"./lib/ai-image.js\";\n\nconst cover = await generateSlideImage({\n provider: \"stepfun-cn\", // 推荐;也支持 stepfun-global / minimax-cn / minimax-global\n prompt: \"青绿色科技封面背景,干净留白,留出标题区域\",\n usage: \"cover\", // StepFun -> 1360x768,MiniMax -> 16:9\n});\n\nif (cover) {\n addImageToSlide(slide, cover, { x: 0, y: 0, w: 10, h: 5.625 });\n addImageOverlay(slide, pres, { color: \"0B1B2B\", opacity: 45 }); // 任何压字的图都需 40-55% 遮罩\n}\n```\n\n### 供应商优先级\n\n1. `generateSlideImage()` 的 `provider` 参数\n2. `PPT_IMAGE_PROVIDER` / `AI_IMAGE_PROVIDER` 环境变量\n3. 仅当 `MINIMAX_API_KEY` 存在且无 `STEPFUN_API_KEY` 时选 MiniMax\n4. 默认:StepFun 国内版\n\n### 环境变量\n\n```bash\nPPT_IMAGE_PROVIDER=stepfun # stepfun | minimax (推荐 stepfun)\nPPT_IMAGE_REGION=cn # cn | global\nSTEPFUN_API_KEY=sk-xxx\nSTEPFUN_REGION=cn # cn -> api.stepfun.com | global -> api.stepfun.ai\nSTEPFUN_API_MODE=platform # platform | step_plan\nMINIMAX_API_KEY=sk-xxx\nMINIMAX_REGION=global # cn -> api.minimaxi.com | global -> api.minimax.io\n```\n\n助手在导入时自动读取 `.env`;shell/CI 变量优先级更高。`.env` 只放本地(已 gitignore),切勿提交 key。\n\n### 尺寸映射\n\n| 用途 | StepFun 尺寸 | MiniMax 比例 | PPTX 布局 |\n| --- | --- | --- | --- |\n| `cover` / `coverOverlay` | `1360x768` | `16:9` | `10 × 5.625 in` |\n| `hero` / `bannerWide` | `1360x768`(+裁切) | `16:9` / `21:9` | `10 × 3 in` / `10 × 2.45 in` |\n| `sideStrip` / `phoneMockup` | `768x1360` | `9:16` | `2.5 × 4.44 in` / `1.8 × 3.2 in` |\n| `card` | `1024x1024` | `1:1` | `2.5 × 2.5 in` |\n| `cardWide` / `showcase` | `1184x896` | `4:3` | `3.5 × 2.65 in` / `3.9 × 2.95 in` |\n| `cardTall` | `896x1184` | `3:4` | `2.3 × 3.04 in` |\n| `icon` | `512x512` | `1:1` | `1.5 × 1.5 in` |\n\n规则:用 `getImageUsageConfig(usage, provider)` 或 `SIZE_MAP`,不要手写混用 StepFun 尺寸和 MiniMax 比例。StepFun `step-image-edit-2` 支持精确的 PPT 友好像素尺寸,这也是推荐它的原因。\n\n### 国内 / 国际版端点\n\n| 供应商 | 版本 | 默认 Base URL |\n| --- | --- | --- |\n| StepFun | 国内 | `https://api.stepfun.com/v1` |\n| StepFun | 国际 | `https://api.stepfun.ai/v1` |\n| StepFun Step Plan | 国内 | `https://api.stepfun.com/step_plan/v1` |\n| StepFun Step Plan | 国际 | `https://api.stepfun.ai/step_plan/v1` |\n| MiniMax | 国内 | `https://api.minimaxi.com/v1` |\n| MiniMax | 国际 | `https://api.minimax.io/v1` |\n\n官方文档:[StepFun 国内](https://platform.stepfun.com/docs/zh/api-reference/images/image) · [StepFun 国际](https://platform.stepfun.ai/docs/en/api-reference/images/image) · [StepFun Step Plan](https://platform.stepfun.com/docs/zh/step-plan/integrations/image-api) · [MiniMax 国内](https://platform.minimaxi.com/docs/api-reference/image-generation-i2i)\n\n---\n\n## 🧪 QA 预期\n\n真实交付前先渲染检查:\n\n```bash\nsoffice --headless --convert-to pdf deck.pptx\npdftoppm -jpeg -r 100 deck.pdf slide\n```\n\n重点检查:中文溢出、全角符号挤压、图片上文字可读性、二维码对比度、页脚压内容、AI 配图比例是否匹配。`render-qa.mjs` 会自动跑确定性检查。\n\n### 色彩 QA 规则\n\n- 正文 / URL / 脚注:**≥ 4.5:1**\n- 大标题 / 图标 / 边框 / UI:**≥ 3:1**\n- 不用高饱和副色当正文\n- 不只靠红/绿表达状态\n- AI 图上放文字需 40–55% 遮罩\n\n---\n\n## 🧭 与 `guizang-ppt-skill` 的关系\n\n`guizang-ppt-skill` 是成熟的**单文件 HTML 横向翻页 deck** 技能 —— 浏览器优先、强审美模板。本仓库走的是**另一条路线,不是竞品**。\n\n| 维度 | `guizang-ppt-skill` | `ppt-skills`(本仓库) |\n| --- | --- | --- |\n| **输出物** | 单文件 HTML,浏览器 | 真实可编辑 `.pptx`,PowerPoint |\n| **适合** | 线下分享、demo day、个人风格演讲 | 需交付 .pptx、后续可编辑、中文排版稳定的 deck |\n| **审美系统** | 两套固定模板(杂志风、瑞士风) | 两套锁定 recipe + 可扩展主题系统 |\n| **QA 方式** | HTML 版式校验器(`data-layout`) | PPTX 渲染 + 启发式 QA、CJK 溢出、可编辑性、色彩对比 |\n| **配图** | Codex/GPT-Image 入 HTML | provider 层(StepFun/MiniMax)返回 PPTX layout 元数据 |\n\n**两条路线,互补。** 浏览器演讲选 HTML;交付物必须是 `.pptx` 选本仓库。\n\n---\n\n## 📦 平台支持\n\n| 平台 | 状态 | 说明 |\n| --- | --- | --- |\n| Claude Code / Codex / ZCode | ✅ 支持 | 原生 skill 工作流 |\n| Cursor / 本地 Agent | ✅ 可用 | 需文件读写 + shell |\n| CI(GitHub Actions) | ✅ 已测 | Node 20/22 矩阵,npm ci,smoke + 色彩 QA + demo 构建 + 渲染 QA |\n| 纯聊天机器人 | ⚠️ 不推荐 | 没有文件系统 + shell,稳定 PPTX + QA 很难 |\n\n---\n\n## 📁 仓库结构\n\n```text\nppt-skills/\n README.md README.zh-CN.md docs/ # 渲染好的 demo 图片(已提交)\n package.json design-principles.md\n .github/workflows/ci.yml\n examples/\n build_miku_demo.mjs build_editorial_demo.mjs build_darklaunch_demo.mjs\n color-qa.sample.json color-qa.presets.json cjk-overflow.sample.json render-qa.sample.json\n slides/output/ # 已提交的 .pptx demo —— 用 PowerPoint 打开编辑\n miku-demo.pptx editorial-demo.pptx darklaunch-demo.pptx\n scripts/\n smoke-test.mjs color-qa.mjs color-qa-presets.mjs\n render-qa.mjs cjk-overflow-check.mjs pptx-editable-check.py\n skills/themed-cn-pptx/\n skill.md\n references/ aesthetic-rules.md image-constraints.md layout-slots.md\n recipes/ recipe-editorial-grid.mjs recipe-dark-launch.mjs design-contract*.md\n lib/ ai-image.js stepfun-image.js cjk-text.js pptx-shapes.js zip-reader.js\n```\n\n---\n\n## 🤝 适合 / 不适合\n\n**✅ 适合** —— 需要交付 `.pptx` / 后续在 PowerPoint 编辑 / 中文排版稳定 / 二维码收尾页 / 可验证的 CI 门禁构建。\n\n**❌ 不适合** —— 只要浏览器演示(用 HTML deck 技能)/ 大型动态数据看板 / 永远不碰 PowerPoint 的 deck。\n\n## 🖋️ 版权与 IP 提醒\n\n角色/IP 主题优先使用色彩系统、抽象符号和用户授权素材。不要暗示官方背书;除非用户拥有权利或明确要求 legally-safe 的 inspired-by 方向,否则不要生成商标角色图。\n\n## 🤝 贡献\n\n有 PPT 技能 recipe?在下面目录提 PR:\n\n```text\nskills/<skill-name>/skill.md\nskills/<skill-name>/lib/ # 可选工具代码\nskills/<skill-name>/examples/ # 可选构建脚本\n```\n\n## 许可\n\n[MIT](LICENSE)\n"}, "c847ac81b1b81c5e5f4d0aff959451d3bdc98afa": {"t": 1785846910.6876082, "n": 11048, "h": "fbe2442726a490c2", "c": "# PPT 技能合集\n\n[English](README.md) | **简体中文**\n\n<p align=\"center\">\n <img src=\"docs/img/hero-demos.png\" alt=\"ppt-skills 演示 deck —— miku、editorial-grid、dark-launch\" width=\"820\" />\n</p>\n\n<p align=\"center\">\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/github/license/CacinieP/ppt-skills?style=flat-square\" alt=\"License\" /></a>\n <a href=\"https://github.com/CacinieP/ppt-skills/actions/workflows/ci.yml\"><img src=\"https://img.shields.io/github/actions/workflow/status/CacinieP/ppt-skills/ci.yml?branch=main&label=CI&style=flat-square\" alt=\"CI\" /></a>\n <img src=\"https://img.shields.io/badge/skills-1%20released-39c5bb?style=flat-square\" alt=\"Skills\" />\n <img src=\"https://img.shields.io/badge/output-editable%20.pptx-0A7CFF?style=flat-square\" alt=\"PPTX\" />\n <img src=\"https://img.shields.io/badge/node-%E2%89%A5%2020-339933?style=flat-square\" alt=\"Node\" />\n</p>\n\n用 PptxGenJS 生成并**验收**真实、**可编辑、适配中文排版的 PPTX** 的开源技能合集 —— 由一道确定性 QA 门禁把关,而非肉眼。\n\n首个技能 [`themed-cn-pptx`](skills/themed-cn-pptx/) 内置两套**锁定审美 recipe**(editorial-grid、dark-launch)、provider 感知的 AI 配图层(StepFun / MiniMax),以及三个 QA 工具(渲染 QA、CJK 溢出、可编辑性检查)。\n\n---\n\n## 🎬 演示画廊\n\n三套锁定 demo,全部本仓库生成,**无需任何 API key**(纯色/发丝线占位回退)。下图用 LibreOffice 150 DPI 渲染。\n\n| 演示 | 页数 | 配方 | 风格 |\n| --- | --- | --- | --- |\n| **Miku** | 3 | `miku`(技能展示) | 青粉撞色,明暗交替 |\n| **Editorial Grid** | 6 | `recipe-editorial-grid.mjs` | Nord 中性色,发丝线报告风 |\n| **Dark Launch** | 5 | `recipe-dark-launch.mjs` | 深底大字,白框二维码收尾 |\n\n### Miku —— 技能展示\n\n<p align=\"center\">\n <a href=\"docs/img/demos/miku/miku-slide-1.jpg\"><img src=\"docs/img/demos/miku/miku-slide-1.jpg\" width=\"280\" alt=\"miku 封面\" /></a>\n \n <a href=\"docs/img/demos/miku/miku-slide-2.jpg\"><img src=\"docs/img/demos/miku/miku-slide-2.jpg\" width=\"280\" alt=\"miku 内容\" /></a>\n \n <a href=\"docs/img/demos/miku/miku-slide-3.jpg\"><img src=\"docs/img/demos/miku/miku-slide-3.jpg\" width=\"280\" alt=\"miku 总结\" /></a>\n</p>\n\n### Editorial Grid —— 编辑报告风\n\n<p align=\"center\">\n <a href=\"docs/img/demos/editorial/editorial-slide-1.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-1.jpg\" width=\"195\" alt=\"editorial 第1页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-2.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-2.jpg\" width=\"195\" alt=\"editorial 第2页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-3.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-3.jpg\" width=\"195\" alt=\"editorial 第3页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-4.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-4.jpg\" width=\"195\" alt=\"editorial 第4页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-5.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-5.jpg\" width=\"195\" alt=\"editorial 第5页\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-6.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-6.jpg\" width=\"195\" alt=\"editorial 第6页\" /></a>\n</p>\n\n### Dark Launch —— 发布收尾风\n\n<p align=\"center\">\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-1.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-1.jpg\" width=\"232\" alt=\"darklaunch 第1页\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-2.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-2.jpg\" width=\"232\" alt=\"darklaunch 第2页\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-3.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-3.jpg\" width=\"232\" alt=\"darklaunch 第3页\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-4.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-4.jpg\" width=\"232\" alt=\"darklaunch 第4页\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-5.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-5.jpg\" width=\"232\" alt=\"darklaunch 第5页\" /></a>\n</p>\n\n> `.pptx` 源文件已提交在 `examples/slides/output/`,可直接用 PowerPoint 打开编辑。\n\n---\n\n## ✨ 核心亮点\n\n- **可编辑 PPTX** —— 输出真实 `.pptx`,非整页图片;由 `pptx-editable-check.py` 验证。\n- **中文排版优先** —— 字体回退、全角符号、保守字号;溢出在渲染前预测。\n- **渲染 QA 门禁** —— `render-qa.mjs` 捕捉溢出、遮挡、越界、比例错误、缺页码 badge。\n- **锁定配方** —— 两套锁定 recipe(editorial-grid、dark-launch),不用每次重新决定。\n- **供应商感知 AI 配图** —— StepFun(推荐)/ MiniMax,国内/国际版,PPT 友好尺寸预设。\n- **WCAG 色彩 QA** —— sRGB 亮度对比,非肉眼;CI 门禁遇 P0 即失败。\n- **优雅降级** —— 没有 API key?纯色占位继续生成,绝不崩溃。\n\n---\n\n## 🚀 快速开始\n\n```bash\ngit clone https://github.com/CacinieP/ppt-skills.git\ncd ppt-skills\nnpm ci # 安装锁定依赖\nnpm test # smoke + 预置色板对比度 QA\nnpm run demos # 一次构建全部三套 demo(无需 key)\n```\n\n然后把下面这段发给有 shell 权限的 Agent:\n\n```text\n帮我把这份 README 做成可编辑中文 PPTX,约 8 页,editorial-grid 配方。\n```\n\n**或直接安装技能:**\n\n```bash\nnpx skills add https://github.com/CacinieP/ppt-skills --skill themed-cn-pptx\n```\n\n---\n\n## 📋 命令\n\n### 生成\n\n| 命令 | 作用 |\n| --- | --- |\n| `npm run demo` | 3 页 **Miku** demo(无需 key) |\n| `npm run demo:editorial` | 6 页 **editorial-grid** recipe demo |\n| `npm run demo:darklaunch` | 5 页 **dark-launch** recipe demo |\n| `npm run demos` | 一次构建全部三套 |\n\n### QA 门禁\n\n| 命令 | 作用 |\n| --- | --- |\n| `npm test` | 导入/供应商/尺寸 **+** 预置色板对比度 QA |\n| `npm run qa:render -- deck.pptx` | **PPTX 渲染 + 启发式 QA** —— 溢出、遮挡、越界、图文比例、页码 badge。P0 即退出码 1 |\n| `npm run qa:render -- deck.pptx --render --out ./qa` | 上述 **+** 在装了 LibreOffice + poppler 时额外驱动 `soffice → pdf → jpg` |\n| `npm run qa:cjk -- --text \"标题\" --font-size 44 --box-width 9` | **免渲染 CJK 溢出估算**,生成前先用 |\n| `npm run qa:editable -- deck.pptx` | **可编辑性 / CJK 字体 / 宏 / 主题检查**(Python;无 python-pptx 时 zip 回退) |\n| `npm run color:qa -- --palette 0F2233,F1FBFA,39C5BB,FF77AA --role body` | 调色板 WCAG 对比 |\n| `npm run color:qa:presets` | 全部预置色板(CI 门禁,P0 即退出码 1) |\n\n---\n\n## 🛠️ 工作流\n\n**A. 改已有 PPT** —— 读 deck / `build_*.js`,明确改动范围(颜色、页数、配图、文案、二维码、版式),编辑 + 重新生成,然后跑渲染 QA 修到干净。\n\n**B. 从文稿生成** —— 提取源内容 → 拆成页级信息 → 定义主题 token + 配图需求 → 选可复用版式 → 生成 AI 配图、嵌入、跑渲染 QA。\n\n---\n\n## 🎨 AI 配图\n\n用 [`skills/themed-cn-pptx/lib/ai-image.js`](skills/themed-cn-pptx/lib/ai-image.js)。没有 key → 返回 `null`,构建回退到占位图。\n\n```js\nimport { generateSlideImage, addImageToSlide, addImageOverlay } from \"./lib/ai-image.js\";\n\nconst cover = await generateSlideImage({\n provider: \"stepfun-cn\", // 推荐;也支持 stepfun-global / minimax-cn / minimax-global\n prompt: \"青绿色科技封面背景,干净留白,留出标题区域\",\n usage: \"cover\", // StepFun -> 1360x768,MiniMax -> 16:9\n});\n\nif (cover) {\n addImageToSlide(slide, cover, { x: 0, y: 0, w: 10, h: 5.625 });\n addImageOverlay(slide, pres, { color: \"0B1B2B\", opacity: 45 }); // 任何压字的图都需 40-55% 遮罩\n}\n```\n\n### 供应商优先级\n\n1. `generateSlideImage()` 的 `provider` 参数\n2. `PPT_IMAGE_PROVIDER` / `AI_IMAGE_PROVIDER` 环境变量\n3. 仅当 `MINIMAX_API_KEY` 存在且无 `STEPFUN_API_KEY` 时选 MiniMax\n4. 默认:StepFun 国内版\n\n### 环境变量\n\n```bash\nPPT_IMAGE_PROVIDER=stepfun # stepfun | minimax (推荐 stepfun)\nPPT_IMAGE_REGION=cn # cn | global\nSTEPFUN_API_KEY=sk-xxx\nSTEPFUN_REGION=cn # cn -> api.stepfun.com | global -> api.stepfun.ai\nSTEPFUN_API_MODE=platform # platform | step_plan\nMINIMAX_API_KEY=sk-xxx\nMINIMAX_REGION=global # cn -> api.minimaxi.com | global -> api.minimax.io\n```\n\n助手在导入时自动读取 `.env`;shell/CI 变量优先级更高。`.env` 只放本地(已 gitignore),切勿提交 key。\n\n### 尺寸映射\n\n| 用途 | StepFun 尺寸 | MiniMax 比例 | PPTX 布局 |\n| --- | --- | --- | --- |\n| `cover` / `coverOverlay` | `1360x768` | `16:9` | `10 × 5.625 in` |\n| `hero` / `bannerWide` | `1360x768`(+裁切) | `16:9` / `21:9` | `10 × 3 in` / `10 × 2.45 in` |\n| `sideStrip` / `phoneMockup` | `768x1360` | `9:16` | `2.5 × 4.44 in` / `1.8 × 3.2 in` |\n| `card` | `1024x1024` | `1:1` | `2.5 × 2.5 in` |\n| `cardWide` / `showcase` | `1184x896` | `4:3` | `3.5 × 2.65 in` / `3.9 × 2.95 in` |\n| `cardTall` | `896x1184` | `3:4` | `2.3 × 3.04 in` |\n| `icon` | `512x512` | `1:1` | `1.5 × 1.5 in` |\n\n规则:用 `getImageUsageConfig(usage, provider)` 或 `SIZE_MAP`,不要手写混用 StepFun 尺寸和 MiniMax 比例。StepFun `step-image-edit-2` 支持精确的 PPT 友好像素尺寸,这也是推荐它的原因。\n\n### 国内 / 国际版端点\n\n| 供应商 | 版本 | 默认 Base URL |\n| --- | --- | --- |\n| StepFun | 国内 | `https://api.stepfun.com/v1` |\n| StepFun | 国际 | `https://api.stepfun.ai/v1` |\n| StepFun Step Plan | 国内 | `https://api.stepfun.com/step_plan/v1` |\n| StepFun Step Plan | 国际 | `https://api.stepfun.ai/step_plan/v1` |\n| MiniMax | 国内 | `https://api.minimaxi.com/v1` |\n| MiniMax | 国际 | `https://api.minimax.io/v1` |\n\n官方文档:[StepFun 国内](https://platform.stepfun.com/docs/zh/api-reference/images/image) · [StepFun 国际](https://platform.stepfun.ai/docs/en/api-reference/images/image) · [StepFun Step Plan](https://platform.stepfun.com/docs/zh/step-plan/integrations/image-api) · [MiniMax 国内](https://platform.minimaxi.com/docs/api-reference/image-generation-i2i)\n\n---\n\n## 🧪 QA 预期\n\n真实交付前先渲染检查:\n\n```bash\nsoffice --headless --convert-to pdf deck.pptx\npdftoppm -jpeg -r 100 deck.pdf slide\n```\n\n重点检查:中文溢出、全角符号挤压、图片上文字可读性、二维码对比度、页脚压内容、AI 配图比例是否匹配。`render-qa.mjs` 会自动跑确定性检查。\n\n### 色彩 QA 规则\n\n- 正文 / URL / 脚注:**≥ 4.5:1**\n- 大标题 / 图标 / 边框 / UI:**≥ 3:1**\n- 不用高饱和副色当正文\n- 不只靠红/绿表达状态\n- AI 图上放文字需 40–55% 遮罩\n\n---\n\n## 🧭 与 `guizang-ppt-skill` 的关系\n\n`guizang-ppt-skill` 是成熟的**单文件 HTML 横向翻页 deck** 技能 —— 浏览器优先、强审美模板。本仓库走的是**另一条路线,不是竞品**。\n\n| 维度 | `guizang-ppt-skill` | `ppt-skills`(本仓库) |\n| --- | --- | --- |\n| **输出物** | 单文件 HTML,浏览器 | 真实可编辑 `.pptx`,PowerPoint |\n| **适合** | 线下分享、demo day、个人风格演讲 | 需交付 .pptx、后续可编辑、中文排版稳定的 deck |\n| **审美系统** | 两套固定模板(杂志风、瑞士风) | 两套锁定 recipe + 可扩展主题系统 |\n| **QA 方式** | HTML 版式校验器(`data-layout`) | PPTX 渲染 + 启发式 QA、CJK 溢出、可编辑性、色彩对比 |\n| **配图** | Codex/GPT-Image 入 HTML | provider 层(StepFun/MiniMax)返回 PPTX layout 元数据 |\n\n**两条路线,互补。** 浏览器演讲选 HTML;交付物必须是 `.pptx` 选本仓库。\n\n---\n\n## 📦 平台支持\n\n| 平台 | 状态 | 说明 |\n| --- | --- | --- |\n| Claude Code / Codex / ZCode | ✅ 支持 | 原生 skill 工作流 |\n| Cursor / 本地 Agent | ✅ 可用 | 需文件读写 + shell |\n| CI(GitHub Actions) | ✅ 已测 | Node 20/22 矩阵,npm ci,smoke + 色彩 QA + demo 构建 + 渲染 QA |\n| 纯聊天机器人 | ⚠️ 不推荐 | 没有文件系统 + shell,稳定 PPTX + QA 很难 |\n\n---\n\n## 📁 仓库结构\n\n```text\nppt-skills/\n README.md README.zh-CN.md docs/ # 渲染好的 demo 图片(已提交)\n package.json design-principles.md\n .github/workflows/ci.yml\n examples/\n build_miku_demo.mjs build_editorial_demo.mjs build_darklaunch_demo.mjs\n color-qa.sample.json color-qa.presets.json cjk-overflow.sample.json render-qa.sample.json\n slides/output/ # 已提交的 .pptx demo —— 用 PowerPoint 打开编辑\n miku-demo.pptx editorial-demo.pptx darklaunch-demo.pptx\n scripts/\n smoke-test.mjs color-qa.mjs color-qa-presets.mjs\n render-qa.mjs cjk-overflow-check.mjs pptx-editable-check.py\n skills/themed-cn-pptx/\n skill.md\n references/ aesthetic-rules.md image-constraints.md layout-slots.md\n recipes/ recipe-editorial-grid.mjs recipe-dark-launch.mjs design-contract*.md\n lib/ ai-image.js stepfun-image.js cjk-text.js pptx-shapes.js zip-reader.js\n```\n\n---\n\n## 🤝 适合 / 不适合\n\n**✅ 适合** —— 需要交付 `.pptx` / 后续在 PowerPoint 编辑 / 中文排版稳定 / 二维码收尾页 / 可验证的 CI 门禁构建。\n\n**❌ 不适合** —— 只要浏览器演示(用 HTML deck 技能)/ 大型动态数据看板 / 永远不碰 PowerPoint 的 deck。\n\n## 🖋️ 版权与 IP 提醒\n\n角色/IP 主题优先使用色彩系统、抽象符号和用户授权素材。不要暗示官方背书;除非用户拥有权利或明确要求 legally-safe 的 inspired-by 方向,否则不要生成商标角色图。\n\n## 🤝 贡献\n\n有 PPT 技能 recipe?在下面目录提 PR:\n\n```text\nskills/<skill-name>/skill.md\nskills/<skill-name>/lib/ # 可选工具代码\nskills/<skill-name>/examples/ # 可选构建脚本\n```\n\n## 许可\n\n[MIT](LICENSE)\n"}}, "README.md": {"5986d74ae9292b4868f4bc6bf8a63abf289b1fb2": {"t": 1785674630.7429903, "n": 14138, "h": "e65329a030b7695e", "c": "# PPT Skills\n\n**English** | [简体中文](README.zh-CN.md)\n\n<p align=\"center\">\n <img src=\"docs/img/hero-demos.png\" alt=\"ppt-skills demo decks — miku, editorial-grid, dark-launch\" width=\"820\" />\n</p>\n\n<p align=\"center\">\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/github/license/CacinieP/ppt-skills?style=flat-square\" alt=\"License\" /></a>\n <a href=\"https://github.com/CacinieP/ppt-skills/actions/workflows/ci.yml\"><img src=\"https://img.shields.io/github/actions/workflow/status/CacinieP/ppt-skills/ci.yml?branch=main&label=CI&style=flat-square\" alt=\"CI\" /></a>\n <img src=\"https://img.shields.io/badge/skills-1%20released-39c5bb?style=flat-square\" alt=\"Skills\" />\n <img src=\"https://img.shields.io/badge/output-editable%20.pptx-0A7CFF?style=flat-square\" alt=\"PPTX\" />\n <img src=\"https://img.shields.io/badge/node-%E2%89%A5%2020-339933?style=flat-square\" alt=\"Node\" />\n</p>\n\nOpen-source skills for generating and **accepting** real, **editable, CJK-aware PPTX decks** built with PptxGenJS — verified by a deterministic QA gate, not just eyeballed.\n\nThe first released skill, [`themed-cn-pptx`](skills/themed-cn-pptx/), ships two **locked aesthetic recipes** (editorial-grid, dark-launch), a provider-aware AI image layer (StepFun / MiniMax), and three QA tools (render QA, CJK overflow, editable-text check).\n\n---\n\n## 🎬 Demo Gallery\n\nThree locked demo decks, all generated from this repo with **zero API keys** (solid-color / hairline fallbacks). Rendered here with LibreOffice at 150 DPI.\n\n| Deck | Slides | Recipe | Vibe |\n| --- | --- | --- | --- |\n| **Miku** | 3 | `miku` (skill showcase) | Teal + pink, dark/light alternation |\n| **Editorial Grid** | 6 | `recipe-editorial-grid.mjs` | Nord neutrals, hairline report look |\n| **Dark Launch** | 5 | `recipe-dark-launch.mjs` | Deep navy, oversized type, framed QR close |\n\n### Miku — skill showcase\n\n<p align=\"center\">\n <a href=\"docs/img/demos/miku/miku-slide-1.jpg\"><img src=\"docs/img/demos/miku/miku-slide-1.jpg\" width=\"280\" alt=\"miku cover\" /></a>\n \n <a href=\"docs/img/demos/miku/miku-slide-2.jpg\"><img src=\"docs/img/demos/miku/miku-slide-2.jpg\" width=\"280\" alt=\"miku content\" /></a>\n \n <a href=\"docs/img/demos/miku/miku-slide-3.jpg\"><img src=\"docs/img/demos/miku/miku-slide-3.jpg\" width=\"280\" alt=\"miku summary\" /></a>\n</p>\n\n### Editorial Grid — Nord report look\n\n<p align=\"center\">\n <a href=\"docs/img/demos/editorial/editorial-slide-1.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-1.jpg\" width=\"195\" alt=\"editorial s1\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-2.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-2.jpg\" width=\"195\" alt=\"editorial s2\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-3.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-3.jpg\" width=\"195\" alt=\"editorial s3\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-4.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-4.jpg\" width=\"195\" alt=\"editorial s4\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-5.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-5.jpg\" width=\"195\" alt=\"editorial s5\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-6.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-6.jpg\" width=\"195\" alt=\"editorial s6\" /></a>\n</p>\n\n### Dark Launch — keynote close\n\n<p align=\"center\">\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-1.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-1.jpg\" width=\"232\" alt=\"darklaunch s1\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-2.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-2.jpg\" width=\"232\" alt=\"darklaunch s2\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-3.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-3.jpg\" width=\"232\" alt=\"darklaunch s3\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-4.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-4.jpg\" width=\"232\" alt=\"darklaunch s4\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-5.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-5.jpg\" width=\"232\" alt=\"darklaunch s5\" /></a>\n</p>\n\n> The `.pptx` files themselves are committed at `examples/slides/output/` — open them in PowerPoint and edit directly.\n\n---\n\n## ✨ Highlights\n\n- **Editable PPTX** — real `.pptx`, not flattened slide images; verified by `pptx-editable-check.py`.\n- **CJK-first layout** — font fallback, full-width punctuation, conservative sizes; overflow predicted *before* render.\n- **Render QA gate** — `render-qa.mjs` catches overflow, overlap, off-canvas, bad image ratios, missing page badges.\n- **Locked recipes** — two locked aesthetic recipes (editorial-grid, dark-launch) so you stop re-deciding every detail.\n- **Provider-aware AI images** — StepFun (recommended) / MiniMax, CN + global regions, PPT-friendly size presets.\n- **WCAG color QA** — sRGB luminance contrast, not eyeballing; CI gate fails on P0.\n- **Graceful degradation** — no API key? builds continue with solid-color placeholders, never crash.\n\n---\n\n## 🚀 Quick Start\n\n```bash\ngit clone https://github.com/CacinieP/ppt-skills.git\ncd ppt-skills\nnpm ci # install locked deps\nnpm test # smoke + preset palette contrast QA\nnpm run demos # build all three demo PPTX (no API key needed)\n```\n\nThen hand a prompt to an Agent with shell access:\n\n```text\nMake this README into an editable Chinese PPTX, ~8 slides, editorial-grid recipe.\n```\n\n**Or install the skill directly:**\n\n```bash\nnpx skills add https://github.com/CacinieP/ppt-skills --skill themed-cn-pptx\n```\n\n---\n\n## 📋 Commands\n\n### Generation\n\n| Command | Purpose |\n| --- | --- |\n| `npm run demo` | 3-slide **Miku** demo (no API key) |\n| `npm run demo:editorial` | 6-slide **editorial-grid** recipe demo |\n| `npm run demo:darklaunch` | 5-slide **dark-launch** recipe demo |\n| `npm run demos` | Build all three |\n\n### QA gates\n\n| Command | Purpose |\n| --- | --- |\n| `npm test` | Smoke (imports/provider/size) **+** preset palette contrast QA |\n| `npm run qa:render -- deck.pptx` | **PPTX render + heuristic QA** — overflow, overlap, bounds, image aspect, page badge. P0 exits 1 |\n| `npm run qa:render -- deck.pptx --render --out ./qa` | Above **+** drive `soffice → pdf → jpg` when LibreOffice + poppler installed |\n| `npm run qa:cjk -- --text \"标题\" --font-size 44 --box-width 9` | **Render-free CJK overflow estimator**, use before generating |\n| `npm run qa:editable -- deck.pptx` | **Editable / CJK-font / macro / theme check** (Python; zip-fallback) |\n| `npm run color:qa -- --palette 0F2233,F1FBFA,39C5BB,FF77AA --role body` | WCAG contrast for a palette |\n| `npm run color:qa:presets` | All preset palettes (CI gate, exits 1 on P0) |\n\n---\n\n## 🛠️ Workflows\n\n**A. Modify an existing deck** — read the deck / `build_*.js`, scope the change (colors, pages, images, copy, QR, layout), edit + regenerate, then run render QA and fix until clean.\n\n**B. Generate from manuscript** — extract source → decompose into slide-level messages → define theme tokens + image needs → pick reusable layouts → generate AI images, embed, run render QA.\n\n---\n\n## 🎨 AI Image Generation\n\nUse [`skills/themed-cn-pptx/lib/ai-image.js`](skills/themed-cn-pptx/lib/ai-image.js). No key → returns `null`, build falls back to placeholders.\n\n```js\nimport { generateSlideImage, addImageToSlide, addImageOverlay } from \"./lib/ai-image.js\";\n\nconst cover = await generateSlideImage({\n provider: \"stepfun-cn\", // recommended; also: stepfun-global, minimax-cn, minimax-global\n prompt: \"teal tech cover background, clean whitespace, room for a title\",\n usage: \"cover\", // -> 1360x768 on StepFun, 16:9 on MiniMax\n});\n\nif (cover) {\n addImageToSlide(slide, cover, { x: 0, y: 0, w: 10, h: 5.625 });\n addImageOverlay(slide, pres, { color: \"0B1B2B\", opacity: 45 }); // 40-55% over any image with text\n}\n```\n\n### Provider priority\n\n1. `provider` arg to `generateSlideImage()`\n2. `PPT_IMAGE_PROVIDER` / `AI_IMAGE_PROVIDER` env\n3. MiniMax only if `MINIMAX_API_KEY` set and no `STEPFUN_API_KEY`\n4. Default: StepFun CN\n\n### Environment variables\n\n```bash\nPPT_IMAGE_PROVIDER=stepfun # stepfun | minimax (stepfun recommended)\nPPT_IMAGE_REGION=cn # cn | global\nSTEPFUN_API_KEY=sk-xxx\nSTEPFUN_REGION=cn # cn -> api.stepfun.com | global -> api.stepfun.ai\nSTEPFUN_API_MODE=platform # platform | step_plan\nMINIMAX_API_KEY=sk-xxx\nMINIMAX_REGION=global # cn -> api.minimaxi.com | global -> api.minimax.io\n```\n\nThe helper auto-loads `.env` on import; shell/CI vars take priority. Create `.env` locally — it's gitignored, never commit keys.\n\n### Size → layout mapping\n\n| Usage | StepFun size | MiniMax ratio | PPTX layout |\n| --- | --- | --- | --- |\n| `cover` / `coverOverlay` | `1360x768` | `16:9` | `10 × 5.625 in` |\n| `hero` / `bannerWide` | `1360x768` (+crop) | `16:9` / `21:9` | `10 × 3 in` / `10 × 2.45 in` |\n| `sideStrip` / `phoneMockup` | `768x1360` | `9:16` | `2.5 × 4.44 in` / `1.8 × 3.2 in` |\n| `card` | `1024x1024` | `1:1` | `2.5 × 2.5 in` |\n| `cardWide` / `showcase` | `1184x896` | `4:3` | `3.5 × 2.65 in` / `3.9 × 2.95 in` |\n| `cardTall` | `896x1184` | `3:4` | `2.3 × 3.04 in` |\n| `icon` | `512x512` | `1:1` | `1.5 × 1.5 in` |\n\nRules: use `getImageUsageConfig(usage, provider)` or `SIZE_MAP`; never hand-mix StepFun concrete sizes with MiniMax ratios. StepFun `step-image-edit-2` exposes exact PPT-friendly pixel sizes — that's why it's recommended.\n\n### CN / Global endpoints\n\n| Provider | Region | Default Base URL |\n| --- | --- | --- |\n| StepFun | CN | `https://api.stepfun.com/v1` |\n| StepFun | Global | `https://api.stepfun.ai/v1` |\n| StepFun Step Plan | CN | `https://api.stepfun.com/step_plan/v1` |\n| StepFun Step Plan | Global | `https://api.stepfun.ai/step_plan/v1` |\n| MiniMax | CN | `https://api.minimaxi.com/v1` |\n| MiniMax | Global | `https://api.minimax.io/v1` |\n\nOfficial docs: [StepFun CN](https://platform.stepfun.com/docs/zh/api-reference/images/image) · [StepFun Global](https://platform.stepfun.ai/docs/en/api-reference/images/image) · [StepFun Step Plan](https://platform.stepfun.com/docs/zh/step-plan/integrations/image-api) · [MiniMax CN](https://platform.minimaxi.com/docs/api-reference/image-generation-i2i)\n\n---\n\n## 🧪 QA Expectations\n\nBefore delivering a real deck, render and inspect:\n\n```bash\nsoffice --headless --convert-to pdf deck.pptx\npdftoppm -jpeg -r 100 deck.pdf slide\n```\n\nWatch for: CJK overflow, cropped full-width punctuation, unreadable text on images, QR contrast, footer collisions, AI image aspect mismatches. `render-qa.mjs` automates the deterministic checks.\n\n### Color QA rules\n\n- Body text / URLs / footnotes: **≥ 4.5:1**\n- Large titles / icons / borders / UI: **≥ 3:1**\n- Never use a saturated accent as body text\n- Never rely on red/green alone for status\n- Text over AI images needs a 40–55% overlay\n\n---\n\n## 🧭 Where this sits vs. `guizang-ppt-skill`\n\n`guizang-ppt-skill` is a mature **single-file HTML horizontal-slide deck** skill — browser-first, strong aesthetic templates. This repo is a **different route, not a competitor**.\n\n| Dimension | `guizang-ppt-skill` | `ppt-skills` (this repo) |\n| --- | --- | --- |\n| **Output** | single-file HTML, browser | real editable `.pptx`, PowerPoint |\n| **Best for** | offline talks, demo days, personal keynotes | decks delivered as `.pptx`, edited later, stable Chinese type |\n| **Aesthetic system** | two fixed templates (magazine, Swiss) | two locked recipes + extensible theme system |\n| **QA approach** | HTML layout validator (`data-layout`) | PPTX render + heuristic QA, CJK overflow, editable-text, color contrast |\n| **Image** | Codex/GPT-Image into HTML | provider layer (StepFun/MiniMax) returning PPTX layout metadata |\n\n**Two routes, complementary.** Browser talks → HTML; deliverable `.pptx` → this repo.\n\n---\n\n## 📦 Platform Support\n\n| Platform | Status | Notes |\n| --- | --- | --- |\n| Claude Code / Codex / ZCode | ✅ supported | native skill workflow |\n| Cursor / local Agents | ✅ usable | needs file read/write + shell |\n| CI (GitHub Actions) | ✅ tested | Node 20/22 matrix, npm ci, smoke + color QA + demo builds + render QA |\n| Plain chatbot | ⚠️ not recommended | without a filesystem + shell, stable PPTX + QA is hard |\n\n---\n\n## 📁 Repository Layout\n\n```text\nppt-skills/\n README.md README.zh-CN.md docs/ # rendered demo images (committed)\n package.json design-principles.md\n .github/workflows/ci.yml\n examples/\n build_miku_demo.mjs build_editorial_demo.mjs build_darklaunch_demo.mjs\n color-qa.sample.json color-qa.presets.json cjk-overflow.sample.json render-qa.sample.json\n slides/output/ # the committed .pptx demos — open & edit in PowerPoint\n miku-demo.pptx editorial-demo.pptx darklaunch-demo.pptx\n scripts/\n smoke-test.mjs color-qa.mjs color-qa-presets.mjs\n render-qa.mjs cjk-overflow-check.mjs pptx-editable-check.py\n skills/themed-cn-pptx/\n skill.md\n references/ aesthetic-rules.md image-constraints.md layout-slots.md\n recipes/ recipe-editorial-grid.mjs recipe-dark-launch.mjs design-contract*.md\n lib/ ai-image.js stepfun-image.js cjk-text.js pptx-shapes.js zip-reader.js\n```\n\n---\n\n## 🤝 Suitable / not suitable\n\n**✅ Suitable** — needs a `.pptx` deliverable / later editing in PowerPoint / stable Chinese typography / QR closing slide / verifiable CI-gated build.\n\n**❌ Not suitable** — only need a browser presentation (use an HTML deck skill) / large animated data dashboards / decks that must never touch PowerPoint.\n\n## 🖋️ IP & Character Theme Note\n\nFor character/IP-themed decks, prefer color systems, abstract visual motifs, and user-provided licensed assets. Do not imply official endorsement; do not generate trademarked character art unless the user has rights or explicitly asks for a legally-safe, inspired-by direction.\n\n## 🤝 Contribute\n\nGot a PPT skill recipe? Submit a PR under:\n\n```text\nskills/<skill-name>/skill.md\nskills/<skill-name>/lib/ # optional utility code\nskills/<skill-name>/examples/ # optional build scripts\n```\n\n## License\n\n[MIT](LICENSE)\n"}, "c847ac81b1b81c5e5f4d0aff959451d3bdc98afa": {"t": 1785846910.677663, "n": 14138, "h": "e65329a030b7695e", "c": "# PPT Skills\n\n**English** | [简体中文](README.zh-CN.md)\n\n<p align=\"center\">\n <img src=\"docs/img/hero-demos.png\" alt=\"ppt-skills demo decks — miku, editorial-grid, dark-launch\" width=\"820\" />\n</p>\n\n<p align=\"center\">\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/github/license/CacinieP/ppt-skills?style=flat-square\" alt=\"License\" /></a>\n <a href=\"https://github.com/CacinieP/ppt-skills/actions/workflows/ci.yml\"><img src=\"https://img.shields.io/github/actions/workflow/status/CacinieP/ppt-skills/ci.yml?branch=main&label=CI&style=flat-square\" alt=\"CI\" /></a>\n <img src=\"https://img.shields.io/badge/skills-1%20released-39c5bb?style=flat-square\" alt=\"Skills\" />\n <img src=\"https://img.shields.io/badge/output-editable%20.pptx-0A7CFF?style=flat-square\" alt=\"PPTX\" />\n <img src=\"https://img.shields.io/badge/node-%E2%89%A5%2020-339933?style=flat-square\" alt=\"Node\" />\n</p>\n\nOpen-source skills for generating and **accepting** real, **editable, CJK-aware PPTX decks** built with PptxGenJS — verified by a deterministic QA gate, not just eyeballed.\n\nThe first released skill, [`themed-cn-pptx`](skills/themed-cn-pptx/), ships two **locked aesthetic recipes** (editorial-grid, dark-launch), a provider-aware AI image layer (StepFun / MiniMax), and three QA tools (render QA, CJK overflow, editable-text check).\n\n---\n\n## 🎬 Demo Gallery\n\nThree locked demo decks, all generated from this repo with **zero API keys** (solid-color / hairline fallbacks). Rendered here with LibreOffice at 150 DPI.\n\n| Deck | Slides | Recipe | Vibe |\n| --- | --- | --- | --- |\n| **Miku** | 3 | `miku` (skill showcase) | Teal + pink, dark/light alternation |\n| **Editorial Grid** | 6 | `recipe-editorial-grid.mjs` | Nord neutrals, hairline report look |\n| **Dark Launch** | 5 | `recipe-dark-launch.mjs` | Deep navy, oversized type, framed QR close |\n\n### Miku — skill showcase\n\n<p align=\"center\">\n <a href=\"docs/img/demos/miku/miku-slide-1.jpg\"><img src=\"docs/img/demos/miku/miku-slide-1.jpg\" width=\"280\" alt=\"miku cover\" /></a>\n \n <a href=\"docs/img/demos/miku/miku-slide-2.jpg\"><img src=\"docs/img/demos/miku/miku-slide-2.jpg\" width=\"280\" alt=\"miku content\" /></a>\n \n <a href=\"docs/img/demos/miku/miku-slide-3.jpg\"><img src=\"docs/img/demos/miku/miku-slide-3.jpg\" width=\"280\" alt=\"miku summary\" /></a>\n</p>\n\n### Editorial Grid — Nord report look\n\n<p align=\"center\">\n <a href=\"docs/img/demos/editorial/editorial-slide-1.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-1.jpg\" width=\"195\" alt=\"editorial s1\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-2.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-2.jpg\" width=\"195\" alt=\"editorial s2\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-3.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-3.jpg\" width=\"195\" alt=\"editorial s3\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-4.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-4.jpg\" width=\"195\" alt=\"editorial s4\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-5.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-5.jpg\" width=\"195\" alt=\"editorial s5\" /></a>\n <a href=\"docs/img/demos/editorial/editorial-slide-6.jpg\"><img src=\"docs/img/demos/editorial/editorial-slide-6.jpg\" width=\"195\" alt=\"editorial s6\" /></a>\n</p>\n\n### Dark Launch — keynote close\n\n<p align=\"center\">\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-1.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-1.jpg\" width=\"232\" alt=\"darklaunch s1\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-2.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-2.jpg\" width=\"232\" alt=\"darklaunch s2\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-3.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-3.jpg\" width=\"232\" alt=\"darklaunch s3\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-4.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-4.jpg\" width=\"232\" alt=\"darklaunch s4\" /></a>\n <a href=\"docs/img/demos/darklaunch/darklaunch-slide-5.jpg\"><img src=\"docs/img/demos/darklaunch/darklaunch-slide-5.jpg\" width=\"232\" alt=\"darklaunch s5\" /></a>\n</p>\n\n> The `.pptx` files themselves are committed at `examples/slides/output/` — open them in PowerPoint and edit directly.\n\n---\n\n## ✨ Highlights\n\n- **Editable PPTX** — real `.pptx`, not flattened slide images; verified by `pptx-editable-check.py`.\n- **CJK-first layout** — font fallback, full-width punctuation, conservative sizes; overflow predicted *before* render.\n- **Render QA gate** — `render-qa.mjs` catches overflow, overlap, off-canvas, bad image ratios, missing page badges.\n- **Locked recipes** — two locked aesthetic recipes (editorial-grid, dark-launch) so you stop re-deciding every detail.\n- **Provider-aware AI images** — StepFun (recommended) / MiniMax, CN + global regions, PPT-friendly size presets.\n- **WCAG color QA** — sRGB luminance contrast, not eyeballing; CI gate fails on P0.\n- **Graceful degradation** — no API key? builds continue with solid-color placeholders, never crash.\n\n---\n\n## 🚀 Quick Start\n\n```bash\ngit clone https://github.com/CacinieP/ppt-skills.git\ncd ppt-skills\nnpm ci # install locked deps\nnpm test # smoke + preset palette contrast QA\nnpm run demos # build all three demo PPTX (no API key needed)\n```\n\nThen hand a prompt to an Agent with shell access:\n\n```text\nMake this README into an editable Chinese PPTX, ~8 slides, editorial-grid recipe.\n```\n\n**Or install the skill directly:**\n\n```bash\nnpx skills add https://github.com/CacinieP/ppt-skills --skill themed-cn-pptx\n```\n\n---\n\n## 📋 Commands\n\n### Generation\n\n| Command | Purpose |\n| --- | --- |\n| `npm run demo` | 3-slide **Miku** demo (no API key) |\n| `npm run demo:editorial` | 6-slide **editorial-grid** recipe demo |\n| `npm run demo:darklaunch` | 5-slide **dark-launch** recipe demo |\n| `npm run demos` | Build all three |\n\n### QA gates\n\n| Command | Purpose |\n| --- | --- |\n| `npm test` | Smoke (imports/provider/size) **+** preset palette contrast QA |\n| `npm run qa:render -- deck.pptx` | **PPTX render + heuristic QA** — overflow, overlap, bounds, image aspect, page badge. P0 exits 1 |\n| `npm run qa:render -- deck.pptx --render --out ./qa` | Above **+** drive `soffice → pdf → jpg` when LibreOffice + poppler installed |\n| `npm run qa:cjk -- --text \"标题\" --font-size 44 --box-width 9` | **Render-free CJK overflow estimator**, use before generating |\n| `npm run qa:editable -- deck.pptx` | **Editable / CJK-font / macro / theme check** (Python; zip-fallback) |\n| `npm run color:qa -- --palette 0F2233,F1FBFA,39C5BB,FF77AA --role body` | WCAG contrast for a palette |\n| `npm run color:qa:presets` | All preset palettes (CI gate, exits 1 on P0) |\n\n---\n\n## 🛠️ Workflows\n\n**A. Modify an existing deck** — read the deck / `build_*.js`, scope the change (colors, pages, images, copy, QR, layout), edit + regenerate, then run render QA and fix until clean.\n\n**B. Generate from manuscript** — extract source → decompose into slide-level messages → define theme tokens + image needs → pick reusable layouts → generate AI images, embed, run render QA.\n\n---\n\n## 🎨 AI Image Generation\n\nUse [`skills/themed-cn-pptx/lib/ai-image.js`](skills/themed-cn-pptx/lib/ai-image.js). No key → returns `null`, build falls back to placeholders.\n\n```js\nimport { generateSlideImage, addImageToSlide, addImageOverlay } from \"./lib/ai-image.js\";\n\nconst cover = await generateSlideImage({\n provider: \"stepfun-cn\", // recommended; also: stepfun-global, minimax-cn, minimax-global\n prompt: \"teal tech cover background, clean whitespace, room for a title\",\n usage: \"cover\", // -> 1360x768 on StepFun, 16:9 on MiniMax\n});\n\nif (cover) {\n addImageToSlide(slide, cover, { x: 0, y: 0, w: 10, h: 5.625 });\n addImageOverlay(slide, pres, { color: \"0B1B2B\", opacity: 45 }); // 40-55% over any image with text\n}\n```\n\n### Provider priority\n\n1. `provider` arg to `generateSlideImage()`\n2. `PPT_IMAGE_PROVIDER` / `AI_IMAGE_PROVIDER` env\n3. MiniMax only if `MINIMAX_API_KEY` set and no `STEPFUN_API_KEY`\n4. Default: StepFun CN\n\n### Environment variables\n\n```bash\nPPT_IMAGE_PROVIDER=stepfun # stepfun | minimax (stepfun recommended)\nPPT_IMAGE_REGION=cn # cn | global\nSTEPFUN_API_KEY=sk-xxx\nSTEPFUN_REGION=cn # cn -> api.stepfun.com | global -> api.stepfun.ai\nSTEPFUN_API_MODE=platform # platform | step_plan\nMINIMAX_API_KEY=sk-xxx\nMINIMAX_REGION=global # cn -> api.minimaxi.com | global -> api.minimax.io\n```\n\nThe helper auto-loads `.env` on import; shell/CI vars take priority. Create `.env` locally — it's gitignored, never commit keys.\n\n### Size → layout mapping\n\n| Usage | StepFun size | MiniMax ratio | PPTX layout |\n| --- | --- | --- | --- |\n| `cover` / `coverOverlay` | `1360x768` | `16:9` | `10 × 5.625 in` |\n| `hero` / `bannerWide` | `1360x768` (+crop) | `16:9` / `21:9` | `10 × 3 in` / `10 × 2.45 in` |\n| `sideStrip` / `phoneMockup` | `768x1360` | `9:16` | `2.5 × 4.44 in` / `1.8 × 3.2 in` |\n| `card` | `1024x1024` | `1:1` | `2.5 × 2.5 in` |\n| `cardWide` / `showcase` | `1184x896` | `4:3` | `3.5 × 2.65 in` / `3.9 × 2.95 in` |\n| `cardTall` | `896x1184` | `3:4` | `2.3 × 3.04 in` |\n| `icon` | `512x512` | `1:1` | `1.5 × 1.5 in` |\n\nRules: use `getImageUsageConfig(usage, provider)` or `SIZE_MAP`; never hand-mix StepFun concrete sizes with MiniMax ratios. StepFun `step-image-edit-2` exposes exact PPT-friendly pixel sizes — that's why it's recommended.\n\n### CN / Global endpoints\n\n| Provider | Region | Default Base URL |\n| --- | --- | --- |\n| StepFun | CN | `https://api.stepfun.com/v1` |\n| StepFun | Global | `https://api.stepfun.ai/v1` |\n| StepFun Step Plan | CN | `https://api.stepfun.com/step_plan/v1` |\n| StepFun Step Plan | Global | `https://api.stepfun.ai/step_plan/v1` |\n| MiniMax | CN | `https://api.minimaxi.com/v1` |\n| MiniMax | Global | `https://api.minimax.io/v1` |\n\nOfficial docs: [StepFun CN](https://platform.stepfun.com/docs/zh/api-reference/images/image) · [StepFun Global](https://platform.stepfun.ai/docs/en/api-reference/images/image) · [StepFun Step Plan](https://platform.stepfun.com/docs/zh/step-plan/integrations/image-api) · [MiniMax CN](https://platform.minimaxi.com/docs/api-reference/image-generation-i2i)\n\n---\n\n## 🧪 QA Expectations\n\nBefore delivering a real deck, render and inspect:\n\n```bash\nsoffice --headless --convert-to pdf deck.pptx\npdftoppm -jpeg -r 100 deck.pdf slide\n```\n\nWatch for: CJK overflow, cropped full-width punctuation, unreadable text on images, QR contrast, footer collisions, AI image aspect mismatches. `render-qa.mjs` automates the deterministic checks.\n\n### Color QA rules\n\n- Body text / URLs / footnotes: **≥ 4.5:1**\n- Large titles / icons / borders / UI: **≥ 3:1**\n- Never use a saturated accent as body text\n- Never rely on red/green alone for status\n- Text over AI images needs a 40–55% overlay\n\n---\n\n## 🧭 Where this sits vs. `guizang-ppt-skill`\n\n`guizang-ppt-skill` is a mature **single-file HTML horizontal-slide deck** skill — browser-first, strong aesthetic templates. This repo is a **different route, not a competitor**.\n\n| Dimension | `guizang-ppt-skill` | `ppt-skills` (this repo) |\n| --- | --- | --- |\n| **Output** | single-file HTML, browser | real editable `.pptx`, PowerPoint |\n| **Best for** | offline talks, demo days, personal keynotes | decks delivered as `.pptx`, edited later, stable Chinese type |\n| **Aesthetic system** | two fixed templates (magazine, Swiss) | two locked recipes + extensible theme system |\n| **QA approach** | HTML layout validator (`data-layout`) | PPTX render + heuristic QA, CJK overflow, editable-text, color contrast |\n| **Image** | Codex/GPT-Image into HTML | provider layer (StepFun/MiniMax) returning PPTX layout metadata |\n\n**Two routes, complementary.** Browser talks → HTML; deliverable `.pptx` → this repo.\n\n---\n\n## 📦 Platform Support\n\n| Platform | Status | Notes |\n| --- | --- | --- |\n| Claude Code / Codex / ZCode | ✅ supported | native skill workflow |\n| Cursor / local Agents | ✅ usable | needs file read/write + shell |\n| CI (GitHub Actions) | ✅ tested | Node 20/22 matrix, npm ci, smoke + color QA + demo builds + render QA |\n| Plain chatbot | ⚠️ not recommended | without a filesystem + shell, stable PPTX + QA is hard |\n\n---\n\n## 📁 Repository Layout\n\n```text\nppt-skills/\n README.md README.zh-CN.md docs/ # rendered demo images (committed)\n package.json design-principles.md\n .github/workflows/ci.yml\n examples/\n build_miku_demo.mjs build_editorial_demo.mjs build_darklaunch_demo.mjs\n color-qa.sample.json color-qa.presets.json cjk-overflow.sample.json render-qa.sample.json\n slides/output/ # the committed .pptx demos — open & edit in PowerPoint\n miku-demo.pptx editorial-demo.pptx darklaunch-demo.pptx\n scripts/\n smoke-test.mjs color-qa.mjs color-qa-presets.mjs\n render-qa.mjs cjk-overflow-check.mjs pptx-editable-check.py\n skills/themed-cn-pptx/\n skill.md\n references/ aesthetic-rules.md image-constraints.md layout-slots.md\n recipes/ recipe-editorial-grid.mjs recipe-dark-launch.mjs design-contract*.md\n lib/ ai-image.js stepfun-image.js cjk-text.js pptx-shapes.js zip-reader.js\n```\n\n---\n\n## 🤝 Suitable / not suitable\n\n**✅ Suitable** — needs a `.pptx` deliverable / later editing in PowerPoint / stable Chinese typography / QR closing slide / verifiable CI-gated build.\n\n**❌ Not suitable** — only need a browser presentation (use an HTML deck skill) / large animated data dashboards / decks that must never touch PowerPoint.\n\n## 🖋️ IP & Character Theme Note\n\nFor character/IP-themed decks, prefer color systems, abstract visual motifs, and user-provided licensed assets. Do not imply official endorsement; do not generate trademarked character art unless the user has rights or explicitly asks for a legally-safe, inspired-by direction.\n\n## 🤝 Contribute\n\nGot a PPT skill recipe? Submit a PR under:\n\n```text\nskills/<skill-name>/skill.md\nskills/<skill-name>/lib/ # optional utility code\nskills/<skill-name>/examples/ # optional build scripts\n```\n\n## License\n\n[MIT](LICENSE)\n"}}}} |