Changelog
Install / Update
Section titled “Install / Update”It’s always safe to update while sessions are running. Sessions reconnect automatically.
brew install gmuxapp/tap/gmuxcurl -sSfL https://gmux.app/install.sh | shOr download binaries directly from GitHub Releases.
v1.2.0 - 2026-04-12
Section titled “v1.2.0 - 2026-04-12”Peering internals were refactored into shared sseclient and apiclient
packages, fixing reconnect failures on large terminal snapshots and
sessions disappearing across reconnects.
Session file attribution
Section titled “Session file attribution”The daemon now attributes session files by adapter kind with scrollback matching, fixing cases where sessions lost their title or showed stale adapter badges.
Sidebar and UI
Section titled “Sidebar and UI”Sessions can be reordered via drag-and-drop. Peer labels use hash-based color assignment for stability, and the adapter/outdated badges are replaced by a session info menu. The home and project pages have distinct layouts with better mobile ergonomics.
Features
Section titled “Features”- distinct project page layout and mobile ergonomics (#125)
- (peering) extract sseclient package for shared SSE decoding (#128)
- (peering) extract apiclient package for typed spoke HTTP access (#128)
- (store) add UpsertRemote for sessions already resolved by a peer (#128)
- (sseclient) detect idle streams with configurable read deadline (#129)
- add conversations index for file-backed conversation lookup (#130)
- wire conversations index into gmuxd with lookup API (#130)
- replace stale bool with runner_version and binary_hash (#135)
- (web) move version display from sidebar to home page (#136)
- (web) replace adapter and outdated badges with session info menu (#136)
- (web) peer labels with unique prefix and palette colors (#141)
- (web) drag-to-reorder sessions in the sidebar (#143)
- dismissed sessions no longer reappear after scanner cycle (#115)
- (peering) reconnect loop on remote sessions with large terminal snapshots (#128)
- (peering) preserve session titles forwarded from spokes (#128)
- (peering) keep remote sessions visible across reconnects (#129)
- (web) handle Android autocorrect in mobile input handler (#133)
- (web) guard mobile-input handler with pointer:coarse check (#138)
- (web) polish sidebar logo, spinner visibility, and peer status display (#137)
- (web) surface update notification and clean up dead sidebar import (#137)
- (web) fix session menu clipping, improve button style, rename to session-menu (#139)
- (web) redesign session menu, fix remote staleness, delete dead CSS (#140)
- (web) push home page footer to bottom of viewport (#141)
- (web) use ResizeObserver for terminal fit on initial layout (#141)
- (cli) rename GMUX_VERSION child env var to GMUX_RUNNER_VERSION (#142)
- (daemon) exempt manifest.json from netauth (#145)
- suppress false activity signals during session switching (#144)
- skip unread flag from full-file re-reads on session restart (#144)
- (daemon) attribute session files regardless of directory (#147)
- (web) use hash-based peer color assignment for stability (#149)
- (web) avoid false stale indicator when peer version is unknown (#149)
- (daemon) attribute session files by adapter kind with throttled scrollback matching (#148)
- (daemon) prune orphaned candidates and skip redundant file parsing (#148)
- (daemon) reset adapter title when active session file changes (#148)
- (ci) resolve PR numbers for rebase-merged commits in changelog (#151)
- cover shared peering client packages and planned reliability work (#128)
- add release highlights for v1.2.0 (#152)
v1.1.2
Section titled “v1.1.2”No summary available.
- improve version reporting and install reliability (#124)
v1.1.1
Section titled “v1.1.1”Mutual peers no longer trigger exponential config request storms. The daemon now caches remote configurations on initial connection, replacing per-request HTTP calls that previously caused runaway CPU and load spikes. And other small fixes.
- prevent recursive config fetch storm, zombie daemons, and required peer tokens (#119)
v1.1.0
Section titled “v1.1.0”Sleep recovery
Section titled “Sleep recovery”Peers automatically reconnect and resync after system suspend, clearing stale connections without daemon restarts.
Project matching
Section titled “Project matching”projects.json replaces separate remote and paths fields with a unified match array. Supports exact matching, per-host scoping, and automatic ~ canonicalization. Existing configs migrate on load.
Remote setup and CLI
Section titled “Remote setup and CLI”The gmuxd remote command now uses an interactive flow that correctly handles Tailscale hostname changes and config writes. Added gmuxd log-path for log streaming and improved daemon restart messaging.
Features
Section titled “Features”- unified match rules with project onboarding and modal redesign (#110)
- OG meta tags, mock terminal rendering, remove stale hero.png (#101)
- clickable discovered project rows, document projects.json (#103)
- reconnect peers after system sleep (#104)
- improve Tailscale remote access setup and CLI output (#111)
- simplify landing page CTA, add Discord to getting started (#112)
v1.0.0
Section titled “v1.0.0”Prefix any command with gmux and it shows up in a live browser dashboard. Watch what every agent is doing, steer them from your phone, and aggregate sessions from every machine, container, and VM into one place.
This release stabilizes the core and adds multi-machine support.
Multi-machine sessions
Section titled “Multi-machine sessions”gmux now aggregates sessions across machines. Pick one gmuxd as your dashboard (the hub), and it connects outward to other instances (spokes) to merge their sessions into a single UI. The browser only talks to the hub.
- Tailscale auto-discovery. Enable Tailscale on two machines and they find each other automatically. gmuxd subscribes to tailnet changes and reacts immediately when devices come online. No manual peer configuration, no token exchange. Discovery results are cached so known peers reconnect instantly on restart.
- Devcontainer auto-discovery. Add the gmux devcontainer Feature to any container and gmuxd discovers it via Docker events. Sessions appear in the sidebar with a topology breadcrumb (
workstation > alpine-dev). - Manual peers. For machines not on the same tailnet, configure
[[peers]]inhost.tomlwith a URL and token (inline, file, or shell command). - Transparent proxying. Terminal I/O, kill, resume, dismiss, and launch all forward through the hub. The browser doesn’t know which sessions are local and which are remote.
- Fault tolerance. Each spoke connection is independent. A slow or dead spoke never blocks the hub or other spokes.
Project hub
Section titled “Project hub”Clicking a project name in the sidebar opens a dedicated overview page. Sessions are grouped by host and working directory, with a topology breadcrumb showing the full chain. Per-folder launch buttons route new sessions to the correct machine.
Home page
Section titled “Home page”The home page shows host cards for every connected machine, with status indicators, session counts, and per-host launch buttons. Offline tailnet devices that look like gmux instances appear as dimmed cards so you know what’s out there.
CLI lifecycle
Section titled “CLI lifecycle”gmuxd startbackgrounds viasetsid+ re-exec, logs to~/.local/state/gmux/gmuxd.log, waits for health, prints PID.gmuxd runruns in the foreground for systemd, Docker, or debugging.gmuxd restartis an alias forstart(the old instance is replaced automatically).gmuxd statusshows session counts (local/remote/dead), per-peer connection state with error reasons, and the Tailscale URL.gmuxd stop,gmuxd auth,gmuxd remote,gmuxd versionunchanged.
Terminal and configuration
Section titled “Terminal and configuration”- Three config files.
host.toml(daemon behavior, TOML),settings.jsonc(terminal options, keybinds, UI prefs), andtheme.jsonc(color palette, Windows Terminal theme compatible). All optional, partial configs deep-merge over defaults, settings/theme apply on browser refresh without restarting the daemon. - Platform-aware keybinds. Linux: Ctrl+Alt+T/N/W send the terminal shortcuts the browser steals. Mac: Cmd+Left/Right for Home/End, Cmd+Backspace for delete-to-start, Cmd+K for clear.
- OSC 52 clipboard. Terminal apps that write to the clipboard (vim, tmux) now work in the browser.
- Session replay. Replaced the ring buffer with a virtual terminal emulator. TUI state, colors, and cursor position are preserved exactly on reconnect.
- Resize. The terminal claims viewport dimensions on every session connect. Browser-driven resize uses echo-gated throttling to remove lag.
Security
Section titled “Security”- Unix socket for local IPC. CLI-to-daemon communication uses
~/.local/state/gmux/gmuxd.sock(filesystem permissions, no network exposure). - Token auth always required on TCP. No option to disable it.
- Tailscale identity verification. The tsnet listener checks every connection against the cryptographic WhoIs identity. The node owner is auto-whitelisted; additional accounts go in the
allowlist. - Strict config validation. Unknown keys, malformed allow entries, and duplicate peer names are rejected at startup.
Breaking changes from v0.x
Section titled “Breaking changes from v0.x”- Config file renamed.
config.toml→host.toml. The[network]section is removed; bind address is controlled by theGMUXD_LISTENenvironment variable. - Keybinds moved.
keybinds.jsoncis now a"keybinds"array insidesettings.jsonc. - CLI subcommands.
gmuxd(bare) prints help. Usegmuxd startto background orgmuxd runfor foreground. - TCP auth required. All TCP connections require a bearer token. The prior unauthenticated localhost exception is removed.
All changes
Section titled “All changes”Expand full change list
Features
- Server-side project management with VCS remote grouping (#41, #50)
- Unix socket IPC and mandatory TCP auth (#43)
- Status indicator redesign: unread badges, activity rings, agent-aware (#46)
- Explicit keymap system with
macCommandIsCtrl(#56) - Config layout:
host.toml,settings.jsonc,theme.jsonc(#64) - Hub protocol: peer aggregation, action routing, WS proxying (#74)
- Click “outdated” badge to restart session (#77)
- Project hub page with per-host/folder layout (#86)
- Terminal defaults and keybind handling improvements (#91)
- Per-host launch buttons on home page (#97)
- CLI lifecycle:
start/run/restart/status(#98) - Tailscale auto-discovery via WatchIPNBus (#100)
- OSC 52 clipboard support (#48)
Fixes
- Mobile link taps deferred past scroll events (#44)
- Ring buffer: flush bare CR, trim to frame-start on wrap (#51)
- Virtual terminal for session replay (#68)
- Claim terminal resize on session select (#78)
- Responsive terminal resize with echo-gated throttle (#81)
- SIGHUP for process termination, SIGKILL escalation for fish (#86)
v0.8.0
Section titled “v0.8.0”-
Fixed dev instances unable to connect to their backend. The
gmuxCLI now readsGMUXD_PORTdirectly (same env var asgmuxd), so a single export is sufficient for both binaries. The redundantGMUXD_ADDRenv var has been removed. -
Dev instances now isolate pi session storage. The pi adapter respects
PI_CODING_AGENT_DIR, and the dev scripts export it to an instance-specific directory. Sessions launched from a dev instance no longer appear in (or pollute) your real pi session history. (#39) -
Nested gmux detection. Running
gmux <command>inside an existing gmux session no longer creates a PTY-within-PTY nest. Instead, the session is launched in the background and appears in the gmux UI automatically. (#37) -
User-configurable terminal settings. Two new config files in
~/.config/gmux/let you customize the terminal without rebuilding:theme.jsonc: terminal color palette. Drop in a Windows Terminal theme and it works out of the box.settings.jsonc: terminal options (font, cursor, scrollback), keybinds, and other frontend preferences. Remap keys the browser steals (Ctrl+T, Ctrl+N, Ctrl+W) to PTY sequences viasendKeys, send raw text withsendText, or disable built-in bindings with"none".
-
Config file renamed.
config.tomlis nowhost.tomlto better reflect its purpose (daemon/host behavior). -
Platform-aware default keybinds. On Linux, Ctrl+Alt+T/N/W send Ctrl+T/N/W (workaround for browser-stolen shortcuts). On Mac, Cmd+Left/Right send Home/End, Cmd+Backspace deletes to start of line, and Cmd+K clears the screen, matching iTerm2 conventions.
-
No restart required. Config files are read from disk on each page load, so edit and refresh. (#35)
v0.7.1
Section titled “v0.7.1”- Clean scrollback on screen clear, better ring buffer wrapping. When the 128KB scrollback buffer wraps around, snapshots now start at the first complete line boundary instead of mid-line or mid-escape-sequence. (#36)
- Session attributions survive gmuxd restart. File-to-session attributions
are now persisted to
attributions.jsoninside the /tmp/gmux-sessions directory. (#33) - Fixed 1px horizontal scroll when the terminal is auto-fitted to the viewport (#32)
v0.7.0
Section titled “v0.7.0”- Clickable links in the terminal. URLs in terminal output are now detected and open in a new tab on click. OSC 8 hyperlinks emitted by programs also work without a confirmation dialog. (#29)
- Fixed scroll position jumping when a terminal resize coincides with a synchronized update (BSU/ESU) block, most visible on mobile when the virtual keyboard opens during heavy output.
- Fix scrollback for TUI apps. Pi and claude sessions now retain conversation content. (#27)
- Fixed workspace grouping for adapter sessions (pi, codex). Resumable sessions discovered from session files now resolve their git/jj workspace root correctly. (#25)
- Network listener for containers and VPNs. gmuxd can now bind to a network address beyond localhost, protected by a bearer token. Set
GMUXD_LISTEN=10.0.0.5or add[network] listen = "10.0.0.5"to your config file. Browsers get a login page; programmatic clients use theAuthorization: Bearerheader. Rungmuxd auth-linkto see the token and a ready-to-scan URL for mobile devices. (#31) - Sessions from the same directory now appear next to each other. Within a workspace folder, sessions are grouped by their working directory instead of being interleaved by creation time. (#28)
v0.6.1
Section titled “v0.6.1”- Fixed mobile keyboard autocorrect, predictive text, and voice dictation duplicating text. (#20)
- Smarter error handling for pi sessions. Transient API errors (overloaded, rate-limited) no longer flicker the sidebar status. gmux stays in the working state while pi retries, and only shows a red error dot when all retries are exhausted. The dot clears when you view the session or send a new message. (#22)
- Removed kill button from session header. The X button was easy to tap accidentally; sessions can still be killed from the sidebar. (#18)
v0.6.0
Section titled “v0.6.0”- Smarter scrollback storage. Loading spinners and screen clears no longer waste scrollback buffer space. Spinner frames that overwrite each other via carriage return are collapsed to just the final frame, and screen clears (
ESC[2J/ESC[3J) discard pre-clear content from the buffer. - Fixed mobile keyboard word replacement. iOS autocorrect and Android predictive text would concatenate the corrected word after the original instead of replacing it.
- Fixed scroll position drifting when scrollback is full. When the user was scrolled up and new output arrived in synchronized update blocks, the viewport would gradually drift as old lines were evicted from the scrollback buffer.
- Workspace-aware sidebar grouping. Sessions in jj workspaces or git worktrees that share the same repository are now grouped under a single folder in the sidebar.
v0.5.1
Section titled “v0.5.1”- Faster reconnects for long sessions. Redundant SIGWINCH signals on reconnect caused TUI apps to redraw their entire screen on top of the scrollback replay. Resizes that don’t change the terminal dimensions are now skipped.
- Coalesced terminal output. PTY output is batched (up to 8ms/32KB) before sending to the browser, reducing WebSocket overhead during heavy output.
- Isolated dev environments.
dev-server.shanddev-session.shnow derive ports, socket dirs, and state dirs from the worktree path. Multiple grove worktrees run simultaneously without collisions.
v0.5.0
Section titled “v0.5.0”- OS notifications. Background sessions that finish or produce new output trigger a notification. Suppressed when you’re already looking at gmux, routed to whichever device was most recently active.
- Tab title badge.
(1) gmuxwhen sessions have unread output. gmuxd remotecommand. Sets up Tailscale config, checks prerequisites, and shows connection status.- Auto-resize. Viewport changes now reliably resize the terminal. Multiple tabs at the same size all stay in sync.
- Scroll position preserved during synchronized output. Screen redraws (DEC 2026 BSU/ESU) no longer jump the viewport.
- Self-hosted fonts. All Google Fonts are now bundled at build time. Zero external network requests on localhost.
v0.4.7
Section titled “v0.4.7”- Linux support.
curl -sSfL https://gmux.app/install.sh | shdetects OS and architecture, downloads from GitHub Releases, and verifies SHA-256 checksums. - Auto-update notifications. gmux checks for new releases in the background and shows them in the sidebar and CLI.
- Changelog on the docs site. You’re looking at it.
v0.4.4
Section titled “v0.4.4”- Working indicator no longer gets stuck. Pi’s
aborted(Esc) anderrorstop reasons are now handled; previously onlystopcleared the indicator. - Session titles appear reliably. Fixed a race between the file monitor and SSE subscriber that could silently overwrite title and status updates.
- Atomic store updates.
Store.Updatemethod prevents concurrent goroutines from clobbering each other’s fields. - Seamless daemon upgrade.
gmuxdetects version mismatches with the running daemon and replaces it automatically. - Scroll-to-bottom after reconnect. Switching sessions no longer pins the view to old scrollback content.
- Proper paste handling. Pasted text is sent correctly to the terminal.
v0.4.3
Section titled “v0.4.3”Mobile
Section titled “Mobile”v0.4.3 rounds out the mobile terminal keyboard. The toolbar gains an Alt modifier button that works identically to Ctrl: arm it, type a key, send the escape-prefixed sequence. Holding ← or → now repeats the arrow at iOS key-repeat speed; keep holding and it shifts into word-navigation mode, lighting up the Ctrl button as a visual cue. A background-activity dot appears on the hamburger menu when another session is busy (blue) or has unread output (yellow). Several smaller fixes: Backspace now correctly sends Ctrl+H when Ctrl is armed, Esc refocuses the terminal after sending, and the End scroll button is taller to match the toolbar.
v0.4.1
Section titled “v0.4.1”- Serialized terminal writes. Xterm writes and resizes are queued so the async parser never races with resize.
- Stable fit measurement. Terminal size measured from the shell viewport directly instead of FitAddon’s container measurement.
- Unified resize model.
terminal_resizeevent replaces the oldresize_state/claim_resizeprotocol. - Connect takes over resize. Opening the UI on a device automatically sizes the terminal to fit.
- Tap to focus. Tapping the terminal opens the soft keyboard on mobile.
- Keyboard-aware layout. The app tracks
visualViewportheight so the terminal resizes above the on-screen keyboard. - Passive panning. When a session is sized for another device, drag to pan the oversized terminal.
- Accessory bar keeps keyboard open. Tapping esc, tab, ctrl, arrows, or enter no longer dismisses the soft keyboard.
- Dev environment.
scripts/dev-server.shstarts an isolated dev instance with vite HMR, Go file watching, and Tailscale access.
v0.4.0
Section titled “v0.4.0”Breaking changes
Section titled “Breaking changes”gmuxdis now subcommand-based. Rungmuxd start,gmuxd shutdown,gmuxd version, orgmuxd help. Baregmuxdnow prints help instead of starting the daemon.gmuxd startis now strict by default. If another daemon is already running, it fails unless you pass--replace.
v0.3.0
Section titled “v0.3.0”Sidebar redesign, file attribution fixes, integration tests.
- Sidebar split into live + resumable sections. Live sessions at top, “Resume previous” collapsible drawer for resumable sessions.
- Simplified close button. Always ×; live sessions kill, resumable sessions dismiss.
- Stale session cleanup. Dead runners detected and cleaned up automatically.
- File attribution fixes. Single-candidate attribution now works correctly for pi. Title derived from first user message even when the tool creates the file before user input.
- Title from first user message. Adapters no longer emit title events on every message; initial title set once via file parsing.
close_actionremoved. Field was redundant; frontend derives behavior fromsession.alive.CommandTitlerinterface. Optional adapter capability for custom fallback titles (shell showspytest -xinstead of “shell”).- WebGL terminal renderer. Switched from canvas to WebGL for better performance.
- Terminal resize handoff polish. The “sized for another device” hint is now a compact floating pill and no longer affects terminal height when taking resize ownership.
- Integration tests. End-to-end tests for pi, claude, codex, and shell that launch real tools through gmuxd.
- Fixed macOS “app is damaged” Gatekeeper prompt.
v0.2.4
Section titled “v0.2.4”- File attribution refactored into adapter interface (
FileAttributor). - Codex adapter now attributes session files.
v0.2.3
Section titled “v0.2.3”- Fixed Homebrew tap (was empty after cleanup).
v0.2.2
Section titled “v0.2.2”- Switched Homebrew distribution from cask to formula (install command unchanged).
- Fixed adapter title being lost after session resume.
- Added analytics to website (cookieless, no banner).
v0.2.1
Section titled “v0.2.1”State management rearchitecture. Session state flows through a single path (Register) instead of multiple creation paths racing. Frontend is a pure projection of backend state with no optimistic updates.
- Fixed resume race conditions (duplicate sessions, stale sockets, premature terminal attach).
- Dismissed sessions stay dismissed across scanner cycles.
- Dead sessions no longer auto-selected.
- Status labels null by default, shown only when informative.
- Chrome app-mode launch fixed on macOS (direct binary call instead of
open -a). - New docs: state management, session schema.
v0.2.0
Section titled “v0.2.0”- Claude Code and Codex adapters with session file parsing, live status, and resume.
- Resumable sessions. Sessions transition between alive and resumable states seamlessly.
- Empty state redesign with launcher buttons.
- Fixed Chrome app-mode flag passing on macOS.
- Resume race conditions and dismissed session reappearance fixed.
ResumableandCloseActionderived from adapter capabilities, not hardcoded.
v0.1.0
Section titled “v0.1.0”Initial release.