feat: add visual companion for brainstorming skill

Adds browser-based mockup display to replace ASCII art during
brainstorming sessions. Key components:

- Frame template with OS-aware light/dark theming
- CSS helpers for options, cards, mockups, split views
- Server lifecycle scripts (start/stop with random high port)
- Event watcher using tail+grep for feedback loop
- Claude instructions for using the visual companion

The skill now asks users if they want browser mockups and only
runs in Claude Code environments.
This commit is contained in:
Jesse Vincent
2026-01-17 16:47:03 -08:00
parent fd51e8a6b7
commit ac3af07af0
7 changed files with 665 additions and 64 deletions

View File

@@ -1,73 +1,108 @@
# Visual Companion Reference
## Starting the Server
Quick reference for using the visual brainstorming companion.
Run as a background job:
## Files
| File | Purpose |
|------|---------|
| `lib/brainstorm-server/start-server.sh` | Start server, outputs JSON with URL |
| `lib/brainstorm-server/stop-server.sh` | Stop server and clean up |
| `lib/brainstorm-server/wait-for-event.sh` | Wait for user feedback |
| `lib/brainstorm-server/frame-template.html` | Base HTML template with CSS |
| `lib/brainstorm-server/CLAUDE-INSTRUCTIONS.md` | Detailed usage guide |
| `/tmp/brainstorm/screen.html` | Write your screens here |
| `/tmp/brainstorm/.server.log` | Server output (for watcher) |
## Quick Start
```bash
node ${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/index.js
# 1. Start server
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/start-server.sh
# Returns: {"type":"server-started","port":52341,"url":"http://localhost:52341"}
# 2. Write screen
# Write HTML to /tmp/brainstorm/screen.html
# 3. Wait for feedback (background)
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/wait-for-event.sh /tmp/brainstorm/.server.log
# 4. Read watcher output when it completes
# Returns: {"choice":"a","feedback":"user notes"}
# 5. Clean up when done
${CLAUDE_PLUGIN_ROOT}/lib/brainstorm-server/stop-server.sh
```
Tell the user: "I've started a visual companion at http://localhost:3333 - open it in a browser."
## Pushing Screens
Write HTML to `/tmp/brainstorm/screen.html`. The server watches this file and auto-refreshes the browser.
## Reading User Responses
Check the background task output for JSON events:
```json
{"source":"user-event","type":"click","text":"Option A","choice":"optionA","timestamp":1234567890}
{"source":"user-event","type":"submit","data":{"notes":"My feedback"},"timestamp":1234567891}
```
Event types:
- **click**: User clicked button or `data-choice` element
- **submit**: User submitted form (includes all form data)
- **input**: User typed in field (debounced 500ms)
- **choice**: Explicit choice via `brainstorm.choice()` call
## HTML Patterns
### Choice Cards
## CSS Classes
### Options (A/B/C choices)
```html
<div class="options">
<button data-choice="optionA">
<h3>Option A</h3>
<p>Description</p>
</button>
<button data-choice="optionB">
<h3>Option B</h3>
<p>Description</p>
</button>
<div class="option" data-choice="a" onclick="toggleSelect(this)">
<div class="letter">A</div>
<div class="content">
<h3>Title</h3>
<p>Description</p>
</div>
</div>
</div>
```
### Interactive Mockup
### Cards (visual designs)
```html
<div class="cards">
<div class="card" data-choice="x" onclick="toggleSelect(this)">
<div class="card-image"><!-- mockup --></div>
<div class="card-body">
<h3>Name</h3>
<p>Description</p>
</div>
</div>
</div>
```
### Mockup container
```html
<div class="mockup">
<header data-choice="header">App Header</header>
<nav data-choice="nav">Navigation</nav>
<main data-choice="main">Content</main>
<div class="mockup-header">Label</div>
<div class="mockup-body"><!-- content --></div>
</div>
```
### Form with Notes
### Split view
```html
<form>
<label>Priority: <input type="range" name="priority" min="1" max="5"></label>
<textarea name="notes" placeholder="Additional thoughts..."></textarea>
<button type="submit">Submit</button>
</form>
<div class="split">
<div><!-- left --></div>
<div><!-- right --></div>
</div>
```
### Explicit JavaScript
### Pros/Cons
```html
<button onclick="brainstorm.choice('custom', {extra: 'data'})">Custom</button>
<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>
```
### Mock elements
```html
<div class="mock-nav">Nav items</div>
<div class="mock-sidebar">Sidebar</div>
<div class="mock-content">Content</div>
<button class="mock-button">Button</button>
<input class="mock-input" placeholder="Input">
<div class="placeholder">Placeholder area</div>
```
## User Feedback Format
```json
{
"choice": "option-id", // from data-choice attribute
"feedback": "user notes" // from feedback textarea
}
```
Both fields are optional - user may select without notes, or send notes without selection.