Catalog PyPI
PACKAGE EXPLORERView in registry

a11y-bridge

PyPI

Accessible CLI wrapper — makes any command-line tool screen-reader friendly

a11yaccessibilitycliscreen-readerwcag
Versions collected1
Direct dependencies2From release 0.2.0
Last observed20 Oct, 16:17 UTC

README

Version 0.2.0 documentation

a11y-bridge

Make any CLI tool accessible. Zero config, zero dependencies.

The Problem

CLI tools like oc, kubectl, gh, and docker produce output that is hard to use for people with disabilities:

  • Screen reader users hear tables as a stream of words with no column association — "NAME READY STATUS nginx one one Running" tells you nothing about which value belongs to which header
  • Low-vision users get plain monochrome output with no color to distinguish healthy pods from crashing ones
  • Color-blind users can't tell red errors from green successes when a tool uses color as the only indicator

Most CLI tools don't have built-in accessibility features. Even when they do, they're inconsistent — every tool has different flags, different env vars, different output formats.

The Solution

a11y-bridge wraps any CLI binary and adapts its output to the user's needs:

a11y-bridge oc get pods -n myns

That's it. a11y-bridge detects who you are and adapts:

Sighted user (normal terminal) — adds semantic color:

NAME          READY   STATUS             RESTARTS   AGE
nginx-abc     1/1     Running            0          3d      ← green
postgres-xy   0/1     CrashLoopBackOff   5          4d      ← red

Screen reader user (NO_COLOR set, or screen reader running) — converts tables to labeled sentences:

status: Running: oc get pods -n myns
result: 2 item(s).
result: 1. [OK] NAME: nginx-abc. READY: 1/1. STATUS: Running. RESTARTS: 0. AGE: 3d.
result: 2. [ERROR] NAME: postgres-xy. READY: 0/1. STATUS: CrashLoopBackOff. RESTARTS: 5. AGE: 4d.

Every value paired with its header. [OK] and [ERROR] prefixes replace color. result: labels serve as screen reader navigation landmarks.

Install

The core package has zero dependencies. Install only the domains you need:

# Core only — color, screen reader, table formatting (zero deps)
pip install a11y-bridge

# With audio — TTS (Piper natural voice) + STT (Vosk voice input)
pip install a11y-bridge[audio]

# Everything
pip install a11y-bridge[all]

The AI mode (--askai) needs an API key but no extra pip packages — it uses stdlib urllib.

From source:

git clone https://github.com/cli-accessibility/a11y-bridge.git
cd a11y-bridge
pip install .              # core only
pip install .[audio]       # with audio
pip install .[all]         # everything

Or run without installing:

python -m a11y_bridge oc get pods

Usage

Prefix any command with a11y-bridge:

a11y-bridge oc get pods -n myns
a11y-bridge gh pr list
a11y-bridge kubectl get deployments
a11y-bridge docker ps
a11y-bridge git status

a11y-bridge detects your context automatically. To force a specific mode:

# Force screen reader mode
a11y-bridge --domain screen-reader oc get pods

# Force it via environment
NO_COLOR=1 a11y-bridge oc get pods
A11Y_SCREEN_READER=1 a11y-bridge oc get pods

# Strip ANSI only, no reformatting
a11y-bridge --raw kubectl logs my-pod

# Just set NO_COLOR=1 TERM=dumb, don't touch output
a11y-bridge --passthrough git diff

AI-Powered Interactive Mode

Start a conversational session where you describe what you want in plain language:

a11y-bridge --askai gh
a11y-bridge: AI session for 'gh'. Type natural language or raw commands.

you: show me my open pull requests
status: List open pull requests
status: Running: gh pr list
result: 3 open pull requests. #123 "Fix login bug" updated yesterday,
        #456 "Add dark mode" updated 3 days ago, #789 "Refactor auth"
        updated last week.
a11y-bridge: You could try:
  1. View details of a specific PR
  2. Check CI status of a PR

you: close the second one
status: I will run: gh pr close 456
status: Proceed? [Y/n]
you: y
result: Pull request #456 closed.

you: quit

The AI converts your natural language to CLI commands, executes them safely, and summarizes the output in accessible text. Multi-turn context is preserved — "the second one" resolves against the previous result.

You can also type raw commands directly:

you: pr list --state closed
status: Running: gh pr list --state closed
result: 5 closed pull requests...

Setup

Set your AI provider via environment variables:

# Option 1: Generic key (recommended)
export A11Y_AI_KEY=your-api-key-here
export A11Y_AI_PROVIDER=anthropic    # or: openai, ollama

# Option 2: Provider-specific keys (also works)
export ANTHROPIC_API_KEY=your-key     # for Claude
export OPENAI_API_KEY=your-key        # for OpenAI/compatible

# Option 3: Local Ollama (no key needed)
# Install: https://ollama.com/download
ollama serve                              # start the server
ollama pull qwen2.5-coder:7b-instruct    # download a model (~4.7GB, one-time)
# a11y-bridge auto-detects Ollama on localhost:11434

Optional settings:

export A11Y_AI_URL=http://localhost:11434   # custom API endpoint
export A11Y_MODEL=claude-sonnet-4-6            # specific model name

Safety

Commands are classified by safety level:

LevelWhat happensExamples
SafeAuto-executes, no confirmationget, list, describe, logs, status, whoami
ConfirmAsks "Proceed? [Y/n]"create, apply, merge, close, scale
DangerousRequires typing "yes"delete, drain, destroy, purge, drop

The AI generates commands but never classifies their safety — that's done by the allowlist. The full command is always shown before execution.

Audio Mode

Speak results aloud and use voice input — fully offline using Piper (natural voice) or espeak-ng:

# Command output spoken aloud
a11y-bridge --domain audio gh pr list

# AI session with voice — results spoken, type 'v' to speak input
a11y-bridge --domain audio --askai gh
a11y-bridge: AI session for 'gh' (using anthropic, audio enabled). Type 'v' to use voice input.

you: list all my repos
(each repo spoken one by one in a natural voice)

you: v
a11y-bridge: Listening... (speak now, press Ctrl+C to stop)
heard: show my pull requests
status: Running: gh pr list
(results spoken aloud)

you: quit

Quick setup

After installing, run a11y-bridge setup to check prerequisites and download models:

pip install a11y-bridge[audio]
a11y-bridge setup

This checks for system packages, Python packages, and offers to download the TTS and STT models automatically.

Manual audio prerequisites

System packages needed (install once):

# Linux (Fedora/RHEL)
sudo dnf install espeak-ng pulseaudio-utils  # TTS engine + paplay for audio output

# Linux (Ubuntu/Debian)
sudo apt install espeak-ng pulseaudio-utils  # TTS engine + paplay for audio output

# For voice input (microphone recording):
sudo dnf install alsa-utils   # provides arecord (Fedora/RHEL)
sudo apt install alsa-utils   # provides arecord (Ubuntu/Debian)

# macOS — espeak-ng via Homebrew, or use built-in 'say'
brew install espeak-ng

Piper (natural voice) setup

# Install Piper neural TTS (optional, recommended over espeak-ng)
pip install piper-tts

# Download voice model + config (~60MB, one-time, both files required)
mkdir -p ~/.cache/a11y-bridge/piper
cd ~/.cache/a11y-bridge/piper
curl -sL https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/lessac/medium/en_US-lessac-medium.onnx -o en_US-lessac-medium.onnx
curl -sL https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/lessac/medium/en_US-lessac-medium.onnx.json -o en_US-lessac-medium.onnx.json

Voice input (Vosk STT) setup

# Install Vosk speech-to-text
pip install vosk

# Download speech recognition model (~50MB, one-time)
mkdir -p ~/.cache/a11y-bridge
cd ~/.cache/a11y-bridge
curl -sL https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip -o model.zip
unzip -q model.zip && mv vosk-model-small-en-us-0.15 vosk-model && rm model.zip

Requires arecord (Linux ALSA) or sox for microphone recording.

Audio settings

export A11Y_TTS_RATE=170            # Words per minute (default 170)
export A11Y_TTS_ENGINE=espeak-ng    # Force engine: piper, espeak-ng, say, none

Engine priority: Piper (natural) > espeak-ng (robotic, fast) > say (macOS).

How It Works

In wrapper mode (default), a11y-bridge is a thin wrapper that does not use AI. Under the hood:

  1. Runs your command with NO_COLOR=1 and TERM=dumb to suppress color at source
  2. Captures stdout and stderr
  3. Sighted mode: parses status words (Running, Error, Pending) and adds ANSI color
  4. Screen reader mode: strips remaining ANSI, converts tables to labeled sentences, interprets color semantics as text prefixes, replaces Unicode symbols with text alternatives, extracts hyperlink URLs
  5. Outputs the result with status:/result:/error: labels

Pipe-safe: when stdout is not a terminal, output passes through raw (ANSI-stripped, no labels) so scripts and pipes work normally.

What Gets Adapted

For sighted users — color is added to: status words (Running→green, Error→red, Pending→yellow), active markers (bold green), table headers (bold), URLs (cyan).

For screen reader users:

  • Tables → labeled sentences (NAME: nginx. STATUS: Running.)
  • Color → text prefixes ([OK], [ERROR], [WARN])
  • Unicode symbols → text (✓→[OK], ✗→[FAIL], ⚠→[WARN])
  • Inverse video → [SELECTED: text]
  • OSC 8 hyperlinks → text (link: URL)
  • All output labeled with result:/error:/status:

Requirements

Python 3.11 or later.

