agentainer 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mehmetcanfarsak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,11 +1,81 @@
1
- # Agentainer
1
+ <!-- Banner -->
2
+ <p align="center">
3
+ <img alt="Agentainer — multi-agent orchestrator for AI coding agents" src="https://raw.githubusercontent.com/mehmetcanfarsak/AgentSwarm/main/assets/banner.svg" width="820">
4
+ </p>
5
+
6
+ <!-- Badges -->
7
+ <p align="center">
8
+ <img alt="license" src="https://img.shields.io/badge/license-MIT-blue.svg">
9
+ <img alt="zero deps" src="https://img.shields.io/badge/dependencies-zero-brightgreen.svg">
10
+ <img alt="platform" src="https://img.shields.io/badge/platform-linux%20%2F%20macOS-lightgrey.svg">
11
+ <img alt="tests" src="https://img.shields.io/badge/tests-48%20checks%20passing-success.svg">
12
+ </p>
13
+
14
+ <h1 align="center">Agentainer — Multi-Agent Orchestrator for AI Coding Agents</h1>
15
+
16
+ <p align="center">
17
+ <strong>A zero-dependency multi-agent orchestrator for AI coding agents.</strong><br>
18
+ Run a team of <b>Claude Code</b>, <b>OpenAI Codex</b>, <b>Gemini CLI</b>, and <b>Hermes</b> side by side in <b>tmux</b> — each in its own directory, each messaging the others only where your config allows.
19
+ </p>
20
+
21
+ <p align="center">
22
+ <em>Formerly <strong>AgentSwarm</strong>. Installed globally the command is <code>agentainer</code>; from a clone, <code>./agentainer</code> in the repo root is identical.</em>
23
+ </p>
24
+
25
+ **Agentainer** is a lightweight, stdlib-only orchestrator (Python 3 + bash + tmux, no runtime dependencies) that launches multiple AI coding agents — Claude Code, OpenAI Codex, Google's Gemini CLI, and Hermes — in isolated tmux sessions, each with its own working directory, and routes messages between them under a configurable access-control list. Define your whole agent team in a single YAML file; one command brings it online.
26
+
27
+ <!-- Demo -->
28
+ <p align="center">
29
+ <img alt="Terminal demo: agentainer up starts four agents, status shows them running, send delivers a task, and logs stream the routed messages" src="https://raw.githubusercontent.com/mehmetcanfarsak/AgentSwarm/main/assets/demo.svg" width="760">
30
+ <br>
31
+ <em>Start a four-agent swarm, check status, hand it a task, and watch the messages route — in four commands.</em>
32
+ </p>
2
33
 
