Skip to main content

Skill: Visual brainstorm

Posted on · Updated

Prerequisites

Superpowers is an agentic skills framework & software development methodology that works. This skill uses its brainstorming skill and the Visual Companion server.

https://github.com/obra/superpowers

Folder Structure

visual-brainstorm/
├── SKILL.md
├── screen-template.md
└── spec-review.md

Content

SKILL.md

SKILL.mdmd
---
name: visual-brainstorm
description: Use when the user asks to brainstorm, plan, or design a change from a findings document, a screenshot, a spec, a review follow-up, or an idea, or asks to render the context, the options, and a recommendation in the Visual Companion browser.
---

# Visual brainstorm

## Overview

The user makes design decisions from browser screens, not from terminal text. Each screen shows one decision: the context, the options, and one recommendation. This skill changes some rules of `superpowers:brainstorming`, and it adds a parallel review of the spec.

**REQUIRED SUB-SKILL:** Use `superpowers:brainstorming`. Then read its `visual-companion.md` before you start the server.

## Where this skill overrides brainstorming

The user's instructions have priority over a skill. Where the two skills disagree, use the right column.

| `superpowers:brainstorming` says | With this skill |
| --- | --- |
| Offer the companion just-in-time, in its own message | Start the server at once. The call of this skill is the approval. Do not ask. |
| Start with a line that lets the user skip the questions | Leave that line out. |
| Ask open questions first. Options steer. End with no example answers. | Each decision screen has 2 or 3 options and one recommendation. The question names the option letters. |
| Offer recon, and let the user decide | Read the code and the references at once. Reading changes nothing. |
| Play back 200 to 300 words at intervals | The `.done` banner and the summary screen replace the play-back. |
| Keep scope, tradeoffs, and comparison tables in the terminal | Put every decision and every comparison on a screen. |
| A small change stays in chat | Write the spec for each change, also a small one. Skip the spec only when the user says to build at once. |
| Commit the spec | Write the spec in `docs/superpowers/specs/`. Do not commit. The user decides about commits. |
| Builder check: one fresh subagent | Run the parallel spec review in `spec-review.md`: three or more reviewers, sent in one message. |
| Bring the "theirs" pile in one message | Put the "theirs" pile on one review screen. The user answers all questions in one reply. |
| After approval, invoke `superpowers:writing-plans` | Stop. The user runs `/write-plan`, which uses `superpowers:writing-plans`. |

## Workflow

1. **Start the server.** Do this before you read the code. The project is the folder that the user names. If the user names no folder, it is the git root of the current folder.

   ```sh
   PROJECT=<the absolute path of the project>
   BS=$(ls -d ~/.claude/plugins/cache/claude-plugins-official/superpowers/*/skills/brainstorming | sort -V | tail -1)
   bash "$BS/scripts/start-server.sh" --project-dir "$PROJECT" --open
   ```

   The output gives `screen_dir`. Record the session folder, which is the parent folder of `screen_dir`. You need it to stop the server. Write `00-waiting.html` in `screen_dir` ("Reading the code…"). Give the full URL with `?key=…` in every message. Do not end the turn. Continue to steps 2 and 3 in the same turn.
2. **Read the project rules.** Read the instructions file of the project (`AGENTS.md`, `CLAUDE.md`, or both). If the project has neither, read `README.md`, `CONTRIBUTING.md`, `DEVELOPMENT.md`, the `Makefile`, and the scripts in `package.json`. Write down these items:
   - the build, test, and lint commands;
   - the platform and the run-time limits, for example "Cloudflare Workers, queue with no retries";
   - the rules that span files, for example "a new env var also goes into the README table". When no file states a rule, write the rules that the code shows. You give this list to the reviewers.
   - a reference project or an upstream that the project follows;
   - a style guide for the text.

   If `.gitignore` does not ignore `.superpowers/` and `docs/superpowers/`, say so in a `.note` on screen 1. Do not edit `.gitignore`.
3. **Intake.** Read the input, then make screen 1. Its layout is in `screen-template.md`.
   - **Findings document:** see "Verify a findings document" below.
   - **Screenshot:** screen 1 shows the behavior today next to the behavior that the user wants.
   - **Spec, idea, or follow-up list:** screen 1 shows the scope.

   Find each entry point that writes or reads the changed data. Search for the writes (for example `INSERT INTO <table>` or each call of the setter), not only the obvious caller. List them in a `.note` on screen 1. If a project document (a roadmap or an ideas file) plans the same feature in a different way, name it in the `.note` and make the difference a decision.

   Screen 1 always ends with the list of decisions, "Question 1 … N". Ask: "Is this correct? Reply yes to go to Question 1, or name the row to change."
4. **Reference research.** Do this step when the project or the user names a reference project, or when a decision depends on a fact about an external API that the code does not use yet.
   - For a reference project, read how it does the same feature. Read its source at one pinned commit, and cite `path:line`. Write "Matches <reference>" or "Differs from <reference>: <reason>" on the option.
   - For an external API, read the official docs, and cite the URL.
   - Use one agent for each reference project or API, and send them in one message.
5. **Decision screens.** Make one screen for each decision. Follow the contract in `screen-template.md`. End your turn after each screen, and wait for the answer.

   **Quick mode.** Use it when the user asks for speed, for example "quick" or "just use your recommendations". Put all decisions on one screen, as blocks Q1 to QN. Each block has the options and one recommendation. The question line is: "Reply with one letter for each question, for example "Q1 A, Q2 B". "OK" means all recommendations." The spec and the spec review still run.
6. **Answers.** Use these rules:
   - A short answer such as "option A" or "4a A, 4b B" is a decision. Record it, and show it in the `.done` banner of the next screen.
   - An answer can add or remove a decision. Then change M in "Question N of M" on the next screen, and write the reason in the `.done` banner.
   - "Which one is best?" needs one recommendation with the reasons. Do not give a second list.
   - A side question ("How does the reference do it?") gets its own screen, for example a comparison table. End that turn with the open decision again.
   - A rejection ("I don't like the new message") gets a new file with a `-vN` suffix. Render the full screen again, not only the changed rows.
7. **Spec.** After the last decision, write one spec file, `docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md`. Write it section by section, with several edits. Name the input document in the first section. Include a "Decisions" section and a "My calls" section. Do not edit the findings document.
8. **Parallel spec review.** Follow `spec-review.md`:
   - Choose the reviewers. Send all of them in one message.
   - While they work, push a summary screen of all decisions. Tell the user that the reviewers read the spec now, and that one screen of questions can follow.
   - Wait for all reports. Then merge, verify, and sort the items.
   - Update the spec. Put the questions that only the user can answer on one review screen.
9. **Hand over.** Put the hand-over summary in the terminal message, not on a screen. The summary has these parts:
   - the title "Spec ready: <the topic>" and the spec path;
   - all decisions and all review answers;
   - a table of what the review changed, with each of your calls marked "My call";
   - this question: "Reply OK to approve the spec, or name a section to change. After you approve, run `/write-plan`."

   Stop the server in the same turn, as "Stop the server" below shows. Nothing gets built before the approval. Do not start a plan or an implementation.

## Stop the server

Stop the server when the session ends. The session ends at the first of these events:

- You send the hand-over summary of the finished spec.
- A plan is written from the spec in this session, and the server still runs.
- The user asks you to stop.

1. Run the stop script with the session folder:

   ```sh
   BS=$(ls -d ~/.claude/plugins/cache/claude-plugins-official/superpowers/*/skills/brainstorming | sort -V | tail -1)
   bash "$BS/scripts/stop-server.sh" <the session folder>
   ```

2. Make sure that the output is `{"status": "stopped"}` or `{"status": "not_running"}`.
3. End the terminal message with the line "The Visual Companion server is stopped."

About 15 seconds after the stop, the open tab covers the page with a "Companion paused" overlay. For this reason, the hand-over summary goes in the terminal message. If a change to the spec needs a new screen later, start the server again with the same `--project-dir`. It uses the same port, so the open tab connects again.

## Verify a findings document

A findings document can be older than the code.

