Sonari
A text-to-speech layer that makes Claude Code usable with the screen off. Built for blind and low-vision developers: every session is read aloud in order, and a distinct sound tells you the moment a decision needs you.
- Python
- Swift
- Claude Code hooks
- launchd
- Kokoro TTS
- pytest
01 / Context
Coding agents run in terminals that redraw constantly, and screen readers handle that badly. A blind developer can use the model but not the tool around it. Sonari is a macOS speech layer for Claude Code that reads each session aloud, in order. The goal is a full working session with the screen off.
02 / My role
I built it end to end: the daemon architecture, the sound vocabulary, the hotkey system, and the product decisions about what is worth saying out loud. Sound is the whole interface, so the design work here was picking earcons, verbosity levels, and wording that stays truthful about what the agent is doing.
03 / Problem
The hard part is trust in what you hear. Speech has to arrive in the order things happened, across several concurrent sessions, and it can never stall: a silent failure and a finished task sound identical. That makes liveness the core engineering problem. The interface also has to stay controllable mid-speech, because listening is slow and you constantly want to skip, repeat, or jump.
04 / Approach
A launchd-managed daemon owns the speech pipeline, and every Claude Code session feeds it through hooks; each session’s output is queued and spoken in the order it happened. Decisions get earcons, one sound per type, so a question registers before the words do. Answers go by option number. A small Swift helper intercepts the global hotkeys (stop, repeat, jump between sessions, jump to the open decision) at the OS level, so they work while speech is playing. The core runs on the stock macOS Python with no third-party packages, so an install cannot be broken by whatever Python arrives next; a neural voice is an optional add-on.
05 / Result
Sonari is public and installs from a Claude Code marketplace, and I run my own sessions through it. Most of the engineering went into the failures you would never see: the hotkey helper sounds an alarm if the speech daemon dies, and an update that fails to speak is kept unheard rather than dropped, so you catch up on it instead of missing it.