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 CHANGED
@@ -1,250 +1,150 @@
1
1
  # baro
2
2
 
3
- ## Background Agent Runtime Orchestrator
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
  ![npm downloads](https://img.shields.io/npm/dt/baro-ai) ![npm downloads weekly](https://img.shields.io/npm/dw/baro-ai) ![npm version](https://img.shields.io/npm/v/baro-ai)
8
6
 
9
- ![baro screenshot](https://raw.githubusercontent.com/jigjoy-ai/baro/main/assets/screenshot.png)
7
+ ```bash
8
+ npm install -g baro-ai
9
+ ```
10
10
 
11
- > 📖 **Deep dive:** [Getting the Maximum Out of My Claude Code Subscription](https://jigjoy.ai/blog/getting-the-maximum-out-of-claude-code) the story of why baro exists, how it pairs with Mozaik, and what it looks like in practice.
11
+ ![baro TUI at the end of a real run33 of 33 stories complete on a NestJS service, 2.2× parallel speedup, 32 files modified, PR opened](https://raw.githubusercontent.com/jigjoy-ai/baro/main/assets/screenshot.png)
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
- ## What's new (0.22–0.23)
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
- - **Opus as the default executor** — richer reasoning per story, still with routed Sonnet/Haiku available via `--model` or `.barorc`.
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
- ## Install
44
+ ```bash
45
+ cd your-repo
46
+ baro "Add JWT authentication with role-based access control"
47
+ ```
23
48
 
24
49
  ```
25
- npm install -g baro-ai
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
- Requires [Claude CLI](https://docs.anthropic.com/en/docs/claude-cli) installed and authenticated.
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
- ## Usage
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
- ```bash
33
- # Interactive - opens welcome screen
34
- baro
74
+ ## Recent real run
35
75
 
36
- # Direct - skip to planning
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
- # Use OpenAI for planning
40
- baro --planner openai "Add WebSocket support"
78
+ ## What each participant does
41
79
 
42
- # Limit parallelism to 3 concurrent stories
43
- baro --parallel 3 "Refactor database layer"
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
- # Set story timeout to 5 minutes
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
- # Force a specific model for all phases
49
- baro --model opus "Complex architecture redesign"
94
+ ## Try it
50
95
 
51
- # Disable model routing (use opus everywhere)
52
- baro --no-model-routing "Build entire app"
96
+ ```bash
97
+ npm install -g baro-ai
53
98
 
54
- # Dry run - generate plan without executing
55
- baro --dry-run "Add REST API"
99
+ # Full run (default Architect + Planner + parallel Story Agents)
100
+ baro "Migrate the hardcoded category data to a backend dictionary"
56
101
 
57
- # Resume interrupted execution (or execute a dry-run plan)
58
- baro --resume
102
+ # Trivial goal skip Architect + Critic + Surgeon, single story
103
+ baro --quick "fix the typo on line 42 of README.md"
59
104
 
60
- # Specify working directory
61
- baro --cwd ~/projects/myapp "Add REST API"
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
- ## How it works
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
- All fields are optional. CLI flags override `.barorc`, and interactive changes on the welcome screen override both.
111
+ # Dry-run first, execute later
112
+ baro --dry-run "Add WebSocket support"
113
+ baro --resume
111
114
 
112
- | Field | Values | Default |
113
- |-------|--------|---------|
114
- | `model` | `"routed"`, `"opus"`, `"sonnet"`, `"haiku"` | `"routed"` |
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
- ## Options
119
+ Full options + `.barorc` config + per-phase model overrides: [**docs.baro.rs**](https://docs.baro.rs).
122
120
 
123
- ```
124
- baro [goal] [options]
125
-
126
- Arguments:
127
- goal Project goal (opens welcome screen if omitted)
128
-
129
- Options:
130
- --planner <name> Planner: claude or openai (default: claude)
131
- --model <name> Override model for all phases: opus, sonnet, haiku
132
- --no-model-routing Use opus for everything (disables routing)
133
- --parallel <N> Max concurrent stories, 0 = unlimited (default: 0)
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
- ### Phase 2/3/4 observers (Mozaik bus)
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) installed and authenticated
190
- - macOS (arm64/x64), Linux (x64/arm64), or Windows (x64)
191
- - **Node.js 20+** (orchestrator runtime)
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. I'm actively adding things, testing ideas,
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
- If you like the idea and want to help shape where it goes, PRs are
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
- let prompt = this.resolvePrompt(story);
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 && doc.trim().length > 0) {
9621
- const header = [
9622
- "## Design spec (authoritative \u2014 already decided)",
9623
- "",
9624
- "The Architect made these decisions before any story started.",
9625
- "Treat them as fixed: use these exact file paths, names,",
9626
- "schemas, API shapes, and dependency choices. Do NOT",
9627
- "improvise alternatives \u2014 your siblings are working from",
9628
- "the same spec and divergence breaks the build.",
9629
- "",
9630
- doc.trim(),
9631
- "",
9632
- "---",
9633
- ""
9634
- ].join("\n");
9635
- prompt = header + prompt;
9636
- }
9637
- return prompt;
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(