

Gavel
Physical approval controller for Claude Code
- Size
- 98.8 × 62.1 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 24
- Nets
- 30
- Pads
- 114
- Tracks, vias
- 100, 4
- Pours
- 1
- Routed
- Yes
- KiCad
- KiCad 10.0 (file 20260206)
- Created
- 10 Apr 2026
- Updated
- 3 Jun 2026
Overview
Gavel is an open-source printed circuit board by etalli, from the etalli/Gavel repository on GitHub, published under the MIT licence. It is a 2-layer board of 98.8 × 62.1 mm with 24 parts on 30 nets, routed with 100 tracks and 4 vias.
It is built around the RP2040-ZERO and SK6812MINI-E. Its parts include 5 diodes, 4 connectors, 3 resistors, 3 switches and 1 IC. It belongs with the RP2040 boards of this library.
Main components
2RP2040-ZERO
-- Development Boards & Kits ROHSWaveshareDevelopment Boards & KitsSK6812MINI-E
SMD-40℃~+85℃ 0.6mA 1.78mm 120mcd~240mcd 120° 160mcd~320mcd 1kHz 2.8mm 2000V 3.2mm 3.7V~5.5V 460nm~470nm 515nm~525nm 620nm~625nm 800Kbit/s 815mcd~1275mcd Semi-transparent lens SMD RGB LEDs(Built-in IC) ROHSOPSCO OptoelectronicsRGB LEDs(Built-In IC)
README
README.mdGavel
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 pressing keys on autopilot. A ruling, not a reflex. Gavel acts as a physical reminder and a friction layer against autopilot mode: pause, think, then decide. Happy coding!
What it does
- Input — Three physical buttons answer Claude Code's permission prompts (
1Allow Once /2Always Allow /3Reject) without touching the keyboard. Holding a button for 800ms triggers a custom keyboard macro. - Output — LEDs light up in response to Claude Code hook events, giving real-time feedback on what Claude is doing. Color and pattern vary by tool risk category (read / write / network / destructive). An optional servo can also indicate notification severity.
- Log — Every button press is appended to
~/.claude/gavel/decisions.jsonlfor decision history. Runpython3 hooks/stats.pyto see a summary.
Hardware
The PCB is designed for the Waveshare RP2040 Zero.
| Board | LED output | Status |
|---|---|---|
| Waveshare RP2040 Zero | RGB NeoPixel (GP16) + 3× button LEDs (GP10/GP11/GP12) | Primary (PCB supported) |
| Raspberry Pi Pico | 3× discrete LEDs (GP10/GP11/GP12) | Legacy / DIY wiring only |
The NeoPixel shows the tool risk category color. The 3 button LEDs (one per switch) light up to confirm which button was pressed.
Board type is auto-detected — no manual configuration needed.
Both use the same GPIO pins for buttons (GP2/GP3/GP4). See hardware/wiring.md for full pin assignments.

How it works
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 | Category | NeoPixel | Discrete LEDs |
|---|---|---|---|
PreToolUse | readonly (Read / Grep / LS) | Blue | Center LED dim |
PreToolUse | write (Edit / Write) | Yellow | Two LEDs dim |
PreToolUse | network (WebFetch / Agent) | Orange blink | Blink |
PreToolUse | destructive (Bash etc.) | Red | All bright |
PostToolUse | — | Off | Off |
Notification (info) | — | Single slow flash | Single slow flash |
Notification (warn) | — | Three medium flashes | Three medium flashes |
Notification (error) | — | Five fast red flashes | Five fast flashes |
PostToolUse (context ≥ 90%) | — | Three medium flashes, then off | Three medium flashes, then off |
Setup
1. Hardware Firmware
- 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
(Alternatively, run./install.shto automate this step) - Power cycle the board (unplug and replug USB) so
boot.pytakes effect - Wire buttons and LEDs per
hardware/wiring.md
2. Software (Claude Code Hooks)
- Install the Mac-side dependency:
pip3 install pyserial - Add the project's hook scripts to your
~/.claude/settings.json(instructions pending). - Optional: Run
./install.sh --deployto copy the hook scripts to a stable location (~/.claude/gavel/) and automatically update their paths insettings.json. This is recommended if you plan to move or rename the project folder.
Troubleshooting
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.
License
MIT License — see LICENSE for details.
Parts
24| Qty | Value | Footprint | References |
|---|---|---|---|
| 5 | MountingHole | MountingHole:MountingHole_2.2mm_M2 | H1, H2, H2, H2, H4 |
| 3 | Conn_01x03_Socket | Connector_JST:JST_PH_S3B-PH-K_1x03_P2.00mm_Horizontal | J3, J4, J5 |
| 3 | LED | LED_THT:LED_D3.0mm | D1, D2, D3 |
| 3 | R | Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P7.62mm_Horizontal | R1, R2, R3 |
| 3 | SW_Push | _footprints:k2_CherryMX_KailhChocV1_Socket_Diode-rev2 | SW2, SW3, SW4 |
| 3 | SolderJumper_2_Open | Jumper:SolderJumper-2_P1.3mm_Open_RoundedPad1.0x1.5mm | JP1, JP2, JP3 |
| 2 | SK6812MINI | LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm | D4, D5 |
| 1 | AudioJack4 | _footprints:MJ-4PP-9_1side | J1 |
| 1 | RP2040-ZERO | _footprints:MODULE_RP2040-ZERO | U1 |
Similar boards
- 2 layers102.5 × 72.6 mm

- 2 layers180.1 × 190.7 mm

Dya panelized
cormoran/dya-keyboard
Pre-built QMK firmware is available in latest build's artifact section in this github actions.
228 parts6CC-BY-4.0 - 2 layers229.9 × 123.2 mm

- 2 layers76.2 × 96.7 mm

- 2 layers307 × 101 mm

Bolide-65-pcb
amperolithic/bolide-65-keeb
Bolide65 is a 66 key, 65% keyboard with a rotary encoder and RGB backlighting under each key.
272 partsGPL-3.0 - 2 layers314.3 × 98.8 mm

- 2 layers304.4 × 98.8 mm

- 2 layers248.9 × 93.1 mm

Questions
How big is the Gavel PCB?
It measures 98.8 × 62.1 mm and has 2 copper layers, 1.6 mm thick.
What parts does the Gavel use?
24 parts, built around the RP2040-ZERO and SK6812MINI-E. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
Where can I download the Gavel KiCad files?
From the etalli/Gavel repository on GitHub, at the commit this page was made from: the board is hardware/PCB/Gavel.kicad_pcb and its schematic hardware/PCB/Gavel.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Can I use the Gavel design in my own project?
Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).