-
The OS Upgrade Tax
Two apps, three Tahoe regressions, one afternoon — the price of shipping a macOS suite through an OS upgrade.
-
The Column I Couldn't Copy
Last week I needed to copy a single column out of an HTML table in an email, and discovered that the boring solution — copy the whole table, paste it somewhere, trim it back — is a fifteen-second tax on a one-second intention. So I built CopyLens. Draw a rectangle anywhere on screen; if there's text inside, it lands on the clipboard as text. If not, the cropped image does. Same gesture, two outcomes. Plus a full-disclosure note about how the OCR engine actually got built, which wasn't by me.
-
Rainy Day Isn't a Screensaver
Rainy Day shipped this past weekend. The product page calls it a screensaver. The bundle on disk is a regular .app — no .saver in sight. This is the story of why. A run-down of the macOS frictions that ended my attempt to build it the orthodox way: WebContent suspended within seconds of activation, an Apple SPI that no longer works in macOS 26, a CARenderer that returns blank frames, ScreenCaptureKit edge cases when the saver occludes the screen it's trying to read, multi-instance lifecycle thrash from System Settings previews, and the way ad-hoc signing burns TCC grants on every rebuild. And then the architecture I ended up with — LSUIElement app, SMAppService login item, idle-driven fullscreen NSWindow at screenSaver level — which side-stepped every one of those frictions in an afternoon.
-
Putting The House In Order
Two weeks of housekeeping on the Jorvik estate. It started with Spotlight launching the wrong version of an app, ended with a 1,100-line refactor of Release Manager, and surfaced about ten gigabytes of accumulated nonsense in between. This is the diary of the fortnight: what the audit found, what `ps` told me about my own apps, and why a clean filesystem is a clean countertop.
-
I Deleted Most Of My Release Manager
My Release Manager was a 1,600-line Swift pipeline that built, signed, notarised, packaged, and shipped every Jorvik app. Today it's a 770-line dispatcher, and the work it used to do happens in shell. This is the story of why I stopped reaching for Swift, and what I learned about treating the right tool as the obvious one even when it isn't the prestigious one.
-
The Icons Behind The Notch
MenuTidy was the app I'd quietly filed away as 'done' — collapses your menu bar, cleans up clutter, ships. Today I added a feature I'd been trying to ignore for months: a way to actually click the status icons that the notch on MacBook Pros has politely hidden behind itself. I also fixed a position-memory bug that had been quietly lying to users for months.
-
Default ON Was The Wrong Default
I changed the rendering format of the standard "background pill" option of our menu-bar apps. I set the default to "on", propagated deployment across eleven apps in a sweep, and then realised it was silently changing settings for upgraders who'd never touched the toggle. The pill that came shipping with everyone's next update was a small surprise nobody asked for. A short lesson in `UserDefaults.register`, the difference between "fresh install" and "user with no preference set", and why reversing a convention across eleven repos in one go is sometimes the only honest move.
-
The App I Needed At 1am
"I've lost my mouse pointer" demanded a tiny one-shot utility — and taught me a lesson in why "give the user a Terminal command" is a poor recovery flow when she doesn't have a mouse pointer. Building MouseCatcher, bundling it with ActiveSpace, and the install-permissions detour that nearly derailed it.
-
When the Stars Align (Final Cut)(Maybe)
The latest version of ActiveSpace is shipped. Third and final post in the stars-align saga: the 640×480 virtual display from the Redux turned out to be a perfectly valid second monitor as far as macOS was concerned, with the Dock and cursor both happily wandering onto it. A drift reposition, a cursor fence, and the satisfying deletion of a self-restart mechanism the data showed wasn't needed.
-
Screen Savers Still Exist
I built a screen saver, and why not? It's a full-screen canvas that activates when you step away from your desk. Some would call it a relic of the CRT burn-in past. I say it's a dashboard, a photo frame, an ambient display. It's just wearing the wrong name.
-
Fine, Apple. You Win
Three months of stubbornness, then an afternoon of capitulation. The follow-up to "The Deploy Problem Nobody Talks About": every Jorvik app now ships a signed .pkg installer alongside the .zip, closing most of the quarantine-and-translocation friction the previous post complained about. Why .dmg would have solved nothing, what macOS Installer actually does on your behalf, and — because no release week is complete without one — the story of a build pipeline that silently shipped one of my apps without its own bug fix.
-
The Deploy Problem Nobody Talks About
You can build, sign, notarise and publish a macOS app in three minutes — and still lose hours getting it to run correctly on someone else's machine. This post unpacks the gap between 'released' and 'correctly installed' that only exists when you distribute outside the Mac App Store.
-
Version Numbers Are a Promise
A version number looks trivial — MAJOR.MINOR.PATCH — but for a single app it lives in five places (plist, GitHub release, config, git tag, installation), and any failed step pulls them silently out of sync. This article walks through how our Notes Editor ended up at four different versions simultaneously, why git describe can lie when tags are close together, and how we reworked our Release Manager pipeline to keep the build, release, tag, config, and installed binary all telling the same story.
-
Notarisation is Not Notarisation
A deceptively simple naming mismatch unravels an entire macOS release pipeline, revealing how fragile even well-engineered systems can be when assumptions leak between build, packaging, and runtime environments. In this deep dive, we trace how differences between PRODUCT_NAME, bundle names, and display names caused subtle but cascading failures across signing, notarisation, auditing, and distribution — despite a meticulously designed 10-stage pipeline.
-
Why I Don't Ship Preferences
Most software overloads users with settings — but what if that’s the problem? In this article we argue for fewer preferences and stronger defaults, showing how opinionated design reduces complexity, improves usability, and lets software just work.
-
Typography Matters
Typography on the web is mostly wrong — straight quotes, double hyphens for dashes, three dots for ellipses. Not because writers don’t care, but because the tools don’t care for them. Here’s how the Notes Editor and Web Editor handle curly quotes, smart dashes, acronym wrapping, spell-check suppression, and widow control — so the writer focuses on content and the toolchain handles the rest.
-
When the Stars Align (Redux)
The instant space switching technique that worked on two monitors and broke on one. The twelve-hour debugging odyssey that followed. And the absurd, brilliant fix that saved it.
-
When the Stars Align
How two open-source projects, a handful of undocumented APIs, and a Thursday morning conspired to make macOS space switching instant.
-
The Case for Small Software
Why every Jorvik app is deliberately small, single-purpose, and unburdened by features it doesn't need — and why 1,200 lines of Swift is a feature, not a limitation.
-
Spell-Checking in Three Lines of Code
Adding spell-checking to the Notes Editor took three lines of configuration and one delegate method. This is what building native gets you.