agentainer 0.1.7 → 2.0.1

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.
Files changed (98) hide show
  1. package/README.md +248 -677
  2. package/agentainer +16 -18
  3. package/agentainer.example.yaml +86 -0
  4. package/bin/agentainer.js +9 -8
  5. package/examples/academic-coauthor.yaml +123 -0
  6. package/examples/accessibility-audit.yaml +152 -0
  7. package/examples/affiliate-product-reviews.yaml +106 -0
  8. package/examples/api-design.yaml +157 -0
  9. package/examples/app-store-optimization.yaml +108 -0
  10. package/examples/brainstorm.yaml +27 -128
  11. package/examples/brand-voice-style-guide.yaml +109 -0
  12. package/examples/bug-hunt.yaml +51 -96
  13. package/examples/candidate-screen.yaml +122 -0
  14. package/examples/case-study-writer.yaml +100 -0
  15. package/examples/changelog-release-notes.yaml +114 -0
  16. package/examples/chatbot-builder.yaml +138 -0
  17. package/examples/code-review.yaml +73 -0
  18. package/examples/comparison-guide-writer.yaml +106 -0
  19. package/examples/competitive-intel.yaml +126 -0
  20. package/examples/content-studio.yaml +91 -0
  21. package/examples/course-creator.yaml +133 -0
  22. package/examples/customer-support-triage.yaml +118 -0
  23. package/examples/daily-briefing.yaml +119 -0
  24. package/examples/data-pipeline-builder.yaml +135 -0
  25. package/examples/debate.yaml +16 -90
  26. package/examples/design-system.yaml +138 -0
  27. package/examples/ebook-generator.yaml +90 -0
  28. package/examples/ecommerce-listing-optimizer.yaml +126 -0
  29. package/examples/email-newsletter.yaml +103 -0
  30. package/examples/faq-knowledge-sync.yaml +107 -0
  31. package/examples/game-design.yaml +122 -0
  32. package/examples/glossary-term-writer.yaml +103 -0
  33. package/examples/incident-response.yaml +52 -109
  34. package/examples/knowledge-base.yaml +115 -0
  35. package/examples/landing-page-converter.yaml +103 -0
  36. package/examples/legal-contract-review.yaml +118 -0
  37. package/examples/linkedin-ghostwriter.yaml +93 -0
  38. package/examples/localization.yaml +56 -123
  39. package/examples/meeting-notes.yaml +111 -0
  40. package/examples/migration-planner.yaml +127 -0
  41. package/examples/onboarding-buddy.yaml +111 -0
  42. package/examples/performance-audit.yaml +123 -0
  43. package/examples/podcast-production.yaml +117 -0
  44. package/examples/postmortem.yaml +119 -0
  45. package/examples/pr-review-gate.yaml +123 -0
  46. package/examples/press-release-wire.yaml +96 -0
  47. package/examples/product-spec.yaml +107 -0
  48. package/examples/prompt-engineering-lab.yaml +109 -0
  49. package/examples/quickstart.yaml +48 -0
  50. package/examples/rag-builder.yaml +145 -0
  51. package/examples/refactor-planner.yaml +127 -0
  52. package/examples/research.yaml +25 -0
  53. package/examples/resume-tailor.yaml +116 -0
  54. package/examples/rfp-response.yaml +124 -0
  55. package/examples/sales-coach.yaml +123 -0
  56. package/examples/security-audit.yaml +120 -0
  57. package/examples/seo-audit-and-fix.yaml +138 -0
  58. package/examples/seo-content-factory.yaml +103 -0
  59. package/examples/social-media.yaml +103 -0
  60. package/examples/software-company.yaml +71 -128
  61. package/examples/startup-validator.yaml +115 -0
  62. package/examples/tdd-pingpong.yaml +36 -68
  63. package/examples/technical-documentation.yaml +112 -0
  64. package/examples/test-factory.yaml +114 -0
  65. package/examples/tutorial-howto-creator.yaml +111 -0
  66. package/examples/twitter-x-thread-factory.yaml +91 -0
  67. package/examples/white-paper-research.yaml +96 -0
  68. package/examples/writers-room.yaml +49 -111
  69. package/examples/youtube-script-studio.yaml +107 -0
  70. package/hooks/claude_stop.sh +5 -3
  71. package/hooks/codex_notify.sh +4 -3
  72. package/lib/cli.py +933 -0
  73. package/lib/config.py +267 -308
  74. package/lib/hooks.py +246 -0
  75. package/lib/lock.py +75 -0
  76. package/lib/log.py +64 -0
  77. package/lib/mail.py +699 -0
  78. package/lib/minyaml.py +1 -39
  79. package/lib/reconcile.py +544 -0
  80. package/lib/sessions.py +223 -0
  81. package/lib/supervisor.py +216 -0
  82. package/lib/telegram.py +372 -0
  83. package/lib/tmux.py +355 -0
  84. package/lib/turn.py +167 -0
  85. package/lib/ui.py +1219 -0
  86. package/llms.txt +145 -429
  87. package/package.json +9 -7
  88. package/scripts/check-deps.js +18 -61
  89. package/ui/app.js +1136 -0
  90. package/ui/index.html +404 -0
  91. package/agents.example.yaml +0 -257
  92. package/examples/code-review-broadcast.yaml +0 -109
  93. package/examples/existing-repo.yaml +0 -74
  94. package/examples/multi-language-broadcast.yaml +0 -127
  95. package/examples/ping-pong.yaml +0 -89
  96. package/examples/red-team.yaml +0 -117
  97. package/examples/research-swarm.yaml +0 -129
  98. package/lib/swarm.py +0 -2461
