AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Accessibility

skill-manastalukdar-ai-devstudio-accessibility · by manastalukdar

Accessibility (a11y) compliance checking with WCAG 2.1 validation

No reviews yet
0 installs
24 views
0.0% view→install

Install

$ agentstack add skill-manastalukdar-ai-devstudio-accessibility

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-manastalukdar-ai-devstudio-accessibility)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Accessibility? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Accessibility (a11y) Compliance Checking

I'll analyze your web application for accessibility issues, validate WCAG 2.1 compliance, check ARIA attributes, verify keyboard navigation, validate color contrast, and generate comprehensive accessibility reports.

Compliance Standards:

  • WCAG 2.1 Level A (minimum compliance)
  • WCAG 2.1 Level AA (target standard)
  • WCAG 2.1 Level AAA (enhanced accessibility)
  • Section 508 (US federal requirements)
  • EN 301 549 (EU accessibility requirements)

Frameworks Supported:

  • React (React Testing Library, jest-axe)
  • Vue.js (Vue Test Utils, vue-axe)
  • Angular (Angular testing utilities)
  • HTML/CSS (static analysis)
  • Next.js, Gatsby, Nuxt.js

Arguments: $ARGUMENTS - optional:

  • URL to audit (defaults to http://localhost:3000)
  • WCAG level (A, AA, AAA - defaults to AA)
  • Focus area: --images, --forms, --keyboard, --contrast, --aria (for targeted analysis)

Accessibility ensures:

  • Usability for people with disabilities
  • Keyboard-only navigation support
  • Screen reader compatibility
  • Visual accessibility (contrast, font size)
  • Cognitive accessibility (clear language, structure)

Common a11y issues:

  • Missing alt text on images
  • Insufficient color contrast
  • Missing ARIA labels
  • Non-semantic HTML
  • Keyboard navigation barriers
  • Missing form labels
  • Poor heading hierarchy

Phase 1: Framework & Tool Detection

First, I'll detect your framework and set up accessibility testing tools:

#!/bin/bash
# Accessibility Analysis - Framework Detection & Tool Setup

echo "=== Accessibility (a11y) Compliance Checking ==="
echo ""

# Create accessibility directory
mkdir -p .claude/accessibility
A11Y_DIR=".claude/accessibility"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
REPORT="$A11Y_DIR/a11y-report-$TIMESTAMP.md"
WCAG_LEVEL="${1:-AA}"  # Default to WCAG 2.1 Level AA
TARGET_URL="${2:-http://localhost:3000}"

echo "Configuration:"
echo "  WCAG Level: $WCAG_LEVEL"
echo "  Target URL: $TARGET_URL"
echo "  Analysis directory: $A11Y_DIR"
echo ""

detect_framework() {
    echo "Detecting framework..."
    echo ""

    local framework=""

    if [ ! -f "package.json" ]; then
        echo "⚠️  No package.json found"
        echo "   This skill works best with JavaScript/TypeScript projects"
        echo "   Will perform generic HTML analysis"
        framework="generic"
    else
        # React detection
        if grep -q '"react"' package.json; then
            framework="react"
            echo "✓ React detected"

            # Check for React Testing Library
            if grep -q '@testing-library/react' package.json; then
                echo "  - React Testing Library available"
            fi

            # Check for jest-axe
            if grep -q 'jest-axe' package.json; then
                echo "  - jest-axe available"
            fi

        # Vue detection
        elif grep -q '"vue"' package.json; then
            framework="vue"
            echo "✓ Vue.js detected"

        # Angular detection
        elif grep -q '"@angular' package.json; then
            framework="angular"
            echo "✓ Angular detected"

        # Next.js detection
        elif grep -q '"next"' package.json; then
            framework="next"
            echo "✓ Next.js detected"

        else
            framework="generic"
            echo "✓ Generic web project detected"
        fi
    fi

    echo "$framework"
}

FRAMEWORK=$(detect_framework)
echo ""

Phase 2: Install Accessibility Tools

I'll install axe-core and related accessibility testing tools:

echo "=== Installing Accessibility Testing Tools ==="
echo ""

install_axe_tools() {
    echo "Setting up axe-core (accessibility engine)..."

    # Check for axe-core CLI
    if ! command -v axe >/dev/null 2>&1 && ! npm list -g @axe-core/cli >/dev/null 2>&1; then
        echo "Installing @axe-core/cli..."
        npm install -g @axe-core/cli 2>/dev/null || npm install --save-dev @axe-core/cli

        if [ $? -eq 0 ]; then
            echo "✓ axe-core CLI installed"
        else
            echo "⚠️  Failed to install axe-core CLI"
            return 1
        fi
    else
        echo "✓ axe-core CLI already installed"
    fi

    # Framework-specific setup
    case "$FRAMEWORK" in
        react)
            if ! grep -q 'jest-axe' package.json 2>/dev/null; then
                echo ""
                echo "Installing React accessibility tools..."
                npm install --save-dev jest-axe @testing-library/react @testing-library/jest-dom 2>/dev/null
                echo "✓ jest-axe and React Testing Library installed"
            fi
            ;;

        vue)
            if ! grep -q 'vue-axe' package.json 2>/dev/null; then
                echo ""
                echo "Installing Vue accessibility tools..."
                npm install --save-dev vue-axe 2>/dev/null
                echo "✓ vue-axe installed"
            fi
            ;;
    esac

    # Install pa11y for additional testing
    if ! command -v pa11y >/dev/null 2>&1 && ! npm list -g pa11y >/dev/null 2>&1; then
        echo ""
        echo "Installing pa11y (accessibility testing tool)..."
        npm install -g pa11y 2>/dev/null || echo "⚠️  pa11y installation skipped"
    else
        echo "✓ pa11y available"
    fi

    return 0
}

install_axe_tools
echo ""

Phase 3: Run Accessibility Audits

I'll run comprehensive accessibility tests:

echo "=== Running Accessibility Audits ==="
echo ""

# Check if server is accessible
check_server() {
    echo "Checking if server is accessible at $TARGET_URL..."

    if curl -s --head "$TARGET_URL" >/dev/null 2>&1; then
        echo "✓ Server is accessible"
        return 0
    else
        echo "⚠️  Server not accessible at $TARGET_URL"
        echo ""
        echo "Please start your development server:"
        echo "  npm start"
        echo "  npm run dev"
        echo ""
        echo "Or specify a different URL:"
        echo "  /accessibility $WCAG_LEVEL https://your-site.com"
        return 1
    fi
}

run_axe_analysis() {
    echo "Running axe-core analysis (WCAG $WCAG_LEVEL)..."
    echo ""

    # Map WCAG level to axe tags
    local axe_tags=""
    case "$WCAG_LEVEL" in
        A|a)
            axe_tags="wcag2a,wcag21a"
            ;;
        AA|aa)
            axe_tags="wcag2a,wcag2aa,wcag21a,wcag21aa"
            ;;
        AAA|aaa)
            axe_tags="wcag2a,wcag2aa,wcag2aaa,wcag21a,wcag21aa,wcag21aaa"
            ;;
        *)
            axe_tags="wcag2a,wcag2aa,wcag21a,wcag21aa"
            ;;
    esac

    # Run axe-core
    if command -v axe >/dev/null 2>&1 || npx axe --help >/dev/null 2>&1; then
        npx axe "$TARGET_URL" \
            --tags "$axe_tags" \
            --save "$A11Y_DIR/axe-results.json" \
            --stdout \
            2>&1 | tee "$A11Y_DIR/axe-output.txt"

        if [ $? -eq 0 ]; then
            echo ""
            echo "✓ axe-core analysis complete"

            # Parse results
            if [ -f "$A11Y_DIR/axe-results.json" ]; then
                # Count violations by impact
                CRITICAL=$(jq '[.violations[] | select(.impact=="critical")] | length' "$A11Y_DIR/axe-results.json" 2>/dev/null || echo "0")
                SERIOUS=$(jq '[.violations[] | select(.impact=="serious")] | length' "$A11Y_DIR/axe-results.json" 2>/dev/null || echo "0")
                MODERATE=$(jq '[.violations[] | select(.impact=="moderate")] | length' "$A11Y_DIR/axe-results.json" 2>/dev/null || echo "0")
                MINOR=$(jq '[.violations[] | select(.impact=="minor")] | length' "$A11Y_DIR/axe-results.json" 2>/dev/null || echo "0")

                echo ""
                echo "Violations by Impact:"
                echo "  Critical: $CRITICAL"
                echo "  Serious: $SERIOUS"
                echo "  Moderate: $MODERATE"
                echo "  Minor: $MINOR"
                echo "  Total: $((CRITICAL + SERIOUS + MODERATE + MINOR))"
            fi
        else
            echo "❌ axe-core analysis failed"
            return 1
        fi
    else
        echo "⚠️  axe-core CLI not available"
        return 1
    fi

    return 0
}

run_pa11y_analysis() {
    if command -v pa11y >/dev/null 2>&1; then
        echo ""
        echo "Running pa11y analysis..."

        # Map WCAG level to pa11y standard
        local pa11y_standard=""
        case "$WCAG_LEVEL" in
            A|a) pa11y_standard="WCAG2A" ;;
            AA|aa) pa11y_standard="WCAG2AA" ;;
            AAA|aaa) pa11y_standard="WCAG2AAA" ;;
            *) pa11y_standard="WCAG2AA" ;;
        esac

        pa11y "$TARGET_URL" \
            --standard "$pa11y_standard" \
            --reporter json \
            > "$A11Y_DIR/pa11y-results.json" 2>&1

        if [ $? -eq 0 ]; then
            echo "✓ pa11y analysis complete"

            # Count issues
            PA11Y_ISSUES=$(jq 'length' "$A11Y_DIR/pa11y-results.json" 2>/dev/null || echo "0")
            echo "  Issues found: $PA11Y_ISSUES"
        else
            echo "⚠️  pa11y analysis had issues (may still have results)"
        fi
    fi
}

# Run audits
if check_server; then
    run_axe_analysis
    run_pa11y_analysis
else
    echo "Skipping live server analysis"
    echo "Will provide general accessibility guidance"
fi

echo ""

Phase 4: Analyze Common Accessibility Issues

I'll check for common accessibility problems in the codebase:

echo "=== Analyzing Common Accessibility Issues ==="
echo ""

analyze_static_html() {
    echo "Checking HTML/JSX/Vue files for common issues..."
    echo ""

    # Find source files
    SOURCE_PATTERNS="-name '*.html' -o -name '*.jsx' -o -name '*.tsx' -o -name '*.vue'"

    # Check for images without alt text
    echo "1. Checking for images without alt attributes..."
    MISSING_ALT=$(find . -type f \( $SOURCE_PATTERNS \) \
        -not -path "*/node_modules/*" \
        -not -path "*/dist/*" \
        -not -path "*/build/*" \
        -exec grep -l ']*>' {} \; 2>/dev/null | \
        xargs grep -h ']*>' 2>/dev/null | \
        grep -v 'alt=' | wc -l)

    if [ "$MISSING_ALT" -gt 0 ]; then
        echo "  ❌ Found $MISSING_ALT images potentially missing alt text"
        echo "     Search: grep -r ']*>\\s*/dev/null | wc -l)

    if [ "$BUTTON_ISSUES" -gt 0 ]; then
        echo "  ⚠️  Found $BUTTON_ISSUES potential buttons with icon-only content"
        echo "     These may need aria-label or sr-only text"
    else
        echo "  ✓ Buttons appear to have text content"
    fi

    # Check for form inputs without labels
    echo ""
    echo "3. Checking for form inputs without labels..."
    UNLABELED_INPUTS=$(find . -type f \( $SOURCE_PATTERNS \) \
        -not -path "*/node_modules/*" \
        -exec grep -h ']*>' {} \; 2>/dev/null | \
        grep -v 'id=' | wc -l)

    if [ "$UNLABELED_INPUTS" -gt 0 ]; then
        echo "  ⚠️  Found $UNLABELED_INPUTS inputs potentially without associated labels"
    else
        echo "  ✓ Inputs appear to have proper labeling"
    fi

    # Check for proper heading hierarchy
    echo ""
    echo "4. Checking heading hierarchy..."
    echo "  Run this command to review headings:"
    echo "  grep -rh '/dev/null | wc -l)

    if [ "$SEMANTIC_COUNT" -gt 0 ]; then
        echo "  ✓ Found semantic HTML elements in $SEMANTIC_COUNT files"
    else
        echo "  ⚠️  Few or no semantic HTML elements found"
        echo "     Consider using , , , , , "
    fi

    # Check for ARIA usage
    echo ""
    echo "6. Checking ARIA attribute usage..."
    ARIA_COUNT=$(find . -type f \( $SOURCE_PATTERNS \) \
        -not -path "*/node_modules/*" \
        -exec grep -l 'aria-' {} \; 2>/dev/null | wc -l)

    echo "  Found ARIA attributes in $ARIA_COUNT files"

    # Check for color contrast issues in CSS
    echo ""
    echo "7. Checking for potential color contrast issues..."
    echo "  Common low-contrast colors (review manually):"
    grep -rh "color.*#[cdefCDEF]" --include="*.css" --include="*.scss" \
        --exclude-dir=node_modules . 2>/dev/null | head -5 | sed 's/^/    /'

    echo ""
}

