Create, edit, critique, and repair slide decks (PowerPoint). Use whenever the user asks for a presentation, pitch deck, slides, talk deck, or wants to improve slide layout/typography/visual hierarchy, fix overflow/misalignment, redesign bullet-heavy content into grids/timelines/charts, edit an existing branded template, or convert text/docs into a clean deck. Produces a slide plan + renderer-agnostic IR, runs computed QA checks, and iterates fixes until ship-ready. Also handles editing existing PPTX files via template workflow (rearrange/replace) or direct OOXML XML editing.
Turn raw content into ship-ready slide decks by enforcing a constraint system — grid, type scale, color tokens, component library, deck rhythm — instead of improvising slide-by-slide.
Three jobs:
The authoritative design reference is references/ppt-design-guide.md. All thresholds, archetype specs, IR format, QA checks, and repair ladders live there.
Read the relevant reference files based on what you're doing. Multiple files apply for full deck creation. Read them before writing any code or content.
| Task | Load these references |
|---|---|
| Content planning, slide count, segmenting raw text | references/content-segmentation.md |
| Narrative flow and section sequencing |
references/narrative-arcs.md |
| Choosing a layout archetype for any slide | references/ppt-design-guide.md §3, references/renderer-archetypes.md, scripts/archetype-geometries.json |
| Assertion headline writing and audit | references/headline-audit.md |
| Spatial composition and spacing systems | references/composition-principles.md |
| Asset/image planning and style coherence | references/asset-planning.md |
| Transforming dense text into structured slides | references/transformation-patterns.md |
| Full design guide (thresholds, QA ladders, IR, acceptance criteria) | references/ppt-design-guide.md |
| Quick decisions without reading the full guide | references/quick-cheatsheet.md |
| Colors, themes, dark-mode rules | references/visual-themes.md |
| Typography, hierarchy, and archetype spacing cues | references/typography-color.md |
| Adding charts or data visualizations | references/data-viz.md |
| IR format and element schema | references/ir-schema.md, references/ir.schema.json |
| Agent runtime defaults/preset behavior | references/agent-presets.md |
| Hard constraint tables, overflow strategy, auto-fix ladder, QA rubric | references/constraints-qa.md |
| Renderer archetype coverage + canonical archetype ID strings | references/renderer-archetypes.md, scripts/archetype-geometries.json |
| Vision critique scoring prompt and output schema | references/vision_critique_prompt.md |
| Toolchain comparison, python-pptx best practices | references/ppt-design-guide.md Appendix A–B |
| Full new deck creation (Mode A, end-to-end) | All of the above, in routing order |
FEEDBACK.md for existing related entries before adding.FEEDBACK.md with date and category tag.Proceed with defaults; ask only if missing information blocks execution.
Reasonable defaults when unspecified:
references/typography-color.md)agent_polished (preflight on, animation pass on, auto-build animations off)Deliver all of these unless the user explicitly opts out:
slide-plan.md) — one line per slide: role → archetype → assertion headlinedeck.ir.json) — renderer-agnostic contract following the schema in references/ir-schema.mdqa.report.json + qa.report.md) — pass/fail against hard constraints + prioritized fixesdeck.pptx — if script execution is available (Mode A) or the user requests a fileIf making changes to an existing deck: also produce diff.md listing what changed per slide.
This is the primary creation path. The renderer takes deck.ir.json and outputs deck.pptx via PptxGenJS — keeping content, layout, and rendering strictly separated.
Read these before writing a single line:
references/content-segmentation.md — apply segmentation heuristics and density thresholds to the raw contentreferences/narrative-arcs.md — choose arc shape and section pacing before slide-level designreferences/ppt-design-guide.md §3 + references/renderer-archetypes.md + scripts/archetype-geometries.json — map each content chunk to a named archetype (A1–A24) using the decision tree and canonical geometry contractsreferences/composition-principles.md + references/typography-color.md — select spacing system, type scale, and hierarchy treatmentreferences/visual-themes.md + references/asset-planning.md — select theme/mode and planned asset strategyState your design approach before generating IR.
Extract: facts, claims, numbers, tables, required sections, any must-include visuals.
Output: inputs.digest.md (short summary) + structured list of candidate slide chunks.
Segment content using the heuristics in references/content-segmentation.md. One idea per slide. Assign each slide a rhetorical role (hook, problem, evidence, plan, etc.).
Output: slide plan draft.
Choose one archetype per slide using references/ppt-design-guide.md §3.2 decision tree + canonical IDs in references/renderer-archetypes.md (scripts/archetype-geometries.json for machine checks). Prefer transforming bullet dumps into structure:
This step requires a filled planning table as its output. You may not proceed to Step 4 until this table is complete and both rhythm checks pass.
| Slide | Role | Archetype | Rationale (≤10 words) | Assertion headline | Verb? | Claim? |
|---|---|---|---|---|---|---|
| S01 | … | … | … | … | ✓/✗ | ✓/✗ |
Rules for the Verb? and Claim? columns — read references/headline-audit.md:
If any row has ✗ in either column, fix that headline before continuing.
Rhythm summary (required at bottom of table):
Non-bullet archetypes: X / N (need ≥ 25% = ≥ ceil(N * 0.25)) → PASS / FAIL
Longest consecutive same archetype run: N → PASS (≤ 2) / FAIL (> 2)
Breather slides present: Y/N (required every 4–6 content slides)
If either rhythm row shows FAIL, redesign the affected slides before writing any IR. Do not proceed to Step 4 with a FAIL rhythm summary.
Output: filled planning table + passing rhythm summary.
Create deck.ir.json following references/ir-schema.md and valid against references/ir.schema.json:
deck.tokens: fonts, sizes, colors, griddeck.slides[]: id, archetype (canonical string from renderer-archetypes.md), assertion headline, elements[] with bbox in inchesValidate: python scripts/validate_ir.py deck.ir.json
IR must be complete enough to render deterministically.
Before rendering, snap all element bboxes to the grid:
python scripts/snap_to_grid.py deck.ir.json --out deck.snapped.ir.json
node scripts/pipeline.js deck.snapped.ir.json deck.pptx --preset agent_polished
CLI options:
--preset <name>: agent_polished (default), agent_polished_animated, agent_strict, agent_fast--skip-preflight: skip IR + PPTX preflight steps--skip-animations: skip animation injection step--auto-animations: opt into auto-build reveal heuristics (inject_animations.py --auto)--strict-preflight: fail fast on preflight hard-fail--vision-qa: run thumbnail generation + optional vision QA hook before final PPTX preflightPPTX_AGENT_PRESET=<name> env var sets the default preset for unattended runsFor direct renderer-only runs (without preflight/injection orchestration):
node scripts/render_pptx.js deck.snapped.ir.json deck.pptx
If PptxGenJS is unavailable: output IR + human-editable outline. See Fallback: html2pptx below.
If you used scripts/pipeline.js, IR and PPTX preflights already ran. For explicit/manual QA runs:
Run IR-level checks first:
python scripts/preflight_ir.py deck.snapped.ir.json --out qa.report.json --md qa.report.md
Then PPTX-level checks:
python scripts/preflight_pptx.py deck.pptx --out qa.pptx.json --md qa.pptx.md
Visual thumbnail review is always required before delivery — it catches geometry failures (misaligned cards, unequal column widths, overflow) that preflight scripts cannot detect from XML alone.
If scripts/thumbnail.py is available:
python scripts/thumbnail.py deck.pptx thumbnails
If unavailable, use LibreOffice + pdftoppm:
soffice --headless --convert-to pdf deck.pptx
pdftoppm -jpeg -r 150 deck.pdf slide
Work through each thumbnail and check:
If scripts are unavailable and conversion is not possible, state this explicitly in the QA report and mark the deck as UNVERIFIED — visual QA not completed. Do not present an unverified deck as ship-ready.
If any hard constraint fails, apply fixes in this order (from references/constraints-qa.md):
Stop when: all hard constraints pass + acceptance criteria met, OR 3 iterations reached. If 3 iterations reached, surface remaining issues and best achievable state.
Two paths depending on what the user needs.
Use when: user provides a branded template and wants a new deck built from it.
python -m markitdown template.pptx > template-content.md
python scripts/thumbnail.py template.pptx workspace/thumbnails --cols 4
Read template-content.md completely. Never set range limits when reading this file.
Review thumbnail grid(s) visually. Map each template slide to its closest archetype (A1–A24). Save template-inventory.md:
# Template Inventory
**Total Slides: [count]**
**IMPORTANT: Slides are 0-indexed**
- Slide 0: [Archetype ID] — Description/purpose
- Slide 1: [Archetype ID] — Description/purpose
[... EVERY slide listed with its index ...]
Apply segmentation heuristics (references/content-segmentation.md) to the raw content to determine slide boundaries. Match each content chunk to a target archetype, then to a template slide offering that archetype.
Match layout to actual content: two-column layouts only when you have exactly 2 items; image layouts only when you have actual images. Count content pieces before selecting layout.
Save outline.md with:
template_mapping = [
0, # Slide 0 (A1: Cover)
34, # Slide 34 (A5: Split)
34, # Duplicate for second A5
50, # Slide 50 (A22: Quote)
]
python scripts/rearrange.py template.pptx working.pptx 0,34,34,50
Indices are 0-based. Repeat indices to duplicate.
python scripts/inventory.py working.pptx text-inventory.json
Read text-inventory.json completely. Never set range limits. Only reference shapes that exist in this inventory.
Create replacement-text.json. Rules:
"bullet": true, "level": 0 (no manual bullet symbols)"bold": true"alignment": "CENTER" etc.)"color": "FF0000" (RGB) or "theme_color": "DARK_1" (theme token)Example:
{
"slide-0": {
"shape-0": {
"paragraphs": [
{"text": "Fraud detection now catches 94% of attacks in real time", "bold": true, "alignment": "CENTER"}
]
}
}
}
python scripts/replace.py working.pptx replacement-text.json output.pptx
If overflow errors are reported: apply the overflow ladder from references/constraints-qa.md — never shrink fonts first.
Visual QA:
python scripts/thumbnail.py output.pptx workspace/output-thumbnails --cols 4
Inspect thumbnails for: text cutoff, overlaps, low contrast, elements outside safe margins.
Run PPTX preflight:
python scripts/preflight_pptx.py output.pptx --out qa.pptx.json --md qa.pptx.md
Produce diff.md listing what changed per slide.
Use when: editing comments, speaker notes, animations, slide layouts, or any structural change that goes beyond content replacement.
MANDATORY before touching any XML. Read ooxml.md completely. Never set range limits.
python ooxml/scripts/unpack.py <office_file> <output_dir>
Key paths inside the unpacked directory:
ppt/slides/slide{N}.xml — slide contentppt/notesSlides/notesSlide{N}.xml — speaker notesppt/comments/modernComment_*.xml — commentsppt/slideLayouts/ — layout templatesppt/theme/theme1.xml — color scheme and fontsppt/media/ — images and assetsPositions are in EMUs. Conversion: 1 inch = 914400 EMU. Safe margin floor: 0.5 in = 457200 EMU.
Common fixes:
<a:off x="..." y="..."/> so x ≥ 457200 and y ≥ 457200ppt/notesSlides/notesSlide{N}.xml<a:rPr> elements; update sz attribute (in hundredths of a point: 18pt = sz="1800")python ooxml/scripts/validate.py <output_dir> --original <original_file>
Do not accumulate unvalidated changes. Validate after each edit.
python ooxml/scripts/pack.py <output_dir> <output_file>
python scripts/preflight_pptx.py output.pptx --out qa.pptx.json --md qa.pptx.md
Produce diff.md listing what changed per slide.
Use when: user provides a deck and wants critique, polish, or "make this look professional."
preflight_pptx.py first for computed violations.references/vision_critique_prompt.md for the scoring prompt + JSON schema (aligned with references/ppt-design-guide.md §13).Map all issues to guide codes: OVERFLOW, LOW_CONTRAST, RAINBOW_SLIDE, LABEL_HEADLINE, TEXT_WALL, MISALIGNED_EDGES, CHART_CLUTTER, DECK_MONOTONY, etc.
Use only when Node/PptxGenJS is unavailable and a rendered PPTX is required.
This path breaks the IR → renderer separation principle, but is better than delivering nothing. Read html2pptx.md fully before using it.
Key differences from Mode A:
preflight_pptx.pyAll design rules still apply: assertion headlines, density thresholds, archetype selection, no off-palette colors.
Consult references/ppt-design-guide.md §10–12 and references/constraints-qa.md for the full constraint table and auto-fix ladders.
Never shrink fonts as the first response to overflow. Apply in this order:
python scripts/thumbnail.py presentation.pptx [output_prefix] [--cols N]
Creates thumbnails.jpg (or numbered grid files for large decks). Default: 5 columns, max 30 slides per grid. Range: --cols 3 (12/grid) to --cols 6 (42/grid). Slides are 0-indexed.
soffice --headless --convert-to pdf presentation.pptx
pdftoppm -jpeg -r 150 presentation.pdf slide
# Produces slide-1.jpg, slide-2.jpg, etc.
# Specific range: -f 2 -l 5 for pages 2–5 only
- S01 — [role] — [archetype] — Assertion headline here
- S02 — [role] — [archetype] — Another assertion headline
Save to slide-plan.md. Present in-chat summary before generating IR.
qa.report.md structure:
diff.md structure:
## S03
- Headline: "Product features" → "Three integrations reduce setup time by 60%"
- Archetype: A5_split_50_50 (unchanged)
- Elements: shape-1 body text replaced (4 bullets → 3)
render_pptx.js has dedicated archetype handlers for A1–A24, but slide quality still depends on IR quality (e.g., content density, correct semantic roles, and valid bbox coordinates).preflight_ir.py uses grid sampling to approximate whitespace ratio — accurate to ~2% but not pixel-perfect.preflight_pptx.py cannot detect text overflow/clipping from XML alone; visual QA via thumbnail grid is always required after rendering.When generating code for PPTX operations:
# Python
python3 -m pip install --user --break-system-packages "markitdown[pptx]" defusedxml lxml pillow jsonschema pyyaml
# Node (from skill root)
npm install pptxgenjs sharp adm-zip
# System
sudo apt-get install libreoffice poppler-utils
After installing from .skill, run a lightweight sanity check:
node scripts/pipeline.js evals/files/sample.deck.ir.json out.pptx --preset agent_polished --skip-animations
Expected behavior:
0out.pptx is written