package/agentainer CHANGED
@@ -1,22 +1,23 @@
1
1
  #!/usr/bin/env bash
2
2
  #
3
- # Agentainer -- launch a configurable swarm of coding agents in tmux.
3
+ # Agentainer -- launch a configurable team of coding agents in tmux.
4
4
  #
5
- # ./agentainer up start every agent in agents.yaml
6
- # ./agentainer up -c my-swarm.yaml ...from a different config
7
- # ./agentainer agents.yaml shorthand for `up -c agents.yaml`
8
- # ./agentainer status see who is running
9
- # ./agentainer send --to dev "hi" message an agent
10
- # ./agentainer attach dev jump into an agent's tmux session
11
- # ./agentainer down stop everything
5
+ # ./agentainer up start every agent in agentainer.yaml
6
+ # ./agentainer up -c my-swarm.yaml ...from a different config
7
+ # ./agentainer my-swarm.yaml shorthand for `up -c my-swarm.yaml`
8
+ # ./agentainer validate print the resolved config, launch nothing
9
+ # ./agentainer status see who is running
10
+ # ./agentainer send --to dev "hi" mail an agent
11
+ # ./agentainer attach dev jump into an agent's tmux session
12
+ # ./agentainer down stop everything
12
13
  #
13
14
  # See README.md for the full reference, or llms.txt if you are an LLM.
14
15
  set -euo pipefail
15
16
 
16
- SWARM_HOME="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17
- export SWARM_HOME
17
+ AGENTAINER_HOME="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
18
+ export AGENTAINER_HOME
18
19
 
19
- PYTHON="${SWARM_PYTHON:-}"
20
+ PYTHON="${AGENTAINER_PYTHON:-}"
20
21
  if [[ -z "$PYTHON" ]]; then
21
22
  for candidate in python3 python; do
22
23
  if command -v "$candidate" >/dev/null 2>&1; then
@@ -27,7 +28,7 @@ if [[ -z "$PYTHON" ]]; then
27
28
  fi
28
29
 
29
30
  if [[ -z "$PYTHON" ]]; then
30
- echo "xx Agentainer needs python3 on PATH (or set SWARM_PYTHON)" >&2
31
+ echo "xx Agentainer needs python3 on PATH (or set AGENTAINER_PYTHON)" >&2
31
32
  exit 1
32
33
  fi
33
34
 
@@ -35,9 +36,6 @@ if ! command -v tmux >/dev/null 2>&1; then
35
36
  echo "!! tmux was not found on PATH; every command except 'validate' will fail" >&2
36
37
  fi
37
38
 
