Skip to content
Conduit

skill

agentmux

Multi-agent orchestration for Claude Code and Codex using tmux, Discord ChatOps, and the amux CLI

adelost/agentmuxcommunitylistedunreviewed

Set up

Skills are installed by placing their folder where your agent loads skills.

The download comes from github.com/adelost/agentmux itself, not from our server, so what you get is exactly what its author published.

Install instructions come from the README

Skills do not use an MCP config. Follow the steps in the README below.

README

synced Oct 22, 2026

agentmux

agentmux is local developer tooling for coordinating Claude Code, Codex, Kimi Code and Qwen Code agents across tmux panes. It adds a Discord-based ChatOps interface, a terminal CLI, session isolation, structured logs, media handling, and operational safeguards for long-running AI-assisted development workflows.

Discord / amux CLI
        -> agentmux bridge
        -> durable per-agent queue
        -> tmux panes OR AMUX Code native runtime
        -> Claude Code / Codex / Kimi Code / Qwen Code
        -> structured logs, status, files, and replies

agentmux runs on your machine. It does not host agents for you; it connects your local projects, tmux sessions, and coding-agent CLIs into one controllable workspace.

Why agentmux

  • Run multiple Claude Code, Codex, Kimi Code and Qwen Code sessions side by side.
  • Keep pane histories isolated so resume/continue does not cross wires.
  • Delegate work between agents through the amux CLI.
  • Inspect status, logs, timelines, and recent completed work from one place.
  • Send and receive files, screenshots, PDFs, voice messages, and TTS replies.
  • Recover stuck sessions with explicit operational commands.
  • Protect long-running sessions with loop detection, reminders, and auto-compact support.

Panel send limits

A panel's ordinary amux PROJECT -p N sends may address four different recipients in a rolling15-minute window. The fifth new recipient is refused before enqueue. Repeated sends to a recipient share its slot. An explicit --fanout "reason" admits an exception and records its reason in the event ledger. The check counts admitted send attempts, not recipient execution. --force does not bypass it.

Operator/Discord input, the internal stall watchdog, self-sends and the lsrc:0 dispatcher do not consume those slots. Sender identity still comes from the existing configured-pane detection, not message text.

Held auto-compact notices remember an accepted cause/session beside the generated agents configuration in compact-held-notices.json. Journal-age changes alone never rearm a notice, including after bridge reload. A changed cause or cleared episode can notify again; a failed Discord send remains retryable.

Core Concepts

ConceptPurpose
AgentA named project workspace from agentmux.yaml
PaneOne addressed coding-agent session; tmux or native runtime
BridgeThe Node.js process that connects Discord, tmux, and logs
amuxCLI for sending prompts, reading logs, checking status, and coordinating panes
.agents/Generated per-pane working directories and instruction files

Pane 0 runs in the project root. Pane 1 and above run in .agents/N/, giving each coding agent its own session history while still letting each CLI discover generated project instructions.

Features

Multi-agent orchestration

  • Route different Discord channels to different projects and panes.
  • Run several Claude Code, Codex, Kimi Code and Qwen Code sessions per project.
  • Delegate tasks from one agent to another with amux <agent> -p <pane> "...".
  • Fan out tests, audits, screenshots, or implementation work in parallel.

Reliable session management

  • Structured journal history for Claude, Codex, Kimi and Qwen output extraction.
  • Durable prompt delivery with physical-submit and JSONL receipt verification.
  • Resume hints for panes that restart without prior context.
  • Model-aware context tracking.
  • Recovery commands for stuck panes and blocking prompts.

Durable prompt delivery

Discord, the amux CLI, media handoffs, and internal agent messages all enter one persistent queue before agentmux touches tmux. Delivery is FIFO per pane and single-writer per tmux session, including across bridge processes. The queue also keeps private copies of temporary image and file attachments so a bridge restart cannot turn a valid media prompt into a missing path. Failed job or lock-file writes are logged with their target and error code, release all acquired writer leases, and leave existing submit fences intact. The next round rechecks the exact receipt without retyping the prompt. Receipt polling never sleeps under the session writer, so sibling panes can receive input while a submitted prompt awaits its journal entry. Long and multiline prompts use terminal bracketed-paste mode, so the TUI receives one input transaction rather than a slow stream of painted cells.

