---
title: "What's new in 2.9.16"
description: "A Mac app that stays connected, a new Home with project favicons, and faster recovery after sleep."
canonical: https://tmux-ide.com/docs/release-2-9-16
last_updated: 2026-11-03T09:35:54.000Z
---
# tmux-ide 2.9.16

> A Mac app that stays connected, a new Home with project favicons, and faster recovery after sleep.

`2.9.16` accompanies native macOS alpha `0.1.12`. The CLI/daemon and native app
remain separate installations. Install links are updated after the matching
release assets are published.

This release is about connection stability. The Mac app now recovers from the
faults that used to drop it, the way the TUI already did.

## The app stays connected

When the daemon rejects one pane's update, the app asks for that pane again and
keeps the others running. Before, one bad update ended the stream for every pane
and showed "Input interrupted — reselect pane".

When the stream itself drops, only the stream reconnects:

* The last frame stays on screen, read-only, with a "Reconnecting… attempt N"
  badge and a Retry button.
* Retries continue with backoff, up to 30 s apart. A restarted daemon is found
  again and the same session reopens.
* Keys typed during a drop are refused with a notice. They are never replayed
  into the pane after it reconnects.
* A pane whose source closed keeps its last frame with an "unavailable" badge.
* When a pane is split in or closed from outside the app, for example by
  `tmux-ide open` or another tmux client, the app reconnects with the session's
  new panes in about 0.5–1 s and keeps the frame on screen. A short
  "Reconnecting…" badge can show while it does.

The session catalog also survives a single error. It reconnects, or shows a
notice and retries with backoff, instead of closing.

## After a stall

When the daemon stalls, as it does while a Mac sleeps, tmux pauses the daemon's
view of each pane. Reopening such a session used to rebuild every pane's full history and
could stay at "Connecting terminal" for several seconds. Frames now reuse row hashes
the daemon has already computed. After a 5 s stall, a session with 8 panes opens
in about 1 s and one with 12 panes in about 1.4 s. Without a stall, 8 panes open
in under 0.5 s. Typing after a daemon freeze works without reselecting the pane.

## A new Home

Home is one table of sessions, grouped by machine:

* Each session shows its project's favicon, when the project has one, or a
  terminal icon.
* Rows show windows and panes, last activity and "attached".
* An agent's state appears on its own session's row, such as "Claude · Working"
  or "Codex · Needs input". The separate Agents section is gone.
* A "needs input" pill appears when an agent is waiting. Click it to show only
  those sessions.

Favicons come from fixed names in the session's folder, such as `favicon.ico`
or `public/favicon.svg`. The daemon never follows symlinks, caps each icon at
32 KB, and caches it. Favicons, window counts and last activity arrive with the
session list the app already fetches, in a new v2 sessions resource, so they add
no requests. Older apps and daemons keep working with each other.

Before the app draws a favicon, it reads the image's header. Images larger than
1024 px a side, or 512 px for SVG, are refused, as is anything that would decode
to more than about 4 MB. An SVG that refers to any file, URL or embedded image
is refused too. A refused favicon shows the terminal icon.

Pane titles no longer look like tabs, and the margins around panes are 8 pt.

## Less background work

The daemon now pushes catalog and agent changes to the app instead of the app
polling every 5 s:

* An idle Home makes 3 requests a minute, down from 291, and doesn't redraw.
* Home appears after 8–9 requests, down from 16 in the same test.
* Agent rows stay on screen while they refresh. Only a row whose agent changed
  updates. The daemon reads agent state every 500 ms, so a change shows within
  about 1 s, in the app and in the TUI.

The app checks the daemon's identity once per daemon instance instead of before
every request. Before it sends credentials, it confirms the daemon's process is
still alive and re-checks it every 5 s, so a dead daemon's port doesn't receive
them.

## Diagnostics and smaller fixes

* When a stream drops, the app's log names the check that rejected it, the pane,
  and the daemon's reason. The daemon logs every fault it sends and every stream
  it closes.
* `tmux-ide open` prints a notice when it falls back to a browser that has no
  native controls. The check waits at most 2 s and never applies to the browser
  bundled with the Mac app.
* The Mac app binary no longer crashes when started without arguments.

Update the CLI/daemon and [native app](/docs/native-alpha) separately. Existing
tmux sessions are preserved. Full list of changes:
[CHANGELOG.md](https://github.com/wavyrai/tmux-ide/blob/main/CHANGELOG.md).
