Metadata-Version: 2.4
Name: claude-color
Version: 0.1.0
Summary: Drive any wired VIA-compatible RGB keyboard from Claude Code status
Author: Edocksil
License: MIT
Project-URL: Homepage, https://github.com/Edocksil/claude-color
Project-URL: Repository, https://github.com/Edocksil/claude-color
Project-URL: Issues, https://github.com/Edocksil/claude-color/issues
Keywords: claude-code,qmk,via,hid,rgb,keyboard,hooks,status
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Environment :: Console
Classifier: Operating System :: Microsoft :: Windows
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: hidapi>=0.14
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Dynamic: license-file

# claude-color

![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)
![Platform: Windows](https://img.shields.io/badge/platform-Windows-blue.svg)

**[Live docs & demo → edocksil.github.io/claude-color](https://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](https://docs.astral.sh/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](docs/COMPATIBILITY.md).
- Optional but recommended: the [`qmk_hid`](https://github.com/FrameworkComputer/qmk_hid)
  binary on your PATH (primary backend). Without it, the built-in Python `hidapi`
  backend is used.

## Install

```powershell
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:

```powershell
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:

```powershell
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`:

- `backend` — `auto` (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

```mermaid
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](LICENSE) — © 2026 Edocksil.
