Skip to content

feat: add VIA keyboard support - #8

Merged
snekxs merged 1 commit into
OpenMouse-Project:mainfrom
onyxhq-dev:feat/via-protocol
Oct 31, 2026
Merged

snekxs merged 1 commit into
OpenMouse-Project:mainfrom
onyxhq-dev:feat/via-protocol

Conversation

@onyxhq-dev

@onyxhq-dev onyxhq-dev commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

What

Adds a driver for keyboards running VIA firmware (QMK/VIA). It is exported as @openmouse/keyboard-protocol/via and registered in the driver registry.

VIA boards from any vendor use the same raw HID collection (0xFF60:0x61), so the driver matches on that collection alone. It sits last in the registry, so brand drivers (Wooting, Keychron, Arbiter and so on) still win.

Included

  • Raw HID client: protocol version, layer count, keymap read/write, macros, encoders, custom menu values, layout options, switch matrix state.
  • Keycode tables for legacy (protocol 10 and below) and modern (11 and above) VIA, including lighting and custom keycodes, a keycode picker model, and a composer for layer-tap, mod-tap and modifier combos.
  • Macro encode/decode, with a readable expression form.
  • Definition parsing for VIA v3 and v2 JSON (v2 lighting is expanded to menus).
  • Conversion to and from the names in VIA's .layout.json, and a browser key-code to QMK keycode table.
  • docs/via-support.md with the support ledger.

Not included

EEPROM reset, bootloader jump and macro reset commands are deliberately never sent. Wilba Tech wt_* lighting is not modelled.

Testing

  • npm run check passes (384 tests), including a fake-board test of the HID client.
  • Exercised on one board: Anvil Native (0x7470:0x0002, VIA protocol 11). Encoders, the switch matrix and other protocol versions are covered by unit tests only.

Note: a Keychron board that is not a catalogued Hall-effect model now falls through to the VIA driver. The registry test was updated to expect that.

Note

Add VIA keyboard support with HID client, protocol codecs, and driver registration

  • Adds ViaHidClient in hid.ts, a Web HID client that talks the VIA raw-HID protocol: status reads, keymap read/write with read-back verification, single keycodes, encoders, switch-matrix reads, macros, custom-menu values, and layout options. Commands time out after 1500 ms and a failed transaction faults the session.
  • Adds a pure VIA protocol library in index.ts: report framing, command codecs, keyboard-definition parsing, layout-option choice packing, keycode naming and composition, a keycode picker, macro byte/expression codecs, and custom-menu parsing with showIf condition evaluation.
  • Registers VIA as a fallback driver in registry.ts after brand drivers, so any device with a VIA raw-HID collection (usage page 0xFF60, usage 0x61) matches. Uncatalogued Keychron products now match VIA instead of being unsupported.
  • Exposes the library as ./via and a root via namespace export, plus a new support guide in via-support.md.
  • Risk: driver matching changes — an uncatalogued Keychron product ID previously reported unsupported and now reports as VIA; see the matching tests in registry.test.ts.

Macroscope summarized 731d9ca.

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions github-actions Bot added type: enhancement PR title category: enhancement area: protocol Protocol codecs and shared types area: drivers Device drivers and transport integration area: tests Protocol and driver tests area: documentation Documentation area: dependencies Dependency manifests and lockfiles labels Oct 31, 2026
Comment thread src/via/index.ts Resolved
Comment thread src/drivers/via/hid.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/drivers/via/hid.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Outdated
if (ids.length < 2 || ids.some((id) => !Number.isInteger(id) || id < 0 || id > 0xff)) return null;
const control = toControl(entry);
if (!control) return null;
const bytes = typeof entry.bytes === "number" && entry.bytes >= 1 && entry.bytes <= 4 ? Math.floor(entry.bytes) : 1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High via/index.ts:780

Controls without an explicit bytes field are always parsed as one-byte values, so valid 16-bit ranges and buttons are truncated on reads and values above 255 are rejected by viaNumberToBytes; color controls also need two bytes for hue and saturation. Infer the width from the parsed control when bytes is absent.

-  const bytes = typeof entry.bytes === "number" && entry.bytes >= 1 && entry.bytes <= 4 ? Math.floor(entry.bytes) : 1;
+  const bytes = typeof entry.bytes === "number" && entry.bytes >= 1 && entry.bytes <= 4 ? Math.floor(entry.bytes) : control.type === "color" ? 2 : control.type === "range" ? (control.max > 255 ? 2 : 1) : control.type === "button" ? (control.value > 255 ? 2 : 1) : 1;
🤖 Copy this AI Prompt to have your agent fix this:
In file @src/via/index.ts around line 780:

Controls without an explicit `bytes` field are always parsed as one-byte values, so valid 16-bit ranges and buttons are truncated on reads and values above 255 are rejected by `viaNumberToBytes`; color controls also need two bytes for hue and saturation. Infer the width from the parsed control when `bytes` is absent.

@macroscopeapp

macroscopeapp Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — Adds VIA keyboard configuration support while preserving existing brand-driver precedence. Unresolved review concerns about custom-control widths and toggle payloads need reconciliation because they affect values written to keyboard settings.

Notes:

  • Your repo's Minimum Blocking Severity is Off, so correctness findings do not automatically block approval.

You can add or adjust custom eligibility rules. Learn more.

Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Comment thread src/via/index.ts Resolved
Generic driver for boards running VIA/QMK firmware, found by the raw HID
collection (usage page 0xFF60, usage 0x61) instead of a vendor list.

Driver (drivers/via): protocol version, firmware and keycodes version,
keymap read/write by buffer (protocol 8+) or single key, layer count,
encoders, macro memory, custom-menu values, and layout options. Writes
are read back and the board's reply is returned, since boards clamp or
round custom values.

Codec (src/via): 32-byte command frames, served v3 definition parser with
layout-option decoding, keycode names for both QMK numbering generations,
a macro action codec that keeps bytes it does not understand, VIA's macro
text syntax with QMK key names, and a parser that turns a definition's
menus into range, toggle, dropdown, colour and button controls with their
showIf conditions.

EEPROM reset, bootloader jump and macro reset are never sent. Exercised on
one board (Anvil Native, protocol 11); see docs/via-support.md.
@snekxs
snekxs merged commit 4d5a6f5 into OpenMouse-Project:main Oct 31, 2026
8 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.6.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@onyxhq-dev
onyxhq-dev deleted the feat/via-protocol branch October 31, 2026 04:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: dependencies Dependency manifests and lockfiles area: documentation Documentation area: drivers Device drivers and transport integration area: protocol Protocol codecs and shared types area: tests Protocol and driver tests released type: enhancement PR title category: enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants