skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
brandonburrus/visualplan177 installs

visual-plan

This skill should be used whenever a plan for non-trivial work is being produced, presented, or proposed (a feature, design, refactor, migration, or any multi-step task), including in plan mode and together with whatever planning skill produced the plan. It is the default way to deliver a plan: instead of a wall of text, it renders the plan as MDX to a scannable, self-contained HTML page (diagrams, phases, file-change maps, comparisons) via the `vplan` CLI. It applies when the user says "plan this", "what's the approach", "how should we approach X", "show me the plan", "make a visual plan", "render this plan", or asks for a plan with diagrams/charts, and when they want to review, approve, sign off on, or give feedback on a plan. Skip only for a trivial one-step change or when the user explicitly asks for plain prose.

How do I install this agent skill?

npx skills add https://github.com/brandonburrus/visualplan --skill visual-plan
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    This skill provides an AI agent with the ability to render structured planning information into high-quality visual MDX pages using the `vplan` CLI tool. It focuses on visual documentation, review cycles, and project transparency without sensitive operations.

  • Socketpass

    No alerts

  • Snykwarn

    Risk: MEDIUM · 1 issue

What does this agent skill do?

Purpose

Render a plan as a visual MDX page instead of a wall of text, using the vplan CLI. The component vocabulary is general: although the examples below are code-flavored, it fits any structured plan (a product launch, a research agenda, an incident response), not just software changes. Use the components that fit the plan and skip the ones that do not.

Above all, show, don't tell: a reader should grasp the plan by scanning its diagrams, phases, and tables, with prose only connecting the visuals, not carrying the plan itself. The Show, don't tell section below is the heart of this skill.

If the vplan command is not found, install it globally first: npm i -g vplan@latest (published on npm). Re-run the failed command afterward.

