cellajs/cella/a11y-review

Claude Code and agent skill by cellajs/cella

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Run the WCAG audit, fix what it finds, check each fix in the running app, and review the criteria the audit leaves open, recording every decision with its evidence in the conformance ledger.

Install

npx vskill@latest install cellajs/cella/a11y-review

SKILL.md

The accessibility audit loop

pnpm a11y:run decides what tools can prove and writes the ledger, json/accessibility-conformance.json. The rest it leaves open, with a packet per page for a reviewer. This skill is the procedure around it: run, fix, check the fix, rerun, review, record. The a11y README owns the audit: its commands, partial runs, failed visits, what an app lists in scope-config.ts, and why an agent's decision stays provisional until a person confirms it. Agents also report failures that are not there, so the rules below lean toward leaving a row open.

Run

Run pnpm a11y:run --keep for the fix loop, so the stack stays up between partial runs.

  • A run with skipped visits writes no ledger. Fix the cause (a state's opener that no longer finds its button, a redirect) and run again. Read the visit's failure-<mode>.png and .json first: a step often fails on what an earlier one left behind, such as a page that fell into its error boundary.
  • A probe that fails once and passes on a rerun was a timing miss; rerun before recording it.

Patterns for app UI

The template's accessibility fixes arrive through synced files only. An app's own components need the same patterns, and the audit reports what is missing once the scope lists their pages:

  • Names (1.1.1, 4.1.2): an icon-only button, toggle or link has a translated aria-label; a custom control states its role and state.
  • Focus (2.4.7): a custom focus target carries focus-effect. Never remove the ring (focus-visible:outline-hidden, ring-0) without another visible indicator.
  • Dragging (2.5.7): every drag (reorder, resize, move) has a button or key that does the same. A reorder moves through ReorderHandle, which has both.
  • Character keys (2.1.4): every hotkey needs Ctrl, Alt or Meta (Mod), as in app-nav.tsx. There is no switch to turn shortcuts off, so a character alone or with Shift is never registered.
  • Motion (2.2.2): animation follows the reduced-motion preference: motion-reduce: on CSS transitions and animations, <MotionConfig reducedMotion="user"> or useReducedMotion() for motion components.
  • Dimmed text (1.4.3): dim text with a text step (text-muted-foreground, text-faint-foreground), never with opacity: opacity-* or /70 lowers its contrast below what the token was measured at.

The fix loop

  1. Read the failures in a11y/results/manual-pass.md and a11y/results/axe.json (every failing element per rule and state).
  2. Fix the cause in the component, not the instance: a token, a primitive in frontend/src/modules/ui, a shared form field.
  3. Check the fix in the running app before trusting it. Drive the kept stack with a short Playwright script: startSession (a11y/src/session.ts) signs in, openState(session, '<id>') (a11y/src/drive.ts) opens a state of the scope, also as a phone, a zoomed desktop or with motion allowed. Run it with the kept stack's DEV_PORT_OFFSET and NODE_ENV=development. Check the state the fix is about and one neighbor that shares the component.
  4. Changes that alter data (a reorder, a mute) are put back before the next run: the audit opens the first organization the audit user administers, and a changed order changes which one that is.
  5. Rerun the full audit. Rows the audit decides move by themselves.
  6. A row a reviewer decided keeps its decision and its remark, which now describes the old code: decide it again once step 3 showed the fix holds.

Do not script what the tools already measure: contrast the audit takes from the pixels and token contrast in pnpm style (How a row is decided).

Reviewing the open criteria

Use this part after a full audit, when pnpm -C a11y report lists open criteria.

Preconditions

  • A fresh pnpm a11y:run with no skipped visits.
  • Packets in a11y/results/review/<state>/: screenshot.png, tree.yml (the accessibility tree a screen reader works from), facts.json (headings, landmarks, images, fields, label against name, other languages) and tab-order.json.
  • The open rows and the tools' notes: a11y/results/manual-pass.md.

Rules

  1. Evidence first. Every finding names the state and the element: "org-members: the grid's sort buttons are named only 'button'". A decision without it is refused.
  2. Cover the scope. Supports means every state the criterion applies to was looked at. Say how many in the evidence.
  3. Verify a failure in the live page before recording it: open the state, find the element, confirm in the DOM or the tree. A screenshot alone misleads (text in an image, an element below the fold).
  4. When unsure, record `open` with what was seen. A wrong Supports reaches a published report; an open row costs a person a minute.
  5. Stay inside the criterion. Read its text in WCAG 2.2 Understanding first; note other problems for the row they belong to.
  6. Do not decide what needs assistive technology. 4.1.2 and 4.1.3 get findings from the tree, never Supports: only a screen reader shows what is announced.
  7. Ignore development-only UI: the debug menu, devtools and the "Testing credentials" banner.
  8. A row that failed before becomes Supports only after its fix was driven in the running app. Reading the diff is not evidence; say in the evidence what you did and what happened.

What to check

From the packets alone:

CriterionLook atPasses whenCommon false alarm
1.1.1 Non-text Contentfacts.images, icon buttons in tree.yml, the screenshotEach informative image and icon control has a name that serves the same purpose; decoration is hiddenAn avatar next to the person's name is decoration
1.3.1 Info and RelationshipsScreenshot against tree.ymlWhat looks like a heading, list, table, group or label is one in the treeA visual card grid needs no list role
1.3.2 Meaningful SequenceOrder in tree.yml against reading order in the screenshotThe tree reads in an order that makes senseSidebars before main content
1.3.3 Sensory CharacteristicsInstructions in the textNone relies on shape, color, size, position or sound alone"Above" and "below" with a named target
1.4.1 Use of ColorLinks in text, states, errors, badges, chartsEach also differs by text, icon, underline or shapeDecorative color
1.4.5 Images of TextScreenshot, facts.imagesText is text; logos are exemptScreenshots shown as content
2.4.1 Bypass Blocksfacts.landmarksA main landmark or skip link on each page; an open overlay holds focus, so it needs none
2.4.3 Focus Ordertab-order.json positions against the screenshotFocus follows the visual and logical orderA grid moves by arrow keys; sticky headers come first
2.4.4 Link PurposeLinks in tree.ymlEach name, with its sentence or cell, tells where it goesRepeated "Edit" inside a named row
2.4.5 Multiple WaysNavigation, search and links across statesEach page is reachable in two ways; steps in a process are exempt
2.4.6 Headings and Labelsfacts.headings, facts.fieldsEach describes its topic or purpose
2.5.3 Label in Namefacts.labelNotInNameEvery entry's name contains its visible textA count badge beside the label
3.1.2 Language of Partsfacts.otherLanguages, text in another languageSuch passages carry lang; names and technical terms are exempt
3.2.3, 3.2.4, 3.2.6Navigation, repeated controls and help across statesSame order, same names, help in the same place
3.3.2 Labels or Instructionsfacts.fieldsEach field has a visible label; required and format are statedA search field with a labelled button

From the source, with the tools' notes as the starting point: 1.2.1 to 1.2.5 and 1.4.2 (does the app publish media, or only play what users upload?), 2.2.1 (time limits: the session lifetime, sign-in challenges, toasts that close by themselves), 2.2.2 (motion that starts by itself), 2.5.1 and 2.5.7 (is there a button for every gesture and drag?), 2.5.2 (do actions fire on release?).

By driving the browser (the verify skill explains how to launch, sign in and drive): 3.2.2 (change each kind of field, nothing navigates), 3.3.3 (do error messages say how to fix the input?), 3.3.4 (can destructive actions be confirmed or undone?), 3.3.7 (multi-step flows), 2.1.1 (each function by keyboard: menus, dialogs, the grid, the editor, uploads), 1.4.11 (the audit measures the edge of form controls; measure icons that carry meaning and focus indicators at 3:1), 1.4.13 (hover a tooltip or card, press Escape: it closes, and the sheet or dialog around it stays), 2.5.8 (targets axe could not decide).

Record

Write the decisions to a JSON file and record them in one go. A decision that the evidence cannot carry is refused, and then nothing is written.

json
[
{ "id": "2.4.6", "status": "supports", "by": "agent", "evidence": "Read facts.headings and facts.fields of all 26 states: each heading names its section, each field its content." },
{ "id": "1.1.1", "status": "partially-supports", "by": "agent", "remarks": "Icons in the attachment grid have no text alternative.", "evidence": "org-attachments: 3 file-type icons are img with no name (tree.yml); the other 25 states pass.", "where": ["org-attachments"] },
{ "id": "4.1.2", "status": "open", "by": "agent", "evidence": "tree.yml of all states: custom controls expose role, name and state. Needs a screen reader." }
]
pnpm -C a11y decide --file decisions.json
pnpm -C a11y report

remarks go into the published report: plain words for someone who uses the product, what does not work and how to get around it. evidence is for whoever checks the decision.

With sub-agents

Split by the three groups above, not by state: each sub-agent reads the packets once for its criteria. Sub-agents return decisions as JSON and record nothing. The orchestrator verifies every failure in the live page, drops what it cannot reproduce, and records the rest in one decide call.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Refreshed 25 Oct 2026, 6 days ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/cellajs/cella/a11y-review/badge)](https://verified-skill.com/skills/cellajs/cella/a11y-review)

Something wrong with this skill or its page? Tell us.