llms.txt · git:20260906.b613c13 · 2026-09-06 · sha256 ad3e62b10980caf5
llms.txt git:20260906.b613c13A
Immutable. This exact content is served forever at /api/v1/blob/ad3e62b10980caf5.
# decklet
> Agent-generated, brand-true, real-time editable presentations and assets — one portable HTML file, no office suite.
decklet is a slide engine for agents. The deck is a JSON model; the renderer is the editor; the output is ONE self-contained .html (no dependencies, no network) a human can drag, retype, present and print. Plain Node >= 22 CLI. Playwright is optional and only used by verify/import-html.
Loop: content + format + style -> model.json -> `node bin/validate.mjs model.json` -> `node bin/create.mjs --model model.json [--style style.json] --out deck.html --format slides|carousel|carousel-4x5|document-letter|document-a4` -> `node bin/verify.mjs deck.html [--refs shots/]` -> hand-off. Revising a deck a human edited: `node bin/edits.mjs deck.html` (read the in-file edit log) -> `node bin/create.mjs --model model.json --out deck.html --from deck.html` (keeps deck/slide/row ids, replays the human's edits — human wins, conflicts reported — and keeps the version history) -> verify. The migrate is the LAST step, never the first.
Formats: slides (960x540 or 1600x900) supported; carousel (1080x1080, 1080x1350) and document (Letter 816x1056, A4 794x1123) experimental (sizing/editing/PDF work; text does not flow across pages).
Model: {w,h,format,styles:{roles,margin,pad},slots,layouts:{name:{slot:{x,y,w,role}}},master:[rows with id],slides:[{layout,bg,hide,els:[rows]}]}. A row is {x,y,w,role,text} plus optional box/tile/bar/line/donut/svg/img/html/anim/nowrap/p/bg/bd/radius/align/color/weight/tt. anim is one of rise|fade|pop|wipe: entrance motion on slide ENTRY, staggered 120ms in model order, off under prefers-reduced-motion and absent from print/PDF/contact sheet/verify (they draw the settled frame); any other value is a validate error. Eight roles (Title,Supertitle,H1,H2,Body,Caption,Label,Stat) are the only source of font/size/lh/ls; rows may not override them (no H3, no Subtitle; Title = display headline for cover/closing slides, H1 = content-slide title). styles.margin is the content inset chrome sits on; master chrome is deck-wide and never varies per layout; a slide override row is partial (only the changed props).
PDF: the ⤓ button writes a true slide-sized PDF inside the file (foreignObject -> canvas -> JPEG -> PDF, zero dependencies; verified in Chromium, Safari unconfirmed -> falls back to print). ⌘P is the paper path: named Letter/A4 pages, one slide per page.
## Files
- SKILL.md: the agent authoring skill — inputs, process, model + style contracts, layouts, master, verification thresholds, anti-patterns, worked examples
- README.md: what/for whom/guarantees/feature matrix/roadmap
- deck.html: the engine with its own explainer deck (12 slides, incl. the motion vocabulary and three inlined GIF clips of the editor) — live at https://grunion-ai.github.io/decklet/deck.html
- docs/demo.gif, docs/demo-poster.png: README demo recording, a build product of deck.html via docs/record-demo.mjs (Playwright + ffmpeg)
- docs/record-clips.mjs: films the three editor clips on the explainer's "filmed" slide from deck.html and writes them into examples/explainer/model.json as data: URIs (Playwright + ffmpeg)
- template.html: the engine with an empty model; create.mjs fills /*DECK*/ /*TOKENS*/ /*TITLE*/ /*KEY*/ markers
- bin/validate.mjs: pure-Node model contract validator (exit 1 on errors; --strict for warnings)
- bin/create.mjs: model (+style) -> deck.html with format presets
- bin/verify.mjs: self-containment + contract + layout parity (always) + AE vs refs (optional); writes results.json
- bin/edits.mjs: prints the human edit log + version history a deck file carries (read before revising)
- lib/edits.mjs: node side of the in-file edit core (stampIds/diffDecks/applyLog lifted from template.html's /*EDITS*/ block; blockOf/putBlock for DECK/LOG/VERSIONS)
- bin/import-html.mjs: HTML pages at a fixed viewport -> model.json (master/slots/roles lifted, Title detected on non-content layouts; _lines intent for parity)
- examples/explainer, examples/quarterly-update, examples/launch-carousel, examples/one-pager: brief.md -> model.json (+ style.json)
- test/gate.test.mjs: node --test gate (engine contract, validator, create, import, live proofs); test/edits.test.mjs (ids, log, migrate, create --from); test/editor.test.mjs (live: nibs, PDF arrows, autosave, position, migrate on load, ⌘S write-back, versions, ⌘B)
- CHANGELOG.md, LICENSE (MIT)