{
  "markdown": "# claude-voice-cue\n\n**An audible heads-up when Claude Code is waiting on you.**\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Node](https://img.shields.io/badge/node-%E2%89%A518-brightgreen.svg)](https://nodejs.org)\n[![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey.svg)](#platform-support)\n[![Works with Claude Code](https://img.shields.io/badge/works%20with-Claude%20Code-8A2BE2.svg)](https://code.claude.com)\n[![Zero dependencies](https://img.shields.io/badge/deps-0-success.svg)](package.json)\n\n`claude-voice-cue` installs a native Claude Code hook that plays a short\nvoice cue the instant Claude needs your input — tool approval, plan\nreview, auth prompt. You keep running `claude` exactly as before; the\ntool disappears into the background after a single install step.\n\nIt is a tiny project (~300 lines of code, zero runtime dependencies) and\nit deliberately does one thing.\n\n---\n\n## The problem\n\nAgentic coding tools like Claude Code spend a lot of their runtime\nworking autonomously — reading files, running tests, calling tools. A\ndeveloper's rational response is to tab away and do something else while\nthe agent works. The moment the agent needs an approval (\"can I run this\nshell command? (y/n)\"), the terminal silently waits. If you're in a\ndifferent window, you don't notice. Minutes get wasted per prompt, and\nthere can be dozens of prompts per session.\n\nThe fix is obvious: play a sound. But doing it *well* — without false\npositives, without lag, without fighting the host's TUI — is\nsurprisingly particular work, and no platform-native solution shipped\nwith the product.\n\n## How it works\n\n```\nClaude Code  ─┐\n              │  fires PermissionRequest / Notification hook\n              ▼\n   ~/.claude/settings.json\n              │\n              │  spawns registered command\n              ▼\n    afplay <cached .aiff>          ◄─── macOS fast path\n           — or —\n    node bin/cue.js  →  say/espeak/SAPI     ◄─── fallback\n```\n\nAt install time we write two hook entries into\n`~/.claude/settings.json` and pre-generate a short audio file into\n`~/.claude/claude-voice-cue.aiff`. When Claude Code fires either event,\nits hook runner spawns `afplay` against the cached file. No runtime\nprocess, no stdout polling, no heuristics.\n\n## Quick start\n\n### Option A — Claude Code plugin (recommended)\n\nInside a running `claude` session:\n\n```\n/plugin marketplace add arpan-k09/claude-voice-cue\n/plugin install claude-voice-cue@claude-voice-cue\n```\n\nThat's it. Claude Code wires up the `PermissionRequest` and `Notification`\nhooks automatically; uninstall via `/plugin uninstall claude-voice-cue`.\n\n### Option B — standalone CLI\n\nFor users not on a plugin-capable Claude Code version, or who prefer a\nshell install that modifies `~/.claude/settings.json` directly:\n\n```sh\ngit clone https://github.com/arpan-k09/claude-voice-cue.git\ncd claude-voice-cue\nnode bin/claude-voice-cue.js install   # one-time setup, zero deps\n```\n\nThen use Claude Code exactly as before:\n\n```sh\nclaude\n# Claude works autonomously, you tab away...\n# Claude: \"Do you want me to run the migration script? (y/n)\"\n# 🔊  *Input needed*   <-- fires within ~100ms of the prompt appearing\n```\n\nOptionally put the CLI on your `PATH`:\n\n```sh\nnpm link\nclaude-voice-cue            # shows install status\nclaude-voice-cue test       # plays the cue once so you can verify audio\nclaude-voice-cue uninstall  # removes only our hook entries\n```\n\n## Features\n\n| | |\n|---|---|\n| **Native hook integration** | Uses Claude Code's `PermissionRequest` and `Notification` events — no stdout scraping, no PTY wrapping, no heuristics. |\n| **Sub-100ms reaction time** | `PermissionRequest` bypasses the `Notification` idle debounce. Pre-generated audio skips `say`'s 500–1000ms voice-engine cold start. |\n| **Cross-platform** | macOS `afplay` fast path; Linux/Windows fall back to TTS via `bin/cue.js`. |\n| **Non-blocking** | Hook runs async; a slow TTS call cannot freeze Claude's UI. |\n| **Safe installer** | Atomic writes, pre-mutation backup, malformed-JSON refusal, idempotent re-install, unrelated hooks preserved. |\n| **Zero runtime dependencies** | The installed tool is pure Node stdlib. No `node-pty`, no native builds. |\n| **Zero configuration** | One install command. No config file. No env vars. |\n\n## Platform support\n\n| Platform | Playback | Fallback | Notes |\n|---|---|---|---|\n| **macOS** | `afplay ~/.claude/claude-voice-cue.aiff` | — | Audio pre-generated at install via `say -r 220 -o`. Fastest path. |\n| **Linux** | `node bin/cue.js` → `espeak \"Input needed\"` | terminal bell (`\\a`) | Install `espeak` for actual speech: `sudo apt install espeak`. |\n| **Windows** | `node bin/cue.js` → PowerShell SAPI | terminal bell | `System.Speech.Synthesis.SpeechSynthesizer`. |\n\nThe `bin/cue.js` fallback adds ~100ms of Node startup plus the TTS\nbackend's own cold-start cost. Only macOS currently gets the\npre-generated audio path; extending it to Linux (`espeak -w` + `aplay`)\nand Windows (`Add-Type SAPI` to a cached `.wav` + `Start-Process`) is\nstraightforward and tracked as follow-up work.\n\n## Architecture\n\n```\n.claude-plugin/\n  plugin.json           plugin manifest\n  marketplace.json      marketplace listing (so this repo is self-serving)\nhooks/\n  hooks.json            PermissionRequest + Notification registrations\nscripts/\n  cue.js                plugin launcher — afplay on macOS, else TTS fallback\nassets/\n  input-needed.aiff     pre-generated audio shipped with the plugin\nbin/\n  claude-voice-cue.js   user-facing CLI (Option B): status/install/uninstall/test\n  cue.js                CLI hook entry point (fallback for non-macOS)\nsrc/\n  installer.js          settings.json merge, backup, atomic write, idempotency\n  notifier.js           platform TTS dispatch: say | espeak | SAPI | bell\ntest/\n  installer.test.js     13 zero-dep test cases for install/uninstall lifecycle\n  notifier.test.js      3 cases stubbing child_process.spawn\n```\n\nEach module has a single responsibility and is under ~200 lines. There\nis no plugin system, no configuration layer, and no abstraction beyond\nwhat the problem requires. See [ARCHITECTURE.md](ARCHITECTURE.md) for\nthe full design rationale, including why the original PTY wrapper\napproach was thrown away.\n\n## CLI reference\n\n```\nclaude-voice-cue             show install status and registered events\nclaude-voice-cue install     add our hooks to ~/.claude/settings.json\nclaude-voice-cue uninstall   remove our hooks, leave everything else alone\nclaude-voice-cue test        play the cue once (verifies audio works)\nclaude-voice-cue --help      usage\n```\n\n## Running the tests\n\n```sh\nnpm test\n```\n\nThe full suite runs in <1s, has zero dependencies, and exercises every\nlifecycle branch of the installer (fresh install, re-install, upgrade\nfrom stale paths, malformed JSON refusal, unrelated-hook preservation,\nempty-hooks cleanup) plus the platform-dispatch logic in the notifier.\n\n## Uninstall\n\n```sh\nnode bin/claude-voice-cue.js uninstall\n```\n\nRemoves only our entries from `PermissionRequest` and `Notification`,\ndrops the cached audio file, and leaves every other hook in\n`~/.claude/settings.json` untouched. A timestamped backup of the file\nis written before any change is made.\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). Bug reports and feature requests\nuse the templates under `.github/ISSUE_TEMPLATE/`. The scope of this\nproject is intentionally narrow; contributions that extend the fast\npath to additional platforms, improve safety of the settings merge, or\ntighten the test suite are especially welcome.\n\n## License\n\n[MIT](LICENSE) © Arpan Korat\n\n---\n\nBuilt by [Arpan Korat](https://github.com/arpan-k09).\n",
  "bytes": 7728,
  "sha": "0b6d331c6ebd3ff8fbd23eb8b602488bcded7e4d6aa8f04477d651917df206fd",
  "repo_slug": "arpan-k09/claude-voice-cue",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_arpan_k09_claude_voice_cue_claude_voice__59198e0d/readme"
}