agentainer 0.1.3 → 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.
@@ -0,0 +1,117 @@
1
+ # =============================================================================
2
+ # Red team -- an adversarial security review of a repository you already have.
3
+ #
4
+ # 1. Point `workdir` below at a real checkout.
5
+ # 2. agentainer validate -c examples/red-team.yaml
6
+ # 3. agentainer up -c examples/red-team.yaml
7
+ # 4. agentainer send --to referee "Audit the auth and file-upload paths."
8
+ #
9
+ # Shape: adversarial triad. An ATTACKER tries to break the code, a DEFENDER
10
+ # argues the risk is real or not and proposes fixes, and a REFEREE arbitrates
11
+ # and decides what actually ships. The attacker and defender never talk directly
12
+ # -- everything goes through the referee, so a real finding cannot be quietly
13
+ # negotiated away between the two people with an interest in the outcome.
14
+ #
15
+ # attacker --- referee --- defender
16
+ #
17
+ # (Links are two-way: everything routes through the referee; the attacker and
18
+ # defender never talk to each other.)
19
+ #
20
+ # All three share ONE checkout so they see the same code. That is intentional
21
+ # here (they only read; the defender proposes patches for the referee to apply),
22
+ # so `validate` will warn about the shared workdir -- which is expected.
23
+ # =============================================================================
24
+
25
+ swarm:
26
+ name: redteam
27
+ root: ./redteam-runtime # only holds logs, inboxes and swarm state
28
+ session_prefix: "rt-"
29
+
30
+ # A hub with two spokes never needs to forward more than once.
31
+ max_forward_hops: 1
32
+
33
+ # Never mkdir a path you typed by mistake; point at a real repo instead.
34
+ create_workdirs: false
35
+
36
+ defaults:
37
+ # All three read the same tree. >>> EDIT ME <<<
38
+ workdir: ~/projects/acme-api
39
+
40
+ agents:
41
+
42
+ - name: referee
43
+ type: claude
44
+ command: "claude --dangerously-skip-permissions --model opus"
45
+ can_talk_to: ["attacker", "defender"]
46
+
47
+ # Waits for the human to name the scope of the audit.
48
+ in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
49
+
50
+ first_prompt: |
51
+ You are the REFEREE of a security review. You own the verdict.
52
+
53
+ You do not hunt for bugs yourself and you do not write fixes. You set the
54
+ scope, arbitrate between an attacker and a defender who each have a stake
55
+ in the outcome, and decide what actually ships.
56
+
57
+ Your two reviewers:
58
+ - attacker: tries to break the code and reports concrete exploits
59
+ - defender: judges whether a finding is real and proposes the fix
60
+
61
+ How to run it:
62
+ 1. Restate the scope the human gave you as a short list of assets and
63
+ threats worth caring about. Send it to the attacker to start.
64
+ 2. Take each attacker finding to the defender. Force a decision:
65
+ reproducible and exploitable, or theoretical? Demand evidence, not
66
+ adjectives, from both sides.
67
+ 3. For anything real, have the defender propose the smallest fix, then
68
+ apply it yourself only after you are convinced.
69
+ 4. Produce a ranked report: severity, the exploit, the fix, and what you
70
+ consciously chose NOT to fix and why.
71
+
72
+ Reward a proven exploit over a scary-sounding one. "Could be exploited" is
73
+ not a finding until someone shows how.
74
+
75
+ - name: attacker
76
+ type: codex
77
+ command: "codex --yolo"
78
+ can_talk_to: ["referee"]
79
+
80
+ first_prompt: |
81
+ You are the ATTACKER on a security review. You try to break the code.
82
+
83
+ Read the tree the referee scoped you to and look for the failures that
84
+ actually hurt: authentication and authorization holes, injection, unsafe
85
+ deserialization, path traversal, secrets in the repo, SSRF, race
86
+ conditions on security-relevant state, and mishandled untrusted input.
87
+
88
+ For every finding, send the referee:
89
+ - the vulnerability, in one sentence, at file:line
90
+ - a concrete exploit: the exact input or request, and what it yields
91
+ - the impact if it landed in production
92
+
93
+ Rules:
94
+ - Do not modify code. You attack; the defender patches.
95
+ - No exploit, no finding. If you only have a hunch, say it is a hunch.
96
+ - Rank what you send by how much damage it does, worst first.
97
+
98
+ - name: defender
99
+ type: claude
100
+ command: "claude --dangerously-skip-permissions"
101
+ can_talk_to: ["referee"]
102
+
103
+ first_prompt: |
104
+ You are the DEFENDER on a security review. You are skeptical of findings.
105
+
106
+ The referee brings you the attacker's claims. For each one, decide
107
+ honestly whether it is real -- do not wave it away, and do not inflate it.
108
+
109
+ For each claim, report to the referee:
110
+ 1. Verdict: reproducible and exploitable, or why it is not.
111
+ 2. If real: the smallest fix that closes it without breaking callers,
112
+ and any regression test worth adding.
113
+ 3. Whether the same class of bug exists elsewhere in the tree.
114
+
115
+ Do not apply changes yourself -- propose them; the referee decides what
116
+ ships. Argue with the attacker's reasoning through the referee, with
117
+ evidence, not assertion.
@@ -7,6 +7,15 @@
7
7
  # Shape: hub and spoke. The lead hands out work and assembles the result; the
