Explorar o código

refactor: flatten CLI by removing 'rgb' subcommand — all commands now at root level (e.g. 'qmk-rgb effect' instead of 'qmk-rgb rgb effect'), rename title to 'QMK RGB Tool', add Features section, update AGENTS.md and README.md consistently

Paul Klumpp hai 2 semanas
pai
achega
e7dd8f6044

+ 16 - 16
AGENTS.md

@@ -1,4 +1,4 @@
-# Agent Guidelines — QMK VIA RGB Tool
+# Agent Guidelines — QMK RGB Tool
 
 ## Objective
 Cross-platform Go CLI library for programmatic/agent-friendly control of VIA-compatible keyboard RGB lighting (starting with Impact 80).
@@ -17,23 +17,23 @@ keyboards.json          # VID/PID database + keyboard metadata
 
 ```
 qmk-rgb keyboard info
-qmk-rgb rgb effect breathing
-qmk-rgb rgb effect rainbow_moving_chevron
-qmk-rgb rgb effect rainbow_moving_chevron --zone backlight
-qmk-rgb rgb brightness <val>       # 0-255
-qmk-rgb rgb speed <val>            # 0-255
-qmk-rgb rgb color <hex>            # Six hexadecimal digits
-qmk-rgb rgb mode <index>           # Raw zone-specific effect ID
-qmk-rgb rgb enable
-qmk-rgb rgb disable
-qmk-rgb rgb info
-qmk-rgb rgb save <name>        # Save current RGB state to a profile
-qmk-rgb rgb load <name>        # Load a profile and apply it to the keyboard
-qmk-rgb rgb delete <name>      # Delete a saved profile
-qmk-rgb rgb list               # List saved profiles
+qmk-rgb effect breathing
+qmk-rgb effect rainbow_moving_chevron
+qmk-rgb effect rainbow_moving_chevron --zone backlight
+qmk-rgb brightness <val>       # 0-255
+qmk-rgb speed <val>            # 0-255
+qmk-rgb color <hex>            # Six hexadecimal digits
+qmk-rgb mode <index>           # Raw zone-specific effect ID
+qmk-rgb enable
+qmk-rgb disable
+qmk-rgb info
+qmk-rgb save <name>        # Save current RGB state to a profile
+qmk-rgb load <name>        # Load a profile and apply it to the keyboard
+qmk-rgb delete <name>      # Delete a saved profile
+qmk-rgb list               # List saved profiles
 ```
 
-`rgb` has a persistent `--zone` flag accepting `logo`, `backlight`, or `side`.
+`--zone` is persistent across commands and accepts `logo`, `backlight`, or `side`.
 Without `--zone`, commands target Logo, Backlight, and Side in that order.
 With `--zone`, commands target exactly one zone. Unsupported default targets
 are skipped with a stderr warning; unsupported explicit-zone effects and

+ 47 - 28
README.md

@@ -1,4 +1,4 @@
-# QMK VIA RGB Tool
+# QMK RGB Tool
 
 Control the RGB lighting on QMK-compatible keyboards. Supports Impact 80 and Rainy 75 out of the box, and any other keyboard running QMK with the RGB Matrix subsystem and VIA support.
 
@@ -26,26 +26,32 @@ go install ./cmd/qmk-rgb/
 ./qmk-rgb keyboard info
 
 # RGB commands target Logo, Backlight, and Side by default
-./qmk-rgb rgb effect breathing
-./qmk-rgb rgb effect rainbow_moving_chevron
-./qmk-rgb rgb effect rainbow_moving_chevron --zone backlight
-./qmk-rgb rgb brightness 160
-./qmk-rgb rgb speed 2
-./qmk-rgb rgb color 00ff00
+./qmk-rgb effect breathing
+./qmk-rgb effect rainbow_moving_chevron
+./qmk-rgb effect rainbow_moving_chevron --zone backlight
+./qmk-rgb brightness 160
+./qmk-rgb speed 2
+./qmk-rgb color 00ff00
 # Raw mode IDs are zone-specific; ID 17 is Backlight-only
-./qmk-rgb rgb mode 17 --zone backlight
-./qmk-rgb rgb enable
-./qmk-rgb rgb disable
-./qmk-rgb rgb info
+./qmk-rgb mode 17 --zone backlight
+./qmk-rgb enable
+./qmk-rgb disable
+./qmk-rgb info
 
 # Select exactly one zone
