|
|
@@ -1,5 +1,26 @@
|
|
|
# Agent Guidelines — QMK RGB Tool
|
|
|
|
|
|
+## Read README.md First
|
|
|
+
|
|
|
+`README.md` is the single source of truth for this project's behaviour: the
|
|
|
+command surface, the effect catalog, zone semantics, the protocol, the keyboard
|
|
|
+list and platform setup. **Read it in full before you work on this repository.**
|
|
|
+
|
|
|
+This file deliberately does not repeat any of it. A second copy is a second
|
|
|
+thing that can go stale, and that has happened: a command prefix that had not
|
|
|
+existed for many commits survived in eleven lines of prose, and a
|
|
|
+`keyboards.json` field was documented here as load-bearing while the code never
|
|
|
+read it. So the split is:
|
|
|
+
|
|
|
+- `README.md` — what the software does. Reference.
|
|
|
+- `AGENTS.md` — how to work on it. Discipline.
|
|
|
+- `.claude/skills/qmk-rgb/SKILL.md` — the live-query workflow for the tool.
|
|
|
+
|
|
|
+For the effect catalog specifically, read it from no document at all. Run
|
|
|
+`qmk-rgb-tool effect --list` and use the output. Logo and Side accept fewer
|
|
|
+effects than Backlight, and only the tool knows what the current firmware
|
|
|
+supports.
|
|
|
+
|
|
|
## Objective
|
|
|
Cross-platform Go CLI library for programmatic/agent-friendly control of QMK keyboard RGB lighting.
|
|
|
|
|
|
@@ -14,30 +35,6 @@ internal/rgb/ # Effects, values, color definitions
|
|
|
keyboards.json # Optional name/metadata lookup for known keyboards
|
|
|
```
|
|
|
|
|
|
-## CLI Interface
|
|
|
-
|
|
|
-```
|
|
|
-qmk-rgb-tool keyboard info
|
|
|
-qmk-rgb-tool effect breathing
|
|
|
-qmk-rgb-tool effect rainbow_moving_chevron
|
|
|
-qmk-rgb-tool effect rainbow_moving_chevron --zone backlight
|
|
|
-qmk-rgb-tool effect --list # Every effect per zone (JSON)
|
|
|
-qmk-rgb-tool brightness <val> # 0-255, verified by read-back
|
|
|
-qmk-rgb-tool speed <val> # 0-255, verified by read-back
|
|
|
-qmk-rgb-tool color <hex> # Six hexadecimal digits
|
|
|
-qmk-rgb-tool mode <index> # Raw zone-specific effect ID
|
|
|
-qmk-rgb-tool enable
|
|
|
-qmk-rgb-tool disable
|
|
|
-qmk-rgb-tool info
|
|
|
-qmk-rgb-tool save [name] # Save current RGB state to a profile
|
|
|
-qmk-rgb-tool load [name] # Load a profile and apply it to the keyboard
|
|
|
-qmk-rgb-tool delete [name] # Delete a saved profile
|
|
|
-qmk-rgb-tool list # List saved profiles
|
|
|
-qmk-rgb-tool --device <n> ... # Target keyboard number from `keyboard info`
|
|
|
-```
|
|
|
-
|
|
|
-`save`, `load` and `delete` take an optional name and default to `default`.
|
|
|
-
|
|
|
## Device Selection
|
|
|
|
|
|
Discovery matches every connected keyboard exposing the QMK Raw HID signature
|
|
|
@@ -61,61 +58,6 @@ With `--zone`, commands target exactly one zone. Unsupported default targets
|
|
|
are skipped with a stderr warning; unsupported explicit-zone effects and
|
|
|
unknown names fail before the device is opened.
|
|
|
|
|
|
-### Impact 80 Effect Families
|
|
|
-
|
|
|
-Logo and Side use IDs 0–6: `none`, `wave`, `fixed_wave`, `spectrum`,
|
|
|
-`breathing`, `light`, and `shutdown`.
|
|
|
-
|
|
|
-Backlight uses the complete ID 0–45 family:
|
|
|
-
|
|
|
-```text
|
|
|
-none, solid_color, alphas_mods, gradient_up_down, gradient_left_right,
|
|
|
-breathing, band_sat, band_val, band_pinwheel_sat, band_pinwheel_val,
|
|
|
-band_spiral_sat, band_spiral_val, cycle_all, cycle_left_right,
|
|
|
-cycle_up_down, cycle_out_in, cycle_out_in_dual, rainbow_moving_chevron,
|
|
|
-cycle_pinwheel, cycle_spiral, dual_beacon, rainbow_beacon,
|
|
|
-rainbow_pinwheels, flower_blooming, raindrops, jellybean_raindrops,
|
|
|
-hue_breathing, hue_pendulum, hue_wave, pixel_flow, digital_rain,
|
|
|
-solid_reactive, solid_reactive_wide, solid_reactive_multiwide,
|
|
|
-solid_reactive_cross, solid_reactive_multicross, solid_reactive_nexus,
|
|
|
-solid_reactive_multinexus, splash, multisplash, solid_splash,
|
|
|
-solid_multisplash, starlight, starlight_dual_hue, starlight_dual_sat,
|
|
|
-riverflow
|
|
|
-```
|
|
|
-
|
|
|
-ID 39 is `multisplash`; ID 41 is `solid_multisplash`. Supported aliases are
|
|
|
-`off` → `none`, `breathe` → `breathing`, `rainbow` (zone-dependent),
|
|
|
-`rainbow_wave` (Logo/Side), `solid` (zone-dependent), and legacy `static`.
|
|
|
-Do not assume a numeric effect ID is valid on every zone; use the zone-aware
|
|
|
-name resolver or deliberately use `mode` as a raw escape hatch.
|
|
|
-
|
|
|
-`info` emits a `zones` array containing each selected zone's channel,
|
|
|
-enabled state, effect name and ID, brightness, speed, and color. The
|
|
|
-top-level summary comes from the first selected zone. A failed zone includes
|
|
|
-an `error` field while other zone results remain available; the command
|
|
|
-prints JSON before returning non-zero.
|
|
|
-
|
|
|
-## VIA Protocol Essentials
|
|
|
-
|
|
|
-- Transport: QMK Raw HID over a 32-byte hidraw report, report number `0`
|
|
|
-- Message types:
|
|
|
- - `0x07` — Custom set value
|
|
|
- - `0x08` — Custom get value
|
|
|
-- Impact 80 lighting channels: `0x02` logo, `0x03` backlight, `0x04` side
|
|
|
-- RGB value IDs: brightness `0x01`, effect `0x02`, speed `0x03`, color `0x04`
|
|
|
-- No separate enable handshake is used
|
|
|
-
|
|
|
-## Keyboards (Known VID/PID)
|
|
|
-
|
|
|
-| Keyboard | VID | PID |
|
|
|
-|------------------|--------|--------|
|
|
|
-| Wobkey Rainy 75 | 0x6666 | 0x0001 |
|
|
|
-| Wobkey Impact 80 | 0x36B0 | 0x309F |
|
|
|
-
|
|
|
-`keyboards.json` maps VID+PID → display name. Only `name` is read by the
|
|
|
-code; unknown fields in the file are ignored, so entries may carry extra keys
|
|
|
-without affecting discovery.
|
|
|
-
|
|
|
## Stack
|
|
|
|
|
|
- Go 1.26+ (cross-platform: Linux, macOS, Windows)
|
|
|
@@ -148,12 +90,14 @@ Documented behavior must also match the code:
|
|
|
## Firmware Transforms Values
|
|
|
|
|
|
The Impact 80 firmware rescales or clamps brightness and speed per channel, so
|
|
|
-an accepted 0–255 request is not the value the keyboard holds: `logo` and
|
|
|
-`side` cap brightness at 160 and collapse any speed above 0 to 4, while
|
|
|
-`backlight` scales brightness up to 255 and applies speed as given.
|
|
|
-
|
|
|
-`brightness` and `speed` therefore read every selected zone back and print what
|
|
|
-was actually applied; where all zones match they print `Brightness set to N` or
|
|
|
+an accepted 0–255 request is not the value the keyboard holds. `logo` and `side`
|
|
|
+cap brightness at 160 and collapse any speed above 0 to 4, while `backlight`
|
|
|
+scales brightness up to 255 and applies speed as given. README.md tabulates the
|
|
|
+per-channel behaviour; the rule that follows from it is the part that matters
|
|
|
+when you write code here:
|
|
|
+
|
|
|
+`brightness` and `speed` read every selected zone back and print what was
|
|
|
+actually applied; where all zones match they print `Brightness set to N` or
|
|
|
`Speed set to N`, and where any zone differs they print one summary line naming
|
|
|
each zone's real value and the request. Never let a command report success for a
|
|
|
value the keyboard did not accept. Both read back through the shared
|