v0.9 Spec: --style-gallery Flag (the cover-style gate)
July 10, 2026 · View on GitHub
Date: 2026-06-17
Status: Implemented in v0.9 (feat/v0.9-next).
v1.1 renderer exception: PPT Master already owns a mandatory three-stage Confirm UI with native visual_style preview SVGs. --renderer ppt-master --style-gallery therefore delegates to that surface; it does not create four speculative PPT Master projects.
Motivation
Humanize PPT is for the presentation and compatible with downstream HTML PPT renderers — and it never renders. By v0.8 the flow was: AST slice → (optional --preview-outline review) → production brief → downstream renders. The human picks the renderer and (for guizang) a single style/theme up front, blind. They commit to one look before seeing a single pixel.
The 9-style showcase on "10 分钟入门 Agent 7 概念" showed the cost: people want to see covers side by side before committing. One static thumbnail per style is the cheapest possible preview — a cover is the highest-signal page, and rendering one page is cheap for the downstream skill.
The architecture decision (拍板): the gallery shows ≥4 covers that the downstream skill really renders. Humanize stays in its lane — it emits the spec and the commands; it does not render the covers itself.
Design
New flags
--style-gallery (boolean, default off) — the gate before the outline.
--gallery-count N (int, default 4, minimum 4) — capped at the candidates defined for the renderer.
--style-gallery is checked before --preview-outline in main(): you pick a style, then preview the outline. Passing both stops at the gallery.
What it writes (then stops)
For the resolved primary renderer (choose_routes), Humanize takes the first
N candidates from STYLE_GALLERY_CANDIDATES[renderer] and writes:
commands/style-gallery/<id>.md— a cover-only render command per candidate. It tells the downstream skill to render only S01 in that style and writeoutputs/style-gallery/<id>/cover.{html,png}. Not a full deck.style_gallery.html— a zero-dependency single-file picker that stitches the candidate covers (relative-path<iframe>s) with each candidate's label, description, and the exact re-injection command. Honest about pending state: a not-yet-rendered cover shows the frame backdrop plus an always-visible caption — no faked thumbnail (宁空不摆拍).style_gallery_plan.json— machine-readable: per-candidateid,label,description,cli,command_file,cover_html,cover_png,reinjection_command.
Then it prints {"ok": true, "stopped_at": "style-gallery", ...} and returns 0.
No outline, no brief, no QA.
For ppt-master, the renderer-native branch writes instead:
commands/style-gallery/ppt-master-confirm-ui.md— re-injection command plus the instruction to use PPT Master's Stage 1 direction page.style_gallery_plan.jsonwithmode: downstream-confirm-ui,picker: null, andcandidate_sourcepointing to PPT Master's own visual-style catalog.
It returns stopped_at: ppt-master-style-gate. No fake style_gallery.html, cover image, or candidate deck is emitted.
The candidates
Module-level STYLE_GALLERY_CANDIDATES, keyed by renderer, ≥4 each:
- guizang — spans both tracks so the four covers are visually distinct:
Style A
ink-classic(the known-good baseline), Style Akraft-paper, Style Aindigo-porcelain, Style B Swissikb. - frontend-slides — 4 style directions (editorial-serif, techno-grid, soft-gradient, mono-contrast).
- beautiful-html-templates — 4 template slots filled from the skill's native template library (placeholder slugs; downstream picks real templates).
Each candidate carries cli: the exact renderer/style args grafted onto the
next run. After picking a cover, the human runs the printed
reinjection_command, which resumes the normal outline → brief flow with the
chosen style. (Append --preview-outline for the review checkpoint.)
WebGL static-screenshot trap (ties to QA failure modes)
Guizang Style A covers use a WebGL hero canvas. A static PNG screenshot
captures the canvas before it paints → blank cover (实证: a Style A
ink-classic cover PNG came back 14KB, an empty page). So each Style A
candidate command warns:
- treat
cover.html(the live page) as the source of truth;cover.pngis a thumbnail only, - wait for the canvas's first frame before screenshotting (delay ≥1.5s),
- a
cover.pngunder 20KB is a failed capture, not an empty cover.
The picker footer repeats this so a blank frame is read correctly.
Boundary (unchanged)
Humanize decides what (which candidate styles) and where (the output
paths). The downstream skill produces the cover files. Humanize never opens a
renderer template and never post-processes rendered HTML. The picker is a
Humanize-owned working draft (like preview_outline_html.py), not a deck.
Reuse
run_style_gallery_mode reuses read_source / detect_language /
build_slide_plan / choose_routes / now_iso — the same primitives as the
brief and preview-outline modes. No new parsing path.