Skip to main content

CLED (Claude/Codex LED) — ambient keyboard daemon that maps your AI agents' status onto the keys via OpenRGB

Project description

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.

CLED — your keyboard as a live agent panel

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:6742 and 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cled-0.1.0.tar.gz (6.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cled-0.1.0-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file cled-0.1.0.tar.gz.

File metadata

  • Download URL: cled-0.1.0.tar.gz
  • Upload date:
  • Size: 6.6 MB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for cled-0.1.0.tar.gz
Algorithm Hash digest
SHA256 04db4c772b1590fa573583a304b8c2f94f2880dbaf6c4ca5be1411c5a1d68c19
MD5 3664c7184e8b4be5109f4c5a9321120c
BLAKE2b-256 1e6a0d8557318bf018350de070cdef2b5ddf5096a5bd1dccf872649ffd3ed563

See more details on using hashes here.

File details

Details for the file cled-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: cled-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for cled-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 859d890e1fbbe045fae6cadc3c19c24335b13554cef53f322a45ecb40664d8e8
MD5 4d9f1731125080d739e16104c416b655
BLAKE2b-256 da5795ad7790048fe2807cb74a0228cd5167df823016aef50406df0e79c87a6a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page