wcag-auditor
Use when the user wants to audit their own web application for WCAG accessibility compliance, run an a11y check on a URL (including authenticated routes), generate a markdown accessibility findings report, fill in a VPAT / ACR, or get concrete remediation diffs for accessibility violations. Default target is WCAG 2.2 Level AA (covers 2.0/2.1 A/AA transitively); AAA is opt-in. VPAT fill-in requires a user-supplied ITI VPAT 2.5 INT template; covers WCAG + Section 508 + EN 301 549 via crosswalks.
Works with
---
name: wcag-auditor
description: Use when the user wants to audit their own web application for WCAG accessibility compliance, run an a11y check on a URL (including authenticated routes), generate a markdown accessibility findings report, fill in a VPAT / ACR, or get concrete remediation diffs for accessibility violations. Default target is WCAG 2.2 Level AA (covers 2.0/2.1 A/AA transitively); AAA is opt-in. VPAT fill-in requires a user-supplied ITI VPAT 2.5 INT template; covers WCAG + Section 508 + EN 301 549 via crosswalks.
license: MIT
---
# WCAG Auditor
Audit the user's **own web application** for WCAG 2.2 accessibility compliance.
Runs axe-core via Playwright against public and authenticated routes, maps
violations to specific WCAG success criteria, and proposes concrete Edit-tool
diffs against the user's source code.
## Prerequisites
- **Node.js ≥ 22** (current active LTS). The scripts use modern ESM features and will fail on Node 20. This is the only thing the user must install themselves.
- **Runtime dependencies** (`playwright`, `@axe-core/playwright`, `axe-core`, `fast-xml-parser`, `docx`, `jszip`) and the **Playwright Chromium binary** are installed automatically by Claude on first use — see the bootstrap step at the top of the workflow. The user does not run anything manually.
## When to use this skill
Invoke when the user says any of:
- "audit my site for accessibility"
- "check WCAG compliance" / "run an a11y check"
- "find accessibility bugs in <URL>"
- "generate a VPAT" / "fill in an ACR" / "make an accessibility conformance report"
- "what accessibility issues does <URL> have?"
- "make my site WCAG-compliant"
Do **not** use this skill for:
- Heuristic UI/UX review unrelated to WCAG — use `web-design-guidelines` instead
- Accessibility of native mobile apps, desktop apps, or PDFs — this skill audits web content only
- Auditing sites the user does not own, where no source is available — the skill relies on reading the user's repo to propose fixes
## Workflow
### 0. Bootstrap (auto, on first use and after plugin updates)
**Run this before step 1 every time the skill is invoked.** It is a cheap
no-op when dependencies are already installed, and it self-heals after
plugin version bumps (which land the skill in a new versioned cache dir
without `node_modules/`).
Determine the skill install dir — typically the directory that contains
this `SKILL.md`. In a plugin install that will be something like:
```
~/.claude/plugins/cache/wcag-auditor-tools/wcag-auditor/<version>/skills/wcag-auditor/
```
The skill's `package.json` lives at the **plugin root** (two levels up
from `skills/wcag-auditor/`). From now on, use `<PLUGIN_ROOT>` to refer to
that directory. **Do not `cd` into it** — `cd` can be fragile across Claude
Code shells (especially on Windows where paths contain spaces and
backslashes). Instead, pass the plugin root as an absolute path to every
command, either via `--prefix` (for npm) or as part of the argument path.
1. If `<PLUGIN_ROOT>/node_modules/` does not exist, install dependencies.
Use `--prefix` so the command works regardless of current working
directory and without needing a `cd`:
```bash
npm install --prefix "<PLUGIN_ROOT>"
```
This installs `playwright`, `@axe-core/playwright`, `axe-core`,
`fast-xml-parser`, `docx`, and `jszip`. Tarballs are npm-cached
globally, so subsequent installs after plugin updates are fast.
2. Install the Playwright Chromium binary. **Always invoke Playwright's
CLI entry point directly via `node`**, *not* via `npx playwright` and
*never* via `node_modules/.bin/playwright` — the `.bin/` shim is a
bash script on Unix and a `.cmd` on Windows, and trying to run it
with `node <path-to-shim>` on Windows fails with a `SyntaxError:
missing ) after argument list` (Node parses the bash shebang script
as JavaScript). The CLI entry point is an ESM file and is fully
cross-platform:
```bash
node "<PLUGIN_ROOT>/node_modules/playwright/cli.js" install chromium
```
Exits in under a second with "chromium X is already installed" when
the correct revision is cached (`~/Library/Caches/ms-playwright/` on
macOS, `~/.cache/ms-playwright/` on Linux,
`%LOCALAPPDATA%\ms-playwright\` on Windows). Downloads only when
Playwright version changed.
Both commands are idempotent. If the user has not pre-authorized `npm` /
`node` in their Claude Code permissions, the first invocation prompts for
approval; after that they run silently.
Do not proceed to step 1 until both commands complete successfully
(exit 0). If `npm install` fails (e.g., offline, disk full), surface
the error and stop — the audit scripts cannot run without dependencies.
**Platform note:** on Windows, `<PLUGIN_ROOT>` will look like
`C:\Users\<Name>\.claude\plugins\cache\wcag-auditor-tools\wcag-auditor\<version>`.
Always quote the path when passing to `--prefix` or as an argument, since
it almost always contains spaces (e.g., OneDrive-synced home directories).
### 1. Clarify scope (mandatory gate)
**You MUST confirm all scope parameters with the user via the `AskUserQuestion`
tool before running any audit, login, or score script.** This holds even when
the user's prompt appears complete and even when defaults seem obviously
correct — the user has explicitly opted into confirming defaults rather than
having them silently assumed.
The only exception: if the user has said in this conversation "use defaults,
don't ask" (or equivalent), skip to step 2.
Use `AskUserQuestion` to confirm each of the following. Pre-fill the option
list with the inferred or default value marked, so the user can accept with
one click:
- **Target URL(s)** — the URL, dev server, or staging origin to audit. If the
user provided one, present it as the default option alongside "something
else". If not, this is a free-text answer.
- **WCAG level** — options: `AA (default)`, `AAA (opt-in, aspirational)`.
- **Auth required** — options: `No, public routes only`, `Yes, capture session via login.mjs`.
- **Viewports** — options: `Desktop 1280×800 + mobile 375×667 (default)`, `Custom`.
- **Framework** — only ask if the framework is not unambiguously detectable
from the repo (`package.json`, file layout). If detection is clear, state
the detected framework in your next message and proceed without asking.
Do not start step 2 until every applicable question above has been answered.
### 2. Discover URLs
Consult `references/url-discovery.md`. Detect the framework from the user's
repo (package.json, file layout), run the appropriate recipe to extract a
route list, resolve any dynamic segments (`[id]`, `:id`) to concrete URLs
using real test-user IDs, and produce `urls.txt`. Show the list for review
before auditing.
For authenticated SaaS routes, sitemaps are insufficient — the framework
recipe is essential.
### 3. Set up auth (if needed)
```bash
node scripts/login.mjs --url <login-url> --out ./auth.json
```
Playwright opens a headed browser; the user completes login (including MFA)
and presses Enter in the terminal. Session state saves to `./auth.json`.
**Important caveats to communicate:**
- `auth.json` contains live session credentials — already gitignored, never commit it
- Session expires when the user's app session expires; re-run `login.mjs` when needed
- CSRF tokens with short lifetimes may require re-login
### 4. Run the automated audit
All outputs default to `./wcag-audit/` in the current working directory —
a single workspace directory keeps audit artifacts together and easy to
`.gitignore`. Override with `--out` if needed.
Single URL:
```bash
node scripts/audit.mjs --url <url> --auth ./auth.json
# writes ./wcag-audit/audit-<timestamp>.json
```
Multi-URL (recommended):
```bash
node scripts/audit-site.mjs \
--urls ./urls.txt \
[--sitemap https://example.com/sitemap.xml] \
[--crawl-from https://example.com/dashboard --depth 2] \
--auth ./auth.json
# writes ./wcag-audit/aggregated.json + per-URL JSON + urls.resolved.txt
```
### 5. Run the manual-check pass
Automated axe catches ~30–40% of WCAG failures. For each audited URL, walk
through `references/manual-checks.md` and run the documented Playwright MCP
procedures. Key manual checks:
- **SC 2.4.7 Focus Visible** — Tab through the page, verify focus indicator visible at each step
- **SC 2.1.2 No Keyboard Trap** — verify every widget can be escaped via keyboard
- **SC 1.4.10 Reflow** — resize to 320×800, confirm no horizontal scrolling
- **SC 2.5.8 Target Size (Minimum)** — verify interactive targets ≥ 24×24 CSS pixels
- **SC 1.3.4 Orientation** — resize to portrait and landscape phone dimensions
- **SC 3.2.6 Consistent Help** (new in 2.2) — help mechanism in same relative position across pages
Use `mcp__plugin_playwright_playwright__browser_*` tools. Record each manual
finding the same way as axe violations: cite the SC, describe the failure,
propose a fix.
For AAA audits, also consult `references/manual-checks-aaa.md`.
### 6. Score and derive conformance
```bash
# Multi-URL input
node scripts/score.mjs \
--aggregated ./wcag-audit/aggregated.json \
--out ./wcag-audit/score.json
# Single-URL input is also accepted (wrapped to aggregated shape internally)
node scripts/score.mjs \
--aggregated ./wcag-audit/audit-<timestamp>.json \
--out ./wcag-audit/score.json
```
Produces per-SC classification (Supports / Partially Supports / Does Not
Support / Not Evaluated). The `not-evaluated` SCs are those that require
manual-check results — update them based on step 5.
### 7. Triage & remediate (conversational)
Before starting: announce the total violation count (e.g., "5 violations
found; I'll walk through each one.") and keep an internal list of which
violations are pending, fixed, or declined as you go.
For **each** violation (automated or manual):
1. Cite the WCAG SC by number and title (look up in `references/wcag-2.2-criteria.md`)
2. Explain user impact plainly (who is affected, how)
3. **Locate the source**: match axe's CSS selector and HTML snippet to files in the user's repo. Use `Grep` for HTML patterns, `Glob` for component files.
4. Pick the closest remediation pattern from `references/remediation-patterns.md`
5. Propose a concrete `Edit` tool diff against the matched source file
6. For complex cases, explain the fix first, then offer the edit
**Handling the user's response (critical):**
- **Accept / yes / "fix it"** → apply the edit, mark this violation fixed,
move to the **next violation in the list** without waiting for further
input.
- **Decline / no / "skip" / "not now"** → do **not** stop. Mark this
violation declined, note any reason the user gave, and move to the
**next violation in the list** immediately. A "no" on one violation is
never a signal to end the walkthrough — it only ends this one item.
- **"Stop" / "end" / "that's enough"** → this is the only input that
ends the walkthrough early. Everything else continues.
- **Clarifying question** → answer it, then re-ask the accept/decline
question for the same violation.
Do not batch-ask ("want me to fix all of them?") — present one violation
at a time so the user can make per-item decisions.
When the list is exhausted (or the user says "stop"), print a summary:
total violations, how many fixed, how many declined (with reasons if
given), and remind the user that step 8 (re-audit) is next if any fixes
were applied.
This is the high-value step — the report is useful, but engineering teams
want diffs.
### 8. Re-audit after fixes
If any source edits were applied in step 7, rerun the audit from step 4 so
that the findings report and VPAT reflect the **post-fix state** — a
conformance report based on the pre-fix snapshot is misleading. Overwrite
the prior `./wcag-audit/aggregated.json` (or `audit-<ts>.json` for single-URL)
and rerun `score.mjs` against the new result.
If no edits were applied in step 7 (report-only run), skip this step.
Diff the new `aggregated.json` against the prior one to confirm violations
were fixed and none regressed.
### 9. Generate the findings report
```bash
node scripts/report-generate.mjs \
--aggregated ./wcag-audit/aggregated.json \
--score ./wcag-audit/score.json
# writes ./wcag-audit/report.md
```
Deterministic markdown — same inputs produce byte-identical output. Safe to
diff between runs, commit to the repo, or publish. Reflects the most recent
audit (post-fix if step 8 ran).
### 10. Generate the VPAT ACR (mandatory prompt)
**You MUST prompt the user via `AskUserQuestion` whether to generate a
formal Accessibility Conformance Report, even if they did not mention it.**
A findings report (step 9) is *not* the same artifact as a VPAT/ACR — ACRs
are the deliverable procurement and legal teams expect. Never silently
skip this step.
Present three options:
- **Skip** — the findings report is sufficient for our purposes.
- **Worksheet only** — markdown table (`./wcag-audit/ACR-<product>-<date>-worksheet.md`),
no ITI template required. Fast, always works, good for internal review.
- **Full .docx ACR** — fills in a user-supplied ITI VPAT 2.5 INT `.docx`
template. Best-effort table population; worksheet companion also produced.
User must download the template from
<https://www.itic.org/policy/accessibility/vpat> first — this skill does
not redistribute it.
If the user picks Worksheet or Full .docx, also collect `--product "<name>"`
and `--version "<v>"` via `AskUserQuestion` before running (both are
required by `vpat-fill.mjs`).
Commands:
```bash
# Worksheet mode
node scripts/vpat-fill.mjs \
--aggregated ./wcag-audit/aggregated.json \
--score ./wcag-audit/score.json \
--product "MyApp" --version "1.0"
# writes ./wcag-audit/ACR-MyApp-<date>-worksheet.md
# .docx mode (user-supplied ITI template)
node scripts/vpat-fill.mjs \
--aggregated ./wcag-audit/aggregated.json \
--score ./wcag-audit/score.json \
--product "MyApp" --version "1.0" \
--template ./VPAT2.5INT.docx
# writes ./wcag-audit/ACR-MyApp-<date>.docx + companion worksheet
```
After running, report the absolute output path(s) to the user.
## Flag reference
### `audit.mjs` / `audit-site.mjs`
| Flag | Purpose |
|---|---|
| `--url <url>` / `--urls <path>` / `--sitemap <url>` / `--crawl-from <url>` | URL sources (at least one required for audit-site) |
| `--depth <n>` | Crawl depth for `--crawl-from` (default 1) |
| `--include <glob>` / `--exclude <glob>` | URL filters (repeatable) |
| `--auth <path>` | Playwright `storageState` JSON |
| `--level AA\|AAA` | WCAG level (default AA) |
| `--viewport <WxH>` | Viewport (repeatable; default: 1280x800 + 375x667) |
| `--concurrency <n>` | Parallel audits (default 1, safe for dev servers) |
| `--include-best-practice` | Include axe best-practice rules (non-normative) |
| `--out <path>` | Output path/directory |
| `--fail-on <level>` | Exit 1 on violations ≥ level; one of: none\|minor\|moderate\|serious\|critical\|any (default: none) |
### Exit codes (all scripts)
- `0` — success, threshold not crossed
- `1` — success, threshold crossed (a11y gate failed)
- `2` — script error (network, bad URL, expired auth, axe crash)
## Reference files
| File | Purpose |
|---|---|
| `references/wcag-2.2-criteria.md` | All 86 SCs: number, level, title, intent, W3C URL |
| `references/axe-rule-mapping.md` | axe rule → WCAG SC mapping (auto-generated from axe-core) |
| `references/manual-checks.md` | Manual-check procedures for A/AA SCs axe can't automate |
| `references/manual-checks-aaa.md` | AAA-only manual checks |
| `references/remediation-patterns.md` | Fix library: per rule, HTML/JSX/ARIA snippets |
| `references/url-discovery.md` | Per-framework recipes to generate `urls.txt` |
| `references/section-508-mapping.md` | 508 ↔ WCAG crosswalk |
| `references/en-301-549-mapping.md` | EN 301 549 ↔ WCAG crosswalk |
| `references/vpat-mapping.md` | How findings map into VPAT tables |
## Known limitations (v0.1.0)
- **Auth:** `storageState` only. No bearer tokens, basic auth, or custom headers.
- **Multi-framework:** each audit run covers one framework's recipe at a time.
- **508/EN 301 549:** cells derived from WCAG findings via crosswalks, not independently evaluated.
- **VPAT `.docx` fill-in:** best-effort — template layouts vary. The worksheet is always produced as a safety net.
- **Framework route-manifest parsers:** deferred to v0.2.0. Use documented recipes in `url-discovery.md` for now.
- **Baseline / suppressions file:** not yet supported. Deferred to v0.2.0.More Accessibility skills
skill-creator
anthropics/skills
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
hyperframes-core
heygen-com/hyperframes
The HyperFrames composition contract — build one renderable project. Use for composition structure, the `data-*` timing attributes, `class="clip"`, tracks, sub-compositions, variables, framework-owned media playback, deterministic-render rules, and validation. Also covers Tailwind projects and the STORYBOARD.md / SCRIPT.md plan formats. Read before writing composition HTML.
ui-ux-pro-max
nextlevelbuilder/ui-ux-pro-max-skill
UI/UX design intelligence for web, mobile, and desktop. This skill should be used when designing, building, reviewing, or fixing interfaces, including pages, components, design systems, accessibility, interaction, responsive layout, typography, color, charts, and stack-specific UI implementation. Searchable local data: 79 searchable styles (50 active), 192 product palettes and reasoning profiles, 74 font pairings, 119 UX guidelines, 105 icons, 17 GSAP presets, 25 chart types, and 22 stacks.

