---
name: Deck
description: Use to draft and revise a presentation outline the operator can see and steer — slides with a title, bullets, speaker notes and an image, kept as decks/<name>.deck.json and opened in the Deck app for reordering, inline edits and a full-pane present mode.
tagline: Build a presentation together: your agent drafts the slides, you reorder and refine them.
version: 1
situations: write me a deck, make a presentation, slide deck, pitch deck, outline these slides, reorder the slides, speaker notes, make slide 4 punchier, board update deck, present this, add a slide
requires-secrets:
requires-packages:
---

# Deck

## Why a screen

A deck is judged by order and rhythm, not by prose: the operator has to *see* eight slides at once to
know that slide 4 is flabby and that 6 belongs before 5. So you write `decks/<name>.deck.json`, they
watch the outline redraw, and they answer by dragging a card, fixing a title in place, or clicking a
slide and saying "punchier" — none of which is a paragraph they had to type.

## Where the file lives

One deck is one file: **`decks/<name>.deck.json`**. Images it points at live under
**`decks/assets/`** (where the app saves anything the operator drops on it) or **`files/`** (where
generated images land). Nothing else is touched.

The **New deck** button on the New Session screen seeds `untitled.deck.json` **at the workspace
root** — a scaffold may only name a plain filename. Your first move in that session is to move it
where it belongs: read it, write it to `decks/<slug>.deck.json`, delete the root copy, and tell the
operator the path. The app only reads `decks/**`, so a deck left at the root is invisible to it.

## The format

```json
{
  "version": 1,
  "title": "Harbor — launch review",
  "theme": "dark",
  "slides": [
    {
      "id": "s1",
      "title": "Harbor",
      "bullets": ["Launch review", "12 March, 30 minutes"],
      "notes": "Say the date out loud — half the room thinks this is next quarter.",
      "layout": "title"
    },
    {
      "id": "s3",
      "title": "How it works",
      "bullets": ["One inbox for every channel", "Rules run before a human sees it"],
      "notes": "Walk the diagram left to right.",
      "image": "decks/assets/flow.png",
      "layout": "split"
    },
    {
      "id": "s5",
      "title": "The room on launch day",
      "bullets": [],
      "image": "files/launch-room.png",
      "layout": "image"
    }
  ]
}
```

| field | rule |
|---|---|
| `version` | the number `1`. |
| `title` | the deck's name. Shown in the app header and on the title slide. |
| `theme` | optional, `"light"` or `"dark"`. A hint for whoever renders it later; the app wears the window's theme regardless. |
| `slides[].id` | a short stable string, unique in the file. **Keep an id stable across edits** — it is how the operator's selection survives your rewrite. |
| `slides[].title` | one line. This is what the operator edits in place. |
| `slides[].bullets` | an array of strings. Plain text, no markdown, no HTML — the app renders text and only text. |
| `slides[].notes` | optional speaker notes, one paragraph. |
| `slides[].image` | optional **workspace-relative path** under `files/**` or `decks/assets/**`. Never a URL, never absolute, never `../`. The app reads the bytes over the bridge; a path outside those folders draws as "outside this app's folders". |
| `slides[].layout` | optional: `"title"`, `"bullets"`, `"image"` or `"split"`. Defaults to `"bullets"`. `"split"` is bullets beside the image; `"image"` is the image alone with the title. |

Unknown fields are preserved — the app rewrites the file by editing the object it parsed, so anything
extra you keep in there survives a reorder.

## The loop

1. **You write the file.** Whole-file writes with the `write` tool; keep it pretty-printed with two
   spaces so a diff is readable.
2. **They steer in the app.** The Deck app is in the agent's Apps list. It lists every
   `decks/*.deck.json`, draws each slide as a card, and lets them reorder by drag or by the ▲/▼
   buttons, retitle a slide in place, attach a dropped image, and press **Present** for a full-pane
   run-through with the arrow keys.
3. **You read their edits back.** Before you touch a deck again, **re-read the file**. The order in
   `slides` and the text in `title` may not be what you last wrote — the operator moved a card or
   fixed a word, and the app wrote it. Treat what is on disk as the truth and diff it against what
   you remember out loud if it matters ("you moved *Risks* ahead of *Numbers* — keeping that").
4. **They click a slide to talk about it.** That prefills their composer with the slide named
   (`slide 4: Numbers that matter`) and the slide's own text attached, so the message you get is
   short and the context is exact.

## "Make slide 4 punchier"

That request arrives with the slide already attached as the selection. Do this:

- **Count from 1, in file order.** "Slide 4" is `slides[3]` of the deck named in the message — and of
  the file *as it is on disk right now*, which may have been reordered since you wrote it. Re-read
  first, every time.
- **Punchier means fewer words, not fewer facts.** Cut a bullet to six words or under, put the verb
  first, drop the qualifier ("we think we can" → "we can"), and never invent a number that was not
  already there.
- **Change that one slide.** Write the whole file back with only `slides[3]` different: same `id`,
  same `image`, same position. A "punchier" edit that quietly renumbers or drops a neighbour is the
  fastest way to lose their trust in the app.
- **Say what you cut**, in one line, and let them look: "Slide 4: three bullets became two, dropped
  the Q1 caveat — it is in the notes now."

The same shape answers "shorter", "warmer", "less jargon", "split this into two slides" (add one
slide *after* it with a fresh id, and say so).

## Images

- Reference by workspace-relative path only: `decks/assets/<name>.png` or `files/<name>.png`.
- Anything the operator drops on the app lands in `decks/assets/` and is attached to the slide that
  was selected — so a path you did not write may appear in the file. Keep it.
- Generated stills land in `files/`; point at them where they are rather than copying them.
- No URLs. The app has no network and the image will simply not draw.

## Never

- **Never put HTML or markdown in `title`, `bullets` or `notes`.** The app renders text nodes, so
  tags arrive as literal angle brackets and the deck looks broken.
- **Never rewrite the whole file to change one slide's wording**, in the sense of regenerating ids
  and order. Same ids, same order, unless they asked.
- **Never write outside `decks/`.** The app can only read `decks/**` and `files/**`.
- **Never assume the order you last wrote.** Re-read before every edit.
- **Never delete a deck** because a new one supersedes it. Ask.

## Suggest the app

When they say anything about *seeing* the deck, the *order*, "does this flow", "which slide is
weak", or when they have asked for more than two wording changes in a row: "Open the Deck app — drag
the cards around and click any slide to tell me what to fix. I will keep the file in step."