Workflow

  1. Write the plan to a .mdx file, starting with a single # Title heading (it becomes the plan title; no frontmatter). Then use the components below; you never write import statements, they are always in scope.

  2. Validate before showing the user: vplan check <file>.mdx. Fix every reported file:line:col issue (it names valid enum values and flags unknown components). check also runs a quality lint that flags weak renders (the enforced Gotchas below); its warnings fail check, so fix them too.

  3. Present the plan with vplan <file>.mdx. An interactive review is the default way to deliver a plan, not a special mode reserved for sign-off. It opens the plan with a feedback layer where the user comments on whole sections or on selected text, answers any <Questions> directly (each question becomes an inline answer field; a question with nested option bullets becomes clickable choices, and the picked option's text (or the typed "Other" text) is the answer, printed back as Answer to "<question>":), then clicks Approve / Deny / Iterate. It blocks until they submit, prints the decision, comments, and answers to stdout, and exits: approve 0, deny 1, iterate 2, timeout 3 (--timeout, default 4h; closing the tab counts as deny). Always suffix --timeout with an ms-style unit (30s, 45m, 4h): a bare number is read as milliseconds, so --timeout 240 would wait a quarter second, not 240 minutes. It is a long-running foreground server, so run it in the background. (The explicit --review flag still works but is redundant now that review is the default.) A comment may carry a severity tag: treat a [must-fix] comment as blocking (it must be addressed before the plan can be approved) and a [suggestion] or untagged comment as non-blocking input. Then act on the printed feedback:

    • Approve -> proceed with the plan as written.
    • Iterate -> revise the plan addressing each comment, then simply re-run vplan <file>.mdx; the review tab updates the same plan in place and the round number increments automatically (pass -i N only to override it). Repeat until Approve or Deny. Edit the same .mdx file in place and re-render: vplan snapshots each plan it presents (keyed by the file path), so the next render automatically marks what changed since the last view with a subtle git-gutter accent and a "N changed" summary, letting the user re-review only the delta. Pass --diff <baseline.mdx> to diff against an explicit file instead of the snapshot, or --no-diff to suppress diffing (e.g. a clean first look).
    • Deny -> stop and reconsider; do not proceed.

    Review is the right default for every non-trivial plan. Targeted comments and in-place <Questions> answers drive sharper revisions than back-and-forth chat, and the loop ends in an explicit Approve so you know it is settled. Reach for a static render (step 4) only when the user just wants to look, not shape or decide.

  4. A static page, a live-reloading preview, or a PDF/JPG export are the non-review outputs, for when the user only wants to look or wants a shareable file rather than review one. When you need one, load references/static-exports.md; it holds the commands and flags for these (kept out of here so review stays the default path). Authoring the plan (everything below) is identical whichever output you choose.

Run vplan components anytime for the exact prop signatures.

Components

The data components (FileTree, Chart, Stat, Compare, Matrix, Questions, Checklist) take their data as markdown children, not props: write a normal markdown list (or, for Matrix and a multi-series Chart, a markdown table) between the tags. Only the scalar settings (title, type, status) are attributes. This is fewer tokens and avoids the {[{ ... }]} brace errors that break a render.

  • <Phase title="..." status="planned|active|done">: one step in a numbered vertical timeline; wraps markdown (ordered lists, prose, nested components). The steps auto-number in order. One per major step of the plan.

  • ```mermaid fenced block, for diagrams: architecture (flowchart), sequenceDiagram, dependency graphs, stateDiagram-v2, classDiagram, erDiagram, and xychart-beta. Reach for this first for anything structural. (gantt and pie are not supported; use <Chart> for quantitative data. check now validates each diagram, so an unsupported type fails check with a file:line:col instead of rendering an error box.)

  • <Svg src="./diagrams/power-path.svg" title="Power path" caption="Bench unit, splitter-fed" />: inline a diagram that already exists as a local .svg file, such as an architecture or sequence diagram exported by another tool. src is relative to the plan file; the file is read, sanitized, and inlined at build time, so the page stays self-contained and the diagram follows the page's light/dark theme. title names it for screen readers and the expand view (an exported SVG's own <title> is often a tool default), and caption adds an optional line beneath it. It gets the same hover expand/fullscreen viewer as a mermaid diagram. Static SVG only: <script>, <foreignObject>, event handlers (on*), and any external reference (a href, src, url(...), or @import that is not a same-document #fragment) are refused rather than stripped, and check reports the reason at the tag's line. 2 MB max. Reach for this only when the diagram already exists as a file; write a ```mermaid diagram when you can express it as text.

  • ```math fenced block, a display formula written in LaTeX, typeset as math (complexity bounds, probabilities, linear algebra). Example: ```math then T(n) = O(n \log n).

  • <Callout type="note|tip|risk|decision|warn">: highlight a risk, decision, tip, or note; wraps markdown. (note is blue, tip is green, decision is purple, risk is red, warn is yellow.)

  • <FileTree>: file-change map. One bullet per file, - <change> <path>, where change is add|modify|delete|move. A move needs both ends, - move <from> -> <to> (the file renders at its destination with the origin shown). A path ending in / marks a whole directory (e.g. - delete src/legacy/). A colored file-type icon is added automatically from the path's extension. Append -- <note> to any line for a short inline comment on that change (what it does or why); keep it to a phrase, since it shares the row with the file name.

    <FileTree>
    - add src/gateway/rate-limiter.ts -- sliding-window check against Redis
    - modify src/gateway/middleware.ts -- mount the limiter behind the flag
    - delete src/gateway/legacy/
    </FileTree>
    
  • <Chart type="bar|line|area|scatter|radar|gauge|funnel|treemap|pie" title="...">: estimates/metrics. Single series: one bullet per point, - <label>: <value> (a number). Multi-series (bar/line/area/radar): a table whose header is category | series1 | series2 (cells after the first name the series and become the legend; the first column is the category axis). Specifics: scatter is a table with exactly two value columns read as x and y (| point | x | y |); pie/gauge/funnel/treemap are always single-series, list form only (a table is rejected), with gauge on a 0-100 scale and funnel descending. Add stacked to a multi-series bar/area (<Chart type="bar" stacked>) to stack rather than group.

    <Chart type="bar" title="Effort (days)">
    - Limiter: 2
    - Dashboards: 1
    </Chart>
    
    <Chart type="line" title="Latency by stage (ms)">
    | Stage | p50 | p95 |
    |-------|-----|-----|
    | Auth  | 12  | 30  |
    | DB    | 40  | 120 |
    </Chart>
    
  • <Compare>: weigh approaches side by side as pros/cons cards. Each option is a ## Name heading (append (pick) to mark the recommended one) followed by as many - pro: / - con: bullets as you need.

    <Compare>
    ## Redis sliding window (pick)
    - pro: accurate
    - pro: shared across nodes
    - con: network hop
    
    ## In-memory token bucket
    - pro: fast
    - con: per-node only
    </Compare>
    
  • <Matrix>: a comparison grid (options across the columns, criteria down the rows) for scoring several choices against several dimensions. Write a markdown table; the first column is the row labels, and you append (pick) to one column header to highlight it. Use <Compare> for pros/cons, <Matrix> for a scorecard.

    <Matrix>
    | Dimension | Postgres (pick) | ClickHouse | DynamoDB |
    |-----------|-----------------|------------|----------|
    | Writes    | medium          | high       | high     |
    | Querying  | high            | medium     | low      |
    </Matrix>
    
  • <Questions>: open questions you want the reader to resolve before building, one per bullet. Use this instead of burying uncertainties in prose. The title defaults to "Open questions"; override with title="...". In a --review session each question is directly answerable, so prefer a <Questions> block over prose when you want the reviewer to answer specific questions. Nest bullets under a question to offer multiple-choice options: in a review they become clickable choices (plus an "Other" free-text field), and the chosen option's text comes back as the answer. Offer options whenever you can enumerate the likely answers; they get you a crisp, actionable answer instead of prose. A question with no nested bullets stays free-text.

    <Questions>
    - Should the limiter fail open or fail closed if Redis is unreachable?
      - Fail open, availability first
      - Fail closed, safety first
    - Is a 15-minute access-token TTL acceptable?
    </Questions>
    
  • <Checklist title="Done when">: acceptance criteria / definition of done, as a markdown task list: - [x] for done, - [ ] for todo.

    <Checklist title="Done when">
    - [x] Returns 429 over the limit
    - [ ] Dashboards live
    </Checklist>
    
  • <Stat>: headline plan metrics as a grid of cards (files changed, estimated uptime, rollout). One card per bullet, - <label>: <value> (<intent>) -- <caption>, where intent is one of note|good|warn|risk and both (intent) and -- caption are optional. The value is free text (5 min, 99.9%), not a number. Use this for static facts, not time series (use <Chart> for those). Only add a <Stat> when the plan genuinely has standout numbers worth surfacing; most plans have none, and an invented or filler metric is worse than omitting the component entirely.

    <Stat>
    - Files changed: 12
    - Est. uptime: 99.9% (good)
    - RPO: 5 min (risk) -- worst-case data loss
    </Stat>
    
  • Fenced code blocks are syntax-highlighted (Expressive Code): write ```ts (or js, json, bash, python, go, rust, sql, yaml, etc.) to show a key snippet. Add a file name with ```ts title="src/path/file.ts" to render a filename header on the block.

  • Mark lines and text inside a code block with Expressive Code props in the fence meta string (no component needed). Three marker types: mark (neutral, the default), ins (green, inserted), del (red, removed). Each takes line numbers, ranges, quoted strings, or a /regex/. Use this to call attention to the lines a plan changes.

    • Lines/ranges (neutral): ```ts {2}, ```ts {2-4}, ```ts {1, 3, 5-6}
    • Typed lines: ```ts ins={3-4} del={2} mark={6} (combine freely in one block)
    • Inline text: ```ts "TokenBucket", a rename as ```ts del="oldName" ins="newName"
    • Regex (and capture group): ```ts /\bTODO\b/, ```ts ins=/const (\w+) =/ (marks the group)

Show, don't tell

The whole point of a visual plan is to replace a wall of prose with something the reader grasps by scanning. Default to a component over a sentence: if a fact has structure, show it; do not describe it in paragraphs. Prose is the connective tissue between visuals, never the substance.

  • Lead with the structure. Open with at most a one-paragraph context, then a ```mermaid architecture diagram (or a <Svg> when the diagram already exists as a file), then the <Phase> timeline. The reader should understand the shape of the plan before reading a single full sentence.
  • Prefer a diagram or a <FileTree> to describing structure in words. A flowchart of the data path beats a paragraph tracing it; a file-change map beats sentences listing the files.
  • Move the meaning out of prose into the component that carries it. Risks and decisions go in <Callout>s, open questions in <Questions>, tradeoffs in <Compare> / <Matrix>, acceptance criteria in <Checklist>, not buried in paragraphs where they are easy to skim past.
  • Keep prose tight inside phases. A <Phase> is a step, not an essay: a line or two of intent, then the visual. The visual is the point.
  • Right-size what you show. A large effort opens with a diagram and several phases; a two-or-three-file change may need only a short <FileTree> and a <Checklist>. Do not add a diagram or phase that carries no information: an empty 2-node flowchart shows nothing and is worse than one plain sentence. Show when there is structure to show; otherwise a tight sentence is fine (this applies to <Stat> too, as its own entry notes).

Composing a plan

  • <Phase> and <Callout> wrap arbitrary markdown and components: a <FileTree>, <Chart>, <Matrix>, a ```mermaid diagram, a code block, or a - [ ] task list all nest inside them. Nest freely to group related content under a step or a highlight.
  • Diagrams, charts, and <Svg> each render a hover "expand" button that opens a zoomable, pannable fullscreen viewer, so a dense diagram stays legible even when shrunk inline (code blocks do not). You can lean on it for a necessarily-large diagram, but splitting into smaller diagrams still reads better when the inline view must stand on its own.

Rules

  • Never pass --no-open for a user-facing plan. The point is that the user sees it; the review session opens automatically. Reserve --no-open for an explicit headless/CI request.
  • No images or external assets. The page is a single self-contained file, so a markdown image (![](url)) or any external asset cannot be embedded, and check rejects markdown images. Use a ```mermaid diagram for anything visual, a <Svg> for a diagram that already exists as a local .svg file (inlined at build time, so it is not an external asset), or describe it in text.

Gotchas

Several of these (a wall-of-prose phase, a wide LR mermaid diagram, an over-long Matrix cell, a commented FileTree move row, a wildly-scaled Chart) are now enforced by the check quality lint and will fail it, so they are hard rules, not just style advice.

  • <, {, and } are MDX syntax in prose. A bare <Thing> or {value} can break the render. Wrap literal angle brackets, braces, generics (List<T>), or tag-like text in backticks or a code fence, where every character is safe and literal.
  • Raw inline HTML tags fail check. <kbd>, <sub>, <sup>, <details> and the like are read as unknown components and fail; use backticks or plain text instead. Plain markdown otherwise works alongside the components: GFM tables (outside <Matrix> / <Chart>), blockquotes, footnotes, ~~strikethrough~~, autolinks, - [ ] task lists, and custom-start ordered lists all render.
  • <Chart> shows the shape of the data, not exact figures. There are no on-bar value labels, so any number the reader must know precisely belongs in prose too. Keep labels to a word or two (long bar/line x-axis labels get dropped or crowded), and never put series of wildly different magnitudes on one chart: a value near 50 beside one near 2,000,000 shares a single y-axis and flattens the small series to the zero line. Split into separate charts or normalize to the same unit.
  • <Matrix> cells do not wrap. A long sentence in one cell forces a horizontal scrollbar and pushes the other columns off-screen. Keep cells to a word or a short score; put rationale in prose or a <Callout>, not in a cell.
  • Avoid -- comments on <FileTree> move rows. A move already shows its origin path (the ← <from> annotation), which eats most of the row width, so a comment on the same row gets crowded out. Leave move rows uncommented and put any explanation in prose or a <Callout>; reserve -- comments for add/modify/delete rows, which have the space.
  • Wide mermaid diagrams shrink to illegibility. Prefer top-down (flowchart TD) once a diagram has many nodes; a long left-to-right (LR) chain shrinks to fit the page and becomes effectively unreadable inline. Split a large flow into a few smaller diagrams instead of one sprawling one.

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/brandonburrus/visualplan/visual-plan">View visual-plan on skillZs</a>