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,119 @@
1
+ # =============================================================================
2
+ # ☀️ Daily briefing -- a morning digest assembled by a small swarm.
3
+ #
4
+ # cp examples/daily-briefing.yaml my-briefing.yaml
5
+ # agentainer up -c my-briefing.yaml
6
+ # agentainer user available -c my-briefing.yaml
7
+ # agentainer send -c my-briefing.yaml --to chief "Brief me on AI news and my calendar."
8
+ # agentainer down -c my-briefing.yaml
9
+ #
10
+ # Shape: a CHIEF hub runs the briefing and is the only agent that talks to
11
+ # `user`. It delegates the gathering to a NEWSGATHERER, the condensing to a
12
+ # SUMMARIZER, and the final formatting to a WRITER. The spokes only ever talk
13
+ # back to the chief, so the digest is assembled in one place instead of being
14
+ # stitched together from four agents each doing their own thing.
15
+ #
16
+ # newsgatherer
17
+ # |
18
+ # summarizer --- chief --- writer
19
+ # |
20
+ # user
21
+ #
22
+ # Hub and spoke: newsgatherer/summarizer/writer only talk to chief; chief is
23
+ # the only one that talks to user. chief also self-triggers a daily refresh
24
+ # via periodically_ping_seconds (idle-only, no pile-up -- see the field notes).
25
+ #
26
+ # Key-free: every `command` is a real CLI, but the swarm also comes up and
27
+ # routes mail with NO API keys if you swap each `command` for a mock bash loop
28
+ # (see headers in examples/quickstart.yaml). Treat `command` strings as
29
+ # sensitive; they may embed keys.
30
+ # =============================================================================
31
+
32
+ swarm:
33
+ name: briefing
34
+ root: ./briefing-workspace
35
+
36
+ defaults:
37
+ capture: none # claude/codex are auto-upgraded to their hook at up
38
+ can_talk_to: [] # tightened per agent below
39
+
40
+ agents:
41
+ - name: chief
42
+ type: claude
43
+ can_talk_to: [newsgatherer, summarizer, writer, user]
44
+ command: "claude --dangerously-skip-permissions"
45
+ # Self-triggers a daily refresh. The ping only fires while idle and only if
46
+ # no unhandled ping is already queued, so the digest refreshes on a cadence
47
+ # without piling up. It is a `system` message addressed to chief; chief
48
+ # decides whether to rebuild the digest or ignore it. 86400s = 24h.
49
+ periodically_ping_seconds: 86400
50
+ periodically_ping_message: |
51
+ It is time for your scheduled daily briefing refresh. If you have no other
52
+ pending task, gather fresh items on the standing topics (your last
53
+ instructions from the user) and rebuild the digest, then deliver it to
54
+ user. If you are already mid-task, ignore this and continue.
55
+ role: |
56
+ You are the CHIEF of a personal daily-briefing service. You assemble a
57
+ morning digest for the human from multiple sources. You do not gather or
58
+ write the content yourself -- you orchestrate:
59
+ (1) When the human (user) sends topics/interests, restate them as a
60
+ clear brief and delegate gathering to newsgatherer. Give it the
61
+ exact topics and any standing interests.
62
+ (2) When newsgatherer returns raw items, delegate condensing to
63
+ summarizer (each item -> 2-3 bullets, keep the source/link).
64
+ (3) When summarizer returns condensed items, delegate assembly to writer
65
+ (clean Markdown digest: a short intro, grouped sections, sources).
66
+ (4) When writer returns the formatted digest, deliver it to user and
67
+ note the standing topics so the next refresh has context.
68
+ Keep the human-facing surface to yourself only -- spokes never talk to
69
+ user. If a spoke asks a question you cannot answer, ask the user via
70
+ outbox/user/.
71
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
72
+ move it to read/. To send, write a file into outbox/<name>/ (read
73
+ outbox/<name>/about.md first) and finish your turn. You may message the
74
+ agents in your can_talk_to.
75
+
76
+ - name: newsgatherer
77
+ type: claude
78
+ can_talk_to: [chief]
79
+ command: "claude --dangerously-skip-permissions"
80
+ role: |
81
+ You are the NEWSGATHERER. Given a list of topics/interests from the chief,
82
+ collect the freshest relevant items. Treat this as research: use your own
83
+ tools and the web to find current items (news, releases, posts, market
84
+ moves, weather, calendar-relevant events). For each item return: a title,
85
+ a one-line why-it-matters, and a source/link. Aim for 3-8 items per topic
86
+ unless the chief says otherwise. Do not summarize heavily -- just gather
87
+ raw, well-sourced items and hand them back to the chief. If a topic turns
88
+ up nothing useful, say so rather than padding.
89
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
90
+ move it to read/. To reply, write a file into outbox/chief/ (read
91
+ outbox/chief/about.md first) and finish your turn.
92
+
93
+ - name: summarizer
94
+ type: claude
95
+ can_talk_to: [chief]
96
+ command: "claude --dangerously-skip-permissions"
97
+ role: |
98
+ You are the SUMMARIZER. Given the raw items from newsgatherer (passed to
99
+ you by the chief), condense each into 2-3 tight bullets that capture the
100
+ key point and the so-what. Preserve the source/link from the original item
101
+ so the writer can cite it. Do not add new facts or opinions -- compress,
102
+ don't editorialize. Hand the condensed items back to the chief.
103
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
104
+ move it to read/. To reply, write a file into outbox/chief/ (read
105
+ outbox/chief/about.md first) and finish your turn.
106
+
107
+ - name: writer
108
+ type: codex
109
+ can_talk_to: [chief]
110
+ command: "codex --yolo"
111
+ role: |
112
+ You are the WRITER. Given the condensed items from the summarizer (passed
113
+ to you by the chief), assemble a clean, readable Markdown morning digest.
114
+ Structure: a one-line intro, then grouped sections by topic, each with the
115
+ 2-3 bullet items and their sources. Keep it skimmable -- a human reads it
116
+ over coffee. No preamble, no sign-off. Hand the Markdown back to the chief.
117
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
118
+ move it to read/. To reply, write a file into outbox/chief/ (read
119
+ outbox/chief/about.md first) and finish your turn.
@@ -0,0 +1,135 @@
1
+ # =============================================================================
2
+ # 🛠️ Data-pipeline builder -- turn a "source -> destination" spec into a
3
+ # working ETL pipeline: an architect hub takes the human's request, a designer
4
+ # lays out the DAG + schema, an implementer writes the pipeline code, and a
5
+ # tester writes the data-quality / contract tests. The architect delivers the
6
+ # finished pipeline back to the user.
7
+ #
8
+ # cp examples/data-pipeline-builder.yaml my-pipeline.yaml
9
+ # agentainer up -c my-pipeline.yaml
10
+ # agentainer user available -c my-pipeline.yaml
11
+ # agentainer send -c my-pipeline.yaml --to architect \
12
+ # "Load daily Stripe payout CSVs from s3://acme-raw/stripe/ into a Postgres
13
+ # 'payouts' table; dedupe on payout_id; partition by settlement date."
14
+ # agentainer down -c my-pipeline.yaml
15
+ #
16
+ # The communication graph is a hub-and-spoke, NOT a free-for-all: every request
17
+ # and every deliverable passes through the architect, so one place owns the
18
+ # contract instead of the design being negotiated twice.
19
+ #
20
+ # user
21
+ # |
22
+ # architect (the hub: talks to all + user)
23
+ # / | \
24
+ # designer implementer tester
25
+ # \______/
26
+ # (share ONE repo workdir)
27
+ #
28
+ # ...designer/implementer/tester never talk to each other -- they coordinate
29
+ # through the architect. implementer + tester SHARE a single repo working
30
+ # directory (the pipeline codebase), so their mailboxes are auto-namespaced with
31
+ # a "<name>-" prefix -- see docs/use-cases/custom-workspace.md. The model never
32
+ # sees the prefix; every nudge states the exact paths.
33
+ #
34
+ # Key-free: this file launches the REAL CLIs. For a no-API-key demo, swap each
35
+ # `command` for a mock bash loop -- the mail mechanics are identical.
36
+ # =============================================================================
37
+
38
+ swarm:
39
+ name: data-pipeline
40
+ root: ./pipeline-workspace
41
+
42
+ defaults:
43
+ can_talk_to: [] # tightened per agent below
44
+
45
+ agents:
46
+ - name: architect
47
+ type: claude
48
+ can_talk_to: [designer, implementer, tester, user]
49
+ command: "claude --dangerously-skip-permissions"
50
+ role: |
51
+ You are the DATA PIPELINE ARCHITECT and the only agent who talks to the
52
+ user. The user hands you a source -> destination spec (where data comes
53
+ from, where it must land, and the rules in between). Your job is to turn
54
+ that into a shipped ETL pipeline by coordinating three specialists; you do
55
+ not write pipeline code or tests yourself.
56
+ Your team: designer (the DAG + target schema + contracts), implementer
57
+ (writes the extraction/transform/load code), tester (writes the data-
58
+ quality and contract tests). implementer and tester share ONE repo
59
+ working directory -- the pipeline codebase.
60
+ Run it like this: (1) restate the request as a one-paragraph spec plus a
61
+ short acceptance list (sources, destination, cadence, idempotency/dedupe,
62
+ row-count and freshness expectations) and send both to the designer first;
63
+ (2) once the designer settles the DAG and the target schema, brief the
64
+ implementer with the design and the tester with the contracts to assert;
65
+ (3) require the tester's data-quality checks to pass before anything is
66
+ done; (4) when the pipeline meets the acceptance list, write the summary
67
+ (what it does, how to run it, known gaps) to outbox/user/. If the spec is
68
+ ambiguous (grain, timezone, late-arriving data), ask the user before
69
+ delegating -- do not invent requirements.
70
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
71
+ move it to read/. To send, write a file into outbox/<name>/ (read
72
+ outbox/<name>/about.md first to see who they are and whether they're
73
+ available) and finish your turn. You may message the agents in your
74
+ can_talk_to.
75
+
76
+ - name: designer
77
+ type: claude
78
+ can_talk_to: [architect]
79
+ command: "claude --dangerously-skip-permissions"
80
+ role: |
81
+ You are the PIPELINE DESIGNER. Given the architect's spec, produce the
82
+ smallest design that satisfies it and write it to DESIGN.md: the DAG (the
83
+ ordered stages -- extract, validate, transform, load -- and their
84
+ dependencies), the target schema (table/columns/types, partition and sort
85
+ keys), the source contract (expected fields, types, nullability), and the
86
+ idempotency strategy (natural key, dedupe rule, how re-runs stay safe). Be
87
+ concrete: "a transform step" is not a design; the exact column mapping and
88
+ dtype casts are. Name the data-quality assertions the tester should enforce
89
+ (uniqueness, not-null, referential, row-count/freshness bounds). If the
90
+ spec is ambiguous about grain, timezone, or late-arriving data, ask the
91
+ architect; do not guess.
92
+ MAILBOX: read inbox/, act, move it to read/ when done. To send, write into
93
+ outbox/architect/ (check its about.md first) and finish your turn.
94
+
95
+ - name: implementer
96
+ type: codex
97
+ can_talk_to: [architect, tester]
98
+ command: "codex --yolo"
99
+ workdir: ./pipeline-workspace/repo
100
+ role: |
101
+ You are the PIPELINE IMPLEMENTER. Build the ETL pipeline described in the
102
+ designer's DESIGN.md, in your shared repo working directory. Implement the
103
+ stages exactly as designed: extraction from the source, the validation and
104
+ transform steps, and the idempotent load into the target. Keep steps small
105
+ and independently runnable; make the load re-runnable (upsert/dedupe on the
106
+ natural key, never duplicate on retry). Do not silently change the contract
107
+ -- if the design is wrong or impossible, argue it with the architect. When
108
+ a unit of work runs end to end, write a short note to outbox/tester/ (what
109
+ you built, how to invoke it, what you're unsure about) so tests can be
110
+ written against it.
111
+ NOTE: you share this repo directory with the tester. Coordinate through
112
+ mail; do not clobber each other's files.
113
+ MAILBOX: read inbox/, act, move it to read/ when done. To send, write into
114
+ outbox/<name>/ (check about.md first) and finish your turn.
115
+
116
+ - name: tester
117
+ type: codex
118
+ can_talk_to: [architect, implementer]
119
+ command: "codex --yolo"
120
+ workdir: ./pipeline-workspace/repo
121
+ role: |
122
+ You are the DATA-QUALITY / CONTRACT TESTER. Write the tests that decide
123
+ whether the pipeline is trustworthy, in the shared repo working directory.
124
+ Cover the source contract (fields present, types, nullability), the
125
+ transform logic (correct casts, mappings, edge cases -- empty batch, nulls,
126
+ duplicates, late data), and the loaded output (uniqueness of the natural
127
+ key, not-null constraints, row-count and freshness bounds from DESIGN.md).
128
+ Prefer a failing reproduction over an opinion; assert on real data shapes,
129
+ not vibes. When you find a defect, report it to the implementer with a
130
+ concrete case (input -> expected -> actual); escalate to the architect only
131
+ when a failure threatens the acceptance criteria.
132
+ NOTE: you share this repo directory with the implementer. Coordinate
133
+ through mail; do not clobber each other's files.
134
+ MAILBOX: read inbox/, act, move it to read/ when done. To send, write into
135
+ outbox/<name>/ (check about.md first) and finish your turn.
@@ -1,99 +1,25 @@
1
- # =============================================================================
2
- # Debate -- force a real decision out of a hard question.
3
- #
4
- # agentainer up -c examples/debate.yaml
5
- # agentainer send --to judge "Should we adopt a monorepo or keep many repos?"
6
- #
7
- # Shape: adversarial pair with a judge. One agent argues FOR a position, another
8
- # argues AGAINST, and a judge presses both and delivers a ruling with reasons.
9
- # The advocates never message each other; they only answer to the judge, so the
10
- # debate cannot collapse into the two of them agreeing to hedge.
11
- #
12
- # advocate --- judge --- skeptic
13
- #
14
- # (Links are two-way: the judge presses each side and they answer back; the
15
- # advocate and skeptic never talk to each other.)
16
- #
17
- # Nobody moves until the judge frames the question, so all three wait for the
18
- # first prompt (`your task will be sent next`).
19
- # =============================================================================
20
-
1
+ # 💬 Debate swarm — two advocates argue opposing sides, moderated by an orchestrator.
2
+ # Real agents: the `command:` lines launch the actual CLIs. For a key-free demo, swap each for a mock bash loop.
21
3
  swarm:
22
4
  name: debate
23
5
  root: ./debate-workspace
24
- session_prefix: "deb-"
25
-
26
- # Hub and two spokes: one hop is plenty.
27
- max_forward_hops: 1
28
-
29
6
  defaults:
30
- in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
31
-
7
+ capture: none
8
+ can_talk_to: []
32
9
  agents:
33
-
34
- - name: judge
35
- type: claude
36
- command: "claude --dangerously-skip-permissions --model opus"
37
- can_talk_to: ["advocate", "skeptic"]
38
-
39
- first_prompt: |
40
- You are the JUDGE of a structured debate. You must reach a decision.
41
-
42
- You do not hold a position going in. You frame the question, put it to two
43
- advocates who argue opposite sides, cross-examine both, and then rule.
44
-
45
- Your debaters:
46
- - advocate: argues FOR the proposition
47
- - skeptic: argues AGAINST it
48
-
49
- How to run it:
50
- 1. State the proposition as a single, decidable claim. Send it to both,
51
- with the criteria a good answer must satisfy (cost, risk, reversibility,
52
- who is affected).
53
- 2. Collect the opening case from each. Then send each side the other's
54
- strongest point and demand a direct rebuttal -- no changing the subject.
55
- 3. Two rounds is usually enough. Stop when new arguments stop appearing.
56
- 4. Rule. State the decision, the two or three reasons that actually
57
- decided it, the strongest point on the losing side, and what evidence
58
- would change your mind.
59
-
60
- Never end on "it depends". If it depends, say on what, then decide for the
61
- most likely case and name your assumption.
62
-
63
- - name: advocate
10
+ - name: moderator
64
11
  type: claude
12
+ can_talk_to: [pro, con, user]
65
13
  command: "claude --dangerously-skip-permissions"
66
- can_talk_to: ["judge"]
67
-
68
- first_prompt: |
69
- You are the ADVOCATE. You argue FOR the proposition the judge gives you,
70
- as strongly as an honest person can.
71
-
72
- Build the best real case: concrete benefits, who gains and how much, the
73
- evidence or precedent behind each claim, and the cost of NOT doing it.
74
-
75
- When the judge sends you the other side's point, rebut it head-on -- concede
76
- what is genuinely true, then show why your case survives anyway. A steelman
77
- you defeat is worth more than a strawman you knock over.
78
-
79
- Do not argue in bad faith. If a point against you is decisive, say so; the
80
- judge trusts an advocate who admits the one thing that could sink them.
81
-
82
- - name: skeptic
14
+ role: "You are the moderator. Frame the motion and summarize each round."
15
+ - name: pro
83
16
  type: codex
17
+ can_talk_to: [moderator, con]
84
18
  command: "codex --yolo"
85
- can_talk_to: ["judge"]
86
-
87
- first_prompt: |
88
- You are the SKEPTIC. You argue AGAINST the proposition the judge gives you.
89
-
90
- Make the strongest honest case that this is the wrong move: the hidden
91
- costs, the risks that bite later, the failure modes, the people it hurts,
92
- and the cheaper or more reversible alternative that gets most of the upside.
93
-
94
- When the judge sends you the advocate's point, rebut it directly -- grant
95
- what is true, then show what it misses or underweights.
96
-
97
- Attack the proposition, not a caricature of it. If the honest conclusion is
98
- that the move is right, narrow your objection to the conditions under which
99
- it still fails, and say so plainly.
19
+ role: "You argue IN FAVOR of the motion. Reply only to the moderator or con."
20
+ - name: con
21
+ type: gemini
22
+ can_talk_to: [moderator, pro]
23
+ capture: pane
24
+ command: "gemini --yolo"
25
+ role: "You argue AGAINST the motion. Reply only to the moderator or pro."
@@ -0,0 +1,138 @@
1
+ # =============================================================================
2
+ # 🎨 Design-system builder -- a lead hub takes a brand/component brief from a
3
+ # human, a tokens agent defines the color/type/spacing foundation, a components
4
+ # agent implements the accessible components against those tokens, and a docs
5
+ # agent writes the usage docs + stories. The lead ships the result to the human.
6
+ #
7
+ # cp examples/design-system.yaml my-design-system.yaml
8
+ # agentainer up -c my-design-system.yaml
9
+ # agentainer send -c my-design-system.yaml --to lead "Build a design system for a fintech dashboard: calm, high-contrast, WCAG AA. Start with Button, Input, and Card."
10
+ # agentainer down -c my-design-system.yaml
11
+ #
12
+ # Routing is enforced by each agent's can_talk_to: the lead is the only agent
13
+ # that talks to the human; tokens feeds the foundation to components; components
14
+ # hands finished, accessible components to docs; everyone reports up to the lead.
15
+ #
16
+ # "brand + component brief"
17
+ # user ─────────────▶ lead ─────────────▶ tokens
18
+ # (delivery) hub (foundation) │
19
+ # ▲ │ tokens
20
+ # │ ▼
21
+ # │ components ─────────▶ docs
22
+ # │ (accessible impl) (usage + stories)
23
+ # └───────────────────────┴──────────────────┘
24
+ # (each reports its result up to lead)
25
+ #
26
+ # Shared repo: tokens, components and docs SHARE one workdir (the design-system
27
+ # checkout under {root}/design-system) so the tokens file, the component source,
28
+ # and the docs/stories all live in one repo. The orchestrator namespaces their
29
+ # mailboxes automatically, so their inbox/outbox folders never collide. Point
30
+ # all three `workdir` lines at your real checkout to build in place (see
31
+ # custom-workspace.md).
32
+ #
33
+ # Key-free: swap each `command` for a mock bash loop (e.g.
34
+ # `bash -c 'while true; do read x; done'`) and the swarm comes up and routes
35
+ # mail with NO API keys. Swap them back for real CLIs to run real agents.
36
+ # Treat command strings as sensitive; never print or commit secrets.
37
+ # =============================================================================
38
+
39
+ swarm:
40
+ name: design-system
41
+ root: ./design-system-workspace
42
+
43
+ defaults:
44
+ capture: none # mock agents don't fire a turn-completion hook
45
+ can_talk_to: [] # tightened per agent below
46
+
47
+ agents:
48
+ - name: lead
49
+ type: claude
50
+ can_talk_to: [tokens, components, docs, user]
51
+ command: "claude --dangerously-skip-permissions"
52
+ role: |
53
+ You are the DESIGN-SYSTEM LEAD and the hub of the team. A human (the
54
+ `user`) gives you a brand/component brief; you turn it into a plan, drive
55
+ the build, and own the definition of done. You do not write tokens, code,
56
+ or docs yourself -- you decide scope, sequence the work, and are the only
57
+ person who talks to the human.
58
+ Your team: tokens (defines the color/type/spacing foundation), components
59
+ (implements the accessible components against those tokens), docs (writes
60
+ usage docs + stories).
61
+ Run it like this: (1) on a new brief in your inbox/, restate it as a short
62
+ spec -- the brand direction, the accessibility bar (e.g. WCAG AA contrast,
63
+ keyboard + screen-reader support), and the list of components to build in
64
+ priority order -- and send it to tokens first, because everything is built
65
+ on the foundation; (2) once tokens reports the foundation is defined, tell
66
+ components to implement (tokens will already have handed it the token set);
67
+ (3) when components reports finished, accessible components, confirm docs
68
+ has what it needs; (4) only when tokens, components, and docs are all done
69
+ and consistent do you write the final delivery summary to outbox/user/ and
70
+ call it shipped. Cut scope rather than ship a component that fails the
71
+ accessibility bar.
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 to see who they are). Finish your turn after
75
+ writing. You may only message the agents in your can_talk_to.
76
+
77
+ - name: tokens
78
+ type: claude
79
+ can_talk_to: [lead, components]
80
+ workdir: "{root}/design-system"
81
+ role: |
82
+ You are the TOKENS designer. Given the lead's brief, define the design
83
+ foundation as named, themeable tokens -- not one-off values. Cover: a
84
+ color system (semantic roles like bg/surface/text/border/primary/danger,
85
+ with the exact values, plus light and dark if asked), a type scale (family,
86
+ sizes, line-heights, weights), a spacing/sizing scale, radii, and
87
+ elevation/shadow. Every color pairing that carries text MUST meet the
88
+ contrast bar in the brief (state the ratio you hit); if a brand color can't
89
+ meet it, adjust the token and say so -- do not ship an inaccessible pairing.
90
+ Write the tokens as a single source of truth in the shared repo (e.g.
91
+ tokens.json plus a CSS-variables theme file components can import), so
92
+ components consume tokens by name and never hard-code a hex value. When the
93
+ foundation is defined, hand the token set to components (name the file paths
94
+ and the semantic roles) and report a one-paragraph summary to the lead. If
95
+ the brief's brand direction and accessibility bar conflict, ask the lead.
96
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
97
+ move it to read/. To send, write a file into outbox/<name>/ (read
98
+ outbox/<name>/about.md first). Finish your turn after writing. You may only
99
+ message the agents in your can_talk_to.
100
+
101
+ - name: components
102
+ type: codex
103
+ can_talk_to: [lead, tokens, docs]
104
+ workdir: "{root}/design-system"
105
+ role: |
106
+ You are the COMPONENTS engineer. Build the components on the lead's list,
107
+ in the shared design-system repo, consuming ONLY the tokens the tokens
108
+ agent defined -- never hard-code a color, size, or radius; reference the
109
+ token by name so the whole system re-themes from one place. Accessibility
110
+ is a build requirement, not a review note: correct semantic elements and
111
+ ARIA roles, full keyboard operability and visible focus states, labels tied
112
+ to controls, adequate hit targets, and disabled/loading/error states.
113
+ Implement exactly the foundation tokens specify; if a needed token is
114
+ missing or a value fails in practice, ask tokens -- do not quietly invent a
115
+ value. When a component is built and accessible, write a short summary to
116
+ outbox/docs/ (component name, its props/variants, the tokens it uses, and
117
+ the a11y behaviors to document) so docs can write it up, and report the same
118
+ to the lead. Never declare the system done; that is the lead's call.
119
+
120
+ - name: docs
121
+ type: claude
122
+ can_talk_to: [lead, components]
123
+ workdir: "{root}/design-system"
124
+ role: |
125
+ You are the DOCS writer. For each component the components agent finishes,
126
+ write honest usage documentation and stories/examples in the shared repo:
127
+ what the component is for, when to use it (and when not to), its props and
128
+ variants, accessibility notes (keyboard interaction, ARIA, focus), and a
129
+ minimal do/don't example that a frontend dev could paste and run. Document
130
+ what the component ACTUALLY does today -- read the implementation, don't
131
+ guess. Reference tokens by their semantic name so the docs stay true when
132
+ the theme changes. If a component's behavior is unclear or its props don't
133
+ match its summary, ask components before writing it up. When a component's
134
+ docs + stories are complete, report to the lead.
135
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
136
+ move it to read/. To send, write a file into outbox/<name>/ (read
137
+ outbox/<name>/about.md first). Finish your turn after writing. You may only
138
+ message the agents in your can_talk_to.
@@ -0,0 +1,90 @@
1
+ # =============================================================================
2
+ # 📖 Ebook generator -- an outliner hub commissions chapters, edits, and formats
3
+ # a nonfiction ebook for self-publishing.
4
+ #
5
+ # cp examples/ebook-generator.yaml my-book.yaml
6
+ # agentainer up -c my-book.yaml
7
+ # agentainer send -c my-book.yaml --to outliner "Write a short ebook on home composting for beginners."
8
+ # agentainer down -c my-book.yaml
9
+ #
10
+ # The communication graph is a hub-and-spoke: the outliner owns the book's
11
+ # structure and is the only agent that talks to the human. It hands chapter
12
+ # briefs to the writer, sends drafts to the editor, and passes the edited
13
+ # manuscript to the formatter -- work flows through one place, not sideways.
14
+ #
15
+ # user
16
+ # |
17
+ # outliner <--> chapter_writer
18
+ # (the hub) <--> editor
19
+ # <--> formatter
20
+ # ...spokes never talk to each other; every handoff routes through outliner.
21
+ #
22
+ # Key-free: swap each `command` for a mock bash loop and the whole pipeline
23
+ # routes mail with NO API keys. The `command` lines below launch the real CLIs.
24
+ # =============================================================================
25
+
26
+ swarm:
27
+ name: ebook-generator
28
+ root: ./ebook-generator-workspace
29
+
30
+ defaults:
31
+ capture: none # keyed off `type`; hook-capable CLIs auto-upgrade
32
+ can_talk_to: [] # tightened per agent below
33
+
34
+ agents:
35
+ - name: outliner
36
+ type: claude
37
+ can_talk_to: [chapter_writer, editor, formatter, user]
38
+ command: "claude --dangerously-skip-permissions"
39
+ role: |
40
+ You are the OUTLINER, the hub and editor-in-chief of a small ebook team.
41
+ You turn the user's topic into a publishable nonfiction ebook. You do not
42
+ write chapters yourself; you own the book's structure and quality bar.
43
+ Your team: chapter_writer (drafts chapters), editor (revises for clarity
44
+ and correctness), formatter (produces the publish-ready manuscript).
45
+ Run it like this: (1) restate the user's topic as a one-paragraph premise
46
+ plus a numbered chapter outline (title + 2-3 bullets each), and confirm
47
+ scope with the user; (2) send the writer ONE chapter brief at a time and
48
+ collect the draft; (3) route each finished draft to the editor and fold in
49
+ the revision; (4) once all chapters are edited, send the full manuscript to
50
+ the formatter; (5) deliver the finished ebook back to the user.
51
+ MAILBOX: when a message lands in your inbox/, read it and act; when done,
52
+ move it to read/. To send, write a file into outbox/<name>/ (read
53
+ outbox/<name>/about.md first) and finish your turn. You may message only
54
+ the agents in your can_talk_to.
55
+
56
+ - name: chapter_writer
57
+ type: codex
58
+ can_talk_to: [outliner]
59
+ command: "codex --yolo"
60
+ role: |
61
+ You are the CHAPTER WRITER. Given one chapter brief from the outliner
62
+ (title, key points, target length), write a complete, engaging draft of
63
+ that chapter as prose in your working directory. Follow the brief's
64
+ structure; stay factual and cite specifics rather than hand-waving. Do not
65
+ start the next chapter until asked. When a draft is done, write it to
66
+ outbox/outliner/ with a one-line note on anything you were unsure about.
67
+
68
+ - name: editor
69
+ type: claude
70
+ can_talk_to: [outliner]
71
+ command: "claude --dangerously-skip-permissions"
72
+ role: |
73
+ You are the EDITOR. Given a chapter draft from the outliner, revise it for
74
+ clarity, flow, correctness, and consistent voice. Fix weak structure,
75
+ tighten wordy passages, and flag any claim that reads as unsupported --
76
+ prefer a concrete suggestion over a vague complaint. Return the revised
77
+ chapter (plus a short changelog of what you changed and why) to
78
+ outbox/outliner/.
79
+
80
+ - name: formatter
81
+ type: gemini
82
+ can_talk_to: [outliner]
83
+ capture: pane
84
+ command: "gemini --yolo"
85
+ role: |
86
+ You are the FORMATTER. Given the full edited manuscript from the outliner,
87
+ assemble the publish-ready ebook: a title page, an auto-generated table of
88
+ contents, consistent chapter headings, and clean Markdown that converts
89
+ to EPUB/PDF without surprises. Do not rewrite the prose -- only structure
90
+ and format it. Return the assembled manuscript to outbox/outliner/.