Skip to main content
statuslinesSource-backedReview first Safety · Privacy ·

Accessibility First Statusline - Claude Code Statuslines

WCAG-compliant accessible statusline with screen reader announcements, high-contrast colors, semantic labels, keyboard hints, and reduced motion support.

by JSONbored·added 2025-10-23·
Claude Code
HarnessClaude Code
Language:bash
Review first review before installing

Open the source and read safety notes before installing.

Prerequisites

  • Claude Code CLI installed and configured
  • Bash shell available (bash 4.0+ recommended)
  • jq command-line JSON processor (jq 1.6+ recommended for error handling)
  • Terminal with ANSI color code support
  • Screen reader software (optional, for accessibility features: NVDA, JAWS, VoiceOver, or Orca)
  • Write access to /tmp directory (for token tracking and initialization markers)

Schema details

Install type
config
Reading time
2 min
Difficulty score
10
Troubleshooting
Yes
Breaking changes
No
Runtime and command metadata
Script language
bash
Script body
#!/usr/bin/env bash

# Accessibility-First Statusline for Claude Code
# WCAG 2.1 AA compliant, screen reader friendly, high contrast

# Read JSON from stdin
read -r input

# Extract values
model=$(echo "$input" | jq -r '.model // "unknown"')
dir=$(echo "$input" | jq -r '.workspace.path // "~"' | sed "s|$HOME|~|")
tokens=$(echo "$input" | jq -r '.session.totalTokens // 0')

# Check for PREFERS_REDUCED_MOTION environment variable
if [ "$PREFERS_REDUCED_MOTION" = "1" ]; then
  # No animations, static display
  animation=""
else
  # Minimal indicator (not flashing)
  animation="▪"
fi

# High contrast WCAG AA compliant colors
# Contrast ratio > 4.5:1 against black background
# Using basic ANSI colors for maximum compatibility
WHITE_BOLD="\033[1;37m"    # Bright white (high contrast)
CYAN_BOLD="\033[1;36m"     # Bright cyan (high contrast)
YELLOW_BOLD="\033[1;33m"   # Bright yellow (high contrast)
RESET="\033[0m"

# Semantic labels (screen reader friendly)
LABEL_MODEL="Model:"
LABEL_DIR="Directory:"
LABEL_TOKENS="Tokens:"

# Build statusline with semantic structure
statusline=""
statusline+="${animation} "  # Activity indicator (if motion enabled)
statusline+="${WHITE_BOLD}${LABEL_MODEL}${RESET} ${CYAN_BOLD}${model}${RESET} | "
statusline+="${WHITE_BOLD}${LABEL_DIR}${RESET} ${CYAN_BOLD}${dir}${RESET} | "
statusline+="${WHITE_BOLD}${LABEL_TOKENS}${RESET} ${YELLOW_BOLD}${tokens}${RESET}"

# Output for visual display
echo -e "$statusline"

# Screen reader announcement (stderr for assistive tech)
# Only announce on significant changes (every 1000 tokens)
token_threshold=$((tokens / 1000 * 1000))
if [ -f "/tmp/claude_statusline_last_tokens" ]; then
  last_tokens=$(cat /tmp/claude_statusline_last_tokens)
else
  last_tokens=0
fi

if [ $token_threshold -ne $((last_tokens / 1000 * 1000)) ]; then
  # Announce to screen reader (ARIA live region style)
  echo "Status update: Using $model in directory $dir. Token count: $tokens." >&2
  echo $tokens > /tmp/claude_statusline_last_tokens
fi

# Keyboard navigation hint (on first run)
if [ ! -f "/tmp/claude_statusline_initialized" ]; then
  echo "Accessibility mode enabled. Press Ctrl+C to interrupt, Tab for completion suggestions." >&2
  touch /tmp/claude_statusline_initialized
fi
Full copyable content
{
  "statusLine": {
    "type": "command",
    "command": "$CLAUDE_PROJECT_DIR/.claude/statuslines/accessibility-first-statusline.sh"
  }
}

About this resource

Features

  • WCAG 2.1 AA compliant high-contrast colors (4.5:1 ratio minimum)
  • Screen reader announcements via stderr for assistive technology
  • Semantic labels (Model:, Directory:, Tokens:) for context clarity
  • Reduced motion support via PREFERS_REDUCED_MOTION environment variable
  • Keyboard navigation hints for non-mouse users
  • Threshold-based announcements (every 1000 tokens) to reduce noise
  • Basic ANSI colors for maximum terminal compatibility
  • No complex Unicode characters or Powerline glyphs