analyze_static_html > "$A11Y_DIR/static-analysis.txt"
cat "$A11Y_DIR/static-analysis.txt"

Phase 5: Generate Accessibility Fixes

I'll generate specific fix implementations:

echo ""
echo "=== Generating Accessibility Fixes ==="
echo ""

FIXES_DIR="$A11Y_DIR/fixes"
mkdir -p "$FIXES_DIR"

# Fix 1: Image Accessibility
cat > "$FIXES_DIR/01-image-accessibility.jsx" 

// ❌ BAD: Generic alt text

// ✅ GOOD: Descriptive alt text

// ✅ GOOD: Decorative image (empty alt)

// ✅ GOOD: Complex image with detailed description

    
    
        Sales increased from $10k in January to $50k in December,
        with the highest growth occurring in Q4.
    

// React: Dynamic images
export const AccessibleImage = ({ src, alt, isDecorative = false }) => {
    if (isDecorative) {
        return ;
    }
    return ;
};
IMAGES

# Fix 2: Form Accessibility
cat > "$FIXES_DIR/02-form-accessibility.jsx" 

// ✅ GOOD: Properly labeled input

    Email Address
    

// ✅ GOOD: Label with input inside (implicit)

    Email Address
    

// ✅ GOOD: ARIA label when visual label is hidden

// ✅ GOOD: Error messages

    Password
    
    
        Password must be at least 8 characters
    

// React: Accessible form component
export const AccessibleForm = () => {
    const [email, setEmail] = useState('');
    const [error, setError] = useState('');

    return (
        
            
                
                    Email Address *
                
                 setEmail(e.target.value)}
                    aria-required="true"
                    aria-invalid={!!error}
                    aria-describedby={error ? "email-error" : undefined}
                />
                {error && (
                    
                        {error}
                    
                )}
            
            Submit
        
    );
};
FORMS

# Fix 3: Button Accessibility
cat > "$FIXES_DIR/03-button-accessibility.jsx" Click me

// ❌ BAD: Button with only icon, no accessible text

    

// ✅ GOOD: Proper button with text
Click me

// ✅ GOOD: Icon button with aria-label

    

// ✅ GOOD: Icon button with visually hidden text

    
    Delete item

// CSS for screen-reader only text
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-width: 0;
}

// ✅ GOOD: Loading state

    {isLoading ? 'Saving...' : 'Save'}

// React: Accessible icon button component
export const IconButton = ({ icon: Icon, label, onClick, ...props }) => {
    return (
        
            
            {label}
        
    );
};
BUTTONS

# Fix 4: Keyboard Navigation
cat > "$FIXES_DIR/04-keyboard-navigation.jsx" Click me

// ✅ GOOD: Proper button (keyboard accessible by default)
Click me

// ✅ GOOD: If you must use div, add keyboard support
 {
        if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            handleClick();
        }
    }}
>
    Click me

// ✅ GOOD: Skip to main content link

    Skip to main content

// CSS for skip link (visible on focus)
.skip-link {
    position: absolute;
    top: -40px;
    left: 0;
    background: #000;
    color: white;
    padding: 8px;
    text-decoration: none;
    z-index: 100;
}

.skip-link:focus {
    top: 0;
}

// ✅ GOOD: Focus management in modals
export const Modal = ({ isOpen, onClose, children }) => {
    const modalRef = useRef(null);

    useEffect(() => {
        if (isOpen) {
            // Focus first focusable element
            const focusable = modalRef.current?.querySelector(
                'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
            );
            focusable?.focus();
        }
    }, [isOpen]);

    return isOpen ? (
        
            Modal Title
            {children}
            Close
        
    ) : null;
};

// ✅ GOOD: Roving tabindex

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [manastalukdar](https://github.com/manastalukdar)
- **Source:** [manastalukdar/ai-devstudio](https://github.com/manastalukdar/ai-devstudio)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.