Releases: michellzappa/headroom
Release list
v1.2.6
Headroom 1.2.6 (build 205).
What changed
Changed
- iPhone drops to three tabs. Quotas and Settings both leave the bar: quota
detail is reached from Overview, where the rings already are, and Settings
becomes a toolbar button on every tab instead of a destination competing with
the data. Five tabs for four screens and a preferences pane was one bar doing
two jobs. - The Mac app icon sits on Apple's icon grid — a rounded 824-of-1024 tile with
clear margins, no baked shadow — instead of a full-bleed square. macOS masks
nothing for you, so the Dock was drawing a black rectangle among rounded
ones. iPhone, Watch and the App Store PNG are unchanged: those masks come
from the system, and App Store Connect rejects alpha. - The Welcome window's On your phone pane shows the mobile token itself,
with a Copy button, instead of sending you to Settings to fetch it — a detour
on the one screen whose whole job is getting the phone paired. If the host
has not written the token yet the pane says so and offers to look again. scripts/update-app.shcloses the app up front and defaults its prompt to
yes.
Fixed
- The ESP32 sealed its panel edge in a fixed colour, so every cold-blue boot
frame got a warm strip along the bottom, repainted each splash frame while
the picture above it rolled. It read as the bottom of the panel
misbehaving. The canvas now seals to whatever colour it last cleared to, and
scripts/render_esp32_preview.pymirrors the seal so previews stop promising
pixels the panel eats. - The ESP32 quota page reclaimed 22px it was reserving for page dots nothing
draws, which had left 50px of nothing under the chart against 28 above the
header.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
What's Changed
- fix(scripts): close the app up front, default the prompt to yes by @michellzappa in #11
Full Changelog: v1.2.5...v1.2.6
v1.2.5
Headroom 1.2.5 (build 198).
What changed
Added
- Coding-agent approvals show the agent's actual request. Every field the
provider sent is listed in reading order with its own label — anEditshows
the file, the text being replaced and the replacement, tinted so the pair
reads as a before and after. Bulk fields sit behind Show request so the
feed stays scannable. - Why carries Claude's own stated reasons for asking.
- A value the host had to clip says Shortened to fit, and dropped fields
are counted, so a prefix of a command is never mistaken for the whole one. - Each agent row says how long it has been waiting — same words and placement
as an activity row's age, because they are two halves of one feed. A request
that has sat for six minutes reads very differently from one that just
arrived, and the permission hook gives up at around five. - A third answer, Always allow this exact request, saves a permission rule
so Claude stops asking. Headroom writes only the exact command or path it
showed you — Claude's own "Yes, don't ask again" widens a command to a
prefix, and a grant made from a phone outlives the request that prompted it.
The row prints the rule under the buttons before you tap, and glob
characters in paths are escaped so a folder named[2024-06] Reportscannot
match its siblings. Questions are never offered it. - Each row carries the agent's own mark in its brand colour instead of one
generic speech bubble, so a Claude row and a Codex row stop looking alike. - Notices that can only be dismissed can be swiped away. Rows carrying a real
answer cannot: a swipe that denied a permission would send Claude a decision
by accident. - You can answer Claude's questions from the phone. Its options become the
buttons, and tapping one sends the choice back so Claude carries on without
you touching the Mac. No hook can handAskUserQuestiona selection — but a
deniedPreToolUsecall is documented to show Claude the reason, so the
choice travels as the reason. It is a workaround and behaves like one:
Claude sees a blocked tool plus your words rather than a clean result, so it
may occasionally acknowledge the block. Headroom answers only a single
question of two to six options, never amultiSelectone, and everything
else — a timeout, an odd shape, or Ask on Mac — defers, which leaves the
question to appear on the Mac exactly as before. See
docs/agent-attention.md. - Installed hooks are now version 2, adding a
PreToolUseentry scoped to
AskUserQuestion. Settings reports Outdated until you reinstall them.
Fixed
- An
AskUserQuestionrow is readable. Claude's questions arrive through the
permission hook, and the nestedquestionsarray reached the phone as a wall
of raw JSON — the question was in there, but nobody was going to find it. The
row now leads with the question itself instead of "Use AskUserQuestion", and
each option is one control carrying the reason you would pick it. The first
pass listed the descriptions above a row of buttons repeating the same
labels, which said everything twice. - Answer buttons take the account's accent instead of the system blue, so they
belong to the agent that asked. Short answers stay bordered pills; a
question's options are sentences with a reason under each, and tinting those
turned every one into a large coloured slab. They read as plain rows with a
divider and a chevron now — the shape a grouped list uses everywhere else on
the system — with the colour on the chevron. Ask on Mac sits below the
divider rather than among the answers, because it is the way out rather than
another option. - The provider mark moved to the top-right corner of an agent row. Which agent
asked is a property of the row, not the first thing to read in the sentence. - Claude finished responding no longer stacks. A session's finished or idle
notice replaces the one it makes untrue, so the feed carries at most one per
session instead of a wall of identical rows burying the approvals that
actually want an answer. Superseding is scoped by session and kind, so a
notice arriving can never close a permission request you have not answered.
Changed
- The phone used to decode four fields of a request and drop the rest, which
made anEditapproval read as "Use Edit" and aWriteshow a path but
never the content.detail.requestnow carries typed fields end to end; an
unrecognised tool renders without an app update. - The Claude adapter reads
permission_reasons(the documented field) as well
as the olderpermission_suggestions, and keepstool_use_id/prompt_id
for correlation. docs/agent-attention.mdcorrects its claim that structured questions are
notify-only pending provider support. Against Claude Code 2.1.220 the
Elicitationhook returns real form values,updatedPermissionsmakes
"always allow" answerable, anddecision.interruptexists — all four are
wiring gaps on our side, now written down as such.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
Full Changelog: v1.2.4...v1.2.5
v1.2.4
Headroom 1.2.4 (build 188).
What changed
Added
scripts/update-app.shinstalls the latest notarized Release from the
command line. This landed onmainahead of the bump and ships here rather
than in a release of its own.
Changed
- iOS Overview Connected tile names the Mac and its address (Computer
Name · host / IP), not just the last update time. Settings → Connection
shows the same split. - Watch Overall burndown lines are fully opaque, matching the ESP32 glance.
The binding source stays thicker; context sources no longer fade. - Mac Settings moves the Dashboard row limits out of General and in beside the
integrations whose rows they count. docs/attention.mdwrites down what Attention scoring is: hardcoded product
policy, deliberately not a Settings pane. The README and CONTRIBUTING build
instructions also stop being wrong about XcodeGen being optional and about
-sdk iphonesimulatoron the iPhone target.
Fixed
- A source whose login has gone now says Needs sign-in instead of Not
updating, and says it on the card, in Settings, and in Attention. The host
shipsauth_requirednext tostale, so a dead credential is no longer
indistinguishable from a rate limit or a dropped network. - Quota cards show the host's error whenever there is one. The message was
gated onok, which the host deliberately keeps true while it replays the
last good bars — so the failures that had a reason worth reading were exactly
the ones that hid it. A missing Claude token reported eleven hours of frozen
numbers without ever surfacing theclaude loginit was asking for. - Attention calls out a missing login immediately rather than waiting out the
fifteen-minute stale threshold. Waiting does not fix a login. - The ESP32 corner glyph marks a frozen reading, not just a dropped cable. It
was gated on whether the Mac answered, so the case that lasts — the Mac
replying every ten seconds about numbers it has been unable to refresh since
last night — drew nothing at all. Ages now read42m/11h/3d, and a
dead login is prefixed!.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
What's Changed
- feat(scripts): update-app.sh, install a Release from the CLI by @michellzappa in #10
- feat: say Needs sign-in when a credential dies by @michellzappa in #12
Full Changelog: v1.2.3...v1.2.4
v1.2.3
Headroom 1.2.3 (build 182).
What changed
Fixed
- Multi-Mac over iCloud actually connects. The signed app declared the iCloud
container but carried no application identity to bind it to, so CloudKit
refused every request with "Trying to initialize a container without an
application ID". Releases now take the application identifier, team and
container environment from the provisioning profile, the way Xcode does when
it signs. 1.2.2 looked correct by every check available and never wrote a
single record.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
What's Changed
- fix(build): carry the profile's application identity into the signature by @michellzappa in #9
Full Changelog: v1.2.2...v1.2.3
v1.2.2
Headroom 1.2.2 (build 179).
What changed
Fixed
- Multi-Mac says why it is not syncing. A CloudKit round that failed was
discarded without a word, and the host's trouble text only ever described the
folder transport, so every failure showed up as "No other Macs yet" — the
same words a healthy sync with nobody else on it produces. A missing record
type, a signed-out iCloud account and an unreachable network now each say so. - The CloudKit schema ships as
macos/Headroom-CloudKit.ckdbinstead of living
only in Apple's web console. It has to be deployed to Production before
multi-Mac can work at all: released builds are pinned to that environment,
and CloudKit creates record types automatically only in Development. See
docs/multi-mac.md.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
What's Changed
- fix(multi-mac): deploy the CloudKit schema, and say when it is missing by @michellzappa in #8
Full Changelog: v1.2.1...v1.2.2
v1.2.1
Headroom 1.2.1 (build 176).
What changed
Fixed
- Multi-Mac over iCloud now works in released builds. Every release up to 1.2.0
was notarized without the iCloud provisioning profile, so the published app
carried no CloudKit entitlement and Settings reported iCloud as unavailable
on every Mac that downloaded one. Nothing was red: the release was properly
signed and notarized, and only a note in the build log said the feature was
off. The workflow now embeds the profile, and refuses one whose team does not
match the signing certificate. An app downloaded before this release does not
gain iCloud, because entitlements are sealed into a signature. - Settings no longer claims that signed releases can use iCloud. That was false
for exactly the people reading it on a notarized release, and sent them to
download another copy of what they already had. A local build and a release
built without the profile now say different things. - The iOS archive stopped minting a
Created via APIdevelopment certificate
on every run, which walked the team toward its certificate cap and then
failed the archive itself withChoose a certificate to revoke. - iOS release builds no longer break on SDK-specific
CODE_SIGN_IDENTITYkeys
written into the pbxproj unquoted.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
What's Changed
- fix(ci): iOS archive manual signing (TestFlight) by @michellzappa in #4
- fix(ci): quote pbxproj CODE_SIGN_IDENTITY sdk keys by @michellzappa in #5
- fix(test): expect claude-status in AI sources section by @michellzappa in #6
- fix(ci): embed the iCloud profile in released macOS builds by @michellzappa in #7
Full Changelog: v1.2.0...v1.2.1
v1.2.0
Headroom 1.2.0 (build 167).
What changed
Added
- Major Claude outages on status.claude.com light Attention — partial blips
stay quiet.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
What's Changed
- feat: Claude status.claude.com major-outage Attention (1.2.0) by @michellzappa in #3
New Contributors
- @michellzappa made their first contribution in #3
Full Changelog: v1.1.9...v1.2.0
v1.1.9
Headroom 1.1.9 (build 164).
What changed
Fixed
- Claude auth no longer borrows Claude Code's Keychain on every poll. Headroom
imports the plan token once into~/.headroom/oauth/(one file per account),
refreshes only that copy, and never writes back into Claude Code's item. A
Keychain Deny stays denied until you refresh the source in Settings, instead
of retrying every 20 seconds and re-prompting. Named Claude accounts each get
their own Headroom file, same as before.
Added
- Settings → General can open Headroom at login. macOS may still ask once in
Login Items; the toggle says so and links there when approval is pending.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
Full Changelog: v1.1.8...v1.1.9
v1.1.8
Headroom 1.1.8 (build 162).
What changed
Added
- Settings → General can open Headroom at login. macOS may still ask once in
Login Items; the toggle says so and links there when approval is pending.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
Full Changelog: v1.1.7...v1.1.8
v1.1.7
Headroom 1.1.7 (build 159).
What changed
Changed
- Named accounts next to a brand mark show the user label (
Work), not
Claude · Work. The mark already names the tool; repeating it is how a row
of Claude tabs all truncated to "Claude…". Full titles stay in Settings, the
menu bar and other text-only surfaces.
macOS
Download Headroom-macOS.zip, unzip, open Headroom.app.
Notarized — Gatekeeper should accept it on first open.
On first launch the Welcome sheet starts the bundled host automatically. Confirm Claude / Codex / Cursor, then Continue.
iPhone
Install via TestFlight.
Pairing uses the mobile token (Mac Settings → Copy mobile token), not the host token used by the ESP32.
Full Changelog: v1.1.6...v1.1.7