Building from Source
Build AgentMux from source on Windows, macOS, or Linux. AgentMux is a Rust desktop app with a SolidJS frontend, hosted in a bundled Chromium runtime via CEF (cef-rs).
Prerequisites
Section titled “Prerequisites”| Tool | Version | Purpose |
|---|---|---|
| Node.js | 24 LTS (>=24.11.0) | Frontend build (Vite + SolidJS) |
| Rust | 1.77+ | Backend, host, and launcher |
| Task | Latest | Build orchestration |
| CMake | 3.20+ | Required by cef-dll-sys (CEF C wrapper) |
| Ninja | 1.10+ | Required by cef-dll-sys |
Platform-Specific Dependencies
Section titled “Platform-Specific Dependencies”xcode-select --installbrew install cmake ninjacurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shWindows
Section titled “Windows”- Install Rust from rustup.rs.
- Install Visual Studio Build Tools — select “Desktop development with C++” (provides CMake and Ninja).
- Verify Ninja is on
PATH. The Visual Studio install ships Ninja insideCommon7/IDE/CommonExtensions/Microsoft/CMake/Ninja/; copy or symlinkninja.exeto a PATH entry. From Git Bash (note: the*must be unquoted so the shell expands it):Or substitute the actual edition (Terminal window cp /c/Program\ Files/Microsoft\ Visual\ Studio/*/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/Ninja/ninja.exe /c/Systems/bin/Community,Professional,Enterprise) and year (2022, etc.) so no glob is needed.
Linux (Debian/Ubuntu)
Section titled “Linux (Debian/Ubuntu)”sudo apt install cmake ninja-build build-essential curl wget file libssl-dev git zip \ libwayland-dev libxkbcommon-dev libgtk-3-dev \ libglib2.0-dev libpango1.0-dev libcairo2-dev \ libgdk-pixbuf2.0-dev libatk1.0-devcurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shInstall Task
Section titled “Install Task”# macOSbrew install go-task/tap/go-task
# Linuxsudo snap install task --classic
# Windowswinget install Task.TaskClone and Install
Section titled “Clone and Install”git clone https://github.com/agentmuxai/agentmux.gitcd agentmuxnpm installDevelopment
Section titled “Development”task devThis launches the four-process app with Vite hot reload. The frontend rebuilds on save (SolidJS HMR via Vite); changes to the Rust crates require a rebuild and restart.
After code changes
Section titled “After code changes”| Changed | Action |
|---|---|
| Frontend (TypeScript / SolidJS) | Auto-reloads via Vite HMR |
Rust sidecar (crates/srv/) | task build:backend, then restart task dev |
Rust host (crates/cef/) | task build:host, then restart task dev |
Launcher (crates/launcher/) | task package (portable / installed builds). Note: task dev now runs through the launcher on all platforms as of v0.41.0 — launcher changes are exercised by task dev, not just package builds. |
Build Commands
Section titled “Build Commands”| Command | Description |
|---|---|
task dev | Development mode (CEF host + Vite hot reload) |
task build:host | Build the CEF host binary |
task bundle | Bundle CEF runtime DLLs |
task build:backend | Build agentmux-srv |
task build:frontend | Build frontend only |
task package | Package a local Windows portable (a folder plus a .7z) — ephemeral labeled build, see below |
task package -- --fresh | …with a throwaway data dir (clean-slate session) instead of the branch’s persistent one |
task package:linux | Local Linux AppImage to ~/Desktop (package:linux:deb, :rpm and :tarball make the other formats) |
task package:macos | Local signed macOS .app + .dmg to ~/Desktop (notarized when a notarytool profile is set up) |
task package:msix | Windows MSIX built from a portable (-- -Sign for a self-signed test package) |
task package:installer | Windows .exe installer (Inno Setup) built from a portable |
task clean | Clean build artifacts |
Run task --list to see every task. Each package task runs only on its own platform. package, package:macos and the package:linux tasks each have a package:release twin that bakes the stable channel and refuses to run unless HEAD is a merged release commit; published release artifacts are built by the release pipeline.
Local build labels
Section titled “Local build labels”task package is for local builds. It does not bump the version and does not touch git — the committed version moves only through task release (changesets). Each local build instead carries an ephemeral, traceable label:
agentmux-<version>+g<sha>[.dirty].<stamp>-x64-portableEverything after + is semver build metadata — ignored for version precedence, so a local label can never collide with or reorder a release version. The <sha> ties the build back to its source commit, .dirty marks a build made from uncommitted changes, and <stamp> (a UTC build timestamp) makes every build’s folder unique — so a running instance can never lock the next build’s output folder. The data dir is keyed on a per-build channel local-<branch>-<hash>-<build-id> baked at compile time, so each build is its own isolated instance (its own data dir, cef-cache, and single-instance pipe) — two rebuilds of one branch do not share a data dir or session. Agents and auth are account-wide (under ~/.agentmux/shared/), so a fresh per-build data dir still shows every agent and stays logged in; only pane layout and memories start fresh. (--fresh is now a no-op, since every build is already isolated.) Full rationale: SPEC_LOCAL_BUILD_VERSIONING_2026_05_28.md.
There is no task test. CI runs these, and so can you:
npx vitest run # frontend and script tests (npm test starts vitest in watch mode)npx tsc --noEmit -p tsconfig.citypecheck.json # TypeScript type checkcargo test --workspace -- --test-threads=1 # Rust tests, all cratesSource Layout
Section titled “Source Layout”agentmux/├── crates/launcher/ # Launcher — spawns the host and the sidecar, owns OS-level facts├── crates/cef/ # CEF host — embeds Chromium, owns the OS window├── crates/srv/ # Sidecar — RPC engine, SQLite persistence, sagas├── crates/common/ # Shared library (path resolution, runtime mode, IPC types)├── crates/mcp/ # agentmux-mcp — the MCP server agents use for MuxAPI├── crates/bashwrap/ # Streaming bash wrapper and CLI hook helper├── crates/remote/ # Helper installed on SSH hosts (durable sessions, files)├── crates/procstats/ # Per-process CPU and memory for Tower├── frontend/ # SolidJS + TypeScript (Vite)├── docs/ # Architecture docs; specs in docs/specs/└── Taskfile.yml # Build task definitionsCommunication Flow
Section titled “Communication Flow”launcher ◀── named pipe ──▶ host (CEF) │ ├── JS bridge ──▶ renderer (SolidJS) │ ├── websocket ──▶ sidecar (agentmux-srv) │ │ │ └── ssh ──▶ agentmux-remote on an SSH host │ ▼ OS window, browser panesSee Architecture overview for the full topology and what each edge carries.
Debugging
Section titled “Debugging”Frontend
Section titled “Frontend”Open Chromium DevTools from the hamburger menu (≡) in the top tab bar → Dev Tools, or use the keyboard shortcut. DevTools is no longer a widget-bar entry (moved to the hamburger menu — see Pane types). Reload the renderer with Ctrl+R / Cmd+R.
Backend Logs
Section titled “Backend Logs”The host log lives in <data-dir>/logs/ (per channel/version). The sidecar logs directly to the shared ~/.agentmux/logs/, alongside pointer files that resolve to the running host’s per-channel log. Use the muxlog shell helper from any AgentMux terminal — it handles both:
muxlog host # tail the current host logmuxlog srv # tail the sidecar logmuxlog host '\[fe\]' # filter the host log to frontend linesmuxlog host cat # full file contentsSee Multi-instance & dev mode for the per-instance path layout and pointer-file resolution.
Troubleshooting
Section titled “Troubleshooting”CMake / Ninja errors
Section titled “CMake / Ninja errors”If cargo build fails with “CMake was unable to find a build program corresponding to Ninja”, verify ninja --version works on PATH. On Windows, see the install steps above.
Backend binary not found
Section titled “Backend binary not found”Run task build:backend and verify the binary lands in target/release/ (or the platform-equivalent location). The launcher auto-spawns the sidecar by absolute path.
Frontend not loading
Section titled “Frontend not loading”Check the Vite dev port (task dev prints it on startup) is not already in use. Clear and reinstall if needed:
rm -rf node_modules package-lock.jsonnpm installtask devSchema directory missing after clean
Section titled “Schema directory missing after clean”dist/schema/ is wiped by task clean but automatically recreated by the copy:schema dependency in dev, start, and package tasks.
See Also
Section titled “See Also”- Architecture overview — process topology and IPC edges
- Multi-instance & dev mode — data layout, log discovery
- Reducer stack — how state flows across the four processes
- Contributing — contribution guidelines
- Configuration — settings file format