Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

plan-html

ASecurity

Interactive decision-deck planning. Same research/design thinking as /plan, but the plan is an interactive HTML deck the user works through in the browser — intent cards and decision cards, answered with buttons OR free text, with per-card questions to the agent — iterated in rounds until finalized. Every answer autosaves, so interruptions lose nothing. Use whenever the user wants to plan, review, or iterate on a plan interactively instead of reading markdown in the terminal.

2 stars
0 votes
0 copies
0 views
Added 9/28/2026
ai-agentspythongobashnodegitsecurity

Works with

terminalcli

Security Analysis

A100/100

Scanned 9/28/2026

Install to Claude Code

$npx -y skills add DoryZi/plan-html --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of plan-html?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for plan-html
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/doryzi-plan-html/badge)](https://www.skillsdirectory.com/skills/doryzi-plan-html)

More formats (shields.io, HTML) on the badges page.

Files
SKILL.md
---
name: plan-html
description: Interactive decision-deck planning. Same research/design thinking as /plan, but the plan is an interactive HTML deck the user works through in the browser — intent cards and decision cards, answered with buttons OR free text, with per-card questions to the agent — iterated in rounds until finalized. Every answer autosaves, so interruptions lose nothing. Use whenever the user wants to plan, review, or iterate on a plan interactively instead of reading markdown in the terminal.
---

<!-- experiment-banner:start -->
> 🧪 **This is an experiment** — part of [**AI Will Replace You**](https://doryzidon.com).
>
> **Stop wasting time on AI. I run practical experiments — real lessons you can use tomorrow, biweekly.**
>
> ▶ **[Watch the demo on YouTube](https://youtu.be/cFwvulWoTE4)** · 📖 **[Read the write-up](https://doryzidon.com/blog/stop-approving-plans-you-didnt-read)** · ✉️ **[Subscribe to the newsletter](https://www.linkedin.com/build-relation/newsletter-follow?entityUrn=7453650303100383232)**
>
> More on [@aiwillreplaceyou](https://youtube.com/@aiwillreplaceyou)
<!-- experiment-banner:end -->

# Plan (HTML / interactive, round-based)

Same goal as `/plan` — research a codebase and design an implementation plan
interactively — but the **review surface is the browser deck, not the
terminal**. The plan is delivered as cards the user answers in place:
**intent cards** (what they want, in their words, editable) and **decision
cards** (forks in the design). Free text counts as a full answer; every card
can carry a question to the agent; rounds repeat until the user finalizes.
The user can also **reshape the plan directly**: add their own intents,
boundaries, decisions, or steps with a "+ Add" button per section, and strike
out any card (✕) to remove it. Added cards come back tagged `userAdded`;
struck cards simply vanish from the round.

## HARD OUTPUT RULES — read first

1. **The deck IS the deliverable. Never print the plan as markdown in the
   terminal.** No plan dumps, no "here's a summary of the plan" walls of text,
   no markdown decision lists. Everything the user needs to read goes into
   `plan.json` and is rendered by the deck.
2. **Terminal output is status lines only**, a few short lines per round:
   what stage you're in, the deck URL, the round number, and (between rounds)
   a one-line note of what changed. Nothing else.
3. **Plans persist.** Write `plan.json` to
   `<repo>/design/plans/<slug>/plan.json` (gitignored — verify; add
   `design/plans/` to `.gitignore` if missing). Never `/tmp`: the sibling
   `answers.json` autosave must survive reboots and be findable after an
   interrupted session.
4. **Never lose user input.** Before starting a round, check for an existing
   `answers.json` next to the plan — if present, the user has prior answers;
   the server preloads them automatically. On a `timeout` result, the
   autosaved answers are in the printed JSON (`saved`) — treat them as a
   partial round, don't discard them.

## Workflow

### Stage 1: Understand (chat, minimal)

Ask only what you need to scope the exploration — a couple of questions max.
The deep interrogation does NOT happen in chat: it happens in the deck
(Stage 3), where answers persist and the user can think. Do not proceed until
the user confirms the task framing.

### Stage 2: Explore (parallel agents)

Spawn explore agents in parallel (single message, multiple `Agent` calls),
sized to scope (1 small → 3–4 large), each returning structured markdown with
file paths and line numbers. Synthesize **briefly** (a few lines, not a
report), confirm with the user, then move on. Detailed findings belong in the
deck's card bodies, not the terminal.

### Stage 3: Design → plan.json

Draft the plan **directly as `plan.json`** (schema below).

**Every plan MUST have a `goal`, `intents[]` with a `verify` per intent, a
plan-level `diagramSvg`, and grill cards — no exceptions.** `boundaries[]` is
optional: include it when the task has real scope risk (things that must not
be touched, cost ceilings, "don't refactor X") and skip it for small
contained tasks. The user can drop any boundary with its "Not needed" button.

- **`goal` — one sentence that shouts what we're building and why.** Rendered
  as a highlighted banner at the top of the deck. If you can't write it in
  one sentence, the plan isn't understood yet.

- **GRILL THE USER — hard, but proportionate.** The round-1 deck must
  interrogate the user: turn every real assumption, ambiguity, and unstated
  requirement into a `needs-you` decision card. Cover (where they genuinely
  apply): who/what uses this, edge cases, failure modes, cost/limits,
  security, what NOT to build, and what "done" looks like. Challenge the
  user's framing when you disagree — present the conflict as a card with your
  counter-position in `building`/`tradeoffs`. If an answer comes back vague,
  re-ask it sharper in the next round; don't build on a vague answer.
  **Scale the grilling to scope and risk**: a contained task earns a handful
  of sharp cards, not an inquisition — never manufacture questions to fill
  the deck.

- **The loop must converge — balance looping against finishing.** Every
  round should shrink the open set, not grow it sideways. New cards in round
  N+1 are justified only by the user's answers or by re-exploration findings
  — not by second-guessing settled cards. When nothing real is left open,
  say so in the round-status line and let the user finalize; aim to be
  finalize-ready by round 2–3 for most plans. One round straight to Finalize
  is a success, not a shortcut.
- **`intents[]` — the spine of the plan.** An intent is **one outcome the
  user wants + why + how we prove it's done** — written in the user's own
  words (first person works well: "I want my answers to survive an
  interruption"). It is NOT a feature list and NOT an implementation step;
  if you can't attach a binary `verify` (method + exact command + expected
  result) to it, it's not an intent yet — sharpen it. Intents replace
  acceptance criteria; they are user-editable in the deck, so write them to
  be edited.
  - **Grill clarifying questions ON the intent (`agentQuestions[]`).** When an
    intent is fuzzy, attach pointed clarifying questions directly to it — who
    uses it, what "done"/"revert"/"approve" concretely mean, edge cases — and
    the deck renders them as an in-card checklist the user answers inline.
    Prefer this over spinning up a separate `needs-you` decision when the
    ambiguity is *about the intent itself*; use decision cards for genuine
    forks in the design. Answers come back in the round under the card's
    `grill[]` (each `{id, q, answer}`) — read them and tighten the intent (and
    its `verify`) next round. Soft-gated: unanswered grill questions are
    surfaced and counted but do NOT block Finalize.
- **`boundaries[]` — the fence (optional, shown after the intents).** What's in
  scope, what's out of scope, and what must not be touched. One boundary per
  card, written as a testable statement. When present, boundaries gate
  Finalize — the user must agree to each, rewrite it, or drop it.
- **Diagrams are REQUIRED.** Every plan ships a plan-level `diagramSvg`
  (architecture/flow of what's being built). Additionally, any intent or
  decision that describes structure, flow, or sequence gets its own per-card
  `diagramSvg` — if prose is explaining a shape, draw the shape instead.

  **Diagram authoring rules (the deck styles these classes — use them):**
  - `class="node"` boxes (bright blue). Color-code stages with the variants
    `node alt1` (teal), `node alt2` (amber), `node alt3` (purple),
    `node alt4` (rose) — e.g. inputs teal, processing blue, outputs amber.
  - Titles use `class="node-label"` (white, bold); secondary lines use
    `class="node-sub"` (light blue) — never invent your own fills/colors.
  - Edges: `class="edge"` with `marker-end='url(#arrow)'`; label them with
    `class="edge-label"` where the flow isn't obvious.
  - **Size the viewBox to the content** — ~20px of padding around the
    outermost shapes, no oceans of empty space. Nodes ~140×48 with ~60px
    horizontal gaps read well.

- **UI work gets mocks — always, no exceptions.** Any decision about a
  screen, page, layout, component, or visual flow MUST present **2–3
  alternative mocks as its options** — the user picks a design by clicking a
  mock, not by imagining one from prose. Use option objects (see schema):
  `{"label", "caption", "html", "width", "height"}` for **hi-fi HTML mocks
  (default — prefer these)**, or `{"label", "caption", "viewBox", "svg"}` for
  lo-fi SVG wireframes (fallback only). The deck renders `html` inline in a
  sandboxed, auto-scaled, zoomable iframe.
  **Inline only — NEVER as files.** Do not write mock `.html`/`.png` files to
  disk, do not send mocks as attachments, do not link out. If a visual is not
  inside the deck card, it does not count as delivered. Mock decisions
  automatically render in their own prominent **"🎨 Design mocks"** section
  near the top, expanded by default — you don't need to do anything beyond
  using option objects.

  - **MOCKS MUST LOOK LIKE THE PRODUCT WE ALREADY HAVE — this is the rule
    that matters most.** A mock that doesn't resemble the real app is worse
    than no mock: the user can't judge a layout that looks nothing like what
    they'll get. Before authoring any mock, the explore stage MUST have
    captured the app's actual look — its CSS custom properties / theme tokens
    (colors, radius, spacing), its real component classes (cards, tables,
    badges, buttons), and its font. **Default to hi-fi HTML** that pastes
    those real tokens into a self-contained `<style>` block and reuses the
    real class names and component shapes, so the mock is visually
    indistinguishable from a real screen of the app. If the app is dark, the
    mock is dark; if cards have a 1px `--border` and 8px radius, so does the
    mock. Populate with realistic sample data, not lorem/placeholders.
  - **HTML mock authoring (the default path):**
    - Self-contained `<!doctype html>` with an inline `<style>` — no external
      CSS, fonts, or scripts (the iframe is sandboxed and offline).
    - Copy the app's `:root{--…}` tokens verbatim and build with them; reuse
      the real component class names so the mock reads as the real UI.
    - Set `width`/`height` to a realistic screen size (e.g. `900×600`); the
      deck scales it down to fit. Author at full size — don't pre-shrink.
    - Same `width`/`height` across the 2–3 alternatives so they compare
      like-for-like; vary only the layout being decided.
  - **SVG wireframe fallback (only when there's no app look to match yet,
    e.g. a brand-new product with no styling):** lo-fi and blocky on purpose
    — `wf-frame` for the screen/panel outline, `wf-box` for outlined regions,
    `wf-fill`/`wf-accent` for the regions being decided, `wf-bar` for
    text-line placeholders, `wf-text` for region labels, `wf-note` for small
    annotations. Only these classes — no custom colors. Sizing discipline is
    mandatory or text overflows the frame (the common failure): keep ALL
    shapes and text strictly inside the `viewBox`; leave ~14px padding inside
    `wf-frame`; keep `wf-text` strings short (truncate, don't let them run
    past the box edge) and never start text near the left/right margin where
    it will clip. Same viewBox across the alternatives (~`0 0 200 140` for a
    screen, wider for dashboards).
  - Label every meaningful region so the differences between the 2–3 mocks
    are obvious at a glance; the `caption` states the tradeoff in one line
    ("denser, scales to 100 items" vs "calmer, 10 items max").
  - Mocks can sit alongside plain-string options on the same card (e.g. a
    third option "None of these — see my notes").
- **`decisions[]` — the forks.** Any place the design could go more than one
  way: approach, library, boundary, what to defer, how much freedom the agent
  gets. Mark `needs-you` vs `agent-call` vs `fyi`. Use `dependsOn` to link a
  decision to the intents/decisions it hangs off — the deck shows the user
  their own answers on linked cards.
- **`steps[]`** — numbered implementation steps, each tagged with the intent
  it serves. Steps are derived: when a round changes an intent or decision,
  update the steps to match — they reshape every round and only lock at
  finalize. **Steps are now editable and deletable in the deck** like any
  card: the user can rewrite a step's fields in place, strike it out (✕) to
  delete it, or add their own. **The user's step edits are authoritative** —
  an edited step comes back with `userEdited: true` and its full `draft`;
  keep the user's wording, don't silently regenerate or override it. A step
  struck out is gone (absent from the round). You may still re-derive *other*
  steps when an intent/decision changes, but leave the user's edited/added
  steps as they set them unless their own answers force a change.
- **`finalVerify[]`** — the plan-level gate: for each intent, how the whole
  feature is proven end-to-end once built. **Editable in the deck** — the user
  can edit any row (intent / method / command / expected), add rows, or delete
  them. The edited rows ride back in the round as `finalVerify[]`; treat them
  as authoritative (keep the user's commands/expectations) and reconcile the
  plan's `finalVerify` to match. A new round reseeds the table from your
  updated plan.

### Stage 4: Serve LIVE — answer questions in place, no restart

**Default to live mode.** The deck stays open and you stay in a loop beside
it: the user can ask a question and get the answer **streamed back into the
same open page** — no close, no re-serve. The plan file is the single source
of truth; the page is a live view of it (SSE), and you keep it current.

1. **Serve in live mode — ALWAYS in the background:**

   ```bash
   # ${CLAUDE_PLUGIN_ROOT} resolves to this skill's install dir (plugin install).
   # If you cloned manually instead, use that path, e.g. ~/.claude/skills/plan-html
   python3 "${CLAUDE_PLUGIN_ROOT:-$HOME/.claude/skills/plan-html}/serve_plan.py" \
     --plan <abs-path>/design/plans/<slug>/plan.json --live
   ```

   **Run it with `run_in_background: true` — never foreground.** A
   foreground-blocking serve owns your turn, so the user can't type to you in
   the terminal until it yields. Background-serving keeps both channels open at
   once: the user types into the deck (autosaved + streamed to you) AND can
   still message you in the terminal. Poll the background server's output file
   for events between turns; don't block on it.

   **Stable port for tunnels (`--port`).** By default the server picks a random
   free port, so a `cloudflared` URL dies whenever the deck restarts. If the
   user is on a tunnel and you'll be restarting the deck (e.g. iterating on the
   template), pass `--port <fixed>` so the same tunnel URL keeps working across
   restarts. Otherwise omit it.

   **Don't miss the final event.** On **Finalize**/**Send to agent** the deck
   POSTs the round and the browser shows a "handed back to the agent — you can
   close this tab" page (it can't reliably close a user-opened tab, so the page
   IS the signal, not an auto-close). Because the server runs in the background,
   that round lands in the output file — actively pick it up. If a user says
   "I finalized but nothing happened," the round is in the server's stdout/log;
   read it and proceed.

   The deck opens; every user change autosaves to `answers.json`. The server
   prints a JSON line **per event** to stdout (it does NOT exit on the first
   one):
   - `{"action":"ask","id","cardId","text"}` — a live question (also queued in
     `questions.json`).
   - the full round object on **Send to agent** / **Finalize plan**.
   - `{"action":"timeout",...}` if the idle timeout hits.

   **Grill request.** The intents section has an "Interview me to sharpen
   these intents" button. Clicking it sends an `ask` with
   `cardId:"__intents__"` and a `text` starting `[GRILL REQUEST]`. When you see
   it: write pointed `agentQuestions[]` onto the fuzzy/ambiguous intents (not
   every intent — only ones that genuinely need clarifying), bump `rev`, and
   write `plan.json`. The questions stream into the cards over SSE; the user
   answers inline and the answers come back as `grill[]` (see `agentQuestions`
   under intents). This is grilling on demand — the user pulls it when they
   want it, instead of you front-loading questions on every intent.

   **Optional public tunnel (on demand).** The deck binds `127.0.0.1` by
   default. If the user asks to share it / open it on their phone / "open a
   tunnel" **while a deck is already running**, start a `cloudflared` quick
   tunnel as a SEPARATE background process pointed at the live port — do NOT
   restart the server (that would not lose answers, but it's needless churn and
   changes the port):

   ```bash
   cloudflared tunnel --url http://localhost:<live-port> --no-autoupdate
   ```

   Grep its log for the `https://<random>.trycloudflare.com` URL and paste it
   to the user. The tunnel is ephemeral (URL changes each run, no account
   needed) and stays up until you stop the `cloudflared` process — stop it when
   the plan is done. (`ngrok http <port>` is an alternative if `cloudflared`
   isn't installed.)

2. **Arm a persistent Monitor the instant you serve — this is MANDATORY, not a
   poll.** Every deck event (ask, clarification, finalize, send-round, timeout)
   arrives on the server's stdout the microsecond it happens. Do NOT poll the
   output file between turns — that is what makes a question sit "queued — no
   agent is watching." Instead, the moment the background server is up, attach a
   **persistent Monitor** to its output file so each event wakes you instantly,
   with zero polling — the same instant path finalize already rides:

   ```
   Monitor(persistent: true, command:
     tail -n0 -f <server-output-file> |
       grep -E --line-buffered '"action": ?"(ask|finalize|send-round|timeout)"')
   ```

   With the Monitor armed, asks, clarifications and finalize are all delivered
   one uniform way, instantly. The deck shows an "agent is replying…" spinner on
   Send; if no reply lands in ~25s it flips to "no agent is watching this deck
   right now" — with the Monitor running, that state should essentially never
   appear. If it does, your Monitor died: re-arm it.

   **For each `ask` event — answer DURABLY (write the plan), then optionally
   paint fast (SSE push):**
   - Find the card by `cardId` and append to its `thread`:
     `{"role":"user","text":<their question>}` then your
     `{"role":"agent","text":<answer>}`.
   - Apply any plan change the answer implies (revise options, edit an intent,
     add/remove a card, redraw a diagram, reorder).
   - Bump `rev` and **write `plan.json`. This is the source of truth and the
     ONLY reliable delivery.** The server pushes the new plan over SSE and the
     page reconciles in place; crucially, the server also re-sends the full plan
     on every SSE (re)connect — so an answer written to the plan **survives a
     dropped mobile connection and reappears on reconnect.** An answer that is
     not in the plan is lost if the user's stream blipped (common on phones/
     tunnels). Never rely on the push alone.
   - **Optional instant paint:** you MAY also `POST /answer {cardId, text}` to
     stream the reply into the card a beat sooner. This is a nicety on top of the
     plan write, never a substitute — if you skip the plan write, a reconnect
     shows "still queued" forever even though you "answered."
   - Keep the Monitor armed until a `send-round`/`finalize`/`timeout` event.

   The user can keep working on other cards while you answer one — only the asked
   card shows a "thinking…" state. Don't block the whole plan on one question.

   **If an `ask` lands while you're busy elsewhere:** nothing is lost — it's
   queued in `<plan-stem>.questions.json` and the Monitor still fires. Pick it
   up; writing the plan delivers the answer (and heals any "queued" state) the
   moment the page next has the plan.

3. **On `send-round` / `finalize` / `timeout`** — proceed exactly as the
   round rules below describe. (Live answers and rounds coexist: live handles
   "answer my question now"; a round handles "I've answered a batch, process
   them.")

#### Round handling (also used by live edits)

2. **Read the printed round**
   (`{"action", "round", "agentActions", "cards":[...], "finalVerify":[...]}`).
   `finalVerify` carries the user's edited finish-line rows — reconcile your
   plan's `finalVerify` to match them.

   First check `agentActions` — the user's global requests for the next round:
   - `reexplore: true` — **re-run the exploration agents before answering
     anything**, then update affected cards (and say in one status line what
     changed in the code since last look).
   - `note` — free-text instruction for the next round; honor it.

   Cards arrive in the user's **priority order** (they drag-reorder by the ⠿
   grip): `cards[]` is sorted top-first and each carries `priority` (0 = most
   important within its section). Build in that order; let it set what you
   tackle first.

   **Struck-out cards are GONE — absent means removed.** When the user strikes
   a card (the ✕) it is dropped from the round entirely: it will NOT appear in
   `cards[]`. So a card you sent last round that is **missing this round was
   removed by the user** — drop it from the plan, don't re-add it, don't re-ask
   it. (You lose the "why" — accept the user's call.)

   **User-added cards arrive with `userAdded: true` and a `draft`.** The user
   created this card in the browser and may have filled it in fully or
   partially (`draft` holds whatever they typed: title, intent/boundary text,
   verify, options, status, step fields). **Promote it into the plan** as a
   real card next round: keep the user's content, complete what's missing
   (write a proper `verify` for an added intent, draw a diagram if it has
   structure, normalize options for an added decision), and give it a stable
   id. Treat the user's draft as authoritative intent — fill gaps, don't
   override.

   Then, for each card:
   - `choice` — a button pick (`approve` / `reject` / `agent` / a custom
     option label / a mock label). `null` is fine if `answer` has text:
     **free text is a full answer**, treat it with the same weight as a
     button. (The user can pick any text choice straight from the collapsed
     card via inline quick-answer buttons — same `choice` either way.)
   - `answer` — the user's own words: detail, redirect, or a standalone
     answer. Always read it; it overrides/refines the button.
   - `question` — the user needs an answer before deciding. **Answer it in
     the card's `thread`** (see below), don't make them dig in the terminal.
   - `thread` — the card's Q&A history (`[{role,text},…]`), present only when
     the card was discussed. **This is the reasoning behind the answer**: the
     questions the user asked and the answers given. Read it before acting on
     `choice`/`answer` — a pick often only makes sense given the discussion, and
     on finalize this is the record of WHY each decision went the way it did.
   - `edit` — the user rewrote an intent or a boundary in place. Replace the
     card's text with their version (and adjust dependent decisions/steps/
     verify if the rewrite changes scope). An edited boundary is the user
     re-drawing the fence — re-check every step still fits inside it.

   **Keep the title in sync with the content.** A card's `title` is just a
   short handle — when discussion, an `edit`, a `question`, or your own rework
   changes what a card is actually about, **rewrite its `title` (and `summary`)
   to match.** Don't leave a stale title describing the old meaning. This
   applies to intents, boundaries, decisions, and steps alike: if the content
   moved, the title moves with it. (The deck reconciles the new title live over
   SSE, so the user sees it update in place.)

3. **If `action` is `"send-round"`** — iterate:
   - For every `question`, append to that card's `thread`:
     `{"role":"user","text":<their question>}` then
     `{"role":"agent","text":<your answer>}`.
   - Apply redirects: rejected decisions get reworked (new options or a
     changed design), edited intents get updated, ripple changes through
     steps and verify blocks.
   - Bump `"round"` by 1, write the updated `plan.json`, print **one line**
     saying what changed, and re-serve (step 1). The user's prior answers
     reload automatically; their delivered questions are cleared.

4. **If `action` is `"finalize"`** — briefly restate (2–4 lines max) what was
   decided where it diverged from your defaults, then proceed to build (or
   hand to `/dev-cycle`). Do **not** re-dump the plan.

5. **If `action` is `"timeout"`** (exit code 1) — the user stepped away.
   Their partial answers are in `saved` and on disk. Say so in one line and
   stop; on the next session, re-serve the same plan — nothing is lost.

6. **More questions after finalize? Re-open the deck — never ask in the
   terminal.** Finalize locks the plan, but building often surfaces forks the
   plan didn't cover. When that happens: set `"followUp": true`, bump
   `round`, add ONLY the new `needs-you` cards (keep the locked sections for
   reference — don't re-open settled decisions), and re-serve. The deck shows
   a follow-up banner and the Finalize button becomes **"Resume build"** —
   in follow-up rounds only the new `needs-you` cards gate it; settled
   intents/boundaries stay locked and don't re-gate. (A follow-up intent or
   boundary can be marked `"status": "needs-you"` to gate again.)
   When the answers come back, continue building. Repeat as often as the
   build demands — a follow-up round is cheap; building on a guess isn't.

## plan.json schema

```jsonc
{
  "title": "Feature title",
  "slug": "feature-slug",                       // stable id; also the dir name
  "task": "the original request",               // optional
  "date": "YYYY-MM-DD",                          // optional
  "round": 1,                                    // bump on every re-serve
  "rev": 0,                                       // bump on every LIVE write so the open deck reconciles
  "followUp": false,                             // true = post-finalize round: new questions from the build
  "summary": "1–2 sentence what-and-why (markdown ok)",
  "goal": "REQUIRED — one sentence: what we're building and why, shown as a banner",

  "boundaries": [                                // optional — the fence, shown first when present
    {
      "id": "boundary-scope",
      "title": "Only the skill files change",
      "boundary": "In scope: the three skill files. Out of scope: everything under `src/`. Do **not** add new dependencies. (markdown ok)",
      "thread": []                               // Q&A history, optional
    }
  ],

  "intents": [                                   // REQUIRED — the spine, replaces AC
    {
      "id": "intent-persist",
      "title": "Answers survive interruptions",  // short card title
      "intent": "I want every answer I give to survive a closed tab, a timeout, or a reboot. (markdown ok)",
      "verify": { "method": "e2e", "command": "…exact command…", "expected": "…observable result…" },
      "agentQuestions": [                          // optional — grill the user to sharpen this intent
        { "id": "scope", "q": "Does *every* answer include drag-order, or just card picks? (markdown ok)" }
      ],                                           // answers come back as grill:[{id,q,answer}] on the round
      "thread": [ {"role":"user","text":"…"}, {"role":"agent","text":"…"} ]  // Q&A history, optional
    }
  ],

  "decisions": [
    {
      "id": "round-trip",
      "title": "How decisions return to the agent",
      "status": "needs-you",                     // needs-you | agent-call | fyi
      "summary": "one line shown on the collapsed card",
      "building": "what we're building for this decision (markdown ok)",
      "tradeoffs": ["**option A**: …", "**option B**: …"],   // optional, markdown ok
      "verify": "how we'll prove this was right",            // optional, string or {method,command,expected}
      "options": ["Blocking server", "Watched file"],        // optional; replaces Approve/Reject/Your-call
      // UI decisions: options are mock objects instead — the user clicks a mock to pick it.
      // These cards auto-render in the dedicated "Design mocks" section, expanded, zoomable.
      // PREFER hi-fi HTML that reuses the real app's theme tokens + component classes,
      // so the mock looks like the product. Same width/height across alternatives.
      // "options": [
      //   {"label":"Sidebar", "caption":"nav left, content right",
      //    "html":"<!doctype html><html><head><style>:root{/* paste app tokens */}…</style></head><body>…full mock reusing real classes…</body></html>",
      //    "width":900, "height":600},   // rendered inline, sandboxed, scaled, zoomable
      //   {"label":"Top tabs", "caption":"full-width content", "html":"…", "width":900, "height":600},
      //   // SVG wireframe is the lo-fi FALLBACK (only when there's no app look to match):
      //   {"label":"Lo-fi", "caption":"blocky wireframe", "viewBox":"0 0 200 140",
      //    "svg":"<rect class='wf-frame' x='4' y='4' width='192' height='132'/>…keep all text inside the box…"}
      // ],
      "dependsOn": ["intent-persist"],                       // optional; linked cards shown with the user's answers
      "thread": [],                                          // Q&A history, optional
      "diagramSvg": "<rect class='node' …/>…",               // optional per-card diagram (intents too)
      "diagramViewBox": "0 0 720 240"
    }
  ],

  "steps": [                                     // read-only reference
    { "title": "Step title", "description": "what it does (markdown ok)",
      "files": "path/to/file", "test": "e2e", "intent": "intent-persist" }
  ],

  "finalVerify": [                               // plan-level gate, one row per intent
    { "intent": "intent-persist", "method": "e2e",
      "command": "…exact command…", "expected": "…observable result…" }
  ],

  "diagramSvg": "<rect class='node' …/>…",       // REQUIRED — plan-level architecture/flow diagram
  "diagramViewBox": "0 0 720 240"                // optional
}
```

The deck also sends a global `agentActions` object with every round:
`{"reexplore": bool, "note": "free text"}` — the user's standing panel for
"re-explore the code before answering" and any other next-round instruction.

Notes:
- All prose fields render **markdown** (bold, italic, `code`, fenced blocks,
  bullet lists, links) — format the plan properly; don't write flat text.
- Boundary cards (when present), intent cards, and `needs-you` decisions
  **gate Finalize**; a card is satisfied by a button pick OR free text OR an
  in-place edit. Open questions also block Finalize (they must be answered in
  a round first). A boundary answered "Not needed — drop it" is removed from
  the next round's plan.
- `options` reads better than Approve/Reject when the decision is a concrete
  pick between named approaches.
- The diagram is hand-authored inline SVG (same node/edge classes as before).
  No mermaid, no CDN.

## Rules

**DO:**
- Run the same understand → explore → design stages as `/plan`; only the
  output surface differs.
- Grill hard in round 1: every real assumption becomes a card; vague answers
  get re-asked sharper, never built on — but scale it to scope, and never
  invent questions to keep the loop alive.
- Converge: each round shrinks the open set; when nothing real is left,
  recommend Finalize instead of another round.
- Always include `intents[]` (one outcome + why + verify each) and a
  plan-level diagram; add `boundaries[]` whenever scope needs a fence.
- Draw, don't describe: per-card diagrams for anything with structure, flow,
  or sequence — and 2–3 clickable wireframe mocks for every UI/layout
  decision, without being asked.
- Honor `agentActions` every round — `reexplore` means re-run the explore
  agents before answering anything.
- Treat agreed boundaries as binding: if a later round would cross one,
  raise it as a new decision — don't silently widen scope.
- Surface every real fork as a decision with tradeoffs; link related cards
  with `dependsOn`.
- Answer every user question in the card's `thread` on the next round.
- Keep each card's `title`/`summary` in sync with its content — when the
  meaning changes, rewrite the title; never leave a stale handle.
- Serve in the background (`run_in_background: true`) so the user can type to
  you in the terminal AND into the deck at the same time.
- Start a `cloudflared` tunnel on demand (against the live port, no restart)
  when the user wants the deck public / on their phone.
- Use `uv run --directory` to launch `serve_plan.py` (per CLAUDE.md).

**DON'T:**
- Print the plan, findings, or decision lists as markdown in the terminal —
  the deck is the only plan surface.
- Auto-advance stages without approval, or skip the understanding phase.
- Write production/test code — that's the build phase's job.
- Mark a real fork `agent-call` just to avoid asking — if it changes what you
  build and you have no clear default, it's `needs-you`.
- Add external CDNs/scripts to the deck — it must open offline.
- Write mock files to disk or send mocks as attachments/links — every visual
  renders inline in the deck (svg/html options, diagrams), full stop.
- Discard or overwrite `answers.json` — it's the user's work.

Attribution

DoryZiDoryZi
View sourceMore from DoryZi →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1074701 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

695601 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

691 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →