Skip to content

omriariav/amq-squad

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

amq-squad

Role-aware agent team launcher built on top of AMQ by Aviv Sinai.

AMQ owns messaging between agents. amq-squad owns the layer above: who is in the team, what role each agent plays, and how to bring the whole squad back up after a restart.

Why

AMQ's coop exec is a generic launcher. It sets up a mailbox and execs into claude or codex, but it doesn't know:

  • Which agent is the "CPO" vs "CTO" vs "Fullstack" vs "QA" vs "PM" vs "Designer"
  • What command you originally used to launch each one (cwd, binary, flags, workstream)
  • What slash commands or skills that role leans on
  • Which peers a given agent actively talks to

amq-squad captures this at team-setup time (.amq-squad/team.json) and per-agent at launch time (launch.json + role.md inside the AMQ mailbox). AMQ itself stays unchanged.

Install

go install github.com/omriariav/amq-squad/cmd/amq-squad@v0.6.1

Use @latest if you intentionally want the newest published tag.

Requires Go 1.25+ and the amq binary in PATH (v0.34+). Installing to $GOBIN (or $HOME/go/bin) is enough; the launch commands team show emits use the absolute path to whichever amq-squad binary is running, so nothing else needs to be on PATH.

Quick start

cd ~/Code/my-project
amq-squad team

First run: pick personas from the squad market, then choose which CLI runs each one. amq-squad writes .amq-squad/team.json, seeds .amq-squad/team-rules.md, and prints launch commands. Later runs print the same launch commands without asking again. If you are inside tmux, use amq-squad team launch to open the squad automatically. Otherwise, paste one command into each terminal pane or tab.

You do not need to run amq coop init for the normal single-project flow. Generated launch commands put the team into one AMQ workstream session. By default that workstream is the sanitized team-home directory name, and AMQ creates the needed mailbox directories on first launch. Use amq coop init or a hand-written .amqrc only when you want a custom root, explicit project name, or cross-project peer routing.

Non-interactive setup:

amq-squad team init --personas cpo,cto,senior-dev,frontend-dev,mobile-dev,qa,pm,designer

With per-persona CLI overrides:

amq-squad team init \
  --personas cto,junior-dev,qa \
  --binary junior-dev=codex,qa=claude

Members don't have to share a working directory. The dir where you run team init becomes the team-home (where team.json and team-rules.md live); individual members can live in other projects:

cd ~/Code/project-a
amq-squad team init \
  --personas cpo,cto,fullstack,qa \
  --cwd qa=~/Code/project-b

team show emits a cd <member-cwd> per command so every agent boots in the right project. team sync walks each unique member cwd and syncs CLAUDE.md + AGENTS.md in all of them.

Generated launch commands include these agent defaults:

  • Claude: --permission-mode auto
  • Codex: nothing by default (sandboxed). Pass --trust trusted to prepend --dangerously-bypass-approvals-and-sandbox for the local power-user path. The trust profile is persisted in team.json from team init and re-emitted by team show / team launch.

amq-squad launch --trust sandboxed|trusted controls the same boundary for direct launches. Trust is Codex-specific; Claude defaults are unaffected. Pass --no-default-args to skip all built-in defaults entirely.

--trust trusted and --no-default-args together are rejected, as is sandboxed mode with --dangerously-bypass-approvals-and-sandbox smuggled through --codex-args.

Pass a model name to either binary natively via --model:

amq-squad launch --model gpt-5 codex
amq-squad launch --model sonnet claude

team init --model role=model,... persists per-member models in team.json. team show --model role=model,... and team launch --model ... override per run. Restore replays the persisted model.

Duplicate-launch guard: amq-squad launch refuses by default when a live agent for the same handle/workstream is detected (live amq wake lock, running agent PID with matching command, or fresh active presence). Stale artifacts are cleaned up automatically. team launch preflights the entire roster before any tmux command so a partial team never appears. Override with --force-duplicate when you really want a second instance.

Add native Codex or Claude flags as binary args when the whole team should run with the same extra switches:

amq-squad team init \
  --personas cto,fullstack \
  --codex-args '--enable goals' \
  --claude-args '--chrome'

Those args are stored in .amq-squad/team.json, included in team show and team launch, and treated as launch defaults so bootstrap and --conversation continue to work. Use the same flags on team show or team launch for a one-off run without changing team.json:

amq-squad team launch --codex-args '--enable goals' --claude-args '--chrome'

Launching a team in tmux

If you are already working inside tmux, team launch opens the configured team in the current tmux window:

amq-squad team launch

Defaults:

  • --terminal tmux
  • --target current-window
  • --layout vertical
  • --session <sanitized team-home directory name>
  • --stagger 750ms

The current pane becomes the first agent pane. Additional team members are opened as vertical side-by-side panes, pane titles are set to role names, and agent launches are staggered to avoid flooding terminal control channels.

Preview the exact tmux script without creating panes:

amq-squad team launch --dry-run

Launch into an explicit AMQ workstream:

amq-squad team launch --session issue-96

Use --fresh --session issue-96 when accidental reuse should fail if the workstream already exists.

Explicit workstream names must be AMQ-safe: lowercase letters, digits, -, and _. Release names such as v0.5.0 should be written as v0-5-0.

Alternative layouts:

amq-squad team launch --layout horizontal
amq-squad team launch --layout tiled

To create a separate detached tmux session instead:

amq-squad team launch --target new-session --terminal-session squad-issue-96
tmux attach -t squad-issue-96

When iTerm2 tmux -CC control-mode clients are detected, amq-squad warns about the known pause-after risk. If input stalls in iTerm2 cc-mode, recover from a non-tmux shell:

tmux list-clients
tmux detach-client -t /dev/ttysXXX

Terminal backend plugins

team launch is wired as a small backend registry. The CLI handles shared team loading, bootstrap flags, and common launch options, then dispatches to a terminal backend by name. v0.5.0 ships the tmux backend.

Adding another terminal should be isolated to a new internal/cli/team_launch_<name>.go file that implements teamLaunchBackend and registers itself with registerTeamLaunchBackend from init.

Representative generated commands look like this (sandboxed Codex, the new default):

cd ~/Code/my-project && /path/to/amq-squad launch \
  --role cto \
  --session my-project \
  --team-workstream \
  --trust sandboxed \
  --team-home /Users/you/Code/my-project \
  --me cto \
  codex

cd ~/Code/my-project && /path/to/amq-squad launch \
  --role fullstack \
  --session my-project \
  --team-workstream \
  --trust sandboxed \
  --team-home /Users/you/Code/my-project \
  --me fullstack \
  claude -- --permission-mode auto

Run amq-squad team init --trust trusted (or pick trusted in the interactive prompt) for the local-power-user profile that includes --dangerously-bypass-approvals-and-sandbox for Codex.

Bringing the team back after reboot, terminal close, or upgrade

When a terminal closes, the machine reboots, or you upgrade Codex/Claude, you do not need to remember whether to use team launch or restore. Run:

amq-squad team resume

This inspects .amq-squad/team.json, local launch history, and live-agent signals (wake locks, agent PIDs, presence) and prints a per-member plan plus copy-pasteable commands. Per-member action labels:

  • live: a matching agent is still running; the command is suppressed by default. Pass --force-duplicate to launch a second instance anyway.
  • restore: a launch record exists for the workstream; the emitted command replays it and preserves trust, model, conversation, role, handle, and binary args.
  • launch fresh: no matching launch history; the emitted command is the same shape team launch would use, with current team trust/model/binary args.
  • blocked: ambiguous live state; choose --force-duplicate or narrow with --session.

Common flows:

# Default: resume the team's saved workstream, prefer restore.
amq-squad team resume

# Resume into an explicit session.
amq-squad team resume --session v0-6-0-review

