Install
$ agentstack add skill-manastalukdar-ai-devstudio-accessibility ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
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 →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.
Write a review
Versions
- v0.1.0 Imported from the upstream source.