boxboxbox
i didn't want the codex micro. i wanted mine. edition of 1.

boxboxbox. a box that operates boxbox. the caps still say 7 8 9, and they're wrong about everything.
there's been a dead numpad in my desk drawer for a few months, ever since i simplified the desk and admitted i barely used it.
two weeks ago openai and work louder shipped the codex micro and it's fucking gorgeous. thirteen keys, a joystick, a rotary dial, agent lights breathing under the caps. $230. sold out same day.

render from work louder's page.
i was never going to buy one. i don't even use codex. what am i gonna do with a controller for a product i don't use, put it on the shelf next to the wiis?
but i kept coming back to the page, because a little pad of physical keys for agent stuff is exactly what i'd been wanting. one big fat push to talk key, most of all. wispr flow has quietly taken over how i work, and wispr wants the globe key. my daily keyboard is a 44 key split. there is no room for planets on it. push to talk lived on a mouse button for a while. hated it. every single press.

and the flat's empty this week. senna's keeping me company, and without him this would be a lot worse, but ngl i've still been a little lonely. a little stressed about the future too. when i sit idle the chatter gets loud. i wasn't shopping for an agent controller. i needed something to build.
when i saw the codex micro, i looked at my drawer and thought, hold my beer.

nothing in this stack can tell me no
the runtime my agents live in is codemaxxxing, my opencode fork, five months of replacing other people's opinions with mine. the app i answer them from is boxbox. built that too. and i've been rewriting keyboard firmware in c for years, because of course i have.
the codex micro is a product. it needs injection moulding, packaging, a supply chain, a waitlist. it needs fit and finish, polish, zero configuration, zero bugs. it is not allowed to be a janky homebuilt hacky thing.
mine is allowed. mine is encouraged. mine doesn't even need to be finished, ever. their thing has a joystick and a rotary encoder i don't have. for now.
press it. a real numpad works too.
down: a press becomes a prompt. up: the answer comes home as light.
i press a key on my desk and code ships on a server in another city. every repo between the keycap and the model is mine.
the customer is always me
i love building for people. clauseo is me watching lawyers use the thing, hearing what's broken, fixing it, again and again. i love every lap of that loop.
this past week the customer has been me. the complainer has been me. boxbox all week, and now the board too. the backlog is whatever pissed me off that day.
the unlit keys had these gold numerals just sitting there, and the whole thing read as a numpad. which it is. genius observation. but i didn't build it to look like one, so i complained, and 45 minutes later off wasn't black anymore. it's a faint white whisper now, and yes, we auditioned five candidates for the color of off on my actual desk.
the enter key sat there doing nothing. the guide said "arm to launch". launch? launch what? i come from a 44 key board where every single key earns its keep, a dead key offends me personally. launch died on the spot, rip to a feature nobody asked for, including the guy who shipped it.
the first message i ever dictated through the board, verbatim. "yo this is actually a kind of really cool way to code. i'm just sitting watching the screen and pressing a button. insane. is there an enter button on this? the thing is i can type but how do i send?"
i was filing a feature request INSIDE the first message the board ever carried. by the next afternoon enter was a real key in the firmware, and the commit reads "every dead press was the guess being wrong".
i built a pinning system too. press a button, jump to that agent, the agent keeps its key. then i noticed how i actually work. agents are ephemeral, i spin up a fresh one for every task and almost never go back to an old one. pinning made no sense for me, a queue made sense. so the pins died, killed by me, and the nine seats became a ranked queue of whoever needs me right now.
the whole loop, with nobody in the middle of it. mine.
meanwhile, at the actual job
clauseo shipped all week. main moved, reviews got answered, lawyers got their answers.
i also built a keyboard.
both from the same desk, because my job is answering agents and talking to lawyers, and swapping from a legal research product to keyboard firmware is just answering a different thread. i built boxbox exactly so that switching costs nothing. it's a button now. it's LITERALLY a button now, on the board, which the board helped build.
and agents got scary good at writing code. handwritten code is serial. load the whole problem into your skull, type for six hours, one project at a time. that constraint quietly died and nobody threw it a funeral. projects like this used to rot on my someday list because a weekend of firmware for a toy was never going to beat sleep.
now i wake up and the toy is done. i genuinely don't know what to do with that.
four layers of code for one button
what the board does. push to talk for wispr flow, some shortcuts, lights.
what it took. firmware, a daemon, a server, a runtime, with code landing at all four layers. for a button. i know. i'd do it again tomorrow.
the daemon keeps logs, and the logs say the button won. 508 presses and 164 radio holds so far, most of them today. my favorite feature is the least necessary one. hold the wide zero and the whole board becomes a voice meter, violet columns climbing while i talk. me, yesterday, mid build. "idk like the purple visualiser when you talk also looks fucking sexy as well!"
the radio lap. hold the wide zero, talk, it listens.
look at it. LOOK at the animation. i still can't get over it. it's so fucking cool. so so so fucking cool. the visualiser is the best part of the entire build and i'll say it, the codex micro doesn't do this. thirteen keys, a joystick, a dial, and not one of them meters your voice back at you. i'm still not sure what the joystick is even for, and a rotary encoder for reasoning effort feels like overkill, i barely ever change effort levels. one thing on my desk beats the thing that sold out, and it's the thing i use most.
my real keyboard is still right there and i still type plenty, this computer does more than talk to agents. the crkbd wears kailh jades, the numpad wears kailh jades too, obviously, i'm me. but when an agent needs me, i don't reach for the keyboard anymore. i reach for the board. this is somehow my favorite way to code and i built it by accident.
ok nerds, this part is for you
everyone else, next section.
the board is a magicforce mf17. the mcu is a geehy apm32, an stm32f072 clone whose dfu bootloader never acks the leave request, so every flash "fails" with a timeout after the firmware has already landed. unplug, replug, forgive.
the firmware is a custom qmk keymap in c. raw hid on usage page 0xff60, 32 byte reports. six opcodes go down (hello, palette, frame, global brightness, ping, mode) and three come up (hello ack, key events, mode echo). a 16 slot color palette and a 4 bit perceptual brightness curve live in rom, so a full frame for all seventeen leds is seventeen bytes, palette index in the high nibble, level in the low. there's a 2 second watchdog, and if the host goes quiet the board falls back to its old donor colours and types numbers again. i wanted that. if everything above the firmware dies, the thing on my desk is still a numpad. also, hard won. never enable via. it squats the raw hid usage page and nothing tells you why your protocol went deaf.
the daemon is about three thousand lines of bun on my mac, under launchd. it holds the hid device, watches the boxbox server over sse, and decides every light. raw presses become four verbs (tap, hold, double tap, chord) with timings in a config file that hot reloads while it runs. the voice meter records through sox because ffmpeg was dropping three audio frames in four. there is a small c wrapper whose entire job is making macos show bun a microphone permission prompt. tccd does not negotiate with bun.
the server is boxbox-web on a vm, and the board is just another client of it, same as my phone. it serves the ranked queue. permissions first, then questions, faults, reviews, unread, and under all of those, whatever is working, pulsing lime. the runtime is codemaxxxing on three machines, and it grew a queue depth field on busy sessions specifically so a working key can blink how many prompts are stacked behind it.
seventeen keys, three index systems. wire order, how the daemon thinks. led order, how the ws2812 chain physically snakes through the board, bottom up. matrix order, how the switches scan. every off by one all weekend was one of these three lying about the other two.
first light
there's a commit from saturday called "first light". the one right after it is the one i love. the palette, recalibrated by photograph.
here's the thing about agents writing led code. the model cannot see the board. it knows what #be00ff looks like on a screen, but an led under a smoked cap is a different animal, and every board's leds are their own animal on top of that. writing for a screen and writing for hardware are just not the same job. so the first palette came up so dull the thing looked half dead, and i did the only sensible thing. i started sending photos. "yo this is how dull it is." photo, new curve, photo, new palette. and then i pointed the model at the firmware i'd written for this exact numpad by hand, years ago, when i picked the colors myself, and said go look at what past me chose. past me had taste. between my photos and his old code, the board finally matched the board in my head.
so i'd picked these colors twice, once by hand in the old firmware, once now. i wrote the spec. i knew exactly what it was going to look like.
didn't matter. the formation lap ran, one violet light sweeping the perimeter, and the messages i sent that hour are "omg yes the hello worked" and then "okay wow that was fuckign coooool as fuck yo". typo preserved.
it exists. it exists. the thing from my head is sitting on my desk and it EXISTS.
same feeling as the last brick of a lego set. magical, and you knew the whole time what it would be. holy fuck anyway.
sold out at my house too
after it worked i decided it was too cool not to have a product page. that's the entire reasoning. i want everything i've built to have its own page on this blog eventually, so the numpad goes first.
boxboxbox, the scale 1/1 pit wall kit. paint guide, parts map, a factory test you can actually take, a warning label, and an assembly manual that assembles you, because the kit ships pre-built. part of it is honestly just a user guide for me, i WILL forget my own shortcuts. part of it is that code got cheap enough that "this deserves a product page" is a thing you can say out loud and then simply have. and part of it is that fable 5 is stupidly good at visual stuff and i wanted an excuse to let it cook.
the name is boxboxbox, by the way. it's a box that operates boxbox. yeah. i'm not selling it, so it doesn't have to be a good name. it just has to be mine.
units produced, 1. availability, sold out, see units produced. a product page with no product on it. a janky homebuilt numpad doing an impression of an openai hardware drop, with a more thought out product page than half the real products i've used. it fits me exactly, down to what color "off" is.
it will also never be finished. the three machine keys learned a new job tonight, starting fresh chats, while i was writing this paragraph. that's the point of owning it.
the fastest promise i ever kept
the last post ended with a promise. the firmware compiles, zero leds have lit outside a browser, and when they do, that's the next post.
first light landed twenty four minutes after i hit publish. full honesty, i knew it was close, half the thing was already built when i wrote the line. still counts.
so this is the next post. the board is on, and a key just went gold to my left. gotta go.