Cirrus is the module that closes the loop between "the model suggested a patch" and "the patch is on your default branch as a PR." Most of the hard design work lived in a single component: the diff card.
Why not just render unified diff?
Unified diff is a text format. On a 5.8-inch screen with dynamic type, a monospace wall of + and - lines is unreadable. GitHub figured this out years ago and so did we: you render each line as a first-class UI row, with a colored gutter indicator, a line number, and the actual code. The gutter tells your eye "added" or "removed" before your brain reads the characters.
The hunk header (@@ -42,6 +42,8 @@) is kept exactly as Git prints it — but in a muted strip at the top of each hunk, not mixed into the code. It preserves the signal to developers who know what it means without polluting the main body for everyone else.
The card is a one-tap atom
Every diff in Cirrus is its own card. The card is self-contained: path on top, add/delete counts, a collapsible body, a copy-patch button, an Open PR button. You can tap the chevron to collapse it out of the way once you've decided to apply it. You can long-press to preview the diff against a specific branch. You can swipe to discard — the model's suggestion disappears and your repo is untouched.
The Open PR action is where a lot of iOS LLM apps give up and send you to a web view. We didn't. The app holds a GitHub personal access token in Keychain, makes the PR creation call with the current patch as the body, and returns a native success sheet with the new PR's URL. If the call fails — bad token, detached HEAD, merge conflict — the failure state is shown in-card, with the actual git error, and the card stays on screen so you can retry.
Keychain is the trust boundary
The token is stored with kSecAttrAccessibleWhenUnlockedThisDeviceOnly. That means: it never syncs to iCloud, never leaves the device, and becomes unreadable the moment the phone locks. Every network call Cirrus makes to GitHub routes through a small Swift wrapper that pulls the token out only when the app is frontmost and attaches it only to HTTPS requests to api.github.com. There is no background sync, no cloud relay, no proxy.
What the model sees
Cirrus passes the model a pruned version of the repo — files you've granted permission for, plus the output of a few repo-local tools (grep, tree, git log) — and it returns a structured diff. We validate that the diff applies cleanly before rendering it. If it doesn't apply, we don't render it; we tell the model to try again. You never see a diff card that won't actually do what it shows.
The part nobody else is going to notice
When you apply a patch in Cirrus, the code change is produced by the model running on your phone. Your source does not leave the device. The only network call in the whole flow is the one that creates the PR on GitHub, and it only fires after you tap Open PR. We've timed it: from prompt to PR on a current-gen iPhone averages 18 seconds for a small patch. The phone did the thinking. The cloud did exactly as much as you asked it to.
Tagged Cirrus · Published Apr 11, 2026 · Back to all posts