Added
See what a Claude or Pi session is doing without reading its scrollback. ⌘J
(Ctrl+Shift+J on Windows and Linux) opens an inspector beside the terminal: the
agent's plan, with the tool calls each step ran nested under it, and the full
timeline below. In a grid, the same key turns every tile into its session's plan
and live tool feed, and ⇧⌘J (Ctrl+Alt+Shift+J) gets there from any view. Grid
shortcuts keep working, and typing never reaches a hidden terminal. If an agent
stops reporting mid-turn, its activity greys out and says how long it has been
quiet; shells and other agents that report nothing say so instead.
Sessions running Claude now show how far the agent is through its own plan.
A small pie under the session's state dot fills as the agent works through its
task list, taking its colour from the session state and fading to grey when
the agent stops reporting.
Recent Claude models only provide their task-list tools when a session opts in,
so Hive now turns them on for the Claude sessions it starts. They use some of
the model's context; turn them off under Settings → Agents ("Show Claude's plan
progress in the sidebar"). The change applies to newly started sessions, and a
CLAUDE_CODE_ENABLE_TODO_TOOLS you set yourself is always left alone. Hive already received the plan and every tool call
on each hook and threw them away; it now keeps the last 200 tool calls per
session in memory, ready for the activity panel and grid to come.
Tool arguments never leave the machine that ran them: the hook derives a short
label — a file's basename, a command's first word, a URL's host — and only
that is sent, so a command carrying a token or password cannot reach the
daemon, another window, or the menu bar.
Claude sessions that hand work to subagents now show how many are running, as a
small number on the corner of the plan pie in the sidebar. A subagent's tool
calls no longer take over the session's "running" tool or count against the
parent's plan steps, and a subagent still working after the main agent has
finished no longer flips the session back to working. The plan pie is also
easier to read on dark themes: it's now outlined in the session's state colour,
and it stays tucked under the state icon.
Two new theme presets in Settings → Appearance → Theme, under Community:
Alucard and Hex. Alucard is a warm-black and antique-gold palette
sampled off Ayami Kojima's Symphony of the Night artwork — cream type, gold
accent, moonlight-blue for informational state, and red kept for errors alone.
Hex is the dark-purple one: ink-violet grounds with an amethyst accent, the
saturation held in the chrome so body text stays near-neutral. Neither is a
port of another editor's theme, so unlike the twelve palettes beside them both
are held to the full WCAG contrast gate rather than opting out of it.
Pi sessions now report their tool calls and plan the same way Claude sessions
do. The plan pie fills as Pi works through its plan, and hovering the pie
names the tool Pi is running.
Pi has no task list of its own, so Hive's Pi extension adds a hive_todo tool
to the Pi sessions Hive starts. It uses some of the model's context; turn it off
under Settings → Agents ("Show Pi's plan progress in the sidebar"). The change
applies to newly started sessions. A resumed Pi session shows its plan straight
away, and a new conversation no longer shows the previous one's.
As with Claude, a tool's arguments never leave the machine: the extension sends
only the tool name and a short label, such as a file name, a command name or a
host.
Changed
hivegui.log now records why the window started and why it closed: each launch
logs its parent process and whether it was opened from inside a Hive session, and
each quit says whether it came from Quit, the close button, or a signal such as
killall. Notification clicks and page reloads are logged too. When Hive restarts
itself unexpectedly, the log now points at what did it. Nothing else changes.
Fixed
A tool label that ends in a non-ASCII character (a filename, for example) is no longer cut mid-character when it is shortened to fit the activity view.
A Pi session no longer loses its "needs attention" state when a state report from Pi goes missing: Pi now re-sends its latest state every few seconds, so a question shows as waiting within about 5 seconds even if the first report was lost. A live Pi session also stays on reported state instead of falling back to guessing from terminal output, so the state tooltip reads "reported by the agent" more often. Updating restarts the daemon.
Added
Worktree groups can be named. Double-click a group's title in the sidebar, type a
name, and the header shows it with the branch beside it — so a group of sessions
sharing a worktree can be called "the auth refactor" instead of only being labelled
by whatever git called the branch. Emptying the field clears the name again.
The name belongs to the group, not to its sessions: nothing is renamed, and members
still carrying the branch-derived default name go on showing their window title
instead. It is stored by the daemon against the worktree, so it survives a reload
and a daemon restart, and every open window updates the moment it changes.
Sessions that share a git worktree are now linked in the sidebar. They take the
colour of the session whose worktree they joined, show that colour as a bar on
the right edge of the row, and carry a count on the branch icon; the worktrees
browser names the sessions occupying each worktree instead of only counting
them. Linked sessions also sit together in the sidebar. Dropping one outside its
group — or pressing the reorder keys once it is at the group's edge — moves the
whole group; dropping it on another member, or pressing the reorder keys while
it has room among its own members, reorders it inside the group. Keyboard
navigation, ⌘1-9, the tray and the command palette now all follow the order the
rows are actually painted in.
A session that needs your attention now pulses its sidebar row, so it is
noticeable without reading any row. The pulse is an overlay on whatever ground
the row already has, so a selected row still reads as selected; with animation
disabled it settles to a static tint that stays quieter than the selection
background.
Collapsing a project or a worktree group in the sidebar now animates open and
shut instead of snapping. Collapsed content leaves the keyboard tab order, and
the animation respects the system "reduce motion" setting.
The System theme now lets you pick which preset it uses for each OS scheme — say
Dracula when the OS is dark and GitHub Light when it is light. Two pickers appear
under Theme in Settings → Appearance while System is selected; the defaults are
Hive Dark and Hive Light, so nothing changes until you change it. The choice
applies at boot (no flash of the wrong preset) and follows the OS live.
In-app update now works on Windows, on both the release and the latest channel.
Windows previously got "download it manually on this platform" — advice that was
wrong on the latest channel, which tracks a git checkout and has no release
artifact to download at all. The Update → Updating… → Restart button, the
progress lines and the Reload-vs-Restart distinction are the same as on macOS.
Replacing a running hivegui.exe needs no helper process and no elevation:
Windows refuses to overwrite or delete a mapped image but allows renaming one,
so the update renames the running binaries aside, installs over them, and sweeps
the displaced copies at the next start. A failure part-way through rolls back,
leaving a launchable Hive.
If an update is interrupted in the instant between moving hived.exe aside and
moving the new one in, the next start puts it back, preferring the incoming
image. Before, the startup sweep deleted both halves, leaving no hived.exe and
no way to get one back from inside the app. The same interruption for
hivegui.exe leaves Hive unable to start, so it cannot repair itself: rename
.hivegui.exe.new (or .hivegui.exe.old) in the install directory back to
hivegui.exe.
While an incoming file is less than a couple of minutes old, startup cleanup
and repair leave the install directory alone, so opening a second window cannot
break an update still running in the first.
Two refusals are reported up front rather than after the work: an install
directory Hive cannot write to (move it somewhere you own — %LOCALAPPDATA%\Programs\Hive
is the usual spot), and, on the latest channel, running Hive out of the checkout's
own cmd/hivegui/build/bin, which the build step has to erase.
The latest channel builds through Git for Windows' bash. A bash on the PATH
that launches a WSL distro is skipped rather than used: it cannot reach the
checkout by its Windows path and could not produce a Windows binary anyway, so
it is reported as a missing Git for Windows up front instead of failing part-way
through the build.
The banner also stops telling latest-channel users to "open the releases page
manually", which pointed at a download that does not exist for that channel, and
the button's platform check now comes from the backend — so when an update can't
be applied, the banner says which reason applies instead of blaming the platform.
Note for Windows: the download is checksum-verified but, unlike macOS, not
signature-verified — no Windows release binary is signed, so there is no
publisher to pin.
Changed
New sessions are no longer named after the agent they run. An auto-generated
name is now just adjective-noun, and a session started in a worktree takes the
branch name alone — every surface that shows a name shows the agent beside it,
so carrying it in the name said the same thing twice. Sessions created before
this change keep the names they have, and renaming is unaffected.
Sidebar rows no longer print the agent twice. An auto-generated session name
ends in the agent's own id ("rising-shore claude"), which the row then repeated
as a two-letter code; the name now drops that trailing id at display time — the
stored name is untouched, so rename, search and the hive CLI are unaffected,
and a name you chose yourself is never altered. The two-letter code now carries
the agent's own colour as a tint, so the agent is visible at a glance without
reading the row. Agents that declare no colour render the code plain.
A session's colour is now a bar on the right edge of its sidebar row instead of
a filled square in its own column, and the bar is the colour control: hover it
or tab to it and it widens, and clicking opens the same colour picker as before.
The row reserves the widened width at all times, so nothing moves when it grows.
The compact sidebar density keeps the window title as its single line instead of
the session name. The title is what tells apart two sessions that share a
worktree — they are named after the branch — so it is the line worth keeping. A
session that has published no title still shows its name.
The project header in the sidebar is now a flat uppercase label with a hairline
rule instead of a bordered card, and the active project is marked by the label
taking the accent colour. Both the project label and a worktree group's branch
header stay on screen while you scroll, the group header pinned directly under
the project label, so rows are never visible without the project and branch
they belong to.
The worktree group in the sidebar is now a flat band rather than a rounded,
inset card: a hairline above and below, running the full width of the list.
It matches the project label directly above it, which stopped being a card in
the same release, and it gives the width back — sessions inside a group line
up with the sessions outside one and their window titles get 18px more room
instead of being the narrowest rows in the sidebar.
The window title under a sidebar session name now uses the full width of the
row. It was boxed into the name's column and truncated early, while the space
beside it went to icons that only line 1 uses. Row height is unchanged.
Sessions that share a git worktree now render as a group: a bordered panel
headed by the branch name and the number of sessions in it, collapsible from
the header. Because a worktree session is named after its branch, those rows
used to be identical to each other; inside the panel each row leads with its
window title instead, and the branch is stated once at the top. A session you
renamed yourself keeps its name. The colour bar belongs to the panel — the
whole group shares one colour — while the colour picker stays on each row.
Fixed
A Claude or Pi session that finishes its turn now shows "Waiting for you" and pulses
in the sidebar, instead of dropping quietly to idle — the agent is done and ready for
you whether or not it asked a question. Switching to the session or typing into it
clears it, the same as any other wait.
A failed turn now stays visible too. A Claude API failure used to flip to error and
then fade back to idle the next time the screen redrew, and Pi never reported its
failures at all. Both now show the error glyph, raise a notification, and keep it
until you look.
Custom agents whose command runs claude or pi now report their state like the
built-in agents do: working, waiting for you, finished turns and errors, instead of
guessing from terminal output. A wrapper script around them (for example a
claude-lite shell script) is not recognised and still guesses.
The command field in Settings ▸ Agents now keeps what you type, including a trailing
space, and no longer lets macOS turn -- into an em dash.
A failed Claude turn now keeps its error glyph until you look at the session. About a
minute after any turn, Claude sends an "idle" notification, and that was quietly
turning the red cross into a plain "Waiting for you" before you had a chance to see
what went wrong.
Minimized sessions no longer stay in the sidebar as dimmed rows that ⌘↑/⌘↓ skip over. Minimizing a session now takes it out of the sidebar, the same way minimizing a project does, so every row you see can be reached from the keyboard. Get it back from the tray above the status bar or with ⌘K. If the session you are on is minimized, its row stays until you move to another session.
⇧⌘↑ / ⇧⌘↓ also skip minimized sessions now. The active session moves past the next visible session instead of swapping places with one you can't see, and the minimized session keeps its place in the order.
Ctrl+Shift+V pastes once instead of twice. The terminal read the clipboard and
wrote it to the session itself, but never cancelled the keypress, so the webview
also ran its own paste on top — the same text arrived twice on every use. The
paste now also goes through xterm's paste path, so multi-line clipboard content
keeps its newline normalisation and bracketed-paste framing instead of being
written raw, which had agents submitting once per pasted line.
Pasting, mouse tracking and arrow keys keep working after a session is
reattached or the layout changes width. Repainting a tile begins with a soft
reset, which clears the DEC private modes the running program set — and the
program never sends them again, because it has no idea a new client attached.
Only the cursor and alt-screen were being restored, so everything else was lost
for the life of that tile. Bracketed paste was the visible casualty: without it
agents guess where a paste starts and ends, and anything over about 1 KiB
arrived as several separate pastes, because that is where the operating system
splits a write to the terminal. The daemon now tracks those modes and re-asserts
whatever was live, both in the reattach snapshot and in the resize replay — and
turns off the ones the program switched off while nobody was attached, so a
finished TUI no longer leaves mouse tracking on and spraying click codes into
the shell that follows it.
A session that had printed more than 8 MiB of output got slower and slower to write
to — permanently. The raw scrollback ring trimmed itself by allocating a new buffer
at exactly the retained size and copying the whole thing across, so every later PTY
read re-copied the full 8 MiB and threw away ~19 MB of garbage: about 1.7 ms of CPU
per read. On Windows, where ConPTY hands back roughly one line at a time, that cost
was paid per line of output and capped a busy session at tens of KB/s.
The ring is now a fixed circular buffer allocated once, so trimming is a pointer
move: no copying, no allocation, and the same bytes come back on reattach. Writes
past the cap are roughly a thousand times faster, and steady-state scrollback churn
allocates nothing at all.
Sessions no longer render monochrome when the GUI happened to be launched from
a shell with NO_COLOR set. Hive built every session's environment from the
daemon's own, overriding only TERM, so a NO_COLOR that reached hivegui by
inheritance was handed down to every agent and shell in every tile and stayed
there for the life of the daemon — with no setting anywhere to explain it. A
tile is a colour-capable xterm.js terminal whatever the GUI was started under,
so the variable is now dropped when a session's environment is built, for the
same reason TERM is already forced.
Review fixes for the sidebar redesign: sessions sharing a worktree no longer
paint a second colour bar on every row, a shell session's name drops its
repeated "shell" suffix like every other agent's (so two shells on one worktree
are told apart), a grouped session with no window title shows its name instead
of an empty line, the agent glyph stays legible on light themes, and a collapsed
worktree group reports any session inside it that needs you rather than hiding
it.
The JSON files Hive expects people to hand-edit survive a UTF-8 byte order mark.
Windows PowerShell's Set-Content -Encoding utf8 always writes one — 5.1 has no
BOM-less UTF-8 at all — and Notepad long did the same, so a file written by a
setup script or corrected by hand is likely to carry one. encoding/json does
not skip a BOM, so the read failed on the very first byte.
In update.json that killed the update check with invalid character '\ufeff' looking for beginning of value, and the update button then stayed dead with
nothing in the app to undo it: the only way back was to find the file on disk and
re-encode it. In agents.json it was quieter and worse — a parse failure there
is answered by disabling every custom agent and logging the reason to the daemon
log, so custom agents simply disappeared from the launcher with nothing on screen
to explain it.
Both now drop a leading BOM before parsing. A BOM is an encoding marker rather
than content, so this does not make either file more forgiving of real mistakes:
settings that are genuinely malformed are still reported instead of being
silently replaced, and a file in an encoding Hive cannot read at all — UTF-16,
which is what PowerShell's Out-File and > write by default — still fails,
which is the honest answer for a file that really is unreadable.
The latest-channel updater now says why it cannot update a checkout that has
wandered off its upstream, instead of relaying git.
Leave an integration or feature branch checked out with its upstream still set
to main and the periodic check keeps finding commits the running build lacks,
so the banner keeps offering an update. Pressing it ran git pull --ff-only,
which has nothing to fast-forward, and the banner showed exactly what git said:
Not possible to fast-forward, aborting. — with the command line pasted in
front of it, and no word about which branch, how far off it was, or what to do.
The updater now compares the branch against its upstream before it pulls, the
same place it already refuses a dirty tree, a detached HEAD, or a foreign
remote, and refuses only when the branch has truly diverged — commits ahead
and behind at once, which pull --ff-only cannot reconcile. A branch that
is only ahead (or only behind) still updates normally, exactly as before this
change. When it does refuse, it does so in its own words: the branch, how far
ahead and behind it is, and the way back — git checkout main for a
differently-named branch, or to push or move the local commits when the
diverged branch is the one upstream itself tracks (e.g. main). The
comparison is made against a freshly fetched upstream, not the one the last
periodic check saw hours ago, so the answer is the one the pull would have
found; nothing in the checkout has moved by the time it says so. The four
checkout refusals now live in one place shared by macOS and Windows rather
than two copies that had to be edited in step.
Confirmation dialogs now work on Windows. Deleting a project, killing a live
session, restarting Hive and applying an update all go through a native
confirmation, and every one of them silently did nothing on Windows: the dialog
appeared, but answering it always read as a refusal, so the action was abandoned
before it reached the daemon — with no error to show why. Wails ignores our
button labels on Windows and substitutes a native Yes/No, and Hive only
recognised the macOS OK as consent. It now accepts the labels each platform
actually reports.
Hive no longer flashes console windows across the screen on Windows. Neither
hivegui.exe nor the detached hived.exe owns a console, so every helper they
ran — the git behind worktree inventory and the update check, gh for merged
branches, claude --version, the daemon probe — was handed a console window of
its own by Windows. It arrived in bursts: a stray popup on every poll, and a
volley when checking for an update. Child processes are now created with no
console window, so the work happens where it always should have, out of sight.
Hive no longer gets quietly demoted to Windows' efficiency mode. Windows moves
processes that are not the foreground window to EcoQoS — parked on the
efficiency cores, clocked down — and both halves of Hive fit that description by
design. The session daemon is the one that matters: it runs detached with no
window at all, so it can never be foreground, and it is the half that carries
every byte of agent output through a single-threaded path on its way to your
screen. Nothing had ever told Windows otherwise, so on a machine with
performance and efficiency cores the scheduler was free to decide, and it often
decided wrong — which you felt as a terminal that lagged behind your typing for
no visible reason.
Both the daemon and the window now opt out of execution-speed throttling at
startup, the counterpart to the App Nap opt-out macOS has had all along. On
older Windows, where the API predates the setting, Hive notes it in the log and
carries on: this is a speed-up, never a reason to fail to start.
Sessions on Windows now notice when their process exits. When an agent finished,
a user typed exit, or a tool crashed, the tile stayed alive forever: nothing in
Hive waited on the child, and the session only ever learned about an exit from a
PTY read error — which never came, because conhost keeps the ConPTY output pipe
open until Hive closes the pseudoconsole. The read stayed parked for minutes, so
the session never went to exited, its post-spawn session-id capture kept
polling, and the reader goroutine, its OS thread, the conhost process and the
pseudoconsole all leaked for the life of the daemon. Hive now waits on the
process itself and releases the PTY once the child is gone, after a short grace
period so the last thing the agent printed still lands on the tile.
Ctrl+wheel and trackpad pinch no longer zoom the page out from under the
terminals on Windows. Hive has always owned zoom itself — Ctrl +/- drives a
font size every xterm re-reads — but the GUI never passed Wails any
Windows-platform options, so WebView2 kept its own page zoom running
alongside. The two stacked: pinching resized the page without telling the
terminals, leaving their canvases and their reported rows and columns
disagreeing, and the shell drawing to the wrong geometry.
Two more Windows fixes ride on the same options block: resizing the window
with several terminals open is debounced instead of repainting at every
intermediate size, and dropping a file on the window is ignored, where before
the webview navigated to it — replacing the whole app with a view of that file
and no way back. Dragging sessions around the sidebar is unaffected. macOS and
Linux behave exactly as they did.