# Writing decks with an agent

> Shared deck-writing guidance for seven agent platforms, thin entry points, Claude Code hooks, and safe init updates.

`decks init` installs shared guidance for Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf and OpenCode. The workflow applies to any project with the package. The rules and skills are ordinary Markdown under `.claude/`, kept there for compatibility. Every agent follows the explicit reading order in `AGENTS.md`; the content is maintained once.

```bash title="Terminal"
bun add slidev-addon-decks @slidev/cli slidev-theme-the-unnamed
bunx -p slidev-addon-decks decks init
bunx -p slidev-addon-decks decks new my-talk --story
# Open your preferred agent in this project.
```

With npm, use `npx -p slidev-addon-decks decks ...`. Then ask your agent for the deck in plain language, for example `make a 5-slide story deck about how ocean tides work`. The bare `decks` name on npm is an unrelated package, which is why every command uses `-p slidev-addon-decks`.

## What `init` installs

- **`deck-author` agent** (`.claude/agents/deck-author.md`) is registered natively in Claude Code and builds or revises one deck per session. Other agents follow its role and the shared workflow directly.
- **`building-a-deck` skill** covers the whole workflow: scaffold, sourcing data, verification, build, and when a deck counts as done.
- **`fact-checking-a-deck` skill** reruns the source behind each figure, using the query or source recorded in the deck's `data-sources.md`, and checks the data arrays, card copy and slide text against the results.
- **Rules** in `.claude/rules/` attach by path in Claude Code when you edit files under your decks directory. They cover slide prose (`deck-writing.md`), layout, charts and theme (`deck-patterns.md`), story stages (`story-stage.md`), data provenance (`deck-data.md`), a catalog of AI writing patterns to avoid (`prose-patterns.md`) and your own terminology (`project-glossary.md`, which starts empty).
- **Claude Code hooks** in `.claude/settings.json`. `decks hook lint` runs before every Edit, Write and MultiEdit and denies deck prose that matches an error-level pattern from the package's pattern list. It also checks the `COPY` arrays in story stages. If the scanner can't run, it refuses the write instead of letting it through. `decks hook prompt` adds a reminder of the writing rules when a prompt asks for deck work. Both are Node scripts behind `.claude/hooks/decks.sh`, a short POSIX `sh` wrapper that `init` writes, so they need no `jq` or bash.
- **Shared entry points.** A marked `AGENTS.md` section lists commands and the required reading order. Codex, Cursor, Windsurf and OpenCode read it directly. `CLAUDE.md` and `GEMINI.md` import it. `.github/instructions/decks.instructions.md` points Copilot at it for files under the configured decks directory. Existing text outside marked blocks is preserved; a colliding Copilot rule is reported and kept.
- **Exemplars.** The skills point the agent at two decks inside the package to read and not edit: `node_modules/slidev-addon-decks/agent/exemplars/tides` (story) and `.../agent-experience` (conventional).

The files are the repository's own agent setup with your decks directory (`decksDir` in `decks.json`, default `decks`), the right runner (`bunx` when you have a bun lockfile, else `npx`) and the installed package path filled in.

Only Claude Code runs the installed hooks automatically. In other agents, run `decks check` and `decks lint` during each edit cycle, and follow the shared screenshot, data review and build requirements before handoff. Init tests cover installation, references, updates and preservation of custom files. Live authoring has not been tested in every listed agent.

## Re-running `init`

`.claude/decks.json` records each file `init` wrote and its content hash. When you upgrade the package, run `init` again:

- A file you haven't edited is updated.
- A file you edited is skipped and reported. `--force` overwrites it.
- A file at one of those paths that `init` didn't write is a collision. It is reported and left alone, even with `--force`. Rename or move it and re-run.
- Settings are merged: nothing you have is removed, and an entry is never added twice.
- A file an earlier `init` wrote that the package no longer ships is removed if you haven't edited it, and kept and reported if you have.
- Marked Decks blocks update in place; `CLAUDE.md` and `GEMINI.md` carry imports rather than duplicate guidance.

To keep a file as your own, delete its entry from `.claude/decks.json`.

If the package isn't installed when you run `init`, it writes the agent files and the instructions block but not the hooks, prints the install command and exits 1. Install the package and re-run `init` to add the hooks; the exemplar paths in the skills resolve once it is installed.

When the hooks are committed but the package is missing (a fresh clone before you install, or after you uninstall it), the write hook refuses writes to deck prose under your decks directory, since it can't lint them, and allows every other write. The prompt hook does nothing. If you stop using Decks, remove the two `decks.sh` entries from `.claude/settings.json`.

## Data provenance

Decks with data-driven charts keep `<deck>/data-sources.md`, mapping slide numbers to the queries behind each number. It is the fact-check's input: a figure on a slide must trace to a query in that file, a `data/*.ts` constant, or a `FLAG: author-reported` row. `decks fact-extract <alias>` lists every figure in a deck.

## A real run

The tides deck on the home page started as one prompt, `make a 5-slide story deck about how ocean tides work`, run with `claude -p` in the Decks repository, which uses the same setup as `init`. The run loaded the `building-a-deck` skill, scaffolded with `bun run new tides ocean-tides --story`, fetched NOAA, US Naval Observatory and NASA sources, and finished with `check`, `test`, `lint` and `build` passing. The deck was then fact-checked and edited by hand. The home page shows an excerpt of that run's transcript.
