GitHub - theletterf/defensive-hook: Claude Code hook that plays sounds of your choice when you give negative feedback

3 min read Original article ↗

I sometimes long for audio feedback when interacting with Claude, so I've made a Claude Code hook that makes Claude reply to negative feedback with sounds from a folder. You can use any sound you want.

defensive-hook demo

Built as a Stop hook — it fires after every Claude reply, reads the last user message from the session transcript, scores it for negative sentiment, and plays a sound if the score is high enough.

Requirements

  • macOS (uses afplay for playback; falls back to say -v Trinoids if no sound files are present)
  • Python 3.9+
  • Claude Code

Install

git clone https://github.com/theletterf/defensive-hook.git
cd defensive-hook
bash install.sh

The installer:

  1. Copies defensive_hook.py to ~/.claude/
  2. Creates ~/.claude/negative-sounds/ (the sounds folder)
  3. Adds the hook to ~/.claude/settings.json

Add sounds

Drop any .mp3, .wav, or .aiff files into ~/.claude/negative-sounds/. One is picked at random on each trigger.

If the folder is empty, the hook falls back to macOS say -v Trinoids "negative feedback detected".

How it works

Sentiment is scored with a keyword model — no external dependencies, no API calls:

Match type Score
Negative phrase (e.g. "not what i asked") +2
Negative word (e.g. "wrong", "broken") +1

A score ≥ 2 triggers the sound. Single ambiguous words (like "no" alone) don't fire; combinations and phrases do.

Trigger phrases

that's not · not what i · you're wrong · not right · not correct · doesn't work · not working · didn't work · won't work · this is wrong · that is wrong · still wrong · still broken · still not · you missed · you forgot · you're mistaken · that's incorrect · not what i asked · not what i wanted · not what i meant · that's bad · this is bad · that's broken · totally wrong · completely wrong · you lied · you made up · that's garbage · that's trash · makes no sense

Trigger words

wrong · incorrect · mistake · error · bad · terrible · awful · stupid · useless · broken · fail · failed · failure · hate · frustrated · frustrating · ugh · wtf · damn · dammit · crap · nope · disappointed · disappointing · ridiculous · nonsense · garbage · trash · pathetic · hopeless · worse · worst · no · stop · not · don't · didn't · doesn't · isn't · wasn't · unhelpful · missed · forgot · lied

Manual install

If you prefer not to run the script:

  1. Copy defensive_hook.py to ~/.claude/defensive_hook.py
  2. Create ~/.claude/negative-sounds/ and add your sound files
  3. Add this to the Stop hooks in ~/.claude/settings.json:
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/defensive_hook.py"
          }
        ]
      }
    ]
  }
}

License

MIT