1. Find the commit or the date that the document names. Run `git log --oneline <commit>..HEAD -- <the files that the document names>`. A fix can be already in the code.
2. Split the claims by subsystem, for example the API, the database, or the UI. Use one agent for each subsystem when the claims touch more than two subsystems. Send the agents in one message.
3. Give each claim one verdict:

   | Verdict | Meaning |
   | --- | --- |
   | Confirmed | The code does what the document says. |
   | Partly true | Part of the claim is wrong, or the scope is different. |
   | False | The code does not do it. |
   | Fixed since | A later commit fixed it. Name the commit. |
   | Cannot check | The cited file is not in the repo or in the reference project. |
   | New | You found it. The document does not have it. |

4. Give each open finding a severity: High (data loss, a crash, or a wrong result for the user), Medium (a visible defect with a workaround), or Low (log noise or a cosmetic defect).

## Phone access

Use this only when the user asks for it, and only for that session.

1. Start the server with `--host 0.0.0.0 --url-host <the LAN IP of the PC>`. `--host` sets the interface that the server binds. `--url-host` sets the host name in the returned URL.
2. Give the user the full URL with `?key=…`. The server refuses a request without the key.
3. If the phone cannot open the URL, a firewall can block the port. Tell the user to allow inbound TCP on that port from the LAN subnet only.
4. At the end of the session, tell the user to remove that firewall rule.

## Red flags

| Thought | Correct action |
| --- | --- |
| "I will ask if the user wants the browser." | Start the server. The user always wants it. |
| "This tradeoff is text, so it stays in the terminal." | Put it on a screen. The terminal message has only the URL, a one-line summary, and the question. |
| "The spec is done, but I will keep the server for later." | Stop the server after the hand-over summary. Start it again only when a new screen is necessary. |
| "I will put the hand-over summary on a screen." | Put it in the terminal message. The "Companion paused" overlay covers the screen after the stop. |
| "I will ask an open question first." | Show the options with one recommendation. The user can still give a different answer. |
| "The findings document says X, so X is true." | Check `git log` since the document, and read the code. |
| "The reference project does X. I remember it." | Read its source at a pinned commit, and cite `path:line`. |
| "I will update only the row that changed." | Write a new `-vN` file with the full screen. |
| "I will put three unrelated decisions on one screen." | Use one screen for each decision. Small parts of one decision can share a screen as 4a, 4b, 4c. Quick mode is the only exception. |
| "The user said X, so I must recommend X." | Recommend from the facts. If the recommendation differs from the user's words, say so in the `.rec` box, and give the reason. |
| "The user said quick, so I skip the screens and the spec." | Use quick mode: one screen with all decisions. The spec and the review still run. |
| "I will check the API with the user's keys." | Never. Read the source of the reference projects and the official docs. |
| "The spec is small, so one builder agent is enough." | Send at least R-builder, R-code, and R-edge. A small spec also makes claims about the code. |
| "I will send the next reviewer when the first one is done." | Send all reviewers in one message. |
| "A report is in, so I will tell the user its findings now." | Send one status line. Give the merged result after the last report. |
| "I will ask the review questions in the terminal." | Put them on one review screen, with options and a recommendation for each. |
| "The spec is approved, so I will start the build." | Stop at the spec. The user runs `/write-plan`. |

screen-template.md

screen-template.mdmd
# Screen contract

Each screen is a content fragment. The server wraps it in the frame, but the frame does not have the classes in "Styles". Put the style block in each fragment. Write each screen to a new file in `screen_dir`. Use a number and a topic in the name, for example `03-update-restart.html`. Add `-v2`, `-v3` for a new version of a screen.

## Screen 1: the intake

1. **Title (`h2`).** The topic and the input, for example "Findings: the stream cursor leak".
2. **Table (`table.m`).** For a findings document: #, the claim, the verdict, the evidence as `path:line`, and the severity. For a screenshot: today and wanted, side by side. For a spec or an idea: the scope, in and out.
3. **`.note`.** Anything that the user must know first, for example a stale findings document or a fix that is already in the code.
4. **Decision list.** "Question 1 … N", one line each. This sets M in "Question N of M".

## Decision screens: parts, in this order