3
- Run a team of coding agents — **Claude Code, Codex, Gemini CLI, Hermes** — side by
4
- side in tmux, each in its own directory, each able to message the others only if
5
- your YAML file says it may.
34
+ ---
35
+
36
+ ## <span id="table-of-contents"></span>Table Of Contents
37
+
38
+ - [Why Agentainer](#why-agentainer)
39
+ - [How it fits together](#how-it-fits-together)
40
+ - [Requirements](#requirements)
41
+ - [Install](#install)
42
+ - [Quickstart](#quickstart)
43
+ - [FAQ](#faq)
44
+ - [How it works](#how-it-works)
45
+ - [Capturing what an agent says](#capturing-what-an-agent-says)
46
+ - [Subagents, parallel work, and busy agents](#subagents-parallel-work-and-busy-agents)
47
+ - [Configuration reference](#configuration-reference)
48
+ - [Examples](#examples)
49
+ - [Commands](#commands)
50
+ - [Project layout](#project-layout)
51
+ - [Tests](#tests)
52
+ - [Troubleshooting](#troubleshooting)
53
+ - [A note on flags](#a-note-on-flags)
54
+
55
+
56
+ ## <span id="why-agentainer"></span>✨ Why Agentainer
6
57
 
7
- > Formerly **AgentSwarm**. Installed globally the command is `agentainer`; from a
8
- > clone, the `./agentainer` script in the repo root is the same thing.
58
+ - **Multi-agent, one command.** Spin up a whole team with `agentainer up` — folders, hooks, tmux sessions, and first prompts, all wired automatically.
59
+ - **Zero runtime dependencies.** Just Python 3 + bash + tmux. No pip installs, no bloated toolchain.
60
+ - **Real ACLs, not vibes.** Agents only message who your YAML `can_talk_to` list permits. `"*"` for everyone, an explicit list for tight graphs.
61
+ - **Survives restarts.** Each turn's conversation id is recorded; `up --resume` reattaches instead of starting cold.
62
+ - **Self-healing routing.** Busy agents queue inbound work, stranded messages get swept, and agents are nudged when a reply reaches nobody.
63
+ - **Any mix of CLIs.** Claude, Codex, Gemini, Hermes — or your own type — in the same swarm.
64
+
65
+ ## <span id="how-it-fits-together"></span>🏗️ How It Fits Together
66
+
67
+ *Architecture at a glance: a single `agents.yaml` file maps each AI coding agent to its own tmux session and working directory, while Agentainer routes and logs every message between them under a `can_talk_to` access-control list.*
68
+
69
+ <p align="center">
70
+ <img alt="Agentainer architecture: one YAML file maps each agent to its own tmux session and working directory; Agentainer routes and logs permission-checked messages between them" src="https://raw.githubusercontent.com/mehmetcanfarsak/AgentSwarm/main/assets/architecture.svg" width="900">
71
+ </p>
72
+
73
+ One command starts the swarm: it creates a folder per agent, installs a
74
+ completion hook inside each folder, opens a tmux session per agent, launches
75
+ the CLI, and types each agent's first prompt into it.
76
+
77
+ <details>
78
+ <summary>Plain-text diagram</summary>
9
79
 
10
80
  ```
11
81
  agents.yaml tmux
@@ -21,22 +91,20 @@ your YAML file says it may.
21
91
  one folder per agent messages routed + logged
22
92
  ```
23
93
 
24
- One command starts the swarm: it creates a folder per agent, installs a
25
- completion hook inside each folder, opens a tmux session per agent, launches
26
- the agent's CLI, and types each agent's first prompt into it.
94
+ </details>
27
95
 
28
96
  ---
29
97
 
30
- ## Requirements
98
+ ## <span id="requirements"></span>📋 Requirements
31
99
 
32
- - `tmux` (3.0+)
33
- - `python3` — PyYAML is used if present, otherwise a bundled parser handles the config
34
- - `node` (16+) — only for the global `agentainer` command; not needed if you run `./agentainer` from a clone
100
+ - **`tmux`** (3.0+)
101
+ - **`python3`** — PyYAML is used if present, otherwise a bundled parser handles the config
102
+ - **`node`** (16+) — only for the global `agentainer` command; not needed if you run `./agentainer` from a clone
35
103
  - whichever agent CLIs you reference: `claude`, `codex`, `gemini`, `hermes` — install only the one(s) you actually use
36
104
 
37
- ## Install
105
+ ## <span id="install"></span>🚀 Install
38
106
 
39
- Global, via npm:
107
+ **Global, via npm:**
40
108
 
41
109
  ```bash
42
110
  npm install -g agentainer
@@ -47,14 +115,14 @@ agentainer doctor # check tmux/python3 are present; report which agent CL
47
115
  which agent CLIs are available — it never fails on a missing *agent* CLI, since
48
116
  you may only use one of them.
49
117
 
50
- Or from a clone (no npm needed):
118
+ **Or from a clone (no npm needed):**
51
119
 
52
120
  ```bash
53
121
  git clone https://github.com/mehmetcanfarsak/AgentSwarm.git && cd AgentSwarm
54
122
  ./agentainer --help # same commands as the global `agentainer`, straight from the repo
55
123
  ```
56
124
 
57
- ## Quickstart
125
+ ## <span id="quickstart"></span>⚡ Quickstart
58
126
 
59
127
  ```bash
60
128
  cp agents.example.yaml agents.yaml
@@ -80,9 +148,43 @@ agentainer logs reviewer -n 20 # one agent
80
148
  agentainer inbox developer # messages an agent received
81
149
  ```
82
150
 
151
+ `agentainer status` gives you the whole swarm at a glance — who is up, who is mid-turn, and how deep each queue is:
152
+
153
+ <p align="center">
154
+ <img alt="agentainer status output: a table of agents with their type, state, turn, queue depth, capture mode, and can_talk_to permissions" src="https://raw.githubusercontent.com/mehmetcanfarsak/AgentSwarm/main/assets/screenshot-status.svg" width="820">
155
+ </p>
156
+
157
+ ---
158
+
159
+ ## <span id="faq"></span>❓ FAQ
160
+
161
+ **What is Agentainer?**
162
+ Agentainer is a zero-dependency multi-agent orchestrator that runs a team of AI coding agents — Claude Code, OpenAI Codex, Google's Gemini CLI, and Hermes — in isolated tmux sessions, each with its own working directory, and routes messages between them under a configurable access-control list. You describe the whole team in one YAML file and start it with a single command.
163
+
164
+ **Which AI coding agents does Agentainer support?**
165
+ Claude Code (`claude`), OpenAI Codex (`codex`), Google's Gemini CLI (`gemini`), and Hermes (`hermes`) out of the box. You can also define your own agent type via `agent_types:` — any CLI that takes input on stdin/tty works, with `capture: pane` or `capture: none`.
166
+
167
+ **Does Agentainer need Docker or any runtime dependencies?**
168
+ No. It is stdlib-only: Python 3, bash, and tmux. PyYAML is used if present, but a bundled parser handles the config without it. Node is only needed for the global `npm` launcher — running `./agentainer` from a clone needs no Node at all.
169
+
170
+ **How do I run multiple coding agents together?**
171
+ Write a YAML config listing your agents (and who may talk to whom), then run `agentainer up`. It creates a folder and a tmux session per agent, installs a turn-completion hook, launches each CLI, and types in the first prompt. `agentainer send --to <agent> "…"` messages any agent; `agentainer validate` previews the resolved swarm without launching anything.
172
+
173
+ **Can agents communicate with each other, and how is that controlled?**
174
+ Yes. Agents exchange tagged `<swarm-message>` / `<swarm-send>` blocks. Messaging is a whitelist: an agent may only reach the agents in its `can_talk_to` list (`"*"` means everyone else); anything else is refused. Auto-forwarding (`forward_responses_to`) can relay finished turns hands-free, bounded by a hop count to prevent loops.
175
+
176
+ **How do I resume a swarm after a crash or reboot?**
177
+ Each finished turn records the agent's conversation id in `.swarm/sessions.yaml`. `agentainer up --resume` reattaches every agent to its own conversation instead of starting cold, keeping any queued mail. Claude resumes with `--resume <id>`, Codex with `resume <id>`; Gemini and Hermes have no recoverable session id and always start fresh (with a warning).
178
+
179
+ **Is it safe to let agents run unattended?**
180
+ Agents run with whatever privileges their CLI is launched with. Flags like `claude --dangerously-skip-permissions`, `codex --yolo`, and `gemini --yolo` let them act without confirmation, which is usually what you want for an unattended swarm — so point `root` at a disposable directory and never run a swarm over a checkout you can't afford to lose.
181
+
182
+ **How is Agentainer different from just opening several terminals?**
183
+ It automates the brittle parts: detecting when each turn finishes (via a Stop/notify hook for Claude/Codex, or pane polling for Gemini/Hermes), typing multi-line prompts reliably into a live TUI, pre-trusting folders so the "trust this directory?" modal doesn't eat the first prompt, enforcing the comms ACL, queueing messages to busy agents, and resuming conversations after a restart.
184
+
83
185
  ---
84
186
 
85
- ## How it works
187
+ ## <span id="how-it-works"></span>🔧 How It Works
86
188
 
87
189
  **One folder + one tmux session per agent.** Agent `developer` gets
88
190
  `workspace/developer/` and a tmux session named `developer` (plus any
@@ -121,9 +223,8 @@ agents:
121
223
  checkout), but agents then overwrite each other's files and interleave commits,
122
224
  so `validate` and `up` warn when it happens. See
123
225
  [`examples/existing-repo.yaml`](examples/existing-repo.yaml).
124
-
125
- `root` is still used even when every agent lives elsewhere: it holds `.swarm/`
126
- with the logs, inboxes and the `swarm` shim.
226
+ - `root` is still used even when every agent lives elsewhere: it holds `.swarm/`
227
+ with the logs, inboxes and the `swarm` shim.
127
228
 
128
229
  **Prompts are typed in, not piped.** `swarm up` drops each first prompt into the
129
230
  agent's input box with a tmux bracketed paste, as one block, then presses Enter.
@@ -260,7 +361,7 @@ agent sees on its own terminal. Use `can_talk_to: "*"` for "everyone else".
260
361
 
261
362
  ---
262
363
 
263
- ## Capturing what an agent says
364
+ ## <span id="capturing-what-an-agent-says"></span>🎬 Capturing What An Agent Says
264
365
 
265
366
  Agentainer needs to know when an agent finishes a turn — both to log it and to
266
367
  support auto-forwarding. How it finds out depends on the CLI, and the two
@@ -293,7 +394,7 @@ mechanisms are **not** equally good:
293
394
 
294
395
  Set `capture:` per agent to override the default for its type.
295
396
 
296
- ### Subagents, parallel work, and busy agents
397
+ ### <span id="subagents-parallel-work-and-busy-agents"></span>🧩 Subagents, parallel work, and busy agents
297
398
 
298
399
  Coding agents spawn subagents and background tasks. Four things follow from that.
299
400
 
@@ -408,7 +509,7 @@ speak, and leave `forward_responses_to` unset.
408
509
 
409
510
  ---
410
511
 
411
- ## Configuration reference
512
+ ## <span id="configuration-reference"></span>⚙️ Configuration Reference
412
513
 
413
514
  Full annotated example: [`agents.example.yaml`](agents.example.yaml).
414
515
  Machine-readable summary for agents: [`llms.txt`](llms.txt).
@@ -485,7 +586,7 @@ placeholders.
485
586
 
486
587
  ---
487
588
 
488
- ## Examples
589
+ ## <span id="examples"></span>🧪 Examples
489
590
 
490
591
  Ready-to-run swarms in [`examples/`](examples/):
491
592
 
@@ -495,6 +596,16 @@ Ready-to-run swarms in [`examples/`](examples/):
495
596
  | [`software-company.yaml`](examples/software-company.yaml) | Org chart | Six agents across all four CLIs, with a deliberately restricted comms graph |
496
597
  | [`bug-hunt.yaml`](examples/bug-hunt.yaml) | Pipeline | `forward_responses_to` chaining reproduce → diagnose → fix → verify, hands-free |
497
598
  | [`existing-repo.yaml`](examples/existing-repo.yaml) | Pairing | Two agents in one **existing** checkout, with `create_workdirs: false` |
599
+ | [`red-team.yaml`](examples/red-team.yaml) | Adversarial triad | Attacker vs defender arbitrated by a referee, over one **existing** checkout |
600
+ | [`debate.yaml`](examples/debate.yaml) | Debate + judge | Two advocates argue opposite sides; a judge cross-examines and rules |
601
+ | [`writers-room.yaml`](examples/writers-room.yaml) | Hub + review cycle | An editor driving a writer, fact-checker and critic to a finished article |
602
+ | [`incident-response.yaml`](examples/incident-response.yaml) | Incident hub | A commander coordinating investigator/responder/scribe under time pressure |
603
+ | [`tdd-pingpong.yaml`](examples/tdd-pingpong.yaml) | Tight 2-agent loop | Tester writes one failing test, coder makes it pass, in one shared repo |
604
+ | [`brainstorm.yaml`](examples/brainstorm.yaml) | Diverge + converge | Three angled idea-generators fanning out, then a synthesiser ranks them |
605
+ | [`localization.yaml`](examples/localization.yaml) | Pipeline | Translate → review → back-check, auto-forwarded via `forward_responses_to` |
606
+ | [`multi-language-broadcast.yaml`](examples/multi-language-broadcast.yaml) | Broadcast fan-out | One translator broadcasts a source to N language reviewers; a consolidator compiles and broadcasts back |
607
+ | [`code-review-broadcast.yaml`](examples/code-review-broadcast.yaml) | Broadcast hub | One PR broadcast to specialist reviewers (correctness/security/perf); each replies to the coordinator who synthesizes |
608
+ | [`ping-pong.yaml`](examples/ping-pong.yaml) | Round-robin | Two agents trade a unit of work, each broadcast naming who is up next (distinct from tdd-pingpong's fixed `forward_responses_to`) |
498
609
 
499
610
  ```bash
500
611
  agentainer validate -c examples/research-swarm.yaml # look before you leap
@@ -505,7 +616,7 @@ agentainer send --to lead "Research the state of WebGPU compute shaders."
505
616
  `existing-repo.yaml` intentionally refuses to start until you point `workdir` at
506
617
  a repository that exists.
507
618
 
508
- ## Commands
619
+ ## <span id="commands"></span>💻 Commands
509
620
 
510
621
  | Command | Purpose |
511
622
  |---|---|
@@ -526,7 +637,7 @@ a repository that exists.
526
637
  `agentainer my-swarm.yaml` is shorthand for `agentainer up -c my-swarm.yaml`.
527
638
  `-c` and `$SWARM_CONFIG` both select a config; `-c` wins.
528
639
 
529
- ## Layout
640
+ ## <span id="project-layout"></span>📁 Project Layout
530
641
 
531
642
  ```
532
643
  AgentSwarm/
@@ -541,19 +652,19 @@ AgentSwarm/
541
652
  │ ├── config.py # schema, defaults, validation
542
653
  │ └── minyaml.py # YAML subset parser, used when PyYAML is absent
543
654
  ├── tests/validate.sh # full suite: mock agents, no model calls
544
- ├── examples/ # research swarm, software company, bug hunt, pairing
655
+ ├── examples/ # research, software company, bug hunt, pairing, red team, debate, writers' room, incident, tdd, brainstorm, l10n, multi-language + code-review (broadcast), ping-pong (round-robin)
545
656
  └── workspace/ # created by `up`
546
657
  ├── <agent>/ # one folder per agent
547
658
  └── .swarm/
548
659
  ├── state.json # what `up` started
549
- ├── sessions.yaml # each agent's conversation id, for `up --resume`
660
+ ├── sessions.yaml # each agent's conversation id, for `up --resume`
550
661
  ├── bin/swarm # the `swarm` command agents call
551
662
  ├── logs/ # <agent>.jsonl + swarm.jsonl
552
663
  ├── inbox/<agent>/ # archived messages
553
664
  └── run/ # watcher pids, hop counters
554
665
  ```
555
666
 
556
- ## Tests
667
+ ## <span id="tests"></span>✅ Tests
557
668
 
558
669
  ```bash
559
670
  tests/validate.sh
@@ -565,7 +676,7 @@ nothing. It covers the awkward cases: the check-and-set race between concurrent
565
676
  senders, a queued message beating a reply reminder, a subagent's sidechain turn
566
677
  being skipped, and a transcript read before Claude has flushed it.
567
678
 
568
- ## Troubleshooting
679
+ ## <span id="troubleshooting"></span>🛠️ Troubleshooting
569
680
 
570
681
  **"could not confirm the text arrived; NOT pressing Enter".** The agent's input
571
682
  box never echoed the prompt, so Agentainer refused to submit it. Attach to the
@@ -585,7 +696,7 @@ other. Raise `max_forward_hops`, or break the cycle in `forward_responses_to`.
585
696
  **Nothing captured from a claude agent.** Check `<agent-dir>/.claude/settings.json`
586
697
  exists and `.swarm/logs/hooks.log` for errors. If the agent also looks busy forever,
587
698
  its `type` probably does not match the CLI its `command` runs (see the capture note
588
- under [Busy agents](#busy-agents-and-backpressure)).
699
+ under [Busy agents](#subagents-parallel-work-and-busy-agents)).
589
700
 
590
701
  **Can't scroll up in an attached session.** Agentainer raises tmux's scrollback to
591
702
  `tmux_history_limit` (50000 lines) and turns on `tmux_mouse`, so the wheel scrolls
@@ -594,10 +705,22 @@ use `Ctrl-b [` then PageUp. Both options are set on the tmux server before sessi
594
705
  are created, so a server that was already running keeps its old panes' smaller
595
706
  buffer — restart the swarm (or that pane) to pick up the larger one.
596
707
 
597
- ## A note on flags
708
+ ## <span id="a-note-on-flags"></span>⚠️ A Note On Flags
598
709
 
599
710
  `claude --dangerously-skip-permissions`, `codex --yolo` and `gemini --yolo` let
600
711
  agents act without asking for confirmation. That is usually what you want for an
601
712
  unattended swarm, and it means several models are running tools unsupervised in
602
713
  these directories. Point `root` somewhere disposable, and don't run a swarm over
603
714
  a directory you can't afford to lose.
715
+
716
+ ---
717
+
718
+ ## 🤝 Contributing
719
+
720
+ Pull requests and issues are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for
721
+ the zero-dependency principles, a key-free smoke test, and the PR checklist. A
722
+ safe first run with no API keys lives in [quickstart.yaml](quickstart.yaml).
723
+
724
+ ## 📜 License
725
+
726
+ Released under the [MIT License](LICENSE).
@@ -0,0 +1,147 @@
1
+ # =============================================================================
2
+ # Brainstorm -- diverge into many ideas, then converge on a few worth doing.
3
+ #
4
+ # agentainer up -c examples/brainstorm.yaml
5
+ # agentainer send --to facilitator "Ways to cut our cloud bill by 30%."
6
+ #
7
+ # Shape: fan-out then funnel. A FACILITATOR poses the prompt to three idea
8
+ # generators who each riff from a different angle and never see each other's
9
+ # lists (so they don't converge too early), then hands the pile to a SYNTHESISER
10
+ # who clusters, de-dupes and ranks. The generators talk only to the facilitator.
11
+ #
12
+ # wildcard pragmatist contrarian
13
+ # \ | /
14
+ # `----- facilitator -----'
15
+ # |
16
+ # synthesiser
17
+ #
18
+ # Every link is two-way (the facilitator prompts each generator and they
19
+ # answer back). Ideas diverge across the three generators, then converge
20
+ # through the facilitator to the synthesiser.
21
+ #
22
+ # Deliberately divergent roles keep the three from producing the same list three
23
+ # times. This swarm creates its own folders under `root` -- no repo needed.
24
+ # =============================================================================
25
+
26
+ swarm:
27
+ name: brainstorm
28
+ root: ./brainstorm-workspace
29
+ session_prefix: "bs-"
30
+
31
+ # Fan-out then one funnel step: a single hop is enough.
32
+ max_forward_hops: 1
33
+
34
+ defaults:
35
+ type: claude
36
+
37
+ agents:
38
+
39
+ - name: facilitator
40
+ type: claude
41
+ command: "claude --dangerously-skip-permissions --model opus"
42
+ can_talk_to: ["wildcard", "pragmatist", "contrarian", "synthesiser"]
43
+
44
+ # Waits for the human to supply the actual prompt.
45
+ in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
46
+
47
+ first_prompt: |
48
+ You are the FACILITATOR. You run a divergent-then-convergent session.
49
+
50
+ You do not generate ideas or judge them yourself. You frame the prompt,
51
+ keep the three generators pulling in different directions, then hand the
52
+ raw pile to the synthesiser and relay the result.
53
+
54
+ Your room:
55
+ - wildcard: unconstrained, ambitious, "what if budget were no object"
56
+ - pragmatist: ships this quarter with what we already have
57
+ - contrarian: attacks the framing and the obvious answers
58
+ - synthesiser: clusters, de-dupes and ranks everything at the end
59
+
60
+ How to run it:
61
+ 1. Sharpen the human's prompt into one clear question with a success
62
+ metric. Send it to all three generators, and tell each to lean fully
63
+ into ITS angle -- no self-censoring, no converging yet.
64
+ 2. Do NOT show generators each other's ideas mid-round; that collapses
65
+ the diversity you are paying for.
66
+ 3. When all three have reported, forward the combined, unedited list to
67
+ the synthesiser.
68
+ 4. Relay the synthesiser's ranked shortlist to the human, with the one
69
+ bold idea and the one safe idea called out.
70
+
71
+ In the diverge phase, quantity and range beat quality. Save judgement for
72
+ the synthesiser.
73
+
74
+ - name: wildcard
75
+ type: claude
76
+ command: "claude --dangerously-skip-permissions"
77
+ can_talk_to: ["facilitator"]
78
+
79
+ first_prompt: |
80
+ You are the WILDCARD. Your job is range and ambition, not feasibility.
81
+
82
+ Given the question, produce 8-12 genuinely different ideas, including ones
83
+ that sound expensive, weird, or premature. Assume constraints can be
84
+ renegotiated. Chase the idea that would matter most if it worked.
85
+
86
+ For each: a one-line pitch and the single reason it could be a big deal.
87
+ Do not filter for practicality -- the pragmatist and synthesiser do that.
88
+ Avoid the obvious answer everyone already thought of; go past it.
89
+
90
+ - name: pragmatist
91
+ type: codex
92
+ command: "codex --yolo"
93
+ can_talk_to: ["facilitator"]
94
+
95
+ first_prompt: |
96
+ You are the PRAGMATIST. Your job is ideas that ship soon, cheaply.
97
+
98
+ Given the question, produce 8-12 ideas that a small team could start this
99
+ quarter with tools it already has. Favour reversible, low-risk moves with a
100
+ clear owner and a visible payoff.
101
+
102
+ For each: a one-line pitch, the rough effort, and the expected payoff. Bias
103
+ toward things measurable within a few weeks. Leave the moonshots to the
104
+ wildcard; you own "what can we actually do on Monday".
105
+
106
+ - name: contrarian
107
+ type: claude
108
+ command: "claude --dangerously-skip-permissions"
109
+ can_talk_to: ["facilitator"]
110
+
111
+ first_prompt: |
112
+ You are the CONTRARIAN. You attack the question and the easy answers.
113
+
114
+ First, challenge the framing: is the stated goal the real goal? Is the
115
+ metric measuring the right thing? Name the assumption everyone is making.
116
+
117
+ Then produce 6-10 ideas that come from rejecting the obvious approach:
118
+ do the opposite, remove the thing instead of optimising it, or solve the
119
+ problem one level up so it disappears.
120
+
121
+ For each: the conventional answer you are rejecting, and your alternative.
122
+ Be provocative but honest -- the goal is better options, not just dissent.
123
+
124
+ - name: synthesiser
125
+ type: claude
126
+ command: "claude --dangerously-skip-permissions"
127
+ can_talk_to: ["facilitator"]
128
+
129
+ # The shortlist lands somewhere predictable.
130
+ workdir: ./brainstorm-output
131
+
132
+ first_prompt: |
133
+ You are the SYNTHESISER. You turn a messy pile of ideas into a decision.
134
+
135
+ You receive every idea from all three generators. Write the result to
136
+ SHORTLIST.md.
137
+
138
+ Do this:
139
+ 1. Cluster near-duplicates into single themes; note where two angles
140
+ independently converged (that is a signal).
141
+ 2. Score each theme on impact vs effort. Be explicit about the criteria.
142
+ 3. Produce a ranked shortlist of 3-5 things worth doing, each with why it
143
+ made the cut and the first concrete step.
144
+ 4. Call out the single boldest bet and the single safest quick win, and
145
+ name any idea that is a trap (looks great, fails in practice).
146
+
147
+ Do not just list everything back. The value you add is cutting.
@@ -0,0 +1,109 @@
1
+ # =============================================================================
2
+ # Code review by broadcast -- one PR, several specialist lenses at once.
3
+ #
4
+ # 1. agentainer validate -c examples/code-review-broadcast.yaml
5
+ # 2. agentainer up -c examples/code-review-broadcast.yaml
6
+ # 3. agentainer send --to coordinator "Review PR #42 (git diff main...HEAD)."
7
+ #
8
+ # Shape: a hub built on `broadcast`. The COORDINATOR fans the diff out to
9
+ # every reviewer in one message; each REVIEWER owns one concern (correctness,
10
+ # security, performance) and reports back to the coordinator, who synthesizes a
11
+ # single review. The reviewers never talk to each other -- cross-cutting findings
12
+ # are the coordinator's job to merge.
13
+ #
14
+ # coordinator
15
+ # | (broadcast the PR to all)
16
+ # v
17
+ # +-------+--------+
18
+ # | | |
19
+ # correctness security perf
20
+ # | | |
21
+ # +--- coordinator ---+ (each reviewer replies to the coordinator)
22
+ #
23
+ # `broadcast` is the point of the example: the coordinator reaches several
24
+ # peers with one message and does not care which are mid-task. Every link is
25
+ # two-way. The change under review is passed in the prompt, so the swarm
26
+ # validates and runs without pointing at any repo.
27
+ # =============================================================================
28
+
29
+ swarm:
30
+ name: review
31
+ root: ./review-runtime # only holds logs, inboxes and swarm state
32
+ session_prefix: "rv-"
33
+
34
+ # Broadcasts don't auto-forward, so one hop is all the guard ever needs.
35
+ max_forward_hops: 1
36
+
37
+ # Each agent gets its own scratch folder under `root` for logs and state.
38
+ # The change under review is passed in the prompt (a `git diff`), so the agents
39
+ # never need to read a repo off disk -- point `workdir` here only if you want
40
+ # them to read the tree directly.
41
+ create_workdirs: true
42
+
43
+ agents:
44
+
45
+ - name: coordinator
46
+ type: claude
47
+ command: "claude --dangerously-skip-permissions --model opus"
48
+ can_talk_to: ["correctness", "security", "perf"]
49
+
50
+ in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
51
+
52
+ first_prompt: |
53
+ You are the REVIEW COORDINATOR. You do not review code yourself; you run
54
+ the review and merge the findings.
55
+
56
+ When the human gives you a change (a PR or a `git diff`), broadcast it to
57
+ every reviewer at once, each with the one concern they own:
58
+
59
+ <swarm-broadcast>
60
+ Review this change (PR #42, git diff main...HEAD):
61
+ - correctness: does it do what it claims? logic, edge cases, regressions
62
+ - security: injection, authz, secrets, unsafe deserialization
63
+ - perf: hot paths, N+1s, allocations, unbounded growth
64
+ Reply to me (the coordinator) with findings only for your lane.
65
+ </swarm-broadcast>
66
+
67
+ Collect the three replies. Merge overlapping findings, dedupe, and rank by
68
+ severity. Produce ONE consolidated review: a short verdict (Approve / Request
69
+ changes) followed by a bullet list of findings with file:line and the lane
70
+ that raised each. Do not invent findings the reviewers did not make.
71
+
72
+ - name: correctness
73
+ type: claude
74
+ command: "claude --dangerously-skip-permissions"
75
+ can_talk_to: ["coordinator"]
76
+ first_prompt: |
77
+ You are the CORRECTNESS reviewer. You receive a change broadcast by the
78
+ coordinator; review ONLY whether it does what it claims.
79
+
80
+ Look for: logic errors, off-by-one and boundary mistakes, wrong types or
81
+ null handling, missing or wrong edge-case handling, and silent regressions
82
+ in behaviour. Quote the offending line. When done, reply to the coordinator
83
+ with findings for this lane only -- nothing about security or performance.
84
+
85
+ - name: security
86
+ type: claude
87
+ command: "claude --dangerously-skip-permissions"
88
+ can_talk_to: ["coordinator"]
89
+ first_prompt: |
90
+ You are the SECURITY reviewer. You receive a change broadcast by the
91
+ coordinator; review ONLY for security risk.
92
+
93
+ Look for: injection (SQL/command/HTML), broken or missing authz, secrets
94
+ committed or logged, unsafe deserialization, path traversal, and trust of
95
+ unvalidated input. Quote the offending line and the abuse scenario. When done,
96
+ reply to the coordinator with findings for this lane only.
97
+
98
+ - name: perf
99
+ type: codex
100
+ command: "codex --yolo"
101
+ can_talk_to: ["coordinator"]
102
+ first_prompt: |
103
+ You are the PERFORMANCE reviewer. You receive a change broadcast by the
104
+ coordinator; review ONLY for performance.
105
+
106
+ Look for: accidental O(n^2) or N+1 patterns, allocations in hot loops,
107
+ unbounded growth (caches, lists), missing batching or indexes, and blocking
108
+ calls on the request path. Quote the offending line and the expected cost.
109
+ When done, reply to the coordinator with findings for this lane only.