Use Cases

  • Developers using screen readers (NVDA, JAWS, VoiceOver)
  • Users with visual impairments requiring high contrast
  • Teams enforcing WCAG accessibility compliance
  • Vestibular disorder users needing reduced motion
  • Keyboard-only navigation workflows
  • Inclusive design standard for enterprise environments
  • Testing accessibility of AI-assisted development tools

Requirements

  • Claude Code CLI installed and configured
  • Bash shell available (bash 4.0+ recommended)
  • jq command-line JSON processor (jq 1.6+ recommended for error handling)
  • Terminal with ANSI color code support
  • Screen reader software (optional, for accessibility features: NVDA, JAWS, VoiceOver, or Orca)
  • Write access to /tmp directory (for token tracking and initialization markers)

Configuration

{
  "statusLine": {
    "type": "command",
    "command": "$CLAUDE_PROJECT_DIR/.claude/statuslines/accessibility-first-statusline.sh"
  }
}

Examples

Enhanced Accessibility Statusline with Cost Tracking

Extended version with cost information and improved error handling

#!/usr/bin/env bash

# Enhanced Accessibility-First Statusline with Cost Tracking
# WCAG 2.1 AA compliant with additional metrics

input=$(cat)

# Safe extraction with defaults
model=$(echo "$input" | jq -r '.model.display_name // "unknown"')
dir=$(echo "$input" | jq -r '.workspace.current_dir // "~"' | sed "s|$HOME|~|")
tokens=$(echo "$input" | jq -r '.cost.total_tokens // 0')
cost=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')

# Reduced motion support
if [ "$PREFERS_REDUCED_MOTION" = "1" ]; then
  animation=""
else
  animation="▪"
fi

# WCAG AA compliant colors
WHITE_BOLD="\033[1;37m"
CYAN_BOLD="\033[1;36m"
YELLOW_BOLD="\033[1;33m"
GREEN_BOLD="\033[1;32m"
RESET="\033[0m"

# Build statusline with cost
statusline="${animation} "
statusline+="${WHITE_BOLD}Model:${RESET} ${CYAN_BOLD}${model}${RESET} | "
statusline+="${WHITE_BOLD}Dir:${RESET} ${CYAN_BOLD}${dir}${RESET} | "
statusline+="${WHITE_BOLD}Tokens:${RESET} ${YELLOW_BOLD}${tokens}${RESET} | "
statusline+="${WHITE_BOLD}Cost:${RESET} ${GREEN_BOLD}$${cost}${RESET}"

echo -e "$statusline"

# Screen reader announcement with cost
token_threshold=$((tokens / 1000 * 1000))
if [ -f "/tmp/claude_statusline_last_tokens" ]; then
  last_tokens=$(cat /tmp/claude_statusline_last_tokens)
else
  last_tokens=0
fi

if [ $token_threshold -ne $((last_tokens / 1000 * 1000)) ]; then
  echo "Status: $model in $dir. Tokens: $tokens. Cost: $${cost}." >&2
  echo $tokens > /tmp/claude_statusline_last_tokens
fi

Accessibility Statusline with Custom Announcement Threshold

Configurable announcement frequency for different screen reader preferences

#!/usr/bin/env bash

# Accessibility Statusline with Custom Announcement Threshold
# Allows configuration via environment variable

input=$(cat)

# Configuration: announcement threshold (default 1000 tokens)
ANNOUNCE_THRESHOLD=${STATUSLINE_ANNOUNCE_THRESHOLD:-1000}

model=$(echo "$input" | jq -r '.model.display_name // "unknown"')
dir=$(echo "$input" | jq -r '.workspace.current_dir // "~"' | sed "s|$HOME|~|")
tokens=$(echo "$input" | jq -r '.cost.total_tokens // 0')

# Reduced motion
if [ "$PREFERS_REDUCED_MOTION" = "1" ]; then
  animation=""
else
  animation="▪"
fi

# WCAG colors
WHITE_BOLD="\033[1;37m"
CYAN_BOLD="\033[1;36m"
YELLOW_BOLD="\033[1;33m"
RESET="\033[0m"

statusline="${animation} ${WHITE_BOLD}Model:${RESET} ${CYAN_BOLD}${model}${RESET} | ${WHITE_BOLD}Dir:${RESET} ${CYAN_BOLD}${dir}${RESET} | ${WHITE_BOLD}Tokens:${RESET} ${YELLOW_BOLD}${tokens}${RESET}"

echo -e "$statusline"

# Announcement with custom threshold
token_threshold=$((tokens / ANNOUNCE_THRESHOLD * ANNOUNCE_THRESHOLD))
if [ -f "/tmp/claude_statusline_last_tokens" ]; then
  last_tokens=$(cat /tmp/claude_statusline_last_tokens)