1. **`.done` banner.** It lists the decisions so far. Leave it out when no decision exists yet.
2. **Title (`h2`).** Write "Question N of M:" and the decision as a question.
3. **Subtitle.** Write one sentence with the rule or the goal.
4. **Context: today and after.** Use two panes side by side, with a mockup of the surface that changes (see the table below). The "after" pane shows the recommended option. When each option looks different to the user, add a small mockup to each option too.
5. **Context: the code path.** Use a `pre` tree of the real call path with function names. Mark the place of the bug or the change. Leave this part out when no code path applies.
6. **Options.** Give 2 or 3 options, A to C. Each option has a title, one short paragraph, and pros and cons. Add "(recommended)" to the title of one option. When a reference project has the same feature, write "Matches <reference>" or "Differs from <reference>: <reason>".
7. **`.rec` box.** Give the recommendation and the reason in 2 to 4 sentences.
8. **What changes.** List the files, the tests, and the docs that change for the recommended option. Include each docs file that a project rule ties to the change.

Follow the writing style of the user and of the project for all prose on the screen. Text inside a mockup is the text that the product shows, in the language of the product.

## Mockup for each surface

| Surface | Mockup |
| --- | --- |
| Chat message, bot reply, button, notification | A phone column of 360 px with message bubbles (`.tg`, `.bubble`) |
| CLI output, setup wizard, log | A dark terminal block (`.term`) |
| Web page, dashboard, docs page | A browser preview of the rendered page |
| HTTP API | The request and the response, today and after (`.term`) |
| Race, restart, or queue order | A timeline with one row for each actor |
| Config | A YAML, JSON, or TOML block, today and after |
| Database schema | A `table.m` of the columns, today and after |
| No visible surface (an internal fix) | The code path and the log lines, today and after |

## Styles

Put this block at the top of the fragment.

```html
<style>
  .split2 { display:grid; grid-template-columns:1fr 1fr; gap:14px; margin:10px 0 18px; }
  @media (max-width: 800px){ .split2 { grid-template-columns:1fr; } }
  .term { background:#1e1e1e; color:#d4d4d4; border-radius:8px; padding:10px 12px; font:12.5px/1.5 ui-monospace,monospace; white-space:pre-wrap; overflow-x:auto; }
  .term .c { color:#6a9955; } .term .e { color:#f48771; } .term .g { color:#89d185; } .term .p { color:#9cdcfe; } .term .y { color:#dcdcaa; }
  .lbl { font-size:12px; text-transform:uppercase; letter-spacing:.05em; opacity:.7; margin-bottom:4px; }
  .tg { background:#dfe9d6; border-radius:10px; padding:12px; max-width:360px; }
  .bubble { background:#fff; color:#111; border-radius:10px; padding:8px 10px; font-size:14px; line-height:1.4; box-shadow:0 1px 1px rgba(0,0,0,.12); }
  .bubble .meta { font-size:11px; color:#888; text-align:right; margin-top:4px; }
  table.m { border-collapse:collapse; width:100%; font-size:13.5px; }
  table.m th, table.m td { border:1px solid rgba(127,127,127,.3); padding:6px 8px; text-align:left; vertical-align:top; }
  table.m th { background:rgba(127,127,127,.08); }
  .rec { border-left:4px solid #1e8449; background:rgba(30,132,73,.08); padding:10px 14px; margin:16px 0; }
  .note { border-left:4px solid #d68910; padding:8px 12px; background:rgba(214,137,16,.08); margin:12px 0; font-size:14px; }
  .done { border-left:4px solid #2e86c1; padding:6px 12px; background:rgba(46,134,193,.08); margin:0 0 14px; font-size:13.5px; }
</style>
```

## Skeleton

