name: validate description: | Web standards audit — W3C HTML validity (validator.nu), W3C CSS validity (jigsaw.w3.org/css-validator), WCAG 2.1 accessibility (axe-core, pa11y, WAVE API). Dedicated to syntactic and accessibility conformance. Produces VALIDATE.md at project root. Dispatches the validator-analyzer agent with a STRICT scope filter — no meta/OG/JSON-LD/CWV/security-header noise. Trigger: "validate", "validation", "w3c", "html validity", "css validity", "wcag", "accessibility", "a11y audit", "axe", "pa11y", "wave", "validator.w3.org", "nu validator", "validation html", "accessibilité", "audit a11y", "audit wcag", "normes w3c", "conformité web", "validité html css". For security hardening (CSP, HSTS, 404) → use /harden. For SEO/indexability (meta, sitemap, JSON-LD) → use /seo. For AI engines (llms.txt, QAPage, entity SEO) → use /geo. argument-hint: [URL] [--fix] [--local|--full] [--no-external] allowed-tools:
This skill orchestrates a narrow-scope standards audit :
html-validate /
vnu.jar (LOCAL) or static fallback.stylelint / css-tree (LOCAL) or static fallback.pa11y / @axe-core/cli / WAVE API
(FULL) or axe against built HTML (LOCAL) or static checklist.Scope boundary :
If a finding appears in an out-of-scope area (e.g. missing meta
description), the agent drops it silently — /validate stays focused.
/onboard runs an initial a11y audit at project setup (axe or
static checklist → .onboard-audit/a11y.md). /validate is the
on-demand equivalent, re-runnable anytime against the current
codebase, and also covers HTML/CSS validity (which /onboard does
not)./harden audits security posture (headers, TLS, redirects).
/validate audits conformance. They share no findings./seo and /geo audit indexability. They may flag the same HTML
features (alt attrs, heading structure) but from a ranking
perspective. /validate flags from a standards perspective
(WCAG SC number, W3C rule id). Findings may overlap — both reports
are still valid.$ARGUMENTS contains https?://<url> → TARGET_URL.DOMAIN from TARGET_URL : DOMAIN=${TARGET_URL#http*://}; DOMAIN=${DOMAIN%%/*}.$ARGUMENTS contains --fix → MODE=fix. Else MODE=audit.--local → DEPTH=LOCAL. If --full → DEPTH=FULL.DEPTH=FULL.DEPTH=LOCAL.--no-external → EXTERNAL=off. Else on.EXTERNAL auto-off in LOCAL mode (no URL to scan remotely).HTML_COUNT=$(find . -name "*.html" \
-not -path "*/node_modules/*" \
-not -path "*/dist/*" \
-not -path "*/.next/*" \
-not -path "*/.validate-cache/*" 2>/dev/null | wc -l)
CSS_COUNT=$(find . -name "*.css" \
-not -path "*/node_modules/*" \
-not -path "*/dist/*" \
-not -path "*/.next/*" 2>/dev/null | wc -l)
If both counts are 0 and no URL provided → abort with :
⚠️ No HTML or CSS files found and no URL provided. /validate needs
either local files or a live URL. Re-run with --full <url>.
FRAMEWORK="static"
[ -f astro.config.mjs ] || [ -f astro.config.ts ] && FRAMEWORK="astro"
[ -f next.config.js ] || [ -f next.config.mjs ] || [ -f next.config.ts ] && FRAMEWORK="next"
[ -f vite.config.js ] || [ -f vite.config.ts ] && FRAMEWORK="vite"
[ -f svelte.config.js ] && FRAMEWORK="svelte"
[ -f nuxt.config.js ] || [ -f nuxt.config.ts ] && FRAMEWORK="nuxt"
[ -f vue.config.js ] && FRAMEWORK="vue"
For JS frameworks, HTML validity must target built output. Check for build dir :
BUILD_DIR=""
for d in dist _site build out public; do
[ -d "$d" ] && BUILD_DIR="$d" && break
done
If framework is JS-based and BUILD_DIR is empty, warn :
⚠️ Framework detected : <name>. No build output found.
HTML validity on JSX/TSX source is not meaningful.
Options :
1. Run `npm run build` then re-run /validate
2. Use --full <url> to audit production
3. Continue with partial LOCAL audit (CSS + static WCAG only)
HAS_HTML_VALIDATE=$(npx --no-install html-validate --version >/dev/null 2>&1 && echo yes || echo no)
HAS_STYLELINT=$(npx --no-install stylelint --version >/dev/null 2>&1 && echo yes || echo no)
HAS_AXE=$(npx --no-install @axe-core/cli --version >/dev/null 2>&1 && echo yes || echo no)
HAS_PA11Y=$(npx --no-install pa11y --version >/dev/null 2>&1 && echo yes || echo no)
HAS_VNU=$([ -f /usr/share/vnu/vnu.jar ] || [ -f /opt/vnu/vnu.jar ] && echo yes || echo no)
Missing tools are NOT blockers — agent falls back to remote APIs (FULL) or static checks.
VALIDATE — context
URL : <url or — (local mode)>
Domain : <domain or —>
Depth : LOCAL | FULL
Mode : audit | fix
External : on | off (auto-off in LOCAL)
HTML files : <N>
CSS files : <N>
Framework : <astro | next | vite | svelte | nuxt | vue | static>
Build dir : <dist/ | _site/ | ... | — none found>
Local tools : html-validate=<y/n>, stylelint=<y/n>, axe=<y/n>, pa11y=<y/n>, vnu=<y/n>
If MODE=fix, warn :
⚠️ Fixes proposés comme diffs. Appliqués seulement après confirmation.
Spawn a single validator-analyzer subagent with explicit scope and
collected context :
Agent(
subagent_type="validator-analyzer",
description="validate — W3C HTML + CSS + WCAG audit",
prompt="""
Dispatched from /validate. STRICT SCOPE — W3C HTML validity + W3C
CSS validity + WCAG 2.1 accessibility ONLY.
CONTEXT:
TARGET_URL : <url or "none — LOCAL mode">
DOMAIN : <domain or —>
DEPTH : <LOCAL | FULL>
MODE : <audit | fix>
EXTERNAL : <on | off>
HTML_FILES : <count>
CSS_FILES : <count>
FRAMEWORK : <name>
BUILD_DIR : <path or "none">
LOCAL_TOOLS : html-validate=<y/n>, stylelint=<y/n>, axe=<y/n>, pa11y=<y/n>, vnu=<y/n>
Execute your spec at $HOME/.claude/agents/validator-analyzer.md
starting at STEP 1 (skip STEP 0 — context is above).
OUT OF SCOPE — DROP silently if encountered :
- meta tags (title/description/OG/Twitter/canonical)
- JSON-LD / Schema.org / microdata
- sitemap.xml, robots.txt, llms.txt
- AI crawler directives
- security headers (HSTS/CSP/X-Frame-Options/cookie flags)
- Core Web Vitals, perf budgets
- hreflang, i18n routing
- image compression, video formats
- generic code linting (ESLint, Prettier, TS errors)
Mode behavior :
- MODE=audit : NO file modifications. Report-only. Propose fixes
as diffs in the report (```diff blocks), do NOT apply.
- MODE=fix : Report issues, then produce Fix bundle (§5) with
concrete diffs for auto-fixable items. STOP and emit
"READY TO APPLY — awaiting dispatcher confirmation" at the end
of §5. Do NOT apply any Edit/Write — the dispatcher handles STEP 3.
Output: write <PROJECT_ROOT>/VALIDATE.md per the structure in your
spec (sections 0-8, score XX/100).
"""
)
test -s VALIDATE.md && wc -l VALIDATE.md || echo "MISSING VALIDATE.md"
If missing or empty :
⚠️ validator-analyzer did not produce VALIDATE.md. Options :
A) Retry with same scope
B) Downgrade to LOCAL and retry (if FULL failed on network)
C) Abort
Extract the score and critical-alert count from VALIDATE.md for the console summary :
grep -oE '\*\*Score\*\*\s+:\s+[0-9]+ / 100' VALIDATE.md | head -1
grep -c '^### \[Critique\]' VALIDATE.md
Skip this step if MODE=audit.
If VALIDATE.md ends with READY TO APPLY — awaiting dispatcher confirmation :
## 5. Fix bundle section.Ask :
VALIDATE — fix bundle ready
Files to modify (N) :
- src/Layout.astro (3 fixes : lang attr, alt="", heading renumber)
- src/styles/main.css (1 fix : invalid property removed)
- src/pages/contact.html (2 fixes : unclosed tag, duplicate id)
Critical : X | Haute : Y | Moyenne : Z | Basse : W
Options :
A) Apply all
B) Review each diff before applying
C) Apply only Critique + Haute
D) Abort — keep VALIDATE.md as audit report
On A : apply each bundle via Edit (targeted old_string /
new_string). Never use Write on shared templates (risk of
overwriting /seo or /geo content — meta tags, JSON-LD).
On B : for each diff, show and ask yes/no/skip.
On C : filter to Critique + Haute, then behave as A.
On D : stop, leave VALIDATE.md untouched.
After applying, append a ## 8. Changes applied section with
commit-ready summary lines :
## 8. Changes applied
Date : <ISO-8601>
Files modified : <N>
Fixes applied : <N>
### src/Layout.astro
- [Haute][HTML] Added `lang="en"` to `<html>` (WCAG 3.1.1, W3C required attr)
- [Haute][WCAG AA] Added `alt=""` to decorative icon at line 42
- [Moyenne][HTML] Renumbered h3 → h2 (heading hierarchy, line 67)
### src/styles/main.css
- [Moyenne][CSS] Removed invalid property `bakground` → `background` at line 23
Verification :
- Re-run /validate → expected score bump <before> → <after>
- Tests to run : a11y regression (pa11y-ci), visual snapshot
Never apply fixes without explicit confirmation.
Never use --no-verify on git hooks.
VALIDATE AUDIT COMPLETE
URL : <url or static>
Depth : LOCAL | FULL
Mode : audit | fix
Score : XX / 100 (<before> → <after> if fix applied)
Report : VALIDATE.md
BREAKDOWN :
W3C HTML : <N errors / M warnings>
W3C CSS : <N errors / M warnings>
WCAG 2.1 : <N A> / <M AA> / <K AAA> violations, <L incomplete>
TOP 3 ACTIONS (by severity × user impact) :
1. [Critique] <title> — <file:line>
2. [Haute] <title>
3. [Haute] <title>
NEXT STEPS :
• /validate <url> --fix → apply recommended fixes
• /validate <url> --full → re-run with live URL + remote APIs
• /validate --no-external → skip third-party APIs (faster, LOCAL-like)
• /harden / /seo / /geo → complementary audits (other scopes)
Install for better LOCAL coverage :
npm i -D html-validate stylelint @axe-core/cli pa11y
/harden,
/seo, /geo own those respectively.validator-analyzer. No parallel
fan-out.--fix.
The fix mode prepares the bundle; the dispatcher confirms (A/B/C/D).dist/, _site/, build/, out/), not JSX/TSX source.
Warn if no build dir present.VALIDATE.md at project root (or
docs/VALIDATE.md if that convention exists). On re-run, move
previous content to a ## Historique section, do not overwrite
silently..validate-cache/ (gitignored) stores raw tool
outputs for debugging. Do not commit.