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