Version 0.26.0
New Features
- Live sessions, an experimental restore mode. Sessions have always come back after a restart with their directory, font size and split state, but what comes back is a fresh shell, so whatever was running is gone. Live mode keeps the process instead: each local primary and split pane runs through the bundled zmx multiplexer, so quitting agterm ends the connection to the pane while the process itself keeps running, and the next launch reattaches to it. A build still compiling or an agent halfway through a task is still there. Turn it on in Settings ▸ General ▸ Sessions, where Restore sessions now offers Live sessions beside the existing Fresh shells and Re-run commands, or with
agtermctl restore mode live. The mode is frozen for the life of the process, so it takes effect after restarting agterm. It needs zsh as the macOS login shell; an unsupported shell falls back to fresh shells and Settings says why. Experimental because this is its first release and it changes what a quit means:agtermctl zmx listshows every daemon and the pane holding it,agtermctl zmx pruneclears unclaimed daemons with no attached clients, and switching back to Fresh shells or Re-run commands and restarting reaps every detached agterm daemon in that state directory #515 @umputun - Remote sessions, a first and deliberately limited version. A session running on another Mac can be attached here, where it appears in the sidebar as an ordinary session marked remote, its split included.
agtermctl zmx tree HOSTlists what that machine has to offer andagtermctl zmx attach HOST SESSIONgrabs one of them. Everything goes over ssh and nothing else: no agterm-to-agterm protocol, no port, no listener. Each attached pane is an ssh process holding a connection for as long as the session is open, so closing it here ends your side while the far-side processes carry on. What this version does not do: one attach imports one session rather than a whole workspace, and because the attach is a follower the remote screen arrives at the far side's geometry and does not reflow until the first classified keystroke reaches it, which also means mouse input and Ctrl-L do nothing until then. The requirements sit on the far side rather than this one: it runs 0.26.0 too, its restore mode is Live sessions since that is what puts a daemon behind each pane, and it hasagtermctlon the PATH that ssh gives a remote command. Key-based ssh auth is a precondition, because a non-interactive connection has nobody to answer a password prompt #524 @umputun - no built-in remote picker ships with this yet. The two commands are the whole feature, and the cookbook's
remote-session-pickerrecipe is what turns them into something to use: it lists the far side, puts the rows through agterm's own picker with each one's window, workspace, purpose, directory and running command underneath, then attaches whatever you choose. Wire it to a chord or a palette entry inkeymap.conf. Building a selector into the app is deliberately left until the shape settles #524 @umputun session.contextsets a per-session line saying what a session is for, shown in the title bar and carried on the tree. It survives relaunch and restore, andsession.duplicatedoes not copy it #522 @umputunsession.swapexchanges a split's two panes, moving the terminals rather than the layout: axis and ratio stay put while focus, overlays, status ownership and wait policy follow their terminal #513 @umputunsidebar.widthsets the sidebar divider position from the control API, per window, and echoes the stored width so a clamped request is distinguishable from an honored one #512 @umputunrestore.capturefills the captured-command slots on demand instead of only at exit, for the cases where an orderly quit never happens #452 @ssgreg- cursor shape and blink are settable in Settings ▸ Appearance, which also gets its cursor and font controls rearranged #487 @s1ovac #489 @umputun
- the tree names the shell holding a pane's foreground, so a caller can tell a pane held by a recognized shell from one whose foreground state could not be read. It is not a prompt signal: a shell builtin or a loop runs inside the shell process, so a pane blocked on input looks the same #525 @umputun
Improved
- hidden panes release their GPU buffers instead of holding them for the life of the app. agterm reports occlusion for panes that are not on screen, so a hidden shell stays live while its Metal swap chain is freed after a short grace. Measured on a Debug build with 12 sessions all printing output: 1.1 GB peak with every surface realized, settling to 199 MB once the 11 hidden ones released. It comes with a libghostty pin bump to 683d8db, which carries upstream's hidden-surface GPU work #492 @paul-nameless
- a launch that replays commands paces its pane startup rather than spawning everything at once, which was enough to make a large window's restore stutter #526 @umputun
- a sidebar row whose name is truncated reveals it on hover #520 @umputun
session.restorereports which pane it actually wrote, which a caller addressing by pane token could not otherwise work out #495 @ssgreg- a cookbook recipe closing a session automatically once the command in it finishes #488 @andr81
- the bundled agent skill writes every command with its area prefix. Six families were missing it, so an agent copying a command out of the summary ran something that does not exist #507 @umputun
- the two-agent chat recipe survives labelled Claude composers, multi-agent Codex resume, and transcripts recovered from a bridge #496 #505 #509 #514 @paskal #506 @umputun
Bug Fixes
- an agent spawned from another agent's session repainted the spawner's sidebar row, so the wrong session showed the status #461 @x9x9x9x9x9x91
- one split pane's agent status could erase the other pane's block. A blocked pane now owns the status until it is answered, and a write from the sibling is refused whole rather than half-applied #523 @umputun
- the agent-hooks installer overwrote existing Claude hook data it could not read, and a bad custom regex printed a compile error before every zsh prompt #500 @umputun
- a failed restore save was acknowledged as ok, so a pin the disk had rejected read back as if it were in place #485 @umputun
session.overlay.openaccepted a--size-percentoutside 1 to 100 instead of refusing it #498 @ssgreg- the cookbook's session-badging recipe failed open when it could not badge an armed session #491 @andr81
session type --stdinandquick type --stdinemptied the whole payload on one invalid UTF-8 byte and still answered ok, having typed nothing. Both refuse now. CI jobs also run under timeouts, where all six previously inherited GitHub's 360-minute default #521 @umputun
Signed with a Developer ID certificate and notarized by Apple, so macOS Gatekeeper opens it with no extra steps. Apple Silicon (arm64) only, macOS 14 or later.
- Homebrew:
brew install --cask umputun/apps/agterm - Direct download: open the
.dmgand dragagterm.appinto/Applications.