baro-ai 0.38.2 → 0.39.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 +109 -209
- package/dist/cli.mjs +43 -25
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,250 +1,150 @@
|
|
|
1
1
|
# baro
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Give it a goal, it breaks it into stories, builds a dependency DAG, and runs them in parallel — each story gets its own AI agent.
|
|
3
|
+
> Type a goal in your repo. Walk away. Come back to a pull request.
|
|
6
4
|
|
|
7
5
|
  
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g baro-ai
|
|
9
|
+
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
<sub>baro TUI at the end of an [actual run](https://jigjoy.ai/blog/baro-808-nestjs-jest-tests) — one prompt → 33-story DAG → 32 files modified → PR opened. The summary panel shows wall time (33:23), parallel speedup (2.2×), token usage, and the PR URL.</sub>
|
|
14
|
+
|
|
15
|
+
## Parallel coding agents, no central coordinator
|
|
16
|
+
|
|
17
|
+
Most multi-agent setups have one orchestrator function in the middle that drives N agents. The orchestrator becomes the bottleneck the moment you push past a handful of concurrent agents — and adding a new behaviour means editing its control flow.
|
|
18
|
+
|
|
19
|
+
baro doesn't have that shape. Every part of the run is an independent **participant** on a shared event bus ([Mozaik](https://github.com/jigjoy-ai/mozaik)). N parallel story agents are N independent subprocesses, each emitting and consuming typed events. There is no central `run()` to bottleneck on, and adding a new behaviour is a new participant — not an orchestrator rewrite.
|
|
20
|
+
|
|
21
|
+
```mermaid
|
|
22
|
+
flowchart LR
|
|
23
|
+
subgraph A["Typical multi-agent orchestrator"]
|
|
24
|
+
direction TB
|
|
25
|
+
C{{Coordinator}}
|
|
26
|
+
C --> A1[Agent 1]
|
|
27
|
+
C --> A2[Agent 2]
|
|
28
|
+
C --> A3[Agent N]
|
|
29
|
+
end
|
|
30
|
+
subgraph B["baro on Mozaik"]
|
|
31
|
+
direction TB
|
|
32
|
+
Bus[(shared event bus)]
|
|
33
|
+
P1[Conductor] -.-> Bus
|
|
34
|
+
P2[Story Agent 1] -.-> Bus
|
|
35
|
+
P3[Story Agent N] -.-> Bus
|
|
36
|
+
P4[Critic / Surgeon / ...] -.-> Bus
|
|
37
|
+
end
|
|
38
|
+
```
|
|
12
39
|
|
|
13
|
-
|
|
40
|
+
That's the architectural lever. Everything else baro does — Architect, Planner, Critic, Surgeon, Librarian — is a participant on that bus. They don't call each other; they react to events.
|
|
14
41
|
|
|
15
|
-
|
|
16
|
-
- **Smaller-stories planner** — the planner now biases toward narrower, more independent stories that parallelize better on the DAG.
|
|
17
|
-
- **Branch dedup** — reruns on the same goal reuse the existing `baro/<name>` branch instead of piling up duplicates.
|
|
18
|
-
- **TUI: terminal-clear on tab switch** — cleaner transitions between story logs, DAG view, and stats.
|
|
19
|
-
- **Audit log survives project resets** — JSONL event logs now live in `~/.baro/runs/` by default, so a wiped `node_modules` or a fresh clone doesn't lose history.
|
|
20
|
-
- **Always-on audit + abnormal-exit banner** — every run is recorded, and the TUI surfaces an explicit banner when the orchestrator exits unexpectedly.
|
|
42
|
+
## What a run looks like
|
|
21
43
|
|
|
22
|
-
|
|
44
|
+
```bash
|
|
45
|
+
cd your-repo
|
|
46
|
+
baro "Add JWT authentication with role-based access control"
|
|
47
|
+
```
|
|
23
48
|
|
|
24
49
|
```
|
|
25
|
-
|
|
50
|
+
→ Architect (45s) — design decisions pinned for every story
|
|
51
|
+
→ Planner (38s) — 7 stories in 3 levels
|
|
52
|
+
→ Executing — 4 parallel Claude Code agents on baro/jwt-auth branch
|
|
53
|
+
→ Critic — per-turn acceptance evaluation, self-corrects on fail
|
|
54
|
+
→ Finalizer — PR #142 opened ✓
|
|
26
55
|
```
|
|
27
56
|
|
|
28
|
-
|
|
57
|
+
```mermaid
|
|
58
|
+
flowchart LR
|
|
59
|
+
Goal([your goal]) --> A[Architect<br/><sub>~45s — emits<br/>DecisionDocument</sub>]
|
|
60
|
+
A --> P[Planner<br/><sub>~60s — emits DAG</sub>]
|
|
61
|
+
P --> S1[Story 1]
|
|
62
|
+
P --> S2[Story 2]
|
|
63
|
+
P --> S3[Story 3]
|
|
64
|
+
S1 --> S4[Story 4]
|
|
65
|
+
S2 --> S4
|
|
66
|
+
S3 --> S5[Story 5]
|
|
67
|
+
S4 --> F[Finalizer<br/><sub>opens PR</sub>]
|
|
68
|
+
S5 --> F
|
|
69
|
+
F --> PR([Pull Request])
|
|
70
|
+
```
|
|
29
71
|
|
|
30
|
-
|
|
72
|
+
Every story is one **Claude Code subprocess** (or one Mozaik-native OpenAI session) — auth inherits from your existing setup, no API key plumbing.
|
|
31
73
|
|
|
32
|
-
|
|
33
|
-
# Interactive - opens welcome screen
|
|
34
|
-
baro
|
|
74
|
+
## Recent real run
|
|
35
75
|
|
|
36
|
-
|
|
37
|
-
baro "Add authentication with JWT and role-based access control"
|
|
76
|
+
[**How baro generated 808 NestJS Jest tests autonomously in 71 minutes**](https://jigjoy.ai/blog/baro-808-nestjs-jest-tests) — one prompt, 33-story DAG, two sessions because of the Anthropic 3am usage cap, 64 test suites, 83.5% branch coverage, +13,606 lines of test code, zero phantom bug issues filed.
|
|
38
77
|
|
|
39
|
-
|
|
40
|
-
baro --planner openai "Add WebSocket support"
|
|
78
|
+
## What each participant does
|
|
41
79
|
|
|
42
|
-
|
|
43
|
-
|
|
80
|
+
| Participant | Role |
|
|
81
|
+
|---|---|
|
|
82
|
+
| **Architect** | One Opus call before planning — emits a `DecisionDocument` that pins every cross-cutting design decision (file paths, schemas, API shapes, library choices) so 30 parallel agents don't each invent their own |
|
|
83
|
+
| **Planner** | Decomposes the goal into a story DAG, with the DecisionDocument already pinned |
|
|
84
|
+
| **Conductor** | State machine that drives the run by reacting to bus events |
|
|
85
|
+
| **StoryAgent** | One Claude Code subprocess per story; multi-turn loop until story completes |
|
|
86
|
+
| **Critic** | Per-turn evaluator (Haiku). On fail verdict, injects corrective feedback as the agent's next turn |
|
|
87
|
+
| **Sentry** | Flags overlapping Edit/Write tool calls across concurrent stories |
|
|
88
|
+
| **Librarian** | Indexes one agent's Read/Grep findings so siblings don't redo the exploration |
|
|
89
|
+
| **Surgeon** | On terminal failure, asks Opus for a richer replan (split / prereq / rewire) |
|
|
90
|
+
| **Finalizer** | Runs build verification, opens the GitHub PR with stories table + stats |
|
|
44
91
|
|
|
45
|
-
|
|
46
|
-
baro --timeout 300 "Add unit tests"
|
|
92
|
+
Bus is open. CI deployers, Slack notifiers, ticket triggers — all new participants, no orchestrator changes. Architecture deep-dive: [I tested Claude Code's new /goal feature against my parallel agent setup](https://jigjoy.ai/blog/baro-vs-claude-code).
|
|
47
93
|
|
|
48
|
-
|
|
49
|
-
baro --model opus "Complex architecture redesign"
|
|
94
|
+
## Try it
|
|
50
95
|
|
|
51
|
-
|
|
52
|
-
|
|
96
|
+
```bash
|
|
97
|
+
npm install -g baro-ai
|
|
53
98
|
|
|
54
|
-
#
|
|
55
|
-
baro
|
|
99
|
+
# Full run (default — Architect + Planner + parallel Story Agents)
|
|
100
|
+
baro "Migrate the hardcoded category data to a backend dictionary"
|
|
56
101
|
|
|
57
|
-
#
|
|
58
|
-
baro --
|
|
102
|
+
# Trivial goal — skip Architect + Critic + Surgeon, single story
|
|
103
|
+
baro --quick "fix the typo on line 42 of README.md"
|
|
59
104
|
|
|
60
|
-
#
|
|
61
|
-
baro --
|
|
62
|
-
```
|
|
105
|
+
# Route every phase through GPT-5.5 instead of Claude
|
|
106
|
+
OPENAI_API_KEY=sk-... baro --llm openai "Refactor the database layer"
|
|
63
107
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
1. **Plan** — Claude (Opus) explores your codebase and generates a dependency graph of user stories
|
|
67
|
-
2. **Review** — You review the plan, refine with feedback, accept or quit
|
|
68
|
-
3. **Execute** — Stories run in parallel on a feature branch, each with its own Claude agent (Opus by default in 0.23+; Sonnet/Haiku available via `--model` or `.barorc`)
|
|
69
|
-
4. **Review Agent** — After each level, a review agent (Haiku) checks work against acceptance criteria and creates fix stories if needed
|
|
70
|
-
5. **Finalize** — Runs build verification and creates a GitHub PR with full summary
|
|
71
|
-
|
|
72
|
-
## Features
|
|
73
|
-
|
|
74
|
-
- **Parallel execution** — independent stories run simultaneously, respecting dependency order
|
|
75
|
-
- **DAG engine** — topological sort with level grouping, cycle detection
|
|
76
|
-
- **Model routing** — Opus for planning and execution (0.23+ default), Haiku for review (configurable)
|
|
77
|
-
- **Live TUI** — dashboard with story status, live agent logs, DAG view, stats
|
|
78
|
-
- **Review agent** — automated code review between levels with build detection and auto-fix
|
|
79
|
-
- **Plan refinement** — press `r` on review screen to give feedback and regenerate the plan
|
|
80
|
-
- **Build detection** — auto-detects project type (Cargo, npm, Go, Python, Make) and runs builds during review
|
|
81
|
-
- **Git coordination** — mutex-protected commits, auto-push with retry, pull --rebase, conflict detection
|
|
82
|
-
- **Branch per run** — creates `baro/<name>` branch, keeps main clean, reuses existing branches on rerun (0.23+)
|
|
83
|
-
- **Dry run** — `--dry-run` generates plan and saves to `prd.json` without executing, then `--resume` to run it
|
|
84
|
-
- **Resume** — detects `prd.json` and resumes incomplete executions
|
|
85
|
-
- **PR creation** — creates GitHub PR with stories table, stats, time saved, and review summary
|
|
86
|
-
- **Configurable parallelism** — `--parallel N` to limit concurrent story execution
|
|
87
|
-
- **Story timeout** — `--timeout SECONDS` kills stuck agents (default: 10 minutes, hard timeout disabled in 0.22+)
|
|
88
|
-
- **Time saved** — shows parallel speedup vs sequential execution
|
|
89
|
-
- **System notifications** — terminal bell + OS notification (macOS/Linux/Windows) when done
|
|
90
|
-
- **Retry logic** — failed stories retry automatically (configurable per story)
|
|
91
|
-
- **Interactive settings** — configure model, parallelism, timeout, context, and planner on the welcome screen with Tab/arrow keys
|
|
92
|
-
- **Project config** — `.barorc` file in project root sets defaults (no CLI flags needed)
|
|
93
|
-
- **Session lock** — prevents multiple baro instances from running in the same directory
|
|
94
|
-
- **Audit log** — every bus event written to `~/.baro/runs/<run-id>.jsonl`
|
|
95
|
-
|
|
96
|
-
## Config file
|
|
97
|
-
|
|
98
|
-
Create a `.barorc` in your project root to set defaults:
|
|
99
|
-
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"model": "routed",
|
|
103
|
-
"parallel": 3,
|
|
104
|
-
"timeout": 600,
|
|
105
|
-
"skipContext": false,
|
|
106
|
-
"planner": "claude"
|
|
107
|
-
}
|
|
108
|
-
```
|
|
108
|
+
# Limit parallelism (Anthropic plan tiers cap concurrency)
|
|
109
|
+
baro --parallel 3 "Add unit tests for the auth module"
|
|
109
110
|
|
|
110
|
-
|
|
111
|
+
# Dry-run first, execute later
|
|
112
|
+
baro --dry-run "Add WebSocket support"
|
|
113
|
+
baro --resume
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
| `parallel` | `0` (unlimited) or any number | `0` |
|
|
116
|
-
| `timeout` | seconds per story | `600` |
|
|
117
|
-
| `skipContext` | `true` / `false` | `false` |
|
|
118
|
-
| `planner` | `"claude"`, `"openai"` | `"claude"` |
|
|
119
|
-
| `dryRun` | `true` / `false` | `false` |
|
|
115
|
+
# Self-diagnostic
|
|
116
|
+
baro --doctor
|
|
117
|
+
```
|
|
120
118
|
|
|
121
|
-
|
|
119
|
+
Full options + `.barorc` config + per-phase model overrides: [**docs.baro.rs**](https://docs.baro.rs).
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
--timeout <seconds> Story timeout in seconds (default: 600)
|
|
135
|
-
--dry-run Generate plan only, save to prd.json, do not execute
|
|
136
|
-
--resume Resume from existing prd.json (also runs dry-run plans)
|
|
137
|
-
--skip-context Skip CLAUDE.md auto-generation
|
|
138
|
-
--cwd <path> Working directory (default: current)
|
|
139
|
-
--no-critic Disable live Critic (default: on). The Critic
|
|
140
|
-
reviews each agent turn against acceptance
|
|
141
|
-
criteria via `claude --model haiku` and injects
|
|
142
|
-
corrective feedback when the turn doesn't pass.
|
|
143
|
-
--critic-model <name> Model for the Critic (default: haiku)
|
|
144
|
-
--no-librarian Disable cross-agent runtime memory (default: on)
|
|
145
|
-
--no-sentry Disable file-touch conflict detector (default: on)
|
|
146
|
-
--no-surgeon Disable Surgeon (default: on). The Surgeon
|
|
147
|
-
observes terminal story failures and proposes
|
|
148
|
-
replans (split / prereq / rewire) so failed
|
|
149
|
-
work gets done in a different shape rather
|
|
150
|
-
than dropped.
|
|
151
|
-
--no-surgeon-llm Use deterministic Surgeon (skip-only) instead
|
|
152
|
-
of the LLM-driven replanner. The LLM Surgeon
|
|
153
|
-
is on by default; it costs an Opus call per
|
|
154
|
-
terminal failure but produces richer replans.
|
|
155
|
-
--surgeon-model <name> Model for the Surgeon LLM (default: opus)
|
|
156
|
-
-h, --help Print help
|
|
157
|
-
```
|
|
121
|
+
## How it compares
|
|
122
|
+
|
|
123
|
+
| | Single Claude Code session | DIY `Promise.all` of subprocesses | baro |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| **Plans the work** | you | you | Planner agent |
|
|
126
|
+
| **Pins design decisions** | implicit, drifts | n/a | Architect agent (`DecisionDocument`) |
|
|
127
|
+
| **Parallel agents** | no — one session | yes, you coordinate | yes, on Mozaik bus |
|
|
128
|
+
| **Mid-flight peer awareness** | n/a | implement yourself | Librarian broadcasts |
|
|
129
|
+
| **Replan on failure** | manual | manual | Surgeon agent |
|
|
130
|
+
| **Opens the PR** | manual | manual | Finalizer |
|
|
131
|
+
| **Adding a new behaviour** | new prompt | refactor orchestrator | new bus participant |
|
|
158
132
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
baro 0.19+ runs every story through a TypeScript Mozaik orchestrator.
|
|
162
|
-
Stories on the same DAG level run truly in parallel and observers can
|
|
163
|
-
react to one another's bus events:
|
|
164
|
-
|
|
165
|
-
- **Librarian** (default ON) — when one agent reads a file or runs grep,
|
|
166
|
-
later agents in the run see the digest in their prompt and skip the
|
|
167
|
-
redundant exploration. Measurable token savings on multi-story runs.
|
|
168
|
-
- **Sentry** (default ON) — flags overlapping Edit/Write tool calls
|
|
169
|
-
across concurrent stories.
|
|
170
|
-
- **Critic** (default ON) — Haiku evaluator reviews each agent turn
|
|
171
|
-
against acceptance criteria; on a fail verdict, an inline corrective
|
|
172
|
-
message lands as the agent's next turn so it self-corrects before
|
|
173
|
-
commit. Disable with `--no-critic`.
|
|
174
|
-
- **Surgeon** (default ON, with LLM) — when a story fails its retry
|
|
175
|
-
budget, the Surgeon asks Opus for a richer replan and emits a
|
|
176
|
-
ReplanItem the Conductor applies at the next level boundary. The LLM
|
|
177
|
-
is biased toward keeping the work done — it prefers splitting a too-
|
|
178
|
-
large story into smaller pieces, inserting a prerequisite, or
|
|
179
|
-
rewiring dependencies, over dropping outright. A run is reported as
|
|
180
|
-
successful only when every original story passes; if the Surgeon
|
|
181
|
-
drops a story without replacement, the run terminates with a clear
|
|
182
|
-
"did not complete the goal" verdict instead of a green tick. Disable
|
|
183
|
-
the LLM with `--no-surgeon-llm` to fall back to deterministic
|
|
184
|
-
skip-only behavior, or `--no-surgeon` to remove adaptive replans
|
|
185
|
-
entirely.
|
|
133
|
+
For a deeper side-by-side on a real refactor, see [baro vs Claude Code `/goal`](https://jigjoy.ai/blog/baro-vs-claude-code).
|
|
186
134
|
|
|
187
135
|
## Requirements
|
|
188
136
|
|
|
189
|
-
- [Claude CLI](https://docs.anthropic.com/en/docs/claude-cli)
|
|
190
|
-
-
|
|
191
|
-
-
|
|
137
|
+
- [Claude CLI](https://docs.anthropic.com/en/docs/claude-cli) authenticated (for `--llm claude`, the default) **or** `OPENAI_API_KEY` set (for `--llm openai`)
|
|
138
|
+
- Node.js 20+
|
|
139
|
+
- macOS (arm64/x64), Linux (x64/arm64), Windows (x64)
|
|
192
140
|
- `gh` CLI (optional, for automatic PR creation)
|
|
193
141
|
|
|
194
|
-
> **Windows note:** Windows 10+ is required. For best TUI experience, use [Windows Terminal](https://aka.ms/terminal) or another modern terminal emulator.
|
|
195
|
-
|
|
196
|
-
## Architecture
|
|
197
|
-
|
|
198
|
-
Rust binary distributed via npm. TUI built with ratatui, async execution
|
|
199
|
-
with tokio. Each `baro` invocation spawns the bundled TypeScript
|
|
200
|
-
[Mozaik](https://github.com/jigjoy-ai/mozaik) orchestrator as a
|
|
201
|
-
subprocess; the orchestrator owns story execution and emits typed
|
|
202
|
-
events into a shared `AgenticEnvironment` bus. Each story is one
|
|
203
|
-
`claude` CLI subprocess (auth inherits from your Claude CLI session —
|
|
204
|
-
no API key needed).
|
|
205
|
-
|
|
206
|
-
The orchestrator is itself a Mozaik agentic environment: there is no
|
|
207
|
-
imperative `run()` method, no top-level `Promise.all` loop. The
|
|
208
|
-
**Conductor** is a state machine that reacts to typed bus events
|
|
209
|
-
(`RunStartRequest` → `LevelComputeRequest` → `StorySpawnRequest` →
|
|
210
|
-
`StoryResult` → `LevelCompleted` → …). Spawning a story, evaluating a
|
|
211
|
-
turn, and replanning the DAG are all reactions, not steps in a loop.
|
|
212
|
-
|
|
213
|
-
Ten participants share that bus:
|
|
214
|
-
|
|
215
|
-
| Participant | Role |
|
|
216
|
-
| --------------- | ----------------------------------------------------------------- |
|
|
217
|
-
| `Conductor` | Orchestration state machine — drives the run by reacting |
|
|
218
|
-
| `StoryFactory` | Spawns Story Agents on each `StorySpawnRequest` |
|
|
219
|
-
| `StoryAgent` | Runs one story via Claude CLI, with retries and timeout |
|
|
220
|
-
| `Librarian` | Cross-agent memory — indexes outputs of exploration tools |
|
|
221
|
-
| `Sentry` | Flags overlapping file writes across concurrent stories |
|
|
222
|
-
| `Critic` | Per-turn acceptance-criteria evaluator (default ON, `--no-critic` to disable) |
|
|
223
|
-
| `Surgeon` | Emits DAG replans when a story fails terminally (default ON, `--no-surgeon` to disable) |
|
|
224
|
-
| `Operator` | Bridges external user commands (TUI, web UI) into bus events |
|
|
225
|
-
| `Auditor` | JSONL log of every event on the bus (written to `~/.baro/runs/`) |
|
|
226
|
-
| `Cartographer` | Translates bus events into UI frames for the Rust TUI |
|
|
227
|
-
|
|
228
|
-
The bus is open. New participants — CI deployers, Slack notifiers,
|
|
229
|
-
external ticket triggers — are subscribers and emitters with no changes
|
|
230
|
-
to the orchestrator.
|
|
231
|
-
|
|
232
142
|
## Status & feedback
|
|
233
143
|
|
|
234
|
-
baro is a work in progress.
|
|
235
|
-
and occasionally breaking them — if a run explodes, an [issue on
|
|
236
|
-
GitHub](https://github.com/jigjoy-ai/baro/issues) with the run's audit
|
|
237
|
-
log from `~/.baro/runs/` is the fastest way to get it fixed.
|
|
144
|
+
baro is a work in progress. If a run explodes, the audit log at `~/.baro/runs/<run-id>.jsonl` is the fastest way to get it fixed — open an [issue](https://github.com/jigjoy-ai/baro/issues) with that file attached.
|
|
238
145
|
|
|
239
|
-
|
|
240
|
-
welcome, and you can DM me on Twitter
|
|
241
|
-
[@lotus_sbc](https://twitter.com/lotus_sbc) with ideas, use cases, or
|
|
242
|
-
bug reports.
|
|
146
|
+
Ideas, use cases, bug reports — Discord: [**discord.gg/dvxY9J2kWX**](https://discord.gg/dvxY9J2kWX) · Twitter: [**@lotus_sbc**](https://twitter.com/lotus_sbc)
|
|
243
147
|
|
|
244
148
|
## License
|
|
245
149
|
|
|
246
|
-
MIT
|
|
247
|
-
|
|
248
|
-
---
|
|
249
|
-
|
|
250
|
-
Made by [Lotus](https://github.com/Lotus015) from [JigJoy](https://jigjoy.ai) team
|
|
150
|
+
MIT — [JigJoy](https://jigjoy.ai/) team
|
package/dist/cli.mjs
CHANGED
|
@@ -8324,13 +8324,14 @@ var LevelCompletedItem = class extends BusEvent {
|
|
|
8324
8324
|
}
|
|
8325
8325
|
};
|
|
8326
8326
|
var StorySpawnRequestItem = class extends BusEvent {
|
|
8327
|
-
constructor(storyId, prompt, model, retries, timeoutSecs) {
|
|
8327
|
+
constructor(storyId, prompt, model, retries, timeoutSecs, appendSystemPrompt) {
|
|
8328
8328
|
super();
|
|
8329
8329
|
this.storyId = storyId;
|
|
8330
8330
|
this.prompt = prompt;
|
|
8331
8331
|
this.model = model;
|
|
8332
8332
|
this.retries = retries;
|
|
8333
8333
|
this.timeoutSecs = timeoutSecs;
|
|
8334
|
+
this.appendSystemPrompt = appendSystemPrompt;
|
|
8334
8335
|
}
|
|
8335
8336
|
type = "story_spawn_request";
|
|
8336
8337
|
toJSON() {
|
|
@@ -8340,7 +8341,8 @@ var StorySpawnRequestItem = class extends BusEvent {
|
|
|
8340
8341
|
promptLen: this.prompt.length,
|
|
8341
8342
|
model: this.model,
|
|
8342
8343
|
retries: this.retries,
|
|
8343
|
-
timeoutSecs: this.timeoutSecs
|
|
8344
|
+
timeoutSecs: this.timeoutSecs,
|
|
8345
|
+
appendSystemPromptLen: this.appendSystemPrompt?.length ?? 0
|
|
8344
8346
|
};
|
|
8345
8347
|
}
|
|
8346
8348
|
};
|
|
@@ -8864,6 +8866,9 @@ var ClaudeCliParticipant = class _ClaudeCliParticipant extends BaroParticipant {
|
|
|
8864
8866
|
if (this.options.resumeSessionId) {
|
|
8865
8867
|
args.push("--resume", this.options.resumeSessionId);
|
|
8866
8868
|
}
|
|
8869
|
+
if (this.options.appendSystemPrompt && this.options.appendSystemPrompt.length > 0) {
|
|
8870
|
+
args.push("--append-system-prompt", this.options.appendSystemPrompt);
|
|
8871
|
+
}
|
|
8867
8872
|
if (this.options.extraArgs && this.options.extraArgs.length > 0) {
|
|
8868
8873
|
args.push(...this.options.extraArgs);
|
|
8869
8874
|
}
|
|
@@ -9122,7 +9127,8 @@ var StoryAgent = class extends BaroParticipant {
|
|
|
9122
9127
|
this.transition("running", `attempt ${attempt}`);
|
|
9123
9128
|
const claude = new ClaudeCliParticipant(this.spec.id, {
|
|
9124
9129
|
cwd: this.spec.cwd,
|
|
9125
|
-
model: this.spec.model
|
|
9130
|
+
model: this.spec.model,
|
|
9131
|
+
appendSystemPrompt: this.spec.appendSystemPrompt
|
|
9126
9132
|
});
|
|
9127
9133
|
this.currentClaude = claude;
|
|
9128
9134
|
claude.join(this.envRef);
|
|
@@ -9482,7 +9488,9 @@ var Conductor = class extends BaroParticipant {
|
|
|
9482
9488
|
}
|
|
9483
9489
|
async requestStorySpawn(story) {
|
|
9484
9490
|
const model = this.opts.overrideModel ?? story.model ?? this.opts.defaultModel;
|
|
9485
|
-
|
|
9491
|
+
const resolved = this.resolvePrompt(story);
|
|
9492
|
+
let prompt = resolved.userPrompt;
|
|
9493
|
+
const appendSystemPrompt = resolved.appendSystemPrompt;
|
|
9486
9494
|
if (this.opts.onBeforeStoryLaunch) {
|
|
9487
9495
|
try {
|
|
9488
9496
|
const extra = await this.opts.onBeforeStoryLaunch(story.id, story);
|
|
@@ -9507,7 +9515,8 @@ ${prompt}`;
|
|
|
9507
9515
|
prompt,
|
|
9508
9516
|
model,
|
|
9509
9517
|
story.retries,
|
|
9510
|
-
this.opts.timeoutSecs
|
|
9518
|
+
this.opts.timeoutSecs,
|
|
9519
|
+
appendSystemPrompt
|
|
9511
9520
|
)
|
|
9512
9521
|
);
|
|
9513
9522
|
}
|
|
@@ -9617,24 +9626,26 @@ ${prompt}`;
|
|
|
9617
9626
|
prompt = buildDefaultStoryPrompt(story);
|
|
9618
9627
|
}
|
|
9619
9628
|
const doc = this.prd?.decisionDocument;
|
|
9620
|
-
if (doc
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
|
|
9629
|
+
if (!doc || doc.trim().length === 0) {
|
|
9630
|
+
return { userPrompt: prompt };
|
|
9631
|
+
}
|
|
9632
|
+
const trimmedDoc = doc.trim();
|
|
9633
|
+
const headerLines = [
|
|
9634
|
+
"## Design spec (authoritative \u2014 already decided)",
|
|
9635
|
+
"",
|
|
9636
|
+
"The Architect made these decisions before any story started.",
|
|
9637
|
+
"Treat them as fixed: use these exact file paths, names,",
|
|
9638
|
+
"schemas, API shapes, and dependency choices. Do NOT",
|
|
9639
|
+
"improvise alternatives \u2014 your siblings are working from",
|
|
9640
|
+
"the same spec and divergence breaks the build.",
|
|
9641
|
+
""
|
|
9642
|
+
];
|
|
9643
|
+
if (this.opts.shareArchitectCache) {
|
|
9644
|
+
const appendSystemPrompt = [...headerLines, trimmedDoc].join("\n");
|
|
9645
|
+
return { userPrompt: prompt, appendSystemPrompt };
|
|
9646
|
+
}
|
|
9647
|
+
const header = [...headerLines, trimmedDoc, "", "---", ""].join("\n");
|
|
9648
|
+
return { userPrompt: header + prompt };
|
|
9638
9649
|
}
|
|
9639
9650
|
emit(event) {
|
|
9640
9651
|
this.envRef?.deliverBusEvent(this, event);
|
|
@@ -11684,7 +11695,8 @@ var StoryFactory = class extends BaroParticipant {
|
|
|
11684
11695
|
cwd: this.opts.cwd,
|
|
11685
11696
|
model: claudeModel,
|
|
11686
11697
|
retries: req.retries,
|
|
11687
|
-
timeoutSecs: req.timeoutSecs
|
|
11698
|
+
timeoutSecs: req.timeoutSecs,
|
|
11699
|
+
appendSystemPrompt: req.appendSystemPrompt
|
|
11688
11700
|
});
|
|
11689
11701
|
agent.join(this.envRef);
|
|
11690
11702
|
this.active.set(req.storyId, agent);
|
|
@@ -12114,6 +12126,7 @@ async function orchestrate(config) {
|
|
|
12114
12126
|
overrideModel: config.overrideModel ?? void 0,
|
|
12115
12127
|
defaultModel: config.defaultModel ?? "opus",
|
|
12116
12128
|
intraLevelDelaySecs: config.intraLevelDelaySecs,
|
|
12129
|
+
shareArchitectCache: config.shareArchitectCache ?? false,
|
|
12117
12130
|
onRunStart: useGit ? async (prd) => {
|
|
12118
12131
|
baseSha = await getHeadSha(config.cwd);
|
|
12119
12132
|
if (prd.branchName) {
|
|
@@ -12401,6 +12414,7 @@ function parseArgs(argv) {
|
|
|
12401
12414
|
withSurgeon: false,
|
|
12402
12415
|
surgeonUseLlm: false,
|
|
12403
12416
|
llm: "claude",
|
|
12417
|
+
shareArchitectCache: false,
|
|
12404
12418
|
help: false
|
|
12405
12419
|
};
|
|
12406
12420
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -12474,6 +12488,9 @@ function parseArgs(argv) {
|
|
|
12474
12488
|
args.llm = v;
|
|
12475
12489
|
break;
|
|
12476
12490
|
}
|
|
12491
|
+
case "--share-architect-cache":
|
|
12492
|
+
args.shareArchitectCache = true;
|
|
12493
|
+
break;
|
|
12477
12494
|
default:
|
|
12478
12495
|
process.stderr.write(`[cli] unknown flag: ${a}
|
|
12479
12496
|
`);
|
|
@@ -12553,7 +12570,8 @@ async function main() {
|
|
|
12553
12570
|
surgeonModel: args.surgeonModel,
|
|
12554
12571
|
intraLevelDelaySecs: args.intraLevelDelaySecs,
|
|
12555
12572
|
llm: args.llm,
|
|
12556
|
-
storyModel: args.storyModel
|
|
12573
|
+
storyModel: args.storyModel,
|
|
12574
|
+
shareArchitectCache: args.shareArchitectCache
|
|
12557
12575
|
};
|
|
12558
12576
|
if (args.llm === "openai" && !process.env.OPENAI_API_KEY) {
|
|
12559
12577
|
process.stderr.write(
|