Skip to content

Add headless CLI for uploading/downloading keyboard configurations - #383

Open
joshperry wants to merge 2 commits into
vial-kb:mainfrom
joshperry:cli
Open

Add headless CLI for uploading/downloading keyboard configurations#383
joshperry wants to merge 2 commits into
vial-kb:mainfrom
joshperry:cli

Conversation

@joshperry

@joshperry joshperry commented Feb 6, 2026

Copy link
Copy Markdown

Adds vial-cli, a headless command-line interface for writing and reading .vil layout files without launching the GUI. This enables scripted keyboard configuration, LLM MCP, remote/SSH workflows, and CI-driven provisioning on systems without a display server.

Usage

vial-cli upload <file.vil>      # write a saved layout to the keyboard
vial-cli download <file.vil>    # read the current layout from the keyboard
vial-cli upload layout.vil --device 1  # select keyboard when multiple are connected
vial-cli upload layout.vil --force     # skip UID mismatch check

How it works

This builds on the protocol/GUI decoupling from #382 (deguify) — since the protocol layer no longer imports Qt at module level, the CLI can drive Keyboard.save_layout() and Keyboard.restore_layout() directly over USB without any display dependencies.

Two things that still needed Qt are handled at runtime:

  • Unlocker — a headless implementation is injected into sys.modules before any protocol code runs. It prints the key positions to hold and polls in a text loop instead of showing the Qt dialog.
  • QmkSettings — initialized by loading qmk_settings.json directly, bypassing the GUI's appctx-based resource resolution.

Device discovery

When zero or multiple keyboards are detected, the CLI prints actionable diagnostics (troubleshooting hints for zero, a numbered device list for multiple) and exits non-zero.

UID matching

.vil files store keyboard UIDs as JSON numbers, which lose precision through float64 when created by JavaScript-based tools (e.g. the web configurator). The CLI compares UIDs through float() to tolerate this, and supports --force as an explicit override.

Tests

20 new tests in test_cli.py covering device discovery (all 6 branches), upload validation, the float64 UID edge case, headless unlock flow, download round-trip, and an AST check that cli.py remains Qt-free.

@Pituivan

Pituivan commented Sep 3, 2026

Copy link
Copy Markdown

This is actually really useful. For some reason, my keyboard's persistent memory corrupts when rebooting (I think it's because I use a cheap USB hud), so I have to manually open Vial and load my last saved layout.

This PR would allow me to automate that process on startup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants