Run every agent session from one picker.

Install ax, then start a coordinator in the current project.

1. Install ax

macOS

brew install --cask agentswitch-org/ax/ax

2. Start a coordinator

Run from your project root (any platform)

ax coordinate "Ship the importer. Done when: go test ./... passes."
What this does

The built-in coordinator behavior is written to ~/.config/ax/behaviors/coordinator.md on first use (edit it to customize), and a self-propelled coordinator starts in the current directory: it triages the goal into .coordinator/backlog.md, delegates to tracked workers, and verifies results.

What is AgentSwitch

Daemonless switchboard for CLI coding agents

ax. It gives CLI coding agents one searchable session history and one set of shell verbs.

  • Open the picker with ax, filter, press Enter.
  • Launch Claude Code, Codex, pi, opencode, or a custom CLI harness.
  • Fold local and remote hosts into the same list, including host-qualified rows such as win01/<id>.
  • Detach with Ctrl-a then d, keep the session running, and reattach later.
  • Use it on macOS, Linux, or native Windows; no daemon or server.

tmux and zellij can add mux windows and tabs, but they are optional. The built-in holder is enough for the launch, detach, monitor, reattach loop.

Compose agent work with shell commands

ax gives every session a set of shell verbs: launch, read, send, ask, reply, wait, kill. Each verb prints session ids and JSON on stdout and returns a meaningful exit code, so sessions compose with standard shell tools.

Because those verbs print ids, JSON, and exit codes, normal shell tools can drive them. Use jq to pick a session id, a for loop to launch workers, or a check script to decide whether a run passed. A short behavior prompt can turn one session into a coordinator that launches, steers, and verifies the others, with fences on cost, fan-out, and time.

The recipes page collects copy-paste playbooks that run as written: CI gates, model-tier escalation, parallel fan-outs over a file corpus, scheduled briefings, email triage, and human-approval holds. Each one is shell plus ax.

Two ways to run work

Run a recipe directly: copy it, edit the task text, and run the launch command. This suits a scheduled job or a known one-shot.

Or give the coordinator behavior a goal. The coordinator behavior (behaviors/coordinator.md) plans the work, launches recipes and workers, supervises them, and checks the result against your criteria. If you ask it to fix website prose, the coordinator can run the taste-gate recipe, pass the reviewer its behavior file (behaviors/reviewer.md), and iterate until the prose clears the rubric or the iteration cap is hit.

Use the coordinator when you want it to pick and run the recipe. Use a recipe directly when you already know the script you want.

Install by operating system

The details below cover package alternatives and optional mux bindings:

  • Install ax.
  • Run ax to open the picker, or ax new to start a session.
  • Optionally bind the picker inside tmux or zellij.

No multiplexer is needed. ax's own holder keeps sessions alive when you detach. On native Windows, the default process backend uses ConPTY and named pipes; on macOS and Linux, tmux or zellij are optional. For the full install matrix, see the manual's Installation chapter.

macOS

1. Install ax

Install with Homebrew:

brew install --cask agentswitch-org/ax/ax

Or download the release binary. Go to the latest release, download the .tar.gz for your architecture (darwin_arm64 for Apple Silicon, darwin_amd64 for Intel), extract ax, and place it on your PATH.

Developer fallback with the Go toolchain (requires Go 1.26.4+):

go install github.com/agentswitch-org/ax@latest

Or build from source:

git clone https://github.com/agentswitch-org/ax.git
            cd ax && make install

make install copies ax to ~/.local/bin, which is not on the default macOS PATH. Add export PATH="$HOME/.local/bin:$PATH" to your shell profile if ax is not found.

2. Multiplexer (optional)

Without a multiplexer, ax runs on its own session holder. To let ax drive a multiplexer natively, install tmux with Homebrew:

brew install tmux

Or install zellij instead:

brew install zellij

3. Optional: set the mux config

Only needed if you installed a multiplexer. Tell ax to drive it in ~/.config/ax/config.toml. With no setting, ax uses its own no-mux session holder.

# ~/.config/ax/config.toml
            mux = "tmux" # or "zellij" if you installed zellij