A prompt advances through pending -> pasting -> drafted -> submitted, then ends as acknowledged or delivered_unverified:

  • pasting means agentmux initiated the pane write but has not yet proved that the exact text owns the composer. It remains visible in amux doctor and blocks blind Enter or duplicate paste across restarts.
  • drafted means agentmux owns exact text still associated with the composer. It blocks later writes so payloads cannot merge.
  • submitted means the exact draft left the verified composer after Enter. Large atomic pastes require two independent empty observations (or fresh JSONL proof), so one torn Codex repaint cannot release the FIFO prematurely. Later prompts wait for an exact receipt or an explicit unverified verdict; unrelated ongoing goal work does not prove this prompt was received.
  • acknowledged means the authoritative Claude/Codex history contains the exact prompt. Receipt reconciliation runs independently of later writes.
  • delivered_unverified is a terminal at-most-once fence for a submit lacking an exact receipt. Codex can release it after a closed turn, or ten minutes with human input waiting; the ordinary maximum is 60 minutes. AMUX never re-pastes it, removes it from active queue health, preserves it for audit/retention, and warns the bound Discord channel. That warning has its own durable retry state: a Discord outage cannot reopen the prompt, while a bridge restart retries the warning until it is accepted. Internal producers resolve the current channel from agent:pane; an unbound pane remains explicitly unsent in the audit instead of being marked as warned.

Foreign human drafts, hidden composers, and ambiguous submit results fail closed instead of being overwritten or blindly re-pasted. Durable state and bounded dialect-aware recovery let a restarted bridge resume without losing a prompt or creating an unbounded duplicate loop. Rescue Enter and destructive composer cleanup require two consistent live observations, while a fresh exact JSONL event always wins over tmux repaint. amux doctor reports queue health alongside bridge and tmux health.

Claude's exact user-interruption journal event ends its interrupted turn even when a rejected tool has no later assistant reply. It is an idle observation, not a receipt for a pending prompt. Ordinary tool errors, quoted interruption text and later user or assistant activity retain the existing busy guards; delivery recovery still requires its exact history and live-pane checks.

A blocked CLI handoff returns one durable recovery notice to its recorded sender after two refused wakes or ten minutes of unsuccessful pre-submit delivery. The original task stays in its FIFO; AMUX never assigns it to another model or treats an ambiguous submission as NOT SENT. A transient first failure does not wake the sender. Installation-identity refusals name the AMUX package, not the project's checkout. Parking preserves that cause and lifetime attempt count, and a failed Discord warning remains retryable across bridge restarts.

Native runtime canary (no tmux)

AMUX Code can own selected agents directly through Claude's stream-json mode and Codex app-server. The Discord bridge, CLI, durable FIFO, media uploads, reply mirroring, context meters, interrupt and compact commands stay the same; only the terminal/TUI transport is replaced. Backend selection is explicit per agent and fails closed, so an offline native runtime can never create a second shadow conversation in tmux.

agents:
  skybar-canary:
    dir: ~/.agentmux/canaries/skybar-native
    backend: native
    runtime: http://127.0.0.1:8812
    claude: 1
    codex: 1
    claudeModel: claude-opus-4-8
    codexModel: gpt-5.6-sol
    effort: high
    # Optional: adopt this exact existing native agent/session. A mismatched
    # ID, cwd, engine or missing session fails closed; it never starts fresh.
    nativeAgentIds:
      "0": 22222222-2222-4222-8222-222222222222

Start the independent background process, then sync the canary channels:

amux runtime start --port 8812 \
  --data-dir ~/.agentmux/canaries/skybar-runtime \
  --state-dir ~/.agentmux/canaries/skybar-runtime-service \
  --no-legacy-migration
amux sync
amux skybar-canary -p 0 "reply CANARY_OK"
amux log skybar-canary -p 0
amux esc skybar-canary -p 0

The runtime process is deliberately separate from the Discord bridge. Either one can restart while the other remains available; amux runtime stop refuses to kill an active turn unless --force is explicit. Existing tmux fleets are untouched, and amux restart --all skips native agents.

Before binding a real Discord channel, run the isolated real-engine gate:

npm run test:webui:native-canary -- --port 8812

The gate restarts its own runtime and verifies both engine sessions, delivery, uploads, usage, effort, interrupt, compact, pushed fleet-state events and duplicate-free reply mirroring. It then performs an isolated exact-session native→tmux→native rollback and proves old operation keys replay without a second turn. The live/default tmux socket and production runtime are never touched. See the rollback runbook.