```html
<div class="done">Decided: <b>Q1 = A</b> (validate the upload on the server).</div>

<h2>Question 2 of 4: What does the app do with a ZIP file?</h2>
<p class="subtitle">The app accepts images, PDFs, and text files.</p>

<div class="section">
  <h3>Context: today and after</h3>
  <div class="split2">
    <div><div class="lbl">Today</div><div class="term">…</div></div>
    <div><div class="lbl">After (option A)</div><div class="term">…</div></div>
  </div>
</div>

<div class="section">
  <h3>Context: the code path</h3>
  <pre>handleUpload → detectType → validate → store</pre>
</div>

<div class="section">
  <h3>Options</h3>
  <div class="options">
    <div class="option" data-choice="a" onclick="toggleSelect(this)">
      <div class="letter">A</div>
      <div class="content">
        <h3>… (recommended)</h3>
        <p>…</p>
        <div class="pros-cons">
          <div class="pros"><h4>Pros</h4><ul><li>…</li></ul></div>
          <div class="cons"><h4>Cons</h4><ul><li>…</li></ul></div>
        </div>
      </div>
    </div>
    <!-- B and C use the same markup -->
  </div>
</div>

<div class="rec"><b>Recommendation: A.</b> …</div>

<div class="section">
  <h3>What changes with option A</h3>
  <ul><li><code>src/upload/validate.ts</code>: …</li></ul>
</div>
```

## Terminal message after each screen

Send three lines:

1. The full URL with `?key=…`.
2. One sentence about the screen.
3. The question. On a decision screen, name the option letters. On screen 1, ask: "Is this correct? Reply yes to go to Question 1, or name the row to change."

Put a note for the user, such as a stale source, in a `.note` on the screen, not in the terminal.

spec-review.md

spec-review.mdmd
# Parallel spec review

This review replaces the single builder check of `superpowers:brainstorming`. Several reviewers read the spec at the same time. Each reviewer has a different lens. You merge the reports into one result and one round of questions.

## Choose the reviewers

| Reviewer | When to send it |
| --- | --- |
| R-builder | Always. |
| R-code | Always. Count the source folders (for example the API, the database layer, and the UI) in which the spec changes two or more source files. Tests, migrations, docs, and dependency files do not count. They go with the code that they belong to. If the count is three or more, send one R-code for each of those folders. Add a folder with one changed file to the scope of another R-code. |
| R-edge | Always. |
| R-reference | The spec states a fact about a reference project or an external API (a third-party HTTP API, a protocol, a platform limit) with no `path:line` at a pinned commit and no official docs URL. Examples are a field name, a limit, and a status code. A library API that the code already uses does not count, because R-code checks it. Give R-reference only those facts. |

Send all the reviewers in one message, as background agents with `subagent_type: general-purpose`. Do not wait for one reviewer before you send the next.

## The summary screen

Write `NN-summary.html` in the same message as the reviewers. Use the styles of `screen-template.md`.

1. **`.done` banner.** All decisions.
2. **Title (`h2`).** "Summary: <the topic>".
3. **Table (`table.m`).** Columns: #, the decision, the result for the user, and "Matches <reference>" or "Differs from <reference>" when a reference project exists.
4. **`.note`.** "N reviewers read the spec now. One screen of questions can follow." Write the spec path.

The terminal message has the URL, one sentence about the screen, and "No reply is necessary now."

## Prompts

Replace these placeholders:

- `<SPEC>`: the absolute path of the spec.
- `<REPO>`: the absolute path of the repository.
- `<RULES>`: the instructions file of the project, for example `AGENTS.md` or `CLAUDE.md`. With no such file, the docs that you read in step 2.
- `<CROSS_RULES>`: the list of rules that span files, from step 2.
- `<LANG>`: the main language and its version, for example "Go 1.26" or "TypeScript 5".
- `<PLATFORM>`: the platform and the run-time limits from step 2, for example "Cloudflare Workers with D1; the queue has no retries".
- `<FILES>`: the files that the spec names.

Each prompt ends with the report format below.

### R-builder

```
You are a talented <LANG> software engineer. You've been handed a design document and asked to put together a plan to build what it describes. You will not be able to talk to the person who wrote it.

Read <SPEC>. The repository is <REPO>. Read <RULES> there first. You may read any code to check the document. Change nothing.

Report only the questions you'd still need answered before you could plan this well: places where you'd have to guess and a wrong guess would matter. Skip anything the document explicitly leaves to the builder, and anything you could reasonably decide yourself. Skip nitpicks about wording. If nothing important is left, say "nothing important left".
```

### R-code

