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.
- package/README.md +248 -677
- package/agentainer +16 -18
- package/agentainer.example.yaml +86 -0
- package/bin/agentainer.js +9 -8
- package/examples/academic-coauthor.yaml +123 -0
- package/examples/accessibility-audit.yaml +152 -0
- package/examples/affiliate-product-reviews.yaml +106 -0
- package/examples/api-design.yaml +157 -0
- package/examples/app-store-optimization.yaml +108 -0
- package/examples/brainstorm.yaml +27 -128
- package/examples/brand-voice-style-guide.yaml +109 -0
- package/examples/bug-hunt.yaml +51 -96
- package/examples/candidate-screen.yaml +122 -0
- package/examples/case-study-writer.yaml +100 -0
- package/examples/changelog-release-notes.yaml +114 -0
- package/examples/chatbot-builder.yaml +138 -0
- package/examples/code-review.yaml +73 -0
- package/examples/comparison-guide-writer.yaml +106 -0
- package/examples/competitive-intel.yaml +126 -0
- package/examples/content-studio.yaml +91 -0
- package/examples/course-creator.yaml +133 -0
- package/examples/customer-support-triage.yaml +118 -0
- package/examples/daily-briefing.yaml +119 -0
- package/examples/data-pipeline-builder.yaml +135 -0
- package/examples/debate.yaml +16 -90
- package/examples/design-system.yaml +138 -0
- package/examples/ebook-generator.yaml +90 -0
- package/examples/ecommerce-listing-optimizer.yaml +126 -0
- package/examples/email-newsletter.yaml +103 -0
- package/examples/faq-knowledge-sync.yaml +107 -0
- package/examples/game-design.yaml +122 -0
- package/examples/glossary-term-writer.yaml +103 -0
- package/examples/incident-response.yaml +52 -109
- package/examples/knowledge-base.yaml +115 -0
- package/examples/landing-page-converter.yaml +103 -0
- package/examples/legal-contract-review.yaml +118 -0
- package/examples/linkedin-ghostwriter.yaml +93 -0
- package/examples/localization.yaml +56 -123
- package/examples/meeting-notes.yaml +111 -0
- package/examples/migration-planner.yaml +127 -0
- package/examples/onboarding-buddy.yaml +111 -0
- package/examples/performance-audit.yaml +123 -0
- package/examples/podcast-production.yaml +117 -0
- package/examples/postmortem.yaml +119 -0
- package/examples/pr-review-gate.yaml +123 -0
- package/examples/press-release-wire.yaml +96 -0
- package/examples/product-spec.yaml +107 -0
- package/examples/prompt-engineering-lab.yaml +109 -0
- package/examples/quickstart.yaml +48 -0
- package/examples/rag-builder.yaml +145 -0
- package/examples/refactor-planner.yaml +127 -0
- package/examples/research.yaml +25 -0
- package/examples/resume-tailor.yaml +116 -0
- package/examples/rfp-response.yaml +124 -0
- package/examples/sales-coach.yaml +123 -0
- package/examples/security-audit.yaml +120 -0
- package/examples/seo-audit-and-fix.yaml +138 -0
- package/examples/seo-content-factory.yaml +103 -0
- package/examples/social-media.yaml +103 -0
- package/examples/software-company.yaml +71 -128
- package/examples/startup-validator.yaml +115 -0
- package/examples/tdd-pingpong.yaml +36 -68
- package/examples/technical-documentation.yaml +112 -0
- package/examples/test-factory.yaml +114 -0
- package/examples/tutorial-howto-creator.yaml +111 -0
- package/examples/twitter-x-thread-factory.yaml +91 -0
- package/examples/white-paper-research.yaml +96 -0
- package/examples/writers-room.yaml +49 -111
- package/examples/youtube-script-studio.yaml +107 -0
- package/hooks/claude_stop.sh +5 -3
- package/hooks/codex_notify.sh +4 -3
- package/lib/cli.py +933 -0
- package/lib/config.py +267 -308
- package/lib/hooks.py +246 -0
- package/lib/lock.py +75 -0
- package/lib/log.py +64 -0
- package/lib/mail.py +699 -0
- package/lib/minyaml.py +1 -39
- package/lib/reconcile.py +544 -0
- package/lib/sessions.py +223 -0
- package/lib/supervisor.py +216 -0
- package/lib/telegram.py +372 -0
- package/lib/tmux.py +355 -0
- package/lib/turn.py +167 -0
- package/lib/ui.py +1219 -0
- package/llms.txt +145 -429
- package/package.json +9 -7
- package/scripts/check-deps.js +18 -61
- package/ui/app.js +1136 -0
- package/ui/index.html +404 -0
- package/agents.example.yaml +0 -257
- package/examples/code-review-broadcast.yaml +0 -109
- package/examples/existing-repo.yaml +0 -74
- package/examples/multi-language-broadcast.yaml +0 -127
- package/examples/ping-pong.yaml +0 -89
- package/examples/red-team.yaml +0 -117
- package/examples/research-swarm.yaml +0 -129
- package/lib/swarm.py +0 -2461
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# Code review by broadcast -- one PR, several specialist lenses at once.
|
|
3
|
-
#
|
|
4
|
-
# 1. agentainer validate -c examples/code-review-broadcast.yaml
|
|
5
|
-
# 2. agentainer up -c examples/code-review-broadcast.yaml
|
|
6
|
-
# 3. agentainer send --to coordinator "Review PR #42 (git diff main...HEAD)."
|
|
7
|
-
#
|
|
8
|
-
# Shape: a hub built on `broadcast`. The COORDINATOR fans the diff out to
|
|
9
|
-
# every reviewer in one message; each REVIEWER owns one concern (correctness,
|
|
10
|
-
# security, performance) and reports back to the coordinator, who synthesizes a
|
|
11
|
-
# single review. The reviewers never talk to each other -- cross-cutting findings
|
|
12
|
-
# are the coordinator's job to merge.
|
|
13
|
-
#
|
|
14
|
-
# coordinator
|
|
15
|
-
# | (broadcast the PR to all)
|
|
16
|
-
# v
|
|
17
|
-
# +-------+--------+
|
|
18
|
-
# | | |
|
|
19
|
-
# correctness security perf
|
|
20
|
-
# | | |
|
|
21
|
-
# +--- coordinator ---+ (each reviewer replies to the coordinator)
|
|
22
|
-
#
|
|
23
|
-
# `broadcast` is the point of the example: the coordinator reaches several
|
|
24
|
-
# peers with one message and does not care which are mid-task. Every link is
|
|
25
|
-
# two-way. The change under review is passed in the prompt, so the swarm
|
|
26
|
-
# validates and runs without pointing at any repo.
|
|
27
|
-
# =============================================================================
|
|
28
|
-
|
|
29
|
-
swarm:
|
|
30
|
-
name: review
|
|
31
|
-
root: ./review-runtime # only holds logs, inboxes and swarm state
|
|
32
|
-
session_prefix: "rv-"
|
|
33
|
-
|
|
34
|
-
# Broadcasts don't auto-forward, so one hop is all the guard ever needs.
|
|
35
|
-
max_forward_hops: 1
|
|
36
|
-
|
|
37
|
-
# Each agent gets its own scratch folder under `root` for logs and state.
|
|
38
|
-
# The change under review is passed in the prompt (a `git diff`), so the agents
|
|
39
|
-
# never need to read a repo off disk -- point `workdir` here only if you want
|
|
40
|
-
# them to read the tree directly.
|
|
41
|
-
create_workdirs: true
|
|
42
|
-
|
|
43
|
-
agents:
|
|
44
|
-
|
|
45
|
-
- name: coordinator
|
|
46
|
-
type: claude
|
|
47
|
-
command: "claude --dangerously-skip-permissions --model opus"
|
|
48
|
-
can_talk_to: ["correctness", "security", "perf"]
|
|
49
|
-
|
|
50
|
-
in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
|
|
51
|
-
|
|
52
|
-
first_prompt: |
|
|
53
|
-
You are the REVIEW COORDINATOR. You do not review code yourself; you run
|
|
54
|
-
the review and merge the findings.
|
|
55
|
-
|
|
56
|
-
When the human gives you a change (a PR or a `git diff`), broadcast it to
|
|
57
|
-
every reviewer at once, each with the one concern they own:
|
|
58
|
-
|
|
59
|
-
<swarm-broadcast>
|
|
60
|
-
Review this change (PR #42, git diff main...HEAD):
|
|
61
|
-
- correctness: does it do what it claims? logic, edge cases, regressions
|
|
62
|
-
- security: injection, authz, secrets, unsafe deserialization
|
|
63
|
-
- perf: hot paths, N+1s, allocations, unbounded growth
|
|
64
|
-
Reply to me (the coordinator) with findings only for your lane.
|
|
65
|
-
</swarm-broadcast>
|
|
66
|
-
|
|
67
|
-
Collect the three replies. Merge overlapping findings, dedupe, and rank by
|
|
68
|
-
severity. Produce ONE consolidated review: a short verdict (Approve / Request
|
|
69
|
-
changes) followed by a bullet list of findings with file:line and the lane
|
|
70
|
-
that raised each. Do not invent findings the reviewers did not make.
|
|
71
|
-
|
|
72
|
-
- name: correctness
|
|
73
|
-
type: claude
|
|
74
|
-
command: "claude --dangerously-skip-permissions"
|
|
75
|
-
can_talk_to: ["coordinator"]
|
|
76
|
-
first_prompt: |
|
|
77
|
-
You are the CORRECTNESS reviewer. You receive a change broadcast by the
|
|
78
|
-
coordinator; review ONLY whether it does what it claims.
|
|
79
|
-
|
|
80
|
-
Look for: logic errors, off-by-one and boundary mistakes, wrong types or
|
|
81
|
-
null handling, missing or wrong edge-case handling, and silent regressions
|
|
82
|
-
in behaviour. Quote the offending line. When done, reply to the coordinator
|
|
83
|
-
with findings for this lane only -- nothing about security or performance.
|
|
84
|
-
|
|
85
|
-
- name: security
|
|
86
|
-
type: claude
|
|
87
|
-
command: "claude --dangerously-skip-permissions"
|
|
88
|
-
can_talk_to: ["coordinator"]
|
|
89
|
-
first_prompt: |
|
|
90
|
-
You are the SECURITY reviewer. You receive a change broadcast by the
|
|
91
|
-
coordinator; review ONLY for security risk.
|
|
92
|
-
|
|
93
|
-
Look for: injection (SQL/command/HTML), broken or missing authz, secrets
|
|
94
|
-
committed or logged, unsafe deserialization, path traversal, and trust of
|
|
95
|
-
unvalidated input. Quote the offending line and the abuse scenario. When done,
|
|
96
|
-
reply to the coordinator with findings for this lane only.
|
|
97
|
-
|
|
98
|
-
- name: perf
|
|
99
|
-
type: codex
|
|
100
|
-
command: "codex --yolo"
|
|
101
|
-
can_talk_to: ["coordinator"]
|
|
102
|
-
first_prompt: |
|
|
103
|
-
You are the PERFORMANCE reviewer. You receive a change broadcast by the
|
|
104
|
-
coordinator; review ONLY for performance.
|
|
105
|
-
|
|
106
|
-
Look for: accidental O(n^2) or N+1 patterns, allocations in hot loops,
|
|
107
|
-
unbounded growth (caches, lists), missing batching or indexes, and blocking
|
|
108
|
-
calls on the request path. Quote the offending line and the expected cost.
|
|
109
|
-
When done, reply to the coordinator with findings for this lane only.
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# Pair programming on a repository you already have.
|
|
3
|
-
#
|
|
4
|
-
# This example does NOT create any folders. Both agents are started inside one
|
|
5
|
-
# existing checkout, so they see each other's edits immediately -- a driver who
|
|
6
|
-
# writes the code and a navigator who reads it as it lands.
|
|
7
|
-
#
|
|
8
|
-
# driver <--> navigator (a two-way pair sharing one checkout)
|
|
9
|
-
#
|
|
10
|
-
# 1. Point `workdir` below at a real repository.
|
|
11
|
-
# 2. agentainer validate -c examples/existing-repo.yaml
|
|
12
|
-
# 3. agentainer up -c examples/existing-repo.yaml
|
|
13
|
-
# 4. agentainer send --to driver "Add retry-with-backoff to the HTTP client."
|
|
14
|
-
#
|
|
15
|
-
# Until you edit the paths, `validate` will refuse to run and tell you so --
|
|
16
|
-
# that is the point of `create_workdir: false`.
|
|
17
|
-
# =============================================================================
|
|
18
|
-
|
|
19
|
-
swarm:
|
|
20
|
-
name: pair
|
|
21
|
-
root: ./pair-runtime # only holds logs, inboxes and swarm state
|
|
22
|
-
session_prefix: "pair-"
|
|
23
|
-
|
|
24
|
-
# Never silently mkdir a path the user typed. If it does not exist, that is a
|
|
25
|
-
# typo, not an instruction to create it.
|
|
26
|
-
create_workdirs: false
|
|
27
|
-
|
|
28
|
-
defaults:
|
|
29
|
-
# Both agents share one checkout. Every agent inherits this unless it
|
|
30
|
-
# overrides `workdir` itself.
|
|
31
|
-
#
|
|
32
|
-
# >>> EDIT ME <<<
|
|
33
|
-
workdir: ~/projects/acme-api
|
|
34
|
-
|
|
35
|
-
agents:
|
|
36
|
-
|
|
37
|
-
- name: driver
|
|
38
|
-
type: claude
|
|
39
|
-
command: "claude --dangerously-skip-permissions"
|
|
40
|
-
can_talk_to: ["navigator"]
|
|
41
|
-
|
|
42
|
-
first_prompt: |
|
|
43
|
-
You are the DRIVER in a pairing session. You have the keyboard.
|
|
44
|
-
|
|
45
|
-
You are working in a real repository that someone cares about. Before you
|
|
46
|
-
change anything, read enough of it to match its conventions.
|
|
47
|
-
|
|
48
|
-
Working agreement:
|
|
49
|
-
- Make one coherent change at a time, then tell the navigator what you
|
|
50
|
-
did and why, so they can review it while you continue.
|
|
51
|
-
- Run the tests before you claim something works. Paste real output.
|
|
52
|
-
- Never commit, push, or rewrite git history unless explicitly asked.
|
|
53
|
-
- If the navigator finds a real bug, fix it before moving on.
|
|
54
|
-
|
|
55
|
-
- name: navigator
|
|
56
|
-
type: codex
|
|
57
|
-
command: "codex --yolo"
|
|
58
|
-
can_talk_to: ["driver"]
|
|
59
|
-
|
|
60
|
-
first_prompt: |
|
|
61
|
-
You are the NAVIGATOR in a pairing session. You do not have the keyboard.
|
|
62
|
-
|
|
63
|
-
You read what the driver writes, in the same working tree, and you think
|
|
64
|
-
one step ahead of them. Do not edit files -- your job is to catch what
|
|
65
|
-
they cannot see while typing.
|
|
66
|
-
|
|
67
|
-
Watch for:
|
|
68
|
-
- logic that is wrong on an edge case the tests do not cover
|
|
69
|
-
- error paths that swallow failures
|
|
70
|
-
- a change that breaks an existing caller elsewhere in the repo
|
|
71
|
-
- drifting away from how the rest of this codebase does things
|
|
72
|
-
|
|
73
|
-
Report findings to the driver, citing file:line, with the concrete input
|
|
74
|
-
that goes wrong. If a change looks correct, say so briefly and move on.
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# Multi-language broadcast -- one source, several translations in parallel.
|
|
3
|
-
#
|
|
4
|
-
# agentainer up -c examples/multi-language-broadcast.yaml
|
|
5
|
-
# agentainer send --to translator "Translate ./docs/quickstart.md to es, fr, de."
|
|
6
|
-
#
|
|
7
|
-
# Shape: a fan-out built on `broadcast`, not `forward_responses_to`. One
|
|
8
|
-
# TRANSLATOR holds the source and fans it out to every reviewer at once; the
|
|
9
|
-
# REVIEWERS each own one language and report back to a single CONSOLIDATOR,
|
|
10
|
-
# who compiles the finished set and broadcasts it back to the translator.
|
|
11
|
-
#
|
|
12
|
-
# translator
|
|
13
|
-
# | (broadcast source to all)
|
|
14
|
-
# v
|
|
15
|
-
# +-------+--------+
|
|
16
|
-
# | | |
|
|
17
|
-
# es-rev fr-rev de-rev
|
|
18
|
-
# | | |
|
|
19
|
-
# +--- consolidator ---+ (each reviewer replies to the consolidator)
|
|
20
|
-
# |
|
|
21
|
-
# translator (consolidator broadcasts the compiled piece back)
|
|
22
|
-
#
|
|
23
|
-
# `broadcast` is the point of this example: the translator reaches several
|
|
24
|
-
# peers with one message and does not care who is busy. Every link is two-way,
|
|
25
|
-
# and the reviewers never talk to each other -- all coordination runs through
|
|
26
|
-
# the translator and the consolidator.
|
|
27
|
-
# =============================================================================
|
|
28
|
-
|
|
29
|
-
swarm:
|
|
30
|
-
name: l10n-multi
|
|
31
|
-
root: ./l10n-multi-workspace
|
|
32
|
-
session_prefix: "ml-"
|
|
33
|
-
|
|
34
|
-
# Broadcasts don't auto-forward, so one hop is all the guard ever needs.
|
|
35
|
-
max_forward_hops: 1
|
|
36
|
-
|
|
37
|
-
agents:
|
|
38
|
-
|
|
39
|
-
- name: translator
|
|
40
|
-
type: claude
|
|
41
|
-
command: "claude --dangerously-skip-permissions"
|
|
42
|
-
|
|
43
|
-
# Can reach everyone: broadcasts the source out, and receives the compiled
|
|
44
|
-
# piece back from the consolidator.
|
|
45
|
-
can_talk_to: ["es-rev", "fr-rev", "de-rev", "consolidator"]
|
|
46
|
-
|
|
47
|
-
first_prompt: |
|
|
48
|
-
You are the TRANSLATOR and keeper of the source. You start each job with
|
|
49
|
-
one source document and a list of target languages.
|
|
50
|
-
|
|
51
|
-
Produce a single faithful, natural rendering of the source per language, as a
|
|
52
|
-
native writer would actually say it -- not a word-for-word transposition.
|
|
53
|
-
Preserve exactly: meaning and tone, markup, code blocks, and placeholders
|
|
54
|
-
like {name} or %s.
|
|
55
|
-
|
|
56
|
-
Then fan it out: broadcast the source text to every reviewer at once so they
|
|
57
|
-
each translate their own language in parallel. Use:
|
|
58
|
-
|
|
59
|
-
<swarm-broadcast>
|
|
60
|
-
Source (English):
|
|
61
|
-
...
|
|
62
|
-
Translate to your language only. es-rev -> Spanish, fr-rev -> French,
|
|
63
|
-
de-rev -> German.
|
|
64
|
-
</swarm-broadcast>
|
|
65
|
-
|
|
66
|
-
Wait for the consolidator to return the compiled set, then save each
|
|
67
|
-
language next to the source (e.g. quickstart.es.md) and finish.
|
|
68
|
-
|
|
69
|
-
- name: es-rev
|
|
70
|
-
type: claude
|
|
71
|
-
command: "claude --dangerously-skip-permissions"
|
|
72
|
-
can_talk_to: ["consolidator", "translator"]
|
|
73
|
-
first_prompt: |
|
|
74
|
-
You are the SPANISH reviewer. You receive a source text broadcast by the
|
|
75
|
-
translator and return a faithful, natural Spanish translation of it.
|
|
76
|
-
|
|
77
|
-
Preserve meaning, tone, markup, code blocks and placeholders exactly. Read
|
|
78
|
-
naturally; if the source language shows through, fix it. When done, reply to
|
|
79
|
-
the consolidator (not the group) with your Spanish text and any term you
|
|
80
|
-
deliberately did not translate and why.
|
|
81
|
-
|
|
82
|
-
- name: fr-rev
|
|
83
|
-
type: claude
|
|
84
|
-
command: "claude --dangerously-skip-permissions"
|
|
85
|
-
can_talk_to: ["consolidator", "translator"]
|
|
86
|
-
first_prompt: |
|
|
87
|
-
You are the FRENCH reviewer. You receive a source text broadcast by the
|
|
88
|
-
translator and return a faithful, natural French translation of it.
|
|
89
|
-
|
|
90
|
-
Preserve meaning, tone, markup, code blocks and placeholders exactly. Read
|
|
91
|
-
naturally; if the source language shows through, fix it. When done, reply to
|
|
92
|
-
the consolidator (not the group) with your French text and any term you
|
|
93
|
-
deliberately did not translate and why.
|
|
94
|
-
|
|
95
|
-
- name: de-rev
|
|
96
|
-
type: claude
|
|
97
|
-
command: "claude --dangerously-skip-permissions"
|
|
98
|
-
can_talk_to: ["consolidator", "translator"]
|
|
99
|
-
first_prompt: |
|
|
100
|
-
You are the GERMAN reviewer. You receive a source text broadcast by the
|
|
101
|
-
translator and return a faithful, natural German translation of it.
|
|
102
|
-
|
|
103
|
-
Preserve meaning, tone, markup, code blocks and placeholders exactly. Read
|
|
104
|
-
naturally; if the source language shows through, fix it. When done, reply to
|
|
105
|
-
the consolidator (not the group) with your German text and any term you
|
|
106
|
-
deliberately did not translate and why.
|
|
107
|
-
|
|
108
|
-
- name: consolidator
|
|
109
|
-
type: claude
|
|
110
|
-
command: "claude --dangerously-skip-permissions"
|
|
111
|
-
can_talk_to: ["translator", "es-rev", "fr-rev", "de-rev"]
|
|
112
|
-
first_prompt: |
|
|
113
|
-
You are the CONSOLIDATOR. You collect one translation per language from the
|
|
114
|
-
reviewers and assemble the finished set.
|
|
115
|
-
|
|
116
|
-
You will receive several replies -- keep them straight by language. Compile
|
|
117
|
-
them into one message that lists each language's text. When the set is
|
|
118
|
-
complete, broadcast it back to the translator so they can save the files:
|
|
119
|
-
|
|
120
|
-
<swarm-broadcast>
|
|
121
|
-
Compiled translations:
|
|
122
|
-
Spanish: ...
|
|
123
|
-
French: ...
|
|
124
|
-
German: ...
|
|
125
|
-
</swarm-broadcast>
|
|
126
|
-
|
|
127
|
-
Do not edit the translations; your job is to gather, not to re-translate.
|
package/examples/ping-pong.yaml
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# Ping-pong -- two agents trade a unit of work back and forth, in turn.
|
|
3
|
-
#
|
|
4
|
-
# 1. Point `workdir` below at the repo you want to build in.
|
|
5
|
-
# 2. agentainer validate -c examples/ping-pong.yaml
|
|
6
|
-
# 3. agentainer up -c examples/ping-pong.yaml
|
|
7
|
-
# 4. agentainer send --to runner "Build a rate limiter: N requests per window."
|
|
8
|
-
#
|
|
9
|
-
# Shape: a round-robin built on BROADCAST. This is deliberately different from
|
|
10
|
-
# tdd-pingpong.yaml, which uses `forward_responses_to` (one fixed next step):
|
|
11
|
-
# here every handoff is a broadcast that names who is up next, so the same
|
|
12
|
-
# group can rotate any number of roles in any order.
|
|
13
|
-
#
|
|
14
|
-
# runner <--> coder
|
|
15
|
-
# (each broadcasts to the group, naming the next agent in the @-tag)
|
|
16
|
-
#
|
|
17
|
-
# They share ONE checkout on purpose (that is the whole game), so `validate`
|
|
18
|
-
# will warn about the shared workdir -- expected here. The protocol, not a
|
|
19
|
-
# folder boundary, keeps them from colliding: only one holds the ball at a time.
|
|
20
|
-
# =============================================================================
|
|
21
|
-
|
|
22
|
-
swarm:
|
|
23
|
-
name: pingpong
|
|
24
|
-
root: ./pingpong-runtime # only holds logs, inboxes and swarm state
|
|
25
|
-
session_prefix: "pp-"
|
|
26
|
-
|
|
27
|
-
# Broadcasts don't auto-forward, so one hop is all the guard ever needs.
|
|
28
|
-
max_forward_hops: 1
|
|
29
|
-
|
|
30
|
-
# Never mkdir a path you typed by mistake; point at a real repo instead.
|
|
31
|
-
create_workdirs: false
|
|
32
|
-
|
|
33
|
-
defaults:
|
|
34
|
-
# Both agents build in the same tree. >>> EDIT ME <<<
|
|
35
|
-
workdir: ~/projects/scratch-lib
|
|
36
|
-
|
|
37
|
-
type: claude
|
|
38
|
-
command: "claude --dangerously-skip-permissions"
|
|
39
|
-
# They can each reach the other, so either can broadcast the handoff.
|
|
40
|
-
can_talk_to: ["runner", "coder"]
|
|
41
|
-
|
|
42
|
-
agents:
|
|
43
|
-
|
|
44
|
-
- name: runner
|
|
45
|
-
# Override: the runner starts the job and holds the spec.
|
|
46
|
-
command: "claude --dangerously-skip-permissions"
|
|
47
|
-
can_talk_to: ["coder"]
|
|
48
|
-
|
|
49
|
-
in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
|
|
50
|
-
|
|
51
|
-
first_prompt: |
|
|
52
|
-
You are the RUNNER. You own the task and the spec; the CODER implements
|
|
53
|
-
it. You two trade the work back and forth, exactly one of you active at a
|
|
54
|
-
time.
|
|
55
|
-
|
|
56
|
-
To hand off, broadcast to the group but name the coder explicitly as up
|
|
57
|
-
next, and sign your turn so the other agent knows who just spoke:
|
|
58
|
-
|
|
59
|
-
<swarm-broadcast>
|
|
60
|
-
@coder: your turn. Implement step 1 -- a token bucket with N
|
|
61
|
-
requests per window and a refill rate. Don't exceed the spec.
|
|
62
|
-
-- runner
|
|
63
|
-
</swarm-broadcast>
|
|
64
|
-
|
|
65
|
-
When the coder hands back ("@runner: your turn -- done, here's what I
|
|
66
|
-
built"), review it against the spec. If it meets the bar, broadcast a
|
|
67
|
-
final "done" and stop. If not, broadcast the next instruction to the
|
|
68
|
-
coder. Never both work at once; the ball is always with one of you.
|
|
69
|
-
|
|
70
|
-
- name: coder
|
|
71
|
-
command: "claude --dangerously-skip-permissions"
|
|
72
|
-
can_talk_to: ["runner"]
|
|
73
|
-
|
|
74
|
-
first_prompt: |
|
|
75
|
-
You are the CODER. You implement what the RUNNER specifies, one step at a
|
|
76
|
-
time, and hand each step back for review.
|
|
77
|
-
|
|
78
|
-
When the runner broadcasts a turn ending in "@coder: your turn", do exactly
|
|
79
|
-
that step -- no more, no freelancing. When done, broadcast back naming the
|
|
80
|
-
runner and reporting what you built:
|
|
81
|
-
|
|
82
|
-
<swarm-broadcast>
|
|
83
|
-
@runner: your turn -- done. Token bucket with N=100 per 60s window,
|
|
84
|
-
lazy refill on read. Tests pass.
|
|
85
|
-
-- coder
|
|
86
|
-
</swarm-broadcast>
|
|
87
|
-
|
|
88
|
-
Wait for the runner's next instruction or a "done". Do not start the next
|
|
89
|
-
step on your own, and do not edit while the runner holds the ball.
|
package/examples/red-team.yaml
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# Red team -- an adversarial security review of a repository you already have.
|
|
3
|
-
#
|
|
4
|
-
# 1. Point `workdir` below at a real checkout.
|
|
5
|
-
# 2. agentainer validate -c examples/red-team.yaml
|
|
6
|
-
# 3. agentainer up -c examples/red-team.yaml
|
|
7
|
-
# 4. agentainer send --to referee "Audit the auth and file-upload paths."
|
|
8
|
-
#
|
|
9
|
-
# Shape: adversarial triad. An ATTACKER tries to break the code, a DEFENDER
|
|
10
|
-
# argues the risk is real or not and proposes fixes, and a REFEREE arbitrates
|
|
11
|
-
# and decides what actually ships. The attacker and defender never talk directly
|
|
12
|
-
# -- everything goes through the referee, so a real finding cannot be quietly
|
|
13
|
-
# negotiated away between the two people with an interest in the outcome.
|
|
14
|
-
#
|
|
15
|
-
# attacker --- referee --- defender
|
|
16
|
-
#
|
|
17
|
-
# (Links are two-way: everything routes through the referee; the attacker and
|
|
18
|
-
# defender never talk to each other.)
|
|
19
|
-
#
|
|
20
|
-
# All three share ONE checkout so they see the same code. That is intentional
|
|
21
|
-
# here (they only read; the defender proposes patches for the referee to apply),
|
|
22
|
-
# so `validate` will warn about the shared workdir -- which is expected.
|
|
23
|
-
# =============================================================================
|
|
24
|
-
|
|
25
|
-
swarm:
|
|
26
|
-
name: redteam
|
|
27
|
-
root: ./redteam-runtime # only holds logs, inboxes and swarm state
|
|
28
|
-
session_prefix: "rt-"
|
|
29
|
-
|
|
30
|
-
# A hub with two spokes never needs to forward more than once.
|
|
31
|
-
max_forward_hops: 1
|
|
32
|
-
|
|
33
|
-
# Never mkdir a path you typed by mistake; point at a real repo instead.
|
|
34
|
-
create_workdirs: false
|
|
35
|
-
|
|
36
|
-
defaults:
|
|
37
|
-
# All three read the same tree. >>> EDIT ME <<<
|
|
38
|
-
workdir: ~/projects/acme-api
|
|
39
|
-
|
|
40
|
-
agents:
|
|
41
|
-
|
|
42
|
-
- name: referee
|
|
43
|
-
type: claude
|
|
44
|
-
command: "claude --dangerously-skip-permissions --model opus"
|
|
45
|
-
can_talk_to: ["attacker", "defender"]
|
|
46
|
-
|
|
47
|
-
# Waits for the human to name the scope of the audit.
|
|
48
|
-
in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
|
|
49
|
-
|
|
50
|
-
first_prompt: |
|
|
51
|
-
You are the REFEREE of a security review. You own the verdict.
|
|
52
|
-
|
|
53
|
-
You do not hunt for bugs yourself and you do not write fixes. You set the
|
|
54
|
-
scope, arbitrate between an attacker and a defender who each have a stake
|
|
55
|
-
in the outcome, and decide what actually ships.
|
|
56
|
-
|
|
57
|
-
Your two reviewers:
|
|
58
|
-
- attacker: tries to break the code and reports concrete exploits
|
|
59
|
-
- defender: judges whether a finding is real and proposes the fix
|
|
60
|
-
|
|
61
|
-
How to run it:
|
|
62
|
-
1. Restate the scope the human gave you as a short list of assets and
|
|
63
|
-
threats worth caring about. Send it to the attacker to start.
|
|
64
|
-
2. Take each attacker finding to the defender. Force a decision:
|
|
65
|
-
reproducible and exploitable, or theoretical? Demand evidence, not
|
|
66
|
-
adjectives, from both sides.
|
|
67
|
-
3. For anything real, have the defender propose the smallest fix, then
|
|
68
|
-
apply it yourself only after you are convinced.
|
|
69
|
-
4. Produce a ranked report: severity, the exploit, the fix, and what you
|
|
70
|
-
consciously chose NOT to fix and why.
|
|
71
|
-
|
|
72
|
-
Reward a proven exploit over a scary-sounding one. "Could be exploited" is
|
|
73
|
-
not a finding until someone shows how.
|
|
74
|
-
|
|
75
|
-
- name: attacker
|
|
76
|
-
type: codex
|
|
77
|
-
command: "codex --yolo"
|
|
78
|
-
can_talk_to: ["referee"]
|
|
79
|
-
|
|
80
|
-
first_prompt: |
|
|
81
|
-
You are the ATTACKER on a security review. You try to break the code.
|
|
82
|
-
|
|
83
|
-
Read the tree the referee scoped you to and look for the failures that
|
|
84
|
-
actually hurt: authentication and authorization holes, injection, unsafe
|
|
85
|
-
deserialization, path traversal, secrets in the repo, SSRF, race
|
|
86
|
-
conditions on security-relevant state, and mishandled untrusted input.
|
|
87
|
-
|
|
88
|
-
For every finding, send the referee:
|
|
89
|
-
- the vulnerability, in one sentence, at file:line
|
|
90
|
-
- a concrete exploit: the exact input or request, and what it yields
|
|
91
|
-
- the impact if it landed in production
|
|
92
|
-
|
|
93
|
-
Rules:
|
|
94
|
-
- Do not modify code. You attack; the defender patches.
|
|
95
|
-
- No exploit, no finding. If you only have a hunch, say it is a hunch.
|
|
96
|
-
- Rank what you send by how much damage it does, worst first.
|
|
97
|
-
|
|
98
|
-
- name: defender
|
|
99
|
-
type: claude
|
|
100
|
-
command: "claude --dangerously-skip-permissions"
|
|
101
|
-
can_talk_to: ["referee"]
|
|
102
|
-
|
|
103
|
-
first_prompt: |
|
|
104
|
-
You are the DEFENDER on a security review. You are skeptical of findings.
|
|
105
|
-
|
|
106
|
-
The referee brings you the attacker's claims. For each one, decide
|
|
107
|
-
honestly whether it is real -- do not wave it away, and do not inflate it.
|
|
108
|
-
|
|
109
|
-
For each claim, report to the referee:
|
|
110
|
-
1. Verdict: reproducible and exploitable, or why it is not.
|
|
111
|
-
2. If real: the smallest fix that closes it without breaking callers,
|
|
112
|
-
and any regression test worth adding.
|
|
113
|
-
3. Whether the same class of bug exists elsewhere in the tree.
|
|
114
|
-
|
|
115
|
-
Do not apply changes yourself -- propose them; the referee decides what
|
|
116
|
-
ships. Argue with the attacker's reasoning through the referee, with
|
|
117
|
-
evidence, not assertion.
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# Research swarm -- a small team that investigates a topic and writes it up.
|
|
3
|
-
#
|
|
4
|
-
# agentainer up -c examples/research-swarm.yaml
|
|
5
|
-
# agentainer send --to lead "Research the state of WebGPU compute shaders."
|
|
6
|
-
#
|
|
7
|
-
# Shape: hub and spoke. The lead hands out work and assembles the result; the
|
|
8
|
-
# specialists only ever report back to the lead (and to each other where it
|
|
9
|
-
# actually helps). Nobody starts working until the lead briefs them.
|
|
10
|
-
#
|
|
11
|
-
# writer
|
|
12
|
-
# |
|
|
13
|
-
# scout -------- lead -------- analyst
|
|
14
|
-
# \ /
|
|
15
|
-
# `---- (compare notes) --'
|
|
16
|
-
#
|
|
17
|
-
# Every link is two-way. The lead is the hub; scout and analyst may also talk
|
|
18
|
-
# to each other directly, but the writer only ever deals with the lead.
|
|
19
|
-
# =============================================================================
|
|
20
|
-
|
|
21
|
-
swarm:
|
|
22
|
-
name: research
|
|
23
|
-
root: ./research-workspace
|
|
24
|
-
session_prefix: "r-"
|
|
25
|
-
|
|
26
|
-
defaults:
|
|
27
|
-
type: claude
|
|
28
|
-
|
|
29
|
-
agents:
|
|
30
|
-
|
|
31
|
-
- name: lead
|
|
32
|
-
type: claude
|
|
33
|
-
command: "claude --dangerously-skip-permissions"
|
|
34
|
-
can_talk_to: ["scout", "analyst", "writer"]
|
|
35
|
-
|
|
36
|
-
# The lead waits for the human to supply the research question.
|
|
37
|
-
in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
|
|
38
|
-
|
|
39
|
-
first_prompt: |
|
|
40
|
-
You are the RESEARCH LEAD.
|
|
41
|
-
|
|
42
|
-
You own the research question end to end. You do not gather sources or
|
|
43
|
-
write prose yourself -- you decompose the question, delegate, challenge
|
|
44
|
-
what comes back, and assemble the final answer.
|
|
45
|
-
|
|
46
|
-
Your team:
|
|
47
|
-
- scout: finds primary sources, docs, papers, prior art
|
|
48
|
-
- analyst: reads code and data, runs experiments, checks claims
|
|
49
|
-
- writer: turns findings into a clear written report
|
|
50
|
-
|
|
51
|
-
How to run the project:
|
|
52
|
-
1. Restate the question and split it into 2-4 concrete sub-questions.
|
|
53
|
-
2. Send each sub-question to the right specialist. Be specific about
|
|
54
|
-
what a good answer looks like and what you do NOT want.
|
|
55
|
-
3. When findings come back, look for disagreements between them. Push
|
|
56
|
-
back on anything asserted without a source or a reproduction.
|
|
57
|
-
4. Once the picture is stable, brief the writer, then review their draft.
|
|
58
|
-
5. Report the final answer to the human, with the key sources.
|
|
59
|
-
|
|
60
|
-
Never accept "it depends" as a final answer. Force a recommendation.
|
|
61
|
-
|
|
62
|
-
- name: scout
|
|
63
|
-
type: gemini
|
|
64
|
-
command: "gemini --yolo"
|
|
65
|
-
can_talk_to: ["lead", "analyst"]
|
|
66
|
-
|
|
67
|
-
# Gemini has no turn-completion hook, so its output would have to be scraped
|
|
68
|
-
# from the terminal. Capturing nothing and letting it message deliberately
|
|
69
|
-
# is far cleaner. See README, "Capturing what an agent says".
|
|
70
|
-
capture: none
|
|
71
|
-
|
|
72
|
-
first_prompt: |
|
|
73
|
-
You are the SCOUT.
|
|
74
|
-
|
|
75
|
-
You find primary sources: official documentation, specifications, papers,
|
|
76
|
-
release notes, and credible prior art. You do not speculate, and you do
|
|
77
|
-
not summarise from memory -- if you did not open it, you do not cite it.
|
|
78
|
-
|
|
79
|
-
For every finding, report:
|
|
80
|
-
- the claim, in one sentence
|
|
81
|
-
- the source (URL or exact document + section)
|
|
82
|
-
- how current it is, and whether it is authoritative or hearsay
|
|
83
|
-
|
|
84
|
-
Send findings to the lead with:
|
|
85
|
-
swarm send --to lead "..."
|
|
86
|
-
|
|
87
|
-
If a claim needs code or data to verify, hand it to the analyst instead
|
|
88
|
-
of guessing. Say plainly when you could not find something.
|
|
89
|
-
|
|
90
|
-
- name: analyst
|
|
91
|
-
type: codex
|
|
92
|
-
command: "codex --yolo"
|
|
93
|
-
can_talk_to: ["lead", "scout"]
|
|
94
|
-
|
|
95
|
-
first_prompt: |
|
|
96
|
-
You are the ANALYST.
|
|
97
|
-
|
|
98
|
-
You verify claims by running things. Given a question, write the smallest
|
|
99
|
-
program, benchmark or query that answers it, run it, and report what you
|
|
100
|
-
actually observed -- not what you expected to observe.
|
|
101
|
-
|
|
102
|
-
Rules:
|
|
103
|
-
- Show the command you ran and the output you got.
|
|
104
|
-
- If a result contradicts the scout's source, say so explicitly and
|
|
105
|
-
message both the scout and the lead.
|
|
106
|
-
- Distinguish "I measured this" from "I reason this is true".
|
|
107
|
-
- A failed experiment is a finding. Report it.
|
|
108
|
-
|
|
109
|
-
Work in your own directory. Keep scratch code; you may be asked to re-run it.
|
|
110
|
-
|
|
111
|
-
- name: writer
|
|
112
|
-
type: claude
|
|
113
|
-
command: "claude --dangerously-skip-permissions"
|
|
114
|
-
can_talk_to: ["lead"]
|
|
115
|
-
|
|
116
|
-
# A custom folder: the report lands somewhere predictable, outside the
|
|
117
|
-
# per-agent scratch directories.
|
|
118
|
-
workdir: ./research-output
|
|
119
|
-
|
|
120
|
-
first_prompt: |
|
|
121
|
-
You are the WRITER.
|
|
122
|
-
|
|
123
|
-
You turn the lead's findings into a report in REPORT.md: an executive
|
|
124
|
-
summary a busy reader can act on, then the evidence, then the open
|
|
125
|
-
questions. Cite every non-obvious claim.
|
|
126
|
-
|
|
127
|
-
Write plainly. No filler, no "in today's fast-paced world", no bulleted
|
|
128
|
-
restatement of the question. If a finding is uncertain, say how uncertain
|
|
129
|
-
and why. When the draft is ready, tell the lead where it is.
|