Releases: EveryInc/hands-on-deck
deckhand 2.0.0 — the create path
deckhand 1.x edited decks. deckhand 2.0 designs them.
The create path: write the slide as a webpage
Agents are bad at inventing slide layouts shape-by-shape — and world-class at HTML/CSS. html2patch.py closes that gap: the agent writes the slide as HTML, a headless browser renders it purely as a measuring engine, and every measured box and computed style compiles into an ordinary deck.py patch.
python html2patch.py slide.html --deck deck.pptx --layout Blank -o patch.json
python deck.py deck.pptx apply patch.json -o out.pptx --render img/The output is a patch, not a second file format — and that's the whole architecture:
- One writer. A compiled slide is born with the same shape ids, lint coverage,
fixloop, anddiffas any edit. The agent can nudge one box seconds after creating it, with an ordinary op. - Creates into your template. The patch can
add-slidewith a layout from your branded master and place the HTML-measured shapes onto it. Free-form design inside an existing deck — the thing generate-a-new-file architectures structurally cannot do. - Drift is caught, not hoped away. Browsers and PowerPoint wrap text slightly differently; the post-apply linter re-measures the real deck and reports any overflow with the exact fix.
- Compiled, not approximated. CSS gradients → native gradient fills. Tables keep per-cell fills and measured column widths.
object-fit: cover→ a true picture crop.<ol>numbers, rotation rotates,text-transformapplies, CSS padding → text insets, partial borders → accent lines,writing-mode→ vertical text.
Stress-tested against the browser pixel-by-pixel across five fixture suites, and head-to-head against the best-known HTML-to-PPTX engine on its own constraint set: closer to the browser's render (RMS 24.3 vs 29.5) — and where that engine reported success while silently dropping an entire table and garbling nested lists, deckhand carried both.
Design record: docs/html2patch-spec.md. Clean-room implementation — no code shared with any other HTML-to-PPTX tool.
deck.py grew the keys the compiler needed (yours to use too)
set-style/add-shape:insets:[l,t,r,b](text-frame margins in inches),adjustments:[…](true corner radii),shadow:false(kills the theme's inherited drop shadow, including theeffectRefsome renderers apply anyway),fill:"none"(hollow shapes)add-picture:crop:[l,t,r,b]source fractions — fill a box without distortionadd-table:name,color,fill/ per-cellfillsgrid,col_widths,first_row:false+banding:falseto neutralize theme table styling- Text model:
bullet:"number"for auto-numbered paragraphs alongsidebullet:true - Lint fix: explicit zero text-frame margins no longer treated as "unset" (falsy-zero bug that caused phantom overflow reports)
Upgrading
No breaking changes to existing ops — 2.0 marks the new creation surface, not a compatibility break. The create path needs one optional extra: pip install playwright && playwright install chromium. Core deckhand stays pip install python-pptx Pillow.
25 end-to-end tests, CI on ubuntu with LibreOffice + Chromium.
🤖 Generated with Claude Code