-./qmk-rgb rgb brightness 160 --zone side
+./qmk-rgb brightness 160 --zone side
+
+# Save and load RGB profiles
+./qmk-rgb save paul
+./qmk-rgb load paul
+./qmk-rgb list
+./qmk-rgb delete paul
 
 # Specify a target device (when multiple are connected)
-./qmk-rgb rgb --device /dev/hidraw0 enable
+./qmk-rgb --device /dev/hidrawX enable
 ```
 
-`--zone` is persistent on `rgb` and accepts `logo`, `backlight`, or `side`.
+`--zone` is persistent across commands and accepts `logo`, `backlight`, or `side`.
 Without `--zone`, commands target Logo, Backlight, and Side in that order.
 With `--zone`, commands target exactly the selected zone. An unsupported
 name for an explicit zone fails before the device is opened; a default
@@ -53,6 +59,18 @@ command skips unsupported zones and prints a warning on stderr.
 
 All output is machine-parseable JSON when applicable.
 
+## Features
+
+- **Cross-platform** — Linux, macOS, Windows via [hidapi](https://github.com/libusb/hidapi)
+- **Zone-aware effects** — per-zone effect control (Logo, Backlight, Side) with zone-specific effect catalogs
+- **Profile system** — save, load, list, and delete RGB presets as JSON files in `profiles/`
+- **46 backlight effects** — complete Impact 80 effect family mapped to zone-aware effect names
+- **Compatibility aliases** — `off`, `breathe`, `rainbow`, `solid`, `static` resolve to correct effect IDs per zone
+- **Reactive & splash effects** — honor `rgb color` and `rgb speed` for key-press illumination
+- **Machine-parseable output** — JSON for `keyboard info`, `info`, `list`, and `effect --list`
+- **Agent-friendly** — designed for automation, scripting, and CLI-first workflows
+- **Multiple devices** — `--device` flag to target a specific keyboard when several are connected
+
 ## Impact 80 Zones and Effects
 
 | Zone | CLI name | VIA channel | Effect IDs |
@@ -205,20 +223,21 @@ New keyboards can be added to `keyboards.json`.
 | Command                         | Description                              |
 |---------------------------------|------------------------------------------|
 | `qmk-rgb keyboard info`          | Discover connected VIA-compatible keyboards |
-| `qmk-rgb rgb enable`             | Enable selected lighting zones           |
-| `qmk-rgb rgb disable`            | Disable selected lighting zones           |
-| `qmk-rgb rgb info`               | Show per-zone RGB state (JSON)            |
-| `qmk-rgb rgb effect <name>`      | Set a zone-aware effect by name           |
-| `qmk-rgb rgb brightness <val>`   | Set brightness (0–255) on selected zones |
-| `qmk-rgb rgb speed <val>`        | Set effect speed (0–255) on selected zones |
-| `qmk-rgb rgb color <hex>`        | Set color (e.g. `ff0000`) on selected zones |
-| `qmk-rgb rgb mode <index>`       | Set a raw zone-specific effect ID        |
-| `qmk-rgb rgb --zone <zone> ...`  | Target `logo`, `backlight`, or `side`     |
-| `qmk-rgb rgb --device <path> ...`| Specify HID device path                  |
-| `qmk-rgb rgb save [name]`        | Save current RGB state to `profiles/<name>.json` |
-| `qmk-rgb rgb load [name]`        | Load and apply a profile from `profiles/` |
-| `qmk-rgb rgb list`               | List saved profiles                        |
-| `qmk-rgb rgb delete [name]`      | Delete a saved profile                     |
+| `qmk-rgb keyboard list`          | List all supported keyboards in database  |
+| `qmk-rgb enable`                 | Enable selected lighting zones            |
+| `qmk-rgb disable`                | Disable selected lighting zones           |
+| `qmk-rgb info`                   | Show per-zone RGB state (JSON)            |
+| `qmk-rgb effect <name>`          | Set a zone-aware effect by name           |
+| `qmk-rgb brightness <val>`       | Set brightness (0–255) on selected zones  |
+| `qmk-rgb speed <val>`            | Set effect speed (0–255) on selected zones |
+| `qmk-rgb color <hex>`            | Set color (e.g. `ff0000`) on selected zones |
+| `qmk-rgb mode <index>`           | Set a raw zone-specific effect ID         |
+| `qmk-rgb --zone <zone> ...`      | Target `logo`, `backlight`, or `side`     |
+| `qmk-rgb --device <path> ...`    | Specify HID device path                   |
+| `qmk-rgb save [name]`            | Save current RGB state to `profiles/<name>.json` |
+| `qmk-rgb load [name]`            | Load and apply a profile from `profiles/` |
+| `qmk-rgb list`                   | List saved profiles                        |
+| `qmk-rgb delete [name]`          | Delete a saved profile                     |
 
 ## Profiles
 

+ 1 - 1
cmd/qmk-rgb/rgb/brightness.go → cmd/qmk-rgb/brightness.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"fmt"

+ 1 - 1
cmd/qmk-rgb/rgb/color.go → cmd/qmk-rgb/color.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"fmt"

+ 1 - 1
cmd/qmk-rgb/rgb/commands_test.go → cmd/qmk-rgb/commands_test.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"errors"

+ 1 - 1
cmd/qmk-rgb/rgb/disable.go → cmd/qmk-rgb/disable.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"fmt"

+ 1 - 1
cmd/qmk-rgb/rgb/effect.go → cmd/qmk-rgb/effect.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"encoding/json"

+ 1 - 1
cmd/qmk-rgb/rgb/effect_test.go → cmd/qmk-rgb/effect_test.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"bytes"

+ 1 - 1
cmd/qmk-rgb/rgb/enable.go → cmd/qmk-rgb/enable.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"fmt"

+ 1 - 1
cmd/qmk-rgb/rgb/info.go → cmd/qmk-rgb/info.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"encoding/json"

+ 1 - 1
cmd/qmk-rgb/rgb/info_test.go → cmd/qmk-rgb/info_test.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"bytes"

+ 28 - 19
cmd/qmk-rgb/main.go

@@ -6,20 +6,31 @@ import (
 	"os"
 
 	"github.com/spf13/cobra"
-	"netdome.biz/paul/impact-80/cmd/qmk-rgb/rgb"
 	"netdome.biz/paul/impact-80/internal/device"
 )
 
 // version is set at build time via -ldflags.
 var version = "dev"
 
+var (
+	targetDevice string
+	targetZone   string
+)
+
 func newRootCommand() *cobra.Command {
-	return &cobra.Command{
+	cmd := &cobra.Command{
 		Use:           "qmk-rgb",
-		Short:         "QMK VIA RGB CLI — control VIA-compatible keyboard lighting",
+		Short:         "QMK RGB CLI — control VIA-compatible keyboard lighting",
 		SilenceErrors: true,
 		SilenceUsage:  true,
 	}
+	cmd.PersistentFlags().StringVar(&targetDevice, "device", "", "HID device path to use")
+	cmd.PersistentFlags().StringVar(&targetZone, "zone", "", "RGB lighting zone (logo, backlight, side)")
+	cmd.PersistentPreRunE = func(*cobra.Command, []string) error {
+		_, err := selectedZones()
+		return err
+	}
+	return cmd
 }
 
 var rootCmd = newRootCommand()
@@ -102,22 +113,20 @@ func init() {
 	rootCmd.AddCommand(keyboardCmd)
 	keyboardCmd.AddCommand(keyboardInfoCmd)
 	keyboardCmd.AddCommand(keyboardListCmd)
-	rgbCmd := rgb.Init()
-	rgbCmd.AddCommand(
-		rgb.NewEffectCmd(),
-		rgb.NewBrightnessCmd(),
-		rgb.NewSpeedCmd(),
-		rgb.NewColorCmd(),
-		rgb.NewModeCmd(),
-		rgb.NewEnableCmd(),
-		rgb.NewDisableCmd(),
-		rgb.NewInfoCmd(),
-		rgb.NewProfileSaveCmd(),
-		rgb.NewProfileLoadCmd(),
-		rgb.NewProfileListCmd(),
-		rgb.NewProfileDeleteCmd(),
-	)
-	rootCmd.AddCommand(rgbCmd)
+
+	rootCmd.AddCommand(NewEnableCmd())
+	rootCmd.AddCommand(NewDisableCmd())
+	rootCmd.AddCommand(NewInfoCmd())
+	rootCmd.AddCommand(NewEffectCmd())
+	rootCmd.AddCommand(NewBrightnessCmd())
+	rootCmd.AddCommand(NewSpeedCmd())
+	rootCmd.AddCommand(NewColorCmd())
+	rootCmd.AddCommand(NewModeCmd())
+	rootCmd.AddCommand(NewProfileSaveCmd())
+	rootCmd.AddCommand(NewProfileLoadCmd())
+	rootCmd.AddCommand(NewProfileListCmd())
+	rootCmd.AddCommand(NewProfileDeleteCmd())
+
 	rootCmd.Version = version
 	rootCmd.SetVersionTemplate("	qmk-rgb {{.Version}}\n")
 }

+ 1 - 1
cmd/qmk-rgb/rgb/mode.go → cmd/qmk-rgb/mode.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"fmt"

+ 1 - 1
cmd/qmk-rgb/rgb/profile.go → cmd/qmk-rgb/profile.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"encoding/json"

+ 1 - 21
cmd/qmk-rgb/rgb/rgb.go → cmd/qmk-rgb/rgb.go

@@ -1,20 +1,14 @@
-package rgb
+package main
 
 import (
 	"fmt"
 	"strconv"
 
-	"github.com/spf13/cobra"
 	intdevice "netdome.biz/paul/impact-80/internal/device"
 	intrgb "netdome.biz/paul/impact-80/internal/rgb"
 	"netdome.biz/paul/impact-80/internal/via"
 )
 
-var (
-	targetDevice string
-	targetZone   string
-)
-
 type zoneProtocol interface {
 	SetValue(via.LEDType, uint8, uint8) error
 	SetColor(via.LEDType, uint8, uint8) error
@@ -141,17 +135,3 @@ func ParseUint8(s string) (uint8, error) {
 	}
 	return uint8(v), nil
 }
-
-func Init() *cobra.Command {
-	cmd := &cobra.Command{
-		Use:   "rgb",
-		Short: "RGB lighting commands",
-		PersistentPreRunE: func(*cobra.Command, []string) error {
-			_, err := selectedZones()
-			return err
-		},
-	}
-	cmd.PersistentFlags().StringVar(&targetDevice, "device", "", "HID device path to use")
-	cmd.PersistentFlags().StringVar(&targetZone, "zone", "", "RGB lighting zone")
-	return cmd
-}

+ 6 - 6
cmd/qmk-rgb/rgb/rgb_test.go → cmd/qmk-rgb/rgb_test.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"reflect"
@@ -32,14 +32,14 @@ func TestLightingEnabledRequiresActiveEffectAndBrightness(t *testing.T) {
 	}
 }
 
-func TestDeviceFlagIsInheritedByRGBCommands(t *testing.T) {
+func TestDeviceFlagIsInheritedByCommands(t *testing.T) {
 	originalTargetDevice := targetDevice
 	t.Cleanup(func() { targetDevice = originalTargetDevice })
 
 	const wantPath = "hid-device-0"
 	ran := false
 
-	cmd := Init()
+	cmd := newRootCommand()
 	cmd.AddCommand(&cobra.Command{
 		Use: "probe",
 		Run: func(*cobra.Command, []string) { ran = true },
@@ -121,7 +121,7 @@ func TestZoneChannels(t *testing.T) {
 	}
 }
 
-func TestZoneFlagIsInheritedByRGBCommands(t *testing.T) {
+func TestZoneFlagIsInheritedByCommands(t *testing.T) {
 	originalTargetDevice := targetDevice
 	originalTargetZone := targetZone
 	t.Cleanup(func() {
@@ -131,7 +131,7 @@ func TestZoneFlagIsInheritedByRGBCommands(t *testing.T) {
 
 	const wantPath = "hid-device-0"
 	ran := false
-	cmd := Init()
+	cmd := newRootCommand()
 	cmd.AddCommand(&cobra.Command{
 		Use: "probe",
 		Run: func(*cobra.Command, []string) { ran = true },
@@ -174,7 +174,7 @@ func TestZoneValidationRunsBeforeCommandOpener(t *testing.T) {
 		targetZone = originalTargetZone
 	})
 
-	cmd := Init()
+	cmd := newRootCommand()
 	openerCalled := false
 	cmd.AddCommand(&cobra.Command{
 		Use: "probe",

+ 1 - 1
cmd/qmk-rgb/rgb/speed.go → cmd/qmk-rgb/speed.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	"fmt"

+ 1 - 1
cmd/qmk-rgb/rgb/zones.go → cmd/qmk-rgb/zones.go

@@ -1,4 +1,4 @@
-package rgb
+package main
 
 import (
 	intrgb "netdome.biz/paul/impact-80/internal/rgb"