25d895d 🐛 fix(gitea_workflow): clean up temp repos after job steps 2bc3b11 🐛 fix(gitea_workflow): clean up temporary repo dirs in workflows 98c3f30 📝 docs(agent_rules): allow plan execution on current branch 16c7230 📝 docs(prompts): define custom verify layering 8efc4dd 🐛 fix(skills): quote commit-message description bc8498f 🐛 fix(ci): install tomli for gitea tests 55cda3b 🐛 fix(tests): report missing toml parser clearly c0729c7 🐛 fix(playbook): import Optional for cli compatibility 63e24bf 📦 deps(skills): sync thirdparty skills d2f9356 🐛 fix(ci): isolate gitea workflow repos 588b81d 🐛 fix(ci): inline gitea workflow bootstrap e0b1c3a ♻️ refactor(skills): standardize first-party skill contracts 2c5050d ♻️ refactor(skills): rename repo skills source dir f049dfb 📦 deps(skills): drop duplicate first-party superpowers skills 234b335 ✨ feat(workflow): add superpowers planning and execution state tracking c1702a6 📝 docs(markdown): format tracked markdown and drop stale templates 2325409 📝 docs(markdown): clarify optional markdownlint usage 214c44e 🔧 chore(markdown): add markdownlint baseline and lint fixes a22b324 📝 docs(templates): add execution and memory-bank prompt templates 223a797 📝 docs(templates): update README for Claude Code and current features 4ac8672 📝 docs: simplify README + platform-agnostic tools + auto-create local rules 2431c9d 📝 docs: add claude_md config and use cross-platform paths d64b248 📝 docs: fix README.md inaccuracies and add Claude Code info c8d6bf2 🐛 fix(playbook): use relative paths in CLAUDE.md when not at project root 6518f0f ✨ feat(playbook): auto-create CLAUDE.md with path discovery 6ec9a45 ✨ feat(skills): add skill_link symlink support + platform-agnostic prompt 9f8b6b5 📝 docs: update README and config example for Claude Code support 79cff6c 📝 docs(skills): add Claude Code platform support 452c6f5 ✨ feat(playbook): auto-inject AGENTS.md into CLAUDE.md e1dbf3c 🐛 fix(skills): remove dual-path from commit-message skill f3a7259 🔧 chore(ci): use prepare_repo.sh in both workflows da08212 🔧 chore(ci): extract prepare_repo.sh and clean up workflows 7ade85e 🗑️ remove(tsl): drop syntax_book/, data/ source and build script f94dba0 ♻️ refactor(skills): update playbook.py and tests for thirdparty/ layout b3df412 ♻️ refactor(skills): separate thirdparty skills into thirdparty/ subdirectory 64950e7 📦 deps(skills): sync thirdparty skills a2e3cb0 ✨ feat(playbook): add no_backup deploy controls 8609d59 🐛 fix(docs): repair reference catalog source links 956da11 🐛 fix(playbook): publish hidden ci test fixes 3f67754 📦 deps(skills): sync thirdparty skills 08ca87b 📦 deps(skills): add karpathy thirdparty sync 96b705b 📝 docs(tsl): rebuild canonical syntax and routing manual 3ed5052 📦 deps(skills): sync thirdparty skills 60108dd 📦 deps(skills): sync thirdparty skills da85d4e 🐛 fix(thirdparty): prune nested project snapshots a2a697e 📦 deps(skills): sync thirdparty skills 9df610a 🐛 fix(thirdparty): exclude duplicated superpowers skills 33dd5bb 🐛 fix(thirdparty): preserve optional manifest fields 91b0ea7 🐛 fix(thirdparty): preserve manifest during snapshot update 2e26f98 🔧 chore(thirdparty): generalize skills sync pipeline 5b9c1e3 📦 deps(skills): sync superpowers 2f2d34a 📝 docs(readme): normalize subtree command spacing 62db7db 🐛 fix(ci): serialize superpowers update and sync 3463223 🐛 fix(ci): use literal superpowers sync paths 48f6de8 📦 deps(skills): sync superpowers 4b23529 🔧 chore(ci): merge superpowers update and sync workflow a56d75b 📦 deps(skills): sync superpowers 84bcefa 🔧 chore(ci): use ci[bot] commit author name 00a07e5 📦 deps(skills): sync superpowers 7b84daf 🐛 fix(templates): enforce main loop progress tracking 51373d7 🔧 chore(ci): automate superpowers sync workflow eaaa39c 🐛 fix(ci): prevent stale superpowers sync from restoring skills block 79755c6 📦 deps(skills): sync superpowers 836d878 📦 deps(skills): sync superpowers 8216c9f 📦 deps(skills): sync superpowers 9439505 🐛 fix(playbook): address reported repo issues git-subtree-dir: docs/standards/playbook git-subtree-split: 25d895d8b3f56624ccfe99ad7289e9eb49e0f316
288 lines
12 KiB
Markdown
288 lines
12 KiB
Markdown
# Visual Companion Guide
|
|
|
|
Browser-based visual brainstorming companion for showing mockups, diagrams, and options.
|
|
|
|
## When to Use
|
|
|
|
Decide per-question, not per-session. The test: **would the user understand this better by seeing it than reading it?**
|
|
|
|
**Use the browser** when the content itself is visual:
|
|
|
|
- **UI mockups** — wireframes, layouts, navigation structures, component designs
|
|
- **Architecture diagrams** — system components, data flow, relationship maps
|
|
- **Side-by-side visual comparisons** — comparing two layouts, two color schemes, two design directions
|
|
- **Design polish** — when the question is about look and feel, spacing, visual hierarchy
|
|
- **Spatial relationships** — state machines, flowcharts, entity relationships rendered as diagrams
|
|
|
|
**Use the terminal** when the content is text or tabular:
|
|
|
|
- **Requirements and scope questions** — "what does X mean?", "which features are in scope?"
|
|
- **Conceptual A/B/C choices** — picking between approaches described in words
|
|
- **Tradeoff lists** — pros/cons, comparison tables
|
|
- **Technical decisions** — API design, data modeling, architectural approach selection
|
|
- **Clarifying questions** — anything where the answer is words, not a visual preference
|
|
|
|
A question *about* a UI topic is not automatically a visual question. "What kind of wizard do you want?" is conceptual — use the terminal. "Which of these wizard layouts feels right?" is visual — use the browser.
|
|
|
|
## How It Works
|
|
|
|
The server watches a directory for HTML files and serves the newest one to the browser. You write HTML content to `screen_dir`, the user sees it in their browser and can click to select options. Selections are recorded to `state_dir/events` that you read on your next turn.
|
|
|
|
**Content fragments vs full documents:** If your HTML file starts with `<!DOCTYPE` or `<html`, the server serves it as-is (just injects the helper script). Otherwise, the server automatically wraps your content in the frame template — adding the header, CSS theme, selection indicator, and all interactive infrastructure. **Write content fragments by default.** Only write full documents when you need complete control over the page.
|
|
|
|
## Starting a Session
|
|
|
|
```bash
|
|
# Start server with persistence (mockups saved to project)
|
|
scripts/start-server.sh --project-dir /path/to/project
|
|
|
|
# Returns: {"type":"server-started","port":52341,"url":"http://localhost:52341",
|
|
# "screen_dir":"/path/to/project/.superpowers/brainstorm/12345-1706000000/content",
|
|
# "state_dir":"/path/to/project/.superpowers/brainstorm/12345-1706000000/state"}
|
|
```
|
|
|
|
Save `screen_dir` and `state_dir` from the response. Tell user to open the URL.
|
|
|
|
**Finding connection info:** The server writes its startup JSON to `$STATE_DIR/server-info`. If you launched the server in the background and didn't capture stdout, read that file to get the URL and port. When using `--project-dir`, check `<project>/.superpowers/brainstorm/` for the session directory.
|
|
|
|
**Note:** Pass the project root as `--project-dir` so mockups persist in `.superpowers/brainstorm/` and survive server restarts. Without it, files go to `/tmp` and get cleaned up. Remind the user to add `.superpowers/` to `.gitignore` if it's not already there.
|
|
|
|
**Launching the server by platform:**
|
|
|
|
**Claude Code (macOS / Linux):**
|
|
```bash
|
|
# Default mode works — the script backgrounds the server itself
|
|
scripts/start-server.sh --project-dir /path/to/project
|
|
```
|
|
|
|
**Claude Code (Windows):**
|
|
```bash
|
|
# Windows auto-detects and uses foreground mode, which blocks the tool call.
|
|
# Use run_in_background: true on the Bash tool call so the server survives
|
|
# across conversation turns.
|
|
scripts/start-server.sh --project-dir /path/to/project
|
|
```
|
|
When calling this via the Bash tool, set `run_in_background: true`. Then read `$STATE_DIR/server-info` on the next turn to get the URL and port.
|
|
|
|
**Codex:**
|
|
```bash
|
|
# Codex reaps background processes. The script auto-detects CODEX_CI and
|
|
# switches to foreground mode. Run it normally — no extra flags needed.
|
|
scripts/start-server.sh --project-dir /path/to/project
|
|
```
|
|
|
|
**Gemini CLI:**
|
|
```bash
|
|
# Use --foreground and set is_background: true on your shell tool call
|
|
# so the process survives across turns
|
|
scripts/start-server.sh --project-dir /path/to/project --foreground
|
|
```
|
|
|
|
**Other environments:** The server must keep running in the background across conversation turns. If your environment reaps detached processes, use `--foreground` and launch the command with your platform's background execution mechanism.
|
|
|
|
If the URL is unreachable from your browser (common in remote/containerized setups), bind a non-loopback host:
|
|
|
|
```bash
|
|
scripts/start-server.sh \
|
|
--project-dir /path/to/project \
|
|
--host 0.0.0.0 \
|
|
--url-host localhost
|
|
```
|
|
|
|
Use `--url-host` to control what hostname is printed in the returned URL JSON.
|
|
|
|
## The Loop
|
|
|
|
1. **Check server is alive**, then **write HTML** to a new file in `screen_dir`:
|
|
- Before each write, check that `$STATE_DIR/server-info` exists. If it doesn't (or `$STATE_DIR/server-stopped` exists), the server has shut down — restart it with `start-server.sh` before continuing. The server auto-exits after 30 minutes of inactivity.
|
|
- Use semantic filenames: `platform.html`, `visual-style.html`, `layout.html`
|
|
- **Never reuse filenames** — each screen gets a fresh file
|
|
- Use Write tool — **never use cat/heredoc** (dumps noise into terminal)
|
|
- Server automatically serves the newest file
|
|
|
|
2. **Tell user what to expect and end your turn:**
|
|
- Remind them of the URL (every step, not just first)
|
|
- Give a brief text summary of what's on screen (e.g., "Showing 3 layout options for the homepage")
|
|
- Ask them to respond in the terminal: "Take a look and let me know what you think. Click to select an option if you'd like."
|
|
|
|
3. **On your next turn** — after the user responds in the terminal:
|
|
- Read `$STATE_DIR/events` if it exists — this contains the user's browser interactions (clicks, selections) as JSON lines
|
|
- Merge with the user's terminal text to get the full picture
|
|
- The terminal message is the primary feedback; `state_dir/events` provides structured interaction data
|
|
|
|
4. **Iterate or advance** — if feedback changes current screen, write a new file (e.g., `layout-v2.html`). Only move to the next question when the current step is validated.
|
|
|
|
5. **Unload when returning to terminal** — when the next step doesn't need the browser (e.g., a clarifying question, a tradeoff discussion), push a waiting screen to clear the stale content:
|
|
|
|
```html
|
|
<!-- filename: waiting.html (or waiting-2.html, etc.) -->
|
|
<div style="display:flex;align-items:center;justify-content:center;min-height:60vh">
|
|
<p class="subtitle">Continuing in terminal...</p>
|
|
</div>
|
|
```
|
|
|
|
This prevents the user from staring at a resolved choice while the conversation has moved on. When the next visual question comes up, push a new content file as usual.
|
|
|
|
6. Repeat until done.
|
|
|
|
## Writing Content Fragments
|
|
|
|
Write just the content that goes inside the page. The server wraps it in the frame template automatically (header, theme CSS, selection indicator, and all interactive infrastructure).
|
|
|
|
**Minimal example:**
|
|
|
|
```html
|
|
<h2>Which layout works better?</h2>
|
|
<p class="subtitle">Consider readability and visual hierarchy</p>
|
|
|
|
<div class="options">
|
|
<div class="option" data-choice="a" onclick="toggleSelect(this)">
|
|
<div class="letter">A</div>
|
|
<div class="content">
|
|
<h3>Single Column</h3>
|
|
<p>Clean, focused reading experience</p>
|
|
</div>
|
|
</div>
|
|
<div class="option" data-choice="b" onclick="toggleSelect(this)">
|
|
<div class="letter">B</div>
|
|
<div class="content">
|
|
<h3>Two Column</h3>
|
|
<p>Sidebar navigation with main content</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
That's it. No `<html>`, no CSS, no `<script>` tags needed. The server provides all of that.
|
|
|
|
## CSS Classes Available
|
|
|
|
The frame template provides these CSS classes for your content:
|
|
|
|
### Options (A/B/C choices)
|
|
|
|
```html
|
|
<div class="options">
|
|
<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>
|
|
```
|
|
|
|
**Multi-select:** Add `data-multiselect` to the container to let users select multiple options. Each click toggles the item. The indicator bar shows the count.
|
|
|
|
```html
|
|
<div class="options" data-multiselect>
|
|
<!-- same option markup — users can select/deselect multiple -->
|
|
</div>
|
|
```
|
|
|
|
### Cards (visual designs)
|
|
|
|
```html
|
|
<div class="cards">
|
|
<div class="card" data-choice="design1" onclick="toggleSelect(this)">
|
|
<div class="card-image"><!-- mockup content --></div>
|
|
<div class="card-body">
|
|
<h3>Name</h3>
|
|
<p>Description</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
### Mockup container
|
|
|
|
```html
|
|
<div class="mockup">
|
|
<div class="mockup-header">Preview: Dashboard Layout</div>
|
|
<div class="mockup-body"><!-- your mockup HTML --></div>
|
|
</div>
|
|
```
|
|
|
|
### Split view (side-by-side)
|
|
|
|
```html
|
|
<div class="split">
|
|
<div class="mockup"><!-- left --></div>
|
|
<div class="mockup"><!-- right --></div>
|
|
</div>
|
|
```
|
|
|
|
### Pros/Cons
|
|
|
|
```html
|
|
<div class="pros-cons">
|
|
<div class="pros"><h4>Pros</h4><ul><li>Benefit</li></ul></div>
|
|
<div class="cons"><h4>Cons</h4><ul><li>Drawback</li></ul></div>
|
|
</div>
|
|
```
|
|
|
|
### Mock elements (wireframe building blocks)
|
|
|
|
```html
|
|
<div class="mock-nav">Logo | Home | About | Contact</div>
|
|
<div style="display: flex;">
|
|
<div class="mock-sidebar">Navigation</div>
|
|
<div class="mock-content">Main content area</div>
|
|
</div>
|
|
<button class="mock-button">Action Button</button>
|
|
<input class="mock-input" placeholder="Input field">
|
|
<div class="placeholder">Placeholder area</div>
|
|
```
|
|
|
|
### Typography and sections
|
|
|
|
- `h2` — page title
|
|
- `h3` — section heading
|
|
- `.subtitle` — secondary text below title
|
|
- `.section` — content block with bottom margin
|
|
- `.label` — small uppercase label text
|
|
|
|
## Browser Events Format
|
|
|
|
When the user clicks options in the browser, their interactions are recorded to `$STATE_DIR/events` (one JSON object per line). The file is cleared automatically when you push a new screen.
|
|
|
|
```jsonl
|
|
{"type":"click","choice":"a","text":"Option A - Simple Layout","timestamp":1706000101}
|
|
{"type":"click","choice":"c","text":"Option C - Complex Grid","timestamp":1706000108}
|
|
{"type":"click","choice":"b","text":"Option B - Hybrid","timestamp":1706000115}
|
|
```
|
|
|
|
The full event stream shows the user's exploration path — they may click multiple options before settling. The last `choice` event is typically the final selection, but the pattern of clicks can reveal hesitation or preferences worth asking about.
|
|
|
|
If `$STATE_DIR/events` doesn't exist, the user didn't interact with the browser — use only their terminal text.
|
|
|
|
## Design Tips
|
|
|
|
- **Scale fidelity to the question** — wireframes for layout, polish for polish questions
|
|
- **Explain the question on each page** — "Which layout feels more professional?" not just "Pick one"
|
|
- **Iterate before advancing** — if feedback changes current screen, write a new version
|
|
- **2-4 options max** per screen
|
|
- **Use real content when it matters** — for a photography portfolio, use actual images (Unsplash). Placeholder content obscures design issues.
|
|
- **Keep mockups simple** — focus on layout and structure, not pixel-perfect design
|
|
|
|
## File Naming
|
|
|
|
- Use semantic names: `platform.html`, `visual-style.html`, `layout.html`
|
|
- Never reuse filenames — each screen must be a new file
|
|
- For iterations: append version suffix like `layout-v2.html`, `layout-v3.html`
|
|
- Server serves newest file by modification time
|
|
|
|
## Cleaning Up
|
|
|
|
```bash
|
|
scripts/stop-server.sh $SESSION_DIR
|
|
```
|
|
|
|
If the session used `--project-dir`, mockup files persist in `.superpowers/brainstorm/` for later reference. Only `/tmp` sessions get deleted on stop.
|
|
|
|
## Reference
|
|
|
|
- Frame template (CSS reference): `scripts/frame-template.html`
|
|
- Helper script (client-side): `scripts/helper.js`
|