```
Review a design document against the code that it changes. Change nothing.

Document: <SPEC>
Repository: <REPO> (<LANG>). Read <RULES> first.
Scope: <the subsystem and its folders, or "all">. Start with: <FILES>.

Your lens: code accuracy and integration.
1. Check each claim about the current code in the code: files, functions, types, fields, call sites, behavior, and tests.
2. Find the places that the change touches but the document does not name: other callers, other readers of a changed field, every query of a changed table, tests that will break.
3. Check each call between your scope and another module, in both directions. A change on one side must fit the other side.
4. Check each rule that ties one file to another:
<CROSS_RULES>
   Also look for such rules in the code, for example generated docs, a docs table that a test compares, a registry, an allow list, or an import rule.
```

### R-edge

```
Review a design document for failure modes at run time. Change nothing.

Document: <SPEC>
Repository: <REPO> (<LANG>). Read <RULES> first. Relevant code: <FILES>.
Platform: <PLATFORM>.

Your lens: what goes wrong at run time on this platform? Think about:
- concurrent requests on the same data, retries, cancel, and a restart in the middle of an operation;
- each entry point that reaches the changed code (UI, API, CLI, jobs, workers);
- caches and data that must stay stable;
- old config files, old rows, old clients, and a migration;
- input from a user or a third party that is empty, too large, or hostile;
- errors from the network, the disk, or a dependency, and what the user sees then;
- startup time and resource limits.
Skip anything the document explicitly leaves to the builder.
```

### R-reference

```
Check the external facts of a design document. Change nothing in the repository.

Document: <SPEC>. Facts to check: <the list of facts, each with its section>.
Repository: <REPO>. Read <RULES> first.

Your lens: is each fact correct?
1. For a reference project, read its source on GitHub at one pinned commit. Get the commit with `gh api repos/<owner>/<repo>/commits/<branch> --jq .sha`. Read files from `https://raw.githubusercontent.com/<owner>/<repo>/<sha>/<path>`. Do not clone.
2. For an external API, read the official documentation (load WebSearch and WebFetch with ToolSearch "select:WebSearch,WebFetch").
3. Cite `path:line` at the pinned commit, or the URL.
Never call an external API with the user's keys or credentials.
```

### Report format (append to each prompt)

```
Report format. Give one item for each problem, most important first. Use at most 12 items and 900 words.
- Kind: question | wrong claim | missing touch point | failure mode | wrong external fact
- Spec section: <number or heading>
- Evidence: <path:line, or a URL, or "none">
- Problem: <one or two sentences>
- Why it matters: <what goes wrong in the build or at run time>
- Proposed answer: <what the spec should say, or "only the author can decide">
```

## Merge the reports

1. **Wait for all reports.** When a report arrives, send the URL and one status line, for example "2 of 4 reports are in." Do not relay the items one report at a time.
2. **Merge the items.** Put all items in one list. Two items are one item when they have the same cause, also when they name different spec sections.
3. **Verify.** For each item that changes the spec or that goes to the user, read the cited `path:line` yourself. Drop an item that the code disproves.
4. **Sort.** Use the three piles of `superpowers:brainstorming`:
   - **Answered already:** put the answer in the spec.
   - **Minor:** settle it yourself. Add it to the "My calls" section.
   - **Theirs:** only the user can answer it, and the answer changes what gets built.
5. **Update the spec** with the first two piles. Do this before you show the questions.
6. **Show the questions.** If the "Theirs" pile is empty, go to the hand-over (the last step of `SKILL.md`). Its screen shows what the review changed. Otherwise, put all its questions on one screen. This is the only round of questions.

## The review screen

Write `NN-spec-review.html` in `screen_dir`. Use the styles of `screen-template.md`.

1. **`.done` banner.** All decisions so far.
2. **Title (`h2`).** "Spec review: N questions".
3. **Table (`table.m`).** What the review changed in the spec. Columns: reviewer, item, and change. Mark each of your calls as "My call".
4. **One block for each question,** most important first. Label the blocks R1, R2, and so on. Each block has the question, the context (a mockup or a code path, when one helps), 2 or 3 options A to C, and one option with "(recommended)".
5. **`.rec` box.** The recommendation for each question, in one line each.

Send the terminal message of `screen-template.md`. The question line is: "Reply with one letter for each question, for example "R1 A, R2 B". "OK" means all recommendations."