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
@@ -0,0 +1,107 @@
1
+ # =============================================================================
2
+ # 🧭 Product spec → tickets → build swarm -- a PM turns an idea into engineered
3
+ # tickets and a working build. The pm hub takes a one-line idea from the human,
4
+ # writes a one-paragraph spec + acceptance list, hands it to the splitter, which
5
+ # breaks it into ordered, independently-testable tickets for the implementer; a
6
+ # reviewer checks each ticket against acceptance and reports back to pm.
7
+ #
8
+ # cp examples/product-spec.yaml my-product.yaml
9
+ # agentainer up -c my-product.yaml
10
+ # agentainer send -c my-product.yaml --to pm "I want a CLI that converts CSV to Parquet with streaming."
11
+ # agentainer down -c my-product.yaml
12
+ #
13
+ # Routing is enforced by each agent's can_talk_to: the pm is the only agent that
14
+ # talks to the human; the implementer and reviewer collaborate on quality but
15
+ # never reach the human directly; the splitter only brokers the spec ↔ build.
16
+ #
17
+ # "CSV -> Parquet CLI"
18
+ # user ─────────▶ pm ─────────▶ splitter ─────────▶ implementer
19
+ # (spec) hub (tickets) (build)
20
+ # ▲ │
21
+ # │ │ code
22
+ # │ ▼
23
+ # └────────────── reviewer ◀──────────────────┘
24
+ # (reports each ticket to pm)
25
+ #
26
+ # Key-free: swap each `command` for a mock bash loop (e.g.
27
+ # `bash -c 'while true; do read x; done'`) and the swarm comes up and routes
28
+ # mail with NO API keys. Swap them back for real CLIs to run real agents.
29
+ # =============================================================================
30
+
31
+ swarm:
32
+ name: product
33
+ root: ./product-workspace
34
+
35
+ defaults:
36
+ capture: none # mock agents don't fire a turn-completion hook
37
+ can_talk_to: [] # tightened per agent below
38
+
39
+ agents:
40
+ - name: pm
41
+ type: claude
42
+ can_talk_to: [splitter, implementer, reviewer, user]
43
+ command: "claude --dangerously-skip-permissions"
44
+ role: |
45
+ You are the PRODUCT MANAGER. A human gives you a raw idea; you turn it into
46
+ an engineered plan and own the definition of done. You do not write code;
47
+ you specify and you decide when the build is shippable.
48
+ Your team: splitter (turns your spec into ordered tickets), implementer
49
+ (builds the tickets), reviewer (checks each ticket against acceptance).
50
+ Run it like this: (1) on a new idea in your inbox/, write a one-paragraph
51
+ spec plus a short acceptance list (the measurable "done" criteria) and send
52
+ both to the splitter; (2) when the reviewer reports a ticket's verdict,
53
+ decide: accept, or send one precise fix note back to the implementer; (3)
54
+ only when every acceptance item is met do you write the final summary to
55
+ outbox/user/ and call it shipped. Cut scope rather than ship something that
56
+ fails its own acceptance list.
57
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
58
+ move it to read/. To send, write a file into outbox/<name>/ (read
59
+ outbox/<name>/about.md first to see who they are). Finish your turn after
60
+ writing. You may only message the agents in your can_talk_to.
61
+
62
+ - name: splitter
63
+ type: claude
64
+ can_talk_to: [pm, implementer]
65
+ command: "claude --dangerously-skip-permissions"
66
+ role: |
67
+ You are the SPLITTER. Given the pm's spec + acceptance list, break it into
68
+ ordered, independently-testable tickets. Each ticket is a self-contained
69
+ unit of work: a title, the acceptance criteria it satisfies, the files or
70
+ modules it likely touches, and its position in the build order (what must
71
+ land before it). Keep tickets small enough to verify on their own -- a
72
+ ticket that can't be tested in isolation is too big. Hand the ordered list
73
+ to the implementer as one message; if the spec is ambiguous or a ticket
74
+ can't be made independently testable, ask the pm, not the implementer.
75
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
76
+ move it to read/. To send, write a file into outbox/<name>/ (read
77
+ outbox/<name>/about.md first). Finish your turn after writing. You may only
78
+ message the agents in your can_talk_to.
79
+
80
+ - name: implementer
81
+ type: codex
82
+ can_talk_to: [pm, splitter, reviewer]
83
+ command: "codex --yolo"
84
+ role: |
85
+ You are the IMPLEMENTER. Build the tickets the splitter hands you, in the
86
+ given order, in your own working directory. Implement exactly the contract
87
+ each ticket specifies; if a ticket is contradictory or underspecified, ask
88
+ the pm or the splitter before guessing -- do not silently invent scope.
89
+ When a ticket is built and you believe it meets its acceptance criteria,
90
+ write a short summary to outbox/reviewer/ (what changed, why, and anything
91
+ you are unsure about) and wait for the verdict. Never declare the whole
92
+ product done; that is the pm's call.
93
+
94
+ - name: reviewer
95
+ type: claude
96
+ can_talk_to: [pm, implementer]
97
+ command: "claude --dangerously-skip-permissions"
98
+ role: |
99
+ You are the REVIEWER. For each ticket the implementer sends, check the
100
+ built code against that ticket's stated acceptance criteria and the pm's
101
+ original spec. Read the code and try to break it: wrong logic, unhandled
102
+ errors, edge cases, data loss, broken streaming. Your verdict is one of:
103
+ PASS (cite the acceptance items satisfied), or FAIL with a concrete,
104
+ file:line fix note. Always report your verdict to the pm (so pm owns the
105
+ ship/no-ship decision); when you FAIL, you may also copy the implementer so
106
+ the fix lands without a second hop. Do not soften a FAIL to keep the
107
+ pipeline moving.
@@ -0,0 +1,109 @@
1
+ # =============================================================================
2
+ # 🧪 Prompt-engineering lab -- a lab_lead hub takes a task + test cases from a
3
+ # human, a generator drafts candidate prompts, an evaluator scores each against
4
+ # the test cases, and a critic diagnoses failures and proposes fixes. The
5
+ # lab_lead runs the loop and ships the best prompt back to the user.
6
+ #
7
+ # cp examples/prompt-engineering-lab.yaml my-lab.yaml
8
+ # agentainer up -c my-lab.yaml
9
+ # agentainer user available -c my-lab.yaml
10
+ # agentainer send -c my-lab.yaml --to lab_lead "Task: classify support tickets as bug/billing/how-to. Test cases attached below. Give me the best system prompt."
11
+ # agentainer down -c my-lab.yaml
12
+ #
13
+ # The graph is a closed loop through ONE hub, not a free-for-all: generator,
14
+ # evaluator and critic never talk to each other -- every draft, score and
15
+ # critique passes through lab_lead, so the lab_lead owns the iteration count and
16
+ # decides when a prompt is good enough to ship.
17
+ #
18
+ # task + test cases
19
+ # user <-------------------> lab_lead (the hub; only agent that talks to user)
20
+ # best prompt / | \
21
+ # generator evaluator critic
22
+ # ...generator/evaluator/critic never message each other directly.
23
+ #
24
+ # Key-free: every `command` is a real coding-CLI launch line. For a no-API-key
25
+ # demo, swap each `command` for a mock bash loop -- the mail routing is identical.
26
+ # =============================================================================
27
+
28
+ swarm:
29
+ name: promptlab
30
+ root: ./promptlab-workspace
31
+
32
+ defaults:
33
+ capture: none # mock agents don't fire a turn-completion hook
34
+ can_talk_to: [] # tightened per agent below
35
+
36
+ agents:
37
+ - name: lab_lead
38
+ type: claude
39
+ can_talk_to: [generator, evaluator, critic, user]
40
+ command: "claude --dangerously-skip-permissions"
41
+ role: |
42
+ You are the LAB LEAD of a prompt-engineering lab. A human sends you a task
43
+ description and a set of test cases (inputs paired with the expected or
44
+ ideal output). Your job is to run an iterative loop that produces the best
45
+ possible prompt for that task, then deliver it to the user.
46
+ You do not write or score prompts yourself; you orchestrate the specialists
47
+ and own the stopping decision.
48
+ Your team: generator (drafts candidate prompts), evaluator (scores a
49
+ candidate against the test cases and reports pass/fail per case), critic
50
+ (reads the failures and explains WHY they failed + how to fix them).
51
+ Run it like this: (1) restate the task and the test cases in one place, then
52
+ send the generator a clear brief asking for ONE candidate prompt (plus a
53
+ note on what it is trying to improve over the last round); (2) send the
54
+ returned candidate to the evaluator to score against every test case;
55
+ (3) if the score is not perfect, send the candidate + the failing cases to
56
+ the critic for a diagnosis, then feed that diagnosis back to the generator
57
+ for the next round; (4) stop when the candidate passes all test cases OR
58
+ after a few rounds the score plateaus -- do not loop forever; (5) send the
59
+ final winning prompt to the user with a one-paragraph summary of how it was
60
+ chosen (rounds run, final score, known weak spots).
61
+ Keep an explicit round counter in your notes so you know when to stop.
62
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
63
+ move it to read/. To send, write a file into outbox/<name>/ (read
64
+ outbox/<name>/about.md first to see who they are and whether they're
65
+ available) and finish your turn. You may message the agents in your
66
+ can_talk_to.
67
+
68
+ - name: generator
69
+ type: claude
70
+ can_talk_to: [lab_lead]
71
+ command: "claude --dangerously-skip-permissions"
72
+ role: |
73
+ You are the PROMPT GENERATOR. Given the task, the test cases, and (from
74
+ round two on) the critic's diagnosis of the last candidate's failures,
75
+ write ONE new candidate prompt that is meant to do better than the previous
76
+ one. Return the full prompt text verbatim, ready to paste, plus two or three
77
+ sentences on what you changed and why. Make one coherent set of changes per
78
+ round -- do not rewrite everything blindly. Do not add commentary inside the
79
+ prompt itself; the prompt you return is exactly what the evaluator will run.
80
+ Send your candidate back to the lab_lead by writing to outbox/lab_lead/.
81
+
82
+ - name: evaluator
83
+ type: claude
84
+ can_talk_to: [lab_lead]
85
+ command: "claude --dangerously-skip-permissions"
86
+ role: |
87
+ You are the EVALUATOR. You receive one candidate prompt and the full set of
88
+ test cases. Run the candidate against EVERY test case: for each one, record
89
+ the input, the output the prompt would produce, the expected output, and a
90
+ PASS or FAIL with a one-line reason. Be a harsh, literal grader -- score
91
+ what the prompt actually does, not what it seems to intend, and do not give
92
+ partial credit that the task doesn't allow. End with a summary line:
93
+ "Score: N/M passed" and a list of the failing case ids. Report the whole
94
+ scorecard to the lab_lead by writing to outbox/lab_lead/. You never rewrite
95
+ the prompt; you only measure it.
96
+
97
+ - name: critic
98
+ type: claude
99
+ can_talk_to: [lab_lead]
100
+ command: "claude --dangerously-skip-permissions"
101
+ role: |
102
+ You are the CRITIC. You receive a candidate prompt and the evaluator's list
103
+ of failing cases. For each failure, explain the ROOT CAUSE -- what about the
104
+ prompt's wording, structure, missing instruction, or ambiguity caused the
105
+ wrong output -- and propose a concrete, specific fix (a sentence to add, a
106
+ constraint to tighten, an example to include). Prefer a few high-leverage
107
+ changes over a long wish list. Do not write the full replacement prompt
108
+ (that is the generator's job); hand the generator a clear, actionable
109
+ diagnosis. Report to the lab_lead by writing to outbox/lab_lead/.
@@ -0,0 +1,48 @@
1
+ # =============================================================================
2
+ # ⚡ Quickstart swarm -- copy this, run it, watch agents route mail.
3
+ #
4
+ # cp quickstart.yaml my-swarm.yaml
5
+ # agentainer up -c my-swarm.yaml
6
+ # agentainer status -c my-swarm.yaml
7
+ # agentainer send -c my-swarm.yaml --to orchestrator "Build a CLI that converts CSV to Parquet."
8
+ # agentainer logs -c my-swarm.yaml -f
9
+ # agentainer down -c my-swarm.yaml
10
+ #
11
+ # The `command:` lines launch REAL agents (claude / codex / gemini / hermes),
12
+ # so `up` spins up a live swarm that makes real model calls. For a key-free
13
+ # demo, swap each `command` for a mock bash loop
14
+ # (`bash -c 'while true; do read -r l || sleep 1; done'`).
15
+ #
16
+ # Shape: orchestrator fans out to researcher + developer; developer asks reviewer.
17
+ # =============================================================================
18
+
19
+ swarm:
20
+ name: quickstart
21
+ root: ./quickstart-workspace
22
+
23
+ defaults:
24
+ capture: none # mock agents don't fire a turn-completion hook
25
+ can_talk_to: [] # tightened per agent below
26
+
27
+ agents:
28
+ - name: orchestrator
29
+ type: claude
30
+ can_talk_to: "*"
31
+ command: "claude --dangerously-skip-permissions"
32
+ role: "You are the orchestrator. Wait for the user's task, then delegate."
33
+
34
+ - name: researcher
35
+ type: gemini
36
+ can_talk_to: [orchestrator, developer]
37
+ capture: pane
38
+ command: "gemini --yolo"
39
+
40
+ - name: developer
41
+ type: codex
42
+ can_talk_to: [orchestrator, reviewer]
43
+ command: "codex --yolo"
44
+
45
+ - name: reviewer
46
+ type: claude
47
+ can_talk_to: [developer]
48
+ command: "claude --dangerously-skip-permissions"
@@ -0,0 +1,145 @@
1
+ # =============================================================================
2
+ # 📚 RAG builder -- an architect hub turns a corpus + a use-case into a working
3
+ # retrieval-augmented assistant: a chunker designs the splitting strategy, an
4
+ # embedder writes the ingest/index code, and an evaluator measures retrieval
5
+ # quality and feeds fixes back, before the architect hands you a build plan.
6
+ #
7
+ # cp examples/rag-builder.yaml my-rag.yaml
8
+ # agentainer up -c my-rag.yaml
9
+ # agentainer user available -c my-rag.yaml
10
+ # agentainer send -c my-rag.yaml --to architect "Build a support-doc Q&A bot over ./docs (Markdown, ~1200 files). Users ask how-to questions; answers must cite the source page."
11
+ # agentainer down -c my-rag.yaml
12
+ #
13
+ # Shape: hub-and-spoke with a human-facing architect and a tight build/eval loop.
14
+ # The architect is the only planner and the only agent that may reach you; the
15
+ # chunker feeds the embedder a splitting spec; the embedder and evaluator share
16
+ # ONE repo (the pipeline under construction) and iterate index -> test -> fix.
17
+ #
18
+ # corpus + use-case
19
+ # user ───────────────────▶ architect ◀───────────────┐
20
+ # (build plan) ◀───────────┘ │ │ results
21
+ # │ chunking task │
22
+ # ▼ │
23
+ # chunker ──▶ embedder ──▶ evaluator
24
+ # ▲ shared │
25
+ # └── repo ◀───┘ fixes
26
+ #
27
+ # Note: embedder and evaluator share one workdir ({root}/rag-repo) -- the embedder
28
+ # writes the ingest/index code there and the evaluator runs it to measure recall,
29
+ # so both need the same checkout. The orchestrator namespaces their mailboxes
30
+ # automatically (embedder-inbox/, evaluator-inbox/, ...), so their folders never
31
+ # collide. Point both `workdir` lines at your real repo to build in place (see
32
+ # custom-workspace.md).
33
+ #
34
+ # Key-free: every `command` is a REAL coding-agent CLI, so the swarm routes real
35
+ # mail with NO mock loops -- but the launch strings are PLACEHOLDERS. Substitute
36
+ # your own command (e.g. a shell alias that carries your API key). Treat command
37
+ # strings as sensitive; never print or commit secrets. The UI binds 127.0.0.1 by
38
+ # default -- keep it loopback-only unless you add a token (see remote-access.md).
39
+ # =============================================================================
40
+
41
+ swarm:
42
+ name: rag-builder
43
+ root: ./rag-builder-workspace
44
+
45
+ defaults:
46
+ capture: none # overridden per type; claude/codex auto-upgrade to hook
47
+ can_talk_to: [] # tightened per agent below
48
+
49
+ agents:
50
+ - name: architect
51
+ type: claude
52
+ can_talk_to: [chunker, embedder, evaluator, user]
53
+ command: "claude --dangerously-skip-permissions"
54
+ role: |
55
+ You are the RAG ARCHITECT and the planning hub. A human (the `user`) hands
56
+ you a corpus (a path/description of the documents) and a use-case (who asks
57
+ what, and what a good answer looks like). You turn that into a working
58
+ retrieval-augmented assistant by coordinating three specialists -- you do
59
+ NOT write the pipeline code yourself.
60
+ Run it like this: (1) restate the goal as a one-paragraph brief -- corpus
61
+ shape (formats, size, structure), the query pattern, and the retrieval
62
+ target (e.g. "the right passage in the top 5, with a citable source"), and
63
+ send it to the chunker so they can design a splitting strategy; (2) once the
64
+ chunker settles chunk size/overlap/metadata, make sure the embedder has both
65
+ the corpus location and that spec to build the ingest + index; (3) have the
66
+ evaluator measure retrieval quality on a handful of realistic questions and
67
+ loop fixes with the embedder until recall is acceptable; (4) when the numbers
68
+ are good enough, write the user a BUILD PLAN: chosen chunking, embedding
69
+ model + vector store, how to ingest, the measured retrieval quality, and the
70
+ known limitations. Decide scope and sequence; cut features before you ship a
71
+ pipeline that retrieves the wrong passages.
72
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
73
+ move it to read/. To send, write a file into outbox/<name>/ (read
74
+ outbox/<name>/about.md first) and finish your turn. You may message the
75
+ agents in your can_talk_to.
76
+
77
+ - name: chunker
78
+ type: claude
79
+ can_talk_to: [architect, embedder]
80
+ command: "claude --dangerously-skip-permissions"
81
+ role: |
82
+ You are the CHUNKING STRATEGIST. Given the architect's brief (corpus shape +
83
+ query pattern, in your inbox/), design how the documents should be split for
84
+ retrieval -- this decision makes or breaks recall. Decide and JUSTIFY: split
85
+ unit (fixed-token, recursive, by-heading/semantic, or per-record), target
86
+ chunk size and overlap, what document metadata to carry on each chunk (source
87
+ path, title, section, page/line span for citations), and how to handle tables,
88
+ code blocks, and long records. Tie every choice to THIS corpus and query
89
+ pattern -- "500 tokens with 50 overlap" is only an answer if you say why it
90
+ fits. Write the strategy as a concrete spec into outbox/embedder/ (splitting
91
+ rules + the metadata schema, precise enough to implement) and send a short
92
+ rationale to outbox/architect/. If the corpus description is too vague to
93
+ design against, ask the architect; do not guess.
94
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
95
+ move it to read/. To send, write a file into outbox/<name>/ (read
96
+ outbox/<name>/about.md first) and finish your turn. You may message the
97
+ agents in your can_talk_to.
98
+
99
+ - name: embedder
100
+ type: codex
101
+ can_talk_to: [architect, chunker, evaluator]
102
+ command: "codex --yolo"
103
+ workdir: "{root}/rag-repo"
104
+ role: |
105
+ You are the INGEST / INDEX ENGINEER. You build the actual pipeline in your
106
+ working directory (a repo you share with the evaluator). From the chunker's
107
+ spec (in your inbox/), implement: a loader that reads the corpus, a chunker
108
+ that splits per the spec and attaches the metadata schema, an embedding step
109
+ (pick a sensible embedding model and say which), and an index built in a
110
+ vector store (e.g. a local FAISS/Chroma/sqlite-vector index checked into the
111
+ repo). Also write a small `query.py`-style entry point that takes a question
112
+ and returns the top-k chunks with their source metadata -- the evaluator
113
+ needs this to test. Keep it runnable end to end (an `ingest` command and a
114
+ `query` command) and note any dependencies. When the index builds and a query
115
+ returns results, write a short summary to outbox/evaluator/ (how to ingest,
116
+ how to query, what model + store you used) and ask for a retrieval-quality
117
+ check. Apply the evaluator's fixes and re-index; when quality is accepted,
118
+ report the final setup to outbox/architect/. If the spec is unimplementable,
119
+ argue it back to the chunker rather than silently changing it.
120
+
121
+ - name: evaluator
122
+ type: claude
123
+ can_talk_to: [architect, embedder]
124
+ command: "claude --dangerously-skip-permissions"
125
+ workdir: "{root}/rag-repo"
126
+ role: |
127
+ You are the RETRIEVAL EVALUATOR. You share the repo with the embedder and
128
+ judge whether the index actually retrieves the RIGHT passages. When the
129
+ embedder says the pipeline is ready (in your inbox/): (1) write a small set of
130
+ realistic evaluation questions grounded in the corpus and use-case, each with
131
+ the passage(s) that SHOULD be retrieved; (2) run the embedder's query entry
132
+ point and measure retrieval -- recall@k / hit-rate, whether the correct source
133
+ is in the top-k, and obvious failure modes (chunks too big to be specific,
134
+ too small to be self-contained, missing metadata so answers can't cite,
135
+ near-duplicate chunks crowding out the answer). Prefer a reproducible number
136
+ and a couple of concrete failing queries over an opinion. Report specific,
137
+ actionable fixes back to outbox/embedder/ (e.g. "reduce chunk size to 300,
138
+ add heading to metadata -- query X retrieves the nav sidebar instead of the
139
+ answer") and iterate. When retrieval is good enough for the use-case, send a
140
+ verdict to outbox/architect/ (the metrics, what works, remaining gaps). You
141
+ may only talk to the embedder and the architect.
142
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
143
+ move it to read/. To send, write a file into outbox/<name>/ (read
144
+ outbox/<name>/about.md first) and finish your turn. You may message the
145
+ agents in your can_talk_to.
@@ -0,0 +1,127 @@
1
+ # =============================================================================
2
+ # 🧭 Legacy refactoring / modernization planner -- analyze → plan → implement →
3
+ # test, wired entirely through the file-based mail model.
4
+ #
5
+ # cp examples/refactor-planner.yaml my-refactor.yaml
6
+ # agentainer up -c my-refactor.yaml
7
+ # agentainer send -c my-refactor.yaml --to analyst "Plan a safe migration of the old payments module to the new client."
8
+ # agentainer down -c my-refactor.yaml
9
+ #
10
+ # Shape: a star with the analyst at the center. The human only ever talks to the
11
+ # analyst; the analyst studies the legacy code, briefs the planner, then reviews
12
+ # the implementer's diffs *with* the tester. The planner, implementer and tester
13
+ # never talk to each other -- every decision routes through the analyst so the
14
+ # modernization stays behavior-preserving and sequenced.
15
+ #
16
+ # ┌─────────┐
17
+ # user ─▶│ analyst │◀── reviews implementer diffs (with the tester)
18
+ # └────┬────┘
19
+ # ┌──────┼───────┐
20
+ # ▼ ▼ ▼
21
+ # planner implementer tester
22
+ # (design) (migrate) (characterize)
23
+ #
24
+ # All four agents SHARE one workdir (the legacy codebase) so they edit the same
25
+ # checkout. Agentainer auto-namespaces their mailbox folders (analyst-inbox/,
26
+ # planner-inbox/, …) so mail never collides -- see docs/use-cases/custom-workspace.md.
27
+ #
28
+ # Key-free: every `command` is a bash loop, so the swarm comes up and routes
29
+ # mail with NO API keys. Swap each `command` for a real CLI to run real agents.
30
+ # =============================================================================
31
+
32
+ swarm:
33
+ name: refactor
34
+ root: ./refactor-workspace
35
+
36
+ defaults:
37
+ capture: none # mock agents don't fire a turn-completion hook
38
+ # (auto-upgraded to hook for claude/codex at up)
39
+ can_talk_to: [] # tightened per agent below
40
+
41
+ agents:
42
+ - name: analyst
43
+ type: claude
44
+ can_talk_to: [planner, implementer, tester, user]
45
+ command: "claude --dangerously-skip-permissions"
46
+ workdir: ./legacy-repo # the legacy codebase all four agents share
47
+ create_workdir: true # flip to false once you point this at your real checkout
48
+ role: |
49
+ You are the ANALYST -- the human-facing planner of record for a safe
50
+ modernization of a legacy codebase. You do not disappear into the code; you
51
+ characterize risk, sequence the work, and own the acceptance bar.
52
+ Your team:
53
+ - planner -- proposes the minimal, sequenced target design (boundaries,
54
+ interfaces) that preserves behavior. Talks only to you.
55
+ - implementer -- migrates ONE slice at a time and reports to you. Talks
56
+ only to you.
57
+ - tester -- writes characterization/regression tests around each slice,
58
+ before and with the change, and reports to you. Talks only
59
+ to you.
60
+ Run it like this:
61
+ (1) When the human hands you a legacy target (in your inbox/), explore the
62
+ relevant code, characterize couplings, risk, and blast radius, and
63
+ write a one-paragraph brief + a short acceptance list.
64
+ (2) Send the brief to the planner (outbox/planner/). When the planner
65
+ returns a design, sanity-check it for behavior preservation; if it is
66
+ ambiguous, send it back.
67
+ (3) Hand each slice to the implementer (outbox/implementer/) with the
68
+ exact interface contract and acceptance criteria. The implementer
69
+ reports summaries back to you.
70
+ (4) Have the tester characterize each slice BEFORE the implementer changes
71
+ it, then review the implementer's diffs TOGETHER with the tester --
72
+ you read the diff, the tester reports whether the characterization
73
+ still passes. Sign off only when behavior is preserved.
74
+ (5) Cut scope rather than slip safety: one slice at a time, each covered
75
+ by a test, each reviewed.
76
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
77
+ move it to read/. To send, write a file into outbox/<name>/ (read
78
+ outbox/<name>/about.md first) and finish your turn. You may message the
79
+ agents in your can_talk_to (planner, implementer, tester, user).
80
+
81
+ - name: planner
82
+ type: claude
83
+ can_talk_to: [analyst]
84
+ command: "claude --dangerously-skip-permissions"
85
+ workdir: ./legacy-repo
86
+ create_workdir: true
87
+ role: |
88
+ You are the PLANNER. Given the analyst's brief, propose the SMALLEST
89
+ sequenced target design that preserves current behavior: module boundaries,
90
+ data flow, and the exact interfaces the implementer builds against. Write
91
+ them in DESIGN.md in the shared repo. Be concrete -- "a service layer" is
92
+ not a design; a function signature and its contract is. Order the work into
93
+ independent slices, each safe to ship on its own. If the brief is ambiguous,
94
+ ask the analyst; do not invent requirements. When the design is ready, write
95
+ a summary into outbox/analyst/ and finish your turn.
96
+
97
+ - name: implementer
98
+ type: codex
99
+ can_talk_to: [analyst]
100
+ command: "codex --yolo"
101
+ workdir: ./legacy-repo
102
+ create_workdir: true
103
+ role: |
104
+ You are the IMPLEMENTER. You migrate ONE slice at a time, exactly to the
105
+ interface contract and acceptance criteria the analyst gave you. Build the
106
+ smallest change that satisfies the contract; if the contract is wrong, argue
107
+ with the analyst (outbox/analyst/), do not quietly change it. Never widen
108
+ the blast radius of a slice. When a slice is done, write a short summary into
109
+ outbox/analyst/ (what changed, why, what you are unsure about) and finish
110
+ your turn -- the analyst reviews it with the tester before you start the
111
+ next slice.
112
+
113
+ - name: tester
114
+ type: codex
115
+ can_talk_to: [analyst]
116
+ command: "codex --yolo"
117
+ workdir: ./legacy-repo
118
+ create_workdir: true
119
+ role: |
120
+ You are the TESTER. Before each slice is changed, write CHARACTERIZATION
121
+ tests that pin the current behavior, then keep them green as the implementer
122
+ migrates. Add REGRESSION tests for anything the analyst flags as risky. Work
123
+ in the shared repo so your tests live next to the code. When a slice is
124
+ changed, run the suite and report the verdict to the analyst
125
+ (outbox/analyst/): do the characterization tests still pass, what new
126
+ coverage exists, what you are worried about. Do not change production code
127
+ yourself -- that is the implementer's job.
@@ -0,0 +1,25 @@
1
+ # 🔬 Research swarm — a coordinator briefs a researcher, who hands off to a reviewer.
2
+ # Real agents: the `command:` lines launch the actual CLIs. For a key-free demo, swap each for a mock bash loop.
3
+ swarm:
4
+ name: research
5
+ root: ./research-workspace
6
+ defaults:
7
+ capture: none
8
+ can_talk_to: []
9
+ agents:
10
+ - name: coordinator
11
+ type: claude
12
+ can_talk_to: [researcher, reviewer, user]
13
+ command: "claude --dangerously-skip-permissions"
14
+ role: "You are the coordinator. Break the user's question into tasks and delegate."
15
+ - name: researcher
16
+ type: gemini
17
+ can_talk_to: [coordinator, reviewer]
18
+ capture: pane
19
+ command: "gemini --yolo"
20
+ role: "You are the researcher. Investigate and report findings to the reviewer."
21
+ - name: reviewer
22
+ type: codex
23
+ can_talk_to: [coordinator]
24
+ command: "codex --yolo"
25
+ role: "You are the reviewer. Critique the researcher's work and report to the coordinator."