THE BLOG · RELEASE NOTES

Firmware 0.8.0 and app 0.12.0: the pad can be a Codex Micro now

OpenMicroKbd with its stock keycaps resting on a laptop keyboard, the companion app's key editor open on the screen behind it
Same board, two personalities. Firmware 0.8.0 lets it choose at boot.

Two releases, one idea

The launch post called OpenMicroKbd a recreation of the Codex Micro's control surface: the same thirteen keys, dial, stick and touch pad, driven by our own firmware and our own companion app. That was deliberately the whole claim. What the pad did in front of a coding agent was up to you and the app's key editor.

Today's two releases close that gap from both ends.

Firmware 0.8.0 adds an opt-in Codex Micro compat mode. Switched on, the pad boots with the Codex Micro's USB identity and speaks the device protocol the ChatGPT desktop app uses to talk to that hardware. The desktop app then treats it as the real thing: keys, dial and stick arrive as Codex Micro controls, and the app pushes its six agent status lights and its lighting configuration back to the LEDs. Confirmed on hardware with Codex desktop 26.825 on macOS.

App 0.12.0 adds profile templates. The + button in the header is now a menu: an empty profile, or a template for Codex or Claude Code, both laid out for the keycap set the board ships with. Every printed key emits the right chord straight from the pad, so a fresh board does something sensible the moment it is plugged in, with the app closed.

OpenMicroKbd remains an independent open-source project, not affiliated with, endorsed by, or sponsored by OpenAI, Work Louder or Anthropic. "Codex Micro", "Codex", "ChatGPT" and "Claude Code" refer to their owners' products; all trademarks belong to their respective owners.

Compat mode: the pad boots as a Codex Micro

What the desktop app sees

In compat mode the pad enumerates as VID 0x303A / PID 0x8360, manufacturer "Work Louder", product "Codex Micro", and adds a fifth HID interface: vendor usage page 0xFF00, report ID 6, 64-byte reports carrying a JSON-RPC-style protocol. The desktop app's bundled device kit discovers hardware by exactly that vendor, product and usage page, and it is transport-agnostic, so a wired board qualifies as readily as the Bluetooth original. On the first plug-in the app detected the pad without a pairing step and ran its device.status, v.oai.thstatus and v.oai.rgbcfg traffic against this firmware with no errors.

The official key numbering runs in the same reading order as ours, so the mapping is position for position:

PadCodex MicroWire id
Keys 1–6 (top row and second row)Agent Keys 1–6, with the six status lightsAG00AG05
Keys 7–10Command Keys (defaults Fast / Approve / Decline / Fork)ACT06ACT09
Keys 11 and 12The two switches under the wide Mic key — push-to-talkACT10 / ACT11
Key 13SendACT12
Dial turn / pressDial step / dial press (hold for settings)ENC_CW ENC_CC / ENC
JoystickAnalog stick, four directionsv.oai.rad

What each key does is configured in the desktop app under Settings → Codex Micro, not on the pad, and gestures such as double-press and hold are timed by the host. That is the point: in this mode the app owns the keys, exactly as it owns the original. The pad's own keymap is bypassed while it lasts.

What does not go away is everything of ours. The OpenMicro vendor interface stays on the composite device, so the companion app still connects, firmware updates still work, and the mode switch below is always reachable. The desktop app ignores the extra interfaces. It does open its own interface exclusively, so any probe holding it makes the app's connection fail until the probe exits — the repository's scripts/test-codex-compat.py exercises the mode end to end, and you quit the desktop app before running it.

Switching, with and without the app

Compat mode is off by default and survives reboots once chosen. Two ways to flip it:

The choice lives in the reserved byte of the saved keymap blob. The layout did not change, so older firmware ignores it and a downgrade falls back to OpenMicro mode. Two housekeeping notes: macOS may show Keyboard Setup Assistant the first time the pad appears under each identity — dismiss it, nothing is wrong — and on Linux the second identity needs its own hidraw udev rule for 303a:8360, documented alongside the existing ones.

Where the protocol came from

The protocol is undocumented. This firmware is an independent Rust re-implementation of the behaviour written up by two MIT-licensed projects that emulate the device over Bluetooth, imliubo/codex-micro-4-core2 and digitsisyph/codex-micro-stopwatch. Neither had validated USB; that part is now confirmed against the real app. The codec is pure core Rust with host-side tests against the payload shapes those projects' probes use, and the identifiers are emitted only so a compatible host recognises the device. One id, ACT11, is inferred from the numbering rather than observed, and a desktop app update can change the protocol without notice. The mode stays off unless the owner turns it on.

Profile templates: the stock keycaps, wired

OpenMicroKbd with the stock keycap set installed — a star, a yellow crowned mascot, four clear caps, a grid, a check, a cross, a terminal prompt, a microphone, a party popper and a robot — surrounded by loose spare keycaps
The stock set: ★, the mascot, four clear caps over the activity LEDs, then grid, ✓, ✗, terminal, mic, party popper, robot.

