Skip to content

A lightweight local hook sound router for Codex and Claude Code

Notifications You must be signed in to change notification settings

chaosrun/c-notify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

c-notify

c-notify is a lightweight local hook sound router for Codex and Claude Code. It plays a random audio file from ~/.c-notify/sounds/<tool>/<event>/ when hook events arrive.

Audio files are user-provided. The repository does not bundle sound assets.

简体中文文档: README_ZH.md

Features

  • Tool-specific event namespaces (codex and claude) with independent event sets
  • Random playback from per-event folders
  • Global portable switch: on / off / toggle / status
  • Linux/macOS playback backend support
  • Event folder bootstrap with bilingual README.md per folder
  • Deterministic Codex routing: agent-turn-complete maps directly to task-complete

Quick Start

cd c-notify
chmod +x c-notify c-notify.py
./c-notify init
./c-notify status
./c-notify events

One-Command Install

cd c-notify
chmod +x install.sh
./install.sh

What install.sh does:

  • Installs c-notify to ~/.local/bin/c-notify (symlink)
  • Appends a PATH block to your shell rc file (~/.zshrc for zsh, ~/.bashrc/~/.bash_profile for bash)
  • Writes/updates Codex notify config in ~/.codex/config.toml
  • Writes/updates Claude hooks in ~/.claude/settings.json

Useful flags:

./install.sh --no-codex
./install.sh --no-claude
./install.sh --no-path
./install.sh --bin-dir=/custom/bin

Core categories (Codex):

  • ~/.c-notify/sounds/codex/task-complete/
  • ~/.c-notify/sounds/codex/permission-needed/
  • ~/.c-notify/sounds/codex/task-error/
  • ~/.c-notify/sounds/codex/context-compact/
  • ~/.c-notify/sounds/codex/resource-limit/
  • ~/.c-notify/sounds/codex/session-start/ (optional/manual)

Core categories (Claude):

  • ~/.c-notify/sounds/claude/session-start/
  • ~/.c-notify/sounds/claude/session-end/ (optional)
  • ~/.c-notify/sounds/claude/subagent-start/ (optional)
  • ~/.c-notify/sounds/claude/task-acknowledge/
  • ~/.c-notify/sounds/claude/task-complete/
  • ~/.c-notify/sounds/claude/permission-needed/
  • ~/.c-notify/sounds/claude/task-error/
  • ~/.c-notify/sounds/claude/context-compact/
  • ~/.c-notify/sounds/claude/resource-limit/

Hook Wiring

Codex (~/.codex/config.toml)

notify = ["python3", "/ABSOLUTE/PATH/TO/c-notify/c-notify.py", "hook", "--tool", "codex"]

Notes:

  • Codex notify currently sends agent-turn-complete payloads in normal operation.
  • Codex does not use message-semantic inference; agent-turn-complete always routes to task-complete.
  • Codex task-error / resource-limit / context-compact are explicit/manual categories unless Codex emits native events in the future.
  • approval-requested is kept as a future/manual compatibility alias and maps to permission-needed if such payloads are provided.
  • For real-time approval cues today, use Codex TUI notifications ([tui] notifications = ["approval-requested"]) rather than relying on notify.

Claude Code (~/.claude/settings.json)

Use one command entry for all events:

{
  "hooks": {
    "SessionStart": [
      { "matcher": "", "hooks": [ { "type": "command", "command": "python3 /ABSOLUTE/PATH/TO/c-notify/c-notify.py hook --tool claude", "timeout": 10, "async": true } ] }
    ],
    "SessionEnd": [
      { "matcher": "", "hooks": [ { "type": "command", "command": "python3 /ABSOLUTE/PATH/TO/c-notify/c-notify.py hook --tool claude", "timeout": 10, "async": true } ] }
    ],
    "SubagentStart": [
      { "matcher": "", "hooks": [ { "type": "command", "command": "python3 /ABSOLUTE/PATH/TO/c-notify/c-notify.py hook --tool claude", "timeout": 10, "async": true } ] }
    ],
    "UserPromptSubmit": [
      { "matcher": "", "hooks": [ { "type": "command", "command": "python3 /ABSOLUTE/PATH/TO/c-notify/c-notify.py hook --tool claude", "timeout": 10, "async": true } ] }
    ],
    "Stop": [
      { "matcher": "", "hooks": [ { "type": "command", "command": "python3 /ABSOLUTE/PATH/TO/c-notify/c-notify.py hook --tool claude", "timeout": 10, "async": true } ] }
    ],
    "PermissionRequest": [
      { "matcher": "", "hooks": [ { "type": "command", "command": "python3 /ABSOLUTE/PATH/TO/c-notify/c-notify.py hook --tool claude", "timeout": 10, "async": true } ] }
    ],
    "PostToolUseFailure": [
      { "matcher": "Bash", "hooks": [ { "type": "command", "command": "python3 /ABSOLUTE/PATH/TO/c-notify/c-notify.py hook --tool claude", "timeout": 10, "async": true } ] }
    ],
    "PreCompact": [
      { "matcher": "", "hooks": [ { "type": "command", "command": "python3 /ABSOLUTE/PATH/TO/c-notify/c-notify.py hook --tool claude", "timeout": 10, "async": true } ] }
    ]
  }
}

Notification is intentionally not registered; PermissionRequest is the only permission trigger.

Event Coverage

List current known events:

./c-notify events
./c-notify events --tool codex
./c-notify events --tool claude

Commands

./install.sh
./c-notify init
./c-notify init --refresh-readmes
./c-notify on
./c-notify off
./c-notify toggle
./c-notify status
./c-notify events --tool claude
./c-notify play --tool claude --event task-complete
./c-notify hook --tool codex --debug
./c-notify hook --tool claude --debug

Config

Runtime config path:

  • ~/.c-notify/config.json

Optional override:

  • C_NOTIFY_HOME=/custom/path to relocate config/state/sounds root.
  • C_NOTIFY_INSTALL_HOME=/custom/home to relocate install targets used by install.sh.

Important keys:

  • enabled: master on/off switch
  • sound_root: default ~/.c-notify/sounds
  • volume: playback volume (backend dependent)
  • extensions: allowed audio extensions
  • prevent_overlap: skip new playback while prior process is alive
  • cooldown_seconds and cooldown_by_event: optional throttling
  • hook_strict_exit: default false; when true, hook exits non-zero for unmapped/no-sound outcomes

Platform Support

  • macOS: afplay
  • Linux: pw-play, paplay, ffplay, aplay (fallback order)

Windows support is intentionally out of scope for this first version.

About

A lightweight local hook sound router for Codex and Claude Code

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors