Gavel

A physical controller for Claude Code.

Why "Gavel"?

A judge's gavel makes decisions final — and here, the human is always the judge. Any keyboard could send the same keys, but a dedicated device makes you stop and think instead of hitting a key on autopilot. A ruling, not a reflex.

Input

Three physical buttons answer Claude Code's permission prompts (1 Allow Once / 2 Always Allow / 3 Reject) without touching the keyboard.

Output

LEDs light up in response to Claude Code hook events, giving real-time feedback on what Claude is doing.

How it works

The microcontroller runs two independent roles over a single USB cable:

  1. USB HID keyboard — pressing a button sends the matching keypress to the terminal. Claude Code receives it exactly as if the user typed it. No special Claude Code configuration needed.
  2. Serial listener — Claude Code hooks call Python scripts on the Mac side, which send small JSON messages over the microcontroller's USB serial port to control the LEDs.
Hook LED response
PreToolUse All LEDs solid on
PostToolUse All LEDs off
Notification (info) Single slow flash
Notification (warn) Three medium flashes
Notification (error) Five fast flashes (red only)
PostToolUse (context ≥ 90%) Three medium flashes, then off
Idle — Pico (KITT mode) Night rider sweep
Idle — RP2040 Zero (KITT mode) Blue breathing fade

Setup

Getting started is straightforward:

  1. Install CircuitPython on your board
  2. Copy firmware/boot.py and firmware/code.py to the CIRCUITPY drive
  3. Copy adafruit_hid/ (all boards) and neopixel.mpy (RP2040 Zero only) to CIRCUITPY/lib/
  4. Power cycle the board (unplug and replug USB) so boot.py takes effect
  5. Install the Mac-side dependency: pip3 install pyserial
  6. Wire buttons and LEDs per the hardware wiring guide
  7. Run ./install.sh --deploy to register hooks in ~/.claude/settings.json