| name | feature-plan |
| description | Turns a feature concept into a single self-contained interactive HTML planning artifact. |
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.