8
8
  # specialists only ever report back to the lead (and to each other where it
9
9
  # actually helps). Nobody starts working until the lead briefs them.
10
+ #
11
+ # writer
12
+ # |
13
+ # scout -------- lead -------- analyst
14
+ # \ /
15
+ # `---- (compare notes) --'
16
+ #
17
+ # Every link is two-way. The lead is the hub; scout and analyst may also talk
18
+ # to each other directly, but the writer only ever deals with the lead.
10
19
  # =============================================================================
11
20
 
12
21
  swarm:
@@ -8,6 +8,19 @@
8
8
  # The communication graph is deliberately not a free-for-all: developers talk to
9
9
  # their architect and to QA, but not to each other, so design decisions go
10
10
  # through one place instead of being negotiated twice.
11
+ #
12
+ # cto <--> everyone (the hub: architect, backend, frontend, qa, docs)
13
+ #
14
+ # On the dev side the four form a diamond -- every link two-way:
15
+ #
16
+ # architect
17
+ # / \
18
+ # backend frontend
19
+ # \ /
20
+ # qa
21
+ #
22
+ # ...but backend and frontend never talk to each other, and docs talks only
23
+ # to the cto.
11
24
  # =============================================================================
12
25
 
13
26
  swarm:
@@ -149,4 +162,6 @@ agents:
149
162
 
150
163
  Every entry answers: what changed, and what should a user do differently
151
164
  because of it. No marketing language. When you need to know why something
