Skip to content
Agentmart
Submit a tool

d2-slides

Build a slide deck whose source is text and whose figures are laid out by TALA — one Markdown file with a ```d2 fence per figure, compiled to a self-contained…

Skill by hasegama

IndexedMIT
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/hasegama-d2-slides

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Build a slide deck whose source is text and whose figures are laid out by TALA — one Markdown file with a ```d2 fence per figure, compiled to a self-contained HTML deck (keyboard nav, overview grid, print-to-PDF), each figure as its own SVG, and a copy manifest. The deck is a page, so vlmkit's own gates read it: `check integrity` for a slide that breaks or clips, `check copy --manifest` for text the frame cut off, `check a11y contrast` for a projector. Loop: write `deck.md` → build → gates → fix. Use when asked for slides, a deck, a talk, a presentation, a review walkthrough, or a figure-heavy explainer that has to be presented rather than read. Not for one diagram (`d2-diagram`) or a moving figure (`explanatory-animation`).

Use cases: documents, presentations, design, frontend

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Node.js package

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/d2-slides

What's inside

Skill name
d2-slides
Description
Build a slide deck whose source is text and whose figures are laid out by TALA — one Markdown file with a ```d2 fence per figure, compiled to a self-contained HTML deck (keyboard nav, overview grid, print-to-PDF), each figure as its own SVG, and a copy manifest. The deck is a page, so vlmkit's own gates read it: `check integrity` for a slide that breaks or clips, `check copy --manifest` for text the frame cut off, `check a11y contrast` for a projector. Loop: write `deck.md` → build → gates → fix. Use when asked for slides, a deck, a talk, a presentation, a review walkthrough, or a figure-heavy explainer that has to be presented rather than read. Not for one diagram (`d2-diagram`) or a moving figure (`explanatory-animation`).
License
MIT
Instructions
286 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Agent Skills spec issues

  • files: referenced but missing: examples/d2-slides/README.md

Files (3)

  • SKILL.md
  • build-deck.mjs · assets/
  • deck-review.mjs · assets/

SKILL.md (first lines)

# d2-slides

Paths below: `<skill>` is this skill's directory and `<skills>` the directory the skills are
installed in (`skills/` in mizchi/explainer, `.claude/skills/` in a project that installed them).

A deck is text: the prose is Markdown, every figure is a ```d2 fence, and the
build is a pure function of the file. Nothing is dragged, so a slide can be
reviewed in a diff, regenerated after a rename, and — because the output is an
HTML page — **checked**. That last part is the point: a slide deck normally has
no failing state, so nobody notices the bullet the frame cut in half.

```bash
node <skill>/assets/build-deck.mjs deck.md --out built
# ✓ built/index.html: 8 slides, 5 figure(s) laid out by tala, 26 copy lines → built/copy.txt
#   the deck:   built/index.html   → vlmkit check integrity
#   all slides: built/print.html   → vlmkit check copy --manifest, check a11y contrast, print to PDF
```

Requires `d2` with TALA (`d2 layout` must list `tala (bundled)` — see
`d2-diagram` for installing it) and nothing else: the builder has no
dependencies and the deck loads no network resource.

## The deck format

````markdown
---
title: Nothing tells you the picture is wrong
subtitle: two rounds, measured
date: 2026-09-14
---

# Nothing tells you the picture is wrong      ← a lone `#` heading is the title slide

---

## A D2 diagram is a drawing                  ← `##` is a slide heading

- `d2 validate` reads **syntax**              ← bullets; `code`, **bold**, *italic* work
- there is no `--expect`

```d2                                          ← the figure, laid out by TALA
direction: right
write -> check -> facts
```

<!-- notes: what to say out loud -->          ← speaker notes: printed, never on screen
````

- Slides are separated by a line of exactly `---`; a `---` inside a fence is not
  a separator.
- **Bullets plus a figure** lays them side by side; **a figure alone** gets the
  whole stage; a heading alone is a title slide. `> line` is a pull quote, and a
  fence in any other language stays a code block.
