baro-ai 0.38.2 → 0.39.0

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
@@ -10,14 +10,22 @@ Give it a goal, it breaks it into stories, builds a dependency DAG, and runs the
10
10
 
11
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.
12
12
 
13
- ## What's new (0.22–0.23)
13
+ > 📊 **Recent post:** [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 usage cap, 83.5% branch coverage, zero filed bug issues.
14
14
 
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.
15
+ ## What's new in 0.39
16
+
17
+ - **`--share-architect-cache` (experimental)** — routes the Architect's DecisionDocument through Claude Code's `--append-system-prompt` instead of prepending it to each story's user prompt. Anthropic's prompt cache hashes system + tools as the cache key, so with the flag on stories 2..N read the DD from cache at the 10× discount instead of each re-paying its own `cache_creation`. Default OFF; measure with audit-log token totals before flipping.
18
+
19
+ ## What's new in 0.30–0.38 (the bigger shifts)
20
+
21
+ - **Dual-mode LLM**: `--llm openai` is fully end-to-end now (Architect / Planner / StoryAgent / Critic / Surgeon all route through Mozaik's native OpenAI runner). Defaults: gpt-5.5 for code-shaped phases, gpt-5.4-mini for Critic.
22
+ - **Architect phase**: an upstream agent that fixes cross-cutting design decisions (column names, file paths, API shapes, library choices) **before** any Story Agent starts, so 30 parallel agents don't each invent their own. See [baro vs Claude Code post](https://jigjoy.ai/blog/baro-vs-claude-code) for the architecture.
23
+ - **`--quick`** — skip Architect, force 1-story plan, silence Critic + Surgeon. For trivial goals (`baro --quick "fix the typo on line 42"`) where the design-doc + multi-agent ceremony is overhead.
24
+ - **Per-phase model overrides**: `--architect-model`, `--planner-model`, `--story-model`, `--critic-model`, `--surgeon-model` — pin any individual role to a specific model without forcing the rest with the global `--model`.
25
+ - **Branch per run**: every fresh run creates a new suffixed `baro/<slug>-<id>` branch, never falls back to checkout. Side-by-side runs from sibling clones can't collide on `git push`.
26
+ - **`baro --doctor`** — pre-flight self-check that verifies the `claude` CLI is on PATH and authenticated, the audit dir is writable, and `gh` exists. First thing to run when a baro run fails before any agents start.
27
+ - **Repo moved** to [jigjoy-ai/baro](https://github.com/jigjoy-ai/baro). npm package name unchanged (`baro-ai`).
28
+ - **gpt-5.5 defaults** + UTF-8 panic fix + Ghostty/kitty-keyboard Enter handling + Execute-screen 0/N resume fix (0.38.x).
21
29
 
22
30
  ## Install
23
31
 
@@ -25,73 +33,62 @@ Give it a goal, it breaks it into stories, builds a dependency DAG, and runs the
25
33
  npm install -g baro-ai
26
34
  ```
27
35
 
28
- Requires [Claude CLI](https://docs.anthropic.com/en/docs/claude-cli) installed and authenticated.
36
+ Requires [Claude CLI](https://docs.anthropic.com/en/docs/claude-cli) installed and authenticated for `--llm claude` (the default). For `--llm openai`, set `OPENAI_API_KEY` in your shell env or enter it on the welcome screen.
29
37
 
30
38
  ## Usage
31
39
 
32
40
  ```bash
33
- # Interactive - opens welcome screen
41
+ # Interactive opens the welcome screen
34
42
  baro
35
43
 
36
- # Direct - skip to planning
44
+ # Direct skip to planning
37
45
  baro "Add authentication with JWT and role-based access control"
38
46
 
39
- # Use OpenAI for planning
40
- baro --planner openai "Add WebSocket support"
47
+ # Route every phase through GPT-5.5 (Mozaik-native OpenAI runner)
48
+ OPENAI_API_KEY=sk-... baro --llm openai "Refactor the database layer"
41
49
 
42
50
  # Limit parallelism to 3 concurrent stories
43
51
  baro --parallel 3 "Refactor database layer"
44
52
 
45
- # Set story timeout to 5 minutes
53
+ # Set per-story timeout (default: 600s)
46
54
  baro --timeout 300 "Add unit tests"
47
55
 
48
- # Force a specific model for all phases
56
+ # Force one model everywhere wins over per-phase routing
49
57
  baro --model opus "Complex architecture redesign"
50
58
 
51
- # Disable model routing (use opus everywhere)
52
- baro --no-model-routing "Build entire app"
59
+ # Pin a single phase to a specific model
60
+ baro --story-model sonnet "Add WebSocket support"
53
61
 
54
- # Dry run - generate plan without executing
62
+ # Dry-run generate plan, save to prd.json, don't execute
55
63
  baro --dry-run "Add REST API"
56
64
 
57
- # Resume interrupted execution (or execute a dry-run plan)
65
+ # Resume an interrupted run (also runs dry-run plans)
58
66
  baro --resume
59
67
 
68
+ # Quick fast-path — skip Architect + Critic + Surgeon, single-story plan
69
+ baro --quick "fix the typo on line 42"
70
+
71
+ # EXPERIMENTAL — push Architect's DecisionDocument through Claude Code's
72
+ # cached system-prompt prefix so stories 2..N hit cache for the DD
73
+ baro --share-architect-cache "Add comprehensive test coverage"
74
+
60
75
  # Specify working directory
61
76
  baro --cwd ~/projects/myapp "Add REST API"
77
+
78
+ # Self-diagnostic and exit
79
+ baro --doctor
62
80
  ```
63
81
 
64
82
  ## How it works
65
83
 
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`
84
+ 1. **Architect** (Opus by default, or gpt-5.5 with `--llm openai`) reads the codebase and writes a `DecisionDocument`: the file paths, names, schemas, API shapes, and library choices every story will use.
85
+ 2. **Planner** — decomposes the goal into a dependency DAG of stories, with the DecisionDocument pinned.
86
+ 3. **Review** — you accept the plan, or press `r` to refine it with feedback.
87
+ 4. **Execute** — stories run in parallel on a fresh `baro/<slug>-<id>` branch. Each story is one Claude Code subprocess (or one Mozaik-native OpenAI session).
88
+ 5. **Critic** (per-turn) Haiku evaluator scores each agent turn against its acceptance criteria. On a fail verdict, an inline corrective lands as the agent's next turn so it self-corrects before the next tool call.
89
+ 6. **Sentry + Librarian** (run-wide) — Sentry flags overlapping Edit/Write tool calls; Librarian indexes one agent's Read/Grep so the next agent doesn't redo the exploration.
90
+ 7. **Surgeon** (on terminal failure) — asks Opus for a richer replan (split / prereq / rewire) instead of dropping a failed story outright.
91
+ 8. **Finalize** — runs the project's build verification and opens a GitHub PR with stories table, stats, time saved, and a summary of every story's commits.
95
92
 
96
93
  ## Config file
97
94
 
@@ -124,122 +121,90 @@ All fields are optional. CLI flags override `.barorc`, and interactive changes o
124
121
  baro [goal] [options]
125
122
 
126
123
  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
124
+ goal Project goal (opens welcome screen if omitted)
125
+
126
+ Provider:
127
+ --llm <name> Provider for every phase: claude (default) or openai.
128
+ openai routes through Mozaik's native OpenAI runner
129
+ (gpt-5.x); requires OPENAI_API_KEY.
130
+
131
+ Model selection:
132
+ --model <name> Override ALL phases: opus, sonnet, haiku
133
+ --no-model-routing Equivalent to --model opus
134
+ --architect-model <name> Pin only the Architect phase
135
+ --planner-model <name> Pin only the Planner phase
136
+ --story-model <name> Pin every Story Agent in the run
137
+ --critic-model <name> Model for the Critic (default: haiku)
138
+ --surgeon-model <name> Model for the Surgeon LLM (default: opus)
139
+
140
+ Run shape:
141
+ --parallel <N> Max concurrent stories per level (0 = unlimited)
142
+ --timeout <seconds> Per-story timeout (default: 600)
143
+ --intra-level-delay <secs> Stagger story spawns within a level so Librarian
144
+ can broadcast first agent's findings (default: 10)
145
+ --quick Trivial-goal fast path skip Architect, force
146
+ 1-story plan, disable Critic + Surgeon
147
+ --dry-run Generate plan only, save to prd.json
148
+ --resume Resume from existing prd.json
149
+ --share-architect-cache EXPERIMENTAL route DecisionDocument through
150
+ Claude Code's --append-system-prompt so stories
151
+ 2..N read it from the prompt cache
152
+ --skip-context Skip CLAUDE.md auto-generation
153
+ --cwd <path> Working directory (default: current)
154
+
155
+ Observers:
156
+ --no-critic Disable live Critic (default: ON)
157
+ --no-librarian Disable cross-agent runtime memory (default: ON)
158
+ --no-sentry Disable file-touch conflict detector (default: ON)
159
+ --no-surgeon Disable Surgeon (default: ON)
160
+ --no-surgeon-llm Use deterministic Surgeon (skip-only) instead
161
+ of the LLM-driven replanner
162
+
163
+ Diagnostics:
164
+ --doctor Run self-diagnostic and exit
165
+ -h, --help Print help
157
166
  ```
158
167
 
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.
186
-
187
- ## Requirements
168
+ ### The participants (Mozaik bus)
188
169
 
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)
192
- - `gh` CLI (optional, for automatic PR creation)
193
-
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:
170
+ Every story runs through a TypeScript Mozaik orchestrator. The orchestrator is itself a Mozaik agentic environment: there is no imperative `run()` method, no top-level `Promise.all` loop. The `Conductor` is a state machine that reacts to typed bus events. Spawning a story, evaluating a turn, replanning the DAG — all reactions on the bus, not steps in a loop.
214
171
 
215
172
  | Participant | Role |
216
173
  | --------------- | ----------------------------------------------------------------- |
174
+ | `Architect` | One Opus (or gpt-5.5) turn before planning — emits a `DecisionDocumentItem` that pins every cross-cutting design decision |
175
+ | `Planner` | Decomposes the goal into a story DAG, with the DecisionDocument pinned |
217
176
  | `Conductor` | Orchestration state machine — drives the run by reacting |
218
177
  | `StoryFactory` | Spawns Story Agents on each `StorySpawnRequest` |
219
- | `StoryAgent` | Runs one story via Claude CLI, with retries and timeout |
178
+ | `StoryAgent` | Runs one story via Claude CLI subprocess (or Mozaik OpenAI session) |
220
179
  | `Librarian` | Cross-agent memory — indexes outputs of exploration tools |
221
180
  | `Sentry` | Flags overlapping file writes across concurrent stories |
222
181
  | `Critic` | Per-turn acceptance-criteria evaluator (default ON, `--no-critic` to disable) |
223
182
  | `Surgeon` | Emits DAG replans when a story fails terminally (default ON, `--no-surgeon` to disable) |
183
+ | `Finalizer` | Runs build verification, opens the GitHub PR with stories table + stats |
224
184
  | `Operator` | Bridges external user commands (TUI, web UI) into bus events |
225
185
  | `Auditor` | JSONL log of every event on the bus (written to `~/.baro/runs/`) |
226
186
  | `Cartographer` | Translates bus events into UI frames for the Rust TUI |
227
187
 
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.
188
+ The bus is open. New participants — CI deployers, Slack notifiers, external ticket triggers — are subscribers and emitters with no changes to the orchestrator. (Adding the Architect was a 200-line change because of this shape; see the [Mozaik post](https://jigjoy.ai/blog/baro-vs-claude-code).)
189
+
190
+ ## Requirements
191
+
192
+ - [Claude CLI](https://docs.anthropic.com/en/docs/claude-cli) installed and authenticated (for `--llm claude`, the default), OR `OPENAI_API_KEY` set (for `--llm openai`)
193
+ - macOS (arm64/x64), Linux (x64/arm64), or Windows (x64)
194
+ - **Node.js 20+** (orchestrator runtime)
195
+ - `gh` CLI (optional, for automatic PR creation)
196
+
197
+ > **Windows note:** Windows 10+ is required. For best TUI experience, use [Windows Terminal](https://aka.ms/terminal) or another modern terminal emulator.
198
+
199
+ ## Architecture
200
+
201
+ Rust binary distributed via npm. TUI built with ratatui, async execution with tokio. Each `baro` invocation spawns the bundled TypeScript [Mozaik](https://github.com/jigjoy-ai/mozaik) orchestrator as a subprocess; the orchestrator owns story execution and emits typed events into a shared `AgenticEnvironment` bus.
231
202
 
232
203
  ## Status & feedback
233
204
 
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.
205
+ baro is a work in progress. I'm actively adding things, testing ideas, and occasionally breaking them — if a run explodes, an [issue on GitHub](https://github.com/jigjoy-ai/baro/issues) with the run's audit log from `~/.baro/runs/` is the fastest way to get it fixed.
238
206
 
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.
207
+ If you like the idea and want to help shape where it goes, PRs are welcome, you can DM me on Twitter [@lotus_sbc](https://twitter.com/lotus_sbc), or jump into the [JigJoy Discord](https://discord.gg/dvxY9J2kWX) where the people building baro and Mozaik hang out.
243
208
 
244
209
  ## License
245
210
 
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(