# Refuse if no member has restorable history (catch a stale workstream pick).
amq-squad team resume --restore-existing

# Start a brand-new workstream from team.json (ignore restore records).
amq-squad team resume --fresh --session v0-6-1

# Force a second instance even when a live agent is detected.
amq-squad team resume --force-duplicate

team resume is plan-only. The existing power-user commands stay available: team launch for tmux-pane launches from team intent, restore for explicit launch-history replay, and list for inspection.

At launch time, each agent's bootstrap prompt includes a current team routing block generated from .amq-squad/team.json. That block is the live routing source of truth: role, handle, workstream, project, cwd, and the appropriate amq send shape from the agent's current project. Sibling workstreams are listed as metadata only; message bodies from old workstreams are not loaded unless the user asks.

Built-in personas

Think of personas as employees in a small internal market. The persona is the job you are hiring for; the CLI is the tool that employee runs on.

ID Label Default binary Profile
cpo CPO codex Product direction, scope pressure, user value.
cto CTO codex Architecture, tradeoffs, final technical review.
senior-dev Senior Developer codex Takes harder code paths and reviews junior work.
fullstack Fullstack Developer claude End-to-end feature builder across UI and backend.
frontend-dev Frontend Developer claude Product UI, components, state, browser polish.
backend-dev Backend Developer codex APIs, data flow, services, integrations.
mobile-dev Mobile Developer claude Native and mobile app flows, device polish.
junior-dev Junior Developer codex Fast on scoped tasks, needs review before merge.
qa QA Manager claude Regression thinking, release risk, test coverage.
pm Project Manager / Product Owner claude Keeps work ordered, unblocked, and shippable.
designer Product Designer claude Product flows, visual shape, UI polish.

Defaults are starting points. Override binaries per persona at team init time. Choose a workstream for a run with --session on team show or team launch, or store a shared default with team init --session <workstream>. Launch-time overrides do not write back to .amq-squad/team.json.

team init --session is a single shared workstream name. The old comma-separated role=name syntax is intentionally rejected; use one workstream for the team run, then use threads for focused conversations.

Shared team rules

Team-wide norms ("every change ships via a PR", "CTO approves before merge") live in a single file:

.amq-squad/team-rules.md

Claude reads CLAUDE.md, Codex reads AGENTS.md. Rather than maintaining both by hand, you edit team-rules.md and amq-squad team sync pushes the content into a managed block in both files. Everything outside the markers is yours and stays untouched.

amq-squad team rules init        Seed missing .amq-squad/team-rules.md with a stub
amq-squad team sync              Preview what would change (exit 1 if drift)
amq-squad team sync --apply      Write the managed block into CLAUDE.md and AGENTS.md
amq-squad team sync --apply --allow-outside
                                  Also write member cwds outside team-home

On first --apply with an existing CLAUDE.md, your content is adopted as the user region and the managed block is appended. Subsequent syncs only refresh the managed block. Sync writes are guarded with same-directory temporary files, atomic rename, and a stale-plan check. Member cwds outside the team-home directory require --allow-outside so a hand-edited team.json cannot write instructions into unrelated folders by surprise. Every configured cwd must already exist before sync writes there.

Walkthroughs

Squad in a single project

Two agents in one repo: CTO on codex, Fullstack on claude.

cd ~/Code/my-project
amq-squad team init --personas cto,fullstack

Open .amq-squad/team-rules.md and refine the generated role scope, workflow, approvals, and communication norms for your team. Then push the managed block into the doc files each binary reads:

amq-squad team sync          # preview (exit 1 if anything would change)
amq-squad team sync --apply  # writes the managed block into CLAUDE.md and AGENTS.md

Print the launch commands:

amq-squad team

You'll get two commands, one per role. Open separate terminal panes or tabs and paste one command per pane, or run amq-squad team launch from inside tmux to create the panes automatically. Each agent boots through amq-squad launch, which writes launch.json + a catalog-seeded role.md into the mailbox before handing off to amq coop exec. From there both agents share one AMQ workstream and use the canonical thread p2p/cto__fullstack for design escalations and review handoffs.