Every board leaves the bench with the same keycaps, and until now a fresh profile was a copy of the default with generic labels. Now the + menu offers Empty profile — nothing bound, a blank slate — or Templates ▸ Codex / Claude Code.

The templates share one design rule: every printed key is a plain keystroke stored on the pad. No host interception, no Accessibility permission, nothing that stops working when the app is closed or when the pad moves to another machine. The encoder, joystick and touch pad keep their volume, arrow-key and play/pause defaults, and names de-duplicate (Codex, Codex 2, …). Anything can be re-bound afterwards like in any other profile.

The Codex template

This one targets Codex in the ChatGPT desktop app, and it follows the Codex Micro's own layout rather than inventing one. The clear second row is the session selector: the app's "open recent chat 1–4" commands, the same slots the Micro's Agent Keys follow by default, under the same four LEDs that show agent activity. ✓ and ✗ answer approval prompts. The rest follow their pictures.

Where the chords came from matters, because guessing is how a template ends up typing "π" into a terminal. They were read out of the desktop app itself: its bundle carries the Codex Micro keycap catalog, which maps each cap to an app command, and every command's default keybinding, then cross-checked against the app's shortcuts reference. Chords the app defines as "CmdOrCtrl" resolve to ⌘ on macOS and Ctrl on Windows and Linux, and the template does the same at build time; the few it binds with a literal Ctrl stay Ctrl everywhere.

CapLabelChord (macOS · Windows/Linux)In the desktop app
ATTN⌘⌥A · Ctrl+Alt+ANext chat needing attention
MascotNEW⌘N · Ctrl+NNew chat
Clear ×4CHAT 1–4⌘⌥1…4 · Ctrl+Alt+1…4Open recent chat 1–4
GridMENU⌘K · Ctrl+KCommand menu
APPREnterApprove request
REJEscDecline request
TerminalTERMCtrl+`Toggle terminal
MicMICCtrl+Shift+DStart dictation
Party popperSIDE⌘⌥S · Ctrl+Alt+SOpen side chat
RobotMODELCtrl+Shift+MModel picker

Three of the Micro's signature actions are missing on purpose: Fast mode, Fork and Send have no keyboard chord in the desktop app at all. The real Micro reaches them over its native protocol — which is exactly what compat mode above gives you. A plain keystroke cannot, so the template does not pretend.

The Claude Code template

Claude Code is a terminal program, so its template speaks the CLI's documented interactive-mode shortcuts, which are the same on every operating system. ✓ confirms a permission prompt with Enter, ✗ interrupts or declines with Esc, the mascot cycles permission modes with Shift+Tab, the grid toggles the task checklist, the terminal cap opens the transcript viewer, the mic is push-to-talk once /voice is on, the party popper toggles fast mode and the robot switches model. The four clear caps carry the quiet utilities: background the running task, stash the prompt, search history, open the prompt in an editor.

One caveat that is really a terminal caveat: Claude Code's Option+P and Option+O reach it on macOS only when the terminal sends Option as Meta. iTerm2, Ghostty and WezTerm do by default; Apple Terminal needs Use Option as Meta key switched on in the profile's keyboard settings. Option+T is handled by Claude Code itself.

Which mode, when

If you live in the ChatGPT desktop app, switch compat mode on and stop thinking about it. The app assigns the keys, lights each Agent Key with its chat's state, turns the dial into reasoning effort, holds push-to-talk on the mic, and gets Fast, Fork and Send — the things a keystroke cannot do.

If you live in a terminal, in Claude Code, in the Codex CLI, or in anything else, stay in OpenMicro mode and start from a template. The keys are yours: every one of them is a plain keystroke you can rebind, the four transparent keys still show agent activity from the hooks the app installs, and the pad behaves identically on any machine it is plugged into.

Both modes coexist on one board. Nothing about compat mode is a fork of the firmware, and the companion app keeps working whichever identity the pad booted with.

Get it

Firmware 0.8.0 and app 0.12.0 ship together as release v0.12.0: notarized macOS DMGs for Apple Silicon and Intel, portable Windows ZIPs for x64 and Arm64, and the firmware as .bin, .elf and .hex with checksums. An installed app offers both updates itself — the app update first, then the firmware prompt — and flashes the verified image over USB with no buttons to hold. Compat mode and its Settings toggle need firmware 0.8.0 or newer; the templates need only the app.

The details are where they always are: fw/README.md for the protocol, the boot chords and the provenance notes, and app/README.md for the templates and the full key tables. If you build one and the desktop app does not see it, or a chord lands somewhere unexpected on your terminal, the Discord is the fastest place to say so.

★ Get v0.12.0 Join the Discord ← All Posts