agentsclimarketplace

Docs accessibility

Skill a5c-ai/babysitter/library/specializations/technical-documentation/skills/docs-accessibility

Babysitter enforces obedience on agentic workforces and enables them to manage extremely complex tasks and workflows through deterministic, hallucination-free self-orchestration

Install
npx -y skills add a5c-ai/babysitter --skill docs-accessibility

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

Documentation accessibility validation and remediation. Check WCAG 2.1 compliance, validate alt text, analyze heading hierarchy, verify color contrast, and generate accessibility reports.

SKILL.md

11.1 KB, as published. Nobody here has run it

Documentation Accessibility Skill

Documentation accessibility validation and remediation.

Capabilities

  • WCAG 2.1 compliance checking
  • Image alt text validation
  • Heading hierarchy analysis
  • Color contrast verification
  • Screen reader compatibility testing
  • Keyboard navigation validation
  • ARIA landmark checking
  • Accessibility report generation

Usage

Invoke this skill when you need to:

  • Audit documentation for accessibility
  • Validate image alt text
  • Check heading structure
  • Verify color contrast ratios
  • Generate accessibility reports

Inputs

ParameterTypeRequiredDescription
inputPathstringYesPath to documentation or built site
actionstringYesaudit, validate-images, check-headings
standardstringNoWCAG level (A, AA, AAA)
outputFormatstringNojson, html, sarif
fixbooleanNoAuto-fix issues where possible

Input Example

{
  "inputPath": "./docs/_build/html",
  "action": "audit",
  "standard": "AA",
  "outputFormat": "json"
}

Output Structure

Accessibility Report

{
  "summary": {
    "total": 156,
    "passed": 142,
    "failed": 14,
    "level": "AA",
    "score": 91
  },
  "byCategory": {
    "images": { "passed": 45, "failed": 3 },
    "headings": { "passed": 28, "failed": 2 },
    "contrast": { "passed": 52, "failed": 5 },
    "navigation": { "passed": 17, "failed": 4 }
  },
  "issues": [
    {
      "id": "img-alt-missing",
      "wcag": "1.1.1",
      "level": "A",
      "impact": "critical",
      "description": "Image missing alt text",
      "location": {
        "file": "docs/guide/setup.md",
        "line": 42,
        "element": "<img src=\"diagram.png\">"
      },
      "suggestion": "Add descriptive alt text: alt=\"System architecture diagram showing...\""
    },
    {
      "id": "heading-skip",
      "wcag": "1.3.1",
      "level": "A",
      "impact": "moderate",
      "description": "Heading levels should only increase by one",
      "location": {
        "file": "docs/api/users.md",
        "line": 15,
        "element": "<h4>User Properties</h4>"
      },
      "context": "H2 -> H4 (skipped H3)",
      "suggestion": "Change to <h3> or add missing <h3> above"
    },
    {
      "id": "color-contrast",
      "wcag": "1.4.3",
      "level": "AA",
      "impact": "serious",
      "description": "Text does not meet contrast ratio requirements",
      "location": {
        "file": "docs/_static/custom.css",
        "line": 28,
        "element": ".note { color: #999; }"
      },
      "details": {
        "foreground": "#999999",
        "background": "#ffffff",
        "ratio": "2.85:1",
        "required": "4.5:1"
      },
      "suggestion": "Change to #767676 or darker for 4.5:1 ratio"
    }
  ],
  "wcagCompliance": {
    "A": { "passed": 48, "failed": 6 },
    "AA": { "passed": 35, "failed": 8 },
    "AAA": { "passed": 12, "failed": 0 }
  }
}

WCAG Guidelines Checked

Perceivable (Principle 1)

1.1.1 - Non-text Content:
  - Images have alt text
  - Decorative images have empty alt
  - Complex images have long descriptions
  - Icons have accessible names

1.3.1 - Info and Relationships:
  - Headings properly structured
  - Lists properly marked up
  - Tables have headers
  - Form labels associated

1.4.1 - Use of Color:
  - Color not sole indicator
  - Links distinguishable

1.4.3 - Contrast (Minimum):
  - Text: 4.5:1 ratio
  - Large text: 3:1 ratio
  - UI components: 3:1 ratio

Operable (Principle 2)

2.1.1 - Keyboard:
  - All functionality keyboard accessible
  - No keyboard traps
  - Skip links present

2.4.1 - Bypass Blocks:
  - Skip navigation link
  - Landmark regions

2.4.2 - Page Titled:
  - Descriptive page titles

2.4.6 - Headings and Labels:
  - Descriptive headings
  - Clear labels

2.4.7 - Focus Visible:
  - Visible focus indicators

Understandable (Principle 3)

3.1.1 - Language of Page:
  - lang attribute present

3.2.3 - Consistent Navigation:
  - Navigation consistent across pages

3.3.2 - Labels or Instructions:
  - Form inputs have labels

Image Alt Text Validation

Alt Text Rules

const altTextRules = {
  // Must have alt attribute
  required: {
    test: (img) => img.hasAttribute('alt'),
    message: 'Image must have alt attribute'
  },

  // Alt text should be descriptive
  descriptive: {
    test: (img) => {
      const alt = img.getAttribute('alt');
      const badPatterns = [
        /^image$/i,
        /^photo$/i,
        /^picture$/i,
        /^graphic$/i,
        /\.(?:png|jpg|gif|svg)$/i,
        /^untitled/i
      ];
      return !badPatterns.some(p => p.test(alt));
    },
    message: 'Alt text should describe the image content'
  },

  // Not too long
  length: {
    test: (img) => {
      const alt = img.getAttribute('alt');
      return alt.length <= 125;
    },
    message: 'Alt text should be concise (under 125 characters)'
  },

  // Decorative images should have empty alt
  decorative: {
    test: (img) => {
      if (img.hasAttribute('role') && img.getAttribute('role') === 'presentation') {
        return img.getAttribute('alt') === '';
      }
      return true;
    },
    message: 'Decorative images should have empty alt=""'
  }
};