Squad spanning two projects

One team, members in two repos: CTO and Fullstack in project-a, QA in project-b. The team-home (team.json + team-rules.md) lives in project-a.

Create AMQ project config in each project so cross-project peers have stable project names. amq coop init is the easiest way to create the starter .amqrc files:

(cd ~/Code/project-a && amq coop init)
(cd ~/Code/project-b && amq coop init)

For cross-project messages to route, each project's .amqrc needs a peers entry pointing at the other project's .agent-mail/. Edit ~/Code/project-a/.amqrc:

{
  "root": ".agent-mail",
  "project": "project-a",
  "peers": {
    "project-b": "/Users/you/Code/project-b/.agent-mail"
  }
}

Mirror it in ~/Code/project-b/.amqrc:

{
  "root": ".agent-mail",
  "project": "project-b",
  "peers": {
    "project-a": "/Users/you/Code/project-a/.agent-mail"
  }
}

This peers step is manual today; see the Known gaps section below.

Now pick the team from the team-home project:

cd ~/Code/project-a
amq-squad team init --personas cto,fullstack,qa --cwd qa=~/Code/project-b

Edit ~/Code/project-a/.amq-squad/team-rules.md. Then sync. Because one member lives elsewhere, sync walks both cwds and writes CLAUDE.md + AGENTS.md in each:

amq-squad team sync --apply --allow-outside
# Wrote 4 files: CLAUDE.md and AGENTS.md in project-a, same in project-b

Print the launch commands:

amq-squad team

You'll get three commands, each with the correct cd <member-cwd> so every agent boots in the right repo. Open three panes and paste one per pane. QA's codex or claude will live in project-b's mailbox tree; CTO and Fullstack in project-a's. AMQ uses the peers config you set above to route messages across.

The generated bootstrap for each role prints send commands relative to that role's project. For example, a project-a agent sending to QA in project-b will see a route shaped like:

amq send --to qa --project project-b --session project-a --thread p2p/cto__qa

Commands

amq-squad team                      Smart default: show commands, or init if none exists
amq-squad team init [--personas ...] [--session workstream]
                    [--trust sandboxed|trusted]
                    [--model role=model,...]
                    [--codex-args args] [--claude-args args]
                                    Pick personas, choose CLIs, models, and
                                    Codex trust profile; seed rules.
amq-squad team show [--session name] [--fresh] [--no-bootstrap]
                    [--trust sandboxed|trusted]
                    [--model role=model,...]
                    [--codex-args args] [--claude-args args]
                    [--force-duplicate]
                                    Print launch commands for the configured team
amq-squad team launch [--terminal tmux] [--target current-window|new-session]
                      [--session workstream] [--fresh]
                      [--layout vertical|horizontal|tiled]
                      [--terminal-session name] [--stagger 750ms]
                      [--no-bootstrap]
                      [--trust sandboxed|trusted]
                      [--model role=model,...]
                      [--codex-args args] [--claude-args args]
                      [--force-duplicate] [--dry-run]
                                    Open the configured team in tmux panes.
                                    Whole-roster live-agent preflight runs
                                    before any tmux command; --force-duplicate
                                    overrides.
amq-squad team resume [--session name] [--fresh] [--restore-existing]
                      [--dry-run] [--force-duplicate]
                      [--no-bootstrap] [--trust sandboxed|trusted]
                      [--model role=model,...]
                      [--codex-args args] [--claude-args args]
                                    Plan the safe path to bring the team back
                                    after reboot/upgrade/terminal close.
                                    Classifies each member as
                                    live / restore / launch fresh / blocked
                                    and prints copy-pasteable commands.
                                    Plan-only; no disk mutation.
amq-squad team rules init [--force] Seed or refresh .amq-squad/team-rules.md
amq-squad team sync [--apply] [--allow-outside]
                                    Sync CLAUDE.md and AGENTS.md from team-rules.md