152
- changed, ask the cto.
165
+ changed, ask the cto from your shell (your replies are not auto-captured,
166
+ so a tagged block would not be delivered):
167
+ swarm send --to cto "..."
@@ -0,0 +1,82 @@
1
+ # =============================================================================
2
+ # TDD ping-pong -- two agents grow a feature test-first, one test at a time.
3
+ #
4
+ # 1. Point `workdir` below at the repo you want to build in.
5
+ # 2. agentainer validate -c examples/tdd-pingpong.yaml
6
+ # 3. agentainer up -c examples/tdd-pingpong.yaml
7
+ # 4. agentainer send --to tester "Build a rate limiter: N requests per window."
8
+ #
9
+ # Shape: a tight two-agent loop with a strict protocol. The TESTER writes ONE
10
+ # failing test; the CODER writes the least code to pass it and hands back; the
11
+ # tester writes the next test. Nobody auto-forwards -- each handoff is a
12
+ # deliberate `<swarm-send>`, which keeps the red/green rhythm explicit.
13
+ #
14
+ # tester <--> coder
15
+ #
16
+ # They share ONE checkout on purpose (that is the whole game), so `validate`
17
+ # will warn about the shared workdir -- expected here. The protocol, not a
18
+ # folder boundary, keeps them from colliding: only one holds the ball at a time.
19
+ # =============================================================================
20
+
21
+ swarm:
22
+ name: tddpp
23
+ root: ./tdd-runtime # only holds logs, inboxes and swarm state
24
+ session_prefix: "tdd-"
25
+ create_workdirs: false
26
+
27
+ defaults:
28
+ # Both agents build in the same tree. >>> EDIT ME <<<
29
+ workdir: ~/projects/scratch-lib
30
+
31
+ agents:
32
+
33
+ - name: tester
34
+ type: claude
35
+ command: "claude --dangerously-skip-permissions"
36
+ can_talk_to: ["coder"]
37
+
38
+ # The human hands the feature to the tester, who starts the loop.
39
+ in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
40
+
41
+ first_prompt: |
42
+ You are the TESTER in a TDD ping-pong. You own the RED step.
43
+
44
+ The protocol, one turn at a time:
45
+ 1. Write exactly ONE new failing test that pushes the feature one small
46
+ step forward -- the simplest behaviour not yet implemented.
47
+ 2. Run it. Confirm it fails, and fails for the right reason (not a typo,
48
+ import error, or missing file).
49
+ 3. Hand off to the coder: the test's name, what behaviour it pins down,
50
+ and the failure output you saw. Then stop and wait.
51
+
52
+ Rules:
53
+ - One test per turn. Never write two steps ahead.
54
+ - Test behaviour through the public interface, not private internals.
55
+ - Do NOT write production code -- that is the coder's job. If the design
56
+ the coder chose makes the next test awkward, say so and let them
57
+ refactor on their green turn.
58
+ - When the feature is fully covered and you have no next test, say the
59
+ feature is DONE instead of inventing busywork.
60
+
61
+ - name: coder
62
+ type: codex
63
+ command: "codex --yolo"
64
+ can_talk_to: ["tester"]
65
+
66
+ first_prompt: |
67
+ You are the CODER in a TDD ping-pong. You own the GREEN and REFACTOR steps.
68
+
69
+ When the tester hands you a failing test:
70
+ 1. Write the LEAST code that makes it pass -- honestly the least, even if
71
+ it looks too simple. Do not implement behaviour no test demands yet.
72
+ 2. Run the whole suite. Everything must be green, not just the new test.
73
+ 3. Refactor only now, with tests green: remove duplication, improve names.
74
+ Re-run the suite after refactoring.
75
+ 4. Hand back to the tester: what you did, the passing suite output, and
76
+ anything about the design they should know before the next test.
77
+
78
+ Rules:
79
+ - Do not add tests, and do not edit the tester's tests to make them pass.
80
+ If a test seems wrong, argue for it -- do not quietly change it.
81
+ - Resist gold-plating. YAGNI: the tests define the spec.
82
+ - If a test cannot be made to pass as written, explain why and hand back.
@@ -0,0 +1,129 @@
1
+ # =============================================================================
2
+ # Writers' room -- take a rough idea to a finished, fact-checked article.
3
+ #
4
+ # agentainer up -c examples/writers-room.yaml
5
+ # agentainer send --to editor "Explain how TLS 1.3 speeds up the handshake."
6
+ #
7
+ # Shape: hub with a review cycle. The editor commissions and owns the piece; the
8
+ # writer drafts it; the fact-checker verifies every claim and the critic tears
9
+ # into the prose. Writer, checker and critic all report to the editor, who
10
+ # decides what to revise -- so the draft goes through one owner, not a committee.
11
+ #
12
+ # writer
13
+ # |
14
+ # factchecker --- editor --- critic
15
+ #
16
+ # Every link is two-way, but writer, factchecker and critic each report
17
+ # only to the editor -- never to each other.
18
+ #
19
+ # The article lands in a predictable place (`./writers-room-output/DRAFT.md`),
20
+ # not in a scratch folder, via a custom `workdir` on the writer.
21
+ # =============================================================================
22
+
23
+ swarm:
24
+ name: writersroom
25
+ root: ./writers-room
26
+ session_prefix: "wr-"
27
+
28
+ # Editor -> writer -> editor -> checker/critic. Keep the auto-forward guard low;
29
+ # here nobody auto-forwards anyway, so this is just belt-and-braces.
30
+ max_forward_hops: 2
31
+
32
+ defaults:
33
+ type: claude
34
+
35
+ agents:
36
+
37
+ - name: editor
38
+ type: claude
39
+ command: "claude --dangerously-skip-permissions --model opus"
40
+ can_talk_to: ["writer", "factchecker", "critic"]
41
+
42
+ # Waits for the human to hand over the topic and the audience.
43
+ in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
44
+
45
+ first_prompt: |
46
+ You are the EDITOR. You own the piece from brief to publish.
47
+
48
+ You do not write the prose yourself. You commission it, hold the standard,
49
+ and decide when it is done.
50
+
51
+ Your room:
52
+ - writer: drafts and revises the article
53
+ - factchecker: verifies every factual claim against a source
54
+ - critic: attacks the prose: clarity, structure, honesty
55
+
56
+ How to run it:
57
+ 1. Turn the human's request into a one-paragraph brief: the single idea,
58
+ the reader, the length, and what the piece must NOT become.
59
+ 2. Send the brief to the writer. When a draft comes back, send it to BOTH
60
+ the factchecker and the critic.
61
+ 3. Merge their notes into one revision list, ordered by what matters, and
62
+ send it back to the writer. Drop nitpicks that do not serve the reader.
63
+ 4. Repeat until a checked, clear draft exists. Then deliver the final
64
+ piece to the human and say where it is.
65
+
66
+ Protect the reader's time above the writer's feelings. Cut anything that
67
+ does not earn its place.
68
+
69
+ - name: writer
70
+ type: claude
71
+ command: "claude --dangerously-skip-permissions"
72
+ can_talk_to: ["editor"]
73
+
74
+ # The draft lands somewhere predictable, outside the scratch directories.
75
+ workdir: ./writers-room-output
76
+
77
+ first_prompt: |
78
+ You are the WRITER. You turn the editor's brief into DRAFT.md.
79
+
80
+ Write for the reader in the brief, not for other experts. Lead with the
81
+ single idea, make each paragraph earn the next, and prefer a concrete
82
+ example over an abstraction. No filler, no "in today's fast-paced world",
83
+ no restating the question back at the reader.
84
+
85
+ When you get revision notes from the editor, apply them, and where you
86
+ disagree, make your case briefly rather than silently ignoring the note.
87
+ Mark any claim you are unsure of so the factchecker can find it.
88
+
89
+ Tell the editor where the draft is when a version is ready for review.
90
+
91
+ - name: factchecker
92
+ type: codex
93
+ command: "codex --yolo"
94
+ can_talk_to: ["editor"]
95
+
96
+ first_prompt: |
97
+ You are the FACT-CHECKER. You verify, you do not rewrite.
98
+
99
+ Go through the draft claim by claim. For each factual assertion, decide:
100
+ supported, wrong, or unverifiable -- and show why.
101
+
102
+ Report to the editor:
103
+ - the claim, quoted, with where it appears
104
+ - your verdict, and the source or check behind it
105
+ - for anything wrong, the correct version
106
+
107
+ Where a claim can be tested with code or a quick command, test it and paste
108
+ what you actually observed. Distinguish "I verified this" from "this looks
109
+ plausible but I could not confirm it". Do not touch the prose -- that is the
110
+ writer's job and the critic's beat.
111
+
112
+ - name: critic
113
+ type: claude
114
+ command: "claude --dangerously-skip-permissions"
115
+ can_talk_to: ["editor"]
116
+
117
+ first_prompt: |
118
+ You are the CRITIC. You attack the writing so the reader does not have to.
119
+
120
+ Read the draft as a smart, busy reader who will bail the moment they are
121
+ bored or confused. Report to the editor:
122
+ - where you lost the thread, and why
123
+ - claims that sound impressive but say nothing
124
+ - structure that buries the point, or an opening that does not earn attention
125
+ - a stronger cut: what to remove so the rest lands harder
126
+
127
+ Be specific -- quote the sentence and propose the fix. Praise only what is
128
+ genuinely working, and briefly. Your job is the next draft, not the writer's
129
+ morale.
package/lib/minyaml.py CHANGED
@@ -37,6 +37,13 @@ _KEY_RE = re.compile(
37
37
 
38
38
  _BLOCK_RE = re.compile(r"^([|>])([+-]?)(\d*)$")
39
39
 
40
+ # Only plain base-10 numbers are coerced. Leaving leading-zero ("010"), hex/octal
41
+ # ("0x1F"), bare-exponent ("1e3") and underscore ("1_000") tokens as strings keeps
42
+ # the builtin parser from silently inventing a value that PyYAML would not -- the
43
+ # ambiguous octal/exponent cases are exactly where the two would otherwise disagree.
44
+ _INT_RE = re.compile(r"^[-+]?(?:0|[1-9][0-9]*)$")
45
+ _FLOAT_RE = re.compile(r"^[-+]?(?:[0-9]*\.[0-9]+|[0-9]+\.[0-9]*)(?:[eE][-+][0-9]+)?$")
46
+
40
47
  _UNSUPPORTED = ("&", "*", "!!", "---", "...")
41
48
 
42
49
 
@@ -206,14 +213,10 @@ def _scalar(raw: str):
206
213
  return True
207
214
  if low in ("false", "no", "off"):
208
215
  return False
209
- try:
210
- return int(s, 10)
211
- except ValueError:
212
- pass
213
- try:
216
+ if _INT_RE.match(s):
217
+ return int(s)
218
+ if _FLOAT_RE.match(s):
214
219
  return float(s)
215
- except ValueError:
216
- pass
217
220
  return s
218
221
 
219
222
 
package/lib/swarm.py CHANGED
@@ -2117,7 +2117,17 @@ def cmd_validate(args) -> int:
2117
2117
 
2118
2118
  def cmd_watch(args) -> int:
2119
2119
  cfg = cfgmod.load(args.config)
2120
- run_watcher(cfg, cfg.get(args.agent))
2120
+ agent = cfg.get(args.agent)
2121
+ if agent.capture != "pane":
2122
+ die(
2123
+ f"{agent.name}: capture={agent.capture}, nothing to watch. The pane "
2124
+ f"watcher is only for pane-capture agents (gemini/hermes); "
2125
+ f"{agent.type} agents detect turn completion via "
2126
+ f"{'a Stop hook' if agent.capture == 'hook' else 'no capture at all'}."
2127
+ )
2128
+ if not session_exists(agent.session):
2129
+ die(f"{agent.name}: session {agent.session!r} is not running (start it with `up`).")
2130
+ run_watcher(cfg, agent)
2121
2131
  return 0
2122
2132
 
2123
2133
 
package/llms.txt CHANGED
@@ -275,6 +275,32 @@ stops at `max_forward_hops`. A message you send with `swarm send` resets it to z
275
275
  reproduce → diagnose → fix → verify.
276
276
  - `examples/existing-repo.yaml` — two agents pairing inside one existing checkout,
277
277
  using `create_workdirs: false` so a wrong path fails instead of being created.
278
+ - `examples/red-team.yaml` — adversarial triad: an attacker and defender argue
279
+ through a referee over one existing checkout.
280
+ - `examples/debate.yaml` — two advocates argue opposite sides; a judge
281
+ cross-examines and rules.
282
+ - `examples/writers-room.yaml` — an editor drives a writer, fact-checker and
283
+ critic to a finished article.
284
+ - `examples/incident-response.yaml` — a commander coordinates an investigator,
285
+ responder and scribe under time pressure (hub and spoke).
286
+ - `examples/tdd-pingpong.yaml` — a tester and coder grow a feature test-first,
287
+ one test at a time, via `forward_responses_to`.
288
+ - `examples/brainstorm.yaml` — three idea-generators fan out from a facilitator,
289
+ then a synthesiser ranks them.
290
+ - `examples/localization.yaml` — translate → review → back-check, auto-forwarded
291
+ via `forward_responses_to`; a `NEEDS ANOTHER PASS` verdict loops back to
292
+ the translator with a `<swarm-send>` block.
293
+ - `examples/multi-language-broadcast.yaml` — one translator broadcasts a source to
294
+ N language reviewers; a consolidator compiles and broadcasts back. Built on
295
+ `broadcast`.
296
+ - `examples/code-review-broadcast.yaml` — a coordinator broadcasts a PR to
297
+ specialist reviewers (correctness/security/perf); each replies to the
298
+ coordinator, who synthesizes. Built on `broadcast`.
299
+ - `examples/ping-pong.yaml` — two agents trade a unit of work, each broadcast
300
+ naming who is up next (round-robin via `broadcast`, distinct from
301
+ tdd-pingpong's fixed `forward_responses_to`).
302
+ - `agents.example.yaml` — the fully annotated reference config; every key is
303
+ documented inline.
278
304
 
279
305
  ## Recipes
280
306
 
package/package.json CHANGED
@@ -1,17 +1,24 @@
1
1
  {
2
2
  "name": "agentainer",
3
- "version": "0.1.3",
4
- "description": "Run a configurable swarm of coding-agent CLIs (Claude Code, Codex, Gemini) in tmux and let them talk to each other.",
3
+ "version": "0.1.4",
4
+ "description": "Zero-dependency multi-agent orchestrator: run a team of AI coding agents (Claude Code, Codex, Gemini, Hermes) side by side in tmux with a YAML-defined ACL.",
5
5
  "keywords": [
6
6
  "agents",
7
+ "ai-agents",
7
8
  "ai",
9
+ "llm",
10
+ "agentic",
11
+ "claude-code",
8
12
  "claude",
9
13
  "codex",
10
14
  "gemini",
15
+ "hermes",
11
16
  "tmux",
12
17
  "orchestration",
13
18
  "multi-agent",
14
- "swarm"
19
+ "swarm",
20
+ "prompt-routing",
21
+ "python"
15
22
  ],
16
23
  "homepage": "https://github.com/mehmetcanfarsak/AgentSwarm#readme",
17
24
  "bugs": {