agent mux β the tmux-native, agent-first terminal for macOS
Website Β· Latest release Β· Documentation
Your sessions live in tmux, so they survive everything.
Your agents are observed by muxa, so you always know who needs you.
Your terminal is native, so none of it feels like a compromise.
Every AI-coding session today is a pile of terminals: agents waiting on input you can't see, sessions that die with the app, and a multiplexer UI from 2007. amux collapses that pile:
| πͺ Workspace = tmux session | Every workspace is a real tmux session on a dedicated server (tmux -L amux). Close the app, reopen it β everything is exactly where you left it. |
| π Agents are first-class | muxa correlates Claude Code / Codex / Gemini CLI hook events with tmux panes. Workspaces show live badges: 2 working Β· 1 waiting Β· 1 error. |
| β One command center | Press βK to search open workspaces, detached tmux sessions, SSH hosts, and agents in one native dialog. Agents that need input rise to the top. |
| π₯ Native, not rendered-in-tmux | tmux control mode (-CC) projects windows and panes into native Ghostty surfaces. No status bar, no copy-mode, no double UI. |
| π CLI and GUI see the same world | tmux -L amux attach from any terminal, or drive the app over its unix socket. Splits made in either place appear in both. |
| π Headless prompts | Send text to a workspace over the socket; it lands in the session's active pane β no attach, no focus steal. |
flowchart LR
subgraph agents["agent CLIs"]
A1["Claude Code"] & A2["Codex"] & A3["Gemini"]
end
subgraph tmux["tmux server (-L amux)"]
S1["session β workspace"] --- P1["panes"]
end
D["muxad<br/>(agent observability daemon)"]
APP["amux.app<br/>(native shell Β· Ghostty renderer)"]
A1 & A2 & A3 -- "run inside" --> P1
A1 & A2 & A3 -- "hook events" --> D
tmux -- "control mode (-CC)" --> APP
D -- "state stream (unix socket)" --> APP
APP -- "send-keys / splits / kills" --> tmux
- tmux owns session existence, pane topology, scrollback, and persistence.
- muxa (muxad) owns agent state (
working / waiting_input / waiting_choice / error), prompt history, and activity analytics. - amux.app owns rendering, focus, notifications, and UX β a projection of the two sources of truth above, plus everything a native app should be.
amux turns the usual terminal-scanning loop into a small set of predictable actions:
| Action | Default | Result |
|---|---|---|
| Open Agent & tmux Switcher | βK |
Search local and connected hosts. Open workspaces, detached tmux sessions, and agents share one attention-sorted list. |
| Attend | ββ§J |
Jump directly to the agent that has been waiting for you the longest. |
| Detach workspace | prefix + d |
Close the amux workspace view while leaving its tmux session and processes alive. |
| Reconnect a host | amux ssh <host> |
Discover and attach to remote tmux sessions without giving up the native workspace UI. |
| Observe from a terminal | muxa watch |
Use muxa's TUI against the same agent state stream when you want a headless view. |
The switcher distinguishes open tmux, available tmux, local shell, and SSH-backed workspaces with compact status labels. muxa state is joined to the same rows, so a blocked Claude Code or Codex run is visible before an idle session.
amux 0.2.0 requires Apple Silicon and macOS 14 or later. The release is signed, notarized, stapled, and distributed with Sparkle automatic updates enabled.
Homebrew 6 requires an explicit trust step for third-party taps:
brew tap Open330/tap
brew trust Open330/tap
brew install --cask Open330/tap/amuxDownload amux-macos.dmg,
open it, and drag amux.app to Applications. Future stable releases are offered
through the built-in Sparkle updater.
Requirements: Apple Silicon, macOS 14+, Xcode 26+, zig (for GhosttyKit), tmux 3.x.
Optional: muxa (muxad running) for agent badges.
git clone --recurse-submodules git@github.com:Open330/amux.git
cd amux
./scripts/setup.sh # init submodules, build GhosttyKit, install hooks
# Debug build + launch (tagged: isolated socket/bundle id per tag)
CMUX_SKIP_ZIG_BUILD=1 ./scripts/reload.sh --tag dev --launchNotes:
CMUX_SKIP_ZIG_BUILD=1skips the Ghostty CLI helper, which pins zig 0.15.2 (GhosttyKit itself builds fine with newer zig). The helper isn't needed for the terminal.- If
xcodebuildcomplains about Command Line Tools, eithersudo xcode-select -s /Applications/Xcode.app/Contents/Developeronce, or prefix builds withDEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer. - Everything amux-owned runs against the dedicated
-L amuxtmux server with-f /dev/nullisolation β your~/.tmux.conf, plugins, and default server are never touched.
# build & launch as above, then:
CMUX_TAG=dev scripts/cmux-debug-cli.sh rpc remote.tmux.mirror '{"local":true}' # mirror local sessions
tmux -L amux -f /dev/null new-session -d -s demo # or create one externally
CMUX_TAG=dev scripts/cmux-debug-cli.sh rpc remote.tmux.sessions '{"local":true}' # discover themQuit the app, run tmux -L amux ls β your sessions are still there. Reopen the app β they're workspaces again.
Then press βK. The session appears in the Agent & tmux Switcher alongside any
open workspaces, remote hosts, and muxa-observed agents. The shortcut is editable
in Settings β Keyboard Shortcuts or as shortcuts.bindings.amuxSessionSwitcher
in ~/.config/amux/amux.json.
Detailed plans live in .context/plans/R01-fable.md (architecture) and
.context/plans/R02-fable.md (productization).
| Phase | Scope | Status |
|---|---|---|
| 0 β Feasibility | Local tmux -CC engine on the SSH mirror stack, pty spawn, config isolation, flood/OSC/scrollback gates |
β all gates passed |
| 1 β tmux-backed workspaces | Local one-shot transport, {"local":true} socket RPC family, multipane socket I/O routing, launch-time session reconcile |
β live-verified |
| 2 β Agent layer | CmuxMuxa daemon client (hello/snapshot/subscribe), sidebar agent badges, attend (jump to longest-blocked agent, ββ§J), prompt composer, waiting_choice native sheet |
β shipped |
| muxa co-evolution | muxad carries tmux_socket + tmux_session on the wire so amux joins by session name across servers (Open330/muxa#60) |
β merged (upgrade muxad) |
| 3 β Deep UX | New/attach/detach/kill lifecycle, detach-by-default, workspace-kind chips, session recovery, agent attention routing, and the βK Agent & tmux Switcher | β shipped in 0.2.0 |
| 4 β Product | amux branding, bundled tmux 3.7b + muxad/muxa, opt-in muxad LaunchAgent, first-run wizard, signed + notarized DMG, Sparkle, and Homebrew cask | β 0.2.0 stable release published |
Download the signed, notarized build from Releases.
amux now owns its CLI and storage paths. On first launch it imports existing
~/.config/cmux/cmux.json, ~/.config/cmux/, ~/.cmux/, ~/.cmuxterm/, and
project .cmux/ data into ~/.config/amux/amux.json, ~/.config/amux/,
~/.amux/, and project .amux/. Existing amux files always win and legacy
sources are left untouched for rollback. After import, only amux paths are read
and written; the release no longer installs a cmux CLI alias.
Inherited CMUX_* environment variables and cmux.* action identifiers remain
protocol-level names for existing integrations. They are not executable or
configuration-path aliases. The boundary is documented in
docs/amux-identity.md.
amux is a friendly fork of cmux by Manaflow β a Ghostty-based macOS
terminal with vertical tabs and agent notifications (original README preserved at
docs/upstream-cmux-README.md). amux inherits its rendering stack,
workspace UI, and socket control plane β and crucially its SSH tmux -CC mirror, which amux generalized
into the local engine. Upstream is merged periodically.
| Component | License |
|---|---|
| amux (this repo, cmux fork) | GPL-3.0-or-later (see LICENSE) |
| Ghostty β renderer | MIT |
| muxa β agent observability | MIT OR Apache-2.0 |
| tmux | ISC |
- Reviewed version tags build and publish through GitHub Actions; development CI may also run on the Gitea mirror.
- Contributor rules, typing-latency pitfalls, and package architecture live in
CLAUDE.mdandskills/. - The muxad client package has its own suite:
cd Packages/macOS/CmuxMuxa && swift test. - The original cmux README (incl. its translations) is preserved at
docs/upstream-cmux-README.md; amux ships its own English README and will add translations as the docs mature.