InstallWhat you getDependencies
pip install a11y-bridgeColor, screen reader mode, table formattingNone (stdlib only)
pip install a11y-bridge[audio]+ TTS (Piper natural voice) + STT (Vosk voice input)piper-tts, vosk
pip install a11y-bridge[all]Everything abovepiper-tts, vosk
--askai flag+ AI interactive mode (natural language → commands)None (set A11Y_AI_KEY)

Audio also needs system packages: espeak-ng (Linux, usually pre-installed) or Piper voice model (~60MB, one-time download).

Documentation

License

Apache-2.0

Downloads & popularity

6downloads
1-day window · source-reported counts18 Oct 2026
16984.50
2026-09-14: 169 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-14–2026-09-142026-09-15: 28 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-15–2026-09-152026-09-16: 8 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-16–2026-09-162026-09-17: 4 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-17–2026-09-172026-09-18: 10 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-18–2026-09-182026-09-19: 4 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-19–2026-09-192026-09-20: 3 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-20–2026-09-202026-09-21: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-21–2026-09-212026-09-22: 5 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-22–2026-09-222026-09-23: 2 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-23–2026-09-232026-09-24: 4 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-24–2026-09-242026-09-25: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-25–2026-09-252026-09-26: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-26–2026-09-262026-09-27: 3 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-27–2026-09-272026-09-28: 4 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-28–2026-09-282026-09-29: 6 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-29–2026-09-292026-09-30: 4 · observed 2026-10-20T18:48:46.6830058Z · period 2026-09-30–2026-09-302026-10-05: 5 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-05–2026-10-052026-10-06: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-06–2026-10-062026-10-07: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-07–2026-10-072026-10-08: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-08–2026-10-082026-10-09: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-09–2026-10-092026-10-10: 7 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-10–2026-10-102026-10-11: 3 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-11–2026-10-112026-10-12: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-12–2026-10-122026-10-13: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-13–2026-10-132026-10-14: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-14–2026-10-142026-10-15: 1 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-15–2026-10-152026-10-16: 4 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-16–2026-10-162026-10-18: 6 · observed 2026-10-20T18:48:46.6830058Z · period 2026-10-18–2026-10-18
14 Sept18 Oct

pypistats · 30 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-18 – 2026-10-1862026-10-20T18:48:46.6830058Z
2026-10-16 – 2026-10-1642026-10-20T18:48:46.6830058Z
2026-10-15 – 2026-10-1512026-10-20T18:48:46.6830058Z
2026-10-14 – 2026-10-1412026-10-20T18:48:46.6830058Z
2026-10-13 – 2026-10-1312026-10-20T18:48:46.6830058Z
2026-10-12 – 2026-10-1212026-10-20T18:48:46.6830058Z
2026-10-11 – 2026-10-1132026-10-20T18:48:46.6830058Z
2026-10-10 – 2026-10-1072026-10-20T18:48:46.6830058Z
2026-10-09 – 2026-10-0912026-10-20T18:48:46.6830058Z
2026-10-08 – 2026-10-0812026-10-20T18:48:46.6830058Z
2026-10-07 – 2026-10-0712026-10-20T18:48:46.6830058Z
2026-10-06 – 2026-10-0612026-10-20T18:48:46.6830058Z
2026-10-05 – 2026-10-0552026-10-20T18:48:46.6830058Z
2026-09-30 – 2026-09-3042026-10-20T18:48:46.6830058Z
2026-09-29 – 2026-09-2962026-10-20T18:48:46.6830058Z
2026-09-28 – 2026-09-2842026-10-20T18:48:46.6830058Z
2026-09-27 – 2026-09-2732026-10-20T18:48:46.6830058Z
2026-09-26 – 2026-09-2612026-10-20T18:48:46.6830058Z
2026-09-25 – 2026-09-2512026-10-20T18:48:46.6830058Z
2026-09-24 – 2026-09-2442026-10-20T18:48:46.6830058Z
2026-09-23 – 2026-09-2322026-10-20T18:48:46.6830058Z
2026-09-22 – 2026-09-2252026-10-20T18:48:46.6830058Z
2026-09-21 – 2026-09-2112026-10-20T18:48:46.6830058Z
2026-09-20 – 2026-09-2032026-10-20T18:48:46.6830058Z
2026-09-19 – 2026-09-1942026-10-20T18:48:46.6830058Z
2026-09-18 – 2026-09-18102026-10-20T18:48:46.6830058Z
2026-09-17 – 2026-09-1742026-10-20T18:48:46.6830058Z
2026-09-16 – 2026-09-1682026-10-20T18:48:46.6830058Z
2026-09-15 – 2026-09-15282026-10-20T18:48:46.6830058Z
2026-09-14 – 2026-09-141692026-10-20T18:48:46.6830058Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.2.014 Sept 20262

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
cli-accessibility/a11y-bridge

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 16:17 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:1f9bfd58a7ce45e570107861573d49545aa82e548e88987bb78a13432dcd9474