Pptx Builder
Two-skill plugin: pptx-builder (python-pptx primary, pptxgenjs polish) and diagram-mapper. Calm-precision design, theme-portability gates, host-portable.
Install
claude plugin marketplace add tyroneross/RossLabs-AI-Toolkit
claude plugin install pptx-builder@rosslabs-ai-toolkit
The Problem
Generated PowerPoint decks look fine on the machine that made them, then fall apart when opened elsewhere — fonts substitute, theme colors shift, layouts reflow. The cause is OOXML theme inheritance: a deck that does not fully define its theme inherits the opener’s, and the design breaks. Separate problem: drawing diagrams of a codebase, a workflow, or a state machine usually ends in a hand-built image that goes stale the moment the underlying thing changes.
What I Built
A Claude Code plugin that hosts two skills:
pptx-builder — PowerPoint deck builder built around the calm-precision-pptx hybrid model. python-pptx is the primary structural build engine and the canonical theme owner (typed structure.json → tokens → helpers → .pptx, following Calm Precision design philosophy and a Gestalt decision framework). The pptxgenjs polish layer is now wired (v0.6.0) for slides where pixel-precise composition earns its weight — the cover slide is the first consumer, composed in Node and merged into the python-pptx base by a from-scratch cross-deck slide merge engine at the OOXML/ZIP-package level. Opt in via --polish-cover; default OFF — zero regression to the python-pptx primary path.
diagram-mapper — turns any source artifact (codebase, workflow engine, state machine, API, process doc, org structure, financial model) into an audit-grade diagram with explicit node types, decision branches, and exception paths. Renders to Mermaid (default), SVG, HTML/interactive, or PowerPoint via the same plugin QA stack. When a diagram is embedded into a calm-precision deck, its palette resolves to the deck’s tokens so the diagram matches.
Hard Rules (Mechanically Enforced)
Calm Precision base, enforced as lints:
- Action titles only — full sentences, sentence case, no terminal period, ≤95 chars
- One assertion per slide
- Footnote every numeric claim
- Semantic color only —
BRAND_PRIMARYappears once per slide on the dominant element - Whitespace is content; outer margins ≥ 0.4”
- Slide background set explicitly on every slide (
#FAFBFC)
User overrides also mechanically enforced:
- No em-dashes / en-dashes — use colons, semicolons, commas, “to”
- No horizontal row lines in tables — vertical column separators only
- No decorative lines — table header underline is the only allowed horizontal rule
- No panels for grouping — whitespace and the 12-column grid carry grouping
- No bottom takeaway bar — the action title carries the takeaway
- Native tables and charts — Excel-editable, no images of tables
- Inter only (FONT_PRIMARY = “Inter”; serif fails)
- High-contrast light background mandatory
The QA Gauntlet
Every gate must exit 0 before a deck is considered shippable:
| Gate | What it catches |
|---|---|
validate_structure.py | structure.json schema conformance |
verify_typography.py | Inter only; 3-tier ladder for body / chart-axis / chart-legend |
verify_deck.py | Em-dash / italic / fractional-EMU policy |
text_lint.py | Sentence shape, terminal period, length caps |
contrast_lint.py | WCAG 4.5:1 minimum |
drift_check.py | Tokens-vs-output mismatch (canonical --tokens mode reads the python-primary JSON; legacy --skin mode reads JS skins for back-compat) |
fix_theme_portable.py | Closes the six OOXML inheritance gaps that cause cross-machine drift |
verify_portable.py --strict | Pass/fail gate run before delivery |
render_pptx.py --png | Microsoft PowerPoint on macOS (primary ground truth); LibreOffice via render_qa.sh is the fallback |
Style-Input Modes
Three modes, no mode-switching ceremony:
- No style guidance — built-in default house skin (Calm Precision tokens).
- Copy an existing deck — ingest a sample
.pptx, extract tokens viaextract_theme_colors.py, build new slides that match;fix_theme_portable.py --theme-map <extracted>for paste compatibility. - User-provided style — explicit
.deck-prefs.jsonat the repo root or a named skin.
Repo Layout (folder-per-capability)
skills/pptx-builder/
├── design/references/ vendored calm-precision + user overrides + palette library
├── build/ python-pptx PRIMARY build path + cross-deck slide merge
├── polish/ pptxgenjs polish layer (cover slide wired v0.6.0)
├── structure/ schema.json + validator
├── qa/ typography, lints, contrast, drift, portability, render
├── tokens/ single source of truth
├── samples/ fixtures (cx-premium-kickoff for the slide-1-3 proof)
└── legacy/ demoted v0.2.0 fixed-renderer + v0.3.0 PptxGenJS guided pipeline
Host-Portable
The plugin runs across Claude Code, Codex, and Claude cowork — both skills are host-LLM-driven (the host reasons over the grammar; no vendor API calls in the build or diagram path). AGENTS.md carries host-neutral instructions.
Pairs With
- tyrone-writing-system / deck-structure — lock the argument before drafting
- pyramid-principle / pyramid-presentation — deeper Pyramid storylining
- design plugin —
design-critiqueandaccessibility-reviewpasses