Back to projects
Active Started May 2026

Pptx Builder

Two-skill plugin: pptx-builder (python-pptx primary, pptxgenjs polish) and diagram-mapper. Calm-precision design, theme-portability gates, host-portable.

Private Repo
Claude Code Plugin python-pptx pptxgenjs Python Node Mermaid

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_PRIMARY appears 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:

GateWhat it catches
validate_structure.pystructure.json schema conformance
verify_typography.pyInter only; 3-tier ladder for body / chart-axis / chart-legend
verify_deck.pyEm-dash / italic / fractional-EMU policy
text_lint.pySentence shape, terminal period, length caps
contrast_lint.pyWCAG 4.5:1 minimum
drift_check.pyTokens-vs-output mismatch (canonical --tokens mode reads the python-primary JSON; legacy --skin mode reads JS skins for back-compat)
fix_theme_portable.pyCloses the six OOXML inheritance gaps that cause cross-machine drift
verify_portable.py --strictPass/fail gate run before delivery
render_pptx.py --pngMicrosoft PowerPoint on macOS (primary ground truth); LibreOffice via render_qa.sh is the fallback

Style-Input Modes

Three modes, no mode-switching ceremony:

  1. No style guidance — built-in default house skin (Calm Precision tokens).
  2. Copy an existing deck — ingest a sample .pptx, extract tokens via extract_theme_colors.py, build new slides that match; fix_theme_portable.py --theme-map <extracted> for paste compatibility.
  3. User-provided style — explicit .deck-prefs.json at 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-critique and accessibility-review passes