A physical controller for Claude Code. · Landing page
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 (
1Allow Once /2Always Allow /3Reject) without touching the keyboard. - Output — LEDs light up in response to Claude Code hook events, giving real-time feedback on what Claude is doing.
Two boards are supported:
| Board | LED output |
|---|---|
| Raspberry Pi Pico | 3× discrete LEDs (GP2/GP3/GP4) |
| Waveshare RP2040 Zero | Built-in RGB NeoPixel (GP16) |
Board type is auto-detected — no manual configuration needed.
Both use the same GPIO pins for buttons (GP14/GP15/GP26). See hardware/wiring.md for full pin assignments.
The microcontroller runs two independent roles over a single USB cable:
-
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.
-
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 |
- Install CircuitPython on your board
- Download the CircuitPython library bundle matching your CircuitPython version
- Copy the following to
CIRCUITPY/lib/:adafruit_hid/(folder) — required for all boardsneopixel.mpy— required for Waveshare RP2040 Zero only
- Copy
firmware/boot.pyandfirmware/code.pyto theCIRCUITPYdrive - Power cycle the board (unplug and replug USB) so
boot.pytakes effect - Install the Mac-side dependency:
pip3 install pyserial - Wire buttons and LEDs per
hardware/wiring.md - Run
./install.sh --deployto register hooks in~/.claude/settings.json
Or use the install script:
./install.shUse --deploy to install hooks to ~/.claude/gavel/ — a stable location independent of the project folder path:
./install.sh --deployThis is recommended if you plan to move or rename the project folder.
LEDs do not respond when running hook scripts manually from the terminal
No module named 'serial'
pyserial may not be installed for the python3 used in your terminal session. Fix with:
pip3 install pyserialNote: Claude Code hooks may use a different Python environment that already has pyserial installed, so hooks can work in a Claude Code session even when manual terminal tests fail.
MIT License — see LICENSE for details.
