Skip to content

ChanMeng666/claude-code-audio-hooks

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

101 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Project Banner

Claude Code Audio Hooks

AI-operated audio notification system for Claude Code.
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.

License: MIT Version Platform Claude Code Plugin

Share This Project


Promotional Video

promo-video.mp4

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

Table of Contents

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 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

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)

/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
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<br/>github.com/ChanMeng666/claude-code-audio-hooks via<br/>`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.<br/>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,<br/>audio theme set to chimes."

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

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:

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,<br/>notification, and permission_request β€”<br/>disable everything else.
    CC-->>You: audio-hooks hooks enable-only stop notification<br/>permission_request β€” 3 hooks active, rest disabled.
    You->>CC: Enable session_start and session_end hooks<br/>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,<br/>no desktop popups.
    CC-->>You: Notification mode set to audio_only.
    You->>CC: Switch to notification-only mode β€”<br/>desktop popups but no audio.
    CC-->>You: Notification mode set to notification_only.
    You->>CC: For the stop hook only, use desktop<br/>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
Loading
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<br/>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<br/>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<br/>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<br/>Claude's actual final message instead of<br/>a generic announcement.
    CC-->>You: TTS enabled with speak_assistant_message = true.
    You->>CC: Set the stop hook TTS message to<br/>"Build finished" instead of the default.
    CC-->>You: Custom TTS message for stop set.
    You->>CC: Make sure audio-hooks rate-limit alerts are<br/>enabled with 80% and 95% thresholds for both<br/>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<br/>in my Claude Code settings.
    CC-->>You: audio-hooks statusline install β€” restart to see it.
    You->>CC: Configure the status line to only show<br/>context usage.
    CC-->>You: Visible segments set to [context].
    You->>CC: Show only context and API quota<br/>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<br/>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<br/>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<br/>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<br/>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,<br/>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.1, plugin install.
    You->>CC: Please uninstall audio-hooks completely.
    CC-->>You: Plugin uninstalled. All hooks removed.
    end
Loading

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

flowchart LR
    CC[Claude Code event] -->|stdin JSON| MR{native matcher<br/>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<br/>marker debounce]
    HR -->|reads| CFG[user_preferences.json]
    HR -->|reads| MARK[snooze + focus-flow markers]

    HR -->|fires| AUDIO[Audio playback<br/>26 MP3s, 2 themes]
    HR -->|fires| NOTIF[Desktop notification]
    HR -->|fires| TTS[TTS announcement]
    HR -->|fires| WH[Webhook subprocess<br/>fire-and-forget]
    HR -->|writes| LOG[(NDJSON event log<br/>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
Loading

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
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<br/>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<br/>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
Loading
Β Β Hook Lifecycle
flowchart TD
    EVT[Hook event fires<br/>e.g. Stop] --> SNOOZE{snooze<br/>active?}
    SNOOZE -->|yes| EXIT0[exit 0 silent]
    SNOOZE -->|no| RL{rate_limits<br/>in stdin?}
    RL -->|yes| RLCHK{crossed<br/>threshold?}
    RLCHK -->|yes| RLAUDIO[play warning audio<br/>+ write debounce marker]
    RLCHK -->|no| DEB
    RL -->|no| DEB{debounced<br/>recently?}
    RLAUDIO --> DEB
    DEB -->|yes| EXIT0
    DEB -->|no| FILTER{user filter<br/>matches?}
    FILTER -->|yes, exclude| EXIT0
    FILTER -->|no| ENABLED{hook<br/>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
Loading
Β Β Plugin Layout
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<br/>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
Loading

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

[Opus] Audio Hooks v5.1.1 | 6/26 Sounds | Webhook: ntfy | Theme: Voice
[MUTED 23m]  feat/audio-v5  API Quota: 78%  Context: 65%  /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
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 <dotted.key> Read any config key
audio-hooks set <dotted.key> <value> Write any config key (auto-coerces)
audio-hooks hooks list All 26 hooks with current state
audio-hooks hooks enable/disable <name> Toggle a hook
audio-hooks hooks enable-only <a> <b> Exclusive enable
audio-hooks theme list/set <name> 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 <hook|all> 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.<hook> 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.

{"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):

/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):

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:

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:

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

Legacy script install:

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 Canonical AI-facing operating guide
CHANGELOG.md Detailed version history
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 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


About

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

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors