원클릭으로
slide-inspector
// Quality audit for PowerPoint decks. Catches layout bugs, design inconsistencies, accessibility issues, AI-generation tells, and silent generator failures.
// Quality audit for PowerPoint decks. Catches layout bugs, design inconsistencies, accessibility issues, AI-generation tells, and silent generator failures.
| name | slide-inspector |
| description | Quality audit for PowerPoint decks. Catches layout bugs, design inconsistencies, accessibility issues, AI-generation tells, and silent generator failures. |
| when_to_use | Use whenever reviewing, auditing, or QA-ing a .pptx file — whether you just created it or the user uploaded one. Triggers: 'inspect my slides', 'check this deck', 'review this presentation', 'QA these slides', 'audit my pptx', 'are there any issues with this deck'. Always use as the QA step after creating any presentation with the pptx skill — every deck must pass this inspection before delivery. If you're about to declare a presentation 'done', run this skill first. Also: 'calibrate slide-inspector' triggers one-time calibration mode that mines the user's correction history. |
| allowed-tools | Bash(python3 *) Bash(bash *) Bash(pdftoppm *) Bash(ls *) Bash(rm slide-*.jpg) Read |
A systematic quality audit for PowerPoint presentations. Catches layout bugs, design inconsistencies, readability problems, structural anti-patterns, and AI-generation tells that make slides look unpolished.
Post-creation QA (integrated): After generating a .pptx with the pptx skill, run this inspection before delivering the file. Think of it as the compiler warnings step — you wouldn't ship code without checking for errors.
Standalone audit: When a user uploads a .pptx and asks you to review it, inspect it, or check for issues.
Calibration (one-off, opt-in): When the user invokes calibrate mode, scan their CC history to learn their personal correction patterns and propose custom checks. See references/calibration.md for the procedure.
Before starting any inspection, check whether the user has been offered calibration:
~/.claude/skills/slide-inspector/user-overrides.yaml exists."First time running slide-inspector. I can calibrate it to YOUR style by mining your past pptx correction history (~5-10 min). This adds custom checks for patterns you fix repeatedly that aren't in the defaults. Want to calibrate first? (yes / no)"
references/calibration.md to run the calibration procedure. It creates user-overrides.yaml populated with approved patterns. Then proceed with the inspection.~/.claude/skills/slide-inspector/user-overrides.yaml:
# User declined calibration on first run. Hand-edit anytime to add custom checks.
# Re-run calibration any time with: "calibrate slide-inspector"
overrides:
calibration_status: declined
checks: []
Then proceed with the inspection. Do not ask again.This is a one-time UX moment per user. Once the file exists, it's never re-prompted. The user can re-run calibration any time by saying "calibrate slide-inspector" — that just appends new patterns to the existing file.
The inspection has two complementary layers. Both are needed — programmatic analysis catches structural issues humans miss (overlapping coordinates, font inconsistencies, off-canvas elements), while visual inspection catches aesthetic issues code can't judge (awkward spacing, visual weight imbalance).
Run the structural analyzer on the .pptx file:
python3 ${CLAUDE_SKILL_DIR}/scripts/inspect_slides.py presentation.pptx
This script unpacks the PPTX XML and checks for:
<p:cxnSp> connectors with no shape endpointsBlock 1 · 10min, Step N ·, \d+\s*min) — generator metadata bleeding into slide contentHere's a polished, As an AI, I cannot, trailing markdown **Understanding X, Exploring Y, Navigating Z, Leveraging, Unlocking, Diving into (AI scaffolding language)The script outputs a JSON report. Review it, but don't just parrot it — use it as input to your own judgment.
Convert slides to images and inspect them visually. Uses soffice (LibreOffice) + pdftoppm (Poppler) — both common system tools, neither tied to any other skill:
# Convert pptx → pdf, then pdf → jpeg per slide
soffice --headless --convert-to pdf presentation.pptx
rm -f slide-*.jpg
pdftoppm -jpeg -r 150 presentation.pdf slide
ls -1 "$PWD"/slide-*.jpg
If LibreOffice isn't installed: brew install --cask libreoffice (macOS) or apt install libreoffice (Debian/Ubuntu). pdftoppm comes with poppler (brew install poppler).
If the user has the pptx skill installed, an alternative is its scripts/thumbnail.py which produces a multi-slide grid image instead of one-image-per-slide — useful for deck-level scanning.
Then view each slide image. Read references/checklist.md for the full visual inspection checklist. The key categories:
After both analysis passes, produce a structured report. The report has three output modes — use all three:
A) In-chat issue list — A concise summary in conversation, organized by severity:
B) Annotated analysis — For each slide with issues, describe what's wrong and where. Reference specific elements by their position (e.g., "the title text on slide 3 overlaps with the right-side image").
C) Structured report file — Save a markdown report to the filesystem:
# Slide Inspection Report
## Summary
- X critical issues, Y warnings, Z suggestions
- Overall quality: [Poor / Needs Work / Good / Excellent]
## Slide-by-Slide Findings
### Slide 1: [slide title]
- [severity] [category]: [description]
...
## Cross-Slide Consistency
- Font usage: [findings]
- Color palette: [findings]
- Layout patterns: [findings]
- Code snippet styling: [findings]
- Illustration consistency: [findings]
## Recommendations
1. [prioritized fix]
2. ...
Elements whose bounding boxes intersect are the #1 visual bug. The programmatic analyzer catches coordinate overlaps, but visual inspection catches cases where elements are technically separate but visually collide (e.g., a descender from line 1 touching an ascender from line 2).
Common culprits:
This is one of the most common AI-generated slide problems. Instead of:
// ❌ BAD: Separate addText() calls for each line
slide.addText("Line 1", { x: 1, y: 1, w: 8, h: 0.4 });
slide.addText("Line 2", { x: 1, y: 1.5, w: 8, h: 0.4 });
slide.addText("Line 3", { x: 1, y: 2, w: 8, h: 0.4 });
It should be:
// ✅ GOOD: Single text box with breakLine
slide.addText([
{ text: "Line 1", options: { breakLine: true } },
{ text: "Line 2", options: { breakLine: true } },
{ text: "Line 3" }
], { x: 1, y: 1, w: 8, h: 1.5 });
The programmatic analyzer detects this by looking for sequences of text boxes at the same x-position with incrementing y-positions and similar widths. This pattern causes:
Code on slides needs special treatment to be readable. The inspection checks:
<p:cxnSp> connectors with no shape endpoints (free-floating arrows) usually indicate broken diagram generation. Common with AI-generated systems-thinking diagrams.For decks containing Cyrillic, CJK, Arabic, Devanagari, Hebrew, Greek, etc.:
These span the entire deck, not individual slides:
Slides are a visual medium — dense text belongs in a document, not a deck. This skill assumes presenter mode (you're showing the slide while speaking). Density thresholds reflect that:
** — slipped through generation if user prompt contained scaffolding.These checks span the whole deck rather than individual slides. They surface the kind of scaffolding bloat that experienced presenters strip out — the "skeleton" left behind when an AI builds a "complete" deck instead of a sparse briefing.
Preamble overhead: Count slides before the first content slide (title + agenda + accountability + intro). If preamble exceeds ~15% of total deck length, flag as "preamble feels heavy for deck size — consider opening straight into content."
Decorative section dividers: A section divider is a slide whose only content is a section label + tagline (no charts, screenshots, or data). Flag any divider whose section has fewer than 4 content slides — the divider is heavier than the section it introduces. Suggest replacing with a color-shifted title on the next content slide.
Image-led slide hierarchy: When a slide has a chart, screenshot, or photograph that is clearly the slide's primary information carrier, check that the visual occupies the majority of the canvas (>50% of slide area). If the title text-block is comparable in size to the chart, the layout is reading as "chart caption" rather than "chart." Suggest the inverted layout: chart on top full-width → thin rule → title in band below.
Generated metaphorical imagery on specific-entity slides: When a slide's topic names a specific real product, research paper, news incident, or company action (e.g., "Project Glasswing", "Anthropic post-mortem", "Figure 03 walks at White House"), and the visual on that slide is a stylized illustration / abstract metaphor, flag as "verify a real asset doesn't exist (official product graphic, research figure, press photo)." Real artifacts are nearly always more compelling than generated metaphors when the topic is concrete.
Color-as-architecture overuse: If section colors appear on multiple decorative elements per slide (title + accent bar + glyph + underline), flag as "color is doing structural work that could be done by typography alone." A single colored title is usually sufficient.
Closing-slide weakness: The final slide should ask a directive question or specify a concrete next step, not merely announce a generic ritual ("Q&A", "Thank you", "Commitment round"). Flag generic closes as a missed opportunity.
Every user has personal correction patterns that go beyond the defaults. The skill supports a user-overrides.yaml file that adds custom checks specific to the user.
To generate this file from the user's own correction history:
User: "calibrate slide-inspector"
This triggers the calibration procedure described in references/calibration.md:
~/.claude/projects/*/ for pptx-related sessions~/.claude/skills/slide-inspector/user-overrides.yamlThe user-overrides file is loaded automatically on every subsequent inspection. See user-overrides.yaml.example for the schema and worked examples.
Calibration is opt-in. New users get full default coverage out of the box. Calibration is recommended after ~10+ pptx sessions when there's enough correction history to find real patterns.
Use these guidelines to assign severity:
| Severity | Criteria | Examples |
|---|---|---|
| 🔴 Critical | Content is unreadable, missing, or visually broken | Text cut off, elements overlapping making text illegible, code in proportional font, off-canvas text visible during screen-share, empty slides, non-Latin text rendering as tofu |
| 🟡 Warning | Noticeable quality issue that looks unprofessional | Inconsistent fonts across slides, uneven spacing, missing code background, "one box per line" pattern, image aspect distortion, marooned images, scaffolding leaks, vague title verbs, tool watermarks |
| 🟢 Suggestion | Minor polish that would elevate the deck | Slightly tighter margins possible, illustration style could be more unified, color palette could be tighter, AI-tell vocabulary |
If this was a post-creation QA step: Fix all Critical and Warning issues before delivering. Re-run the inspection after fixes to verify — one fix often creates new problems (e.g., making a text box taller to prevent overflow may push it into the element below).
If this was a standalone audit: Present the report to the user and offer to fix the issues. Prioritize Critical → Warning → Suggestion.
Own scripts (bundled with this skill):
scripts/inspect_slides.py — Programmatic XML analysisscripts/calibrate.sh — Bash pre-filter for the calibration procedure (greps + jq-extracts pptx-related session corrections from ~/.claude/projects/)Own references (bundled):
references/checklist.md — Full visual inspection checklistreferences/calibration.md — Step-by-step procedure for calibration modeTemplates (bundled):
user-overrides.yaml.example — Schema and worked example for custom checksSystem tools (must be installed; not bundled):
soffice (LibreOffice) — PowerPoint to PDF conversion. Install: brew install --cask libreoffice or apt install libreoffice.pdftoppm (Poppler) — PDF to JPEG. Install: brew install poppler or apt install poppler-utils.python3 — runs inspect_slides.py. Only Python stdlib used (no PIL/python-pptx required).jq — used by calibrate.sh for jsonl parsing. Install: brew install jq or apt install jq.Optional: the pptx skill (Anthropic's bundled document-skills/pptx) ships a scripts/thumbnail.py that produces a single grid image instead of per-slide images. If the user has it installed, prefer that for fast deck-level scans. slide-inspector does NOT require the pptx skill — they're independent.
Path resolution at runtime: Use ${CLAUDE_SKILL_DIR} for paths inside this skill — Claude Code resolves it automatically regardless of where this skill is installed.
Real-world quirks that have bitten this skill in practice. Read these before reporting findings.
<p:sp> shapes always carry an empty <p:txBody> in python-pptx/PowerPoint output, whether or not the user added text. The analyzer's parse_element defaults <p:sp> to shape and only promotes to textbox when actual text is present. If you see a "blank-rectangle" issue, the analyzer correctly identified a filled shape with no real text — don't second-guess it.
Title placeholders may have no <a:xfrm> element. They inherit position from the slide layout. The analyzer falls back to a default title-area bbox so the title still reaches vague-title and other title checks. The reported coordinates for inherited-position titles are approximate, not exact.
Off-canvas elements with text are screen-share spoilers, even if they look "decorative". Flag as critical regardless of whether the text seems important — anyone screen-sharing the deck will see anything below the slide. Common cause: leftover element from a previous frame during AI iteration.
non-latin-script is a flag for visual review, not a confirmed font-coverage failure. The analyzer detects script presence but doesn't verify font coverage. Always render the slide and check whether the text appears as readable glyphs vs tofu (□□□).
The placeholder-leak check is a substring match — it will fire on the literal word "placeholder" in any context. If a slide is legitimately ABOUT placeholders (e.g., a tutorial slide), this is a false positive — exercise judgment.
Slide dimensions vary — 4:3 (10×7.5") vs 16:9 widescreen (13.33×7.5"). The analyzer reads from presentation.xml and falls back to widescreen if missing. Off-canvas calculations adjust automatically.
Image intrinsic dimensions are read directly from PNG/JPEG/GIF headers with no PIL dependency. This works for most embeds but fails silently for unusual formats (TIFF, WMF, EMF). If aspect-distortion checks miss an image, check the embedded format.
Density thresholds assume presenter mode (40w warning, 60w critical). For document-style decks (slidedocs intended for reading, not presenting), these thresholds are too aggressive — note this in your report rather than fixing the slide.