An open API service indexing awesome lists of open source software.

https://github.com/chanmeng666/claude-code-audio-hooks

【Stars make the code shine brighter!β­οΈγ€‘πŸ”Š Audio notification system for Claude Code that plays sound alerts when Claude finishes responding. Perfect for multitasking!
https://github.com/chanmeng666/claude-code-audio-hooks

audio-notifications automation bash claude-code cli-tools developer-tools hooks notification-system productivity wsl

Last synced: 24 days ago
JSON representation

【Stars make the code shine brighter!β­οΈγ€‘πŸ”Š Audio notification system for Claude Code that plays sound alerts when Claude finishes responding. Perfect for multitasking!

Awesome Lists containing this project

README

          


[![Project Banner](./public/claude-code-audio-hooks-logo.svg)](#)

# Claude Code Audio Hooks

**AI-operated audio notification system for Claude Code & Cursor IDE.**

You type one slash command at install time. Then natural language forever.

26 hook events, 2 audio themes, rate-limit alerts, webhooks, TTS, context monitor β€” all operated by Claude Code on your behalf.

**πŸ†• 5.1.5 β€” Painless upgrades.** Existing users never lose config across upgrades. New `audio-hooks upgrade` wraps `claude plugin update` / `uninstall + install` with `--keep-data` automatically; auto-migration preserves your settings when new keys are added in future versions; dual-location backups survive even rough `claude plugin uninstall`. Run it any time you want to refresh the plugin code Cursor's bridge invokes. See [CHANGELOG](./CHANGELOG.md#515---2026-05-01).

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Version](https://img.shields.io/badge/version-5.1.5-blue.svg)](https://github.com/ChanMeng666/claude-code-audio-hooks)
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-green.svg)](https://github.com/ChanMeng666/claude-code-audio-hooks)
[![Claude Code](https://img.shields.io/badge/Claude_Code-v2.1.80%2B-brightgreen.svg)](https://claude.ai/download)
[![Plugin](https://img.shields.io/badge/install-just_talk_to_Claude-purple.svg)](#-install-in-60-seconds)

**Share This Project**

[![][share-x-shield]][share-x-link]
[![][share-linkedin-shield]][share-linkedin-link]
[![][share-reddit-shield]][share-reddit-link]
[![][share-telegram-shield]][share-telegram-link]
[![][share-whatsapp-shield]][share-whatsapp-link]

---

### Promotional Video

https://github.com/user-attachments/assets/3504d214-efac-4e01-84c0-426430b842d6

Built with Remotion, Claude Code, ElevenLabs & Suno. Source: claude-code-audio-hooks-promo-video

Table of Contents

- [What's New in v5.0](#-whats-new-in-v50)
- [Install in 60 Seconds](#-install-in-60-seconds)
- [Just Say It β€” Natural Language Control](#-just-say-it--natural-language-control)
- [How It Works](#-how-it-works)
- [Key Features](#-key-features)
- [Technical Reference](#-technical-reference)
- [Platform Support](#-platform-support)
- [Troubleshooting](#-troubleshooting)
- [Uninstall](#-uninstall)
- [For Developers](#-for-developers)
- [Documentation](#-documentation)
- [Contributing](#-contributing)
- [License](#-license)
- [Author](#-author)

---

## What's New in v5.0

v5.0 β€” AI-first redesign (click to expand)

v5.0 is an **AI-first redesign**. Every project surface is now machine-operable end-to-end so Claude Code can install, configure, snooze, troubleshoot, and upgrade the project on a human's behalf without any clicks, prompts, or doc reading.

| Highlight | Effect |
|---|---|
| **`audio-hooks` JSON CLI** | Single binary with 27 subcommands. JSON to stdout, stable error codes + suggested commands. |
| **`/audio-hooks` SKILL** | Natural-language activation: "snooze audio for an hour" β€” Claude runs it for you. |
| **NDJSON structured logging** | Schema `audio-hooks.v1` with stable error code enums. |
| **Plugin-native install** | Two commands and you're done. |
| **4 new hook events** | `PermissionDenied`, `CwdChanged`, `FileChanged`, `TaskCreated` β€” 26 total. |
| **Native matcher routing** | `hooks.json` registers per-matcher handlers with unique audio per variant. |
| **Rate-limit alerts** | One-shot warning at 80%/95% of your 5h or 7d quota. |
| **TTS speak Claude's reply** | Instead of "Task completed", TTS speaks Claude's actual final message. |
| **Status line with context monitor** | Color-coded Context and API Quota bars with `/compact` reminders. |
| **ElevenLabs audio generator** | One-line manifest edit + one-command rebuild for new audio. |

### v5.0 in Action





Plugin Installed

Plugin Installed β€” 26 hooks registered


SKILL Registration

/audio-hooks SKILL active




Status Line

Context monitor status line


Marketplace

Marketplace registration



See [`CHANGELOG.md`](CHANGELOG.md) for full details.

---

## Install in 60 Seconds

**For 99% of operations, you just talk to Claude Code in plain English.** The exception is the one-time install: `/reload-plugins` has no CLI equivalent, so the human types it exactly once. Everything else β€” configure, snooze, theme, webhook, troubleshoot, uninstall β€” is pure natural language.

### Step 1 β€” Open Claude Code

```bash
claude
```

### Step 2 β€” Install with one prompt

Paste this into Claude Code:

> **Please install the audio-hooks plugin from `github.com/ChanMeng666/claude-code-audio-hooks`. Use the Bash tool to run `claude plugin marketplace add ChanMeng666/claude-code-audio-hooks` then `claude plugin install audio-hooks@chanmeng-audio-hooks`. After both commands complete, tell me to type `/reload-plugins` to activate the plugin.**

### Step 3 β€” Type `/reload-plugins` (the one manual slash command)

```text
/reload-plugins
```

### Step 4 β€” Verify and configure with one prompt

> **Verify audio-hooks works by running `audio-hooks diagnose` and `audio-hooks test all`. Then switch to the chime audio theme.**

**Total:** 1 shell command + 2 natural-language prompts + 1 slash command = **4 things**. From here on: natural language forever.

Install flow diagram

```mermaid
sequenceDiagram
participant Human
participant Terminal
participant Claude as Claude Code
participant Bash as Bash tool
participant Skill as /audio-hooks SKILL
participant CLI as audio-hooks CLI

Human->>Terminal: type `claude` to start a session
Human->>Claude: "install audio-hooks plugin from
github.com/ChanMeng666/claude-code-audio-hooks via
`claude plugin marketplace add` and `claude plugin install`"
Claude->>Bash: claude plugin marketplace add ChanMeng666/claude-code-audio-hooks
Bash-->>Claude: "Successfully added marketplace"
Claude->>Bash: claude plugin install audio-hooks@chanmeng-audio-hooks
Bash-->>Claude: "Installed audio-hooks. Run /reload-plugins to apply."
Claude-->>Human: "Plugin installed.
Type /reload-plugins to activate it."

rect rgb(255, 230, 200)
Note over Human: The one manual slash command in the whole flow
Human->>Claude: /reload-plugins
Claude-->>Human: "Reloaded: 8 plugins, 37 hooks, 5 skills"
end

Human->>Claude: "verify audio-hooks works and switch to chime audio"
Claude->>Skill: SKILL activates on intent
Claude->>Bash: audio-hooks diagnose
Bash-->>Claude: {"ok":true,"errors":[],"warnings":[]}
Claude->>Bash: audio-hooks test all
Bash-->>Claude: {"ok":true,"passed":6,"failed":0}
Claude->>Bash: audio-hooks theme set custom
Bash-->>Claude: {"ok":true,"theme":"custom"}
Claude-->>Human: "Done. 26 hooks active, all tests passed,
audio theme set to chimes."

Note over Human,CLI: From here on: pure natural language forever.
```

---

## Just Say It β€” Natural Language Control

Once installed, you operate the project the same way β€” just talk to Claude Code. Every configuration is a single message:

```mermaid
sequenceDiagram
actor You as You
participant CC as Claude Code

rect rgb(219, 234, 254)
Note over You,CC: Audio Theme
You->>CC: Switch audio-hooks to the chime theme.
CC-->>You: audio-hooks theme set custom β€” switched to chimes.
You->>CC: Switch audio-hooks to the voice theme.
CC-->>You: audio-hooks theme set default β€” switched to ElevenLabs Jessica.
end

rect rgb(220, 252, 231)
Note over You,CC: Snooze & Mute
You->>CC: Snooze audio for 30 minutes.
CC-->>You: audio-hooks snooze 30m β€” muted until 3:45 PM.
You->>CC: Snooze audio for 8 hours.
CC-->>You: audio-hooks snooze 8h β€” quiet for the rest of the day.
You->>CC: Unmute audio.
CC-->>You: audio-hooks snooze off β€” audio resumed.
You->>CC: Is audio currently muted?
CC-->>You: audio-hooks snooze status β€” not snoozed.
end

rect rgb(254, 243, 199)
Note over You,CC: Hook Selection & Notification Mode
You->>CC: Configure audio-hooks to only fire on stop,
notification, and permission_request β€”
disable everything else.
CC-->>You: audio-hooks hooks enable-only stop notification
permission_request β€” 3 hooks active, rest disabled.
You->>CC: Enable session_start and session_end hooks
so I hear when sessions begin and end.
CC-->>You: session_start and session_end enabled.
You->>CC: Switch audio-hooks to audio-only mode,
no desktop popups.
CC-->>You: Notification mode set to audio_only.
You->>CC: Switch to notification-only mode β€”
desktop popups but no audio.
CC-->>You: Notification mode set to notification_only.
You->>CC: For the stop hook only, use desktop
notification without audio.
CC-->>You: Per-hook override: stop β†’ notification_only.
You->>CC: Make notifications more detailed.
CC-->>You: Detail level set to verbose.
end
```

```mermaid
sequenceDiagram
actor You as You
participant CC as Claude Code

rect rgb(237, 233, 254)
Note over You,CC: Webhooks & Integrations
You->>CC: Send audio-hooks alerts to my Slack webhook
at https://hooks.slack.com/services/... and test it.
CC-->>You: Webhook set to slack format. Test delivered.
You->>CC: Send alerts to my Discord webhook instead.
CC-->>You: Webhook set to discord format. Test delivered.
You->>CC: Send alerts to ntfy at
https://ntfy.sh/my-channel. Test it.
CC-->>You: Webhook set to ntfy format. Test delivered.
You->>CC: Only send stop and stop_failure events
to the webhook, nothing else.
CC-->>You: Webhook hook_types set to [stop, stop_failure].
end

rect rgb(254, 226, 226)
Note over You,CC: TTS & Rate Limits
You->>CC: Enable audio-hooks TTS and have it speak
Claude's actual final message instead of
a generic announcement.
CC-->>You: TTS enabled with speak_assistant_message = true.
You->>CC: Set the stop hook TTS message to
"Build finished" instead of the default.
CC-->>You: Custom TTS message for stop set.
You->>CC: Make sure audio-hooks rate-limit alerts are
enabled with 80% and 95% thresholds for both
5-hour and 7-day windows.
CC-->>You: Rate-limit alerts on β€” 80%, 95% for both windows.
end

rect rgb(207, 250, 254)
Note over You,CC: Status Line & Context Monitor
You->>CC: Install the audio-hooks status line
in my Claude Code settings.
CC-->>You: audio-hooks statusline install β€” restart to see it.
You->>CC: Configure the status line to only show
context usage.
CC-->>You: Visible segments set to [context].
You->>CC: Show only context and API quota
in the status line.
CC-->>You: Visible segments set to [context, api_quota].
You->>CC: Reset the status line to show all segments.
CC-->>You: Visible segments reset to all.
end

rect rgb(232, 245, 233)
Note over You,CC: Focus Flow
You->>CC: Enable the audio-hooks focus flow
with breathing exercises.
CC-->>You: Focus flow enabled β€” 4-7-8 breathing.
You->>CC: Switch focus flow to hydration reminders.
CC-->>You: Focus flow mode set to hydration.
You->>CC: Only show focus flow if Claude thinks
for more than 30 seconds.
CC-->>You: min_thinking_seconds set to 30.
end

rect rgb(229, 231, 235)
Note over You,CC: Monitor, Debug & Uninstall
You->>CC: Enable the audio-hooks file_changed hook and
configure it to watch .env and .envrc.
CC-->>You: file_changed enabled, watching [.env, .envrc].
You->>CC: Test all my audio-hooks hooks and tell me
if any failed.
CC-->>You: audio-hooks test all β€” 26/26 passed.
You->>CC: What's the current state of audio-hooks?
CC-->>You: audio-hooks status β€” theme: default,
18 hooks enabled, 0 errors.
You->>CC: Show me the last 20 errors and clear the log.
CC-->>You: 2 errors found (WEBHOOK_TIMEOUT). Log cleared.
You->>CC: What version of audio-hooks am I running?
CC-->>You: v5.1.3, plugin install.
You->>CC: Please uninstall audio-hooks completely.
CC-->>You: Plugin uninstalled. All hooks removed.
end
```

Each prompt is one message. Claude Code parses it, runs the right subcommand(s), and reports back. **You don't memorise anything.**

Plain-text prompt reference β€” copy-friendly table

| Goal | Paste this into Claude Code |
|---|---|
| **Audio Theme** | |
| Switch to chime sounds | *"Switch audio-hooks to the chime theme."* |
| Switch to voice sounds | *"Switch audio-hooks to the voice theme."* |
| **Snooze & Mute** | |
| Mute for 30 minutes | *"Snooze audio for 30 minutes."* |
| Mute for the rest of the day | *"Snooze audio for 8 hours."* |
| Unmute | *"Unmute audio."* |
| Check mute status | *"Is audio-hooks currently muted?"* |
| **Hook Selection** | |
| Only keep critical alerts | *"Only fire audio-hooks on stop, notification, and permission_request. Disable everything else."* |
| Enable session start/end sounds | *"Enable the session_start and session_end hooks."* |
| Enable tool execution sounds | *"Enable pretooluse and posttooluse audio."* |
| **Notification Mode** | |
| Audio only, no desktop popups | *"Switch audio-hooks to audio-only mode."* |
| Desktop popups only, no audio | *"Switch audio-hooks to notification-only mode."* |
| Per-hook override | *"For the stop hook, use desktop notification without audio."* |
| Make notifications verbose | *"Make audio-hooks notifications more detailed."* |
| Disable all notifications | *"Disable all audio-hooks notifications entirely."* |
| **Focus Flow** | |
| Breathing exercises | *"Enable the audio-hooks focus flow with breathing exercises."* |
| Hydration reminders | *"Switch audio-hooks focus flow to hydration reminders."* |
| Custom URL during thinking | *"Set audio-hooks focus flow to open `https://example.com` during thinking."* |
| Longer thinking delay | *"Only show focus flow if Claude thinks for more than 30 seconds."* |
| **Webhooks** | |
| Send alerts to Slack | *"Send audio-hooks alerts to my Slack webhook at `https://hooks.slack.com/services/...` and test it."* |
| Send alerts to Discord | *"Send audio-hooks alerts to my Discord webhook at `https://discord.com/api/webhooks/...` and test it."* |
| Send alerts to Teams | *"Send audio-hooks alerts to my Teams webhook. Test it."* |
| Send alerts to ntfy | *"Send audio-hooks alerts to `https://ntfy.sh/my-topic` in ntfy format. Test it."* |
| Only webhook certain events | *"Only send stop and stop_failure events to the webhook."* |
| Disable webhook | *"Disable the audio-hooks webhook."* |
| **TTS (Text-to-Speech)** | |
| Speak Claude's reply out loud | *"Enable audio-hooks TTS and speak Claude's actual final message."* |
| Custom TTS message for a hook | *"Set the audio-hooks stop TTS message to 'Build finished'."* |
| Limit spoken message length | *"Limit audio-hooks TTS to 300 characters."* |
| **Rate-limit Alerts** | |
| Enable with custom thresholds | *"Enable audio-hooks rate-limit alerts at 80% and 95% for both windows."* |
| Adjust 5-hour thresholds | *"Set audio-hooks 5-hour rate-limit thresholds to 75% and 90%."* |
| **Status Line** | |
| Add a status bar | *"Install the audio-hooks status line."* |
| Status bar: context only | *"Only show context usage in the audio-hooks status line."* |
| Status bar: context + API quota | *"Show context and API quota in the audio-hooks status line."* |
| Status bar: show everything | *"Reset the audio-hooks status line to show all segments."* |
| Remove status bar | *"Uninstall the audio-hooks status line."* |
| **File Watching** | |
| Watch .env for changes | *"Enable the audio-hooks file_changed hook and watch `.env` and `.envrc`."* |
| **Monitor & Debug** | |
| Test all hooks | *"Test all audio-hooks and tell me if any failed."* |
| Show current state | *"Show the current audio-hooks status β€” enabled hooks, theme, and recent errors."* |
| Why no sound? | *"Audio-hooks isn't playing sounds. Diagnose and fix it."* |
| Show recent errors | *"Show me the last 20 audio-hooks errors."* |
| Clear the log | *"Clear the audio-hooks event log."* |
| Check version | *"What version of audio-hooks am I running?"* |
| Adjust debounce timing | *"Set audio-hooks debounce to 1000ms."* |
| **Uninstall** | |
| Uninstall | *"Please uninstall audio-hooks completely."* |

---

## How It Works

```mermaid
flowchart LR
CC[Claude Code event] -->|stdin JSON| MR{native matcher
routing}
MR -->|session_start_resume| HR[hook_runner.py]
MR -->|stop_failure_rate_limit| HR
MR -->|notification_idle_prompt| HR
MR -->|...| HR

HR -->|reads| RL[rate-limit pre-check
marker debounce]
HR -->|reads| CFG[user_preferences.json]
HR -->|reads| MARK[snooze + focus-flow markers]

HR -->|fires| AUDIO[Audio playback
26 MP3s, 2 themes]
HR -->|fires| NOTIF[Desktop notification]
HR -->|fires| TTS[TTS announcement]
HR -->|fires| WH[Webhook subprocess
fire-and-forget]
HR -->|writes| LOG[(NDJSON event log
schema audio-hooks.v1)]

style CC fill:#4A90E2,color:#fff
style HR fill:#7ED321,color:#000
style RL fill:#F5A623,color:#000
style AUDIO fill:#F5A623,color:#000
style WH fill:#9013FE,color:#fff
style LOG fill:#50E3C2,color:#000
```

Claude Code fires hook events as JSON on stdin. Native matchers in `hooks.json` route each event to `hook_runner.py` with a synthetic event name. The runner checks snooze state, rate-limit thresholds, debounce, and user filters β€” then fires audio playback, desktop notifications, TTS, and webhooks as configured.

Β Β AI Control Surface

```mermaid
flowchart TB
USER[Human] -->|natural language| CLAUDE[Claude Code]
CLAUDE -->|activates| SKILL[/audio-hooks SKILL/]
SKILL -->|invokes via Bash tool| BIN[bin/audio-hooks]

BIN -->|reads| CONFIG[(user_preferences.json
in plugin data dir)]
BIN -->|reads| MARKERS[(snooze + focus-flow markers)]
BIN -->|reads| LOGS[(NDJSON event log)]
BIN -->|writes| CONFIG
BIN -->|writes| MARKERS

BIN -->|invokes| HR[hook_runner.run_hook
for `audio-hooks test`]

BIN -->|JSON to stdout| CLAUDE
CLAUDE -->|reports back| USER

style USER fill:#4A90E2,color:#fff
style CLAUDE fill:#9013FE,color:#fff
style SKILL fill:#7ED321,color:#000
style BIN fill:#F5A623,color:#000
```

Β Β Hook Lifecycle

```mermaid
flowchart TD
EVT[Hook event fires
e.g. Stop] --> SNOOZE{snooze
active?}
SNOOZE -->|yes| EXIT0[exit 0 silent]
SNOOZE -->|no| RL{rate_limits
in stdin?}
RL -->|yes| RLCHK{crossed
threshold?}
RLCHK -->|yes| RLAUDIO[play warning audio
+ write debounce marker]
RLCHK -->|no| DEB
RL -->|no| DEB{debounced
recently?}
RLAUDIO --> DEB
DEB -->|yes| EXIT0
DEB -->|no| FILTER{user filter
matches?}
FILTER -->|yes, exclude| EXIT0
FILTER -->|no| ENABLED{hook
enabled?}
ENABLED -->|no| EXIT0
ENABLED -->|yes| FIRE[play audio + notif + TTS + webhook]
FIRE --> LOG[write NDJSON event]

style EVT fill:#4A90E2,color:#fff
style FIRE fill:#7ED321,color:#000
style RLAUDIO fill:#F5A623,color:#000
style EXIT0 fill:#999,color:#fff
```

Β Β Plugin Layout

```mermaid
flowchart TB
REPO[claude-code-audio-hooks/]

REPO --> CP[.claude-plugin/marketplace.json]
REPO --> PLUGINS[plugins/audio-hooks/]
REPO --> CANON[CANONICAL SOURCE]

PLUGINS --> P_MANIFEST[.claude-plugin/plugin.json]
PLUGINS --> P_HOOKS[hooks/hooks.json
matcher-scoped]
PLUGINS --> P_RUNNER[runner/run.py]
PLUGINS --> P_SKILL[skills/audio-hooks/SKILL.md]
PLUGINS --> P_BIN[bin/ β€” audio-hooks + statusline]
PLUGINS --> P_AUDIO[audio/ β€” bundled MP3s]
PLUGINS --> P_CONFIG[config/default_preferences.json]

CANON --> C_HOOKS[hooks/hook_runner.py]
CANON --> C_BIN[bin/audio-hooks + audio-hooks.py + .cmd]
CANON --> C_AUDIO[audio/default + audio/custom]
CANON --> C_CONFIG[config/]
CANON --> C_SCRIPTS[scripts/ β€” install + build-plugin + uninstall]

C_HOOKS -.->|build-plugin.sh syncs| P_HOOKS
C_BIN -.->|build-plugin.sh syncs| P_BIN
C_AUDIO -.->|build-plugin.sh syncs| P_AUDIO

style REPO fill:#4A90E2,color:#fff
style PLUGINS fill:#7ED321,color:#000
style CANON fill:#F5A623,color:#000
```

---

## Key Features

### Status Line with Context Monitor

Real-time context window and API quota bars β€” color-coded warnings before Claude enters the "agent dumb zone".


Status Line β€” context window monitor

```text
[Opus] Audio Hooks v5.1.3 | 6/26 Sounds | Webhook: ntfy | Theme: Voice
[MUTED 23m] feat/audio-v5 API Quota: 78% Context: 65% (130K/200K) /compact
```

| Color | Range | Meaning | Action |
|---|---|---|---|
| Green | < 50% | Safe β€” agent performs well | Keep working |
| Yellow | 50-80% | Caution β€” entering the "dumb zone" | Type `/compact` or `/clear` |
| Red | > 80% | Danger β€” agent makes frequent errors | Type `/compact` immediately |

**Absolute counts (v5.1.3+).** When Claude Code reports the context window size, the segment also shows current/max tokens, e.g. `Context: 83% (166K/200K)`. This makes the math obvious when you `/model`-switch between context-window variants β€” switching from Opus 4.7 (1M) to Sonnet 4.6 (200K) keeps your tokens identical but shrinks the denominator 5Γ—, so a sudden jump from `17%` to `83%` is **expected**, not a bug. See `docs/TROUBLESHOOTING.md#context-97-or-any-sudden-jump-right-after-switching-models` for the full explanation.

10 customisable segments

| Segment | Shows |
|---|---|
| `model` | Model name (e.g. `[Opus]`) |
| `version` | Audio Hooks version |
| `sounds` | Enabled sound count |
| `webhook` | Webhook status |
| `theme` | Audio theme |
| `snooze` | Mute countdown (when active) |
| `focus` | Focus Flow mode (when active) |
| `branch` | Git branch name |
| `api_quota` | API usage quota bar |
| `context` | Context window usage bar |

### Audio Themes

| Theme | Style | Source |
|---|---|---|
| `default` | ElevenLabs **Jessica** voice β€” short spoken phrases like *"Task completed"* | `audio/default/*.mp3` |
| `custom` | Modern UI sound effects (chimes, beeps) | `audio/custom/chime-*.mp3` |

Say *"switch to chimes"* or *"switch to voice"* β€” Claude Code handles the rest.

### 26 Hook Events

26 events covering the full Claude Code lifecycle β€” from session start to file changes, permission requests to rate-limit warnings. 6 are enabled by default; toggle any with natural language.

Full hook events table

| Hook | Default | Audio file | Native matchers |
|---|:-:|---|---|
| `notification` | on | notification-urgent.mp3 | `permission_prompt` / `idle_prompt` / `auth_success` / `elicitation_dialog` |
| `stop` | on | task-complete.mp3 | |
| `subagent_stop` | on | subagent-complete.mp3 | agent type |
| `permission_request` | on | permission-request.mp3 | tool name |
| `permission_denied` | on | permission-denied.mp3 | |
| `task_created` | on | task-created.mp3 | |
| `task_completed` | | team-task-done.mp3 | |
| `session_start` | | session-start.mp3 | `startup` / `resume` / `clear` / `compact` |
| `session_end` | | session-end.mp3 | `clear` / `resume` / `logout` / `prompt_input_exit` |
| `pretooluse` | | task-starting.mp3 | tool name |
| `posttooluse` | | task-progress.mp3 | tool name |
| `posttoolusefailure` | | tool-failed.mp3 | tool name |
| `userpromptsubmit` | | prompt-received.mp3 | |
| `subagent_start` | | subagent-start.mp3 | agent type |
| `precompact` / `postcompact` | | notification-info.mp3 / post-compact.mp3 | `manual` / `auto` |
| `stop_failure` | | stop-failure.mp3 | `rate_limit` / `authentication_failed` / `billing_error` / `server_error` / `unknown` |
| `teammate_idle` | | teammate-idle.mp3 | |
| `config_change` | | config-change.mp3 | |
| `instructions_loaded` | | instructions-loaded.mp3 | |
| `worktree_create` / `worktree_remove` | | worktree-create.mp3 / worktree-remove.mp3 | |
| `elicitation` / `elicitation_result` | | elicitation.mp3 / elicitation-result.mp3 | |
| `cwd_changed` | | cwd-changed.mp3 | |
| `file_changed` | | file-changed.mp3 | literal filenames |

### Webhooks

Fan out hook events to Slack, Discord, Teams, ntfy, or any HTTP endpoint. Versioned `audio-hooks.webhook.v1` payload. Fire-and-forget via subprocess β€” never blocks the hook. Say *"send alerts to my Slack"* and Claude Code sets it up.

### Rate-limit Alerts

Watches every hook's stdin for `rate_limits` and plays a one-shot warning at configurable thresholds (default 80%/95%). Each `(window, threshold, resets_at)` fires exactly once β€” warned at 80%, again at 95%, never spammed.

### TTS β€” Speak Claude's Reply

Instead of a static "Task completed", TTS speaks Claude's actual final message (truncated to 200 chars). Off by default β€” privacy-conscious. Say *"speak Claude's actual reply when done"* to enable.

### Focus Flow

Anti-distraction micro-task during Claude's thinking time: guided breathing exercise, hydration reminder, custom URL, or shell command. Auto-closes when Claude finishes. Say *"enable focus flow with breathing exercises"*.

---

## Technical Reference

CLI, configuration, environment variables, error codes, logging, manual install (click to expand)

### `audio-hooks` CLI

Single Python binary on PATH. JSON output, no prompts, no spinners.

| Subcommand | Purpose |
|---|---|
| `audio-hooks manifest` | Canonical introspection β€” every subcommand, hook, config key, error code, env var |
| `audio-hooks manifest --schema` | JSON Schema for `user_preferences.json` |
| `audio-hooks status` | Full state snapshot |
| `audio-hooks version` | Version + install mode detection |
| `audio-hooks get ` | Read any config key |
| `audio-hooks set ` | Write any config key (auto-coerces) |
| `audio-hooks hooks list` | All 26 hooks with current state |
| `audio-hooks hooks enable/disable ` | Toggle a hook |
| `audio-hooks hooks enable-only ` | Exclusive enable |
| `audio-hooks theme list/set ` | Audio theme |
| `audio-hooks snooze [duration]/off/status` | Mute hooks (default 30m) |
| `audio-hooks webhook/set/clear/test` | Webhook config + test |
| `audio-hooks tts set ...` | TTS config |
| `audio-hooks rate-limits set ...` | Rate-limit alert thresholds |
| `audio-hooks test ` | Smoke-test hooks |
| `audio-hooks diagnose` | System check |
| `audio-hooks logs tail/clear` | NDJSON event log |
| `audio-hooks install/uninstall` | Non-interactive install/uninstall |
| `audio-hooks statusline show/install/uninstall` | Status line management |

### Configuration Keys

| Key | Type | Default | Effect |
|---|---|---|---|
| `audio_theme` | `default` \| `custom` | `default` | Voice recordings vs chimes |
| `enabled_hooks.` | bool | varies | Per-hook toggle |
| `playback_settings.debounce_ms` | int | 500 | Min ms between same hook firing |
| `notification_settings.mode` | enum | `audio_and_notification` | `audio_only` / `notification_only` / `audio_and_notification` / `disabled` |
| `notification_settings.detail_level` | enum | `standard` | `minimal` / `standard` / `verbose` |
| `webhook_settings.enabled` | bool | `false` | Webhook fan-out |
| `webhook_settings.url` | string | `""` | Target URL |
| `webhook_settings.format` | enum | `raw` | `slack` / `discord` / `teams` / `ntfy` / `raw` |
| `webhook_settings.hook_types` | array | `["stop","notification",...]` | Which hooks fire the webhook |
| `tts_settings.enabled` | bool | `false` | TTS announcements |
| `tts_settings.speak_assistant_message` | bool | `false` | TTS Claude's actual reply on stop |
| `tts_settings.assistant_message_max_chars` | int | 200 | Truncation cap |
| `rate_limit_alerts.enabled` | bool | `true` | Watch stdin rate_limits |
| `rate_limit_alerts.five_hour_thresholds` | int[] | `[80, 95]` | 5h window thresholds |
| `rate_limit_alerts.seven_day_thresholds` | int[] | `[80, 95]` | 7d window thresholds |
| `focus_flow.enabled` / `mode` / `min_thinking_seconds` / `breathing_pattern` | mixed | off / `breathing` / 15 / `4-7-8` | Anti-distraction micro-task |
| `statusline_settings.visible_segments` | string[] | `[]` (all) | Status line segments to show |

### Environment Variables

| Variable | Purpose |
|---|---|
| `CLAUDE_PLUGIN_DATA` | Plugin install state directory (auto-set by Claude Code) |
| `CLAUDE_PLUGIN_ROOT` | Plugin install root (auto-set) |
| `CLAUDE_AUDIO_HOOKS_DATA` | Explicit override for state directory |
| `CLAUDE_AUDIO_HOOKS_PROJECT` | Explicit override for project root |
| `CLAUDE_HOOKS_DEBUG` | `1` to write debug-level events to NDJSON log |
| `CLAUDE_NONINTERACTIVE` | `1` to force scripts into non-interactive mode |
| `ELEVENLABS_API_KEY` | Used by `scripts/generate-audio.py` (never logged) |

### Stable Error Codes

| Code | When | Suggested fix |
|---|---|---|
| `AUDIO_FILE_MISSING` | Audio file doesn't exist | `audio-hooks diagnose` |
| `AUDIO_PLAYER_NOT_FOUND` | No audio player binary | `audio-hooks diagnose` |
| `AUDIO_PLAY_FAILED` | Player exited with error | `audio-hooks test` |
| `INVALID_CONFIG` | `user_preferences.json` malformed | `audio-hooks manifest --schema` |
| `CONFIG_READ_ERROR` | Can't read config | `audio-hooks status` |
| `WEBHOOK_HTTP_ERROR` | Webhook returned non-2xx | `audio-hooks webhook test` |
| `WEBHOOK_TIMEOUT` | Webhook timed out | `audio-hooks webhook test` |
| `NOTIFICATION_FAILED` | Desktop notification failed | `audio-hooks diagnose` |
| `TTS_FAILED` | TTS engine failed | `audio-hooks tts set --enabled false` |
| `SETTINGS_DISABLE_ALL_HOOKS` | `disableAllHooks: true` in settings | `audio-hooks diagnose` |
| `DUAL_INSTALL_DETECTED` | Both install methods active | `bash scripts/uninstall.sh --yes` |
| `PROJECT_DIR_NOT_FOUND` | Can't locate project | `audio-hooks status` |
| `UNKNOWN_HOOK_TYPE` | Unrecognised hook name | `audio-hooks hooks list` |
| `INTERNAL_ERROR` | Unexpected error | `audio-hooks logs tail` |

### NDJSON Event Log

Every event is one JSON object per line at `${CLAUDE_PLUGIN_DATA}/logs/events.ndjson`. Schema `audio-hooks.v1`.

```json
{"ts":"2026-04-11T10:23:45.123Z","schema":"audio-hooks.v1","level":"info","hook":"stop","session_id":"abc","action":"play_audio","audio_file":"chime-task-complete.mp3","duration_ms":42}
```

Levels: `debug`, `info`, `warn`, `error`. Log rotation: 5 MB cap, 3 files kept.

### Manual Install Reference

**Plugin install** (two slash commands inside Claude Code):

```text
/plugin marketplace add ChanMeng666/claude-code-audio-hooks
/plugin install audio-hooks@chanmeng-audio-hooks
/reload-plugins
```

**Legacy script install** (pre-v5.0, still works):

```bash
git clone https://github.com/ChanMeng666/claude-code-audio-hooks.git
cd claude-code-audio-hooks
bash scripts/install-complete.sh # auto non-interactive on non-TTY
```

Both paths share the same `hook_runner.py` and `audio-hooks` CLI. They are mutually exclusive β€” `audio-hooks diagnose` reports `DUAL_INSTALL_DETECTED` if both are active.

### ElevenLabs Audio Generator

`scripts/generate-audio.py` reads `config/audio_manifest.json` and regenerates audio via the ElevenLabs API:

```bash
ELEVENLABS_API_KEY=sk_... python scripts/generate-audio.py # generate missing
ELEVENLABS_API_KEY=sk_... python scripts/generate-audio.py --force # regenerate all
python scripts/generate-audio.py --dry-run # preview
```

To add a new audio file: edit `config/audio_manifest.json`, run the generator, then `bash scripts/build-plugin.sh`.

---

## Platform Support

| Platform | Audio player | Status |
|---|---|---|
| **Windows** (PowerShell / Git Bash / WSL2) | PowerShell MediaPlayer | Fully supported |
| **macOS** | `afplay` | Fully supported |
| **Linux** | `mpg123` / `ffplay` / `paplay` / `aplay` (auto-detected) | Fully supported |

Python 3.6+ is the only runtime requirement.

---

## Troubleshooting

Β Β No sound at all

Run `audio-hooks diagnose`, look for any error code, and run its `suggested_command`. Or just say: *"Audio-hooks isn't playing sounds. Diagnose and fix it."*

Β Β Hearing double sounds

Both legacy script install and plugin install are active. Diagnose reports `DUAL_INSTALL_DETECTED`. Fix: `bash scripts/uninstall.sh --yes` (removes legacy, preserves config).

Β Β Plugin won't install

Run `claude plugin validate plugins/audio-hooks` from the project root β€” surfaces manifest schema errors. v5.0.1+ verified clean on Claude Code v2.1.101.

Β Β pretooluse / posttooluse too noisy

They fire on every tool execution (Read, Glob, Grep, etc.) β€” disabled by default for this reason. Enable explicitly with *"enable pretooluse and posttooluse audio"*.

---

## Uninstall

**Plugin install:** say *"uninstall audio-hooks"* or manually:

```text
/plugin uninstall audio-hooks@chanmeng-audio-hooks
```

**Legacy script install:**

```bash
bash scripts/uninstall.sh --yes # preserve config + audio
bash scripts/uninstall.sh --yes --purge # remove everything
```

---

## For Developers

Repository layout, workflow, and contribution guide (click to expand)

### Repository Layout

```
claude-code-audio-hooks/
β”œβ”€β”€ .claude-plugin/marketplace.json
β”œβ”€β”€ plugins/audio-hooks/ # plugin layout (populated by build-plugin.sh)
β”‚ β”œβ”€β”€ .claude-plugin/plugin.json
β”‚ β”œβ”€β”€ hooks/hooks.json
β”‚ β”œβ”€β”€ runner/run.py
β”‚ β”œβ”€β”€ skills/audio-hooks/SKILL.md
β”‚ β”œβ”€β”€ bin/
β”‚ β”œβ”€β”€ audio/
β”‚ └── config/default_preferences.json
β”œβ”€β”€ hooks/hook_runner.py # CANONICAL
β”œβ”€β”€ bin/ # CANONICAL
β”‚ β”œβ”€β”€ audio-hooks / audio-hooks.py / audio-hooks.cmd
β”‚ └── audio-hooks-statusline / .py / .cmd
β”œβ”€β”€ audio/ # CANONICAL: 26 default + 26 custom
β”œβ”€β”€ config/
β”‚ β”œβ”€β”€ default_preferences.json
β”‚ β”œβ”€β”€ user_preferences.schema.json
β”‚ └── audio_manifest.json
β”œβ”€β”€ scripts/
β”‚ β”œβ”€β”€ install-complete.sh / install-windows.ps1
β”‚ β”œβ”€β”€ uninstall.sh / build-plugin.sh
β”‚ β”œβ”€β”€ generate-audio.py
β”‚ └── ...
β”œβ”€β”€ CLAUDE.md
β”œβ”€β”€ README.md
└── CHANGELOG.md
```

### Workflow

1. Edit canonical files (`/hooks/`, `/bin/`, `/audio/`, `/config/`)
2. Run `bash scripts/build-plugin.sh` to sync into plugin layout
3. CI verifies in-sync via `bash scripts/build-plugin.sh --check`
4. Validate: `claude plugin validate plugins/audio-hooks`
5. Test: `python bin/audio-hooks.py test all`

### Contributing

Pull requests welcome. Fork, clone, make changes to canonical files, run `build-plugin.sh`, validate, test end-to-end, and submit with a conventional commit message.

---

## Documentation

| Document | Purpose |
|---|---|
| [**CLAUDE.md**](CLAUDE.md) | Canonical AI-facing operating guide |
| [**CHANGELOG.md**](CHANGELOG.md) | Detailed version history |
| [**docs/ARCHITECTURE.md**](docs/ARCHITECTURE.md) | System architecture details |
| `audio-hooks manifest` | Live source of truth β€” always up to date |

---

**Design Philosophy** β€” This project is **AI-operated**, not AI-assisted. A typical CLI tool: the human learns the tool. **claude-code-audio-hooks**: the human says what they want, Claude Code learns the tool and does the work. The human is **upstream** of Claude Code, not downstream of the CLI.

---

## License

This project is licensed under the **MIT License** β€” see [LICENSE](LICENSE) for details.

- Commercial use allowed
- Modification allowed
- Distribution allowed
- Private use allowed

---

## Author






Chan Meng


Chan Meng



Creator & Lead Developer





GitHub


LinkedIn


Website



Buy Me A Coffee

---

[![][back-to-top]](#readme-top)

[back-to-top]: https://img.shields.io/badge/-BACK_TO_TOP-black?style=flat-square

[share-x-shield]: https://img.shields.io/badge/-Share%20on%20X-black?labelColor=black&logo=x&logoColor=white&style=flat-square
[share-x-link]: https://x.com/intent/tweet?text=Check%20out%20Claude%20Code%20Audio%20Hooks%20-%20AI-operated%20audio%20notifications%20for%20Claude%20Code&url=https%3A%2F%2Fgithub.com%2FChanMeng666%2Fclaude-code-audio-hooks

[share-linkedin-shield]: https://img.shields.io/badge/-Share%20on%20LinkedIn-blue?labelColor=blue&logo=linkedin&logoColor=white&style=flat-square
[share-linkedin-link]: https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fgithub.com%2FChanMeng666%2Fclaude-code-audio-hooks

[share-reddit-shield]: https://img.shields.io/badge/-Share%20on%20Reddit-orange?labelColor=black&logo=reddit&logoColor=white&style=flat-square
[share-reddit-link]: https://www.reddit.com/submit?title=Claude%20Code%20Audio%20Hooks%20-%20AI-operated%20audio%20notifications&url=https%3A%2F%2Fgithub.com%2FChanMeng666%2Fclaude-code-audio-hooks

[share-telegram-shield]: https://img.shields.io/badge/-Share%20on%20Telegram-blue?labelColor=blue&logo=telegram&logoColor=white&style=flat-square
[share-telegram-link]: https://t.me/share/url?text=Claude%20Code%20Audio%20Hooks%20-%20AI-operated%20audio%20notifications&url=https%3A%2F%2Fgithub.com%2FChanMeng666%2Fclaude-code-audio-hooks

[share-whatsapp-shield]: https://img.shields.io/badge/-Share%20on%20WhatsApp-green?labelColor=green&logo=whatsapp&logoColor=white&style=flat-square
[share-whatsapp-link]: https://api.whatsapp.com/send?text=Check%20out%20Claude%20Code%20Audio%20Hooks%20-%20AI-operated%20audio%20notifications%20for%20Claude%20Code%20https%3A%2F%2Fgithub.com%2FChanMeng666%2Fclaude-code-audio-hooks