Package: @pbpyrojust/universal-accessibility-audit
CLI commands: universal-a11y-audit, uaaudit
Version: 0.2.8
A CLI toolkit for WCAG accessibility audits and browser-native AI readiness scoring with sitemap discovery, Playwright + axe-core scanning, and ticket-ready outputs. Built for development, staging, protected, and production sites.
- Sitemap-first URL discovery with WordPress, Yoast, Drupal, and standard sitemap.xml support
- Playwright + axe-core WCAG 2.1 Level AA scanning
- Agentic Lighthouse-style scoring for browser-native AI readiness
- Image alt text inventory with readability ratings
- Manual browser-saved sitemap XML fallback for protected sites
- CSV, JSON, Markdown, and backlog/ticket-ready outputs with importance and out-of-control flags
- WebMCP Protocol, Accessibility Trees, Semantic Data Formatting, and Layout Stability scoring
- Support for HTTP Basic Auth and form-login protected sites
- Node.js 20+
- pnpm (recommended) or npm
- Playwright Chromium
pnpm install
pnpm exec playwright install --with-deps chromiumOr with npm:
npm install
npx playwright install --with-deps chromiumnpm install -g @pbpyrojust/universal-accessibility-audit
npx playwright install --with-deps chromiumRun a full audit:
node scripts/run-audit.mjs --site https://www.example.comOr use the pnpm shortcut:
pnpm audit --site https://www.example.comOr use the installed CLI:
universal-a11y-audit audit --site https://www.example.com
uaaudit audit --site https://www.example.comnode scripts/run-audit.mjs --site <url> [options]| Flag | Description |
|---|---|
--site <url> |
(required) Target website URL |
--sitemap-url <url> |
Use a specific sitemap URL when auto-discovery is not enough |
--urls-file <path> |
Provide a text file of URLs to audit (one per line) |
--out-dir <path> |
Base output folder (default: reports) |
--run-id <id> |
Explicit run folder name |
--batch-size <n> |
Cap the number of URLs scanned in one run |
--slow |
Use more conservative navigation timing and retries |
--respect-robots |
Respect robots.txt disallow rules during URL filtering/crawling |
--cloudflare-aware |
Detect likely Cloudflare/WAF challenge pages and back off |
--retries <n> |
Override navigation retry count |
--backoff-ms <ms> |
Override retry backoff timing |
--crawl-delay-ms <ms> |
Add delay between scanned pages |
--no-tickets |
Skip ticket CSV generation in the full audit workflow |
--sheet-url <url> |
Google Sheet URL for filter link generation |
--include-path <filter> |
Include only URLs matching this path filter |
--exclude-path <filter> |
Exclude URLs matching this path filter |
--include-sitemaps <filter> |
Comma-separated filters for sitemap index entries |
--include-all-sitemaps |
Include all sitemaps from the sitemap index |
# Full sitemap-based audit
node scripts/run-audit.mjs --site https://www.example.com
# Protected-site conservative scan
node scripts/run-audit.mjs --site https://www.example.com --slow --respect-robots --cloudflare-aware
# Small-batch audit from a manual URL list
node scripts/run-audit.mjs --site https://www.example.com --urls-file ./reports/manual-urls.txt --batch-size 10
# Audit with HTTP Basic Auth
node scripts/run-audit.mjs --site https://staging.example.com --http-username myuser --http-password mypass
# Audit with form login
node scripts/run-audit.mjs --site https://staging.example.com --auth-config ./auth.local.json
# Explicit output folder
node scripts/run-audit.mjs --site https://www.example.com --out-dir ./reportsFor staging or password-protected sites, the tool supports two auth methods.
| Flag | Description |
|---|---|
--http-username <user> |
HTTP Basic Auth username |
--http-password <pass> |
HTTP Basic Auth password |
node scripts/run-audit.mjs \
--site https://staging.example.com \
--http-username your-user \
--http-password your-pass| Flag | Description |
|---|---|
--auth-config <path> |
Path to a local form-login config JSON file |
--login-url <url> |
Override the login URL |
--username <user> |
Override the username |
--password <pass> |
Override the password |
--username-selector <sel> |
Override the username input selector |
--password-selector <sel> |
Override the password input selector |
--submit-selector <sel> |
Override the submit button selector |
--ready-selector <sel> |
Override the post-login ready selector |
--post-login-wait-ms <ms> |
Override post-login wait time |
Create an auth config from auth-config.example.json:
{
"loginUrl": "https://staging.example.com/login",
"username": "your-username",
"password": "your-password",
"usernameSelector": "input[name='username']",
"passwordSelector": "input[name='password']",
"submitSelector": "button[type='submit']",
"readySelector": "body",
"postLoginWaitMs": 2000
}Instead of putting secrets on the command line:
export A11Y_HTTP_USERNAME=your-user
export A11Y_HTTP_PASSWORD=your-passOr for form login:
export A11Y_LOGIN_USERNAME=your-user
export A11Y_LOGIN_PASSWORD=your-passDo not commit real auth config files, credentials, or environment files.
The project ignores local auth files such as *.auth.json, auth.local.json, .auth.local.json, and .a11y-auth.local.json.
Each audit run creates a timestamped folder under reports/:
reports/
example.com-20260122-141010/
urls.txt
a11y-violations.csv
a11y-report.json
a11y-run-metadata.json
a11y-summary-google-doc.md
a11y-github-tickets.csv
a11y-image-alts.csv
agentic-lighthouse-scores.csv
agentic-lighthouse-report.json
latest
| File | Description |
|---|---|
urls.txt |
URL list used for the run |
a11y-violations.csv |
One row per violating axe node with impact, priority, importance, WCAG refs, ownership hints |
a11y-report.json |
Full per-page JSON scan results including axe results and Agentic Lighthouse page details |
a11y-run-metadata.json |
Run timing, page counts, axe rollups, and agentic scoring rollups |
a11y-summary-google-doc.md |
Paste-ready executive summary with WCAG findings and Agentic Lighthouse averages |
a11y-github-tickets.csv |
Backlog-ready tickets for global issues, page-level issues, and low agentic scores |
a11y-image-alts.csv |
Image alt-text inventory with readability ratings and suggested review notes |
agentic-lighthouse-scores.csv |
Per-page, per-category agent-readiness scores with findings and recommendations |
agentic-lighthouse-report.json |
Structured Agentic Lighthouse scoring details for every scored page |
latest |
Text pointer containing the latest run ID |
The audit workflow runs four steps:
- Discover URLs from the sitemap, unless
--urls-fileis provided. - Scan pages with Playwright, axe-core, image-alt inventory, and Agentic Lighthouse scoring.
- Generate a Google Docs-ready Markdown summary.
- Generate a GitHub/backlog-ready ticket CSV, unless
--no-ticketsis used.
The scan is intentionally two-layered:
- WCAG/axe layer: finds accessibility violations and affected DOM nodes.
- Agentic Lighthouse layer: scores how well AI/browser agents can understand, call, and safely operate functional page surfaces.
Violation output includes an importance field in addition to impact/priority for triage in ticketing systems.
The scan also flags issues that are likely out of direct control when they appear inside iframes, embedded media players, third-party widgets, or externally hosted embeds.
importance,likely_out_of_control,control_notes
importance,likely_out_of_control,control_notes,ticket_notes
The out-of-control detection is a best-effort heuristic designed to surface likely iframe/embed issues for manual review.
Each scan includes an agent-readiness score modeled after Lighthouse-style category scoring, separate from axe/WCAG violations.
| Category | What it checks |
|---|---|
| WebMCP Protocol | WebMCP-style manifests, page-level registration signals, named functional surfaces (cart, checkout, search, filter, sort, login, booking) |
| Accessibility Trees | Whether form controls and clickable components expose precise accessible names through labels, text, ARIA, titles, or placeholders |
| Semantic Data Formatting | Machine-readable discovery files: /llms.txt, /robots.txt, /sitemap.xml, /.well-known/ai-plugin.json |
| Layout Stability | Observed cumulative layout shift and whether interactive controls move after page load |
90–100: pass70–89: needs review0–69: fail
Agentic tickets are generated for category scores below 90.
Discover and export all URLs from a site's sitemap without running an audit:
node scripts/build-urls-from-sitemap.mjs --site https://www.example.com --out ./reports/urls.txtRun the Playwright + axe-core + agentic scan against a pre-built URL list:
node scripts/a11y-audit.mjs --urls-file ./reports/urls.txt --out-dir ./reports --run-id <run-id>node scripts/a11y-audit.mjs --crawl --start https://www.example.com --max-pages 50 --out-dir ./reportsnode scripts/generate-google-doc-report.mjs --run-dir ./reports/<run-id> --site https://www.example.comnode scripts/generate-ticket-csv.mjs --run-dir ./reports/<run-id>Extract URLs from a locally saved sitemap XML file:
node scripts/convert-sitemap-xml-to-urls.mjs --input ./saved-sitemap.xml --out ./reports/urls.txtWhen installed globally via npm, all commands are available through the universal-a11y-audit or uaaudit CLI:
| Command | Description |
|---|---|
audit --site <url> |
Full workflow: build URLs, scan, summary, ticket CSV |
build-urls --site <url> --out <path> |
Build a URL list from sitemap discovery |
scan --urls-file <path> --out-dir <path> |
Run Playwright + axe-core + agentic scan |
report --run-dir <path> |
Generate the docs-ready Markdown summary |
tickets --run-dir <path> |
Generate the GitHub/backlog ticket CSV |
sitemap-xml-to-urls --input <path> --out <path> |
Convert a saved sitemap XML into urls.txt |
help |
Show CLI help |
version |
Show package version |
universal-a11y-audit audit --site https://www.example.com
universal-a11y-audit audit --site https://www.example.com --slow --respect-robots --cloudflare-aware
universal-a11y-audit build-urls --site https://www.example.com --out ./reports/urls.txt
universal-a11y-audit scan --urls-file ./reports/urls.txt --out-dir ./reports
universal-a11y-audit report --run-dir ./reports/<run-id>
universal-a11y-audit tickets --run-dir ./reports/<run-id>
universal-a11y-audit sitemap-xml-to-urls --input ./saved-sitemap.xml --out ./reports/urls.txt| Script | Description |
|---|---|
pnpm audit |
Full audit against example.com |
pnpm audit:crawl |
Crawl-based audit (max 50 pages) |
pnpm audit:urls |
Scan from a pre-built URL list |
pnpm audit:slow |
Full audit in slow/protected-site mode |
pnpm build:urls |
Build URLs from sitemap only |
pnpm report |
Generate summary from latest run |
pnpm sitemap:xml-to-urls |
Convert saved sitemap XML to URL list |
pnpm pack:check |
Dry-run npm pack to verify package contents |
This repo is intended to stay public. Do not commit:
.npmrcwith real tokens- npm or GitHub access tokens
.envfiles with secrets- generated real-world reports under
reports/ - saved sitemap XML files from client sites
- internal or staging URLs
- browser/session files
git status
git ls-files
git grep -n "_authToken"
git grep -n "BEGIN PRIVATE KEY"
git grep -n "github_pat_"
git grep -n "ghp_"This project publishes as a public npm CLI package with optional GitHub Actions auto-publish on version tags. See PUBLISHING.md for the exact release steps.
MIT