Fail-closed fleet cutover

Once the canary is green, amux cutover migrates existing tmux panes by their exact persisted engine session IDs. It is a read-only dry run unless --apply is explicit, repeats the idle and queue proof immediately before stopping tmux, writes a phase receipt, and rolls both config files and sessions back on any failed continuity check. Configured dev services can move to the native process supervisor; shell panes must be explicitly dropped. An explicit --allow-empty creates a fresh session only for a pane with neither an engine session nor persisted turn history. See the cutover runbook.

Hook-pushed pane state (event ledger)

Panes report their own state transitions through Claude Code hooks instead of amux guessing from terminal scraping. bin/install-hooks.mjs registers a lightweight hook (Stop / Notification / UserPromptSubmit / SessionStart) that appends one JSON line per turn boundary to ~/.agentmux/events.jsonl. Status readers (ps, done, wait, auto-compact) merge these pushed events with scraping via an allowlist: a pushed event may only refine a scraped idle/unknown, never contradict a live observation (modals, working). Scraping remains the fallback, so nothing breaks if hooks are missing.

node bin/install-hooks.mjs        # install (idempotent, backs up settings)
node bin/install-hooks.mjs --dry  # preview
node bin/install-hooks.mjs --remove

Permission asks and session starts also surface in amux timeline as 🔔 event rows.

Health: doctor + bridge watchdog

The release installer keeps shared, editable skills under ~/.agentmux/skills. Codex and Claude link there, rather than into the installed npm package. Editing a skill therefore cannot change the release hashes and block agent startup. An upgrade preserves differing previous copies under ~/.agentmux/skill-backups before refreshing them. Independent provider skills are left in place.

amux doctor surfaces every silent failure mode in one table: bridge dead/hung/unsupervised, bridge running OLDER code than the repo (restart needed), hooks broken, ledger stale, tmux unreachable, panes below 60x20, and sessions without an attached client. Undersized panes are red because they are impractical for a human operator to read or navigate; detached sessions warn because they can resurrect at tmux's fallback size. Geometry is not a prompt-ingestion or delivery-health signal. Exit codes 0/1/2 make it cron-friendly.

amux doctor --workspaces runs only the read-only Git checks, also included in ordinary amux doctor. It reuses restart inventory discovery under configured agent directories and Git's own worktree registry. It names duplicate checkouts of the remote default branch, operation markers older than 24 hours, missing registered paths, and the main working tree's branch/behind count. Ordinary feature worktrees are not required to track trunk. Operation age is the marker's mtime, not proof that a process has hung. Trunk comparisons use local remote-tracking refs, so fetch explicitly when you need current remote state. Unresolved index entries are checked separately with git ls-files --unmerged -z, including when HEAD matches trunk and no operation marker remains. Normal staged WIP is not a conflict; conflict counts imply neither an age nor an owner. The scan has a 15-second budget (plus the current bounded Git read); incomplete coverage is a warning. It never fetches, refreshes indexes, resets, stashes, removes worktrees, or starts a background poller.

The bridge writes a 30s heartbeat (~/.agentmux/bridge-heartbeat.json). bin/bridge-watchdog-cron.sh (install: bash bin/install-bridge-watchdog.sh, runs every minute) kills a bridge after its five-minute stale-heartbeat threshold, revives a fully dead stack only in explicit managed (--detach) mode, and rebuilds tmux only after three consecutive socket-probe failures. Manual and intentionally stopped bridges stay user-owned. Rate-limited, logged to ~/.agentmux/watchdog.log, kill-switch touch ~/.agentmux/watchdog-OFF.

Media and operator workflows

  • Voice message transcription.
  • Text-to-speech replies.
  • File and image transfer in both directions.
  • Agent-generated image attachments through [image: /absolute/path.png].
  • Optional Voice PWA endpoint for trusted local or tailnet clients.

Discord voice notes are stored privately before transcription. If STT fails, the pane receives one separate notice with the error and audio path; the original stays pending for transcript retries. The notice and transcript have different durable identities, so a notice cannot suppress the eventual words. There is one failure notice per message, including messages with several audio files. Recipient-resolved records suppress late STT results and notices. Later text messages can pass a failed voice note. Clips over 45 seconds are split into ordered 25-second parts by the existing wrapper, preserving Opus or Vorbis bytes in Ogg (otherwise WAV), with at most three concurrent calls to ~/bin/transcribe. All parts must succeed; any Whisper fallback is labelled in both the pane and Discord transcript.

Shared search model owner

Search reuses one per-user model owner through a kernel-backed lease acquired before native weights load. Compatible package releases share a protocol socket; incompatible protocols or another index wait rather than load a second model. The default idle exit is 30 minutes after the last question (AMUX_EMBEDDER_IDLE_MIN overrides it). Health pings do not extend it; active queries, model loading and background index work prevent shutdown. An older pre-lease worker is left running and new callers report an explicit lexical-only handover until it finishes. The V8 heap flag is not an RSS limit; native model memory is outside that cap.

Suggestions human-comment relay

An optional one-minute poller routes unanswered human comments from private Suggestions boards to explicit amux panes. It authenticates reads with a dedicated read-scoped token loaded from an owner-only credential file and never stores that credential in relay state. Idle polls use no agent prompts or model tokens; durable delivery, API-confirmed answers, bounded reminders, untrusted-data fencing, and overlap locking are built in. See docs/suggestions-comment-bridge.md.

Requirements

  • Linux, macOS, or WSL
  • Node.js 20+
  • tmux 3.2+
  • At least one supported coding-agent CLI:
    • Claude Code
    • Codex CLI
    • Kimi Code
  • A Discord bot token if you want the Discord bridge

Isolated worktree gates

Ignored dependency directories do not follow a new Git worktree. Bootstrap all tracked npm and uv roots before testing:

amux worktree-deps /path/to/worktree
amux worktree-deps /path/to/worktree --check
amux gate --scoped /path/to/worktree

The bootstrap discovers root and nested package-lock.json files. Relocatable npm trees are installed once into an immutable, Git-common-dir cache keyed by the package, lock, repository .npmrc, npm version, platform, architecture, and Node ABI, then linked into the worktree. A changed lock gets a different cache; it can never silently reuse the previous compiler. npm workspaces and local/file links remain local.

Python always gets a real worktree-local .venv: shared virtualenvs can retain editable paths to another checkout. uv sync --locked and lock hashes make dependency drift a visible failure instead of modifying uv.lock.

amux gate --scoped provisions first, selects tools/gate.sh, make check, npm run check, or npm test in that order, and reports every skipped root. It never reports green when a tracked dependency root could not be provisioned, no full gate exists, the gate fails, or a lock changed. Use -- command ... for a repository-owned full gate that cannot be inferred. Before agentmux itself is installed, the stdlib-only bootstrap remains available as node /path/to/agentmux/bin/worktree-deps.mjs /path/to/worktree.

Quick Start

git clone https://github.com/adelost/agentmux
cd agentmux
bash bin/setup.sh

The setup script checks prerequisites, installs npm dependencies, creates starter config in ~/.agentmux/, and installs the fetched origin/master commit as a copied global npm package. It never npm links the CLI to the checkout. AMUX launches configured coding engines in their fully autonomous modes; this is an intentional product contract, not a hidden setup side effect.

Add the first project with the installed engine detected automatically, then start the local queue broker. Discord is optional:

amux add myproject ~/projects/myproject
amux serve --detach

For later upgrades, fetch first and pass the full immutable commit identity:

git fetch origin
MASTER_SHA=$(git rev-parse refs/remotes/origin/master)
node bin/install-release.mjs --sha "$MASTER_SHA"

Claude Agent/Task calls use the existing PreToolUse guard. AMUX_CLAUDE_SUBAGENT_CAP in ~/.agentmux/.env defaults to 1; 0 disables the cap. Start/stop and tool receipts release the slot, including background agents and a TaskStop. When a spawn would be refused, the guard first frees slots whose agent has stopped (its task notification in the parent journal) or belonged to an earlier Claude process; a started or resumed process begins with no slots. Each attempt appends a time, pane, decision and description to ~/.agentmux/subagent-spawns.jsonl, never the prompt. An unknown count allows the call and records countKnown:false.

The installer builds only git archive bytes from that SHA, preserves local runtime config without checking out another branch, refreshes the Claude hooks, and writes ~/.agentmux/release-receipt.json. amux doctor turns red if the global package points into a Git worktree, the receipt or binary realpath drifts, hook hashes/behavior drift, or the running bridge reports another source SHA.

Create or edit ~/.agentmux/agentmux.yaml:

guild: "YOUR_DISCORD_SERVER_ID"
category: "Agent Cave"

dream:
  agent: api
  pane: 0

agents:
  api:
    dir: ~/projects/api
    panes: 2
    codex: 1
    shells: 2

  frontend:
    dir: ~/projects/frontend
    panes: 2

Sessions use tmux's tiled layout by default, including mixed Claude, Codex, service, and shell fleets. Set layout: on an agent only when that session deliberately needs another tmux layout.

dream.agent and dream.pane select the existing Claude/Codex pane that curates the nightly fleet digest. AMUX verifies an exact compact receipt and posts the full prompt to that pane's Discord channel; there is no hidden model. Only explicitly configured dream.candidates may replace an unavailable curator.

Dream also runs a separate nightly context-budget pass, including when there is no new digest work or the curator fails. It uses tokens, not file bytes or the bridge's unchanged 60-percent daytime trigger. Defaults are more than 80,000 tokens and at least 30 minutes idle. Change them in the source YAML:

dream:
  agent: api
  pane: 0
  compact:
    maxTokens: 80000
    idleMinutes: 30

Set dream.compact: false to disable this pass. Preview with amux compact --nightly --dry, run with amux compact --nightly, or name one pane with amux compact --nightly api -p 0. It never starts stopped engines, switches models, uses an API fallback, or clears sessions. Working/unknown, drafted, queued, unmeasured and low-quality contexts are skipped. Claude and Codex have exact compact adapters; Kimi/native are explicitly unsupported here. The existing delivery lease and final live revalidation protect each attempt. Each exact session gets at most one attempt per night, including after a crash. Claude's exact command receipt can appear only after compaction finishes. Its command and compact-boundary checks share one five-minute budget, with no rescue Enter; a late or ambiguous outcome is not permission to compact again. ~/.agentmux/nightly-compact/YYYY-MM-DD/ records per-pane intent, before/after tokens and actual receipt outcome. A failed or blocked budget pass exits nonzero so the existing cron failure notification also covers maintenance, not just the digest. A compact still above budget or without a new token measurement is unresolved, never reported as within budget or blindly retried. A context another pass already compacted, with no work since, is already-compacted: tonight attempted nothing and may not retry, so it shows its size when known but does not fail the night. The budget is a target, not a guarantee about the engine's native summarizer. Dream's own curator is already compacted before its task; its fresh activity keeps the later nightly pass from compacting it again. The thin memory hook refreshes references on the next real Claude turn; other harnesses can use amux memory context and amux search without loading full daily files.

Start the bridge:

amux serve

This keeps logs visible in the current terminal; Ctrl+C stops the bridge. For an explicitly managed background bridge, run amux serve --detach. The managed supervisor does not use tmux; it owns a detached process group with an identity-checked private receipt. Both modes are observable with amux doctor.

In Discord, run:

/sync

This creates or updates the project channels from agentmux.yaml.

Discord Setup

  1. Create a bot in the Discord Developer Portal.
  2. Enable Message Content Intent for the bot.
  3. Invite the bot to your server with permissions to send messages, read history, attach files, and manage channels.
  4. Put the token in ~/.agentmux/.env:
DISCORD_TOKEN=your-token-here
  1. Put your Discord server ID in ~/.agentmux/agentmux.yaml.
  2. Start agentmux and run /sync.

Everyday Commands

Discord commands:

CommandDescription
/syncCreate or update Discord channels from config
/statusClaude: pane/context; Codex: native account, effective model, context and rolling usage limits
/switch [1|2]Codex: toggle or explicitly select this pane's ChatGPT account profile
/model <name> [effort]Codex: compact with a fresh receipt, then restart/resume only this pane. astra and gpt-6 select gpt-6-astra; sol selects gpt-5.6-sol
/peekShow the last response from the target pane
/rawShow raw tmux pane output
/escSend Escape to the target pane
/dismissDismiss a blocking prompt where supported
/use <agent>[.pane]Temporarily retarget the channel
/reloadReload config
/restartRestart only the bridge process
/restart allRecreate every configured tmux session, then restart the bridge (interrupts active turns)

Discord accepts the double-slash spelling too (//status, //switch, //model ..., //restart all), which avoids Discord's own slash-command UI.

For Codex panes, codexModel and optional effort in agentmux.yaml apply to tmux as well as native configuration. At tmux startup an explicit launch selection wins, then a saved pane /model choice, then the configured default, and only then session history. A configured model without an effort preserves the previous effort. Defaults are not saved as manual pane choices, so later config changes still apply. Updating config does not interrupt a running turn or wake stopped panes; amux ps labels configured and last-observed models separately.

Bridge notices

Voice transcripts are posted in Discord with their heading, bounded chunks and speech-to-text note. Pane-to-pane messages retain their full text. Delivery, receipt, context and compaction notices are visible again, as before 9d37147. Transport idempotency and the tool-line environment setting remain in place.

The quota box is a table of every account, named Claude A, Claude W, Codex A and Codex W (by the login's entry, else the login's initial): how many panes run on it, the percent of the week left and the weekly reset. A five-hour window appears under its account only while it blocks it, and a second short line gives the subscription's renewal date, the free resets left and the day the first of them ends when the login's entry has them; what does not fit 32 characters gets a line of its own. At most one action follows: the switch command, when a used-up window comes back, or a free reset. A week that lasts until its reset at the last day's pace gets no advice. The box is the warning (80/90/100 percent), the /quota reply and the top of amux quota. Bridge notices and command replies are in English, without emoji.

~/.agentmux/account-profiles.json version 2 has one entry per login under accounts ("claude:wetterlind": {"name": "Claude W", "subscription": {"renewsOn": "2026-11-05", "freeResetsLeft": 0, "freeResetsReadOn": "2026-10-17"}}), filled in by hand from the billing and usage pages, and slots only for a slot's non-default home. freeResetsExpire optionally lists when each free reset ends, as the usage page gives it (["2026-10-29T20:24+01:00"]); a reset stops counting when its time has passed. amux quota --json puts name and subscription on every account, also when its reading failed. Version 1 files still give their slot homes.

Set AMUX_TOOL_LINES_CHANNELS in the bridge environment to a comma-separated list of pane addresses or Discord channel IDs to restore the old tool rows in those channels. * restores them everywhere; unset is the concise default. Restart the bridge after changing its environment.

Two Codex accounts

Profile 1 is the existing ~/.codex login. Profile 2 is isolated under ~/.config/agent/codex-profiles/2. Credentials never move between profiles; only a verified, quiescent pane-owned rollout can transfer for exact resume. Set up the second account once:

CODEX_HOME="$HOME/.config/agent/codex-profiles/2" codex login --device-auth

Preview or request a pane, project or configured-fleet switch:

amux accounts switch codex:2 claw -p 5 --dry
amux accounts switch codex:2 claw -p 5
amux accounts switch codex:2 --all
amux accounts switch codex:2 --all --json --request-id dashboard-request-uuid
amux accounts switch-status --json --request-id dashboard-request-uuid

JSON switches atomically register the complete pane scope before doing account work. The same request id returns its existing receipt; switch-status only reads it, including after a bridge or dashboard restart. After correcting a blocker, switch ... --request-id ID --retry-blocked explicitly retries that batch without changing its pane identities. Per-pane phase, reason, result kind and totals distinguish pending, blocked, verified switches and dormant selections. A divergent dormant history keeps both journals and saves a labeled handover for a fresh session on the next real start, shown as mode: fresh-next-start.

Running panes compact first under the existing delivery and native-receipt guards, then preserve their model, effort and exact portable session. A nonportable session needs a saved, labeled handover; failed verification restores the previous account. Busy panes keep a durable request which the existing journal watcher applies at a safe idle boundary. Dormant selections take effect at the next normal start and never wake a pane. Single-pane --continue-file PATH queues that continuation once after verification. Actual weekly-limit recovery works in either direction; forecasts never switch accounts. AMUX_CODEX_LIMIT_RECOVERY_ENABLED=false disables it.

A Claude pane stopped at a spent week resumes its exact session on the logged-in Claude account with the most weekly room, and amux accounts rotate moves such a pane together with the messages its limit parked (AMUX_CLAUDE_LIMIT_RECOVERY_ENABLED=false disables the automatic move). Sending to a stopped pane warns the sender, and AMUX_IDLE_CAPACITY_TARGET names the pane told when capacity sits unused; see docs/accounts.md.

//switch remains pane-local and native //status shows the actual account. Model launch overrides are process-local rather than persisted by the TUI picker into the account-wide config.toml.

Rotate a Claude fleet between accounts

Account homes are declared in ~/.agentmux/account-profiles.json; OAuth files stay inside each provider-owned home. Prepare and authenticate profile 2 once:

amux accounts login claude:2

Inspect a fleet rotation without changing a pane:

amux accounts rotate claude:2 --dry

The target can also be a login dir or an account email (amux accounts rotate claude:wetterlind@example.test --dry). The real rotation first locks delivery and refuses active turns, drafts, unknown state, or missing exact sessions. Only a warm context above 80k tokens gets a verified /compact on its source first; cold or small contexts move as they are, since the switch is a cache miss either way (see docs/accounts.md). It then switches the profile and resumes each exact session. Sleeping panes are only marked for their next wake; they are not started. A failed restart rolls that pane back to its previous profile and reports PARTIAL or BLOCKED, never false success.

From Discord, /byt <login> replies with the same plan and changes nothing; /byt <login> ok from the operator, within 10 minutes, switches. amux quota shows under each account the panes that run on it right now.

The secondary Claude profile shares only the projects session-history directory with profile 1. Credentials, settings, and quota remain isolated. No logout or token copy is part of the workflow.

Automatic quota recovery

The sidecar reads OAuth usage for each pane's selected Claude profile, once per profile per poll. Exact-session resume uses that same profile, model and effort. It does not rotate accounts or purchase a model call to check quota. After a manual resume, a matching journal and live --resume process can release old quota scheduling parks under the existing delivery lease. Submitted jobs retain their status and submit fences; only delivery reconciliation can acknowledge them. A stale or different session, draft, or unproven live process stays held. A continuation parked after a successful restart is made schedulable again when capacity returns, without a second restart or continuation. Explicit cancellation remains a broker decision, not a manual queue-file rewrite.

A terminal synthetic rate-limit receipt also closes the busy assessment when only same-session, engine-authored background task notifications follow it. New user input or tool activity invalidates that evidence. Idle is not quota availability, a delivery acknowledgement, or permission to resend.

Terminal commands:

amux ps
amux api -p 1 "run the test suite and summarize failures"
amux wait api -p 1
amux log api -p 1
amux log api -p 1 --tmux
amux timeline --since 30min
amux done --since 2h
amux asks --open
amux esc api -p 1
amux restart --all       # rebuild the full configured tmux fleet, even when invoked inside tmux

Personal todos with daily 08:00 push:

amux todo                      # list active
amux todo add "buy SSD"        # to Idag / snart
amux todo add --parked "..."   # later
amux todo done 5               # by id (or substring)
amux todo rm 5
amux todo-remind --dry         # preview push
bin/install-todo-cron.sh       # enable daily reminder

Backed by ~/.agentmux/workspace/memory/tasks.md. An existing OpenClaw file can be reused explicitly with AMUX_TODOS_PATH. Full docs in docs/todo.md.

Suggestions comment relay:

bin/install-suggestions-comment-bridge.sh install
bin/install-suggestions-comment-bridge.sh status
bin/install-suggestions-comment-bridge.sh run-once
bin/install-suggestions-comment-bridge.sh remove

Copy suggestions-comment-bridge.yaml.example, set your own HTTPS baseUrl and map projects to panes. With no configured URL the integration is disabled. Full routing, answer/retry, and security contract: docs/suggestions-comment-bridge.md.

Suggestions watchdog outbox delivery:

bin/install-suggestions-watchdog-outbox.sh install
bin/install-suggestions-watchdog-outbox.sh status
bin/install-suggestions-watchdog-outbox.sh run-once

This separate privileged consumer discovers every accessible public project, resolves each live bootstrap brokerOwner, and ACKs Suggestions only after agentmux records a verified delivery receipt. Failures remain pending under one durable identity. An explicit bounded project list is available as an override. See docs/suggestions-watchdog-outbox.md.

Exact Unicode for Suggestions writes

Agent-authored board mutations use amux-suggest with a strict UTF-8 JSON body file. When a request contains a human quote, pass the original quote in a separate --expect-file and provide --read-path; the client checks that text unchanged before the mutation, sends the persisted body bytes verbatim, then checks the authoritative GET response. Reusing a mutationId with different bytes fails locally instead of becoming an ambiguous retry. A single final LF or CRLF in the quote file is treated as text-file framing, not quote content.

amux-suggest --method PATCH \
  --base-url 'https://tasks.example.com' \
  --path '/api/tickets/DEMO-0014/admin?project=demo' \
  --body-file /tmp/demo-0014-update.json \
  --expect-file /tmp/original-quote.txt \
  --read-path '/api/tickets/DEMO-0014?project=demo'

bin/install-hooks.mjs installs a PreToolUse/Bash guard that rejects direct inline curl/Python mutations to the configured Suggestions API. With no SUGGEST_BASE_URL it is inert. Read-only calls remain available. The guard is at the authoring boundary because JSON, HTTP, and Suggestions storage already preserve Unicode; a retyped ASCII quote cannot be reconstructed downstream.

ax is installed as a shorter alias for amux.

Agent-to-Agent Delegation

Agents can use amux from their own terminal, so one pane can coordinate others:

amux api -p 1 "run backend tests"
amux frontend -p 1 "audit the dashboard layout"
amux wait api -p 1
amux wait frontend -p 1
amux log api -p 1
amux log frontend -p 1

Generated .agents/CLAUDE.md and .agents/AGENTS.md files teach Claude Code and Codex how to use these commands from inside project panes. They also carry the shared ownership policy: one active feature per agent, one end-to-end owner per feature, targeted checks and owner-driven merge/deploy. When a work board is configured, agents may self-claim explicitly claimable work. A project manager is an optional sidecar that watches capacity, blockers, dropped work and duplicates; it is not a mandatory route for tasks, review, merge or delivery. Dormant coding panes stay dormant until a real task targets them.

amux hints-sync refreshes that generated block across every configured workspace immediately; the bridge performs the same fleet sync at startup. Operator additions below the generated end marker remain intact.

An agent's send ([from project:N]) that pastes 8 or more consecutive words from one of the operator's Discord messages of the last 14 days is refused before the queue, and the refusal lists every quoted run. Case and punctuation are ignored; the bridge's own tags, links, paths and ids are not counted. His original words remain in the automatically recorded conversation; use source pointers under the authority policy, not manual quotation logs. The operator's own messages are never checked. AMUX_QUOTE_GUARD_ENABLED=false turns it off.

Configuration

Common .env variables:

VariableDefaultDescription
DISCORD_TOKENunsetDiscord bot token; required only for the bridge
AGENTMUX_YAML~/.agentmux/agentmux.yamlConfig file path
TMUX_SOCKET/tmp/agentmux-tmux.socktmux socket used by agentmux
TIMEOUT_S600Max wait for a pane response
TTS_VOICEen-US-AriaNeuraledge-tts voice
AMUX_OPERATOR_NAMEthe operatorHuman-facing operator label
AMUX_TOOL_LINES_CHANNELSunsetComma-separated channel IDs or pane addresses that retain old tool rows; * selects all
SUGGEST_BASE_URLunsetOptional self-hosted Suggestions-compatible board
AGENTMUX_RECORD0Save request/response recordings when set to 1

See agentmux.yaml.example for a fuller project config example.

Documentation

  • CircleKit Product Studio is a local, unpublished tool. Install its locked dependencies and run npm link in that checkout, then run v1d-studio here. To record the AMUX policy trace, run v1d-studio record --product amux. The selected focused test is declared in studio.workspace.json; the viewer does not start the bridge. Link declaration laws use v1d-studio laws --product amux-link.
  • Reliability: Loop Guard, Drift Guard, Auto-Compact, and recovery commands.
  • CLI Reference: amux commands, log modes, timelines, and orchestrator commands.
  • Public distribution: core/integration boundary and the no-private-default contract.
  • Support: supported surface and a safe diagnostic bundle.
  • Security: vulnerability-reporting procedure and the explicit autonomy model.

Troubleshooting

If a Codex model change stopped during startup, retry the explicit model command, for example amux model project -p 6 sol xhigh. It resumes the recorded session, keeps compact and input checks, and clears the saved transition block only after the selected model is verified. An automatic wake does not erase that block or replay a message. Startup goal menus choose Leave paused.

If a pane does not respond:

amux log <agent> -p <pane> --tmux
amux esc <agent> -p <pane>
amux enter <agent> -p <pane>       # submit an existing composer
amux clearline <agent> -p <pane>   # idle editor only; verified empty afterward
amux wait <agent> -p <pane>

From Discord, use /raw, /esc, /dismiss, or //new for the same recovery path.

If Discord channels are missing or stale, run /sync again after checking agentmux.yaml.

Tests

npm test

License

MIT

↑↓ navigate openesc close