# Feature Plan

> Turns a feature concept into a single self-contained interactive HTML planning artifact.

- Skill: `peppesilletti/feature-plan` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add peppesilletti/feature-plan`
- Raw SKILL.md: https://api.skillmd.com/api/skills/peppesilletti/feature-plan/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: peppesilletti (https://skillmd.com/u/peppesilletti)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/peppesilletti/feature-plan

---


# feature-plan

Produce **one self-contained HTML artifact** that makes a feature plan graspable at a glance and grounded in the user's actual codebase. This skill **plans only** — it stops at a rendered artifact. It does not implement the feature.

The skill ships two things you build from:

- `template.html` — a fixed scaffold. You fill its `{{TOKENS}}` and comment-delimited slots; you do **not** restyle its design.


## Inputs (sources)

Each section can be *seeded* from a source if one is supplied, else *autogenerated* from the concept:

| Section | Seed from, if present | Else autogenerate from |
|---|---|---|
| §1 interaction mock | the concept doc / brief | the concept |
| §2 story map | an MCP board (Miro, FigJam, …) or a doc | the concept |
| §3 architecture | an ADR / design doc | the concept + the codebase |
| §4 decisions | open questions in the ADR / concept | what you find while planning |

**Sources are authoritative on _shape_.** If the user hands you a story map, do not reorder or re-slice it — inherit its backbone and slices verbatim and only fill the gaps (file paths, verify steps, new/exists tags). Re-derive nothing the source already decided.

Which sources get used is decided **interactively** — see the Intake step below.

## The pipeline: intake → seed → ground → surface → render

### 1. Intake — ask what to build from (interactive)
Don't assume the inputs. Open with a **multiple-choice menu (multi-select)** — e.g. the `AskUserQuestion` tool — and let the user pick which resources they want to supply:

- **Concept doc / brief** — a PRD, ticket, or notes describing the feature
- **Story map** — from an MCP board (Miro, FigJam, …)
- **Story map** — from an existing doc / file
- **Architecture / decisions** — from an ADR or design doc
- **None — I'll describe it in chat** — autogenerate every section from the conversation

Then:

- **For each resource the user selected, ask a follow-up for its path or reference** — a file path for a doc/ADR, a board URL or ID for an MCP source. Ask only for what they picked; never prompt for paths to things they didn't choose.
- Any section with no chosen resource is **autogenerated from the concept** (the table above).
- If a picked MCP source turns out to be unavailable when you fetch it, say so plainly and fall back to autogenerating that section.
- **Skip the menu only when running fully autonomously** — invoked with sources already specified and no user present to ask. Then infer the sources from what you were handed.

### 2. Seed
Pull each section from its chosen source (or autogenerate). Hold the concept in plain language first — you cannot write §1 until you can say, in one sentence, what the thing is and who it's for.

### 3. Ground (always-on — this is what makes the artifact worth more than a generic plan)
Scan the **actual repository**. Sources give intent; the code gives truth. Every claim in the artifact must be reconciled with what's really there:

- **Find analogs and conventions.** New code is described in the repo's *own idiom* — "a module shaped like `X`," "a use-case like `Y`." Discover the patterns by reading the code; never impose a generic structure.
- **Classify every component** as one of three, honestly:
  - `exists` → a real file. Use its real path and **deep-link it** in the diagram (`vscode://file/ABSOLUTE/PATH:LINE`).
  - `new` → code to be written. Describe where it lands or the existing analog to mimic. It is forward-looking and legitimately not in the repo yet — that is the point, not a gap. **Never give it a path that implies it already exists**, and never a vscode click link.
  - `external` → a boundary (third-party API, service). No path.
- **Use absolute paths** in vscode links — the installer's real repo root.

The cardinal sin: letting a `new` thing masquerade as a concrete existing file, or inventing a path to make a slice look grounded. If you couldn't find it, say `new` and describe the analog.

### 4. Surface
Anything you cannot resolve becomes **visible**, never an invisible "fix":

- A genuine open choice (or a question left open by the ADR) → render it as the §4 decision, risk-rated safest-first.
- A source slice that conflicts with what the code allows → keep the slice (the source is authoritative on shape) but flag the tension in its tooltip; don't silently drop or "correct" it.

Only render §4 when a real decision exists. If there's none, delete the section and the header's warn pill (the template marks where).

### 5. Render
Copy `template.html` directory into the user's repo (a `docs/` folder is a sensible default — confirm or follow an existing convention). Fill the slots. Then open it / tell the user the path.

## Filling the template

The template's own comments are the spec — read them. The essentials:

- **§1 — make it _felt_.** The `{{STATIC_PROTOTYPE}}` slot is the whole container: build a short, concrete, **static** snapshot of the feature in use, before any architecture. **Decide the shape from how the feature is actually used — never default to chat.** Stay on-brand by drawing from the §1 toolbox classes the template ships — `chat` (conversational), `panel` (settings / forms / controls: the `.mock` frame + rows, toggles, fields, selects, buttons), `table` (data views / lists / results: `.mock-table` rows + status dots) — or compose freely with the design tokens; never go off-palette. Fill it with specific, real-sounding content, not generic placeholder text. End with a `.scope-note` only if a line foreshadows the §4 decision.
- **§2 — the story map.** Backbone columns = the user's journey, left to right. Rows = **vertical slices**, each one thin feature working end-to-end (something the user can verify as a self-contained unit), *not* "all the DB work, then all the API work." Conventions:
  - **Slice 0 is a throwaway clickable mock** (`.sm-lab.start`) — fastest path to feeling the UX, real surface + faked everything behind it.
  - Order rows as a walking skeleton: mock → thinnest real end-to-end pipe → real data → richer behavior → later/optional slices (`.sm-lab.opt`).
  - Each cell is `fill` (real work this slice ships for that step), `canned` (stubbed/faked), or `empty` (untouched).
  - Each slice's tooltip carries **Files** (to create/touch, or the analog to mimic) and **Verify** (how to see it work).
  - **Grid invariant:** the `.smgrid` CSS `repeat(N,…)` must equal the backbone column count, and every row must emit exactly N cells. Get this wrong and the layout breaks.
  - A cross-cutting *quality* layer (streaming, offline, perf) that isn't a journey step goes in the optional ribbon, not a column.
- **§3 — the diagram.** Fill the `archDef` NODES / EDGES / CLICKS regions. Keep `classDef` and `class` assignments in sync with node kinds. `exists` nodes get vscode click links; `new`/`external` do not. The legend is static.
- **§4 — decisions.** Cards risk-rated `.safe → .mid → .hot`, safest first. Keep each card **scannable, never a wall of text**: a one-line `.gist`, then 2–3 compact `.opt-meta` label/value rows (Trade-off, Cost, Best for, Risk… — pick what matters, bold the key word). Add the optional `.opt-flow` mini-diagram only when an option is a *shape* worth showing (pipeline, fan-out, before→after); delete it otherwise. Drop the whole section if there's no real decision.

## Output discipline

- The artifact is **a single self-contained HTML file** (mermaid loads from CDN, so it needs network when opened).
- Nothing in the shipped skill is specific to any one codebase. Everything codebase-specific is discovered at runtime and lives only in the generated artifact.
- Respect the template's chrome (tokens, animation, tooltip system, mermaid init, the Download-PDF button + print stylesheet). Editing it is off-contract; your job is content, not restyling.
- Keep prose concise and in plain terms. When you reference codebase context the user may not have loaded, briefly say what it is rather than assuming they know it.

