From 93d6335ccf1106121dfd05b1e2dba4ffb3dd6330 Mon Sep 17 00:00:00 2001 From: OmniaZ1 Date: Sun, 21 Jun 2026 18:32:37 +0800 Subject: [PATCH 01/14] feat: add Hermes Agent support + cross-platform Chrome detection - SKILL.md: add Hermes install command alongside Claude Code/Codex - SKILL.md: add version, author, license, platforms to frontmatter - render.sh: auto-detect Chrome on macOS, Linux, and Windows (Git Bash/MSYS) instead of hardcoding macOS path - README.md / README.zh-CN.md: add Hermes Agent to install instructions - render.sh: support CHROME env var override for custom paths --- README.md | 4 ++++ README.zh-CN.md | 6 +++++- SKILL.md | 13 ++++++++++--- scripts/render.sh | 34 ++++++++++++++++++++++++++++++---- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index fe3b522..b8c631a 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,10 @@ word speaker scripts on every slide. ## Install (one command) ```bash +# Hermes Agent +hermes skills install https://github.com/lewislulu/html-ppt-skill + +# Claude Code / Codex npx skills add https://github.com/lewislulu/html-ppt-skill ``` diff --git a/README.zh-CN.md b/README.zh-CN.md index a41c787..d3ed52b 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -43,10 +43,14 @@ idx:N})` 通知 iframe,iframe 只是切换 `.is-active` class —— **不重 ## 一行命令安装 ```bash +# Hermes Agent +hermes skills install https://github.com/lewislulu/html-ppt-skill + +# Claude Code / Codex npx skills add https://github.com/lewislulu/html-ppt-skill ``` -装好后,任何支持 AgentSkill 的 agent(Claude Code / Codex / Cursor / OpenClaw 等) +装好后,任何支持 AgentSkill 的 agent(Hermes Agent / Claude Code / Codex / Cursor 等) 都能用这套能力做 PPT。对 agent 说: > "做一份 8 页的技术分享 slides,用 cyberpunk 主题" diff --git a/SKILL.md b/SKILL.md index 0250b9a..f34511d 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,5 +1,9 @@ --- name: html-ppt +version: 1.0.0 +author: lewis +license: MIT +platforms: [linux, macos, windows] description: HTML PPT Studio — author professional static HTML presentations in many styles, layouts, and animations, all driven by templates. Use when the user asks for a presentation, PPT, slides, keynote, deck, slideshow, "幻灯片", "演讲稿", "做一份 PPT", "做一份 slides", a reveal-style HTML deck, a 小红书 图文, or any kind of multi-slide pitch/report/sharing document that should look tasteful and be usable with keyboard navigation. Triggers include keywords like "presentation", "ppt", "slides", "deck", "keynote", "reveal", "slideshow", "幻灯片", "演讲稿", "分享稿", "小红书图文", "talk slides", "pitch deck", "tech sharing", "technical presentation". --- @@ -12,6 +16,10 @@ All pages share a token-based design system in `assets/base.css`. ## Install ```bash +# Hermes Agent +hermes skills install https://github.com/lewislulu/html-ppt-skill + +# Claude Code / Codex npx skills add https://github.com/lewislulu/html-ppt-skill ``` @@ -193,9 +201,8 @@ html-ppt/ ## Rendering to PNG -`scripts/render.sh` wraps headless Chrome at -`/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`. For multi-slide -capture, runtime.js exposes `#/N` deep-links, and render.sh iterates 1..N. +`scripts/render.sh` wraps headless Chrome for PNG export. It auto-detects +Chrome on macOS, Linux, and Windows (Git Bash / MSYS). ```bash ./scripts/render.sh templates/single-page/kpi-grid.html # single page diff --git a/scripts/render.sh b/scripts/render.sh index 1711c16..1f83378 100755 --- a/scripts/render.sh +++ b/scripts/render.sh @@ -7,13 +7,39 @@ # render.sh all # autodetect .slide count # render.sh # custom output dir # -# Requires: Google Chrome at /Applications/Google Chrome.app (macOS). +# Auto-detects Chrome on macOS, Linux, and Windows (Git Bash / MSYS). set -euo pipefail -CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" -if [[ ! -x "$CHROME" ]]; then - echo "error: Chrome not found at $CHROME" >&2 +# --- Cross-platform Chrome detection --- +CHROME="" +if [[ "$(uname -s)" == MINGW* ]] || [[ "$(uname -s)" == MSYS* ]] || [[ "$(uname -s)" == CYGWIN* ]]; then + # Windows (Git Bash / MSYS / Cygwin) + for candidate in \ + "${LOCALAPPDATA:-}/Google/Chrome/Application/chrome.exe" \ + "${PROGRAMFILES:-}/Google/Chrome/Application/chrome.exe" \ + "/c/Program Files/Google/Chrome/Application/chrome.exe" \ + "/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" + do + if [[ -f "$candidate" ]]; then CHROME="$candidate"; break; fi + done +elif [[ "$(uname -s)" == "Darwin" ]]; then + # macOS + if [[ -x "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ]]; then + CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" + fi +else + # Linux + for candidate in google-chrome google-chrome-stable chromium chromium-browser; do + if command -v "$candidate" &>/dev/null; then + CHROME="$candidate" + break + fi + done +fi + +if [[ -z "$CHROME" ]]; then + echo "error: Google Chrome not found. Install Chrome or set CHROME env var." >&2 exit 1 fi From 03a1f2ebb001a72f78a0ce936c0d3bd671141a51 Mon Sep 17 00:00:00 2001 From: OmniaZ1 Date: Sun, 21 Jun 2026 18:55:18 +0800 Subject: [PATCH 02/14] fix: cross-platform 'open' commands + remove .clawscan-allow - README.md / README.zh-CN.md / SKILL.md / authoring-guide.md: add 'macOS: open, Windows: start, Linux: xdg-open' comments next to all 'open' commands in Quick Start sections - Remove .clawscan-allow (Claude Code specific, not needed) --- .clawscan-allow | 12 ------------ README.md | 3 ++- README.zh-CN.md | 3 ++- SKILL.md | 1 + references/authoring-guide.md | 1 + 5 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 .clawscan-allow diff --git a/.clawscan-allow b/.clawscan-allow deleted file mode 100644 index 4c90d10..0000000 --- a/.clawscan-allow +++ /dev/null @@ -1,12 +0,0 @@ -# Security scan allowlist for html-ppt-skill -# These patterns are false positives from template content, not actual threats. - -# Path traversal: templates reference shared assets via relative paths -# e.g. templates/full-decks/weekly-report/ → ../../../assets/ -# This is the correct relative path to the skill root assets directory. -traversal:templates/full-decks/*/index.html - -# Destructive commands: testing-safety-alert template displays forbidden -# commands as text examples in a security policy demo slide. -# They are HTML content, not executable code. -destructive:templates/full-decks/testing-safety-alert/index.html diff --git a/README.md b/README.md index b8c631a..6815ac4 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,8 @@ module auto-initialised on slide enter via `fx-runtime.js`. # Scaffold a new deck from the base template ./scripts/new-deck.sh my-talk -# Browse everything +# Browse everything (open in browser) +# macOS: open, Windows: start, Linux: xdg-open open templates/theme-showcase.html # all 36 themes (iframe-isolated) open templates/layout-showcase.html # all 31 layouts open templates/animation-showcase.html # all 47 animations diff --git a/README.zh-CN.md b/README.zh-CN.md index d3ed52b..e5b8b61 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -161,7 +161,8 @@ chart-pie · chart-radar · arch-diagram · process-steps · cta · thanks # 从 base 模板新建一个 deck ./scripts/new-deck.sh my-talk -# 浏览所有内容 +# 浏览所有内容(在浏览器中打开) +# macOS: open, Windows: start, Linux: xdg-open open templates/theme-showcase.html # 全部 36 主题(iframe 隔离) open templates/layout-showcase.html # 全部 31 布局 open templates/animation-showcase.html # 全部 47 动效 diff --git a/SKILL.md b/SKILL.md index f34511d..7f7654c 100644 --- a/SKILL.md +++ b/SKILL.md @@ -105,6 +105,7 @@ Only after those are clear, scaffold the deck and start writing. 1. **Scaffold a new deck.** From the repo root: ```bash ./scripts/new-deck.sh my-talk + # Open in browser: macOS: open, Windows: start, Linux: xdg-open open examples/my-talk/index.html ``` 2. **Pick a theme.** Open the deck and press `T` to cycle. Or hard-code it: diff --git a/references/authoring-guide.md b/references/authoring-guide.md index 4285d65..05c6813 100644 --- a/references/authoring-guide.md +++ b/references/authoring-guide.md @@ -89,6 +89,7 @@ Pick **one** accent animation per slide. Everything else should be calm. ## 8. Review in-browser ```bash +# Open in browser: macOS: open, Windows: start, Linux: xdg-open open examples/my-talk/index.html ``` From 184b1e6482bfd319821572c0ed1e3e751019b7be Mon Sep 17 00:00:00 2001 From: OmniaZ1 Date: Sun, 21 Jun 2026 19:26:48 +0800 Subject: [PATCH 03/14] fix: render.sh MSYS path conversion for Windows Chrome MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chrome on Windows cannot open file:// URLs with MSYS paths (/c/Users/...). Convert to Windows paths using cygpath -m (file:///C:/Users/...) and cygpath -w for --screenshot target. Tested: demo-deck 6 slides, hermes-test 6 slides, kpi-grid, cover — all render correctly on Windows 11 Git Bash. --- scripts/render.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/render.sh b/scripts/render.sh index 1f83378..ab238de 100755 --- a/scripts/render.sh +++ b/scripts/render.sh @@ -73,6 +73,11 @@ fi render_one() { local url="$1" target="$2" + local win_target="$target" + # On Windows (MSYS/Git Bash), convert paths for native Chrome + if command -v cygpath &>/dev/null; then + target="$(cygpath -w "$target")" + fi "$CHROME" \ --headless=new \ --disable-gpu \ @@ -82,15 +87,22 @@ render_one() { --window-size=1920,1080 \ --screenshot="$target" \ "$url" >/dev/null 2>&1 - echo " ✔ $target" + echo " ✔ $win_target" } +# --- Build file:// URL (convert MSYS path for Windows Chrome) --- +if command -v cygpath &>/dev/null; then + FILE_URL="file:///$(cygpath -m "$ABS")" +else + FILE_URL="file://$ABS" +fi + if [[ "$COUNT" == "1" ]]; then OUT_FILE="${OUT:-$(dirname "$FILE")/${STEM}.png}" - render_one "file://$ABS" "$OUT_FILE" + render_one "$FILE_URL" "$OUT_FILE" else for i in $(seq 1 "$COUNT"); do - render_one "file://$ABS#/$i" "$OUT/${STEM}_$(printf '%02d' "$i").png" + render_one "${FILE_URL}#/$i" "$OUT/${STEM}_$(printf '%02d' "$i").png" done fi From 80770a3f7e21ea6ad0e72b6034dc332eb55cf325 Mon Sep 17 00:00:00 2001 From: OmniaZ1 Date: Sun, 21 Jun 2026 20:17:38 +0800 Subject: [PATCH 04/14] =?UTF-8?q?feat:=20Darwin=20skill=20evolution=20?= =?UTF-8?q?=E2=80=94=20failure=20modes,=20anti-patterns,=20checkpoints,=20?= =?UTF-8?q?workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Darwin 9-dimension evaluation improvements (baseline 69.4 → target 82+): - dim3 (Failure Modes): Added 10-row fallback table covering render.sh, theme switching, fonts CDN, canvas FX, path rewrite, Chart.js, etc. - dim9 (Anti-Patterns): Added 12-item DON'T/DO table covering common authoring mistakes (blank files, hex colors, missing runtime.js, etc.) - dim4 (Checkpoints): Added 2 explicit 🔴 CHECKPOINT markers before authoring begins and after user requirements are gathered - dim2 (Workflow): Added 8-step Authoring Workflow table with explicit Input → Action → Output for each step - Fixed: '14 full-deck' → '15 full-deck' (presenter-mode-reveal was missing from the count) --- SKILL.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/SKILL.md b/SKILL.md index 7f7654c..26feb2c 100644 --- a/SKILL.md +++ b/SKILL.md @@ -70,8 +70,8 @@ Keyboard in audience window: `S` open presenter · `T` cycle theme · `← →` ## Before you author anything — ALWAYS ask or recommend -**Do not start writing slides until you understand three things.** Either ask -the user directly, or — if they already handed you rich content — propose a +🔴 **CHECKPOINT: Do not start writing slides until you understand three things.** +Either ask the user directly, or — if they already handed you rich content — propose a tasteful default and confirm. 1. **Content & audience.** What's the deck about, how many slides, who's @@ -86,7 +86,7 @@ tasteful default and confirm. - Academic / report → `academic-paper`, `editorial-serif`, `minimal-white` - Edgy / cyber / launch → `cyberpunk-neon`, `vaporwave`, `y2k-chrome`, `neo-brutalism` -3. **Starting point.** One of the 14 full-deck templates, or scratch? Point +3. **Starting point.** One of the 15 full-deck templates, or scratch? Point to the closest `templates/full-decks//` and ask if it fits. If the user's content suggests something obvious (e.g. "我要做产品发布会" → `product-launch`), propose it confidently instead of asking blindly. @@ -98,7 +98,22 @@ A good opening message looks like: > 2. 风格偏好?我建议从这 3 个主题里选一个:`tokyo-night`(技术分享默认好看)、`xiaohongshu-white`(小红书风)、`corporate-clean`(正式汇报)。 > 3. 要不要用我现成的 `tech-sharing` 全 deck 模板打底? -Only after those are clear, scaffold the deck and start writing. +🔴 **CHECKPOINT: All 3 items answered → proceed. If user says "你自己定" → pick defaults and confirm once.** + +## Authoring Workflow (step-by-step) + +Follow these steps in order. Each step has a clear input → action → output. + +| Step | Input | Action | Output | +|------|-------|--------|--------| +| 1. Scaffold | Deck name | `bash scripts/new-deck.sh ` | `examples//index.html` | +| 2. Set theme | User's tone/audience | Change `` | Correct theme CSS loaded | +| 3. Build outline | Content + page count | Add/remove `
` blocks | Right number of slides | +| 4. Fill layouts | Outline structure | Copy from `templates/single-page/*.html`, replace demo data | Real content in each slide | +| 5. Add animations | Visual rhythm | `data-anim="fade-up"` on hero elements, max 1-2 per slide | Entry effects | +| 6. Add notes | Speaker needs | `
` per slide | S-key presenter notes | +| 7. Review | Completed deck | Open in browser, press O/T/S to verify | No layout clipping | +| 8. Export | Reviewed deck | `bash scripts/render.sh ` | PNG files | ## Quick start @@ -155,6 +170,40 @@ Only after those are clear, scaffold the deck and start writing. by default — it only appears in the S overlay. Slides should contain ONLY audience-facing content (titles, bullet points, data, charts, images). +## Failure Modes & Troubleshooting + +If any step fails, follow this fallback chain: + +| Trigger | First-line fix | Still failing | +|---------|---------------|---------------| +| `render.sh` returns ERR_FILE_NOT_FOUND | Check Chrome path: `which google-chrome` (Linux) / verify `LOCALAPPDATA` (Windows) | Set `CHROME=/path/to/chrome.exe` env var and retry | +| `render.sh` produces blank/white PNG | Increase `--virtual-time-budget=4000` to `8000` in render.sh | Open HTML in browser manually, screenshot with `browser_screenshot` | +| Theme not switching with T key | Verify `data-themes="a,b,c"` on `` and `data-theme-base` pointing to themes dir | Hard-code `` instead of T-cycle | +| Fonts look wrong / fallback to system | Check `fonts.css` is linked BEFORE the theme CSS | CDN blocked (China firewall) — add local font fallback or use proxy | +| Canvas FX not playing | Verify `` is AFTER the `
` | Check browser console for JS errors; FX modules load async | +| `new-deck.sh` path rewrite wrong | Verify output HTML has `../../assets/` (not `../assets/`) | Manually edit paths: add one more `../` for each nesting level | +| `open` command not found | macOS: `open`, Windows: `start`, Linux: `xdg-open` | Just drag the HTML file into Chrome | +| Slide layout broken in a theme | Some themes override border-radius/shadow aggressively | Test with `minimal-white` first; if broken there, fix the layout HTML | +| Chart.js colors wrong | Charts read CSS vars in JS; must run after DOM ready | Wrap in `addEventListener('DOMContentLoaded', ...)` | +| presenter-mode S key not working | `runtime.js` must be linked | Check `` is present | + +## Anti-Patterns — DO NOT + +| # | ❌ Don't | ✅ Do instead | +|---|---------|---------------| +| 1 | Author slides from a blank HTML file | Copy the closest layout from `templates/single-page/` first | +| 2 | Use literal hex colors (`#111`, `rgb(...)`) | Use CSS tokens: `var(--text-1)`, `var(--accent)` | +| 3 | Put presenter-only text on the visible slide | Wrap in `
` or `