else
  last_tokens=0
fi

if [ $token_threshold -ne $((last_tokens / ANNOUNCE_THRESHOLD * ANNOUNCE_THRESHOLD)) ]; then
  echo "Status update: $model in $dir. Tokens: $tokens." >&2
  echo $tokens > /tmp/claude_statusline_last_tokens
fi

Accessibility First Statusline Installation Example

Complete setup instructions with directory creation and permissions

#!/bin/bash
# Installation script for Accessibility First Statusline

# Create statuslines directory
mkdir -p .claude/statuslines

# Download or create the script
cat > .claude/statuslines/accessibility-first-statusline.sh << 'SCRIPT_EOF'
#!/usr/bin/env bash
# Paste the full statusline script from the primary example above before running this installer.
SCRIPT_EOF

# Make executable
chmod +x .claude/statuslines/accessibility-first-statusline.sh

# Add to settings.json
if [ ! -f .claude/settings.json ]; then
  echo '{"statusLine":{"type":"command","command":"$CLAUDE_PROJECT_DIR/.claude/statuslines/accessibility-first-statusline.sh"}}' > .claude/settings.json
else
  # Merge with existing settings (requires jq)
  jq '.statusLine = {"type":"command","command":"$CLAUDE_PROJECT_DIR/.claude/statuslines/accessibility-first-statusline.sh"}' .claude/settings.json > .claude/settings.json.tmp
  mv .claude/settings.json.tmp .claude/settings.json
fi

echo "Accessibility First Statusline installed successfully!"

Troubleshooting

Screen reader not announcing status updates even though script outputs to stderr

Verify screen reader is configured to read stderr output. Test with: echo 'test announcement' >&2. Check that /tmp/claude_statusline_last_tokens file exists and updates correctly. Adjust announcement threshold (currently 1000 tokens) in script if announcements are too frequent or infrequent. Some screen readers require specific terminal emulator settings to read stderr.

Colors appear too dim or hard to read on terminal background despite WCAG compliance

WCAG contrast ratios assume black/dark background. For light backgrounds, invert color scheme: Use dark ANSI codes (30-37) instead of bright (90-97). Test contrast using WebAIM contrast checker or similar tool. Adjust ANSI color codes based on terminal theme. Check terminal color profile settings.

Animation indicator (▪) still showing even with PREFERS_REDUCED_MOTION=1 set

Set environment variable: export PREFERS_REDUCED_MOTION=1. Add to ~/.bashrc or ~/.zshrc for persistence. Verify with: echo $PREFERS_REDUCED_MOTION (should show 1). Restart Claude Code session after setting environment variable. Check that script is reading environment variable correctly.

Keyboard navigation hints appearing every session instead of just once

Check /tmp/claude_statusline_initialized file exists and persists. Verify /tmp is writable: touch /tmp/test && rm /tmp/test. On system reboot, /tmp clears - this is expected behavior. Move initialization marker to ~/.cache/claude-statusline/ for persistence across reboots. Check file permissions on /tmp directory.

Semantic labels (Model:, Directory:, Tokens:) making statusline too verbose or crowded

Labels are essential for screen readers but can be shortened: 'M:' instead of 'Model:', 'D:' for 'Directory:', 'T:' for 'Tokens:'. Balance visual brevity with semantic meaning. Test with screen reader first before removing labels. Consider using abbreviated labels that maintain semantic meaning.

jq command not found error when script executes

Install jq: macOS (brew install jq), Linux (sudo apt-get install jq or sudo yum install jq), or download from https://stedolan.github.io/jq/download/. Verify installation: which jq. Check PATH includes jq location. Use full path to jq if not in PATH: /usr/local/bin/jq or /usr/bin/jq.

Statusline not appearing in Claude Code interface

Verify script is executable: chmod +x .claude/statuslines/accessibility-first-statusline.sh. Check script outputs to stdout (not stderr for main display). Verify .claude/settings.json has correct statusLine configuration. Test script manually: echo '{"model":{"display_name":"Test"},"workspace":{"current_dir":"/test"}}' | ./accessibility-first-statusline.sh

Token count always shows 0 or incorrect value

Check JSON input structure: jq -r '.cost.total_tokens' should extract token count. Verify Claude Code is passing cost data in JSON. Use fallback: jq -r '.cost.total_tokens // 0' for missing values. Test JSON parsing: echo '$input' | jq '.cost' to inspect cost object structure.

#accessibility#wcag#screen-reader#high-contrast#inclusive#a11y

Source citations

Signals

Loading live community signals…

More like this, weekly

A short, calm digest of reviewed Claude resources. Unsubscribe any time.