skill
agentmux
Multi-agent orchestration for Claude Code and Codex using tmux, Discord ChatOps, and the amux CLI
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
README
synced Oct 22, 2026agentmux
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
amuxCLI. - 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
| Concept | Purpose |
|---|---|
| Agent | A named project workspace from agentmux.yaml |
| Pane | One addressed coding-agent session; tmux or native runtime |
| Bridge | The Node.js process that connects Discord, tmux, and logs |
amux | CLI 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:
pastingmeans agentmux initiated the pane write but has not yet proved that the exact text owns the composer. It remains visible inamux doctorand blocks blind Enter or duplicate paste across restarts.draftedmeans agentmux owns exact text still associated with the composer. It blocks later writes so payloads cannot merge.submittedmeans 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.acknowledgedmeans the authoritative Claude/Codex history contains the exact prompt. Receipt reconciliation runs independently of later writes.delivered_unverifiedis 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 fromagent: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
- Create a bot in the Discord Developer Portal.
- Enable Message Content Intent for the bot.
- Invite the bot to your server with permissions to send messages, read history, attach files, and manage channels.
- Put the token in
~/.agentmux/.env:
DISCORD_TOKEN=your-token-here
- Put your Discord server ID in
~/.agentmux/agentmux.yaml. - Start agentmux and run
/sync.
Everyday Commands
Discord commands:
| Command | Description |
|---|---|
/sync | Create or update Discord channels from config |
/status | Claude: 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 |
/peek | Show the last response from the target pane |
/raw | Show raw tmux pane output |
/esc | Send Escape to the target pane |
/dismiss | Dismiss a blocking prompt where supported |
/use <agent>[.pane] | Temporarily retarget the channel |
/reload | Reload config |
/restart | Restart only the bridge process |
/restart all | Recreate 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:
| Variable | Default | Description |
|---|---|---|
DISCORD_TOKEN | unset | Discord bot token; required only for the bridge |
AGENTMUX_YAML | ~/.agentmux/agentmux.yaml | Config file path |
TMUX_SOCKET | /tmp/agentmux-tmux.sock | tmux socket used by agentmux |
TIMEOUT_S | 600 | Max wait for a pane response |
TTS_VOICE | en-US-AriaNeural | edge-tts voice |
AMUX_OPERATOR_NAME | the operator | Human-facing operator label |
AMUX_TOOL_LINES_CHANNELS | unset | Comma-separated channel IDs or pane addresses that retain old tool rows; * selects all |
SUGGEST_BASE_URL | unset | Optional self-hosted Suggestions-compatible board |
AGENTMUX_RECORD | 0 | Save 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 linkin that checkout, then runv1d-studiohere. To record the AMUX policy trace, runv1d-studio record --product amux. The selected focused test is declared instudio.workspace.json; the viewer does not start the bridge. Link declaration laws usev1d-studio laws --product amux-link. - Reliability: Loop Guard, Drift Guard, Auto-Compact, and recovery commands.
- CLI Reference:
amuxcommands, 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