Skip to main content
Glama
README.md
# yo-bug ๐Ÿ›

**English** ยท [็ฎ€ไฝ“ไธญๆ–‡](./README.zh-CN.md)

**"Yo, bug!"** โ€” Point at bugs, AI fixes them.

![yo-bug demo](https://raw.githubusercontent.com/WYYkerwin/yo-bug/master/assets/demo.gif)

MCP Server that gives AI coding assistants QA superpowers. One install, then your AI handles the entire test-feedback-fix loop.

In vibe coding, the bottleneck is testing: humans find bugs but struggle to describe them. yo-bug solves this by letting users point, click, or type โ€” while the AI automatically receives element locations, console errors, network failures, action recordings, and annotated screenshots.

## What it does

| For the Human | For the AI |
|---|---|
| Click a broken element โ†’ done | Gets: CSS selector + computed styles + React/Vue component name |
| Draw on a screenshot โ†’ done | Gets: annotated PNG as inline image content |
| Type a behavior bug ("scroll doesn't auto-jump") โ†’ done | Gets: structured text feedback linked to a checklist case |
| Check off a multi-step test case | Gets: which cases passed/failed, with linked feedback per case |
| Just use the app normally | Gets: last 100 user actions + 50 console errors + failed network calls |

The AI drives the entire workflow through MCP tools. Humans never need to learn commands, configure proxies, or modify their code.

## Install

```bash
npx yo-bug install
```

(or `npm install -g yo-bug && yo-bug install` if you prefer a global install)

This auto-detects your AI tool (Claude Code / Cursor / Windsurf) and writes the MCP config. One time, done forever.

## How it works

```
AI writes code
    โ†’ AI calls start_test_session()
    โ†’ Reverse proxy starts, injects test SDK into HTML responses
    โ†’ Browser opens (zero code changes to your project)
    โ†’ AI pushes grouped test cases (8 QA dimensions, multi-step scenarios)
    โ†’ Human runs each case; pass/fail at the case level
    โ†’ When failing, picks feedback mode: element / screenshot / text
    โ†’ AI calls list_feedbacks() + get_feedback() โ€” sees diagnostic data
    โ†’ AI must state root cause BEFORE writing fix (enforced by tool response)
    โ†’ AI fixes โ†’ calls resolve_feedback() โ†’ browser shows verify card
    โ†’ Human clicks Fixed / Locate (jump to element) / Still broken
    โ†’ Loop until done
```

## MCP Tools (9 total)

### Session Control
| Tool | Description |
|---|---|
| `start_test_session(port?, open?, storage?)` | Start test mode: auto-detect dev server, launch reverse proxy with SDK injection, open browser. `storage` defaults to `"project"` (saves under `<cwd>/.yo-bug/feedback/`); pass `"home"` for `~/.yo-bug/` |
| `stop_test_session()` | Stop test mode, return session summary (feedback stats, checklist results, weak dimensions, whether dev server was auto-closed) |

### Feedback
| Tool | Description |
|---|---|
| `list_feedbacks(status?, type?, limit?, all_sessions?)` | List submitted feedback. Defaults to current session only |
| `get_feedback(id)` | Full details: element info, console errors, network errors, action steps, annotated screenshot. Response includes a **mandatory diagnostic protocol** that forces the AI to identify root cause before writing code |
| `resolve_feedback(id)` | Mark as fixed โ†’ pushes a rich verification card to the browser (with screenshot thumbnail, element selector, page URL, locate button). Human confirms |

### Test Checklist (Grouped Test Cases)
| Tool | Description |
|---|---|
| `create_checklist(title, cases)` | Push structured test cases to browser. Each case has a title, sequential `steps[]`, expected result, priority, and QA dimension |
| `get_checklist_status()` | See which cases passed/failed and any user feedback per case |

### Test History
| Tool | Description |
|---|---|
| `save_test_record(module, ...)` | Save test results per module. Accumulates history for future reference |
| `get_test_history(module)` | Get historical test records. Shows frequently failing scenarios so AI prioritizes coverage |

## 8 QA Test Dimensions

The `create_checklist` tool embeds professional QA methodology. AI is guided to cover:

1. **Happy path** โ€” Core functionality works end-to-end
2. **Empty/boundary** โ€” Empty inputs, special chars, max length, zero/negative values
3. **Error states** โ€” Offline, server errors, timeouts, recovery
4. **Duplicate ops** โ€” Double-click, re-submit, concurrent requests
5. **State recovery** โ€” Refresh, back/forward, deep links, tab close/reopen
6. **Loading/async** โ€” Loading states, failed loads, stale data
7. **Responsive** โ€” 375px mobile width, touch targets, overflow
8. **Interaction detail** โ€” Tab order, Enter/Escape, disabled states, focus

Each case is multi-step (open page โ†’ fill form โ†’ click submit โ†’ verify result), so the human marks a whole scenario passed/failed rather than micro-managing each step.

## Three Feedback Modes

When a checklist case fails, users pick a mode that fits the bug:

| Mode | Shortcut | When to use |
|---|---|---|
| **Element** | `Alt+E` | Visual / component bug โ€” click the broken element, AI gets selector + styles + framework component name |
| **Screenshot** | `Alt+S` | Layout / styling bug โ€” drag to select a region, annotate with arrow / rect / circle / freehand / text |
| **Text** | (Checklist `โœ—`) | Behavior / logic bug ("doesn't auto-scroll", "wrong order") โ€” pure description, AI uses console/network data to find cause |

Other shortcuts: `Alt+X` toggle mode bar, `Esc` exit anything.

## In-Browser Feedback Management

Above the floating bug button you'll see a list icon with a red badge showing open feedback count. Click it to:

- See all open feedback you've submitted this session
- Edit description inline (click description text)
- Delete a feedback (trash icon, confirms first)
- View screenshot thumbnails

When all feedback is resolved, the button auto-hides.

## Auto-Captured Context

Every feedback submission automatically includes:

- **Console errors** โ€” last 50 `console.error`/`console.warn` entries with stack traces
- **Network failures** โ€” last 50 failed `fetch`/`XHR` requests with status, URL, duration
- **Unhandled exceptions** โ€” last 50 `window.onerror` + `unhandledrejection` events
- **Action recording** โ€” last 100 user actions (click / input / navigate / scroll / keypress) with timestamps
- **Element info** โ€” CSS selector, tag, text content, bounding rect, computed styles, React/Vue component name (when in element mode)

## Verify-Fix Flow

When AI calls `resolve_feedback()`, a rich verify card appears on the left:

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โ–ผ VERIFY FIX            [3] โ”‚  โ† collapsible header with count
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ [thumbnail*] "Button click  โ”‚
โ”‚              does nothing"   โ”‚
โ”‚              bug ยท element   โ”‚
โ”‚  ๐Ÿ“ <button> #submit-btn    โ”‚  โ† only when element info exists
โ”‚  ๐Ÿ”— /orders                  โ”‚
โ”‚  โฑ 5 min ago                โ”‚
โ”‚  [๐ŸŽฏ Locate*] [โœ“] [โœ—]        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
   * thumbnail only if a screenshot was attached
   * Locate only if an element selector was captured
```

- **๐ŸŽฏ Locate** scrolls to the element + flashes a red pulse twice. If the verify card was submitted on a different URL, it navigates there first. If the element no longer exists on the current page, shows a toast
- **โœ“ Fixed** confirms the fix โ†’ status: resolved
- **โœ— Still broken** sends it back โ†’ status: open (AI sees it in next `list_feedbacks` call)
- Click the header bar to collapse the whole stack when it gets in the way

## Theming

- Auto-detects `prefers-color-scheme` (light or dark)
- All UI uses design tokens, contrast-verified (WCAG AA)
- Glass-morphism panels with backdrop blur; clearly distinct from white host pages

## Works Inside Modal Dialogs

If your app opens a `<dialog>.showModal()` (which traps focus and inerts the rest of the page), yo-bug still works: it detects the open modal via the `:modal` selector plus a `MutationObserver`, and relocates the SDK host inside the dialog so focus is shared.

This means you can submit text feedback even when a modal is open โ€” the textarea will accept input normally. When the dialog closes, the host moves back out.

## i18n

SDK auto-detects `<html lang="...">`:
- Any value starting with `zh` (`zh`, `zh-CN`, `zh-Hans`, ...) โ†’ Chinese interface
- Everything else โ†’ English interface

MCP tool descriptions are in English (AI translates to the user's language naturally in chat).

## Architecture

```
Browser โ†’ Reverse Proxy (localhost:3695+) โ†’ Dev Server (localhost:5173)
              โ”‚
              โ”œโ”€ Auto-injects SDK into HTML responses
              โ”œโ”€ WebSocket passthrough (HMR works normally)
              โ”œโ”€ Feedback API (POST/GET/PATCH/DELETE)
              โ”œโ”€ Checklist API (push/poll/update)
              โ””โ”€ Verify API (push/confirm)

MCP Server (stdio) โ† AI Tool (Claude Code / Cursor / Windsurf)
              โ”‚
              โ”œโ”€ start/stop_test_session โ†’ controls proxy lifecycle
              โ”œโ”€ feedback tools โ†’ reads user submissions w/ diagnostic protocol
              โ”œโ”€ checklist tools โ†’ pushes grouped test cases, reads results
              โ””โ”€ history tools โ†’ persists test records per module
```

The proxy auto-detects dev server framework (Vite, Next.js, CRA, Webpack, Nuxt, Angular, Svelte, Astro) and port. If the dev server is already running, it connects. If not, it starts one. On `stop_test_session` it cleans up โ€” and tells the AI whether the dev server was auto-closed or left running (because the user had started it themselves).

If port `3695` is taken, yo-bug auto-increments to `3696`, `3697`... up to `3795`. Multiple projects can run yo-bug simultaneously without conflict.

## Security

- All data stays local โ€” feedback files in `<project>/.yo-bug/feedback/` by default (auto-`.gitignore`'d), or `~/.yo-bug/` if you opt in
- Feedback IDs validated against path traversal
- Input fields whitelist-filtered and length-limited
- Network interceptor uses exact pathname matching (no substring false positives)
- No data sent to any external service

## Requirements

- Node.js >= 18
- Any MCP-compatible AI tool
- A current-version browser (Chrome / Edge / Firefox / Safari)

## License

MIT