Skip to main content

Drive any wired VIA-compatible RGB keyboard from Claude Code status

Project description

claude-color

License: MIT Python 3.11+ Platform: Windows

Live docs & demo → edocksil.github.io/claude-color

Drive a wired VIA-compatible keyboard's RGB from Claude Code status — see at a glance whether Claude is working, waiting for you, or idle, without looking at the terminal.

  • working → blue-purple
  • waiting for you (permission / input) → amber
  • idle (turn done, session alive) → deep green
  • Claude Code exits / no session running → your normal lighting is restored

Why claude-color

Built to be correct under real conditions, not just a demo:

  • Multi-session aware — one keyboard, many Claude Code sessions, resolved by priority (waiting > working > idle).
  • Survives crashes & sleep — sessions are tracked by their Claude process; dead ones are pruned, and a boot/logon/unlock reconcile restores your lighting when no session is running.
  • Accurate status — distinguishes a real permission prompt (amber) from a finished-but-idle session (green) via Claude Code's notification_type.
  • Restores your lighting — captures your real keyboard color and puts it back, with a guard against capturing its own status colors.
  • Windows-first, keyboard-generic (any wired VIA RGB keyboard), 85+ tests.

Requirements

  • Windows 11, Python 3.11+ — installed and run via uv (no system Python needed).
  • Any wired keyboard exposing a VIA raw-HID interface with an RGB matrix, connected by USB cable. VIA support is most commonly provided by QMK firmware with VIA enabled, but only the VIA protocol is required — not QMK itself. Developed and validated on the Keychron Q6 Max. Wireless is not supported (wired only). See docs/COMPATIBILITY.md.
  • Optional but recommended: the qmk_hid binary on your PATH (primary backend). Without it, the built-in Python hidapi backend is used.

Install

uv run claude-color doctor        # confirm the keyboard is detected
uv run claude-color test          # cycle working/waiting/idle, then restore
uv run claude-color install       # add hooks to %USERPROFILE%\.claude\settings.json

To make claude-color a global command (so Claude Code can invoke the hooks from any terminal), install it as a uv tool — --editable keeps it tracking this repo:

uv tool uninstall kbstatus     # remove the old command (if previously installed)
uv tool install --editable .   # exposes `claude-color` on PATH (~\.local\bin)
claude-color install           # wire hooks (migrates any old kbstatus wiring)

Ensure the uv tool bin dir is on PATH so Claude Code and the scheduled task can invoke claude-color.

Demo

Run the color cycle any time to see (or show off) all three statuses. It cycles working → waiting → idle and then restores your current lighting:

claude-color test                 # ~2s per color (quick check)
claude-color test --dwell 30      # hold each color 30s (slow demo)

Configure

Edit %LOCALAPPDATA%\claude-color\config.toml:

  • backendauto (default), qmk_hid, or hidapi
  • solid_effect_index — the VIA "solid color" effect index for your keymap. If claude-color test shows an animation instead of a solid color, change this and rerun claude-color test.
  • vid / pid — hex, only needed if multiple HID devices match. Find yours with claude-color doctor or qmk_hid -l.
  • [colors] — H/S/V (0–255) per state
  • staleness_minutes — a stuck session is forgotten after this (default 120)

How it works

flowchart LR
    CC["Claude Code hooks"] -->|"SessionStart · UserPromptSubmit · Notification · Stop · SessionEnd"| K["claude-color hook"]
    K --> S["state.json<br/>(per session, by PID)"]
    S -->|"winner: waiting &gt; working &gt; idle"| KB["keyboard RGB<br/>(VIA raw-HID)"]
    R["claude-color reconcile<br/>(logon / unlock)"] --> S

Claude Code fires hooks (SessionStart, UserPromptSubmit, Notification, Stop, SessionEnd). Each runs claude-color hook, which updates a per-session state file (%LOCALAPPDATA%\claude-color\state.json) and pushes the highest-priority color (waiting > working > idle) across all live sessions. Sessions are tracked by their Claude process id; dead ones are pruned, and a scheduled claude-color reconcile (logon/unlock) restores your lighting when no Claude is running. When the last session ends, the lighting captured at first SessionStart is restored.

Troubleshooting

  • No color changes: run claude-color doctor. If available: False, check the USB cable (wireless is not supported) and try backend = "hidapi" or set vid/pid.
  • Animation instead of solid color: fix solid_effect_index.
  • Colors never restore: baseline capture may be unsupported on your firmware via the active backend; try backend = "hidapi". Logs are in %LOCALAPPDATA%\claude-color\claude-color.log.
  • Uninstall: claude-color uninstall.

License

MIT — © 2026 Edocksil.

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

claude_color-0.1.0.tar.gz (30.2 kB view details)

Uploaded Source

Built Distribution

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

claude_color-0.1.0-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: claude_color-0.1.0.tar.gz
  • Upload date:
  • Size: 30.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for claude_color-0.1.0.tar.gz
Algorithm Hash digest
SHA256 083f0f4213f2db355417872088c52f1a062be216da29b0fca6d8496fb47ff56e
MD5 c0c4f80db8af740ab670cb7615e0c473
BLAKE2b-256 b2938faee27407d1970ed7d7dca2c9b50b5f3df32c7edaca8e6b93815407d580

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_color-0.1.0.tar.gz:

Publisher: release.yml on Edocksil/claude-color

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: claude_color-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 22.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for claude_color-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5049b1e49c6a703925cf7689adf00331b8d99458fc110c501ad490af9356fa81
MD5 7fa13c3600c1e88e5f6b58298e0f85bb
BLAKE2b-256 0a3c01001cefb9e93cb095abca6692b39983e84fef73a4d1c8b3888e3112af72

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_color-0.1.0-py3-none-any.whl:

Publisher: release.yml on Edocksil/claude-color

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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