Steven
Steven6 min read

Four Releases in Twenty-Six Hours: Language Plumbing and a Bridge Release

GeekBye v1.7.6 through v1.8.1: a language setting that had never left the laptop, a Cmd+/ overlay that shows your real keybindings, a version with zero code changes — and the chicken-and-egg of migrating your auto-update feed.

Engineering
Release
Desktop
GeekBye Releases
Four Releases in Twenty-Six Hours: Language Plumbing and a Bridge Release

Between a Thursday morning and a Friday afternoon in February 2026, GeekBye shipped four releases: v1.7.6, v1.7.7, v1.8.0, and v1.8.1 — sixteen commits, about twenty-six hours between the first tag and the last. No single one of them is a headline. Together they're a portrait of what small-release weeks actually contain: a feature finally finishing its journey, a quality-of-life overlay, a version number with no code in it, and one genuinely instructive piece of release engineering.

The language that never left the laptop

GeekBye has had a transcript-language setting since September 2025. It worked — locally. Pick Spanish and the on-device speech-to-text pipeline dutifully transcribed Spanish. But grep the v1.7.5 codebase for that setting and you find it in exactly three places: the audio handler, the Settings UI, and the settings hook. Not in the API client. Not in the session tracker. For four months, every request that left the machine was language-blind: backend session records had no idea what language they represented, and the AI chat received Spanish transcripts with no hint that they were Spanish.

v1.7.6 is the release where the setting finished its journey — two commits, one day. The audio session start now carries transcriptLanguage in its payload, and the AI stream-chat request gained the same field, threaded through a small helper that reads the setting and deliberately returns undefined when it's auto or unset, so older backends degrade gracefully instead of choking on a field they don't know. There's a quiet bonus fix hiding in the diff, too: to pass the language, session start had to move after language resolution — which, as we read it, also closed an error path where a session could be started (and counted against limits) and then orphaned when language resolution failed a moment later.

The lesson generalizes: a setting isn't shipped when it has a UI and an effect. It's shipped when it reaches every consumer that should know about it. Ours stopped at the network boundary for four months, and nobody noticed, because the local behavior — the visible behavior — was correct the whole time. (This was the crude first pass at language handling, for the record; teaching the AI to actually answer in the conversation's language is a much later chapter of this story. And note it's a different axis from the interface language — a couple of releases on, shipping the whole app in thirty languages gave the UI its own app_language setting, deliberately separate from the transcript language plumbed here.)

Cmd+/ — an overlay that doesn't lie about your keybindings

v1.8.0's user-facing feature is a keyboard-shortcuts overlay on Cmd+/ — 193 lines of new component, and one design decision worth stealing: it doesn't render a hardcoded cheat sheet. It fetches the live shortcut configuration and renders customKeys || defaultKeys, so a user who remapped their keys sees their keys. A shortcuts overlay that shows defaults to someone who changed them isn't documentation; it's misinformation with nice typography.

The rest is small correctness touches: the overlay positions itself left or right of the app card depending on which side of the screen has room, and dismisses on Escape, on Cmd+/ again, or on a click outside. Cmd+/ itself joins the same remappable preset system as every other shortcut — which matters, because Cmd+/ is "toggle comment" in most editors, and a tool for developers shouldn't squat on an editor key you can't move. (That same remapping editor is where, a few releases later, a one-line safety valve for cancelling a half-finished rebinding produced a React crash that was born and fixed in twelve minutes — the machinery that lets you move a key is deceptively easy to break.)

The bridge release

The interesting engineering happened in the version numbers nobody would look at twice. v1.8.0 also migrated the project's releases to a new GitHub organization — org housekeeping on the surface, except for one property of desktop auto-update: the feed URL is baked into the binary. Every v1.8.0 install polls the new organization's releases. And every install out in the world — all of them v1.7.7 or older — polls the old one, forever, unless something appears there.

That's the chicken-and-egg: publish your next release only to the new repo and the entire existing fleet never sees it. Sixteen minutes after the v1.8.0 tag, a new flag landed in the release script: --publish-owner, which rewrites where electron-builder uploads the artifacts after the build — explicitly "without affecting the compiled app code," as the code comment puts it. That's the whole trick, and it's exactly the right seam: the binary's baked-in feed and the artifacts' upload destination are two different decisions, and a migration needs them decoupled for one release. Build v1.8.1 pointing at the new feed, upload it to the old repo; old clients see the update there, install it, and wake up polling the new organization. The commit message calls this a "bridge release," which is the right name. v1.8.1 was tagged two hours and twenty minutes after v1.8.0. (For the origin story of why this project treats auto-update with respect bordering on fear, see the auto-update that made our app unkillable.)

And v1.7.7? One commit. The version bump itself. No fix, no revert, no explanation in the history — our best reading is a publish that needed re-running, and we'd rather admit that than invent a story. Sometimes a version number exists because releasing software is a real-world process with real-world hiccups, not a pure function of the source tree. As for why 1.7 became 1.8 at all: no commit says, but the feed migration is the meaningful compatibility boundary — every 1.8.x binary looks at a different organization than every 1.7.x binary — and that deserves a minor bump more than any feature does.

Three things this week taught us

  1. Trace a setting to every consumer. The language preference was "done" for four months while the backend stayed blind. The visible, local behavior being correct is exactly what let the gap survive — the audit question is "who else should know about this value?", asked at every boundary.
  2. Render live config, not documentation. The shortcuts overlay reads the same source of truth the shortcut system uses. Anything else drifts the first time a user customizes.
  3. A feed migration needs one release that lives in both worlds. New feed in the binary, old repo for the upload. If your release tooling can't separate those two targets, add the flag before you need it — ours arrived sixteen minutes after it was needed, which is close enough to count.

For the previous chapter in the v1 story, the login page IS the demo (v1.7.5); for the next, redesigning the dashboard around one wave chart (v1.8.2); and for the whole arc, the anatomy of shipping software to perfection.

Related Articles

The Three Verbs That Keep Web Audio Alive
Steven
Steven9 min read

The Three Verbs That Keep Web Audio Alive

Two GeekBye point releases, two months apart and in two different files, taught our audio code the same lesson from opposite ends: stop treating the browser's AudioContext as disposable. One release learned to resume() a context macOS had silently suspended mid-recording; the other learned to suspend() instead of close() so back-to-back sessions stop slamming into Chromium's roughly-six-context ceiling. Resume, suspend, close — that's the whole plot.

Engineering
Audio
Desktop
Telling a Call From an Open App
Steven
Steven9 min read

Telling a Call From an Open App

GeekBye can notice you've joined a video meeting and offer to record it. The detection turns out to be the easy half — a Swift binary reading window titles every ten seconds. The hard half is precision: not firing when Zoom is merely open, not prompting for a meeting you're already recording, and not muting the microphone in the call you're actually in. Three releases, and each one is a guard that had to learn to not defeat itself.

Engineering
macOS
Desktop
Taking the Backend Out of the Upload Path
Steven
Steven8 min read

Taking the Backend Out of the Upload Path

GeekBye records your screen and saves the video to your Google Drive. The first version shipped every recording through GeekBye's own servers on the way there; a release later, the file went straight from your machine to Drive, and the backend was demoted to holding a single pointer. The interesting part is how little code the 'direct, resumable' version actually contains — because the resumability came from deleting a proxy, not from writing one.

Engineering
Architecture
Desktop