amq-squad launch --role <r> --session <s> [--team-workstream] --me <handle>
                 [--conversation ref] [--no-bootstrap] [--no-default-args]
                 [--trust sandboxed|trusted] [--model <name>]
                 [--codex-args args] [--claude-args args]
                 [--force-duplicate]
                 <binary> [-- <flags>]
                                    Launch one agent. Writes launch.json + role.md
                                    in the AMQ mailbox, adds a bootstrap prompt,
                                    then execs 'amq coop exec'.
                                    Usually called by the output of 'team show'.
                                    --trust sandboxed (default) keeps Codex
                                    out of bypass mode; --trust trusted
                                    prepends --dangerously-bypass-approvals-and-sandbox.
                                    Claude defaults (--permission-mode auto)
                                    are still prepended when missing.
                                    --no-default-args opts out of all built-in
                                    defaults.
                                    --model passes a native --model <name>
                                    flag to Codex or Claude.
                                    --codex-args and --claude-args add native
                                    binary flags, such as '--enable goals' or
                                    '--chrome', while still allowing bootstrap.
                                    --conversation stores a restore ref and
                                    translates it to Codex or Claude resume args.
                                    --force-duplicate overrides the duplicate
                                    live-agent guard for the same handle and
                                    workstream.
                                    Do not combine --conversation with extra args
                                    after "--"; use --codex-args or --claude-args
                                    for native flags that should remain compatible
                                    with conversation restore.

amq-squad restore [--project dir1,dir2,...] [--conversation ref]
                                    Reconstruct launch commands from local
                                    launch.json history and nearby role.md
                                    persona files. Falls back to older AMQ
                                    mailbox history when launch.json is absent
                                    and the binary can be inferred.
                                    For records that look active, the metadata
                                    line surfaces wake-health:
                                      wake: pid:N    wake.lock present and
                                                     the wake process is alive
                                      wake: missing  agent looks active but
                                                     no wake.lock was found
                                      wake: stale    wake.lock present but
                                                     the PID is dead or
                                                     unrelated
amq-squad restore --exec --role cto Exec one selected local launch through
                                    amq coop exec.

amq-squad list [--json]             List restorable amq-squad records and
                                    AMQ-only inferred history across known
                                    projects.
amq-squad version                   Print the installed amq-squad version.

Files it writes

<project>/.amq-squad/team.json           Team intent: which roles are on this squad.
<project>/.amq-squad/team-rules.md       Shared norms and workflow (user-edited).
<project>/CLAUDE.md, AGENTS.md           Managed block synced from team-rules.md;
                                         user content outside markers untouched.
<AM_ROOT>/agents/<handle>/extensions/
  io.github.omriariav.amq-squad/
    launch.json                          Per-agent invocation record, written at launch.
                                         Includes conversation ref when supplied.
    role.md                              Per-agent role doc, seeded from the catalog
                                         with default operating guidance. User
                                         edits are preserved.

<AM_ROOT> is resolved via AMQ's JSON env contract (amq env --json) so amq-squad and amq coop exec always agree on the mailbox, root source, handle, and session. v0.6.1 writes extension namespaced metadata under extensions/io.github.omriariav.amq-squad/ and still reads legacy direct-agent launch.json and role.md files created by v0.5.x.

Known gaps

  • True cross-workstream sends from a setup terminal still depend on upstream AMQ semantics tracked in avivsinai/agent-message-queue#96. The normal team flow now avoids that path by launching one workstream and routing peer conversations with --thread.
  • Multi-cwd teams still need manual peers config in each project's .amqrc for cross-project AMQ routing. team sync doesn't touch .amqrc; that's left to the user until we're sure of the shape.

Requires

  • Go 1.25+
  • amq binary in PATH (v0.34+)
  • tmux in PATH for amq-squad team launch

About

Role-aware agent team launcher built on top of AMQ by @avivsinai

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors