Multi-Agent Workflow — wake agents, talk across machines, see the mesh.
maw is a CLI for running multiple AI agents across machines. You wake an agent in a tmux window, send it tasks, watch its screen, and see what it cost — all from one terminal. One node or twenty; same commands. Built on Bun and engine-agnostic — drives Claude Code, Codex, Aider, and OpenCode alike.
# One line:
curl -fsSL https://raw.githubusercontent.com/Soul-Brews-Studio/maw-js/main/install.sh | bash
# Or manually:
bun add -g github:Soul-Brews-Studio/maw-js
# Or from source:
ghq get Soul-Brews-Studio/maw-js && cd "$(ghq root)/github.com/Soul-Brews-Studio/maw-js" && bun install && bun linkVersioning:
maw-jsuses CalVer —v{yy}.{m}.{d}[-alpha.{HHMM}](e.g.v26.5.17-alpha.752). Migrated from SemVer alpha on 2026-04-18. Cutting a release? See CONTRIBUTING.md → Versioning. Background: CHANGELOG · umbrella #526.
If maw vanishes unexpectedly (see #531 — root cause: npm name collision, fixed in #557 via rename to maw-js), recovery paths:
- One-shot reinstall:
bun add -g github:Soul-Brews-Studio/maw-js - Self-heal command:
bunx -p github:Soul-Brews-Studio/maw-js maw doctor— auto-detects + restores - Shell hook: source
scripts/maw-heal.shfrom your.bashrc/.zshrc— checks on every shell init
Defense-in-depth: maw update stashes the binary to ~/.bun/bin/maw.prev before any destructive bun remove and restores on retry-fail (#551). maw doctor remains useful if the binary disappears for other reasons (older alpha, manual bun remove, disk full, etc.).
Full runbook: docs/install-recovery.md.
maw serve # start API + UI on :3456
maw ui install # download the federation lens
maw ui # → http://localhost:3456/federation_2d.html
maw ls --recent 5 # find recent sessions
maw wake neo --split # wake side-by-side with an oracle
maw bring neo --to work:review --pick # bring to an explicit session:window when fuzzy
maw hey neo "what are you working on?" # bare-name addressing worksmaw installs API-only. The React frontend ships separately from
Soul-Brews-Studio/maw-ui.
maw ui install # latest release
maw ui install --version v1.15.0 # specific version
maw ui status # verify installationDownloads dist.tar.gz from the maw-ui GitHub Release and extracts to the
active maw data dir (~/.maw/ui/dist/ by default today, or
$XDG_DATA_HOME/maw/ui/dist/ when MAW_XDG=1). Restart the maw server to
serve the new UI.
# Download dist.tar.gz from a release page, then:
MAW_UI_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/maw/ui/dist"
mkdir -p "$MAW_UI_DIR"
tar -xzf dist.tar.gz -C "$MAW_UI_DIR" --strip-components=1ghq get -u github.com/Soul-Brews-Studio/maw-ui
cd "$(ghq root)/github.com/Soul-Brews-Studio/maw-ui"
bun install && bun run build
ln -sf "$(pwd)/dist" "${XDG_DATA_HOME:-$HOME/.local/share}/maw/ui/dist"maw now has a central path resolver for config, state, data, and cache.
Legacy installs remain readable, but new runtime writers are moving away from
~/.config/maw/ and direct ~/.maw/ roots.
maw doctor xdg # show active config/state/data/cache roots
maw doctor xdg --json # machine-readable migration inventory
maw doctor xdg --migrate --dry-run # preview safe copy-forward moves
maw doctor xdg --migrate # copy legacy artifacts into XDG targets
MAW_XDG=1 maw doctor xdg # opt into spec-correct runtime pathsThe migration command is intentionally non-destructive: it copies missing artifacts forward and preserves existing destinations plus legacy sources.
maw wake org/repo # clone via ghq + wake
maw wake https://github.com/org/repo # full URL works too
maw wake org/repo --issue 5 # clone + send issue as prompt
maw bud myname --root # create a fresh oracle (no parent)
maw bud myname --from neo # bud from an existing oracle
# 👉 maw bud <stem> always creates repo <stem>-oracle.
# Never include "-oracle" in <stem> — it doubles the suffix.
# e.g. maw bud fusion → fusion-oracle ✓
# maw bud fusion-oracle → fusion-oracle-oracle ✗Talk across machines with HMAC-SHA256 signing.
maw hey neo "hello" # default: inbox + immediate pane delivery
maw hey neo "later" --inbox # queue-only: write receiver inbox, skip pane injection
maw hey white:neo "hello" # canonical form — remote node, window 1
maw hey white:neo:3 "hello hermes" # pick a specific tmux window (#410)
maw peek white:neo # see their screen
maw ping # check peer connectivity
# Config (maw.config.json)
{
"node": "oracle-world",
"federationToken": "shared-secret-min-16-chars",
"namedPeers": [{ "name": "white", "url": "http://10.20.0.7:3456" }]
}See the mesh in a browser. Any federation can point the lens at any backend:
maw ui # local lens
maw ui white # lens pointed at white's data
maw ui --tunnel 10.20.0.16 # SSH tunnel + lens URLThe lens reads ?host= at runtime (drizzle studio pattern). Packed-serve mode: maw ui install downloads the lens, maw serve serves it alongside the API on a single port.
Frontend repo: Soul-Brews-Studio/maw-ui
maw ls # compact session summary
maw ls -v / -c # detailed / compact views
maw ls --recent [n] # sort by creation time
maw peek [agent] # see agent screen
maw hey <agent> <msg> [--inbox] # send now by default; --inbox queues only
maw wake <oracle> [task] # wake oracle in tmux
maw wake --dry-run/--list # preview without side effects
maw wake --from-snapshot # restore from a wake snapshot
maw sleep <oracle> # gracefully stop
maw done <window> # auto-save + clean up worktree/branch
maw new <name> # create a workspace session
maw team bring <team> # bring oracles into a workspace
maw team create/oracle-invite # team management
maw scaffold <name> # structure-only project creation
maw snapshots list/show # browse wake snapshots
maw bud <name> [--from parent] # spawn new oracle
maw fleet ls/health/doctor # fleet config + health tools
maw oracle scan # discover oracles across nodes
maw plugin install <name> # install a registry or peer plugin
maw <plugin> serve # run plugin-owned browser/process UIs
maw fck # command correction plugin
maw fleet-ui serve # fleet dashboard plugin
maw messages serve # message ledger browser plugin
maw ui # open federation lens
maw serve [port] # start API server (default: 3456)Full command reference: maw --help
maw is now a plugin OS as much as a CLI. Core commands stay small,
while registry plugins add focused tools that can be enabled, served,
or removed without changing the engine.
maw plugin ls # installed + tiered plugins
maw plugin install <name> # install from maw-plugin-registry or peers
maw plugin enable <name> # opt into disabled-but-installed tools
maw <plugin> serve # run a plugin-owned browser/process UIThe plugin manifest supports CLI commands, capabilities, APIs, lifecycle
hooks, and engine-backed serve processes. Registry plugins such as
fleet-ui, messages, and fck can extend the operator surface without
promoting every experiment into core.
Charter-driven multi-agent teams with worktree isolation:
# Charter-based (recommended)
maw team up my-team --dry-run # preview spawn plan
maw team up my-team # spawn from .maw/teams/my-team.yaml
maw team down my-team # graceful shutdown
maw team reassign codex-1 "#999" # kill + fresh wake + re-dispatch
# Ad-hoc
maw new project-room --no-attach
maw team create project-room
maw team oracle-invite mawjs-issuer --team project-room
maw team bring project-roomCharter YAML declares members, engines, worktrees, and prompts. Workers
get isolated git worktrees; prompts are delivered via send-keys (works
with any engine — Claude Code, Codex, Aider, OpenCode).
Wake is now a lifecycle, not just a launch command. Plugins can declare
hooks.wake, hooks.serve, and hooks.sleep in plugin.json; maw can
preview wake plans, record snapshots, and restore from a previous launch.
maw wake neo --dry-run # inspect target/session/plugin effects
maw snapshots list # list captured wake state
maw wake neo --from-snapshot <id>| Endpoint | Purpose |
|---|---|
GET /api/config |
Node identity + agents map |
GET /api/fleet-config |
Fleet entries with sync_peers + lineage |
GET /api/feed?limit=200 |
Live event log |
GET /api/federation/status |
Peer connectivity |
POST /api/peer/exec |
Signed command relay between nodes |
POST /api/proxy/* |
HTTP relay for mixed-content peers |
Full reference: docs/federation.md
maw-js (backend + CLI) maw-ui (frontend)
├── src/commands/ (CLI + plugin dispatch) ├── src/components/
├── src/api/ (engine + plugin APIs) ├── src/hooks/
├── src/engine/ (WebSocket + serve proxy)├── src/lib/
├── src/transports/ (HTTP/tmux/hub) └── 16 HTML entry points
├── plugins (89 vendor plugin surfaces)
├── test/ (800+ test files)
└── install.sh
Oct 2025 maw.env.sh 30+ shell commands
Mar 2026 maw.js Bun/TS rewrite, tmux orchestration
Mar 2026 maw-js + maw-ui Backend/frontend split
Apr 2026 v2.0.0-alpha.66 Plugin OS foundation, Bun runtime,
federation API + maw-ui split
May 2026 v26.5.20-alpha.2203 Plugin engine, lifecycle hooks,
team workspaces, 89 plugins,
800+ test files, near-100% coverage,
portable Rust spec fixtures
Jun 2026 v26.6.6-alpha.1830 Charter-driven teams, engine-aware
wake/done, cross-node federation,
lean-core extraction (RFC #2113),
shared isClaudeLikeEngine helper
Peer handshake regressions hide on a single host. The Docker harness
spins up two maw-js:test containers on a shared network and runs
maw peers probe both directions as a round-trip smoke test.
bash scripts/test-docker-federation.sh # build + up + probe + teardown
bash scripts/dev-federation.sh up # leave the 2-node stack runningCI runs the same script via .github/workflows/federation-docker.yml
on any PR that touches docker/**, src/transports/**, or the peers
plugin. Full runbook: docs/federation/docker-testing.md.
Onboarding a new node? Use maw pair generate / maw pair <url> <code>
for a 6-char ephemeral handshake — see
docs/federation/pair-code.md.
The Rust port is tracked through portable JSON fixtures instead of prose-only
specs. See docs/maw-rs-port-status.md for the
current fixture inventory, crate lanes, and contributor entry points.
Plugins can be discovered and installed peer-to-peer (Shape A, no central
registry required). See
docs/plugins/shape-a-demo.md for a
7-step walkthrough — peers, federated search, @peer install, consent.
For fresh-install bootstrap, plugin source tiers, vendored registry plugins,
and maw plugin install trust/lock behavior, see
docs/plugins/install-architecture.md.