- Each slide is a fixed **1280×720 frame**, scaled to whatever screen it is
  shown on. Nothing reflows between a laptop and a projector, which is also why
  a screenshot of slide 4 is the same picture everywhere.

## The loop

```
1. write deck.md                                     prose in Markdown, every figure a ```d2 fence
2. node …/build-deck.mjs deck.md --out built         fails on the first figure that does not compile,
                                                     naming the slide; warns when a slide's prose
                                                     overflows its frame's character budget
3. vlmkit check integrity built/index.html            a slide that breaks, clips, collides or paints nothing
4. vlmkit check integrity built/print.html --viewports 1280
                                                     every slide at once — this is what catches the
                                                     bullet the frame cut off
5. vlmkit check copy built/print.html --manifest built/copy.txt --allow-invisible unknown
                                                     every line of the deck's own text still on a slide
                                                     (add --forbid stale.txt when you are editing a deck:
                                                     the claim you removed must really be gone)
6. vlmkit check a11y contrast built/print.html        readable from the back of the room
7. node …/d2-facts.mjs --from-svg built/slide-NN.svg --expect slide-NN.facts.json
                                                     what each figure DRAWS, for every figure that has
                                                     facts it must not get wrong — steps 3-6 are blind to it
8. node …/deck-review.mjs built --out review           shoot each slide, hand the PNGs to a reader
   node …/deck-review.mjs built --answers a.json      score what it read back: fidelity, order, SPLITs
9. read built/index.html in a browser, or the PNG of a slide; fix the Markdown; go to 2
```

**Step 7 is not optional decoration, and the four page gates do not cover it.**
They read the page: a figure that compiles and draws the wrong thing passes all
four. The checker takes the slide SVGs the build already writes and needs no
`d2` (it reads the render), so this costs one command per figure:

```bash
node <skills>/d2-diagram/assets/d2-facts.mjs --from-svg built/slide-04.svg \
  --expect slide-04.facts.json     # exits 1 and names the box or edge that is wrong
```

The same trick pins **two figures to each other**, which nothing else does: when
slides 2 and 3 both claim `ledger` is the writer, hold *both* SVGs to one sheet
(`{"boxes": ["checkout","ledger"], "deps": ["checkout->ledger"], "forbidden": ["checkout->orders"]}`).
Update one figure and forget the other and that sheet fails on the one you
missed. The fact-sheet schema is `d2-diagram`'s; `exhaustive: true` is what makes
an extra box an error rather than a shrug.

## Step 8: somebody has to read it

Steps 3-7 are the page and the figures' geometry. None of them reads the slide
the way a viewer does, and that gap is not theoretical: in the v1/v2 rounds two
defects reached a **delivered** deck — a sentence rendered as two blocks, and a
fragment sitting above its own bullet — with all four gates green, because
every fragment was visible text and nothing overflowed.

```bash
node <skill>/assets/deck-review.mjs built --out review
#   → review/slide-NN.png, one per slide, plus review-brief.md
#   hand that directory to a vision model or an agent; it answers JSON
node <skill>/assets/deck-review.mjs built --answers review/answers.json
#   read 19/21, invented 6, fidelity 0.70, order 1.00
#   ⚠ SPLIT: "…it calls ledger, which is now the only writer to orders."
#     every word is on the slide, the sentence is not — read back as 2 blocks
```

The scoring is deterministic, against the `slides.json` the build writes: each
slide's text **in reading order** (which `copy.txt` is not — the manifest is a
set, and it lists bullets before paragraphs while the page renders paragraphs

From hasegama/pstack-agents, MIT.

More from hasegama/pstack-agents

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Oct 5, 2026 (24 days ago)
Last release
Oct 5, 2026 (24 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from hasegama

Cite this page

d2-slides skill. Agent Mart. https://agentmart.dev/skills/hasegama-d2-slides (last updated 2026-10-24)