A desk lamp that tells you which of your AI coding agents is waiting for you.
Run three coding agents across two machines and you spend the day alt-tabbing to find out which one stopped to ask a question. This is a small tower on the desk that answers that without a window: green means working, amber means one of them needs you.
No telemetry. Status is computed locally and pushed over BLE or USB serial — nothing leaves the machine.
| State | Light | Meaning |
|---|---|---|
working |
green | at least one session is running |
needs-you |
amber, breathing | a session is waiting for input |
idle |
red | sessions are open but nothing is running |
asleep |
red at 3 %, breathing | no live sessions |
| — | red + amber double flash | not a state: the link is down |
The most urgent session wins. If anything is waiting for you, the light goes amber even while the others keep working — which is the only rule that matters when the point is to stop you checking.
| Variant | Board | Link | Pins |
|---|---|---|---|
| Wireless | ESP32 (WiFi+BT) | BLE; cable carries 5 V only | GPIO 25 / 26 / 27 |
| Wired | Arduino Nano (ATmega328P) | USB serial, 115200 | D9 / D10 / D11 |
| Panel | Nano + WS2812B strip + MAX7221 matrix | USB serial, 115200 | D2 strip · D3/D4/D5 matrix |
All three speak the same line protocol, fit the same enclosure, and are driven by the
same daemon. The only difference is the transport field in config.json.
Common to all: three 10 mm diffused LEDs (red / amber / green) with 110/100/100 Ω resistors, a printed body 100 × 66 × 106 mm, and a swappable MCU sled — so changing variant is a five-minute job, not a rebuild.
Dimensions and layout: hardware/MECHANICAL.md ·
hardware/layout.svg · hardware/BOM.csv
The daemon runs without a beacon attached, printing what it would send:
pip install -r cli/requirements.txt
python cli/beacond.py --transport dryStart an agent session in another window and watch the state change. That is the whole system minus the LEDs, and it is the right way to find out whether you want one.
pip install -r cli/requirements.txt- Flash the firmware:
- wireless:
firmware/beacon/beacon.ino→ ESP32 Dev Module - wired:
firmware/beacon_nano/beacon_nano.ino→ Arduino Nano
- wireless:
- Install the hooks:
python cli/install_hooks.py - On a wired machine, put
"transport": "serial"inconfig.json(not needed for BLE) - Run the daemon:
python cli/beacond.py
Per-machine checklists:
| Guide | Covers |
|---|---|
| SETUP-LAPTOP-WINDOWS.md | Windows + ESP32, wireless (BLE) |
| SETUP-DESKTOP-UBUNTU.md | Ubuntu + Arduino Nano, wired (serial) |
| SETUP-PANEL-NANO.md | Panel build with strip and matrix |
| HARDWARE-BUILD.md | Buying, printing, assembly order, fit checks |
| TROUBLESHOOTING.md | Symptom to cause |
BLE Nordic UART Service (6E400001-B5A3-F393-E0A9-E50E24DCCA9E), line based:
STATE working|idle|needs-you|asleep
CONTEXT 0..100 context window usage; the panel matrix displays it
BRIGHT 0..255
PING -> PONG
The wired variant sends the same lines over USB serial at 115200 8N1.
To drive the beacon from your own agent, write those lines. That is the entire integration surface — there is no SDK, and there does not need to be one.
| Agent | Method |
|---|---|
| Claude Code | hooks plus transcript inspection |
| opencode | its SQLite session database |
| Codex CLI, Copilot CLI | coarse file-mtime watcher |
Each session writes a small state file; the daemon reduces them to one state by urgency and pushes it. Sessions that die without cleaning up are aged out, so a crashed terminal does not leave the light stuck on green.
hardware/ MECHANICAL.md (layout and dimensions), layout.svg, BOM.csv
firmware/ beacon/ ESP32: BLE NUS server + three LEDC PWM channels
beacon_nano/ Nano: USB serial + PROGMEM gamma table
beacon_nano_panel/ Nano panel: WS2812B strip + 8x8 matrix
cli/ beacond.py (daemon), beacon_hook.py (Claude Code bridge),
install_hooks.py, beacon_send.py (bench test), agentbeacon/ (package)
docs/ per-machine setup guides and troubleshooting
This is the first public release. It runs on my own desk every day, across two machines and all three hardware variants — but that is a sample size of one, and "works here" is not the same as "works".
I am actively building on this, and feedback is genuinely wanted. Especially:
- State detection that gets it wrong. If the light says working while the agent is waiting for you, that is the bug that matters most. An issue saying what you were doing at the time is more useful than it sounds.
- The build guides. If a step is ambiguous or an ordering is wrong, you found it by losing an hour to it — please say so.
- Other agents. The protocol is four lines; if you wire up an agent that is not listed, a pull request or even a description of how you did it is welcome.
- Anything about the enclosure. Print tolerances vary, and the sled fit is the part I would expect to be off on somebody else's printer.
Open an issue for anything, including "this looked interesting and then I got stuck at". That is a bug report about the documentation and it counts.
- Hardware (CAD, schematics, layout): CERN-OHL-S v2 — see LICENSE-HARDWARE
- Firmware and CLI: MIT — see LICENSE
🇹🇷 Türkçe: README.tr.md