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,129 +1,67 @@
|
|
|
1
1
|
# =============================================================================
|
|
2
|
-
# Writers' room --
|
|
2
|
+
# ✍️ Writers' room -- a single editor coordinates a small stable of writers who
|
|
3
|
+
# draft sections of a document and hand them back for assembly.
|
|
3
4
|
#
|
|
4
|
-
#
|
|
5
|
-
# agentainer
|
|
5
|
+
# cp examples/writers-room.yaml my-doc.yaml
|
|
6
|
+
# agentainer up -c my-doc.yaml
|
|
7
|
+
# agentainer send -c my-doc.yaml --to editor "Draft a launch post for v2."
|
|
8
|
+
# agentainer down -c my-doc.yaml
|
|
6
9
|
#
|
|
7
|
-
# Shape:
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# decides what to revise -- so the draft goes through one owner, not a committee.
|
|
10
|
+
# Shape: many-to-one. The editor is the only hub; writers never talk to each
|
|
11
|
+
# other (no cross-contamination of voice). Each writer drafts one slice and
|
|
12
|
+
# returns it to the editor, who assembles.
|
|
11
13
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
14
|
+
# writer-1 \ / editor
|
|
15
|
+
# writer-2 > (all talk only to the editor) <
|
|
16
|
+
# writer-3 /
|
|
15
17
|
#
|
|
16
|
-
#
|
|
17
|
-
# only to the editor -- never to each other.
|
|
18
|
-
#
|
|
19
|
-
# The article lands in a predictable place (`./writers-room-output/DRAFT.md`),
|
|
20
|
-
# not in a scratch folder, via a custom `workdir` on the writer.
|
|
18
|
+
# Real agents: commands launch the actual CLIs (claude / codex / gemini / hermes). For a key-free demo, swap each `command` for a mock bash loop.
|
|
21
19
|
# =============================================================================
|
|
22
20
|
|
|
23
21
|
swarm:
|
|
24
|
-
name:
|
|
25
|
-
root: ./writers-room
|
|
26
|
-
session_prefix: "wr-"
|
|
27
|
-
|
|
28
|
-
# Editor -> writer -> editor -> checker/critic. Keep the auto-forward guard low;
|
|
29
|
-
# here nobody auto-forwards anyway, so this is just belt-and-braces.
|
|
30
|
-
max_forward_hops: 2
|
|
22
|
+
name: writers-room
|
|
23
|
+
root: ./writers-room-workspace
|
|
31
24
|
|
|
32
25
|
defaults:
|
|
33
|
-
|
|
26
|
+
capture: none
|
|
27
|
+
can_talk_to: []
|
|
34
28
|
|
|
35
29
|
agents:
|
|
36
|
-
|
|
37
30
|
- name: editor
|
|
38
31
|
type: claude
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
and decide when it is done.
|
|
50
|
-
|
|
51
|
-
Your room:
|
|
52
|
-
- writer: drafts and revises the article
|
|
53
|
-
- factchecker: verifies every factual claim against a source
|
|
54
|
-
- critic: attacks the prose: clarity, structure, honesty
|
|
55
|
-
|
|
56
|
-
How to run it:
|
|
57
|
-
1. Turn the human's request into a one-paragraph brief: the single idea,
|
|
58
|
-
the reader, the length, and what the piece must NOT become.
|
|
59
|
-
2. Send the brief to the writer. When a draft comes back, send it to BOTH
|
|
60
|
-
the factchecker and the critic.
|
|
61
|
-
3. Merge their notes into one revision list, ordered by what matters, and
|
|
62
|
-
send it back to the writer. Drop nitpicks that do not serve the reader.
|
|
63
|
-
4. Repeat until a checked, clear draft exists. Then deliver the final
|
|
64
|
-
piece to the human and say where it is.
|
|
65
|
-
|
|
66
|
-
Protect the reader's time above the writer's feelings. Cut anything that
|
|
67
|
-
does not earn its place.
|
|
68
|
-
|
|
69
|
-
- name: writer
|
|
32
|
+
can_talk_to: [writer_1, writer_2, writer_3, user]
|
|
33
|
+
command: "claude --dangerously-skip-permissions"
|
|
34
|
+
role: |
|
|
35
|
+
You are the EDITOR. You receive the assignment in your inbox/ and break it
|
|
36
|
+
into section briefs -- one per writer -- each with a tight word count, an
|
|
37
|
+
angle, and the voice to use. Collect the drafts, line-edit them into one
|
|
38
|
+
consistent piece, and return the assembled draft. Keep every writer on the
|
|
39
|
+
same voice; flag contradictions rather than silently smoothing them.
|
|
40
|
+
|
|
41
|
+
- name: writer_1
|
|
70
42
|
type: claude
|
|
43
|
+
can_talk_to: [editor]
|
|
71
44
|
command: "claude --dangerously-skip-permissions"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
Tell the editor where the draft is when a version is ready for review.
|
|
90
|
-
|
|
91
|
-
- name: factchecker
|
|
45
|
+
role: |
|
|
46
|
+
You are WRITER 1 (technical lead). Draft exactly the brief the editor
|
|
47
|
+
sends you, in their voice, within their word count. Return it as mail to
|
|
48
|
+
the editor. Do not invent facts you cannot support.
|
|
49
|
+
|
|
50
|
+
- name: writer_2
|
|
51
|
+
type: gemini
|
|
52
|
+
can_talk_to: [editor]
|
|
53
|
+
capture: pane
|
|
54
|
+
command: "gemini --yolo"
|
|
55
|
+
role: |
|
|
56
|
+
You are WRITER 2 (the story). Draft exactly the brief the editor sends
|
|
57
|
+
you -- a human narrative arc -- in their voice, within their word count.
|
|
58
|
+
Return it as mail to the editor.
|
|
59
|
+
|
|
60
|
+
- name: writer_3
|
|
92
61
|
type: codex
|
|
62
|
+
can_talk_to: [editor]
|
|
93
63
|
command: "codex --yolo"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
Go through the draft claim by claim. For each factual assertion, decide:
|
|
100
|
-
supported, wrong, or unverifiable -- and show why.
|
|
101
|
-
|
|
102
|
-
Report to the editor:
|
|
103
|
-
- the claim, quoted, with where it appears
|
|
104
|
-
- your verdict, and the source or check behind it
|
|
105
|
-
- for anything wrong, the correct version
|
|
106
|
-
|
|
107
|
-
Where a claim can be tested with code or a quick command, test it and paste
|
|
108
|
-
what you actually observed. Distinguish "I verified this" from "this looks
|
|
109
|
-
plausible but I could not confirm it". Do not touch the prose -- that is the
|
|
110
|
-
writer's job and the critic's beat.
|
|
111
|
-
|
|
112
|
-
- name: critic
|
|
113
|
-
type: claude
|
|
114
|
-
command: "claude --dangerously-skip-permissions"
|
|
115
|
-
can_talk_to: ["editor"]
|
|
116
|
-
|
|
117
|
-
first_prompt: |
|
|
118
|
-
You are the CRITIC. You attack the writing so the reader does not have to.
|
|
119
|
-
|
|
120
|
-
Read the draft as a smart, busy reader who will bail the moment they are
|
|
121
|
-
bored or confused. Report to the editor:
|
|
122
|
-
- where you lost the thread, and why
|
|
123
|
-
- claims that sound impressive but say nothing
|
|
124
|
-
- structure that buries the point, or an opening that does not earn attention
|
|
125
|
-
- a stronger cut: what to remove so the rest lands harder
|
|
126
|
-
|
|
127
|
-
Be specific -- quote the sentence and propose the fix. Praise only what is
|
|
128
|
-
genuinely working, and briefly. Your job is the next draft, not the writer's
|
|
129
|
-
morale.
|
|
64
|
+
role: |
|
|
65
|
+
You are WRITER 3 (the example/code). Draft exactly the brief the editor
|
|
66
|
+
sends you -- runnable snippets with commentary -- in their voice, within
|
|
67
|
+
their word count. Return it as mail to the editor.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# 🎬 YouTube script studio -- turn a video topic into a full publish-ready
|
|
3
|
+
# package: script -> title/thumbnail copy -> description + tags + chapters.
|
|
4
|
+
#
|
|
5
|
+
# cp examples/youtube-script-studio.yaml my-studio.yaml
|
|
6
|
+
# agentainer up -c my-studio.yaml
|
|
7
|
+
# agentainer send -c my-studio.yaml --to producer "Make a 10-min video: 'Why your sourdough won't rise'."
|
|
8
|
+
# agentainer down -c my-studio.yaml
|
|
9
|
+
#
|
|
10
|
+
# The producer is the hub: it briefs a researcher (hooks + retention patterns),
|
|
11
|
+
# a scriptwriter (the actual script), and a metadata_writer (title, thumbnail
|
|
12
|
+
# copy, description, tags, chapters). Script and metadata are written as peers so
|
|
13
|
+
# titles/chapters track the real script -- but the producer stays the only agent
|
|
14
|
+
# that talks to you.
|
|
15
|
+
#
|
|
16
|
+
# make a video X
|
|
17
|
+
# user ─────────────▶ producer ◀───────────────────────┐
|
|
18
|
+
# (package) ◀──────┼──────────────┬───────────┐ │
|
|
19
|
+
# ▼ ▼ ▼ │
|
|
20
|
+
# researcher scriptwriter metadata_writer
|
|
21
|
+
# └────peer────┘
|
|
22
|
+
# ...producer <--> everyone; scriptwriter <--> metadata_writer; user via hub only.
|
|
23
|
+
#
|
|
24
|
+
# Key-free / no API keys: every `command` below is a placeholder launch line for a
|
|
25
|
+
# real coding-agent CLI. Swap each for a mock bash loop and the whole studio comes
|
|
26
|
+
# up and routes mail with NO API keys -- the mechanics are identical.
|
|
27
|
+
# =============================================================================
|
|
28
|
+
|
|
29
|
+
swarm:
|
|
30
|
+
name: youtube-script-studio
|
|
31
|
+
root: ./youtube-script-studio-workspace
|
|
32
|
+
|
|
33
|
+
defaults:
|
|
34
|
+
capture: none # tightened per agent (pane for gemini/hermes)
|
|
35
|
+
can_talk_to: [] # tightened per agent below
|
|
36
|
+
|
|
37
|
+
agents:
|
|
38
|
+
- name: producer
|
|
39
|
+
type: claude
|
|
40
|
+
workdir: "{root}/repo"
|
|
41
|
+
can_talk_to: [researcher, scriptwriter, metadata_writer, user]
|
|
42
|
+
command: "claude --dangerously-skip-permissions"
|
|
43
|
+
capture: none
|
|
44
|
+
role: |
|
|
45
|
+
You are the PRODUCER, the hub of a YouTube video studio. You turn the
|
|
46
|
+
user's topic into a publish-ready package and are the ONLY agent who talks
|
|
47
|
+
to the user. You do not write the script yourself; you set the angle,
|
|
48
|
+
audience, target length, and the promise of the video, then coordinate.
|
|
49
|
+
Your team: researcher (hook ideas + retention/pacing patterns for this
|
|
50
|
+
topic), scriptwriter (writes the full script), metadata_writer (title
|
|
51
|
+
options, thumbnail copy, description, tags, chapter markers).
|
|
52
|
+
Run it like this: (1) restate the topic as a one-paragraph brief -- angle,
|
|
53
|
+
audience, length, the single promise -- and send it to the researcher
|
|
54
|
+
first; (2) pass the research to the scriptwriter to draft the script;
|
|
55
|
+
(3) have the metadata_writer build titles/thumbnail/description/tags/
|
|
56
|
+
chapters against the FINAL script; (4) assemble everything and send the
|
|
57
|
+
finished package to the user.
|
|
58
|
+
MAILBOX: when a message lands in your inbox/, read it and act; when done,
|
|
59
|
+
move it to read/. To send, write a file into outbox/<name>/ (read
|
|
60
|
+
outbox/<name>/about.md first to see who they are and whether they are
|
|
61
|
+
available) and finish your turn. You may only message the agents in your
|
|
62
|
+
can_talk_to list.
|
|
63
|
+
|
|
64
|
+
- name: researcher
|
|
65
|
+
type: gemini
|
|
66
|
+
workdir: "{root}/repo"
|
|
67
|
+
can_talk_to: [producer]
|
|
68
|
+
command: "gemini --yolo"
|
|
69
|
+
capture: pane
|
|
70
|
+
role: |
|
|
71
|
+
You are the RESEARCHER. Given the producer's brief, find what makes THIS
|
|
72
|
+
topic watchable: 3-5 strong hook openers, the questions the audience
|
|
73
|
+
actually types, the moments where viewers drop off and how to hold them
|
|
74
|
+
(pattern interrupts, open loops, payoff placement), and any facts or
|
|
75
|
+
angles worth including. You do not write the script -- you hand the
|
|
76
|
+
producer a tight research brief they can pass to the scriptwriter. Report
|
|
77
|
+
only to the producer.
|
|
78
|
+
|
|
79
|
+
- name: scriptwriter
|
|
80
|
+
type: claude
|
|
81
|
+
workdir: "{root}/repo"
|
|
82
|
+
can_talk_to: [producer, metadata_writer]
|
|
83
|
+
command: "claude --dangerously-skip-permissions"
|
|
84
|
+
capture: none
|
|
85
|
+
role: |
|
|
86
|
+
You are the SCRIPTWRITER. Given the producer's brief and the researcher's
|
|
87
|
+
findings, write the full video SCRIPT.md: a cold-open hook in the first 15
|
|
88
|
+
seconds, a clear through-line, spoken-word narration (not bullet points),
|
|
89
|
+
B-roll / on-screen cues in brackets, and a call to action. Match the
|
|
90
|
+
target length and audience. When the script is solid, send a copy straight
|
|
91
|
+
to the metadata_writer so titles and chapters track the real script, and
|
|
92
|
+
report the draft to the producer.
|
|
93
|
+
|
|
94
|
+
- name: metadata_writer
|
|
95
|
+
type: codex
|
|
96
|
+
workdir: "{root}/repo"
|
|
97
|
+
can_talk_to: [producer, scriptwriter]
|
|
98
|
+
command: "codex --yolo"
|
|
99
|
+
capture: none
|
|
100
|
+
role: |
|
|
101
|
+
You are the METADATA_WRITER. Working from the FINAL script, produce the
|
|
102
|
+
packaging that gets the video found and clicked: 5-8 title options (front-
|
|
103
|
+
load the keyword, keep them honest), thumbnail copy (2-4 punchy words),
|
|
104
|
+
an SEO description with the payoff in the first two lines, a tag list, and
|
|
105
|
+
timestamped chapter markers derived from the script's sections. If the
|
|
106
|
+
script is missing a section you need for a chapter, ask the scriptwriter
|
|
107
|
+
directly; deliver the finished packaging to the producer.
|
package/hooks/claude_stop.sh
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Claude Code `Stop` hook: fires when Claude finishes responding.
|
|
3
3
|
# Claude passes a JSON payload on stdin containing `transcript_path`.
|
|
4
|
-
# Installed automatically into <agent-workdir>/.claude/settings.json by
|
|
4
|
+
# Installed automatically into <agent-workdir>/.claude/settings.json by
|
|
5
|
+
# `agentainer up`.
|
|
5
6
|
#
|
|
6
7
|
# A hook must never break the agent it is attached to, so every failure here is
|
|
7
8
|
# swallowed and the script always exits 0.
|
|
9
|
+
set -uo pipefail
|
|
8
10
|
|
|
9
11
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
10
12
|
|
|
11
13
|
log="/dev/null"
|
|
12
|
-
if [[ -n "${
|
|
13
|
-
log="$
|
|
14
|
+
if [[ -n "${AGENTAINER_ROOT:-}" ]] && mkdir -p "$AGENTAINER_ROOT/.agentainer/logs" 2>/dev/null; then
|
|
15
|
+
log="$AGENTAINER_ROOT/.agentainer/logs/hooks.log"
|
|
14
16
|
fi
|
|
15
17
|
|
|
16
18
|
"$HERE/agentainer" hook claude >>"$log" 2>&1
|
package/hooks/codex_notify.sh
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Codex `notify` program: codex invokes it with a JSON payload as $1 whenever a
|
|
3
3
|
# turn completes (payload type: "agent-turn-complete", with last-assistant-message).
|
|
4
|
-
# Wired up via <agent-workdir>/.codex/config.toml + CODEX_HOME by `
|
|
4
|
+
# Wired up via <agent-workdir>/.codex/config.toml + CODEX_HOME by `agentainer up`.
|
|
5
5
|
#
|
|
6
6
|
# Always exits 0 so a hook failure can never disturb the agent.
|
|
7
|
+
set -uo pipefail
|
|
7
8
|
|
|
8
9
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
9
10
|
|
|
10
11
|
log="/dev/null"
|
|
11
|
-
if [[ -n "${
|
|
12
|
-
log="$
|
|
12
|
+
if [[ -n "${AGENTAINER_ROOT:-}" ]] && mkdir -p "$AGENTAINER_ROOT/.agentainer/logs" 2>/dev/null; then
|
|
13
|
+
log="$AGENTAINER_ROOT/.agentainer/logs/hooks.log"
|
|
13
14
|
fi
|
|
14
15
|
|
|
15
16
|
"$HERE/agentainer" hook codex "${1:-}" >>"$log" 2>&1
|