CLED
Claude/Codex LED — an ambient daemon that turns your keyboard into a live status panel for your AI coding agents (and your machine), driven by OpenRGB.
CLED maps your running agent sessions onto the keys: glance down and see, by color, which of your Claude Code / Codex sessions is working, which is waiting on you, and how hard your machine is breathing — without alt-tabbing to check.
Live demo & install →
Demo video made with /brag
What you see
F1 ─────────────── F12 RAM usage, fills left → right
1 2 3 4 ... 9 one slot per agent tab in the focused iTerm2 window
┌ red = busy (mid-turn, working)
├ green = idle (waiting for you)
├ amber = stale (idle > 20 min)
└ blue = other (tab isn't a recognized agent)
Numpad 0–9 per-core CPU load, green → yellow → red
Enter rainbow heartbeat (the daemon is alive)
everything else dim
Requirements
- A keyboard with LEDs!
- macOS. Agent detection reads the focused iTerm2 window via AppleScript, so iTerm2 + macOS are assumed.
- OpenRGB installed (the app). CLED talks to its
server on
127.0.0.1:6742and launches it for you if it isn't running. - Python ≥ 3.11, managed with uv.
- An OpenRGB-supported RGB keyboard. Developed against a Corsair K70 RGB MK.2 SE (Direct mode, 116 LEDs); key regions are addressed by OpenRGB LED name, so it generalizes to other boards where those names match.
Install & run
CLED is on PyPI, so the quickest path — no clone — is with uv:
uvx cled # fetch and run in one step, nothing installed
For a persistent cled command on your PATH:
uv tool install cled
cled
In Claude Code? Install the plugin and let your agent do the setup — it checks your machine (OpenRGB, a controllable keyboard, iTerm2) and launches the daemon in its own window:
/plugin marketplace add latent-spaces/cled
/plugin install cled@cled
Then invoke it with /cled. The plugin is a thin launcher around the same uvx cled, so the PyPI package above stays the single source of truth.
Or run from a clone, handy if you want to hack on it (see Make it yours below):
git clone https://github.com/latent-spaces/cled
cd cled
uv run cled
However you start it, the daemon connects to OpenRGB if it's already up, and
otherwise starts the server itself. Press Ctrl-C to quit (the OpenRGB server is
left running).
macOS, no root
On macOS, OpenRGB can drive the keyboard as a plain user — no sudo, no Input
Monitoring grant — but only when the server runs inside your GUI/Aqua session.
CLED relies on this: it self-heals the server with
open -a OpenRGB --args --server --noautoconnect
which is the launch context that has HID access. The catch: start CLED from a
terminal in your normal desktop session. Running under sudo (or from a
non-GUI/CLI-orphan context) sees zero devices, and also breaks agent detection —
Path.home() and iTerm2 automation both need your user session.
How it works
| File | Role |
|---|---|
rgb.py |
OpenRGB client + render loop (RGBSession). Self-heals: reconnects on connection errors, and refreshes the server when it detects a wake-from-sleep (a >60s wall-clock gap between frames means the HID handle went stale). |
agent_tabs.py |
Watches tabs in the focused iTerm2 window (osascript + ps) and maps each to a status — Claude Code reads its session JSONL, Codex reads its rollout state — to tell busy from idle. |
cled.py |
The daemon. Composes each frame (agents + CPU + RAM + heartbeat) and runs the loop at 10 fps. |
Make it yours
CLED is deliberately small and self-contained — three short modules, the Python
standard library, and two dependencies (openrgb-python, psutil). There's no
framework and no hidden machinery; the whole thing fits in one sitting.
So fork it and bend it to your setup — a different key layout, your own status colors, a provider for another agent or terminal. Each behavior lives in a few small, obvious functions. Just ask Claude to change the behavior you want.
Release files for cled 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cled-0.1.0.tar.gz | 6.6 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cled-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 6.6 MB
Release files / cled-0.1.0.tar.gz
| Download URL | cled-0.1.0.tar.gz |
|---|---|
| Size | 6.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
04db4c772b1590fa573583a304b8c2f94f2880dbaf6c4ca5be1411c5a1d68c19
|
|
BLAKE2b-256 checksum How to use checksums |
1e6a0d8557318bf018350de070cdef2b5ddf5096a5bd1dccf872649ffd3ed563
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / cled-0.1.0-py3-none-any.whl
| Download URL | cled-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
859d890e1fbbe045fae6cadc3c19c24335b13554cef53f322a45ecb40664d8e8
|
|
BLAKE2b-256 checksum How to use checksums |
da5795ad7790048fe2807cb74a0228cd5167df823016aef50406df0e79c87a6a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|