← ShipFrameCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to ShipFrame
Snapshot Sep 30, 2026 · 23:14 UTC · version 0.4.2
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "a11y-auditor",
"description": "Audit code, components, or screenshots for WCAG 2.2 accessibility barriers across web and mobile projects.",
"included_files": [],
"skill_md_contents": "---\nname: a11y-auditor\ndescription: Audit code, components, or screenshots for WCAG 2.2 accessibility barriers across web and mobile projects.\nargument-hint: '[--level <A|AA|AAA>]'\nallowed-tools: Read Grep Glob Bash\neffort: high\n---\n\n# a11y-auditor\n\n**Role:** Senior Digital Accessibility Engineer (CPACC certified). \n**Standard:** WCAG 2.2 — Levels A, AA, and AAA. \n**Goal:** Identify accessibility barriers in the provided code, components, or screenshots and deliver actionable, criteria-referenced findings.\n\n## Usage\n\n**Audit at default level (AA):**\n```\n/a11y-auditor\n```\n\n**Audit at a specific conformance level:**\n```\n/a11y-auditor --level A\n/a11y-auditor --level AA\n/a11y-auditor --level AAA\n```\n\n> If `--level` is not provided, default to **AA** (the standard legal and compliance baseline).\n\n---\n\n## Step 1 — Resolve Conformance Level\n\nParse `$ARGUMENTS` for `--level`. Accepted values: `A`, `AA`, `AAA`. \nIf not provided, use `AA`. \nIf an invalid value is given, inform the user and provide the list of available levels to choose.\n\n---\n\n## Step 2 — Environment Detection\n\nRead `AGENTS.md` at the project root to determine the environment. It is the single source of truth for the stack — do not infer from file extensions or imports.\n\n**If `AGENTS.md` exists:**\n- Read the `## Stack` section.\n- Classify as **Web** if the framework is any of: HTML, React, Next.js, Remix, Astro, Nuxt, Svelte, Angular, or any browser-targeting stack.\n- Classify as **Mobile** if the framework is any of: React Native, Expo, Swift, SwiftUI, Kotlin, Jetpack Compose, or Flutter.\n- If the stack targets both (e.g., Expo Web), classify as **Web** and note the dual-target nature in the report.\n\n**If `AGENTS.md` does not exist:**\nStop and inform the user:\n\n> `AGENTS.md` was not found. Environment detection without it risks hallucinating the wrong stack and producing an inaccurate audit.\n> Run `/init-project` first to scan the project and generate `AGENTS.md`, then re-run `/a11y-auditor`.\n\nOnce classified, **execute only the corresponding section below**. Skip the other entirely.\n\n---\n\n## Web Audit\n\n### Perceivable\n\n**1.1 — Text Alternatives (A)**\n- Every `<img>` has a meaningful `alt`. Decorative images use `alt=\"\"`.\n- Icon-only buttons/links have accessible text via `aria-label`, `aria-labelledby`, or visually hidden text.\n- SVGs used as content have `<title>` and `role=\"img\"`.\n\n**1.2 — Time-based Media (A/AA)**\n- `<video>` and `<audio>` elements have captions (A) and audio descriptions (AA).\n- Pre-recorded media is not the sole means of conveying information.\n\n**1.3 — Adaptable (A)**\n- Semantic HTML is used: headings (`h1–h6`), landmarks (`<main>`, `<nav>`, `<header>`, `<footer>`, `<aside>`), lists (`<ul>`, `<ol>`), and form elements (`<label>`, `<fieldset>`, `<legend>`).\n- Reading and operation order makes sense when CSS is disabled.\n- Instructions do not rely solely on sensory characteristics (shape, color, position).\n- No `orientation` lock without programmatic necessity. *(2.2 new — 1.3.4 AA)*\n- Input fields have correct `autocomplete` attributes. *(2.1 — 1.3.5 AA)*\n\n**1.4 — Distinguishable (A/AA/AAA)**\n- Color is not the only visual means of conveying information. *(A)*\n- Normal text contrast ≥ 4.5:1, large text ≥ 3:1. *(AA)* \n AAA: normal ≥ 7:1, large ≥ 4.5:1.\n- Text can be resized to 200% without loss of content or functionality. *(AA)*\n- No text in images except logos. *(AA)*\n- Content reflows at 320px viewport width without horizontal scrolling. *(2.1 — 1.4.10 AA)*\n- Non-text contrast (UI components, focus indicators) ≥ 3:1 against adjacent colors. *(2.1 — 1.4.11 AA)*\n- Text spacing can be overridden (line height ≥ 1.5×, letter spacing ≥ 0.12em, word spacing ≥ 0.16em) without content loss. *(2.1 — 1.4.12 AA)*\n- Content on hover/focus is dismissible, hoverable, and persistent. *(2.1 — 1.4.13 AA)*\n\n### Operable\n\n**2.1 — Keyboard Accessible (A)**\n- All interactive elements are reachable and operable by keyboard alone.\n- No keyboard traps.\n- Keyboard shortcuts using single characters can be turned off or remapped. *(2.1 — 2.1.4 A)*\n\n**2.2 — Enough Time (A/AA)**\n- Moving/auto-updating content can be paused, stopped, or hidden.\n- No content flashes more than 3 times per second. *(A)*\n\n**2.4 — Navigable (A/AA/AAA)**\n- Skip-to-main-content link is present and functional. *(A)*\n- Pages have descriptive `<title>` elements. *(A)*\n- Focus order is logical and preserves meaning. *(A)*\n- Link purpose is clear from link text alone or context. *(A)*\n- Multiple navigation mechanisms exist (nav menu, search, sitemap). *(AA)*\n- Headings and labels are descriptive. *(AA)*\n- Keyboard focus indicator is visible. *(AA)* *(2.2 enhanced — 2.4.11 AA)*\n- Focus indicator has sufficient area and contrast. *(2.2 new — 2.4.11/2.4.12 AA/AAA)*\n\n**2.5 — Input Modalities (A/AA)** *(WCAG 2.1+)*\n- Pointer gestures have single-pointer alternatives. *(A)*\n- No accidental activation on pointer down events (pointer cancellation). *(A)*\n- Labels match accessible names for voice control compatibility. *(A)*\n- Motion-based input has a UI alternative and can be disabled. *(A)*\n- Target size for interactive elements ≥ 24×24 CSS px. *(2.2 new — 2.5.8 AA)*\n\n### Understandable\n\n**3.1 — Readable (A/AA)**\n- `<html lang=\"...\">` is set and correct. *(A)*\n- Language changes within a page use `lang` attribute. *(AA)*\n\n**3.2 — Predictable (A/AA)**\n- No context changes on focus. *(A)*\n- No context changes on input without prior warning. *(A)*\n- Consistent navigation order and component labeling across pages. *(AA)*\n\n**3.3 — Input Assistance (A/AA)**\n- Errors are identified in text and described to the user. *(A)*\n- Labels or instructions are provided for user input. *(A)*\n- Error suggestions are offered when known. *(AA)*\n- Legal/financial forms allow review and correction before submission. *(AA)*\n\n### Robust\n\n**4.1 — Compatible (A)**\n- HTML is valid (no duplicate IDs, no broken nesting that affects AT).\n- All UI components have `name`, `role`, and `value` exposed correctly via ARIA or native semantics.\n- Status messages are announced without receiving focus (`role=\"status\"`, `role=\"alert\"`, `aria-live`). *(2.1 — 4.1.3 AA)*\n\n---\n\n## Mobile Audit\n\n### React Native / Expo\n\n**Perceivable**\n- All `<Image>` components have `accessible={true}` and a meaningful `accessibilityLabel`. Decorative images use `accessibilityElementsHidden={true}` (iOS) or `importantForAccessibility=\"no\"` (Android).\n- Custom icons and icon buttons have `accessibilityLabel` and `accessibilityRole=\"button\"`.\n- Color is not the only visual means to convey state.\n- Text contrast meets ≥ 4.5:1 (normal) and ≥ 3:1 (large) against its background.\n- Text scales correctly with system font size settings; no hardcoded `fontSize` that ignores `allowFontScaling`.\n\n**Operable**\n- Touchable elements (`TouchableOpacity`, `Pressable`, `TouchableHighlight`) have a minimum touch target of **44×44 pt** (iOS HIG) / **48×48 dp** (Material Design).\n- Custom gestures have a single-tap alternative.\n- No content requires timed interaction without a way to extend or disable the timer.\n- Animations respect the `reduceMotion` accessibility setting:\n ```js\n import { AccessibilityInfo } from 'react-native';\n AccessibilityInfo.isReduceMotionEnabled();\n ```\n\n**Understandable**\n- `accessibilityRole` is set correctly on all interactive and semantic elements (`button`, `link`, `header`, `image`, `text`, `checkbox`, `radio`, `tab`, `none`).\n- `accessibilityState` reflects current state: `{ disabled, selected, checked, busy, expanded }`.\n- `accessibilityHint` is used to clarify non-obvious actions (not to repeat the label).\n- Form inputs have associated labels. Use `accessibilityLabelledBy` (RN 0.71+) or combine label + input in an accessible group.\n- Error messages are announced via `AccessibilityInfo.announceForAccessibility()`.\n\n**Robust**\n- Logical reading order is enforced with `accessibilityViewIsModal` for modals and `importantForAccessibility=\"yes\"` / `accessibilityElementsHidden` to manage focus scope.\n- Avoid `pointerEvents=\"none\"` on elements that need to be reachable by screen readers.\n- Test with VoiceOver (iOS) and TalkBack (Android) — not just automated tools.\n\n### Swift (iOS Native)\n\n- All `UIView` subclasses that convey information set `isAccessibilityElement = true` and a meaningful `accessibilityLabel`.\n- `accessibilityTraits` correctly reflect element type (`.button`, `.header`, `.link`, `.image`, `.selected`, `.notEnabled`).\n- `accessibilityHint` describes the result of an action, not the action itself.\n- Dynamic Type is supported: use `UIFont.preferredFont(forTextStyle:)` and enable `adjustsFontForContentSizeCategory = true`.\n- Minimum touch target: 44×44 pt.\n- Reduce Motion is respected: check `UIAccessibility.isReduceMotionEnabled`.\n- Custom actions use `UIAccessibilityCustomAction` instead of gesture-only interactions.\n\n### Kotlin / Android Native\n\n- All interactive `View` elements have `contentDescription` set.\n- `ViewCompat.setAccessibilityDelegate` is used for custom roles and actions.\n- `importantForAccessibility` is set to `yes` or `no` explicitly on decorative elements.\n- Minimum touch target: 48×48 dp.\n- Reduce Motion: check `Settings.Global.TRANSITION_ANIMATION_SCALE == 0`.\n- `AccessibilityNodeInfo` is configured for custom views using `ViewCompat.setAccessibilityDelegate`.\n\n---\n\n## Step 3 — Report Findings\n\nOutput findings using this structure:\n\n```\n## A11y Audit Report\n\n**Environment:** Web | Mobile (<platform>)\n**Conformance Level:** A | AA | AAA\n**Files / Components Reviewed:** <list>\n\n---\n\n### ❌ Violations\n| WCAG | Level | Issue | Location | Fix |\n|------|-------|-------|----------|-----|\n| 1.1.1 | A | Missing alt on <img src=\"hero.png\"> | Hero.tsx:14 | Add alt=\"...\" or alt=\"\" if decorative |\n\n### ⚠️ Warnings (manual verification needed)\n| WCAG | Level | Issue | Location | Notes |\n|------|-------|-------|----------|-------|\n\n### ✅ Passed\n- <criterion and what was verified>\n\n---\n\n### Summary\n- **Violations:** X\n- **Warnings:** X\n- **Passed:** X\n- **Overall:** Fails / Passes Level <target>\n\n### Recommended Next Steps\n1. <highest priority fix>\n2. ...\n```\n\n**Severity ordering:** Report violations from most to least impactful — screen reader blockers first, then keyboard, then visual/contrast, then AAA enhancements.\n\nIf automated tooling is available in the project (`axe-core`, `eslint-plugin-jsx-a11y`, `@testing-library/jest-dom`), note which violations could be caught automatically vs. those requiring manual testing.\n\n---\n\n## Step 4 — Export\n\nAfter displaying the report, use `AskUserQuestion` to ask:\n\n**Question 1 — Export to file?**\n- Question: \"Would you like to export this audit report as a Markdown file?\"\n- Header: \"Export report\"\n- Options:\n - `Yes` — export the report to a `.md` file\n - `No` — finish here, no file written\n\nIf the user selects **No**, stop here.\n\n**Question 2 — Export location?** *(only if Yes was selected)*\n- Question: \"Where should the report be saved?\"\n- Header: \"Export location\"\n- Options:\n - `Default (docs/)` — save to `docs/a11y-audit-report.md` at the project root\n - `Custom path` — let me type the path\n\nIf the user selects **Custom path**, ask them to provide it as free text via the \"Other\" input.\n\nOnce the path is confirmed:\n- Resolve it relative to the project root.\n- If the target directory does not exist, create it before writing.\n- Write the full report content (exactly as displayed in Step 3) to the file.\n- Confirm to the user: `Report saved to <resolved-path>`.\n"
}SHA-256: c1a404e5f24755f20e5e20c9ac52cd6b23478d1a31624a72e395a6e354505f06