Arm the annotation stream with the Monitor tool:
command: npx bryllen watch --stream
persistent: true
description: Bryllen canvas annotations
The stream prints one compact JSON line per annotation; each line arrives as a notification that wakes you. Between annotations you are free — no polling loop, and the designer can chat with you while the stream is armed. Monitor notifications are canvas events, not user replies. If the stream emits a server unreachable error line (or the monitor exits), the dev server died: restart it (steps 1–2) and re-arm the Monitor.
Fallback — only if the Monitor tool is unavailable in this harness: run npx bryllen watch in a loop. Each call waits up to 15 seconds and prints either an annotation or {"timeout": true}; on timeout, run it again.
When an annotation arrives, process it by type:
Regular annotation arrives (JSON with annotation data) — process it:
The annotation IS the map. Read the fields, construct the path, done:
project → src/projects/{project}/
frameId prefix (e.g. v9-shell) → v9/ folder
componentName → file in components/ or pages/
NEVER guess the project from git commits, Explore agents, or "which is active" heuristics.
- Run
npx bryllen progress <id> "Reading file..." to show status on canvas
- Grep for
componentName in src/projects/{project}/{iteration}/ — that's the file
- Read the
comment, selector, and computedStyles for what to change
- Follow the guard protocol (see CLAUDE.md "Before any edit")
- Map to file in
v<N>/components/ or v<N>/pages/
- Run
npx bryllen progress <id> "Applying changes..."
- Token routing: Route visual value changes through
tokens.css
- Apply the requested changes
- Run
npx bryllen progress <id> "Taking screenshot..."
- Visual review: Run
npx bryllen screenshot --frame <frameId>
- Read the returned screenshot file to see the result
- Check for: broken contrast, overflow/clipping, misalignment, wrong colors, missing styles
- If issues found: fix them and screenshot again
- If clean: proceed
- Run
npx bryllen resolve <id> (this auto-commits project changes)
- Log the change to
CHANGELOG.md
- Done — the Monitor stays armed for the next annotation (poll fallback: run
npx bryllen watch again)
Iteration request arrives (JSON has type: 'iteration') — run the iteration protocol:
- Read
manifest.ts, find the active iteration (last with frozen: false)
- Freeze it (
frozen: true)
- Copy folder:
cp -r v<N>/ v<N+1>/
- Rename CSS scope in
v<N+1>/tokens.css: .iter-v<N> → .iter-v<N+1>
- Add new iteration to manifest with
frozen: false, update import paths
- Apply the changes described in the annotation's
comment
- Follow all guards (showcase, component hierarchy, token routing)
- Visual review: Run
npx bryllen screenshot (no --frame = all frames)
- Read the screenshot to verify the new iteration looks correct
- Fix any visual issues before resolving
- Run
npx bryllen resolve <id> (this auto-commits project changes)
- Log to
CHANGELOG.md
- Done — the Monitor stays armed for the next annotation (poll fallback: run
npx bryllen watch again)
Project request arrives (JSON has type: 'project') — create a new project:
- Parse the JSON comment:
{ name, description, prompt }
- Create the project folder structure:
src/projects/<name>/v1/{tokens.css, components/index.ts, pages/, context/}
- CRITICAL: tokens.css MUST use
:root, .iter-v1 as the selector — without :root, frames render as unstyled plain text because they don't have the .iter-v1 class wrapper. This is the #1 cause of "designs show unstyled text" bug.
- Create
manifest.ts (with import './v1/tokens.css' at the top) and CHANGELOG.md
- If
prompt is provided, follow the "What happens next" sequence from /bryllen-new EXACTLY — especially step 1 which REQUIRES generating 3-5 genuinely different design directions. The "All Directions" page must be the first thing the designer sees.
- Run
npx bryllen resolve <id>
- Done — the Monitor stays armed for the next annotation (poll fallback: run
npx bryllen watch again)
Share request arrives (JSON has type: 'share') — deploy to GitHub Pages:
- Parse the JSON comment:
{ project: '<name>' }
- Run
npx bryllen progress <id> "Checking GitHub authentication..."
- Check GitHub auth: run
gh auth status
- If not logged in: check for token in
~/.bryllen/auth.json
- If token exists: set
GH_TOKEN env var for gh-pages
- If no token: tell designer to click "Login with GitHub" in the Share popover
- Check gh CLI: run
which gh
- If not installed: use
npm:gh-pages package directly (it uses GH_TOKEN)
- Run
npx bryllen progress <id> "Building project..."
- Invoke
/bryllen-share <project-name> — this handles build, deploy, and URL writing
- Run
npx bryllen resolve <id>
- Done — the Monitor stays armed for the next annotation (poll fallback: run
npx bryllen watch again)
Pick request arrives (JSON has type: 'pick') — promote the picked direction(s) to a new iteration:
- Read the
frameId, frameIds, and comment from the annotation
frameIds is an array when multiple frames were selected (marquee multi-select)
frameId is a +-joined string of all IDs (e.g., "dir-a+dir-b+dir-c")
- Run
npx bryllen progress <id> "Picking direction..."
- Find each frame's source file (component or page) from the frameIds
- Create a new iteration that:
- Single pick: Copies the picked direction as the starting point
- Multi-pick: Combines ALL picked directions — extract shared patterns, merge complementary elements, resolve conflicts thoughtfully
- Builds out all states (loading, error, empty, success, etc.)
- Names it appropriately (e.g., "V3 — Picked Direction" or "V3 — Combined")
- Update the previous iteration's manifest entry:
- Single pick: Set
pickedFrameId to the chosen frame's ID (this fades other frames)
- Multi-pick: Set
pickedFrameIds to the array of chosen frame IDs (all picked frames stay unfaded)
- Set
frozen: true
- Add the new iteration to manifest with
frozen: false
- Run
npx bryllen progress <id> "Taking screenshot..."
- Run
npx bryllen screenshot to verify the result
- Run
npx bryllen resolve <id> (auto-commits)
- Log to
CHANGELOG.md
- Done — the Monitor stays armed for the next annotation (poll fallback: run
npx bryllen watch again)
Multi-pick strategy:
When the designer selects multiple frames, they want to combine strengths from each:
- Extract what works best from each direction (layout from A, color palette from B, interaction from C)
- Resolve conflicts by choosing the stronger solution or creating a synthesis
- The result should feel cohesive, not like a Frankenstein of disconnected parts
- When in doubt, ask the designer which element they prefer via a comment in the annotation response
Context image annotation arrives (annotation on a Context Image component) — use the image for inspiration:
- Run
npx bryllen context --project <name> --iteration <v> to get image paths
- Read the images with the Read tool to analyze via Vision
- Apply the designer's comment (e.g., "use these colors", "make more like this")
- Reference specific visual elements from the context images when generating
Timeout (JSON contains "timeout": true) — poll-fallback mode only; the stream never prints timeouts. No annotation arrived: run npx bryllen watch again to keep waiting.