38
- # The config is resolved in lib/swarm.py: -c, then $SWARM_CONFIG, then
39
- # ./agents.yaml, then the agents.yaml next to this script. Deliberately NOT
40
- # exported here -- a stale SWARM_CONFIG would shadow the config that a hook
41
- # discovers from the agent's working directory.
42
-
43
- exec "$PYTHON" "$SWARM_HOME/lib/swarm.py" "$@"
39
+ # The config is resolved in lib/cli.py: -c, then $AGENTAINER_CONFIG, then
40
+ # ./agentainer.yaml, then the agentainer.yaml next to this script.
41
+ exec "$PYTHON" "$AGENTAINER_HOME/lib/cli.py" "$@"
@@ -0,0 +1,86 @@
1
+ # =============================================================================
2
+ # agentainer.example.yaml — reference configuration for Agentainer v2.
3
+ #
4
+ # Copy it to start your own swarm:
5
+ #
6
+ # cp agentainer.example.yaml my-swarm.yaml
7
+ # agentainer up -c my-swarm.yaml
8
+ # agentainer status -c my-swarm.yaml
9
+ # agentainer send -c my-swarm.yaml --to orchestrator "Build a CSV->Parquet CLI."
10
+ # agentainer down -c my-swarm.yaml
11
+ #
12
+ # This file is FULLY COMMENTED and KEY-FREE: every `command:` runs a tiny
13
+ # `bash` loop instead of a real agent CLI, so the swarm comes up and routes
14
+ # mail with NO API keys and NO model calls. To run real agents, swap each
15
+ # `command` for the actual CLI you installed and drop `capture: none` so turns
16
+ # get detected.
17
+ #
18
+ # The v2 model: agents RECEIVE by reading a file (inbox/) and SEND by writing a
19
+ # file (outbox/<name>/). The orchestrator owns routing, ACL, message IDs,
20
+ # read-state, queueing, retries, and the durable log.
21
+ # =============================================================================
22
+
23
+ swarm:
24
+ name: my-swarm # any label; shown in `status` / logs
25
+ root: ./my-swarm-workspace # disposable working dir; agents get <root>/<name>/ subdirs
26
+ supervise: true # run the liveness supervisor (heartbeat) at up
27
+ supervise_interval_ms: 15000 # how often the supervisor reconciles agents
28
+ ready_timeout_ms: 30000 # give up waiting for an agent's input prompt after this
29
+ busy_timeout_ms: 120000 # mark a silent agent idle after this long
30
+ user_available: false # the human mailbox starts away (set `agentainer user available`)
31
+
32
+ # Optional Telegram bridge (off by default). When enabled, the orchestrator
33
+ # mirrors mail to a Telegram chat over HTTPS (stdlib only, no dependency), and a
34
+ # Telegram reply to a mirrored message routes back into the swarm as `user` mail.
35
+ # Create a bot with @BotFather for the token; get your chat id from @userinfobot.
36
+ # It is easiest to set all of this from the UI (`agentainer serve` -> Settings).
37
+ # telegram:
38
+ # enabled: true
39
+ # bot_token: "123456:ABC-DEF..." # keep this secret; it is a credential
40
+ # chat_id: "123456789" # the chat/user id to send to & accept replies from
41
+ # mirror: "*" # "*"/all, or a list of agent names to mirror
42
+ # mirror_user: true # also mirror mail addressed to you (default true)
43
+ # mirror_system: false # mirror system pings/bounces too (default false)
44
+
45
+ defaults:
46
+ # capture: how the orchestrator knows a turn finished.
47
+ # hook -> per-type hook/notify (claude Stop hook, codex `notify`) [default for those types]
48
+ # pane -> poll the tmux pane (gemini / hermes, or any CLI without a hook)
49
+ # none -> no turn detection (mock agents; the agent never "finishes")
50
+ # `capture: none` is auto-upgraded to `hook` on hook-backed types at load time.
51
+ capture: none
52
+ can_talk_to: [] # tightened per agent below
53
+
54
+ agents:
55
+ # The orchestrator fans work out to the workers. It may also talk to the human.
56
+ - name: orchestrator
57
+ type: claude
58
+ can_talk_to: [developer, reviewer, user] # may also talk to the human mailbox
59
+ # Real agent: command: "claude --dangerously-skip-permissions"
60
+ command: "claude --dangerously-skip-permissions"
61
+ role: "You are the orchestrator. Wait for the user's task, then delegate to workers."
62
+
63
+ # A worker that can only reply to the orchestrator (enforced by the ACL).
64
+ - name: developer
65
+ type: codex
66
+ can_talk_to: [orchestrator]
67
+ # Real agent: command: "codex"
68
+ command: "codex --yolo"
69
+ role: "You are a developer. Implement what the orchestrator asks."
70
+
71
+ # A reviewer that checks the developer's work.
72
+ - name: reviewer
73
+ type: claude
74
+ can_talk_to: [developer]
75
+ # Real agent: command: "claude"
76
+ command: "claude --dangerously-skip-permissions"
77
+ role: "You are a reviewer. Read the developer's output and critique it."
78
+
79
+ # An optional idle pinger: every N seconds, if idle, the orchestrator drops a
80
+ # `system` nudge into this agent's queue (idle-only, no pile-up, min-cadence).
81
+ # - name: researcher
82
+ # type: gemini
83
+ # can_talk_to: [orchestrator]
84
+ # command: "bash -c 'while true; do read -r l || sleep 1; done'"
85
+ # periodically_ping_seconds: 600
86
+ # periodically_ping_message: "Any progress to report? Reply, or stay quiet."
package/bin/agentainer.js CHANGED
@@ -4,14 +4,15 @@
4
4
  // npm symlinks this file into a bin directory (e.g. /usr/local/bin/agentainer).
5
5
  // Node resolves that symlink before setting __dirname, so __dirname always
6
6
  // points at the real bin/ inside the installed package -- which makes the
7
- // package root, and therefore SWARM_HOME, reliable no matter where npm puts us.
7
+ // package root, and therefore AGENTAINER_HOME, reliable no matter where npm
8
+ // puts us.
8
9
  "use strict";
9
10
 
10
11
  const path = require("path");
11
12
  const { spawnSync } = require("child_process");
12
13
 
