wand-decks-kit
v0.11.0
Published
Rebuilds or authors a client-ready .pptx on the Wand design system: measured fit, embedded Geist, verbatim content.
Downloads
826
Readme
wand-kit v0.4.0
The code half of the Decks power prompt. ../PROMPT.md is the other half
and wins on every design question. This replaces wand-template.pptx —
there is no binary template to keep alive any more.
Use it
The kit runs in two shapes, and the commands are the same in both:
From the repo —
power-prompts/decks/kit/, with fonts and gradients resolved from the sharedbrand/at the repo root. This is where you change it. See../README.md.Packaged —
node tools/package.mjs deckswrites a zip withPROMPT.mdat the root, the kit around it andbrand/copied in. Upload that zip plus a source deck to a fresh chat and say:Unzip this and read PROMPT.md, then run the pipeline on the attached deck.
lib/brand.js is what makes both work; WAND_BRAND_DIR overrides it.
Why a kit and not a template
wand-template.pptx could only live in Project knowledge, and Project knowledge
stores .pptx as a ~15 KB text dump — so the binary was unreachable from the
place it was stored, and the container resets between sessions. That loop is why
the template never got built. Code doesn't have that problem.
Contents
| Path | What |
|---|---|
| wand.js | The front door. doctor / rebuild / layouts / validate / preview / ship |
| START-HERE.md | What to do when all you have is this folder and a .pptx |
| wand_kit.js | Tokens, chrome, primitives, 26 layouts |
| node_modules/ | fontkit and pptxgenjs, vendored. Pure JS, no native builds, so the zip is portable |
| lib/measure.js | Real Geist text metrics via fontkit — fit is measured, not guessed |
| lib/trace.js | Records shape calls so the preview reuses the real layout code |
| lib/schema.js | Every layout's fields and item caps, as data. Drives validate, plan and layouts |
| lib/plan.js | Phase 2-3 worksheet: source shape, layout shortlist, verbatim text, field stubs |
| pylib/ | wandxml.py and ttf.py - the stdlib fallbacks that make pip install optional |
| lib/layouts_dense.js | Roadmaps, architecture stacks, matrices, proof walls |
| lib/layouts_consult.js | Problem grids, split panels, comparison tables, numbered lists |
| build.js | Spec → .pptx, or --preview, or --check |
| preview/ | Browser preview at the 10" grid, with overflow flags and §1 rails |
| tools/extract.py | Phase 0/1 — normalises any canvas onto the 10" grid, dumps verbatim |
| embed_fonts.py | Wraps Geist as uncompressed EOT and wires it into the package |
| qa_coverage.py | Diffs the Phase 1 dump against the built deck; exit 1 on any miss |
| lib/brand.js | Resolves the shared brand/ — 12 Geist faces, gradients, orb, marks, 36 icons |
| docs/ | SPEC.md (spec format) · LAYOUTS.md (catalog) · PIPELINE.md (the six phases as commands) |
| examples/ | template.json — one slide per layout, self-describing |
| ../PROMPT.md | The power prompt. Source of truth on design questions |
Quick start
node wand.js doctor # what works here. No install step of any kind:
# node_modules ships in the zip, and the Python
# side runs on the standard library
node wand.js rebuild source.pptx # normalise, dump verbatim, write work/PLAN.md
# ... you write work/deck.json from the worksheet ...
node wand.js ship work/deck.json # validate, fit, build, embed, coverage, inspectThe individual stages are still there (extract, plan, validate, check,
preview, build, inspect) so a failure can be re-run on its own, and
build.js still works exactly as before. Full loop: docs/PIPELINE.md.
The three things that make complex rebuilds tractable
Measurement instead of eyeballing. lib/measure.js opens the actual Geist
TTFs and measures wrapped text. build.js --check reports every box that
overflows in the real font. This matters because LibreOffice — the only
renderer available in the container — ignores embedded fonts and substitutes
DejaVu, so visual QA over-reports overflow and loses all weight information.
Two of the three "overflows" fixed by eye in the first Infinite Labor build
turned out to fit fine.
One spec, two renderers. lib/trace.js runs a spec through the real layout
functions against a fake presentation object that records every shape. The
browser preview draws that recording. It therefore cannot drift from the .pptx,
and you can iterate on layout in a page refresh instead of a build-embed-convert-
rasterise cycle.
Content separated from geometry. A spec has no coordinates, colours, or font sizes. So a rebuild diffs cleanly in two directions: spec against the source's verbatim text, layout against the design system.
Six gates, not one. ship runs all of them because they are blind
to different things. validate checks fields and item counts against the layout
catalog. --check measures fit in real Geist, bounds against the content band,
and that every asset a slide references exists. qa_coverage.py asks whether
every source string survived. inspect reads the built file. And the preview is
the only one that can tell you a slide is correct and still ugly.
A row hidden under a closing band passes coverage — the text is in the XML — and fails bounds. A paraphrased sentence passes everything except coverage. A mistyped glyph name used to pass all of them and then throw a stack trace from inside pptxgenjs; now it fails the asset check with the slide number.
Conventions
- Every layout resolves colour through
theme(dark). Never hardcode a hex in a build script or a spec. - Titles take a string or a 3-part array for the accent-italic device:
["Two kinds of colleagues. ", "One set of drives", "."]. One per title. - Card corner radius is recomputed per shape by
radius(w, h). Use it. - Layouts whose title can wrap should place content with
contentTop()rather than a fixed y.archStack,matrixGrid,phaseCardsandnumberedCardsdo.
Known gaps
- Icon polarity. The 36 glyphs are white or accent-tinted. A white glyph on
a
surfacetile (light theme) is low-contrast. Checkassets/_icon-contact-sheet.pngbefore picking; the kit doesn't track which is which. The asset check catches a missing glyph, not a wrong one. - Icons are chosen by number, not meaning. The example specs pick plausible glyphs, not semantically right ones.
- Older layouts use fixed content-band coordinates. Migrate one to
contentTop()when it next misbehaves. compareTabletops out at 3 reason cards and 4 table rows. Wider comparisons need a new layout.- No
addChart()wrapper. Native charts only for real multi-series data; ranked magnitudes go throughbarRank/bridge. - The preview approximates text layout. It's a browser, not PowerPoint —
trust
--checkover the preview's own overflow flags for the final call. - The layout shortlist is tuned on one deck.
planranks candidates by shape and gets the right layout into the top three reliably on the deck it was measured against. Treat a confident single answer with suspicion, and read the verbatim text before choosing.
Versioning
Bump VERSION in wand_kit.js, version in ../manifest.json and the header
of ../STATUS.md together, and say what moved in ../CHANGELOG.md. If a session
hands you back a new zip, replace your local copy — a stale kit builds on stale
geometry and nothing will warn you.