4. Bind the picker to a key

See Bind the picker below. The keybindings are the same on macOS, Linux, and WSL.

Linux

1. Debian, Ubuntu, and WSL

Install the .deb directly from the latest GitHub release. The command selects amd64 or arm64 from the Debian package architecture.

set -eu
arch=$(dpkg --print-architecture)
tag=$(curl -fsSL https://api.github.com/repos/agentswitch-org/ax/releases/latest |
  sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')
test -n "$tag"
version=${tag#v}
curl -fL \
  "https://github.com/agentswitch-org/ax/releases/download/$tag/ax_${version}_linux_${arch}.deb" \
  -o /tmp/ax.deb
sudo apt install /tmp/ax.deb
ax version

Manual package install

To install a package downloaded in the Windows browser:

  1. Run dpkg --print-architecture in WSL. The result is usually amd64; use arm64 on an ARM-based Windows machine.
  2. Open the latest ax release in the Windows browser. Under Assets, download ax_<version>_linux_<arch>.deb for that architecture.
  3. In WSL, run explorer.exe . and move the downloaded .deb into the folder that opens.
  4. Install the package with the command below.
sudo apt install ./ax_*_linux_*.deb
ax version

2. Other Linux distributions

Install the latest tarball to ~/.local/bin:

curl -fsSL https://agentswitch.org/install.sh | sh
ax version

Fedora, RHEL, Rocky, and AlmaLinux users can download the matching .rpm from the latest release, then install it:

sudo dnf install ./ax_<version>_linux_<arch>.rpm

Developer fallback with the Go toolchain (requires Go 1.26.4+):

go install github.com/agentswitch-org/ax@latest

Or build from source:

git clone https://github.com/agentswitch-org/ax.git
            cd ax && make install

make install copies ax to ~/.local/bin. Make sure that directory is on your PATH.

3. Multiplexer (optional)

Without a multiplexer, ax runs on its own session holder. To let ax drive a multiplexer natively, install tmux with your package manager.

Debian and Ubuntu:

sudo apt install tmux

zellij is not in every apt repository. Install it from the zellij release binaries or with cargo install zellij.

4. Optional: set the mux config

Only needed if you installed a multiplexer. Tell ax to drive it in ~/.config/ax/config.toml. With no setting, ax uses its own no-mux session holder.

# ~/.config/ax/config.toml
            mux = "tmux" # or "zellij" if you installed zellij

5. Bind the picker to a key

See Bind the picker below. The keybindings are the same on macOS, Linux, and WSL.

Windows

1. Install ax

Install the latest release with PowerShell:

irm https://agentswitch.org/install.ps1 | iex

Manual PowerShell install:

$cpu = $env:PROCESSOR_ARCHITEW6432
            if (-not $cpu) { $cpu = $env:PROCESSOR_ARCHITECTURE }
            $arch = if ($cpu -eq 'ARM64') { 'arm64' } else { 'amd64' }
            $release = Invoke-RestMethod 'https://api.github.com/repos/agentswitch-org/ax/releases/latest'
            $asset = $release.assets | Where-Object { $_.name -match "windows_$arch\.zip$" } | Select-Object -First 1
            if (-not $asset) { throw "No Windows asset for $arch in the latest release" }
            $dir = Join-Path $env:LOCALAPPDATA 'ax\bin'
            $exe = Join-Path $dir 'ax.exe'
            $tmpDir = $null
            try {
            $tmpDir = Join-Path ([IO.Path]::GetTempPath()) ('ax-install-' + [Guid]::NewGuid().ToString('N'))
            $extractDir = Join-Path $tmpDir 'extract'
            $zip = Join-Path $tmpDir $asset.name
            New-Item -ItemType Directory -Force -Path $tmpDir, $extractDir, $dir | Out-Null
            Invoke-WebRequest $asset.browser_download_url -OutFile $zip
            Expand-Archive -LiteralPath $zip -DestinationPath $extractDir -Force
            $stagedExe = Get-ChildItem -LiteralPath $extractDir -Filter 'ax.exe' -File -Recurse | Select-Object -First 1
            if (-not $stagedExe) { throw 'Release asset did not contain ax.exe' }
            Copy-Item -LiteralPath $stagedExe.FullName -Destination $exe -Force
            } finally {
            if ($tmpDir -and (Test-Path -LiteralPath $tmpDir)) {
            Remove-Item -LiteralPath $tmpDir -Recurse -Force -ErrorAction SilentlyContinue
            }
            }
            $userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
            if ($userPath -notlike "*$dir*") { [Environment]::SetEnvironmentVariable('Path', "$dir;$userPath", 'User') }
            $env:Path = "$dir;$env:Path"
            ax version

Developer fallback with the Go toolchain (requires Go 1.26.4+):

go install github.com/agentswitch-org/ax@latest

2. Use the native no-mux backend

Leave mux unset. Native Windows uses ax's process backend: each harness runs under ConPTY, steering input goes through a per-session named pipe, and Ctrl-a then d detaches without ending the session.

tmux popup bindings do not apply on native Windows. Use ax, ax new, ax attach, ax read, and ax send from PowerShell or Windows Terminal. WSL is still fine when you want the Linux toolchain.

3. Optional: federate a Windows host

A Windows box such as win01 can be a remote host. If its OpenSSH default shell is PowerShell, set shell = "pwsh" so ax quotes remote arguments for PowerShell.

[[host]]
            name = "win01"
            transport = "ssh -t win01"
            shell = "pwsh"
            # headless = true # use if remote interactive launch/attach is not verified

Remote session ids appear as win01/<id>. ax config status shows each host's OS, shell, ax version, and wire compatibility.

Release candidates

Release candidates publish as GitHub prereleases, which releases/latest does not return; these blocks resolve the newest release directly.

macOS and Linux:

set -eu
tag=$(curl -fsSL https://api.github.com/repos/agentswitch-org/ax/releases |
  sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' | head -n 1)
os=$(uname -s | tr '[:upper:]' '[:lower:]')
arch=$(uname -m); case "$arch" in x86_64) arch=amd64 ;; aarch64|arm64) arch=arm64 ;; esac
curl -fL -o /tmp/ax.tar.gz \
  "https://github.com/agentswitch-org/ax/releases/download/$tag/ax_${tag#v}_${os}_${arch}.tar.gz"
tar -xzf /tmp/ax.tar.gz -C /tmp ax
/tmp/ax version
mkdir -p ~/.local/bin && install -m 0755 /tmp/ax ~/.local/bin/ax

Debian, Ubuntu, and WSL via the .deb instead:

set -eu
tag=$(curl -fsSL https://api.github.com/repos/agentswitch-org/ax/releases |
  sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' | head -n 1)
arch=$(dpkg --print-architecture)
curl -fL -o /tmp/ax.deb \
  "https://github.com/agentswitch-org/ax/releases/download/$tag/ax_${tag#v}_linux_${arch}.deb"
sudo apt install /tmp/ax.deb
ax version

Windows PowerShell:

$tag = (irm https://api.github.com/repos/agentswitch-org/ax/releases)[0].tag_name
$arch = if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') { 'arm64' } else { 'amd64' }
irm "https://github.com/agentswitch-org/ax/releases/download/$tag/ax_$($tag.TrimStart('v'))_windows_$arch.zip" -OutFile "$env:TEMP\ax.zip"
Expand-Archive "$env:TEMP\ax.zip" -DestinationPath "$env:LOCALAPPDATA\ax\bin" -Force
& "$env:LOCALAPPDATA\ax\bin\ax.exe" version

The installers pin any tag with AX_RELEASE_TAG=v0.1.3-rc.1 (sh) or $env:AX_RELEASE_TAG (PowerShell), and Homebrew has the ax-rc cask.

Bind the picker

Bind the picker to a key. One key opens the session table over whatever you are doing, and a second key starts a new session. These bindings are for tmux, zellij, and WSL-style shells; on native Windows, start with the plain ax and ax new commands.

tmux

Add these lines to ~/.tmux.conf. The prefix is whatever chord you already use.

bind-key a display-popup -E -B -s 'bg=terminal' -w 100% -h 100% "ax pick"
            bind-key A display-popup -E -B -s 'bg=terminal' -w 100% -h 100% "ax new"

Reload the config with tmux source-file ~/.tmux.conf. Then <prefix> a opens the picker and <prefix> A starts a new session. Use -w 85% -h 80% for a floating box instead of a full-screen popup, or source the bundled tmux/ax.tmux from the repository.

zellij

Add a keybinding to ~/.config/zellij/config.kdl that runs the picker in a floating pane.

keybinds {
            normal {
            bind "Alt a" {
            Run "ax" "pick" {
            floating true
            close_on_exit true
            name "ax"
            }
            }
            }
            }

Then Alt+a opens the picker in a floating pane that closes when you leave it. Swap pick for new on a second binding to start a fresh session the same way.

First run

Set a default harness

Set a default harness once so a bare prompt launches it. Put this in ~/.config/ax/config.toml:

# ~/.config/ax/config.toml
            default_harness = "claude"

After this, ax "prompt" launches your default harness. A known verb or harness name shadows a bare prompt, so ax read, ax new, and ax codex "prompt" keep their usual meaning. Every example on this site uses the short form.

Launch, detach, reattach

Run your first task from any project directory:

ax "run the test suite and fix any failures"

ax prints the session id and returns your shell prompt. The session runs in ax's own session holder, so it does not depend on the terminal you launched it from. Open the picker to see it working:

ax

The picker lists every session with its status, model, cost, and a live transcript preview. Press Enter to attach and watch. Press Ctrl-a then d to detach, and the session keeps running. Later, reattach from any terminal. That loop does not need tmux, zellij, or any other external holder.

A multiplexer is optional. Install tmux or zellij, set mux in the config, and ax drives it natively with a real window per session. See the manual's Multiplexer backends chapter.

Run a project coordinator

Use a coordinator when one goal has several independent parts.

  • You give one session the goal and acceptance criteria.
  • It launches tracked workers, reads their progress, and verifies the result.
  • You watch the run in the picker and answer only when it asks.
  • A write fence keeps the coordinator in .coordinator/*.md; real edits go through workers.

Start it

One command from the project root, on any platform:

ax coordinate "Ship the v2 importer. Done when: go test ./... passes and the README covers the new flow."

The coordinator behavior ships inside the ax binary. On first use it is written to ~/.config/ax/behaviors/coordinator.md; edit that file to customize, and your copy wins on every later run. --harness picks the harness (default: default_harness, else claude), --small selects the trimmed variant for small local models, and any launch flag overrides the defaults (ax coordinate --help lists them). The picker's compose flow (c, then "coordinator") is the same thing with prompts.

For a scripted or customized bootstrap, the copy-and-own recipe still works: curl -fsSL https://agentswitch.org/coordinator.sh | sh (or irm https://agentswitch.org/coordinator.ps1 | iex on Windows), built on behaviors/coordinator.md and recipes/coding-project-coordinator.

Watch it

ax coordinate launches the coordinator with --write './.coordinator/**/*.md', --fence best-effort, --no-subagents, --max-workers 2, --max-depth 2, --keep-live, --self-propel, and --attach. Self-propel is ax's outer loop: when the coordinator ends a turn with the backlog still open, ax re-invokes it instead of letting it stall, until the goal's done criteria pass, it genuinely needs you, or an idle cap trips. This works for claude, pi, and codex.

Open the picker with ax to watch the run. Press f to filter to the run, T to show the run tree, and r to answer when a session shows needs you. Open-ended coordinators intentionally leave cost and token fences off; edit the script if you want a hard cap that cascade-kills the run.

Use it from compose

The startup sequence leaves the script in ~/.config/ax/recipes. Point compose at that directory to start it later from the picker:

# ~/.config/ax/config.toml
            behaviors_dir = "~/.config/ax/behaviors"
            recipes_dir = "~/.config/ax/recipes"

Then open ax, press c, choose recipe, and launch coding-project coordinator.

Where to go next