Alt Text Suggestions

function suggestAltText(imagePath, context) {
  const suggestions = [];

  // Based on filename
  const filename = path.basename(imagePath, path.extname(imagePath));
  if (filename.includes('diagram')) {
    suggestions.push(`Diagram showing ${extractContext(context)}`);
  }
  if (filename.includes('screenshot')) {
    suggestions.push(`Screenshot of ${extractContext(context)}`);
  }
  if (filename.includes('logo')) {
    suggestions.push(`${extractBrand(filename)} logo`);
  }

  // Based on surrounding text
  const heading = findNearestHeading(context);
  if (heading) {
    suggestions.push(`Illustration for ${heading}`);
  }

  return suggestions;
}

Heading Structure Analysis

Heading Hierarchy Check

function analyzeHeadings(content) {
  const headings = extractHeadings(content);
  const issues = [];

  let lastLevel = 0;
  headings.forEach((heading, index) => {
    const level = heading.level;

    // Check for skipped levels
    if (level > lastLevel + 1 && lastLevel !== 0) {
      issues.push({
        type: 'heading-skip',
        heading: heading.text,
        line: heading.line,
        expected: lastLevel + 1,
        actual: level
      });
    }

    // Check for multiple H1s
    if (level === 1 && index > 0) {
      issues.push({
        type: 'multiple-h1',
        heading: heading.text,
        line: heading.line
      });
    }

    lastLevel = level;
  });

  return {
    structure: buildHeadingTree(headings),
    issues
  };
}

Color Contrast Checking

Contrast Ratio Calculation

function getContrastRatio(foreground, background) {
  const fgLuminance = getRelativeLuminance(foreground);
  const bgLuminance = getRelativeLuminance(background);

  const lighter = Math.max(fgLuminance, bgLuminance);
  const darker = Math.min(fgLuminance, bgLuminance);

  return (lighter + 0.05) / (darker + 0.05);
}

function meetsContrastRequirement(ratio, isLargeText, level = 'AA') {
  const requirements = {
    'AA': { normal: 4.5, large: 3 },
    'AAA': { normal: 7, large: 4.5 }
  };

  const threshold = isLargeText
    ? requirements[level].large
    : requirements[level].normal;

  return ratio >= threshold;
}

CSS Analysis

async function analyzeStylesheet(cssPath) {
  const css = await fs.readFile(cssPath, 'utf8');
  const ast = postcss.parse(css);
  const issues = [];

  ast.walkDecls('color', (decl) => {
    const rule = decl.parent;
    const bgColor = findBackgroundColor(rule) || '#ffffff';
    const fgColor = decl.value;

    const ratio = getContrastRatio(fgColor, bgColor);

    if (!meetsContrastRequirement(ratio, false, 'AA')) {
      issues.push({
        selector: rule.selector,
        foreground: fgColor,
        background: bgColor,
        ratio: ratio.toFixed(2),
        line: decl.source.start.line,
        suggestion: suggestAccessibleColor(fgColor, bgColor)
      });
    }
  });

  return issues;
}

Keyboard Navigation

Focus Testing

async function testKeyboardNavigation(page) {
  const issues = [];

  // Get all focusable elements
  const focusable = await page.$$('a, button, input, select, textarea, [tabindex]');

  for (const element of focusable) {
    await element.focus();

    // Check focus visibility
    const hasFocusStyle = await page.evaluate((el) => {
      const styles = window.getComputedStyle(el);
      const focusStyles = window.getComputedStyle(el, ':focus');
      return (
        styles.outline !== 'none' ||
        styles.boxShadow !== 'none' ||
        focusStyles.outline !== 'none'
      );
    }, element);

    if (!hasFocusStyle) {
      issues.push({
        type: 'focus-not-visible',
        element: await element.evaluate(el => el.outerHTML.substring(0, 100))
      });
    }
  }

  return issues;
}

Workflow

  1. Parse content - Load documentation files or built HTML
  2. Extract elements - Find images, headings, links, etc.
  3. Check images - Validate alt text
  4. Analyze headings - Check hierarchy
  5. Test contrast - Verify color ratios
  6. Check navigation - Validate keyboard access
  7. Generate report - Output findings

Dependencies

{
  "devDependencies": {
    "axe-core": "^4.8.0",
    "pa11y": "^6.2.0",
    "lighthouse": "^11.0.0",
    "puppeteer": "^21.0.0",
    "color-contrast-checker": "^2.1.0"
  }
}

CLI Commands

# Run axe-core audit
npx axe ./docs/_build/html --rules wcag2aa

# Run pa11y
npx pa11y https://docs.example.com --standard WCAG2AA

# Lighthouse accessibility audit
npx lighthouse https://docs.example.com --only-categories=accessibility

# Check single page
npx axe https://docs.example.com/guide --save report.json

Best Practices Applied

  • Always provide alt text for informative images
  • Use empty alt for decorative images
  • Maintain logical heading hierarchy
  • Ensure 4.5:1 contrast for normal text
  • Provide visible focus indicators
  • Include skip navigation links
  • Use semantic HTML elements

References

Target Processes

  • docs-testing.js
  • docs-audit.js
  • style-guide-enforcement.js

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.