Claude
Skills
Sign in
Back

storybook

Included with Lifetime
$97 forever

Audit a Storybook instance for setup errors, a11y violations, interaction failures, and visual regressions. Auto-starts (or reuses) Storybook from cwd, walks every story headless, captures per-state screenshots (default/hover/active/focus-visible), harvests a11y+interactions panels, and runs claude -p visual grounding. Triggers when "audit storybook", "check my stories", "find storybook issues", "storybook a11y review".

Securityscripts

What this skill does


# Storybook Audit Skill

Audits a project's Storybook instance for setup failures, addon-a11y
violations, addon-interactions assertion failures, and per-state visual
regressions. Claude orchestrates a sequence of small bash scripts under
`scripts/` and JS injections under `injections/`; every deterministic step is
delegated, every subjective judgement (visual grounding) is performed by a
nested `claude -p` invocation. Like `/lint` for a Storybook -- reports scored
findings with severity classification, does NOT fix.

> **Visual Grounding Principle**: Per-state screenshots (`default`, `hover`,
> `active`, `focus-visible`) are the **primary** visual evidence for every
> AI-adjudicated finding. Non-default states identical to the default
> (pHash distance <= 2.0) are dropped; a dropped `focus-visible` shot is
> recorded as a P2 *missing focus indicator* finding rather than a missing
> screenshot defect. AI verdicts are only emitted against screenshots that
> survive the dedupe pass.

## 1. INTRODUCTION

### Purpose & Context

**Purpose**: Produce an evidence-backed report covering every story in a
Storybook instance, scoring findings by P0/P1/P2 severity with screenshot and
panel-state evidence.

**When to use**:

- Audit a Storybook instance before a UI release or PR merge
- Check accessibility coverage across all stories at once
- Verify play-function interactions still pass after a refactor
- Catch broken stories, blank canvases, or render-time console errors
- Surface missing focus-visible indicators across an entire component library

**Prerequisites**:

- `chrome-devtools` MCP server -- the primary Chrome owner. Launched with
  `--isolated`; confirmed via `list_pages` before any script runs.
- `agent-browser` CLI -- connects to chrome-devtools MCP's Chrome via
  `--cdp <port>`. Subcommands used: `open <url>`, `eval <expr>`, `snapshot`.
- `jq` -- all script JSON read/write.
- `curl` -- HTTP probes (`/index.json`, story iframe HTTP status).
- `magick` (ImageMagick) -- pHash dedupe for per-state screenshots
  (`magick compare -metric PHASH`).
- `claude` (Claude Code CLI, headless `-p` mode) -- visual grounding per
  screenshot.
- Node + npm in the target project, so `npm run storybook` can be invoked
  when no instance is already running.

### Your Role

You are a **Storybook QA Director**. You delegate mechanical work to the
scripts under `scripts/` and reserve your attention for orchestration and the
subjective visual grounding adjudication. You do not fix issues -- only
classify and report.

- **Thin orchestrator**: Invoke each phase script; pass run state via files
  under `$RUN_DIR`. Never re-implement script logic inline.
- **Evidence-first**: Every grounding verdict cites the screenshot path the
  capture step produced.
- **No re-runs**: Do not re-list stories, re-capture states, or re-probe
  panels once the canonical artifacts exist under `$RUN_DIR`.
- **Graceful degradation**: If `@storybook/addon-a11y` or
  `@storybook/addon-interactions` is missing, the relevant phase logs a
  warning to stderr and continues -- it is not a hard failure.
- **Headless by default**: pass `--headed` only when the user explicitly
  asks; it is forwarded to chrome-devtools MCP's `new_page`.

## 2. SKILL OVERVIEW

### Skill Input/Output Specification

#### Required Inputs

- A project directory at `$PWD` (or `--cwd`) whose `package.json` declares
  Storybook (`storybook` dependency, any `@storybook/*` package, or a
  `scripts.storybook*` entry).

#### Optional Inputs

- `--port <N>` -- Storybook port (default 6006).
- `--headed` -- forwarded to chrome-devtools MCP `new_page` for visible
  Chrome (default: headless).
- `--no-spawn` -- never start Storybook; require an instance already
  running on `--port`.
