snappy-swarm skill
$ npx snappy-skills install snappy-swarm
$ npx snappy-skills install --all
$ npx snappy-skills update
How to construct agent prompts for BOTH code-review and browser-testing agents, collect results, resolve conflicts, and decide when to stop.
typescript// No verbs exported yet. Add exports in api.ts, then document them here:
// | Function | Purpose |
// |---|---|
// | `someVerb(...)` | what it does |
bashnpx tsx ~/.claude/skills/snappy-swarm/api.ts help
env("KEY") from ../snappy-settings/load.tsNothing in the collection names this skill.
<!-- SNAPPY-CONTRACT-VERBS-START -->
Generated from api.ts HAND_CONTRACT. Do not hand-edit this block.
This skill declares no executable verbs. Its instruction-only label is intentional.
When an answer carries face_hint, show it with one snappy_present(<answer>) call.
See /snappy-faces for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->
The system spec lives at ~/.claude/skills/snappy-settings/skill-spec.md. It defines the entire Snappy operating system. You enforce it.
1. Fix gaps (P — proportional). MANDATORY. If this AGENTS.md didn't cover your case — if you had to read another file, run a command not documented here, work around a wrong selector, or discover a quirk — you MUST attempt an Edit before you can log.
agent-browser screenshot <path> takes path positionally, not as --output <path>. That's one line in a table. Edit it in. Do not just log it.2. Validate structure. Check this skill against the spec:
api.ts exists with typed exports, CLI mode, import { env } from "../snappy-settings/load.ts"api.ts calls APIs directly (no Xano proxy, unless this skill IS a Xano DB skill)AGENTS.md has API module section with import + function table + CLIcertificate: block (premises / action / trace / evidence / conclusion). Same-session toasts are NOT evidence — must be a fresh independent read. Missing or weak certificates are a gap: P-fix them inline and log to ~/.claude/logs/verification-gaps.log.~/.claude/skills/snappy-settings/scripts/dry-check.sh <name-or-keyword>. If it matches an existing skill, extend that one instead. Fragmentation is the enemy.2b. If you just reported an action as successful, verify your certificate. You may not claim PASS unless the evidence: line is a fresh independent read (reload, new session, server round-trip). If your evidence is a toast, a return value, or a same-session DOM read, downgrade the claim to INCONCLUSIVE and log to verification-gaps.log.
3. Log always.
bashecho "[$(date -u +%FT%TZ)] <skill-name>: <what was missing or fixed> [FIXED|LOGGED]" >> ~/.claude/logs/agents-md-feedback.log
FIXED = you patched it. LOGGED = too large for inline fix, queued for drain-skill-regen.sh.
Do not skip this. Every agent run must leave the system better than it found it.
<!-- SKILL-INDEX-START -->
[snappy-swarm Index]|root: ~/.claude/skills/snappy-swarm|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,agents-md-setup.md,interview-questions.md,swarm-modes.md,wave-orchestration.md}
<!-- SKILL-INDEX-END -->
---
name: snappy-swarm
description: How to construct agent prompts for BOTH code-review and browser-testing agents, collect results, resolve conflicts, and decide when to stop.
---
# snappy-swarm — Agent Loader
How to construct agent prompts for BOTH code-review and browser-testing agents, collect results, resolve conflicts, and decide when to stop.
## API
```typescript
// No verbs exported yet. Add exports in api.ts, then document them here:
// | Function | Purpose |
// |---|---|
// | `someVerb(...)` | what it does |
```
## CLI
```bash
npx tsx ~/.claude/skills/snappy-swarm/api.ts help
```
## Rules
- Credentials via `env("KEY")` from `../snappy-settings/load.ts`
- Direct API calls only — no Xano proxying unless this IS a Xano DB skill
- No hardcoded tokens, no bash fallbacks
- Every exported function returns a real value or throws; no silent "TODO"s
## Used by
Nothing in the collection names this skill.
<!-- SNAPPY-CONTRACT-VERBS-START -->
## Contract verbs
Generated from `api.ts` `HAND_CONTRACT`. Do not hand-edit this block.
This skill declares no executable verbs. Its `instruction-only` label is intentional.
## Show the result
When an answer carries `face_hint`, show it with one `snappy_present(<answer>)` call.
See `/snappy-faces` for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->
---
## Self-correcting loader (PID feedback)
The system spec lives at `~/.claude/skills/snappy-settings/skill-spec.md`. It defines the entire Snappy operating system. You enforce it.
### Before you finish, do two things:
**1. Fix gaps (P — proportional). MANDATORY.** If this AGENTS.md didn't cover your case — if you had to read another file, run a command not documented here, work around a wrong selector, or discover a quirk — you MUST attempt an `Edit` before you can log.
- **Default action: edit this AGENTS.md.** Surgical. Add the missing line, table row, or code example where it belongs. No restructuring.
- **Only LOGGED is allowed when:** the fix needs >10 lines, spans multiple files, or requires a structural rewrite (in which case the drain-skill-regen.sh queue picks it up).
- "I didn't have time" / "it's minor" / "the next agent will figure it out" are NOT valid reasons to skip the Edit. The whole point of this loop is that minor gaps compound.
- Concrete example of a valid P-fix: lesson-2 ship agent discovered `agent-browser screenshot <path>` takes path positionally, not as `--output <path>`. That's one line in a table. Edit it in. Do not just log it.
- The goal: the next agent never has to leave the loader.
**2. Validate structure.** Check this skill against the spec:
- `api.ts` exists with typed exports, CLI mode, `import { env } from "../snappy-settings/load.ts"`
- `api.ts` calls APIs directly (no Xano proxy, unless this skill IS a Xano DB skill)
- `AGENTS.md` has API module section with import + function table + CLI
- No bash fallbacks, no hardcoded tokens anywhere
- **Every action row carries a `certificate:` block** (premises / action / trace / evidence / conclusion). Same-session toasts are NOT evidence — must be a fresh independent read. Missing or weak certificates are a gap: P-fix them inline and log to `~/.claude/logs/verification-gaps.log`.
- **DRY:** before you add a new function or new skill, run `~/.claude/skills/snappy-settings/scripts/dry-check.sh <name-or-keyword>`. If it matches an existing skill, extend that one instead. Fragmentation is the enemy.
- If any check fails → fix it or log it
**2b. If you just reported an action as successful, verify your certificate.** You may not claim PASS unless the `evidence:` line is a fresh independent read (reload, new session, server round-trip). If your evidence is a toast, a return value, or a same-session DOM read, downgrade the claim to INCONCLUSIVE and log to `verification-gaps.log`.
**3. Log always.**
```bash
echo "[$(date -u +%FT%TZ)] <skill-name>: <what was missing or fixed> [FIXED|LOGGED]" >> ~/.claude/logs/agents-md-feedback.log
```
`FIXED` = you patched it. `LOGGED` = too large for inline fix, queued for drain-skill-regen.sh.
**Do not skip this.** Every agent run must leave the system better than it found it.
<!-- SKILL-INDEX-START -->
[snappy-swarm Index]|root: ~/.claude/skills/snappy-swarm|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,agents-md-setup.md,interview-questions.md,swarm-modes.md,wave-orchestration.md}
<!-- SKILL-INDEX-END -->
Orchestrate parallel AI agent swarms for multi-wave quality passes. Code-review agents fix what they can see in source. Browser agents fight through the real app — clicking buttons, filling forms, navigating flows, and finding the bugs that only surface when you actually use the thing.
You have a project. You want every page, every component, every flow brought up in quality — not one at a time, but in waves. Snappy Swarm interviews you once to understand scope, then fires wave after wave of parallel agents. Some read code. Others open a real browser and use your app like a real user would — tapping, scrolling, typing, and refusing to accept broken shit.
/snappy-swarm1. /snappy-swarm
2. Answer 4-5 interview questions (multiple choice)
3. AGENTS.md gets created/updated with project context
4. Wave 1 fires: parallel agents audit and fix (code + browser)
5. Wave 2 fires: agents verify fixes + catch what Wave 1 missed
6. Repeat until quality target met
| Need to... | Read this |
|---|---|
| Understand swarm modes | swarm-modes.md |
| Set up AGENTS.md | agents-md-setup.md |
| See interview flow details | interview-questions.md |
| Understand wave orchestration | wave-orchestration.md |
Before any agents fire, interview the user to lock in scope. Use AskUserQuestion with multiple choice. The interview captures everything needed so agents can work autonomously.
Q1: "What kind of swarm?"
→ Code Review (read source, find and fix issues)
→ Browser Testing (agents open the app, click through features, find real UX bugs)
→ Full Assault (Recommended) (code review THEN browser testing waves)
Q2: "What's the scope?"
→ Entire app (every page and component)
→ Specific pages (list them)
→ Specific system (auth, feed, chat, etc.)
→ Changed files only (git diff)
Q3: "Quality standard?"
→ Ship it (fix critical issues only)
→ Premium polish (Recommended) (thorough but pragmatic)
→ Obsessive (every detail, every edge case, fight for perfection)
Q4: "How many waves?"
→ Quick pass (1 wave, fast fixes)
→ Standard (2-3 waves) (Recommended) (each wave builds on last)
→ Until perfect (keep going until zero issues found)
Q5: "Auto-commit after each wave?"
→ Yes, commit with wave summary
→ No, I'll review and commit manually (Recommended)
After the interview, summarize the swarm plan and get confirmation before firing.
Dev server check: If the swarm includes browser testing, ask the user to confirm their dev server is running and on what port. Browser agents need a live URL.
Auth credentials: For browser testing, also ask for login credentials (email/password). The orchestrator saves these to agent-browser's encrypted auth vault so agents can auto-login.
Before agents can work effectively, they need project context. Check if AGENTS.md exists at project root.
If missing: Generate one using the vercel-agent methodology (see agents-md-setup.md):
If exists: Read it, verify it's current, update if stale.
The AGENTS.md is critical — it's what makes every agent in the swarm effective without re-explaining context.
CRITICAL: This phase runs BEFORE any browser-testing wave. Skip for code-review-only swarms.
Browser agents run in parallel — each one needs its own isolated browser session. Without session isolation, agents share one browser and fight over the same page (all get stuck on login).
bash# 1. Save auth credentials to agent-browser's encrypted vault
agent-browser auth save app-login \
--url {dev_server_url} \
--username {login_email} \
--password {login_password}
# 2. Verify auth works with a test session
agent-browser --session preflight-test auth login app-login
agent-browser --session preflight-test snapshot -i
# Should show authenticated app shell — NOT a login page
agent-browser --session preflight-test close
# 3. Each agent's prompt includes:
# export AGENT_BROWSER_SESSION=agent-{N}
# agent-browser auth login app-login
--session agent-1 creates a fully isolated browser instance (own cookies, own page state)AGENT_BROWSER_SESSION=agent-1 env var does the same thing — simpler for agentsauth login app-login navigates to the saved URL, auto-fills the form, and submitsagent-browser session list shows all active sessionsagent-browser --session agent-N closeSee wave-orchestration.md for the complete browser agent prompt template with session setup.
Code-Review Agents (subagent_type: "general-purpose"):
Browser-Testing Agents (subagent_type: "general-purpose" with agent-browser):
AGENT_BROWSER_SESSION=agent-{N})agent-browser auth login app-login (credentials saved by orchestrator)snapshot -i to see interactive elements with @ref selectorsclick @e5), fill forms (fill @e3 "text"), navigate, scroll┌──────────────────────────────────────────────────────┐
│ WAVE N │
│ │
│ 1. Divide scope into parallel work units │
│ 2. Fire agents (code-review OR browser-testing) │
│ 3. Agents find issues AND fix them │
│ 4. Collect results │
│ 5. Build check │
│ 6. Feed summary into Wave N+1 │
└──────────────────────────────────────────────────────┘
Code Review swarm: All waves are code-review agents.
Browser Testing swarm: All waves are browser-testing agents.
Full Assault swarm (recommended):
This order matters — fix code-level issues first so browser agents aren't tripped up by obvious bugs.
Each agent gets a specific feature or page to own:
Code-Review Swarm:
Agent 1 → /home (feed, stories, post cards)
Agent 2 → /messages (DM list, conversation view)
Agent 3 → /profile (user profile, settings)
Agent 4 → /groups (group list, group chat)
Browser-Testing Swarm (each agent gets a FEATURE to exercise):
Agent 1 → Studio Panel: tap companion, open studio, configure, generate
Agent 2 → Messaging: open DM, send message, see AI reply, scroll history
Agent 3 → Group Chat: open group, send message, see round-robin responses
Agent 4 → Feed Interaction: like/unlike posts, open iterate dialog, comment
Agent 5 → Navigation: settings, profile, search, back button, deep links
Key difference: Browser agents are assigned by FEATURE/FLOW, not just page. They exercise a complete user journey end-to-end.
Use the Agent tool with subagent_type: "general-purpose". Fire all independent agents in a single message for true parallelism.
For browser agents: The orchestrator MUST run agent-browser auth save before firing. Each agent's prompt includes export AGENT_BROWSER_SESSION=agent-{N} and agent-browser auth login app-login as the very first steps.
See wave-orchestration.md for complete prompt templates for both code-review and browser-testing agents, including the full browser session setup block.
After all agents in a wave complete:
npm run build) to catch any conflicts## Wave {N} Complete — {Code Review | Browser Testing}
### Agents: {count}
### Issues Found: {count}
### Issues Fixed: {count}
### Files Modified: {list}
### By Agent:
- Agent 1 (Studio Panel): Tested 3 flows — found 2 bugs, fixed 2
- Agent 2 (Messaging): Tested send/receive — found 1 issue, fixed 1
...
### Remaining Issues:
- [Issue that needs human decision]
- [Issue that spans multiple scopes]
### Build Status: PASS/FAIL
### Next Wave: Yes/No — [reason]
| Mode | What Happens |
|---|---|
| Code Review | Agents read source, fix issues. Fast. Catches type errors, missing states, perf issues. |
| Browser Testing | Agents open the app, click through features, find real UX bugs. Slower but catches what code review can't. |
| Full Assault | Code review first, then browser testing. Best of both worlds. Recommended. |
See swarm-modes.md for detailed checklists per mode.
Browser agents are NOT passive observers. They are aggressive testers who:
AGENT_BROWSER_SESSION=agent-{N}agent-browser auth save BEFORE firing browser agents. Agents should never manually fill login formsUser: /snappy-swarm
[Interview]
Q1: Full Assault (code review + browser testing)
Q2: Entire app
Q3: Obsessive
Q4: Standard (2-3 waves)
Q5: Yes, auto-commit
Dev server: localhost:3000 confirmed
Auth: user@example.com / password123
[Phase 2: AGENTS.md created/verified]
[Phase 2.5: Browser Session Setup]
→ agent-browser auth save app-login --url http://localhost:3000 --username user@example.com --password password123
→ Preflight test: auth login → snapshot -i → authenticated ✓
[Wave 1: Code Review — 5 agents fire in parallel]
Agent 1: /home — fixed 4 issues (skeleton mismatch, missing loading state, ...)
Agent 2: /messages — fixed 6 issues (stale message detection, polling dedup, ...)
Agent 3: /profile — fixed 2 issues (avatar fallback, responsive layout)
Agent 4: /groups — fixed 3 issues (message ordering, typing indicator)
Agent 5: /settings — fixed 1 issue (dark mode toggle transition)
Build: PASS
Commit: "fix: wave 1 — 16 code-review fixes across all pages"
[Wave 2: Browser Testing — 4 agents fire in parallel, each with own session]
→ Agent 1: AGENT_BROWSER_SESSION=agent-1, auth login → /home ✓
→ Agent 2: AGENT_BROWSER_SESSION=agent-2, auth login → /messages ✓
→ Agent 3: AGENT_BROWSER_SESSION=agent-3, auth login → /groups ✓
→ Agent 4: AGENT_BROWSER_SESSION=agent-4, auth login → /home ✓
Agent 1: Studio flow — found flyout buttons untargetable during animation → fixed scale
Agent 2: Messaging — send DM works, AI reply appears, scroll OK
Agent 3: Group chat — round-robin works, but typing indicator stuck → fixed
Agent 4: Feed — like/unlike works, iterate dialog Grok preset selection works
Build: PASS
Commit: "fix: wave 2 — 3 browser-testing fixes (animation, typing indicator)"
[Session cleanup: agent-browser session list → close all]
[Wave 3: Browser Testing — 0 new issues → DONE]
Final report delivered.
Detailed checklists for code-review and browser-testing agents.
How to generate and maintain AGENTS.md using vercel-agent methodology.
Complete interview flow with all questions and how answers map to swarm configuration.
Deep dive into wave execution — agent prompt construction for BOTH code-review and browser-testing agents, result collection, build verification.
agent-browser — Browser automation CLI that browser-testing agents usevercel-agent — AGENTS.md generation methodologydogfood — Manual app testing (swarm automates this)debug-fix-verify-agent — Individual debug workflowfrontend-dev-guidelines / backend-dev-guidelines — Quality standardsSkill Status: COMPLETE
Progressive Disclosure: 4 resource files
Skills whose description overlaps this one enough that a reader could pick the
wrong door. Each row is that skill's own first sentence about itself, so the
choice is made on its words, not on a summary written here.
| Skill | Reach for it instead when |
|---|---|
snappy-agent-host |
Run the REAL Claude Code, Codex, and Gemini CLIs through ACP via the skills MCP, with durable… |
snappy-ax |
Drive any Mac app through the Accessibility tree (AXUIElement) the way the shipping tools act… |
snappy-browse |
THE DEFAULT for actually driving a browser on this machine -- Snappy stack and client sites v… |
snappy-calendar |
Google Calendar operations for Snappy -- view events, create meetings, check availability, sc… |
snappy-client-total |
Jordan Cameron's mortgage adviser CRM for New Zealand -- the largest and most active client e… |
snappy-deploy |
Meta-deployment skill that orchestrates ALL Snappy project deployments across the four suppor… |
snappy-desktop |
macOS desktop automation primitive for the Snappy stack via Midscene vision AI (`npx @midscen… |
snappy-dom-cartographer |
Master DOM mapping agent for the Snappy swarm. |
snappy-maintenance |
Snappy project maintenance -- keeping all client and internal systems healthy across Vercel… |
snappy-nightshift |
The overnight orchestration operating system: one orchestrator drives a repo toward 100% all… |
snappy-os-operator |
Operate SnappyOS like a pro through product doors only: governed connector reads, staged writ… |
snappy-resident |
The non-stop user seat: drive the Snappy OS app as a real user through a real browser (agent-… |
snappy-voice-control |
Voice control on macOS, extracted from two shipping open-source agents (fazm by mediar-ai; Ag… |
---
name: snappy-swarm
instruction-only: true
description: >
Orchestrate swarms of parallel AI agents for multi-wave quality passes across a project.
Interview mode sets scope, then fires wave after wave of agents — code-review agents AND
browser-testing agents that actually click, type, navigate, and fight through the real app.
Sets up AGENTS.md for agent context. Browser agents use agent-browser to find real UX bugs
that code review alone will never catch.
Triggers: snappy swarm, quality swarm, agent swarm, multi-wave, quality pass, wave of agents,
swarm mode, parallel agents, quality sweep, bulk improvements, polish everything, fix everything,
improve all pages, dogfood swarm, ship quality, browser test, e2e swarm, click through the app
---
# Snappy Swarm
Orchestrate parallel AI agent swarms for multi-wave quality passes. Code-review agents fix what they can see in source. **Browser agents fight through the real app** — clicking buttons, filling forms, navigating flows, and finding the bugs that only surface when you actually use the thing.
## Purpose
You have a project. You want every page, every component, every flow brought up in quality — not one at a time, but in waves. Snappy Swarm interviews you once to understand scope, then fires wave after wave of parallel agents. Some read code. **Others open a real browser and use your app like a real user would** — tapping, scrolling, typing, and refusing to accept broken shit.
## When to Use This Skill
- "I want quality passes on every page"
- "Polish everything" / "fix everything"
- "Send agents to improve the whole app"
- "Run a swarm" / "quality sweep"
- "Dogfood the whole app and fix what you find"
- "Test the app in a real browser"
- "Click through every feature and fix what's broken"
- User invokes `/snappy-swarm`
- Large codebase needs systematic improvement across many files
---
## Quick Start
```
1. /snappy-swarm
2. Answer 4-5 interview questions (multiple choice)
3. AGENTS.md gets created/updated with project context
4. Wave 1 fires: parallel agents audit and fix (code + browser)
5. Wave 2 fires: agents verify fixes + catch what Wave 1 missed
6. Repeat until quality target met
```
---
## Navigation Guide
| Need to... | Read this |
|------------|-----------|
| Understand swarm modes | [swarm-modes.md](swarm-modes.md) |
| Set up AGENTS.md | [agents-md-setup.md](agents-md-setup.md) |
| See interview flow details | [interview-questions.md](interview-questions.md) |
| Understand wave orchestration | [wave-orchestration.md](wave-orchestration.md) |
---
## The Interview (Phase 1)
Before any agents fire, interview the user to lock in scope. Use `AskUserQuestion` with multiple choice. The interview captures everything needed so agents can work autonomously.
### Batch 1 — What and Where
```
Q1: "What kind of swarm?"
→ Code Review (read source, find and fix issues)
→ Browser Testing (agents open the app, click through features, find real UX bugs)
→ Full Assault (Recommended) (code review THEN browser testing waves)
Q2: "What's the scope?"
→ Entire app (every page and component)
→ Specific pages (list them)
→ Specific system (auth, feed, chat, etc.)
→ Changed files only (git diff)
```
### Batch 2 — How Deep
```
Q3: "Quality standard?"
→ Ship it (fix critical issues only)
→ Premium polish (Recommended) (thorough but pragmatic)
→ Obsessive (every detail, every edge case, fight for perfection)
Q4: "How many waves?"
→ Quick pass (1 wave, fast fixes)
→ Standard (2-3 waves) (Recommended) (each wave builds on last)
→ Until perfect (keep going until zero issues found)
```
### Batch 3 — Commits
```
Q5: "Auto-commit after each wave?"
→ Yes, commit with wave summary
→ No, I'll review and commit manually (Recommended)
```
After the interview, summarize the swarm plan and get confirmation before firing.
**Dev server check**: If the swarm includes browser testing, ask the user to confirm their dev server is running and on what port. Browser agents need a live URL.
**Auth credentials**: For browser testing, also ask for login credentials (email/password). The orchestrator saves these to agent-browser's encrypted auth vault so agents can auto-login.
---
## AGENTS.md Setup (Phase 2)
Before agents can work effectively, they need project context. Check if `AGENTS.md` exists at project root.
**If missing**: Generate one using the vercel-agent methodology (see [agents-md-setup.md](agents-md-setup.md)):
1. Scan project structure (framework, conventions, key files)
2. Identify stack versions that differ from training data
3. Document build/test/lint commands
4. List common pitfalls specific to this codebase
5. Write compressed, retrieval-led AGENTS.md
**If exists**: Read it, verify it's current, update if stale.
The AGENTS.md is critical — it's what makes every agent in the swarm effective without re-explaining context.
---
## Browser Session Setup (Phase 2.5 — Before Browser Waves)
**CRITICAL**: This phase runs BEFORE any browser-testing wave. Skip for code-review-only swarms.
Browser agents run in parallel — each one needs its **own isolated browser session**. Without session isolation, agents share one browser and fight over the same page (all get stuck on login).
### What the Orchestrator Does
```bash
# 1. Save auth credentials to agent-browser's encrypted vault
agent-browser auth save app-login \
--url {dev_server_url} \
--username {login_email} \
--password {login_password}
# 2. Verify auth works with a test session
agent-browser --session preflight-test auth login app-login
agent-browser --session preflight-test snapshot -i
# Should show authenticated app shell — NOT a login page
agent-browser --session preflight-test close
# 3. Each agent's prompt includes:
# export AGENT_BROWSER_SESSION=agent-{N}
# agent-browser auth login app-login
```
### How Session Isolation Works
- `--session agent-1` creates a fully isolated browser instance (own cookies, own page state)
- `AGENT_BROWSER_SESSION=agent-1` env var does the same thing — simpler for agents
- `auth login app-login` navigates to the saved URL, auto-fills the form, and submits
- Each agent is independently authenticated in its own browser
- `agent-browser session list` shows all active sessions
- Sessions are cleaned up with `agent-browser --session agent-N close`
See [wave-orchestration.md](wave-orchestration.md) for the complete browser agent prompt template with session setup.
---
## Wave Execution (Phase 3)
### Two Types of Agents
**Code-Review Agents** (subagent_type: "general-purpose"):
- Read source files, find issues, edit files to fix them
- Great at: type safety, missing error handling, performance patterns, code style
- Blind spot: can't see what the app actually looks like or how it behaves in a browser
**Browser-Testing Agents** (subagent_type: "general-purpose" with agent-browser):
- Each agent gets its OWN isolated browser session (`AGENT_BROWSER_SESSION=agent-{N}`)
- Auto-login via `agent-browser auth login app-login` (credentials saved by orchestrator)
- Open the real running app in a browser and USE IT
- Use `snapshot -i` to see interactive elements with `@ref` selectors
- Click buttons (`click @e5`), fill forms (`fill @e3 "text"`), navigate, scroll
- Find bugs that only appear at runtime: broken clicks, missing elements, wrong routing, animations that block interaction
- **FIGHT to make things work** — don't just accept that a button doesn't respond, investigate WHY and fix the underlying code
- After finding a bug through the browser, they switch to reading/editing source code to fix it
### Wave Structure
```
┌──────────────────────────────────────────────────────┐
│ WAVE N │
│ │
│ 1. Divide scope into parallel work units │
│ 2. Fire agents (code-review OR browser-testing) │
│ 3. Agents find issues AND fix them │
│ 4. Collect results │
│ 5. Build check │
│ 6. Feed summary into Wave N+1 │
└──────────────────────────────────────────────────────┘
```
### Wave Ordering by Swarm Type
**Code Review swarm**: All waves are code-review agents.
**Browser Testing swarm**: All waves are browser-testing agents.
**Full Assault swarm** (recommended):
- Wave 1: Code-review agents (fix obvious source-level issues first)
- Wave 2: Browser-testing agents (find UX bugs in the now-cleaner app)
- Wave 3+: Browser-testing agents (verify fixes, find remaining issues)
This order matters — fix code-level issues first so browser agents aren't tripped up by obvious bugs.
### Work Unit Division
Each agent gets a specific feature or page to own:
```
Code-Review Swarm:
Agent 1 → /home (feed, stories, post cards)
Agent 2 → /messages (DM list, conversation view)
Agent 3 → /profile (user profile, settings)
Agent 4 → /groups (group list, group chat)
Browser-Testing Swarm (each agent gets a FEATURE to exercise):
Agent 1 → Studio Panel: tap companion, open studio, configure, generate
Agent 2 → Messaging: open DM, send message, see AI reply, scroll history
Agent 3 → Group Chat: open group, send message, see round-robin responses
Agent 4 → Feed Interaction: like/unlike posts, open iterate dialog, comment
Agent 5 → Navigation: settings, profile, search, back button, deep links
```
**Key difference**: Browser agents are assigned by FEATURE/FLOW, not just page. They exercise a complete user journey end-to-end.
### Firing Agents
Use the `Agent` tool with `subagent_type: "general-purpose"`. Fire all independent agents in a **single message** for true parallelism.
**For browser agents**: The orchestrator MUST run `agent-browser auth save` before firing. Each agent's prompt includes `export AGENT_BROWSER_SESSION=agent-{N}` and `agent-browser auth login app-login` as the very first steps.
### Agent Prompt Templates
See [wave-orchestration.md](wave-orchestration.md) for complete prompt templates for both code-review and browser-testing agents, including the full browser session setup block.
### Between Waves
After all agents in a wave complete:
1. **Collect results** from each agent
2. **Deduplicate** overlapping fixes
3. **Run build** (`npm run build`) to catch any conflicts
4. **Summarize** wave results for the user
5. **Decide** whether to fire another wave:
- If issues remain → fire Wave N+1 with findings
- If quality target met → stop and report
- If "until perfect" mode → keep going until a wave finds zero issues
### Wave Summary Format
```
## Wave {N} Complete — {Code Review | Browser Testing}
### Agents: {count}
### Issues Found: {count}
### Issues Fixed: {count}
### Files Modified: {list}
### By Agent:
- Agent 1 (Studio Panel): Tested 3 flows — found 2 bugs, fixed 2
- Agent 2 (Messaging): Tested send/receive — found 1 issue, fixed 1
...
### Remaining Issues:
- [Issue that needs human decision]
- [Issue that spans multiple scopes]
### Build Status: PASS/FAIL
### Next Wave: Yes/No — [reason]
```
---
## Swarm Modes (Quick Reference)
| Mode | What Happens |
|------|-------------|
| Code Review | Agents read source, fix issues. Fast. Catches type errors, missing states, perf issues. |
| Browser Testing | Agents open the app, click through features, find real UX bugs. Slower but catches what code review can't. |
| Full Assault | Code review first, then browser testing. Best of both worlds. **Recommended.** |
See [swarm-modes.md](swarm-modes.md) for detailed checklists per mode.
---
## Browser Agent Philosophy
Browser agents are NOT passive observers. They are **aggressive testers** who:
1. **Fight to make things work** — If a button doesn't respond, they investigate why. Is it covered by another element? Is the click handler broken? Is an animation blocking it?
2. **Don't accept the status quo** — "It loaded without crashing" is not a passing grade. They verify that every interactive element actually does what it should.
3. **Exercise real user flows** — Not just "can I see the page" but "can I tap this companion, open studio, pick a style, and generate?"
4. **Fix what they find** — After discovering a bug through the browser, they read the source code, understand the root cause, and edit the file to fix it.
5. **Report precisely** — "Button X at [aria-label=Studio] doesn't appear when companion selected because flyoutPosition is null" not "something seems off."
---
## Anti-Patterns
- **Don't skip the interview** — Agents without clear scope waste context window
- **Don't fire browser agents without session isolation** — They'll share one browser and fight over the login page. Every agent needs `AGENT_BROWSER_SESSION=agent-{N}`
- **Don't skip auth setup** — Run `agent-browser auth save` BEFORE firing browser agents. Agents should never manually fill login forms
- **Don't fire too many agents at once** — 4-6 per wave is ideal; more causes merge conflicts
- **Don't skip the build check between waves** — Parallel edits can conflict
- **Don't use for tiny changes** — If it's one file, just edit it directly
- **Don't forget AGENTS.md** — Agents without project context make training-data assumptions
- **Don't treat browser testing as optional** — Code review alone misses half the bugs. Real users click things.
---
## Example Session
```
User: /snappy-swarm
[Interview]
Q1: Full Assault (code review + browser testing)
Q2: Entire app
Q3: Obsessive
Q4: Standard (2-3 waves)
Q5: Yes, auto-commit
Dev server: localhost:3000 confirmed
Auth: user@example.com / password123
[Phase 2: AGENTS.md created/verified]
[Phase 2.5: Browser Session Setup]
→ agent-browser auth save app-login --url http://localhost:3000 --username user@example.com --password password123
→ Preflight test: auth login → snapshot -i → authenticated ✓
[Wave 1: Code Review — 5 agents fire in parallel]
Agent 1: /home — fixed 4 issues (skeleton mismatch, missing loading state, ...)
Agent 2: /messages — fixed 6 issues (stale message detection, polling dedup, ...)
Agent 3: /profile — fixed 2 issues (avatar fallback, responsive layout)
Agent 4: /groups — fixed 3 issues (message ordering, typing indicator)
Agent 5: /settings — fixed 1 issue (dark mode toggle transition)
Build: PASS
Commit: "fix: wave 1 — 16 code-review fixes across all pages"
[Wave 2: Browser Testing — 4 agents fire in parallel, each with own session]
→ Agent 1: AGENT_BROWSER_SESSION=agent-1, auth login → /home ✓
→ Agent 2: AGENT_BROWSER_SESSION=agent-2, auth login → /messages ✓
→ Agent 3: AGENT_BROWSER_SESSION=agent-3, auth login → /groups ✓
→ Agent 4: AGENT_BROWSER_SESSION=agent-4, auth login → /home ✓
Agent 1: Studio flow — found flyout buttons untargetable during animation → fixed scale
Agent 2: Messaging — send DM works, AI reply appears, scroll OK
Agent 3: Group chat — round-robin works, but typing indicator stuck → fixed
Agent 4: Feed — like/unlike works, iterate dialog Grok preset selection works
Build: PASS
Commit: "fix: wave 2 — 3 browser-testing fixes (animation, typing indicator)"
[Session cleanup: agent-browser session list → close all]
[Wave 3: Browser Testing — 0 new issues → DONE]
Final report delivered.
```
---
## Resource Files
### [swarm-modes.md](swarm-modes.md)
Detailed checklists for code-review and browser-testing agents.
### [agents-md-setup.md](agents-md-setup.md)
How to generate and maintain AGENTS.md using vercel-agent methodology.
### [interview-questions.md](interview-questions.md)
Complete interview flow with all questions and how answers map to swarm configuration.
### [wave-orchestration.md](wave-orchestration.md)
Deep dive into wave execution — agent prompt construction for BOTH code-review and browser-testing agents, result collection, build verification.
---
## Related Skills
- `agent-browser` — Browser automation CLI that browser-testing agents use
- `vercel-agent` — AGENTS.md generation methodology
- `dogfood` — Manual app testing (swarm automates this)
- `debug-fix-verify-agent` — Individual debug workflow
- `frontend-dev-guidelines` / `backend-dev-guidelines` — Quality standards
---
**Skill Status**: COMPLETE
**Progressive Disclosure**: 4 resource files
## Near neighbours
Skills whose description overlaps this one enough that a reader could pick the
wrong door. Each row is that skill's own first sentence about itself, so the
choice is made on its words, not on a summary written here.
| Skill | Reach for it instead when |
|---|---|
| `snappy-agent-host` | Run the REAL Claude Code, Codex, and Gemini CLIs through ACP via the skills MCP, with durable… |
| `snappy-ax` | Drive any Mac app through the Accessibility tree (AXUIElement) the way the shipping tools act… |
| `snappy-browse` | THE DEFAULT for actually driving a browser on this machine -- Snappy stack and client sites v… |
| `snappy-calendar` | Google Calendar operations for Snappy -- view events, create meetings, check availability, sc… |
| `snappy-client-total` | Jordan Cameron's mortgage adviser CRM for New Zealand -- the largest and most active client e… |
| `snappy-deploy` | Meta-deployment skill that orchestrates ALL Snappy project deployments across the four suppor… |
| `snappy-desktop` | macOS desktop automation primitive for the Snappy stack via Midscene vision AI (`npx @midscen… |
| `snappy-dom-cartographer` | Master DOM mapping agent for the Snappy swarm. |
| `snappy-maintenance` | Snappy project maintenance -- keeping all client and internal systems healthy across Vercel… |
| `snappy-nightshift` | The overnight orchestration operating system: one orchestrator drives a repo toward 100% all… |
| `snappy-os-operator` | Operate SnappyOS like a pro through product doors only: governed connector reads, staged writ… |
| `snappy-resident` | The non-stop user seat: drive the Snappy OS app as a real user through a real browser (agent-… |
| `snappy-voice-control` | Voice control on macOS, extracted from two shipping open-source agents (fazm by mediar-ai; Ag… |
How to generate and maintain an AGENTS.md file that gives every swarm agent the project context it needs to work effectively.
Based on Vercel's research: passive context via AGENTS.md achieves 100% pass rate vs 53% baseline.
Without AGENTS.md, each agent in the swarm:
With AGENTS.md, every agent:
bash# Framework detection
ls package.json tsconfig.json next.config.* vite.config.* nuxt.config.*
# Key directories
ls -la app/ src/ components/ lib/ pages/ public/
# Dependencies
cat package.json | jq '.dependencies, .devDependencies'
# Build/test commands
cat package.json | jq '.scripts'
This is THE critical step. Ask:
Follow this exact structure (order matters for context window efficiency):
markdown# AGENTS.md
## Project Overview
[1-2 sentences: what this project is]
## Stack
- Framework: [exact version]
- Language: [TypeScript/JavaScript + version]
- Styling: [Tailwind/CSS Modules/etc + version]
- State: [React state/Zustand/Redux/etc]
- Backend: [API layer details]
- Database: [if applicable]
## Architecture
[Key architectural decisions — monorepo? API routes? Service layer?]
## File Conventions
app/ → Next.js App Router pages
components/ → Reusable UI components
lib/ → Utilities, hooks, services
lib/services/ → API client functions
lib/types/ → TypeScript type definitions
## Commands
npm run dev # Development server
npm run build # Production build
npm run typecheck # Type checking
npm run lint # Linting
npm test # Tests
## Key Patterns
### [Pattern 1: e.g., API Calls]
[How API calls work in this project — not how they work in general]
### [Pattern 2: e.g., Component Structure]
[Project-specific component patterns]
## Common Pitfalls
- [Thing that looks right but is wrong in this project]
- [Deprecated pattern that training data still suggests]
- [Non-obvious requirement]
## Environment
[Required env vars, without values]
Quick validation checklist:
AGENTS.md goes stale. Update when:
After each swarm run, check if agents made mistakes that better AGENTS.md would have prevented. If so, update it.
| File | Purpose | Audience |
|---|---|---|
CLAUDE.md |
User's personal instructions for Claude | Main Claude session |
AGENTS.md |
Project context for all AI agents | Swarm agents, any AI tool |
They complement each other. CLAUDE.md has user preferences; AGENTS.md has project facts.
If CLAUDE.md already has good project context, AGENTS.md can reference it or extract the project-specific parts.
markdown# AGENTS.md
## Project Overview
Next.js frontend with Xano backend, Tailwind CSS styling.
## Stack
- Next.js 16 (App Router, Turbopack)
- TypeScript 5.x (strict mode)
- Tailwind CSS 4.x
- Xano backend (REST API)
- shadcn/ui components
## Architecture
- App Router with (app) group for authenticated routes
- Service layer in lib/services/ wraps all API calls
- Types in lib/types/ — always import from there
- Components use shadcn/ui primitives
## File Conventions
app/(app)/[page]/page.tsx → Authenticated pages
app/(auth)/[page]/page.tsx → Auth pages (login, signup)
components/[name].tsx → PascalCase, one component per file
lib/services/index.ts → All API functions
lib/types/index.ts → All TypeScript types
lib/hooks/ → Custom React hooks
## Commands
npm run dev # Dev server with Turbopack
npm run build # Production build (run before committing)
npm run lint # ESLint
## Key Patterns
- API calls: Use apiClient() from lib/services, never raw fetch
- Auth: Token stored in cookies, apiClient handles headers
- Loading: Use skeleton components from components/skeleton-loader
- Errors: Toast via sonner, error boundaries for crashes
## Common Pitfalls
- Don't import server-only code in client components
- Avatar URLs have fallback chain: default_avatar_url || avatar_url
- Build must pass before committing (pre-commit hook)
- Use --no-verify if eslint hook has circular JSON error
# AGENTS.md Setup Guide How to generate and maintain an AGENTS.md file that gives every swarm agent the project context it needs to work effectively. Based on Vercel's research: passive context via AGENTS.md achieves **100% pass rate** vs 53% baseline. --- ## Why AGENTS.md Matters for Swarms Without AGENTS.md, each agent in the swarm: - Relies on training data (often outdated) - Doesn't know project conventions - Makes wrong assumptions about file locations - Uses deprecated patterns - Creates inconsistent code With AGENTS.md, every agent: - Knows the exact stack and versions - Follows project conventions - Finds files where they actually are - Uses current patterns - Produces consistent code --- ## Generation Workflow ### Step 1: Scan Project Structure ```bash # Framework detection ls package.json tsconfig.json next.config.* vite.config.* nuxt.config.* # Key directories ls -la app/ src/ components/ lib/ pages/ public/ # Dependencies cat package.json | jq '.dependencies, .devDependencies' # Build/test commands cat package.json | jq '.scripts' ``` ### Step 2: Identify What Differs from Training Data This is THE critical step. Ask: - What version of the framework? (Next.js 15 vs 16 matters) - What patterns differ from docs? (App Router vs Pages Router) - What custom conventions exist? (file naming, folder structure) - What APIs are non-standard? (custom hooks, service layer) - What common mistakes would an agent make? ### Step 3: Write AGENTS.md Follow this exact structure (order matters for context window efficiency): ```markdown # AGENTS.md ## Project Overview [1-2 sentences: what this project is] ## Stack - Framework: [exact version] - Language: [TypeScript/JavaScript + version] - Styling: [Tailwind/CSS Modules/etc + version] - State: [React state/Zustand/Redux/etc] - Backend: [API layer details] - Database: [if applicable] ## Architecture [Key architectural decisions — monorepo? API routes? Service layer?] ## File Conventions ``` app/ → Next.js App Router pages components/ → Reusable UI components lib/ → Utilities, hooks, services lib/services/ → API client functions lib/types/ → TypeScript type definitions ``` ## Commands ```bash npm run dev # Development server npm run build # Production build npm run typecheck # Type checking npm run lint # Linting npm test # Tests ``` ## Key Patterns ### [Pattern 1: e.g., API Calls] [How API calls work in this project — not how they work in general] ### [Pattern 2: e.g., Component Structure] [Project-specific component patterns] ## Common Pitfalls - [Thing that looks right but is wrong in this project] - [Deprecated pattern that training data still suggests] - [Non-obvious requirement] ## Environment [Required env vars, without values] ``` ### Step 4: Validate Quick validation checklist: - [ ] Would an agent using only this doc know where to put a new component? - [ ] Does it mention the exact framework version? - [ ] Are build commands correct and current? - [ ] Does it warn about project-specific gotchas? - [ ] Is it under 200 lines? (Longer = agents skip parts) --- ## Maintenance AGENTS.md goes stale. Update when: - Framework version changes - New conventions are established - New pitfalls discovered during swarm waves - Architecture changes significantly After each swarm run, check if agents made mistakes that better AGENTS.md would have prevented. If so, update it. --- ## Relationship to CLAUDE.md | File | Purpose | Audience | |------|---------|----------| | `CLAUDE.md` | User's personal instructions for Claude | Main Claude session | | `AGENTS.md` | Project context for all AI agents | Swarm agents, any AI tool | They complement each other. CLAUDE.md has user preferences; AGENTS.md has project facts. If CLAUDE.md already has good project context, AGENTS.md can reference it or extract the project-specific parts. --- ## Template for Common Stacks ### Next.js + Tailwind + Xano ```markdown # AGENTS.md ## Project Overview Next.js frontend with Xano backend, Tailwind CSS styling. ## Stack - Next.js 16 (App Router, Turbopack) - TypeScript 5.x (strict mode) - Tailwind CSS 4.x - Xano backend (REST API) - shadcn/ui components ## Architecture - App Router with (app) group for authenticated routes - Service layer in lib/services/ wraps all API calls - Types in lib/types/ — always import from there - Components use shadcn/ui primitives ## File Conventions app/(app)/[page]/page.tsx → Authenticated pages app/(auth)/[page]/page.tsx → Auth pages (login, signup) components/[name].tsx → PascalCase, one component per file lib/services/index.ts → All API functions lib/types/index.ts → All TypeScript types lib/hooks/ → Custom React hooks ## Commands npm run dev # Dev server with Turbopack npm run build # Production build (run before committing) npm run lint # ESLint ## Key Patterns - API calls: Use apiClient() from lib/services, never raw fetch - Auth: Token stored in cookies, apiClient handles headers - Loading: Use skeleton components from components/skeleton-loader - Errors: Toast via sonner, error boundaries for crashes ## Common Pitfalls - Don't import server-only code in client components - Avatar URLs have fallback chain: default_avatar_url || avatar_url - Build must pass before committing (pre-commit hook) - Use --no-verify if eslint hook has circular JSON error ``` ### Adjust per project. The template is a starting point, not gospel.
#!/usr/bin/env npx tsx
/**
* snappy-swarm/api.ts — How to construct agent prompts for BOTH code-review and browser-testing agents, collect results, resolve conflicts, and decide when to stop.
*
* This is a scaffolded stub. Replace the CLI below with real verbs.
* Credentials load via `env("<CREDENTIAL_KEY>")` from `../snappy-settings/load.ts`.
*/
import { realpathSync } from "fs";
import { env } from "../snappy-settings/load.ts";
import { annotationsForClass } from "../snappy-settings/tool-annotations.ts";
import { refusalTable } from "../snappy-settings/refusal-codes.ts";
// --- CLI ---
/** WHAT THIS HAND ANSWERS, and what each verb does to the world.
* Derived from this file's own CLI dispatch by
* `snappy-hands/contract-derive.ts` — a verb the code does not implement is
* never declared here. Snappy's daemon reads it (`api.ts contract`) to
* validate every call, build the argument words in order, decide whether the
* act runs now or stages for the owner, and hand the child exactly the
* environment keys named in `requires` — never a value, never anything else.
*/
/** THE HOST-FACING FACTS ⟨lane CONTRACTS N–Z, 2026-09-09⟩. `class` is the
* closed effect set snappy-tool-design rule 18 grades; `annotations` are
* DERIVED from it by the ONE derivation in
* `snappy-settings/tool-annotations.ts`, never written per verb, so a class
* and its published hints cannot disagree; `refusals` projects the ONE closed
* table in `snappy-settings/refusal-codes.ts`; `requires` is exactly the
* credential keys this file's own executable reads name, and nothing else. */
export const HAND_CONTRACT = {
skill: "snappy-swarm",
description: "Orchestrate swarms of parallel AI agents for multi-wave quality passes across a project. Interview mode sets scope, then fires wave after wave of agents — code-review agents AND browser-testing agents that actually click, type, navigate, and fight through the real app. Sets up AGENTS.md for agent context. Browser agents use agent-browser to find real UX bugs that code review alone will never catch. Triggers: snappy swarm, quality swarm, agent swarm, multi-wave, quality pass, wave of agents, swarm mode, parallel agents, quality sweep, bulk improvements, polish everything, fix everything, improve all pages, dogfood swarm, ship quality, browser test, e2e swarm, click through the app",
managed: false,
requires: [] as string[],
refusals: refusalTable("unknown_verb"),
verbs: {
},
} as const;
if (import.meta.url === `file://${realpathSync(process.argv[1])}` && process.argv[2] === "contract") {
console.log(JSON.stringify(HAND_CONTRACT, null, 2));
process.exit(0);
}
if (import.meta.url === `file://${realpathSync(process.argv[1])}`) {
const [, , cmd] = process.argv;
if (!cmd || cmd === "help") {
console.log("Usage: npx tsx api.ts <help>");
console.log("Scaffolded skill — replace this CLI with real verbs.");
process.exit(0);
}
console.error(`Unknown: ${cmd}`);
process.exit(1);
}
#!/usr/bin/env npx tsx
/**
* snappy-swarm/api.ts — How to construct agent prompts for BOTH code-review and browser-testing agents, collect results, resolve conflicts, and decide when to stop.
*
* This is a scaffolded stub. Replace the CLI below with real verbs.
* Credentials load via `env("<CREDENTIAL_KEY>")` from `../snappy-settings/load.ts`.
*/
import { realpathSync } from "fs";
import { env } from "../snappy-settings/load.ts";
import { annotationsForClass } from "../snappy-settings/tool-annotations.ts";
import { refusalTable } from "../snappy-settings/refusal-codes.ts";
// --- CLI ---
/** WHAT THIS HAND ANSWERS, and what each verb does to the world.
* Derived from this file's own CLI dispatch by
* `snappy-hands/contract-derive.ts` — a verb the code does not implement is
* never declared here. Snappy's daemon reads it (`api.ts contract`) to
* validate every call, build the argument words in order, decide whether the
* act runs now or stages for the owner, and hand the child exactly the
* environment keys named in `requires` — never a value, never anything else.
*/
/** THE HOST-FACING FACTS ⟨lane CONTRACTS N–Z, 2026-09-09⟩. `class` is the
* closed effect set snappy-tool-design rule 18 grades; `annotations` are
* DERIVED from it by the ONE derivation in
* `snappy-settings/tool-annotations.ts`, never written per verb, so a class
* and its published hints cannot disagree; `refusals` projects the ONE closed
* table in `snappy-settings/refusal-codes.ts`; `requires` is exactly the
* credential keys this file's own executable reads name, and nothing else. */
export const HAND_CONTRACT = {
skill: "snappy-swarm",
description: "Orchestrate swarms of parallel AI agents for multi-wave quality passes across a project. Interview mode sets scope, then fires wave after wave of agents — code-review agents AND browser-testing agents that actually click, type, navigate, and fight through the real app. Sets up AGENTS.md for agent context. Browser agents use agent-browser to find real UX bugs that code review alone will never catch. Triggers: snappy swarm, quality swarm, agent swarm, multi-wave, quality pass, wave of agents, swarm mode, parallel agents, quality sweep, bulk improvements, polish everything, fix everything, improve all pages, dogfood swarm, ship quality, browser test, e2e swarm, click through the app",
managed: false,
requires: [] as string[],
refusals: refusalTable("unknown_verb"),
verbs: {
},
} as const;
if (import.meta.url === `file://${realpathSync(process.argv[1])}` && process.argv[2] === "contract") {
console.log(JSON.stringify(HAND_CONTRACT, null, 2));
process.exit(0);
}
if (import.meta.url === `file://${realpathSync(process.argv[1])}`) {
const [, , cmd] = process.argv;
if (!cmd || cmd === "help") {
console.log("Usage: npx tsx api.ts <help>");
console.log("Scaffolded skill — replace this CLI with real verbs.");
process.exit(0);
}
console.error(`Unknown: ${cmd}`);
process.exit(1);
}
The interview captures everything agents need to work autonomously. All questions use AskUserQuestion with multiple choice.
This is the MOST IMPORTANT question. It determines whether agents just read code or actually USE the app.
Question: "What kind of swarm do you want to run?"
Header: "Type"
Options:
- "Full Assault (Recommended)" — Code-review agents fix source-level issues THEN browser agents
open the real app and click through every feature, finding UX bugs code review can't catch
- "Browser Testing" — Agents open your running app in a real browser. They click buttons, fill
forms, navigate flows, and fight to make everything actually work. They fix what they find.
- "Code Review" — Agents read source files, find and fix issues. Fast but can't catch runtime bugs.
Maps to: Wave composition. "Full Assault" = code-review wave(s) then browser wave(s). "Browser Testing" = all browser waves. "Code Review" = all code-review waves.
IMPORTANT: When presenting this question, make it crystal clear that "Browser Testing" means agents literally open a browser, navigate to pages, click elements, type into inputs, and verify that features actually work. Not just code scanning.
Question: "What's the scope of this swarm?"
Header: "Scope"
Options:
- "Entire app (Recommended)" — Every page and feature gets an agent
- "Specific pages" — You'll list which pages to target
- "Specific system" — Focus on one system (auth, feed, chat, etc.)
- "Changed files only" — Only files changed since last commit (git diff)
Maps to: How work units are divided. "Entire app" scans routes to build agent list. "Changed files only" uses git diff --name-only to scope.
If "Specific pages": Follow up with free text asking which pages.
If "Specific system": Follow up with free text asking which system.
Question: "How thorough should agents be?"
Header: "Standard"
Options:
- "Ship it" — Fix critical issues only, fast pass
- "Premium polish (Recommended)" — Thorough but pragmatic, production-quality
- "Obsessive" — Every detail, every edge case. Agents fight for perfection and
don't accept "it works well enough." They look for animation timing issues,
tap target sizes, loading state flickers, everything.
Maps to: Agent prompt QUALITY STANDARD field. Affects how aggressively agents investigate.
Question: "How many waves?"
Header: "Waves"
Options:
- "Quick pass (1 wave)" — Fast, one round of fixes
- "Standard (2-3 waves) (Recommended)" — Each wave builds on the last
- "Until perfect" — Keep going until a wave finds zero issues
Maps to: Wave loop termination condition.
Question: "How should changes be committed?"
Header: "Commits"
Options:
- "Auto-commit per wave" — Commit after each wave with summary message
- "Manual (Recommended)" — You review and commit when ready
Maps to: Whether git add + git commit runs automatically between waves.
If the swarm includes browser testing (Full Assault or Browser Testing), you MUST gather this info before firing browser agents:
"Browser agents need a running dev server. Is your dev server running? What port?"
Options:
npm run dev in background)CRITICAL: Do not fire browser agents without a confirmed, running dev server URL.
"Browser agents need to log in. What are the test credentials?"
Options:
Maps to: The orchestrator runs agent-browser auth save app-login --url {url} --username {email} --password {password} to save credentials to the encrypted auth vault. Agents then use agent-browser auth login app-login to auto-authenticate.
If project has CLAUDE.md with test credentials: Skip this question and use the documented credentials automatically. Example: if CLAUDE.md says Email: test@example.com / Password: test123, use those.
If no credentials found: You MUST ask. Browser agents cannot test an authenticated app without logging in.
After the interview, construct a config:
typescriptinterface SwarmConfig {
type: "full-assault" | "browser-testing" | "code-review"
scope: "entire-app" | "specific-pages" | "specific-system" | "changed-files"
scopeDetails?: string // If specific pages/system selected
standard: "ship-it" | "premium" | "obsessive"
waves: "quick" | "standard" | "until-perfect"
autoCommit: boolean
devServerUrl?: string // For browser testing waves
authProfileName?: string // agent-browser auth profile (default: "app-login")
authEmail?: string // Login email for browser agents
authPassword?: string // Login password for browser agents
}
Before firing agents, show the user:
Swarm Plan:
Type: Full Assault (code review → browser testing)
Scope: Entire app (6 pages detected)
Standard: Obsessive
Waves: 2-3 (standard)
Commits: Auto-commit per wave
Dev Server: http://localhost:3000
Auth: user@example.com (saved to agent-browser vault)
Session Isolation: Each browser agent gets AGENT_BROWSER_SESSION=agent-{N}
Wave 1 — Code Review (5 agents):
Agent 1 → /home (feed, stories, post cards)
Agent 2 → /messages (DM list, conversation)
Agent 3 → /profile (user profile, highlights)
Agent 4 → /groups (group list, group chat)
Agent 5 → /settings (preferences, theme)
Wave 2 — Browser Testing (4 agents, isolated sessions):
Agent 1 (session: agent-1) → Studio flow (tap companion → configure → generate)
Agent 2 (session: agent-2) → Messaging (send DM → receive reply → scroll)
Agent 3 (session: agent-3) → Feed interactions (like, comment, iterate dialog)
Agent 4 (session: agent-4) → Navigation (settings, search, back button, deep links)
Pre-flight: auth save → preflight test → verified ✓
Ready to swarm?
Wait for user confirmation before proceeding.
Scan the project for routes:
bash# Next.js App Router
find app -name "page.tsx" -not -path "*/api/*" | sort
Group routes into logical units. For code review, each page = one agent. For browser testing, group into features/flows.
For browser agents, don't just assign pages — assign USER FLOWS:
Instead of:
Agent 1 → /home page
Agent 2 → /messages page
Do this:
Agent 1 → "Studio generation flow" (home → tap companion → studio panel → configure → generate)
Agent 2 → "DM conversation flow" (messages list → open DM → type → send → see AI reply)
Agent 3 → "Post interaction flow" (feed → like post → open iterate → select preset → generate)
Agent 4 → "Group chat flow" (groups → open group → send message → see responses)
This ensures agents test complete journeys, not just page loads.
bashgit diff --name-only HEAD
Group changed files by directory/page for agent assignment.
| Project Size | Pages | Code Agents/Wave | Browser Agents/Wave |
|---|---|---|---|
| Small | 1-3 | 1-3 | 2-3 |
| Medium | 4-8 | 4-6 | 3-5 |
| Large | 9-15 | 6-8 | 4-6 |
| Very Large | 15+ | 8-10 (batch) | 5-6 (batch) |
Browser agents are typically fewer than code agents because each browser agent tests a complete flow that may span multiple pages.
# Interview Flow — Complete Reference
The interview captures everything agents need to work autonomously. All questions use `AskUserQuestion` with multiple choice.
---
## Question Sequence
### Q1: Swarm Type
This is the MOST IMPORTANT question. It determines whether agents just read code or actually USE the app.
```
Question: "What kind of swarm do you want to run?"
Header: "Type"
Options:
- "Full Assault (Recommended)" — Code-review agents fix source-level issues THEN browser agents
open the real app and click through every feature, finding UX bugs code review can't catch
- "Browser Testing" — Agents open your running app in a real browser. They click buttons, fill
forms, navigate flows, and fight to make everything actually work. They fix what they find.
- "Code Review" — Agents read source files, find and fix issues. Fast but can't catch runtime bugs.
```
**Maps to**: Wave composition. "Full Assault" = code-review wave(s) then browser wave(s). "Browser Testing" = all browser waves. "Code Review" = all code-review waves.
**IMPORTANT**: When presenting this question, make it crystal clear that "Browser Testing" means agents literally open a browser, navigate to pages, click elements, type into inputs, and verify that features actually work. Not just code scanning.
### Q2: Scope
```
Question: "What's the scope of this swarm?"
Header: "Scope"
Options:
- "Entire app (Recommended)" — Every page and feature gets an agent
- "Specific pages" — You'll list which pages to target
- "Specific system" — Focus on one system (auth, feed, chat, etc.)
- "Changed files only" — Only files changed since last commit (git diff)
```
**Maps to**: How work units are divided. "Entire app" scans routes to build agent list. "Changed files only" uses `git diff --name-only` to scope.
**If "Specific pages"**: Follow up with free text asking which pages.
**If "Specific system"**: Follow up with free text asking which system.
### Q3: Quality Standard
```
Question: "How thorough should agents be?"
Header: "Standard"
Options:
- "Ship it" — Fix critical issues only, fast pass
- "Premium polish (Recommended)" — Thorough but pragmatic, production-quality
- "Obsessive" — Every detail, every edge case. Agents fight for perfection and
don't accept "it works well enough." They look for animation timing issues,
tap target sizes, loading state flickers, everything.
```
**Maps to**: Agent prompt `QUALITY STANDARD` field. Affects how aggressively agents investigate.
### Q4: Wave Count
```
Question: "How many waves?"
Header: "Waves"
Options:
- "Quick pass (1 wave)" — Fast, one round of fixes
- "Standard (2-3 waves) (Recommended)" — Each wave builds on the last
- "Until perfect" — Keep going until a wave finds zero issues
```
**Maps to**: Wave loop termination condition.
### Q5: Commit Strategy
```
Question: "How should changes be committed?"
Header: "Commits"
Options:
- "Auto-commit per wave" — Commit after each wave with summary message
- "Manual (Recommended)" — You review and commit when ready
```
**Maps to**: Whether `git add` + `git commit` runs automatically between waves.
---
## Dev Server & Auth Check (for Browser Testing)
If the swarm includes browser testing (Full Assault or Browser Testing), you MUST gather this info before firing browser agents:
### Dev Server
```
"Browser agents need a running dev server. Is your dev server running? What port?"
```
Options:
- "Yes, port 3000" (most common)
- "Yes, different port" (ask which)
- "No, start it for me" (run `npm run dev` in background)
**CRITICAL**: Do not fire browser agents without a confirmed, running dev server URL.
### Auth Credentials
```
"Browser agents need to log in. What are the test credentials?"
```
Options:
- "Use project defaults" — Read from CLAUDE.md or .env (look for test credentials section)
- "I'll provide them" — Ask for email + password
**Maps to**: The orchestrator runs `agent-browser auth save app-login --url {url} --username {email} --password {password}` to save credentials to the encrypted auth vault. Agents then use `agent-browser auth login app-login` to auto-authenticate.
**If project has CLAUDE.md with test credentials**: Skip this question and use the documented credentials automatically. Example: if CLAUDE.md says `Email: test@example.com / Password: test123`, use those.
**If no credentials found**: You MUST ask. Browser agents cannot test an authenticated app without logging in.
---
## Interview Output: Swarm Configuration
After the interview, construct a config:
```typescript
interface SwarmConfig {
type: "full-assault" | "browser-testing" | "code-review"
scope: "entire-app" | "specific-pages" | "specific-system" | "changed-files"
scopeDetails?: string // If specific pages/system selected
standard: "ship-it" | "premium" | "obsessive"
waves: "quick" | "standard" | "until-perfect"
autoCommit: boolean
devServerUrl?: string // For browser testing waves
authProfileName?: string // agent-browser auth profile (default: "app-login")
authEmail?: string // Login email for browser agents
authPassword?: string // Login password for browser agents
}
```
### Confirmation Message
Before firing agents, show the user:
```
Swarm Plan:
Type: Full Assault (code review → browser testing)
Scope: Entire app (6 pages detected)
Standard: Obsessive
Waves: 2-3 (standard)
Commits: Auto-commit per wave
Dev Server: http://localhost:3000
Auth: user@example.com (saved to agent-browser vault)
Session Isolation: Each browser agent gets AGENT_BROWSER_SESSION=agent-{N}
Wave 1 — Code Review (5 agents):
Agent 1 → /home (feed, stories, post cards)
Agent 2 → /messages (DM list, conversation)
Agent 3 → /profile (user profile, highlights)
Agent 4 → /groups (group list, group chat)
Agent 5 → /settings (preferences, theme)
Wave 2 — Browser Testing (4 agents, isolated sessions):
Agent 1 (session: agent-1) → Studio flow (tap companion → configure → generate)
Agent 2 (session: agent-2) → Messaging (send DM → receive reply → scroll)
Agent 3 (session: agent-3) → Feed interactions (like, comment, iterate dialog)
Agent 4 (session: agent-4) → Navigation (settings, search, back button, deep links)
Pre-flight: auth save → preflight test → verified ✓
Ready to swarm?
```
Wait for user confirmation before proceeding.
---
## Scope Detection
### Entire App
Scan the project for routes:
```bash
# Next.js App Router
find app -name "page.tsx" -not -path "*/api/*" | sort
```
Group routes into logical units. For code review, each page = one agent. For browser testing, group into features/flows.
### Browser Testing: Feature-Based Scoping
For browser agents, don't just assign pages — assign USER FLOWS:
```
Instead of:
Agent 1 → /home page
Agent 2 → /messages page
Do this:
Agent 1 → "Studio generation flow" (home → tap companion → studio panel → configure → generate)
Agent 2 → "DM conversation flow" (messages list → open DM → type → send → see AI reply)
Agent 3 → "Post interaction flow" (feed → like post → open iterate → select preset → generate)
Agent 4 → "Group chat flow" (groups → open group → send message → see responses)
```
This ensures agents test complete journeys, not just page loads.
### Changed Files Only
```bash
git diff --name-only HEAD
```
Group changed files by directory/page for agent assignment.
---
## Adapting to Project Size
| Project Size | Pages | Code Agents/Wave | Browser Agents/Wave |
|--------------|-------|-------------------|---------------------|
| Small | 1-3 | 1-3 | 2-3 |
| Medium | 4-8 | 4-6 | 3-5 |
| Large | 9-15 | 6-8 | 4-6 |
| Very Large | 15+ | 8-10 (batch) | 5-6 (batch) |
Browser agents are typically fewer than code agents because each browser agent tests a complete flow that may span multiple pages.
/**
* COVERAGE FOR SNAPPY-SWARM'S DECLARED REFUSAL CODES
* (snappy-tool-design rule 33: "refusal codes form one closed table and each
* row has coverage").
*
* Two things are graded here, and the second is the one that matters. The
* first is that the hand's table is a PROJECTION of the collection's one
* closed table in snappy-settings/refusal-codes.ts — same object, not a copy
* that can drift. The second is that every declared code is GROUNDED: the
* evidence that justified declaring it is re-checked here, because a refusal
* code with no path that emits it is a branch the reader waits for and never
* sees, and a table of those passes a lint while teaching a lie.
*
* The code list is spelled out rather than read from the contract: a test that
* iterates the thing it grades passes for an empty table.
*/
import { strict as assert } from "node:assert";
import { test } from "node:test";
import { readFileSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { HAND_CONTRACT } from "./api.ts";
import { REFUSAL_CODES } from "../snappy-settings/refusal-codes.ts";
const SOURCE = readFileSync(join(dirname(fileURLToPath(import.meta.url)), "api.ts"), "utf8");
/** Every refusal code snappy-swarm declares. */
const DECLARED = [
"unknown_verb",
] as const;
test("snappy-swarm declares exactly these refusal codes", () => {
assert.deepEqual(Object.keys(HAND_CONTRACT.refusals).sort(), [...DECLARED].sort());
});
test("every declared code is the SAME row as the one closed table's, never a copy", () => {
const table = HAND_CONTRACT.refusals as Record<string, unknown>;
for (const code of DECLARED) {
assert.equal(table[code], REFUSAL_CODES[code], `${code} is not the shared row`);
}
});
test("unknown_verb is grounded: the contract closes the verb set, so a word outside it is refusable", () => {
assert.ok(Object.keys(HAND_CONTRACT.verbs).length >= 0);
assert.ok(!Object.keys(HAND_CONTRACT.verbs).includes("no-such-verb"));
});
/**
* COVERAGE FOR SNAPPY-SWARM'S DECLARED REFUSAL CODES
* (snappy-tool-design rule 33: "refusal codes form one closed table and each
* row has coverage").
*
* Two things are graded here, and the second is the one that matters. The
* first is that the hand's table is a PROJECTION of the collection's one
* closed table in snappy-settings/refusal-codes.ts — same object, not a copy
* that can drift. The second is that every declared code is GROUNDED: the
* evidence that justified declaring it is re-checked here, because a refusal
* code with no path that emits it is a branch the reader waits for and never
* sees, and a table of those passes a lint while teaching a lie.
*
* The code list is spelled out rather than read from the contract: a test that
* iterates the thing it grades passes for an empty table.
*/
import { strict as assert } from "node:assert";
import { test } from "node:test";
import { readFileSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { HAND_CONTRACT } from "./api.ts";
import { REFUSAL_CODES } from "../snappy-settings/refusal-codes.ts";
const SOURCE = readFileSync(join(dirname(fileURLToPath(import.meta.url)), "api.ts"), "utf8");
/** Every refusal code snappy-swarm declares. */
const DECLARED = [
"unknown_verb",
] as const;
test("snappy-swarm declares exactly these refusal codes", () => {
assert.deepEqual(Object.keys(HAND_CONTRACT.refusals).sort(), [...DECLARED].sort());
});
test("every declared code is the SAME row as the one closed table's, never a copy", () => {
const table = HAND_CONTRACT.refusals as Record<string, unknown>;
for (const code of DECLARED) {
assert.equal(table[code], REFUSAL_CODES[code], `${code} is not the shared row`);
}
});
test("unknown_verb is grounded: the contract closes the verb set, so a word outside it is refusable", () => {
assert.ok(Object.keys(HAND_CONTRACT.verbs).length >= 0);
assert.ok(!Object.keys(HAND_CONTRACT.verbs).includes("no-such-verb"));
});
Two types of agents exist: Code-Review (read source, edit files) and Browser-Testing (open app, click, type, navigate). Each has different checklists and priorities.
FOCUS: Visual quality and UX polish.
CHECKLIST: Layout alignment, spacing consistency, dark mode, responsive breakpoints,
loading states, transitions, accessibility.
FIX STYLE: Match existing design system. Use project's CSS variables and utility classes.
DO NOT: Change functionality. Only improve how things look and feel.
What to check: Consistent padding/margin, text truncation, dark mode contrast, hover/active/focus states, ARIA labels, smooth transitions, skeleton loaders.
Priority: Broken layouts > Missing states > Dark mode > Responsive > Accessibility > Polish
FOCUS: Find and fix bugs, broken flows, and missing error handling.
CHECKLIST: API error handling, loading/empty states, type safety, edge cases,
null checks, stale data, memory leaks, cleanup in useEffect.
FIX STYLE: Minimal, targeted fixes. Don't refactor — just fix the bug.
DO NOT: Add features. Only fix what's broken or missing.
What to check: API calls without error handling, missing loading states, empty states for no data, type safety (no any), null/undefined checks, stale closures, double-click prevention, proper cleanup.
Priority: Crashes > Data loss > Broken flows > Missing error handling > Type safety > Edge cases
FOCUS: Speed and efficiency improvements.
CHECKLIST: Unnecessary re-renders, redundant API calls, missing lazy loading,
large bundle imports, unoptimized images, missing memoization.
FIX STYLE: Measure before optimizing. Only fix clear performance issues.
DO NOT: Premature optimization. Only fix issues with measurable impact.
What to check: Missing memo/useMemo, redundant fetches, sequential requests that could be parallel, full library imports, missing lazy loading, blocking main thread operations.
Priority: Redundant API calls > Re-renders > Lazy loading > Bundle size > Virtualization
FOCUS: Comprehensive quality audit — bugs, polish, and performance.
CHECKLIST: All three checklists above, prioritized by impact:
Critical: crashes, broken flows, layout breaks
High: missing states, dark mode, redundant calls
Medium: responsiveness, type safety, re-renders
Low: accessibility, bundle size, micro-polish
FIX STYLE: Fix everything you find. Be thorough but don't over-engineer.
Browser agents have a fundamentally different approach. They USE the app. Each agent runs in its own isolated browser session (AGENT_BROWSER_SESSION=agent-{N}).
1. export AGENT_BROWSER_SESSION=agent-{N} # Isolated session
2. agent-browser auth login app-login # Auto-login via saved profile
3. agent-browser snapshot -i # Verify authenticated state
If step 3 shows a login page instead of the app, STOP and report — auth setup failed.
Every browser agent verifies these for their assigned flow:
Navigation & Routing
Interactive Elements
Async Operations
Visual State
Browser agents don't just verify happy paths. They FIGHT:
== FIGHT FOR QUALITY ==
1. SNAPSHOT BEFORE EVERY ACTION — Always `agent-browser snapshot -i` to get fresh @refs.
Refs go stale after navigation or state changes. Never use old refs.
2. CLICK EVERYTHING — Use @ref selectors from snapshots: `agent-browser click @e5`
Did something happen? Take another snapshot. Verify the state changed.
If @ref doesn't work, try: `agent-browser find role button click --name "Button Text"`
3. INVESTIGATE FAILURES — A button that doesn't respond is NOT "the page loaded fine."
That IS the bug. Why doesn't it respond?
- Is another element covering it? → Check z-index, overflow
- Is it hidden during animation? → Check initial scale/opacity
- Is the click handler wrong? → Read the source, trace the handler
- Is it outside the viewport? → `agent-browser scroll down` first
- JS fallback: `agent-browser eval "document.querySelector('.btn').click()"`
4. TRY EDGE CASES:
- What happens with empty input?
- What happens with very long text? `agent-browser fill @e3 "a]|repeat:500"`
- What happens if you click twice rapidly?
- What happens if you click during a loading state?
- What happens if you navigate away and back?
5. DON'T ACCEPT MEDIOCRITY:
- "It works" is not enough. Does it work WELL?
- Is the loading state too fast to see? (might not exist)
- Does the success feedback actually appear?
- Is the animation smooth or janky?
6. FIX WHAT YOU FIND:
- After discovering a bug through the browser, switch to reading source code
- Understand the root cause (not just the symptom)
- Edit the file to fix it
- Verify: `agent-browser open {url}` to reload, then re-test
7. CLEANUP WHEN DONE:
- `agent-browser close` to clean up your session
Form Submission Flow:
List/Feed Flow:
Dialog/Modal Flow:
Navigation Flow:
| Swarm Type | Wave 1 | Wave 2 | Wave 3+ |
|---|---|---|---|
| Code Review | Code agents | Code agents | Code agents |
| Browser Testing | Browser agents | Browser agents | Browser agents |
| Full Assault | Code agents | Browser agents | Browser agents |
| Standard | Code Agent Behavior | Browser Agent Behavior |
|---|---|---|
| Ship it | Fix critical bugs only | Test happy path only |
| Premium | Thorough, all checklists | Test happy path + key edge cases |
| Obsessive | Every detail | Test everything, try to break it, fight for perfection |
# Swarm Modes — Detailed Checklists
Two types of agents exist: **Code-Review** (read source, edit files) and **Browser-Testing** (open app, click, type, navigate). Each has different checklists and priorities.
---
## Code-Review Agent Checklists
### Quality Polish
```
FOCUS: Visual quality and UX polish.
CHECKLIST: Layout alignment, spacing consistency, dark mode, responsive breakpoints,
loading states, transitions, accessibility.
FIX STYLE: Match existing design system. Use project's CSS variables and utility classes.
DO NOT: Change functionality. Only improve how things look and feel.
```
**What to check**: Consistent padding/margin, text truncation, dark mode contrast, hover/active/focus states, ARIA labels, smooth transitions, skeleton loaders.
**Priority**: Broken layouts > Missing states > Dark mode > Responsive > Accessibility > Polish
### Bug Hunt
```
FOCUS: Find and fix bugs, broken flows, and missing error handling.
CHECKLIST: API error handling, loading/empty states, type safety, edge cases,
null checks, stale data, memory leaks, cleanup in useEffect.
FIX STYLE: Minimal, targeted fixes. Don't refactor — just fix the bug.
DO NOT: Add features. Only fix what's broken or missing.
```
**What to check**: API calls without error handling, missing loading states, empty states for no data, type safety (no `any`), null/undefined checks, stale closures, double-click prevention, proper cleanup.
**Priority**: Crashes > Data loss > Broken flows > Missing error handling > Type safety > Edge cases
### Performance
```
FOCUS: Speed and efficiency improvements.
CHECKLIST: Unnecessary re-renders, redundant API calls, missing lazy loading,
large bundle imports, unoptimized images, missing memoization.
FIX STYLE: Measure before optimizing. Only fix clear performance issues.
DO NOT: Premature optimization. Only fix issues with measurable impact.
```
**What to check**: Missing memo/useMemo, redundant fetches, sequential requests that could be parallel, full library imports, missing lazy loading, blocking main thread operations.
**Priority**: Redundant API calls > Re-renders > Lazy loading > Bundle size > Virtualization
### Full Audit
```
FOCUS: Comprehensive quality audit — bugs, polish, and performance.
CHECKLIST: All three checklists above, prioritized by impact:
Critical: crashes, broken flows, layout breaks
High: missing states, dark mode, redundant calls
Medium: responsiveness, type safety, re-renders
Low: accessibility, bundle size, micro-polish
FIX STYLE: Fix everything you find. Be thorough but don't over-engineer.
```
---
## Browser-Testing Agent Checklists
Browser agents have a fundamentally different approach. They USE the app. Each agent runs in its own isolated browser session (`AGENT_BROWSER_SESSION=agent-{N}`).
### Session Setup (FIRST THING every browser agent does)
```
1. export AGENT_BROWSER_SESSION=agent-{N} # Isolated session
2. agent-browser auth login app-login # Auto-login via saved profile
3. agent-browser snapshot -i # Verify authenticated state
```
If step 3 shows a login page instead of the app, STOP and report — auth setup failed.
### Core Browser Testing Checklist
Every browser agent verifies these for their assigned flow:
**Navigation & Routing**
- Page loads without blank screen or flash
- Back button works correctly
- Deep links resolve to the right page
- Loading states appear during navigation
- Error pages show for invalid routes
**Interactive Elements**
- Every button in the flow is clickable and responds
- Buttons do what their label/tooltip says
- Inputs accept text and show it
- Dropdowns/selects open and options are selectable
- Toggles change state visually AND functionally
- Dialogs open, contain expected content, and close properly
**Async Operations**
- Loading indicators appear during API calls
- Success states show after completion
- Error states show meaningful messages on failure
- UI doesn't freeze during async work
- Rapid clicks don't cause duplicate operations
**Visual State**
- Selected/active states are visually distinct
- Hover states exist on interactive elements
- Animations complete without blocking interaction
- No elements overlapping or clipping content
- Scroll works and content is reachable
### Aggressive Testing Mindset
Browser agents don't just verify happy paths. They FIGHT:
```
== FIGHT FOR QUALITY ==
1. SNAPSHOT BEFORE EVERY ACTION — Always `agent-browser snapshot -i` to get fresh @refs.
Refs go stale after navigation or state changes. Never use old refs.
2. CLICK EVERYTHING — Use @ref selectors from snapshots: `agent-browser click @e5`
Did something happen? Take another snapshot. Verify the state changed.
If @ref doesn't work, try: `agent-browser find role button click --name "Button Text"`
3. INVESTIGATE FAILURES — A button that doesn't respond is NOT "the page loaded fine."
That IS the bug. Why doesn't it respond?
- Is another element covering it? → Check z-index, overflow
- Is it hidden during animation? → Check initial scale/opacity
- Is the click handler wrong? → Read the source, trace the handler
- Is it outside the viewport? → `agent-browser scroll down` first
- JS fallback: `agent-browser eval "document.querySelector('.btn').click()"`
4. TRY EDGE CASES:
- What happens with empty input?
- What happens with very long text? `agent-browser fill @e3 "a]|repeat:500"`
- What happens if you click twice rapidly?
- What happens if you click during a loading state?
- What happens if you navigate away and back?
5. DON'T ACCEPT MEDIOCRITY:
- "It works" is not enough. Does it work WELL?
- Is the loading state too fast to see? (might not exist)
- Does the success feedback actually appear?
- Is the animation smooth or janky?
6. FIX WHAT YOU FIND:
- After discovering a bug through the browser, switch to reading source code
- Understand the root cause (not just the symptom)
- Edit the file to fix it
- Verify: `agent-browser open {url}` to reload, then re-test
7. CLEANUP WHEN DONE:
- `agent-browser close` to clean up your session
```
### Flow-Specific Testing Patterns
**Form Submission Flow**:
1. Navigate to form
2. Fill each field (verify it accepts input)
3. Submit with valid data → verify success
4. Submit with empty required fields → verify validation
5. Submit twice rapidly → verify no double submit
**List/Feed Flow**:
1. Verify items render
2. Scroll through items (check virtualization if needed)
3. Interact with an item (like, click, expand)
4. Verify interaction persists (not reset on scroll)
5. Pull to refresh / load more (if applicable)
**Dialog/Modal Flow**:
1. Trigger dialog open
2. Verify content renders inside dialog
3. Interact with every element in the dialog
4. Close dialog (X button, backdrop click, Escape key)
5. Verify underlying page state is correct after close
**Navigation Flow**:
1. Visit each main route
2. Use browser back/forward
3. Click internal links
4. Verify breadcrumbs/active states update
5. Test deep link directly (paste URL)
---
## Mapping Interview Answers to Agent Type
| Swarm Type | Wave 1 | Wave 2 | Wave 3+ |
|------------|--------|--------|---------|
| Code Review | Code agents | Code agents | Code agents |
| Browser Testing | Browser agents | Browser agents | Browser agents |
| Full Assault | Code agents | Browser agents | Browser agents |
| Standard | Code Agent Behavior | Browser Agent Behavior |
|----------|--------------------|-----------------------|
| Ship it | Fix critical bugs only | Test happy path only |
| Premium | Thorough, all checklists | Test happy path + key edge cases |
| Obsessive | Every detail | Test everything, try to break it, fight for perfection |
How to construct agent prompts for BOTH code-review and browser-testing agents, collect results, resolve conflicts, and decide when to stop.
Every code-review agent gets this structure:
You are Agent {N} in a quality swarm, Wave {W}.
== PROJECT CONTEXT ==
{Insert AGENTS.md content here, or key excerpts if AGENTS.md is very long}
== YOUR ASSIGNMENT ==
Scope: {list of files/directories this agent owns}
Mode: {quality-polish | bug-hunt | performance | full-audit}
Standard: {ship-it | premium | obsessive}
== CHECKLIST ==
{Mode-specific checklist from swarm-modes.md}
== INSTRUCTIONS ==
1. Read every file in your scope thoroughly
2. For each file, check against the checklist above
3. Fix issues directly by editing files
4. Track what you found and what you fixed
5. Note anything that needs human decision or spans outside your scope
== OUTPUT FORMAT ==
Return a structured summary:
FINDINGS:
- [file:line] Issue description → FIXED / NEEDS ATTENTION / SKIPPED (reason)
FILES MODIFIED:
- path/to/file.tsx
ISSUES REMAINING:
- [description of anything you couldn't fix]
QUALITY SCORE: {1-10} for your scope area
Browser agents get a completely different prompt. They USE the app. Each agent gets its OWN isolated browser session — this is critical for parallel execution.
You are Agent {N} — a browser-testing agent in Wave {W}.
== YOUR MISSION ==
You are testing a LIVE RUNNING APP at {dev_server_url}.
Your job: exercise the "{feature_name}" flow by actually using the app in a real browser.
Click buttons. Fill inputs. Navigate. Scroll. USE IT LIKE A REAL USER.
== BROWSER SESSION SETUP (DO THIS FIRST!) ==
You have your own isolated browser session. EVERY agent-browser command MUST use your session.
Step 1 — Set your session env var (do this ONCE at the start):
export AGENT_BROWSER_SESSION=agent-{N}
Step 2 — Authenticate using the pre-saved auth profile:
agent-browser auth login {auth_profile_name}
Step 3 — Verify you're logged in:
agent-browser snapshot -i
You should see the app's authenticated shell (navigation, content, etc.).
If you see a login page, something went wrong — do NOT proceed until authenticated.
== AGENT-BROWSER COMMAND REFERENCE ==
ALL commands automatically use your session via the AGENT_BROWSER_SESSION env var.
Navigation:
agent-browser open {url} — Navigate to a URL
agent-browser scroll down — Scroll down
agent-browser scroll up — Scroll up
agent-browser press Escape — Press a key
agent-browser wait --load networkidle — Wait for page to fully load
Inspection (USE FREQUENTLY):
agent-browser snapshot -i — See interactive elements only (PREFERRED)
agent-browser snapshot — See full page text representation
agent-browser snapshot -c — Compact mode (removes empty elements)
agent-browser screenshot — Take a visual screenshot
Interaction (USE @ref SELECTORS from snapshots):
agent-browser click @e5 — Click element with ref e5
agent-browser fill @e3 "hello world" — Type into input with ref e3
agent-browser find role button click --name Submit — Find by ARIA role and click
Advanced:
agent-browser eval "document.querySelector('.my-class').click()" — JS fallback
agent-browser get text @e1 — Get text content of element
agent-browser is visible .my-selector — Check if element is visible
== HOW SNAPSHOT REFS WORK ==
When you run `snapshot -i`, you get output like:
[ref=e1] <button> Home
[ref=e2] <button> Messages
[ref=e3] <input placeholder="Search...">
[ref=e4] <button> Settings
Use these refs to interact: `click @e1`, `fill @e3 "text"`, `get text @e4`
Refs change after navigation/state changes — always take a fresh snapshot before clicking.
== YOUR FLOW TO TEST ==
{Specific user journey for this agent, e.g.:}
1. Navigate to the home page
2. Find a companion in the stories bar
3. Click on the companion to select them
4. Verify the action flyout appears (Studio, Surprise, Message buttons)
5. Click "Studio" — verify the Studio panel opens
6. Select a style, scene, and expression
7. Click Generate — verify the generating indicator appears
8. Wait for result — verify new post appears in feed
== QUALITY STANDARD: {standard} ==
== MINDSET: FIGHT FOR QUALITY ==
You are NOT a passive observer. You are an AGGRESSIVE TESTER.
DO:
- Take a `snapshot -i` before EVERY interaction to get fresh refs.
- Click every button in your flow using @ref selectors. Verify it does what it should.
- If something doesn't respond to a click, investigate WHY.
Is it covered by another element? Check z-index.
Is the click handler missing? Read the source code.
Is an animation blocking it? Check animation timing.
- If a dialog opens, take a snapshot and interact with EVERYTHING in it.
- If you find a bug, READ THE SOURCE CODE and FIX IT by editing files.
- Take snapshots before and after key actions to verify state changes.
- Try edge cases: rapid clicking, empty inputs, long text, back button.
- Verify loading states actually appear during async operations.
- Check that error states show meaningful messages.
DON'T:
- Accept "it loaded without errors" as a passing grade.
- Skip elements because they're hard to click — that IS the bug.
- Give up after one attempt. Try `find role button click --name "X"` or JS eval as fallback.
- Use stale refs — always snapshot before clicking.
- Report issues without investigating root cause.
- Just observe — IMPROVE. Find bugs, understand them, fix the code.
== WHEN YOU FIND A BUG ==
1. Take a snapshot showing the issue
2. Describe exactly what happened vs what should have happened
3. Read the relevant source code to understand WHY
4. Edit the source file to fix the root cause
5. Verify the fix: `agent-browser open {url}` to reload, then re-test the flow
== CLEANUP ==
When you're done testing, close your session:
agent-browser close
== OUTPUT FORMAT ==
FLOW TESTED: {description of what you tested}
STEPS COMPLETED:
1. [step] — PASS / FAIL (detail)
2. [step] — PASS / FAIL (detail)
...
BUGS FOUND AND FIXED:
- [description] — Root cause: [cause] — Fix: [what you changed in which file]
BUGS FOUND BUT NOT FIXED:
- [description] — Why: [reason you couldn't fix it]
OBSERVATIONS:
- [anything notable about UX, timing, visual issues]
FILES MODIFIED:
- path/to/file.tsx
For subsequent waves, prepend previous wave context:
== PREVIOUS WAVE RESULTS ==
Wave {W-1} completed with {N} agents.
Agent covering your scope found:
{Previous agent's findings for this scope}
Other agents found (cross-cutting):
{Summary of cross-scope issues}
YOUR FOCUS THIS WAVE:
1. Verify previous fixes are correct — retest the flows that had bugs
2. Find issues the previous wave missed — go deeper
3. Check for regressions introduced by other agents' fixes
4. Test edge cases that first-pass agents didn't try
5. Look at the UX critically — not just "does it work" but "does it work WELL"
Before firing ANY browser-testing agents, the orchestrator MUST set up auth:
bash# Run this ONCE before firing browser agents
# The auth profile name should match what agents are told to use
agent-browser auth save app-login \
--url {dev_server_url} \
--username {login_email} \
--password {login_password}
This saves credentials to an encrypted vault. Agents reference the profile by name — they never see raw credentials.
bash# Test with a throwaway session
agent-browser --session preflight-test auth login app-login
agent-browser --session preflight-test snapshot -i
# Should show authenticated app shell, NOT a login page
agent-browser --session preflight-test close
Every browser agent prompt MUST include:
export AGENT_BROWSER_SESSION=agent-{N} — unique per agentagent-browser auth login app-login — uses the saved profileagent-browser snapshot -i — verify auth succeededCRITICAL: Without session isolation, all agents share one browser and fight over the same page. Each agent MUST have AGENT_BROWSER_SESSION set to a unique value.
After all agents complete, clean up sessions:
bashagent-browser session list
# Close any remaining sessions
agent-browser --session agent-1 close
agent-browser --session agent-2 close
# etc.
Use a single message with multiple Agent tool calls:
Agent 1: subagent_type="general-purpose", prompt="You are Agent 1..."
Agent 2: subagent_type="general-purpose", prompt="You are Agent 2..."
Agent 3: subagent_type="general-purpose", prompt="You are Agent 3..."
All agents in the same message fire in parallel. Do NOT await one before firing the next.
Code-review agents: Consider isolation: "worktree" for write-heavy work to prevent merge conflicts.
Browser-testing agents: Do NOT use worktree isolation — they need to see the same running dev server. Instead, each agent gets its own browser session via AGENT_BROWSER_SESSION=agent-{N}. This gives full browser isolation (separate cookies, separate page state, separate navigation) while still hitting the same dev server.
When agents complete, parse results into structured format:
typescriptinterface AgentResult {
agentId: number
type: "code-review" | "browser-testing"
scope: string
findings: {
description: string
status: "fixed" | "needs-attention" | "skipped" | "passed"
file?: string
line?: number
}[]
filesModified: string[]
issuesRemaining: string[]
qualityScore?: number // Code-review agents
stepsCompleted?: { step: string; result: "pass" | "fail" }[] // Browser agents
}
Multiple agents may touch shared files. Check for:
Resolution: Prefer the fix from the agent whose scope owns the file.
After every wave, run the project build:
bashnpm run build
Wave 1: Code-Review agents → Build Check → Report
↓
Wave 2: Browser-Testing agents → Build Check → Report
↓
If issues remain: Wave 3 (Browser-Testing) → Build Check → Report
If clean: Done
Wave 1: Code-Review agents → Build Check → Report
↓
If issues remain: Wave 2 (with findings) → Build Check → Report
↓
If clean: Done
Wave 1: Browser-Testing agents → Build Check → Report
↓
If issues remain: Wave 2 (with findings) → Build Check → Report
↓
If clean: Done
Fire Wave N → Build Check → Report
↓
If any issues found: Fire Wave N+1 → loop
If zero issues: Done
↓
Safety limit: Max 5 waves (prevent infinite loop)
After each successful wave, commit only the files agents modified:
bashgit add {specific files from agent results}
git commit -m "fix: wave {N} ({type}) — {issue_count} fixes
{brief summary of main fixes}
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
After all waves complete, show the user:
git diff)Some issues span multiple agents' scopes:
Handle by:
## Wave {N} Complete — {Code Review | Browser Testing}
Agents: {count} | Issues Found: {found} | Fixed: {fixed}
Build: PASS / FAIL | Type: {code-review | browser-testing}
### Changes by Agent
| Agent | Feature/Scope | Found | Fixed | Result |
|-------|---------------|-------|-------|--------|
| 1 | Studio flow | 3 | 3 | 5/6 steps passed |
| 2 | Messaging | 1 | 1 | 4/4 steps passed |
| 3 | Feed | 2 | 2 | 3/3 steps passed |
### Key Fixes
- Flyout buttons untargetable during animation → fixed scale: 0 to 0.6
- Click-outside handler using wrong event → switched to mousedown
- Button spacing too tight → increased gap
### Next: {Wave N+1 / Done}
## Swarm Complete
Total Waves: {count} ({N} code-review, {M} browser-testing)
Total Issues Found: {total} | Fixed: {fixed}
Files Modified: {count}
Build: PASS
### Wave Summary
| Wave | Type | Agents | Found | Fixed |
|------|------|--------|-------|-------|
| 1 | Code Review | 5 | 16 | 16 |
| 2 | Browser Test | 4 | 3 | 3 |
| 3 | Browser Test | 4 | 0 | 0 |
### All Fixed Issues
{grouped by category}
### Remaining (Human Decision)
{anything agents couldn't resolve}
Root cause: Agents sharing the same browser session (no --session flag).
export AGENT_BROWSER_SESSION=agent-{N} in their promptagent-browser auth save was run before firing agentsagent-browser --session test auth login app-loginagent-browser session list — each agent should have its own sessionsnapshot -i to get current refs — refs go stale after navigation@ref selectors (e.g. click @e5) instead of CSS selectorsfind role button click --name "Button Text"agent-browser eval "document.querySelector('selector').click()" as JS fallbackagent-browser scroll down firstsnapshot -i between steps to verify current page stateagent-browser open {url} to navigate directly instead of clicking throughsnapshot -i and pick the specific @reffind role button click --name "Exact Text" for precision# Wave Orchestration — Deep Dive
How to construct agent prompts for BOTH code-review and browser-testing agents, collect results, resolve conflicts, and decide when to stop.
---
## Agent Prompt Construction
### Code-Review Agent Prompt
Every code-review agent gets this structure:
```
You are Agent {N} in a quality swarm, Wave {W}.
== PROJECT CONTEXT ==
{Insert AGENTS.md content here, or key excerpts if AGENTS.md is very long}
== YOUR ASSIGNMENT ==
Scope: {list of files/directories this agent owns}
Mode: {quality-polish | bug-hunt | performance | full-audit}
Standard: {ship-it | premium | obsessive}
== CHECKLIST ==
{Mode-specific checklist from swarm-modes.md}
== INSTRUCTIONS ==
1. Read every file in your scope thoroughly
2. For each file, check against the checklist above
3. Fix issues directly by editing files
4. Track what you found and what you fixed
5. Note anything that needs human decision or spans outside your scope
== OUTPUT FORMAT ==
Return a structured summary:
FINDINGS:
- [file:line] Issue description → FIXED / NEEDS ATTENTION / SKIPPED (reason)
FILES MODIFIED:
- path/to/file.tsx
ISSUES REMAINING:
- [description of anything you couldn't fix]
QUALITY SCORE: {1-10} for your scope area
```
### Browser-Testing Agent Prompt (THE IMPORTANT ONE)
Browser agents get a completely different prompt. They USE the app. Each agent gets its OWN isolated browser session — this is critical for parallel execution.
```
You are Agent {N} — a browser-testing agent in Wave {W}.
== YOUR MISSION ==
You are testing a LIVE RUNNING APP at {dev_server_url}.
Your job: exercise the "{feature_name}" flow by actually using the app in a real browser.
Click buttons. Fill inputs. Navigate. Scroll. USE IT LIKE A REAL USER.
== BROWSER SESSION SETUP (DO THIS FIRST!) ==
You have your own isolated browser session. EVERY agent-browser command MUST use your session.
Step 1 — Set your session env var (do this ONCE at the start):
export AGENT_BROWSER_SESSION=agent-{N}
Step 2 — Authenticate using the pre-saved auth profile:
agent-browser auth login {auth_profile_name}
Step 3 — Verify you're logged in:
agent-browser snapshot -i
You should see the app's authenticated shell (navigation, content, etc.).
If you see a login page, something went wrong — do NOT proceed until authenticated.
== AGENT-BROWSER COMMAND REFERENCE ==
ALL commands automatically use your session via the AGENT_BROWSER_SESSION env var.
Navigation:
agent-browser open {url} — Navigate to a URL
agent-browser scroll down — Scroll down
agent-browser scroll up — Scroll up
agent-browser press Escape — Press a key
agent-browser wait --load networkidle — Wait for page to fully load
Inspection (USE FREQUENTLY):
agent-browser snapshot -i — See interactive elements only (PREFERRED)
agent-browser snapshot — See full page text representation
agent-browser snapshot -c — Compact mode (removes empty elements)
agent-browser screenshot — Take a visual screenshot
Interaction (USE @ref SELECTORS from snapshots):
agent-browser click @e5 — Click element with ref e5
agent-browser fill @e3 "hello world" — Type into input with ref e3
agent-browser find role button click --name Submit — Find by ARIA role and click
Advanced:
agent-browser eval "document.querySelector('.my-class').click()" — JS fallback
agent-browser get text @e1 — Get text content of element
agent-browser is visible .my-selector — Check if element is visible
== HOW SNAPSHOT REFS WORK ==
When you run `snapshot -i`, you get output like:
[ref=e1] <button> Home
[ref=e2] <button> Messages
[ref=e3] <input placeholder="Search...">
[ref=e4] <button> Settings
Use these refs to interact: `click @e1`, `fill @e3 "text"`, `get text @e4`
Refs change after navigation/state changes — always take a fresh snapshot before clicking.
== YOUR FLOW TO TEST ==
{Specific user journey for this agent, e.g.:}
1. Navigate to the home page
2. Find a companion in the stories bar
3. Click on the companion to select them
4. Verify the action flyout appears (Studio, Surprise, Message buttons)
5. Click "Studio" — verify the Studio panel opens
6. Select a style, scene, and expression
7. Click Generate — verify the generating indicator appears
8. Wait for result — verify new post appears in feed
== QUALITY STANDARD: {standard} ==
== MINDSET: FIGHT FOR QUALITY ==
You are NOT a passive observer. You are an AGGRESSIVE TESTER.
DO:
- Take a `snapshot -i` before EVERY interaction to get fresh refs.
- Click every button in your flow using @ref selectors. Verify it does what it should.
- If something doesn't respond to a click, investigate WHY.
Is it covered by another element? Check z-index.
Is the click handler missing? Read the source code.
Is an animation blocking it? Check animation timing.
- If a dialog opens, take a snapshot and interact with EVERYTHING in it.
- If you find a bug, READ THE SOURCE CODE and FIX IT by editing files.
- Take snapshots before and after key actions to verify state changes.
- Try edge cases: rapid clicking, empty inputs, long text, back button.
- Verify loading states actually appear during async operations.
- Check that error states show meaningful messages.
DON'T:
- Accept "it loaded without errors" as a passing grade.
- Skip elements because they're hard to click — that IS the bug.
- Give up after one attempt. Try `find role button click --name "X"` or JS eval as fallback.
- Use stale refs — always snapshot before clicking.
- Report issues without investigating root cause.
- Just observe — IMPROVE. Find bugs, understand them, fix the code.
== WHEN YOU FIND A BUG ==
1. Take a snapshot showing the issue
2. Describe exactly what happened vs what should have happened
3. Read the relevant source code to understand WHY
4. Edit the source file to fix the root cause
5. Verify the fix: `agent-browser open {url}` to reload, then re-test the flow
== CLEANUP ==
When you're done testing, close your session:
agent-browser close
== OUTPUT FORMAT ==
FLOW TESTED: {description of what you tested}
STEPS COMPLETED:
1. [step] — PASS / FAIL (detail)
2. [step] — PASS / FAIL (detail)
...
BUGS FOUND AND FIXED:
- [description] — Root cause: [cause] — Fix: [what you changed in which file]
BUGS FOUND BUT NOT FIXED:
- [description] — Why: [reason you couldn't fix it]
OBSERVATIONS:
- [anything notable about UX, timing, visual issues]
FILES MODIFIED:
- path/to/file.tsx
```
### Wave 2+ Additions
For subsequent waves, prepend previous wave context:
```
== PREVIOUS WAVE RESULTS ==
Wave {W-1} completed with {N} agents.
Agent covering your scope found:
{Previous agent's findings for this scope}
Other agents found (cross-cutting):
{Summary of cross-scope issues}
YOUR FOCUS THIS WAVE:
1. Verify previous fixes are correct — retest the flows that had bugs
2. Find issues the previous wave missed — go deeper
3. Check for regressions introduced by other agents' fixes
4. Test edge cases that first-pass agents didn't try
5. Look at the UX critically — not just "does it work" but "does it work WELL"
```
---
## Browser Session Pre-Flight (Orchestrator Responsibility)
Before firing ANY browser-testing agents, the orchestrator MUST set up auth:
### Step 1: Save Auth Credentials
```bash
# Run this ONCE before firing browser agents
# The auth profile name should match what agents are told to use
agent-browser auth save app-login \
--url {dev_server_url} \
--username {login_email} \
--password {login_password}
```
This saves credentials to an encrypted vault. Agents reference the profile by name — they never see raw credentials.
### Step 2: Verify Auth Works
```bash
# Test with a throwaway session
agent-browser --session preflight-test auth login app-login
agent-browser --session preflight-test snapshot -i
# Should show authenticated app shell, NOT a login page
agent-browser --session preflight-test close
```
### Step 3: Include Session Setup in Every Agent Prompt
Every browser agent prompt MUST include:
1. `export AGENT_BROWSER_SESSION=agent-{N}` — unique per agent
2. `agent-browser auth login app-login` — uses the saved profile
3. `agent-browser snapshot -i` — verify auth succeeded
**CRITICAL**: Without session isolation, all agents share one browser and fight over the same page. Each agent MUST have `AGENT_BROWSER_SESSION` set to a unique value.
### Step 4: Cleanup After Wave
After all agents complete, clean up sessions:
```bash
agent-browser session list
# Close any remaining sessions
agent-browser --session agent-1 close
agent-browser --session agent-2 close
# etc.
```
---
## Firing Agents in Parallel
Use a single message with multiple `Agent` tool calls:
```
Agent 1: subagent_type="general-purpose", prompt="You are Agent 1..."
Agent 2: subagent_type="general-purpose", prompt="You are Agent 2..."
Agent 3: subagent_type="general-purpose", prompt="You are Agent 3..."
```
All agents in the same message fire in parallel. Do NOT await one before firing the next.
### Isolation Consideration
**Code-review agents**: Consider `isolation: "worktree"` for write-heavy work to prevent merge conflicts.
**Browser-testing agents**: Do NOT use worktree isolation — they need to see the same running dev server. Instead, each agent gets its own browser session via `AGENT_BROWSER_SESSION=agent-{N}`. This gives full browser isolation (separate cookies, separate page state, separate navigation) while still hitting the same dev server.
---
## Result Collection
When agents complete, parse results into structured format:
```typescript
interface AgentResult {
agentId: number
type: "code-review" | "browser-testing"
scope: string
findings: {
description: string
status: "fixed" | "needs-attention" | "skipped" | "passed"
file?: string
line?: number
}[]
filesModified: string[]
issuesRemaining: string[]
qualityScore?: number // Code-review agents
stepsCompleted?: { step: string; result: "pass" | "fail" }[] // Browser agents
}
```
### Deduplication
Multiple agents may touch shared files. Check for:
1. **Same file edited by multiple agents** — Review changes for conflicts
2. **Contradictory fixes** — One agent adds something, another removes it
3. **Overlapping changes** — Two agents fix the same thing differently
Resolution: Prefer the fix from the agent whose scope owns the file.
---
## Build Verification
After every wave, run the project build:
```bash
npm run build
```
### If Build Passes
- Wave succeeded — report results, proceed to next wave
### If Build Fails
- Parse error output
- Identify which agent's changes broke the build
- Fix the build error
- Re-run build to confirm fix
- Then report results
---
## Wave Progression Logic
### Full Assault (Recommended)
```
Wave 1: Code-Review agents → Build Check → Report
↓
Wave 2: Browser-Testing agents → Build Check → Report
↓
If issues remain: Wave 3 (Browser-Testing) → Build Check → Report
If clean: Done
```
### Code Review Only
```
Wave 1: Code-Review agents → Build Check → Report
↓
If issues remain: Wave 2 (with findings) → Build Check → Report
↓
If clean: Done
```
### Browser Testing Only
```
Wave 1: Browser-Testing agents → Build Check → Report
↓
If issues remain: Wave 2 (with findings) → Build Check → Report
↓
If clean: Done
```
### Until Perfect (Any Type)
```
Fire Wave N → Build Check → Report
↓
If any issues found: Fire Wave N+1 → loop
If zero issues: Done
↓
Safety limit: Max 5 waves (prevent infinite loop)
```
---
## Commit Strategy
### Auto-Commit (Per Wave)
After each successful wave, commit only the files agents modified:
```bash
git add {specific files from agent results}
git commit -m "fix: wave {N} ({type}) — {issue_count} fixes
{brief summary of main fixes}
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
```
### Manual Commit
After all waves complete, show the user:
1. Full diff (`git diff`)
2. Summary of all changes
3. Suggested commit message
---
## Cross-Cutting Issues
Some issues span multiple agents' scopes:
- **Shared components**: A button style issue affects every page
- **Service layer**: An API client bug affects all data fetching
- **Global styles**: CSS changes affect everything
Handle by:
1. Flagging them in agent results as "cross-cutting"
2. Fixing once in a dedicated pass after the wave
3. Including in next wave context so agents don't re-flag
---
## Reporting
### Per-Wave Report
```
## Wave {N} Complete — {Code Review | Browser Testing}
Agents: {count} | Issues Found: {found} | Fixed: {fixed}
Build: PASS / FAIL | Type: {code-review | browser-testing}
### Changes by Agent
| Agent | Feature/Scope | Found | Fixed | Result |
|-------|---------------|-------|-------|--------|
| 1 | Studio flow | 3 | 3 | 5/6 steps passed |
| 2 | Messaging | 1 | 1 | 4/4 steps passed |
| 3 | Feed | 2 | 2 | 3/3 steps passed |
### Key Fixes
- Flyout buttons untargetable during animation → fixed scale: 0 to 0.6
- Click-outside handler using wrong event → switched to mousedown
- Button spacing too tight → increased gap
### Next: {Wave N+1 / Done}
```
### Final Report
```
## Swarm Complete
Total Waves: {count} ({N} code-review, {M} browser-testing)
Total Issues Found: {total} | Fixed: {fixed}
Files Modified: {count}
Build: PASS
### Wave Summary
| Wave | Type | Agents | Found | Fixed |
|------|------|--------|-------|-------|
| 1 | Code Review | 5 | 16 | 16 |
| 2 | Browser Test | 4 | 3 | 3 |
| 3 | Browser Test | 4 | 0 | 0 |
### All Fixed Issues
{grouped by category}
### Remaining (Human Decision)
{anything agents couldn't resolve}
```
---
## Troubleshooting
### Browser Agents All Stuck on Login Page
**Root cause**: Agents sharing the same browser session (no `--session` flag).
- Verify each agent has `export AGENT_BROWSER_SESSION=agent-{N}` in their prompt
- Verify `agent-browser auth save` was run before firing agents
- Test auth manually: `agent-browser --session test auth login app-login`
- Check `agent-browser session list` — each agent should have its own session
### Browser Agents Can't Click Elements
- Take a fresh `snapshot -i` to get current refs — refs go stale after navigation
- Use `@ref` selectors (e.g. `click @e5`) instead of CSS selectors
- If ref doesn't work, try `find role button click --name "Button Text"`
- Try `agent-browser eval "document.querySelector('selector').click()"` as JS fallback
- Check if animations are blocking (scale: 0, opacity: 0 during transition)
- Check z-index stacking — another element may be covering the target
- Verify the element is in viewport: `agent-browser scroll down` first
### Browser Agents Get Lost
- Always `snapshot -i` between steps to verify current page state
- Use `agent-browser open {url}` to navigate directly instead of clicking through
- Include explicit "verify you see X" steps between navigation
- Make flow descriptions specific with element text/labels to look for
### "matched 2 elements" Error
- The selector matched multiple elements. Use `snapshot -i` and pick the specific `@ref`
- Or use `find role button click --name "Exact Text"` for precision
### Agents Not Finding Issues
- Check AGENTS.md has enough context
- Verify scope mapping is correct
- Try "obsessive" standard — agents look deeper
- For browser agents: make flows more specific, test more edge cases
### Too Many Conflicts Between Agents
- Reduce agents per wave (3-4 instead of 6-8)
- Use worktree isolation for code-review agents
- Make scope boundaries clearer
### Build Keeps Breaking
- Check for circular dependencies between scopes
- Run typecheck between waves
- Consider sequential waves for fragile codebases