13
14
  const PKG_ROOT = path.resolve(__dirname, "..");
14
- const ENTRY = path.join(PKG_ROOT, "lib", "swarm.py");
15
+ const ENTRY = path.join(PKG_ROOT, "lib", "cli.py");
15
16
 
16
17
  // `agentainer doctor` re-runs the dependency check without touching Python.
17
18
  if (process.argv[2] === "doctor") {
@@ -21,11 +22,11 @@ if (process.argv[2] === "doctor") {
21
22
  process.exit(r.status === null ? 1 : r.status);
22
23
  }
23
24
 
24
- // Locate a Python interpreter, mirroring ./agentainer (SWARM_PYTHON, then python3,
25
- // then python).
25
+ // Locate a Python interpreter, mirroring ./agentainer (AGENTAINER_PYTHON, then
26
+ // python3, then python).
26
27
  function findPython() {
27
- const candidates = process.env.SWARM_PYTHON
28
- ? [process.env.SWARM_PYTHON]
28
+ const candidates = process.env.AGENTAINER_PYTHON
29
+ ? [process.env.AGENTAINER_PYTHON]
29
30
  : ["python3", "python"];
30
31
  for (const cand of candidates) {
31
32
  const probe = spawnSync(cand, ["--version"], { stdio: "ignore" });
@@ -42,7 +43,7 @@ function has(cmd, args) {
42
43
  const python = findPython();
43
44
  if (!python) {
44
45
  process.stderr.write(
45
- "xx Agentainer needs python3 on PATH (or set SWARM_PYTHON).\n" +
46
+ "xx Agentainer needs python3 on PATH (or set AGENTAINER_PYTHON).\n" +
46
47
  " Run `agentainer doctor` for install hints.\n"
47
48
  );
48
49
  process.exit(1);
@@ -59,7 +60,7 @@ if (!has("tmux", ["-V"])) {
59
60
 
60
61
  const result = spawnSync(python, [ENTRY, ...process.argv.slice(2)], {
61
62
  stdio: "inherit",
62
- env: { ...process.env, SWARM_HOME: PKG_ROOT },
63
+ env: { ...process.env, AGENTAINER_HOME: PKG_ROOT },
63
64
  });
64
65
 
65
66
  if (result.error) {
@@ -0,0 +1,123 @@
1
+ # =============================================================================
2
+ # 🎓 Academic paper co-writing swarm -- a literature hub surveys prior work and
3
+ # drives a structured pipeline: methodology review, section drafting, and a
4
+ # final citation/claim check that reports back to the human.
5
+ #
6
+ # cp examples/academic-coauthor.yaml my-paper.yaml
7
+ # agentainer up -c my-paper.yaml
8
+ # agentainer send -c my-paper.yaml --to literature "Draft a survey on retrieval-augmented generation for code."
9
+ # agentainer down -c my-paper.yaml
10
+ #
11
+ # `literature` is the hub. It takes the research question from the human, surveys
12
+ # prior work, and briefs the methodologist and writer. The methodologist and
13
+ # writer talk ONLY to literature -- never to each other -- so every hand-off is
14
+ # sequenced and reconciled in one place. The citation checker verifies the draft
15
+ # and reports its verdict straight to the human.
16
+ #
17
+ # research question
18
+ # user ───────────────────▶ literature ◀──┬──▶ methodologist (rigor/validity)
19
+ # (verdict) ◀── hub └──▶ writer (drafts sections)
20
+ # ◀─────────────── citation ◀────────── (checks claims + references)
21
+ #
22
+ # ...methodologist/writer never talk to each other; literature and citation are
23
+ # the only agents that talk to user.
24
+ #
25
+ # NOTE: this is a decision-support tool, not an author. The humans on the paper
26
+ # own authorship, scientific integrity, and every claim that ships. Treat all
27
+ # agent output as a draft to verify -- especially citations, which LLMs
28
+ # fabricate. The `citation` agent narrows the risk; it does not remove it.
29
+ #
30
+ # Key-free: swap each `command` for a mock bash loop (e.g.
31
+ # `bash -c 'while true; do read x; done'`) and the swarm comes up and routes
32
+ # mail with NO API keys. Swap them back for real CLIs to run real agents.
33
+ # =============================================================================
34
+
35
+ swarm:
36
+ name: academic-coauthor
37
+ root: ./academic-coauthor-workspace
38
+
39
+ defaults:
40
+ capture: none # mock agents don't fire a turn-completion hook
41
+ can_talk_to: [] # tightened per agent below
42
+
43
+ agents:
44
+ - name: literature
45
+ type: claude
46
+ can_talk_to: [methodologist, writer, citation, user]
47
+ command: "claude --dangerously-skip-permissions"
48
+ role: |
49
+ You are the LITERATURE LEAD and the hub of this paper. You take a research
50
+ question from the human, survey the prior work, and turn it into a paper
51
+ the team can build. You do not judge methodology yourself, draft prose, or
52
+ verify citations -- you direct and you decide. You are the point of contact
53
+ for the user and the only one who declares the paper ready.
54
+ Your team: methodologist (checks rigor and threats to validity), writer
55
+ (drafts the paper section by section), citation (verifies every claim is
56
+ supported and every reference is well-formed).
57
+ Run it like this: (1) restate the question as a scope note -- the gap in
58
+ the literature, the contribution, and a section outline (abstract,
59
+ intro/related work, methods, results, discussion) -- and survey the key
60
+ prior work into RELATED-WORK.md; (2) send the proposed approach to the
61
+ methodologist and hold drafting until validity threats are addressed;
62
+ (3) hand the outline, survey, and settled method to the writer, one section
63
+ at a time; (4) when a section is drafted, send it to citation for a claim
64
+ and reference check; (5) reconcile the feedback, request fixes, and only
65
+ then tell the user the paper is ready. Cut scope before you ship a claim
66
+ you cannot support.
67
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
68
+ move it to read/. To send, write a file into outbox/<name>/ (read
69
+ outbox/<name>/about.md first to see who they are and whether they're
70
+ available). Finish your turn after writing. You may only message the agents
71
+ in your can_talk_to.
72
+
73
+ - name: methodologist
74
+ type: claude
75
+ can_talk_to: [literature]
76
+ command: "claude --dangerously-skip-permissions"
77
+ role: |
78
+ You are the METHODOLOGIST. Given the literature lead's proposed approach,
79
+ check whether it can actually support the paper's claims. Assess construct,
80
+ internal, and external validity; name the threats to validity explicitly
81
+ and say how each could be mitigated or must be acknowledged as a
82
+ limitation. Check that the evaluation, baselines, sample, and statistics
83
+ fit the research question -- an approach that cannot answer the question is
84
+ a defect, not a detail. Do not draft the paper; return a concise rigor memo
85
+ (what is sound, what is at risk, what must change) to the literature lead.
86
+ If the proposal is too vague to assess, ask before you sign off.
87
+
88
+ - name: writer
89
+ type: claude
90
+ can_talk_to: [literature]
91
+ command: "claude --dangerously-skip-permissions"
92
+ role: |
93
+ You are the WRITER. Draft the paper section by section from the literature
94
+ lead's outline, survey, and the settled methodology, in your own working
95
+ directory (write to DRAFT.md). Write in a precise academic register: state
96
+ the contribution plainly, keep claims proportional to the evidence, and
97
+ only assert what the provided material supports -- if you need a fact,
98
+ figure, or citation the brief does not give you, ask the literature lead
99
+ rather than inventing it. Never fabricate a reference or a result. Mark any
100
+ spot that needs a citation with a clear [CITE: ...] placeholder for the
101
+ citation checker. Return each drafted section to the literature lead for
102
+ review before moving on.
103
+
104
+ - name: citation
105
+ type: claude
106
+ can_talk_to: [literature, user]
107
+ command: "claude --dangerously-skip-permissions"
108
+ role: |
109
+ You are the CITATION AND CLAIMS CHECKER, the paper's last line of defense.
110
+ Take the drafted sections and verify two things: every factual or numeric
111
+ claim is actually supported by a cited source, and every reference is
112
+ real and well-formed (authors, title, venue, year; DOI/URL where possible).
113
+ Flag unsupported claims, overstatements beyond what a source shows, missing
114
+ citations at [CITE: ...] markers, and any reference you cannot confirm
115
+ exists -- fabricated or hallucinated citations are the top-priority find.
116
+ Produce a checklist verdict: claim -> supported / unsupported / needs
117
+ source, and reference -> verified / malformed / unverifiable. Report the
118
+ verdict to the literature lead for fixes, and send the human a plain-English
119
+ summary of what you could and could not confirm so a person makes the final
120
+ integrity call. You do not draft prose or invent sources.
121
+ MAILBOX: read your inbox/, act, then move the message to read/. To send,
122
+ write a file into outbox/<name>/ (check outbox/<name>/about.md first).
123
+ Finish your turn after writing. You may only message literature and user.
@@ -0,0 +1,152 @@
1
+ # =============================================================================
2
+ # Accessibility (WCAG) audit -- a lead orchestrates a web accessibility review of
3
+ # a live URL or a front-end repo against WCAG 2.2 AA, split across the three
4
+ # human-facing POUR principles, then a reporter writes the conformance report.
5
+ #
6
+ # cp examples/accessibility-audit.yaml my-a11y.yaml
7
+ # agentainer up -c my-a11y.yaml
8
+ # agentainer send -c my-a11y.yaml --to lead "Audit https://example.com/checkout (React SPA; repo at ./web)."
9
+ # agentainer down -c my-a11y.yaml
10
+ #
11
+ # This is DISTINCT from examples/security-audit.yaml: that hunts vulnerabilities
12
+ # (OWASP / STRIDE); this checks WCAG 2.2 AA / ADA conformance -- alt text,
13
+ # contrast, keyboard operability, focus order, form labels, error handling.
14
+ #
15
+ # Shape: LEAD is the hub. perceivable / operable / understandable each own ONE
16
+ # WCAG principle and never talk to each other (they'd double-report the same
17
+ # component); they report only to LEAD, who sequences the audit and hands the
18
+ # consolidated findings to reporter. Only LEAD and REPORTER may reach the human.
19
+ #
20
+ # perceivable ────┐
21
+ # operable ───────┼──▶ lead ──▶ reporter ──▶ user
22
+ # understandable ─┘ ▲ │
23
+ # └────────────┘ (reporter can ask lead to clarify)
24
+ #
25
+ # Real agents: commands launch the actual CLIs (claude / codex / gemini / hermes).
26
+ # For a key-free demo, swap each `command` for a mock bash loop -- the routing is
27
+ # identical and `agentainer validate` proves it without launching anything.
28
+ # =============================================================================
29
+
30
+ swarm:
31
+ name: accessibility-audit
32
+ root: ./accessibility-audit-workspace
33
+
34
+ defaults:
35
+ capture: none # mock agents don't fire a turn-completion hook
36
+ can_talk_to: [] # tightened per agent below
37
+
38
+ agents:
39
+ - name: lead
40
+ type: claude
41
+ can_talk_to: [perceivable, operable, understandable, reporter, user]
42
+ command: "claude --dangerously-skip-permissions"
43
+ role: |
44
+ You are the LEAD ACCESSIBILITY AUDITOR. A human sends you a target -- a live
45
+ URL and/or a front-end repo path -- plus a one-line description (framework,
46
+ key user flows). You run the whole WCAG 2.2 AA audit and are the only agent
47
+ that talks to the human. You do NOT do the analysis yourself -- you scope it,
48
+ sequence it, and synthesize the results.
49
+ Your team, one per WCAG POUR principle:
50
+ - perceivable (Principle 1: text alternatives, captions, adaptable
51
+ structure, color contrast, resize/reflow)
52
+ - operable (Principle 2: keyboard access, focus order & visibility,
53
+ skip links, target size, no keyboard traps, no seizures)
54
+ - understandable (Principle 3: language, predictable behavior, form labels,
55
+ error identification and suggestion)
56
+ Run it: (1) briefly acknowledge the target to the human and state the
57
+ conformance bar (WCAG 2.2 Level AA unless they say otherwise); (2) send the
58
+ URL + repo path + the specific pages/flows to audit to ALL THREE principle
59
+ auditors, telling each to stay strictly in its lane; (3) collect all three
60
+ reports (they arrive as separate messages in your inbox/); (4) forward the
61
+ consolidated perceivable + operable + understandable findings to reporter and
62
+ ask for the final conformance report; (5) forward reporter's report to the
63
+ user. De-duplicate overlaps, flag conflicting verdicts, and never let two
64
+ auditors claim the same component.
65
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
66
+ move it to read/. To send, write a file into outbox/<name>/ (read
67
+ outbox/<name>/about.md first) and finish your turn. You may message the
68
+ agents in your can_talk_to.
69
+
70
+ - name: perceivable
71
+ type: claude
72
+ can_talk_to: [lead]
73
+ command: "claude --dangerously-skip-permissions"
74
+ role: |
75
+ You are the PERCEIVABLE auditor -- WCAG Principle 1 only. Given the URL and/or
76
+ repo path, check that information and UI components are presentable in ways
77
+ users can perceive. Cover: 1.1.1 non-text content (meaningful alt text on
78
+ images; empty alt on decorative; labels on icon buttons); 1.2 captions and
79
+ alternatives for audio/video; 1.3.1 info & relationships (semantic HTML --
80
+ real headings h1..hN in order, list/table markup, landmark regions, labels
81
+ programmatically tied to inputs); 1.3.4 orientation and 1.3.5 input purpose;
82
+ 1.4.3 contrast (>=4.5:1 body text, >=3:1 large text and UI components/graphics
83
+ per 1.4.11); 1.4.4 resize text to 200%; 1.4.10 reflow at 320px; 1.4.12 text
84
+ spacing. Read the actual markup/CSS/components; do not guess. For each finding:
85
+ the WCAG success criterion (e.g. "1.4.3 Contrast (Minimum)"), severity
86
+ (critical/serious/moderate/minor), the element and file:line or selector, the
87
+ failing value (e.g. measured ratio 2.8:1), and a one-line fix. Do NOT audit
88
+ keyboard or forms -- that is operable's and understandable's lane. Write your
89
+ findings back to outbox/lead/ as a structured list.
90
+
91
+ - name: operable
92
+ type: claude
93
+ can_talk_to: [lead]
94
+ command: "claude --dangerously-skip-permissions"
95
+ role: |
96
+ You are the OPERABLE auditor -- WCAG Principle 2 only. Given the URL and/or
97
+ repo path, check that all UI components and navigation are operable. Cover:
98
+ 2.1.1 keyboard (every control reachable and usable by keyboard alone) and
99
+ 2.1.2 no keyboard trap; 2.2 timing (adjustable time limits, pause/stop for
100
+ moving content); 2.3.1 three-flashes/seizure safety; 2.4.1 bypass blocks
101
+ (skip-to-content link); 2.4.2 page titled; 2.4.3 focus order matches meaning;
102
+ 2.4.4 link purpose in context; 2.4.7 focus visible; 2.4.11 focus not obscured;
103
+ 2.5.3 label in name; 2.5.7 dragging alternatives; 2.5.8 target size (>=24x24
104
+ CSS px). Actually tab through the flows and inspect focus management (modals,
105
+ menus, custom widgets, ARIA roles/states). For each finding: the WCAG success
106
+ criterion, severity, the element and file:line or selector, what breaks under
107
+ keyboard-only use, and a one-line fix. Do NOT audit contrast/alt text or form
108
+ error copy -- those are the other two auditors' lanes. Write your findings
109
+ back to outbox/lead/.
110
+
111
+ - name: understandable
112
+ type: claude
113
+ can_talk_to: [lead]
114
+ command: "claude --dangerously-skip-permissions"
115
+ role: |
116
+ You are the UNDERSTANDABLE auditor -- WCAG Principle 3 only. Given the URL
117
+ and/or repo path, check that information and operation of the UI are
118
+ understandable. Cover: 3.1.1 language of page (lang attribute) and 3.1.2
119
+ language of parts; 3.2.1 on focus / 3.2.2 on input (no surprise context
120
+ changes); 3.2.3 consistent navigation and 3.2.4 consistent identification;
121
+ 3.2.6 consistent help; 3.3.1 error identification (errors named in text, not
122
+ color alone); 3.3.2 labels or instructions on every input; 3.3.3 error
123
+ suggestion; 3.3.4/3.3.6 error prevention for legal/financial/data submissions;
124
+ 3.3.7 redundant entry; 3.3.8 accessible authentication. Focus on forms, auth,
125
+ and multi-step flows. For each finding: the WCAG success criterion, severity,
126
+ the element and file:line or selector, why a user would be confused or blocked,
127
+ and a one-line fix. Do NOT audit contrast or keyboard operability -- those are
128
+ the other two lanes. Write your findings back to outbox/lead/.
129
+
130
+ - name: reporter
131
+ type: claude
132
+ can_talk_to: [lead, user]
133
+ command: "claude --dangerously-skip-permissions"
134
+ role: |
135
+ You are the REPORT AUTHOR. Given the consolidated perceivable, operable, and
136
+ understandable findings from the lead, write the FINAL WCAG 2.2 AA
137
+ accessibility conformance report for a human reader (a front-end lead or an
138
+ accessibility specialist preparing a VPAT/ADA posture).
139
+ Structure it: Executive summary (overall conformance verdict + the top 3
140
+ blockers for disabled users); a findings table (WCAG success criterion, level
141
+ A/AA, severity, element, file:line or selector, remediation); a
142
+ per-principle rollup (Perceivable / Operable / Understandable: pass, or count
143
+ of failures); and a prioritized remediation roadmap (fix criticals first,
144
+ grouped so one code change closes several findings). Map every finding to its
145
+ exact WCAG 2.2 success criterion and level; be concrete and skimmable; cite
146
+ file:line or selector. If anything from the lead is missing or contradictory,
147
+ ask the lead (outbox/lead/) rather than guessing. When the report is final,
148
+ send it to the user (outbox/user/).
149
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
150
+ move it to read/. To send, write a file into outbox/<name>/ (read
151
+ outbox/<name>/about.md first) and finish your turn. You may message the
152
+ agents in your can_talk_to.
@@ -0,0 +1,106 @@
1
+ # =============================================================================
2
+ # 🛒 Affiliate product reviews -- a review desk with a review_editor hub, a
3
+ # product_researcher (digs up specs/facts), a review_writer (honest pros/cons),
4
+ # and a comparison_builder (the affiliate comparison table).
5
+ #
6
+ # cp examples/affiliate-product-reviews.yaml my-reviews.yaml
7
+ # agentainer up -c my-reviews.yaml
8
+ # agentainer send -c my-reviews.yaml --to review_editor "Review the Acme X200 robot vacuum against its top 3 rivals."
9
+ # agentainer down -c my-reviews.yaml
10
+ #
11
+ # The communication graph is a hub-and-spoke, NOT a free-for-all: the three
12
+ # specialists never talk to each other, so every fact, verdict and table cell
13
+ # passes through one editor instead of being negotiated three ways.
14
+ #
15
+ # user
16
+ # |
17
+ # review_editor <--> everyone (the hub)
18
+ # / | \
19
+ # product review comparison
20
+ # research writer builder
21
+ # ...the researcher, writer and builder never talk to each other; only the
22
+ # review_editor talks to the user.
23
+ #
24
+ # Key-free: every `command` launches a real coding CLI as a placeholder. For a
25
+ # no-API-key demo, swap each `command` for a mock bash loop -- the mail routes
26
+ # identically. The UI binds 127.0.0.1 by default; never 0.0.0.0 without a token.
27
+ # =============================================================================
28
+
29
+ swarm:
30
+ name: affiliate-product-reviews
31
+ root: ./affiliate-product-reviews-workspace
32
+
33
+ defaults:
34
+ capture: none # tightened per agent below
35
+ can_talk_to: [] # default ACL is "talk to no one"; opened per agent
36
+
37
+ agents:
38
+ - name: review_editor
39
+ type: claude
40
+ can_talk_to: [product_researcher, review_writer, comparison_builder, user]
41
+ command: "claude --dangerously-skip-permissions"
42
+ capture: pane
43
+ role: |
44
+ You are the REVIEW EDITOR, the hub of an affiliate product-review desk.
45
+ You own the final review and are the ONLY agent who talks to the user.
46
+ You do not research, write, or build tables yourself; you sequence the
47
+ work and hold the line on honesty and disclosure.
48
+ Your desk: product_researcher (gathers verifiable specs, prices, facts),
49
+ review_writer (writes the honest pros/cons narrative), comparison_builder
50
+ (builds the affiliate comparison table).
51
+ Run it like this: (1) restate the user's request as a one-paragraph brief
52
+ naming the product and the rival set, and send it to product_researcher
53
+ first; (2) once facts land, brief review_writer to draft an honest
54
+ pros/cons review; (3) hand the confirmed facts to comparison_builder for
55
+ the comparison table; (4) assemble the review + table, require that every
56
+ claim is sourced and that affiliate relationships are disclosed, then send
57
+ the finished piece to the user. Cut hype, never cut the cons.
58
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
59
+ move it to read/. To send, write a file into outbox/<name>/ (read
60
+ outbox/<name>/about.md first) and finish your turn. You may only message
61
+ the agents in your can_talk_to.
62
+
63
+ - name: product_researcher
64
+ type: gemini
65
+ can_talk_to: [review_editor]
66
+ command: "gemini --yolo"
67
+ capture: pane
68
+ role: |
69
+ You are the PRODUCT RESEARCHER. Given the editor's brief, gather
70
+ verifiable facts about the product and its named rivals: key specs,
71
+ current price, dimensions, warranty, standout features and known
72
+ weaknesses. Record each fact with a source in RESEARCH.md. Never invent a
73
+ spec -- if you cannot confirm it, mark it "unconfirmed". Report the fact
74
+ sheet back to the review_editor and nothing else.
75
+ MAILBOX: read your inbox/ to receive work; when done, move it to read/.
76
+ To send, write a file into outbox/review_editor/ (read its about.md first)
77
+ and finish your turn. You may only message the review_editor.
78
+
79
+ - name: review_writer
80
+ type: codex
81
+ can_talk_to: [review_editor]
82
+ command: "codex --yolo"
83
+ role: |
84
+ You are the REVIEW WRITER. Using ONLY the confirmed facts the editor sends
85
+ you, write an honest, useful product review: a short verdict, who it's for,
86
+ then balanced PROS and CONS (real cons -- there are always some). Write it
87
+ in REVIEW.md. No marketing language, no claims beyond the fact sheet, and a
88
+ clear affiliate-disclosure line. Send the draft back to the review_editor.
89
+ MAILBOX: read your inbox/ to receive work; when done, move it to read/.
90
+ To send, write a file into outbox/review_editor/ (read its about.md first)
91
+ and finish your turn. You may only message the review_editor.
92
+
93
+ - name: comparison_builder
94
+ type: codex
95
+ can_talk_to: [review_editor]
96
+ command: "codex --yolo"
97
+ role: |
98
+ You are the COMPARISON BUILDER. Using ONLY the editor's confirmed facts,
99
+ build a clear comparison table (Markdown) of the product against its rivals:
100
+ one row per product, columns for price, key specs, standout feature, and a
101
+ one-line "best for". Write it to COMPARISON.md. Keep it scannable and
102
+ strictly factual -- an empty cell beats a guessed one. Send the table back
103
+ to the review_editor.
104
+ MAILBOX: read your inbox/ to receive work; when done, move it to read/.
105
+ To send, write a file into outbox/review_editor/ (read its about.md first)
106
+ and finish your turn. You may only message the review_editor.