Architecture

July 13, 2026 · View on GitHub

amux is a terminal UI (Bubble Tea v2) for running and orchestrating coding agents. Each agent runs in its own tmux session hosted in a pseudo-terminal; amux parses that terminal output with a built-in emulator, composes it with the surrounding UI, and renders the result. Two binaries share the internal packages: cmd/amux (the interactive app) and cmd/amux-harness (a headless renderer used for deterministic perf and render testing).

For the runtime detail of the app package — lifecycle, PTY flow, tmux activity tagging, and persistence invariants — see internal/app/ARCHITECTURE.md. For the message boundaries and command discipline between the app pump and the panes, see internal/app/MESSAGE_FLOW.md. For the streaming/scrolling model — flush pipeline, DEC 2026 frame atomicity, viewport anchoring, and drag auto-scroll — see internal/ui/center/SCROLLING.md.

Dependency direction

Dependencies point downward. Most UI code reaches OS and process boundaries through the tmux/pty/git/data layers. UI packages may still own interaction-local adapters when the behavior is part of a widget boundary, such as clipboard writes and file-picker filesystem reads in internal/ui/common, per-tab PTY tracing in internal/ui/center, and shell plumbing in the sidebar terminal. Shared process, persistence, git, tmux, and PTY behavior — including the shared PTY/tmux read-loop and session plumbing in internal/ui/ptyio — belongs in the lower layers.

            cmd/amux            cmd/amux-harness
                \                   /
                 v                 v
              internal/app  (message pump, services, tmux-activity lease)
                 |  \
                 |   `-- internal/ui/{dashboard, center, sidebar, diff}
                 |              |
                 |              v
                 |       internal/ui/{compositor, layout, common, ptyio, theme}
                 v              |
   internal/{tmux, pty, git,    v
     data, update, config,  internal/vterm   (terminal emulator)
     supervisor, process}
                 \              /
                  v            v
        internal/{safego, perf, logging, messages, validation}

External render-engine coupling

internal/ui/compositor imports github.com/charmbracelet/ultraviolet directly on the core render path (vtermlayer.go, pool.go, canvas_drawable.go). ultraviolet has no semver releases; its go.mod pseudo-version is whatever charm.land/bubbletea/v2 requires (MVS picks bubbletea's pin). Keep the pin in lockstep with bubbletea: upgrade bubbletea and let go mod tidy pull the matching ultraviolet — never bump ultraviolet on its own, because a mismatched pair can break rendering with no compiler warning.

Packages

The table is hand-maintained; keep it in sync when adding or moving a package.

PackageResponsibilityEntry points
cmd/amuxApp entrypoint: flag parsing, terminal setup, tmux socket janitormain.go
cmd/amux-harnessHeadless render/perf harness (no TTY) for CI and local profilingmain.go
internal/appBubble Tea root: message pump, services, layout, tmux-activity leader leaseapp_core.go, app_init.go
internal/app/activityAgent-activity detection logic and per-session lease statelogic.go, types.go
internal/ui/centerCenter pane: agent tab strip, per-tab PTY I/O, diff viewer, selectionmodel.go, tab_actor.go
internal/ui/sidebarSidebar pane: workspace file tree + embedded tmux terminalterminal.go
internal/ui/dashboardDashboard pane: project/workspace tree and toolbarmodel.go
internal/ui/diffScrollable, syntax-aware git diff viewer (a center tab)model.go
internal/ui/compositorComposes vterm snapshots + UI layers into a frame; delta ANSIcanvas.go
internal/ui/layoutPane geometry and layout modesmanager.go
internal/ui/commonShared widgets (dialogs, file picker), selection, clipboard; re-exports themedialog.go, theme_reexport.go
internal/ui/ptyioShared PTY/tmux plumbing: read loop, output filtering/trimming, flush/chunk tuning consts, session bootstrap/restoredoc.go, pty_reader.go, tuning.go
internal/ui/themeColor palette, theme registry, icons, and lipgloss stylescolors.go, theme.go, icons.go
internal/vtermTerminal emulator: ANSI/VT parsing → cell grid + scrollback → ANSIvterm.go
internal/tmuxtmux CLI wrapper: sessions, capture, resize, activity tagstmux.go
internal/ptyPseudo-terminals backing hosted agents (Agent, Terminal)agent.go
internal/gitgit worktree-per-workspace model: worktrees, branches, diff, watcheroperations.go, workspace.go
internal/dataWorkspace record persistence (atomic JSON via WorkspaceStore)workspace_store.go
internal/fsatomicCrash-safe single-file writes: temp-write, fsync, atomic rename-over (with .bak restore on Windows)fsatomic.go
internal/updateSelf-update: version check, download, verify, installupdater.go
internal/configConfiguration: assistants, UI settings, resolved pathsconfig.go
internal/supervisorNamed background workers with restart/backoff and error surfacingsupervisor.go
internal/processCross-platform process-group teardown (kill agent process trees)treekill_unix.go
internal/safegoPanic-safe goroutine helpers with a pluggable panic handlersafego.go
internal/pprofhttpOpt-in pprof HTTP server wiring with explicit mux and timeoutsserver.go
internal/perfOpt-in counters/timers for the harness and perf baselinesperf.go
internal/loggingFile-based logger; the output channel for internal packageslogger.go
internal/messagesShared Bubble Tea message vocabulary between pump and panesmessages.go
internal/validationInput/path guards (assistant, base ref, project path, workspace)validation.go
internal/shellutilShared shell-quoting primitive (POSIX single-quote escaping)shellutil.go
internal/testutilShared test polling helpers (deadline/poll loops with consistent failure messaging)wait.go
internal/e2ePTY-driven end-to-end tests exercising the real binary(tests)