- `--story <id-glob>` -- restrict capture and panel scrape to matching ids.
- `--max-grounding N` -- cap the number of `claude -p` grounding calls.

#### Expected Outputs

- **Markdown report** at `$RUN_DIR/report.md` -- P0/P1/P2 sections with
  screenshot references.
- **JSON report** at `$RUN_DIR/report.json` -- machine-readable contract for
  downstream tooling.
- **Per-story artifacts** at `$RUN_DIR/stories/<id>/`:
  - `default.png`, `hover.png` (if differs), `active.png` (if differs),
    `focus-visible.png` (if differs)
  - `states.json` -- dedupe verdicts and pHash distances
  - `panels.json` -- a11y violations and interaction run outcomes
- **Smoke artifact** at `$RUN_DIR/smoke.json`.
- **Story index** at `$RUN_DIR/stories.json`.

#### Data Flow Summary

The skill detects Storybook in the cwd, brings up an instance (or reuses one),
attaches chrome-devtools MCP and agent-browser to the same Chrome, walks every
story headless, captures four per-state screenshots, scrapes addon-a11y and
addon-interactions panel state, grounds each non-dropped screenshot with
`claude -p`, and finally aggregates everything into a P0/P1/P2 report.
Concurrency is **serial per-story by default**; the model MAY parallelise the
per-story loop up to 4 via bash `&` + `wait`, but the canonical invocation is
serial for safety.

### Visual Overview

```plaintext
  PHASE 1: DETECT                    PHASE 2: LIFECYCLE UP
  ───────────────                    ─────────────────────
  scripts/detect.sh --cwd $PWD       scripts/lifecycle-up.sh --port 6006
  package.json signal:                 probe :PORT/index.json
   - storybook dep                     reuse OR spawn `npm run <script>`
   - @storybook/* dep                  poll readiness up to 90s
   - scripts.storybook*                writes $RUN_DIR/sb.pid + sb.log
  exit 1 -> abort                    exit 1 with --no-spawn and no instance
  │                                  │
  v                                  v
  PHASE 3: ATTACH CHROME             PHASE 4: SMOKE
  ──────────────────────             ──────────────
  list_pages (MCP)                   scripts/smoke.sh --cdp $CDP --url ...
  new_page http://localhost:PORT       install console.error listener
  CDP port from webSocketDebuggerUrl   sidebar presence
  agent-browser --cdp $CDP open ...    sample 3 stories for 404 / blank
  │                                  │
  v                                  v
  PHASE 5: LIST STORIES              PHASE 6: PER-STORY LOOP (serial)
  ─────────────────────              ─────────────────────────────────
  scripts/list-stories.sh              for ID in stories.json:
   GET /index.json (v7+)                 capture-states.sh --story $ID
   fallback: eval injections/             4 states + pHash dedupe
   story-index.js (v6+v7)                scrape-panels.sh --story $ID
   writes $RUN_DIR/stories.json           a11y + interactions panels
  │                                  │
  v                                  v
  PHASE 7: VISUAL GROUNDING          PHASE 8: REPORT
  ─────────────────────────          ────────────────
  for each non-dropped shot:           scripts/report.sh --run-dir $RUN_DIR
    scripts/ground.sh --image ...      severity bucketing
    --state default|hover|...          report.md + report.json
  honour --max-grounding cap         │
  │                                  v
  v                                  PHASE 9: TEARDOWN
                                     ─────────────────
                                     if spawned=true:
                                       scripts/lifecycle-down.sh
```

### Severity Bucketing

Severity assignment is performed by `scripts/report.sh`. The model does not
re-classify findings.

| Bucket | Triggers |
|--------|----------|
| **P0** | render crash, story 404, a11y `serious` or `critical`, interaction assertion failed |
| **P1** | a11y `moderate`, console error during story render, grounding "issue detected" with high-confidence keywords |
| **P2** | a11y `minor`, low-confidence grounding finding, missing focus-visible indicator (dropped focus-visible screenshot) |

## 3. SKILL IMPLEMENTATION

### Security

**Untrusted Input Handling** (OWASP LLM01): Story source, MDX docs, addon
Files: 15
Size: 76.1 KB
Complexity: 81/100
Category: Security

Related in Security