@allthingsclaude/blueprints 0.4.6 → 0.4.8

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
@@ -140,7 +140,7 @@ Control which models power your agents:
140
140
  | `/email` | Create on-brand HTML email templates (newsletters, announcements, transactional) |
141
141
  | `/pitch` | Create an on-brand HTML presentation deck with speaker notes |
142
142
  | `/og` | Auto-generate Open Graph images for all pages in your project |
143
- | `/imagine` | Generate images using Nano Banana 2 (Gemini/fal.ai) |
143
+ | `/imagine` | Generate images using Nano Banana 2 (Gemini/fal.ai) or GPT Image 2 (fal.ai), or both side-by-side |
144
144
  | `/storyboard` | Extract UI interaction specs from video mockups |
145
145
  | `/showcase` | Design an award-winning landing page with animations and micro-interactions |
146
146
  | `/diagram` | Generate Mermaid diagrams from your codebase |
@@ -442,7 +442,7 @@ Agents are specialized workers launched by commands. Each agent is assigned a mo
442
442
  | `finalize` | `/finalize` | Session wrap-up and commits |
443
443
  | `handoff` | `/handoff` | Context documentation |
444
444
  | `i18n` | `/i18n` | Internationalization auditing and setup |
445
- | `imagine` | `/imagine` | Image generation via Nano Banana 2 |
445
+ | `imagine` | `/imagine` | Image generation via Nano Banana 2 or GPT Image 2 |
446
446
  | `implement` | `/implement` | Autonomous plan execution |
447
447
  | `migrate` | `/migrate` | Dependency upgrades and migrations |
448
448
  | `og` | `/og` | Open Graph image generation for all pages |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: imagine
3
- description: Generate images via Nano Banana 2 API
3
+ description: Generate images via Nano Banana 2 or GPT Image 2
4
4
  tools: Bash
5
5
  model: {{MODEL}}
6
6
  author: "@markoradak"
@@ -16,8 +16,10 @@ You generate images by running a single Bash command. Nothing else.
16
16
  - Do NOT search the web or use the Write tool
17
17
  - If the command fails, report the error and stop immediately
18
18
  - ONLY use these exact API endpoints:
19
- - fal generate: `https://fal.run/fal-ai/nano-banana-2`
20
- - fal edit: `https://fal.run/fal-ai/nano-banana-2/edit`
19
+ - fal nano generate: `https://fal.run/fal-ai/nano-banana-2`
20
+ - fal nano edit: `https://fal.run/fal-ai/nano-banana-2/edit`
21
+ - fal gpt generate: `https://fal.run/openai/gpt-image-2`
22
+ - fal gpt edit: `https://fal.run/openai/gpt-image-2/edit`
21
23
  - gemini: `https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent`
22
24
 
23
25
  ## CRITICAL: Shell escaping
@@ -30,6 +32,7 @@ You generate images by running a single Bash command. Nothing else.
30
32
 
31
33
  Extract from the prompt you received:
32
34
  - `prompt` — the enhanced image prompt
35
+ - `model` — `nano-banana-2`, `gpt-image-2`, or `both`
33
36
  - `api` — "gemini" or "fal"
34
37
  - `mode` — "generate" or "edit"
35
38
  - `name` — snake_case name for the output file
@@ -37,9 +40,38 @@ Extract from the prompt you received:
37
40
  - `resolution` — "1K", "2K", or "4K"
38
41
  - `reference_images` — file paths (only if mode is "edit")
39
42
 
40
- Output file: `generated/imagine_{name}.png`
43
+ ## Template selection
41
44
 
42
- ## fal + generate
45
+ | model | mode | use template |
46
+ |------------------|----------|-----------------------------|
47
+ | nano-banana-2 | generate | `gemini + generate` if api=gemini, else `fal nano + generate` |
48
+ | nano-banana-2 | edit | `gemini + edit` if api=gemini, else `fal nano + edit` |
49
+ | gpt-image-2 | generate | `fal gpt + generate` |
50
+ | gpt-image-2 | edit | `fal gpt + edit` |
51
+ | both | generate | `both + generate` (parallel fal nano + fal gpt) |
52
+ | both | edit | `both + edit` (parallel fal nano + fal gpt) |
53
+
54
+ ## Output file(s)
55
+
56
+ - `model=nano-banana-2` or `gpt-image-2` → `generated/imagine_{name}.png`
57
+ - `model=both` → `generated/imagine_{name}_nano.png` AND `generated/imagine_{name}_gpt.png`
58
+
59
+ ## aspect_ratio → image_size preset (gpt-image-2 only)
60
+
61
+ gpt-image-2 doesn't take `aspect_ratio`/`resolution`. Map to fal preset name:
62
+
63
+ | aspect_ratio | image_size preset |
64
+ |--------------|--------------------|
65
+ | `1:1` | `square_hd` |
66
+ | `16:9` | `landscape_16_9` |
67
+ | `9:16` | `portrait_16_9` |
68
+ | `4:3` | `landscape_4_3` |
69
+ | `3:4` | `portrait_4_3` |
70
+ | anything else| `landscape_4_3` |
71
+
72
+ Always pass `quality: "high"` for gpt-image-2.
73
+
74
+ ## fal nano + generate
43
75
 
44
76
  Copy this template exactly, substituting PROMPT, NAME, ASPECT, RESOLUTION:
45
77
 
@@ -51,7 +83,7 @@ PROMPTEOF
51
83
  node -e 'var fs=require("fs");fs.writeFileSync("/tmp/imagine_payload.json",JSON.stringify({prompt:fs.readFileSync("/tmp/imagine_prompt.txt","utf-8").trim(),aspect_ratio:"ASPECT",resolution:"RESOLUTION"}))' && curl -s "https://fal.run/fal-ai/nano-banana-2" -H "Authorization: Key $FAL_KEY" -H "Content-Type: application/json" -d @/tmp/imagine_payload.json -o /tmp/imagine_resp.json && IMG=$(node -p 'JSON.parse(require("fs").readFileSync("/tmp/imagine_resp.json","utf-8")).images[0].url') && curl -s "$IMG" -o generated/imagine_NAME.png && rm -f /tmp/imagine_resp.json /tmp/imagine_payload.json /tmp/imagine_prompt.txt
52
84
  ```
53
85
 
54
- ## fal + edit
86
+ ## fal nano + edit
55
87
 
56
88
  Copy this template exactly, substituting PROMPT, NAME, ASPECT, RESOLUTION, PATH1/PATH2:
57
89
 
@@ -87,8 +119,62 @@ PROMPTEOF
87
119
  node -e 'var fs=require("fs"),prompt=fs.readFileSync("/tmp/imagine_prompt.txt","utf-8").trim(),imgs=["PATH1","PATH2"],parts=imgs.map(function(p){return {inline_data:{mime_type:"image/"+p.split(".").pop(),data:fs.readFileSync(p).toString("base64")}}});parts.push({text:prompt});fs.writeFileSync("/tmp/imagine_payload.json",JSON.stringify({contents:[{parts:parts}],generationConfig:{responseModalities:["IMAGE"],imageConfig:{aspectRatio:"ASPECT",imageSize:"RESOLUTION"}}}))' && curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent" -H "Content-Type: application/json" -H "x-goog-api-key: $GEMINI_API_KEY" -d @/tmp/imagine_payload.json -o /tmp/imagine_resp.json && node -e 'var fs=require("fs"),r=JSON.parse(fs.readFileSync("/tmp/imagine_resp.json","utf-8")),c=r.candidates,p=c&&c[0]&&c[0].content&&c[0].content.parts,i=p&&p.find(function(x){return x.inlineData||x.inline_data});if(!i){var e=r.error;console.error(e&&e.message||"No image");process.exit(1)}var d=i.inlineData||i.inline_data;fs.writeFileSync("generated/imagine_NAME.png",Buffer.from(d.data,"base64"))' && rm -f /tmp/imagine_resp.json /tmp/imagine_payload.json /tmp/imagine_prompt.txt
88
120
  ```
89
121
 
122
+ ## fal gpt + generate
123
+
124
+ Copy this template exactly, substituting PROMPT, NAME, IMAGE_SIZE (mapped from aspect_ratio per the table above):
125
+
126
+ ```
127
+ mkdir -p generated
128
+ cat << 'PROMPTEOF' > /tmp/imagine_prompt.txt
129
+ PROMPT
130
+ PROMPTEOF
131
+ node -e 'var fs=require("fs");fs.writeFileSync("/tmp/imagine_payload.json",JSON.stringify({prompt:fs.readFileSync("/tmp/imagine_prompt.txt","utf-8").trim(),image_size:"IMAGE_SIZE",quality:"high"}))' && curl -s "https://fal.run/openai/gpt-image-2" -H "Authorization: Key $FAL_KEY" -H "Content-Type: application/json" -d @/tmp/imagine_payload.json -o /tmp/imagine_resp.json && IMG=$(node -p 'JSON.parse(require("fs").readFileSync("/tmp/imagine_resp.json","utf-8")).images[0].url') && curl -s "$IMG" -o generated/imagine_NAME.png && rm -f /tmp/imagine_resp.json /tmp/imagine_payload.json /tmp/imagine_prompt.txt
132
+ ```
133
+
134
+ ## fal gpt + edit
135
+
136
+ Copy this template exactly, substituting PROMPT, NAME, IMAGE_SIZE, PATH1/PATH2:
137
+
138
+ ```
139
+ mkdir -p generated
140
+ cat << 'PROMPTEOF' > /tmp/imagine_prompt.txt
141
+ PROMPT
142
+ PROMPTEOF
143
+ node -e 'var fs=require("fs"),prompt=fs.readFileSync("/tmp/imagine_prompt.txt","utf-8").trim(),imgs=["PATH1","PATH2"],urls=imgs.map(function(p){return "data:image/"+p.split(".").pop()+";base64,"+fs.readFileSync(p).toString("base64")});fs.writeFileSync("/tmp/imagine_payload.json",JSON.stringify({prompt:prompt,image_urls:urls,image_size:"IMAGE_SIZE",quality:"high"}))' && curl -s "https://fal.run/openai/gpt-image-2/edit" -H "Authorization: Key $FAL_KEY" -H "Content-Type: application/json" -d @/tmp/imagine_payload.json -o /tmp/imagine_resp.json && IMG=$(node -p 'JSON.parse(require("fs").readFileSync("/tmp/imagine_resp.json","utf-8")).images[0].url') && curl -s "$IMG" -o generated/imagine_NAME.png && rm -f /tmp/imagine_resp.json /tmp/imagine_payload.json /tmp/imagine_prompt.txt
144
+ ```
145
+
146
+ ## both + generate
147
+
148
+ Runs fal nano-banana-2 and fal gpt-image-2 in parallel within a single Bash call. Substitute PROMPT, NAME, ASPECT, RESOLUTION, IMAGE_SIZE:
149
+
150
+ ```
151
+ mkdir -p generated
152
+ cat << 'PROMPTEOF' > /tmp/imagine_prompt.txt
153
+ PROMPT
154
+ PROMPTEOF
155
+ node -e 'var fs=require("fs"),p=fs.readFileSync("/tmp/imagine_prompt.txt","utf-8").trim();fs.writeFileSync("/tmp/imagine_nano_payload.json",JSON.stringify({prompt:p,aspect_ratio:"ASPECT",resolution:"RESOLUTION"}));fs.writeFileSync("/tmp/imagine_gpt_payload.json",JSON.stringify({prompt:p,image_size:"IMAGE_SIZE",quality:"high"}))' && (curl -s "https://fal.run/fal-ai/nano-banana-2" -H "Authorization: Key $FAL_KEY" -H "Content-Type: application/json" -d @/tmp/imagine_nano_payload.json -o /tmp/imagine_nano_resp.json & curl -s "https://fal.run/openai/gpt-image-2" -H "Authorization: Key $FAL_KEY" -H "Content-Type: application/json" -d @/tmp/imagine_gpt_payload.json -o /tmp/imagine_gpt_resp.json & wait) && NANO=$(node -p 'JSON.parse(require("fs").readFileSync("/tmp/imagine_nano_resp.json","utf-8")).images[0].url') && GPT=$(node -p 'JSON.parse(require("fs").readFileSync("/tmp/imagine_gpt_resp.json","utf-8")).images[0].url') && (curl -s "$NANO" -o generated/imagine_NAME_nano.png & curl -s "$GPT" -o generated/imagine_NAME_gpt.png & wait) && rm -f /tmp/imagine_nano_resp.json /tmp/imagine_gpt_resp.json /tmp/imagine_nano_payload.json /tmp/imagine_gpt_payload.json /tmp/imagine_prompt.txt
156
+ ```
157
+
158
+ ## both + edit
159
+
160
+ Runs fal nano-banana-2/edit and fal gpt-image-2/edit in parallel. Substitute PROMPT, NAME, ASPECT, RESOLUTION, IMAGE_SIZE, PATH1/PATH2:
161
+
162
+ ```
163
+ mkdir -p generated
164
+ cat << 'PROMPTEOF' > /tmp/imagine_prompt.txt
165
+ PROMPT
166
+ PROMPTEOF
167
+ node -e 'var fs=require("fs"),prompt=fs.readFileSync("/tmp/imagine_prompt.txt","utf-8").trim(),imgs=["PATH1","PATH2"],urls=imgs.map(function(p){return "data:image/"+p.split(".").pop()+";base64,"+fs.readFileSync(p).toString("base64")});fs.writeFileSync("/tmp/imagine_nano_payload.json",JSON.stringify({prompt:prompt,aspect_ratio:"ASPECT",resolution:"RESOLUTION",image_urls:urls}));fs.writeFileSync("/tmp/imagine_gpt_payload.json",JSON.stringify({prompt:prompt,image_urls:urls,image_size:"IMAGE_SIZE",quality:"high"}))' && (curl -s "https://fal.run/fal-ai/nano-banana-2/edit" -H "Authorization: Key $FAL_KEY" -H "Content-Type: application/json" -d @/tmp/imagine_nano_payload.json -o /tmp/imagine_nano_resp.json & curl -s "https://fal.run/openai/gpt-image-2/edit" -H "Authorization: Key $FAL_KEY" -H "Content-Type: application/json" -d @/tmp/imagine_gpt_payload.json -o /tmp/imagine_gpt_resp.json & wait) && NANO=$(node -p 'JSON.parse(require("fs").readFileSync("/tmp/imagine_nano_resp.json","utf-8")).images[0].url') && GPT=$(node -p 'JSON.parse(require("fs").readFileSync("/tmp/imagine_gpt_resp.json","utf-8")).images[0].url') && (curl -s "$NANO" -o generated/imagine_NAME_nano.png & curl -s "$GPT" -o generated/imagine_NAME_gpt.png & wait) && rm -f /tmp/imagine_nano_resp.json /tmp/imagine_gpt_resp.json /tmp/imagine_nano_payload.json /tmp/imagine_gpt_payload.json /tmp/imagine_prompt.txt
168
+ ```
169
+
90
170
  ## After the command completes
91
171
 
92
- Report the output path: `generated/imagine_{name}.png`
172
+ Report the output path(s):
173
+ - single model → `generated/imagine_{name}.png`
174
+ - both → `generated/imagine_{name}_nano.png` and `generated/imagine_{name}_gpt.png`
93
175
 
94
176
  If the command failed, report the error. Do NOT retry.
177
+
178
+ ### Known caveat
179
+
180
+ `gpt-image-2/edit` accepts `image_urls` per its schema, but the official examples only show HTTPS URLs. Data URIs may or may not be accepted — if you see an error like "invalid url" or "unable to fetch image" coming from the gpt-image-2 edit endpoint, surface it verbatim and stop. Do not attempt to upload reference images to a host as a workaround.
@@ -12,10 +12,15 @@ Full autonomous development loop. I'll take it from idea to committed code on a
12
12
 
13
13
  **Working Directory**: !`pwd`
14
14
 
15
- **Branch**: !`git branch --show-current 2>/dev/null || echo "Not a git repository"`
15
+ **Is Git Repo**: !`git rev-parse --is-inside-work-tree 2>/dev/null || echo "no"`
16
+
17
+ **Branch**: !`git branch --show-current 2>/dev/null || echo "(not a repo — will scan children)"`
16
18
 
17
19
  **Git Status**:
18
- !`git status --short 2>/dev/null || echo "Not a git repository"`
20
+ !`git status --short 2>/dev/null || echo "(not a repo)"`
21
+
22
+ **Child Git Repos** (for multi-repo mode):
23
+ !`find . -mindepth 2 -maxdepth 2 -name .git -type d 2>/dev/null`
19
24
 
20
25
  **Active Plan**:
21
26
  !`cat {{STATE_FILE}} 2>/dev/null || echo "No active plan"`
@@ -24,7 +29,7 @@ Full autonomous development loop. I'll take it from idea to committed code on a
24
29
  !`ls -1 {{PLANS_DIR}}/PLAN_*.md 2>/dev/null || echo "No plans found"`
25
30
 
26
31
  **Project Detection**:
27
- !`ls package.json tsconfig.json Cargo.toml go.mod pyproject.toml requirements.txt 2>/dev/null || echo "No recognized project files"`
32
+ !`ls package.json tsconfig.json Cargo.toml go.mod pyproject.toml requirements.txt 2>/dev/null || echo "(no root-level project files — multi-repo likely)"`
28
33
 
29
34
  ---
30
35
 
@@ -40,12 +45,13 @@ You are now in **AUTOPILOT MODE** — a full development loop that orchestrates
40
45
 
41
46
  ### Step 0: Parse Arguments
42
47
 
43
- Parse `$ARGUMENTS` for:
48
+ Parse `$ARGUMENTS` for (in order):
44
49
  - **`--full`** flag: If present, run the entire loop without stopping for confirmation — commit automatically, skip approval prompts, maximize autonomy. Remove this flag from the remaining arguments before further processing.
45
- - **Plan name**: If the first remaining word matches an existing plan in `{{PLANS_DIR}}/PLAN_{NN}_{NAME}.md`, treat it as a plan name to execute.
50
+ - **`--repos a,b,c`** flag: If present, overrides auto-detection for multi-repo mode. Value is a comma-separated list of child directory names that should be treated as "affected" regardless of what the plan references. Remove this flag and its value from the remaining arguments. Store as `REPOS_OVERRIDE`.
51
+ - **Plan name**: If the first remaining word matches an existing plan in `{{PLANS_DIR}}/PLAN_{NN}_{NAME}.md` (case-insensitive, matched by the `{NAME}` portion), treat it as a plan name to execute.
46
52
  - **Feature description**: Otherwise, treat remaining arguments as a feature description for brainstorming.
47
53
 
48
- Store the `--full` preference — you'll check it at every commit checkpoint and decision point.
54
+ Store the `--full` and `REPOS_OVERRIDE` preferences — you'll check them at commit checkpoints and in Step 3a respectively.
49
55
 
50
56
  ---
51
57
 
@@ -55,7 +61,14 @@ Follow this decision tree **in order**:
55
61
 
56
62
  #### 1a. Check for Active Plan in STATE.md
57
63
 
58
- Read `{{STATE_FILE}}`. If it contains an active plan (status is `In Progress` or `Paused`):
64
+ Look for `{{STATE_FILE}}` in this search order (first match wins):
65
+ 1. `./{{STATE_FILE}}` — cwd
66
+ 2. `../{{STATE_FILE}}` — parent directory (useful when user accidentally ran from inside a child repo in a multi-repo setup)
67
+
68
+ If found in the parent, emit a notice: "Found {{TASKS_DIR}}/ in parent directory — treating parent as the working root. Suggest running `/autopilot` from `{parent_abspath}` in the future."
69
+
70
+ Then, if STATE.md contains an active plan (status is `In Progress` or `Paused`):
71
+ - If the resolved STATE.md is at `../`, **change working directory to the parent** before continuing. All subsequent steps (discovery, branching, commits) must operate relative to the parent.
59
72
  - Load the plan file referenced in STATE.md
60
73
  - Check which phase we're on and what tasks remain
61
74
  - **If there are uncompleted tasks** → skip to **Step 3** (branch) then **Step 4** (execute)
@@ -134,26 +147,112 @@ Use the Task tool to launch the plan agent (`subagent_type="plan"`) with the fea
134
147
 
135
148
  Wait for the plan agent to complete, then load and display a brief summary of the plan.
136
149
 
137
- **COMMIT CHECKPOINT**: After plan is created, commit it:
138
- - Stage the plan file and STATE.md
139
- - Use the Task tool to launch the commit agent (`subagent_type="commit"`) with context: "docs: add implementation plan for {NAME}"
150
+ **COMMIT CHECKPOINT (conditional)**: After plan is created, commit it **only if cwd is a git repo**:
151
+ - Check: `git rev-parse --is-inside-work-tree 2>/dev/null`
152
+ - If cwd IS a git repo (single-repo or meta-repo case):
153
+ - Stage the plan file and STATE.md
154
+ - Use the Task tool to launch the commit agent (`subagent_type="commit"`) with context: "docs: add implementation plan for {NAME}"
155
+ - If cwd is NOT a git repo (parent-with-child-repos case):
156
+ - **Skip the commit** — the plan and STATE.md stay as uncommitted coordination artifacts at the parent level.
157
+ - Report: "Plan created at parent level (not a git repo) — left uncommitted as coordination artifact. To version it, init a meta-repo at the parent or commit in any workflow you choose."
140
158
 
141
159
  ---
142
160
 
143
- ### Step 3: Create Feature Branch
161
+ ### Step 3: Detect Repositories & Create Feature Branch(es)
162
+
163
+ Before starting implementation, detect the repository topology and create feature branches.
164
+
165
+ #### 3a. Discover Repos & Determine Mode
166
+
167
+ Always perform both discoveries below before deciding mode. Mode is chosen based on **what the plan references**, not purely on whether cwd is a git repo. This correctly handles three distinct layouts: plain single-repo, parent-is-not-a-repo-but-children-are, and parent-is-a-meta-repo-with-child-repos.
168
+
169
+ **Discovery 1 — is cwd itself a git repo?**
170
+ ```bash
171
+ git rev-parse --is-inside-work-tree 2>/dev/null
172
+ ```
173
+ Store as `CWD_IS_REPO` (true/false).
174
+
175
+ **Discovery 2 — are there child git repos?**
176
+ ```bash
177
+ find . -mindepth 2 -maxdepth 2 -name .git -type d 2>/dev/null
178
+ ```
179
+ Store the list as `CHILD_REPOS`. (Avoid `for` / `while` loops in inline shell — some harnesses reject control-flow statements.)
180
+
181
+ **Discovery 3 — which repos does the plan reference?**
182
+ If there's an active plan file (`{{PLANS_DIR}}/PLAN_{NN}_{NAME}.md`), for each entry in `CHILD_REPOS`, grep the plan for its directory name:
183
+ ```bash
184
+ grep -c "{child_repo_name}" {{PLANS_DIR}}/PLAN_{NN}_{NAME}.md
185
+ ```
186
+ Any child with **> 0 mentions** goes into `AFFECTED_CHILDREN`.
187
+
188
+ **Mode decision** (evaluate in this order, first match wins):
189
+
190
+ | Condition | Mode | `AFFECTED_REPOS` | Notes |
191
+ |---|---|---|---|
192
+ | User passed `--repos a,b,...` | multi | `{a, b, ...}` | Explicit override wins over all auto-detection |
193
+ | `AFFECTED_CHILDREN` is non-empty | multi | `AFFECTED_CHILDREN` | Applies even if cwd is itself a git repo (meta-repo case). The parent repo, if any, is NOT branched — it stays where it is. |
194
+ | `CWD_IS_REPO` is true | single | `[.]` | No child repos mentioned in plan → plain single-repo |
195
+ | Otherwise | fail | — | "No git repo found here, and no child directories with `.git/` are referenced by the plan. Either cd into a repo, initialize one, or verify the plan references the correct repo directories." |
196
+
197
+ **Ambiguity warning**: If `CHILD_REPOS` is non-empty but `AFFECTED_CHILDREN` is empty AND `CWD_IS_REPO` is true (falling through to single-repo mode), this might indicate a plan authoring mistake. Emit a warning before proceeding:
198
+
199
+ > "Detected child git repos {list} but the plan does not reference any of them by directory name. Proceeding with single-repo mode (branching in cwd). If you intended multi-repo, either (a) update the plan's file paths to include the repo prefix (e.g., `{child_name}/src/...`), or (b) re-run with `--repos {child_name}` to force multi-repo mode."
200
+
201
+ Prompt the user to confirm before continuing (in `--full` mode, auto-continue with the warning still logged).
202
+
203
+ **Important — meta-repo case**: If cwd is a git repo AND there are affected children, we enter **multi-repo mode**. Branches are created only in the affected children. The parent (meta) repo is left alone — no branch, no commits, no state mutations. STATE.md changes at the parent level remain uncommitted coordination artifacts. If the user later wants to version those in the meta-repo, they can commit them manually via `/commit`.
204
+
205
+ Report the decision:
206
+ - Single-repo: "Branching in this repo."
207
+ - Multi-repo: "Plan touches {N} child repo(s): {list}. Will branch in each. Parent repo (if any) left untouched."
208
+
209
+ #### 3b. Pre-flight: Check for Dirty Working State
210
+
211
+ Before branching, guard against clobbering uncommitted work in any target repo.
212
+
213
+ For each repo in `AFFECTED_REPOS`:
214
+ 1. `cd {repo}` (skip for single-repo mode where this is cwd)
215
+ 2. Run: `git status --short`
216
+ 3. If non-empty → mark this repo as "dirty" and collect the output.
217
+ 4. `cd -`
218
+
219
+ If any repo is dirty:
220
+ - Report to the user: list each dirty repo and its `git status --short` output.
221
+ - Ask: "Uncommitted changes found in {N} repo(s). How should I proceed?
222
+ - **stash** — I'll stash the changes in each dirty repo before branching (`git stash push -u -m 'autopilot pre-branch'`). You can restore with `git stash pop` later.
223
+ - **abort** — stop autopilot so you can handle the changes manually.
224
+ - **continue** — proceed anyway; the uncommitted changes will carry onto the new branch (only safe if you want them there)."
225
+ - In `--full` mode, default to **abort** (never silently discard or carry unintended work).
226
+ - Wait for user decision before proceeding.
227
+
228
+ If all repos are clean (or user chose stash/continue), proceed to 3c.
229
+
230
+ #### 3c. Create Branches
144
231
 
145
- Before starting implementation, create a feature branch:
232
+ Determine the branch name:
233
+ - Convert plan name to lowercase kebab-case
234
+ - Prefix with `feat/` (e.g., plan "USER_AUTH" → branch `feat/user-auth`)
146
235
 
147
- 1. Determine the branch name from the plan name:
148
- - Convert plan name to lowercase kebab-case
149
- - Prefix with `feat/` (e.g., plan "USER_AUTH" → branch `feat/user-auth`)
150
- 2. Check if the branch already exists:
151
- - If yes and we're resuming → switch to it: `git checkout feat/{name}`
152
- - If yes and NOT resuming → switch to it (it may have prior work)
153
- - If no → create it: `git checkout -b feat/{name}`
154
- 3. Confirm the branch: `git branch --show-current`
236
+ **Single-repo mode**: run branching in cwd.
237
+ **Multi-repo mode**: run branching in each affected repo.
155
238
 
156
- Report: "Working on branch: `feat/{name}`"
239
+ For each target repo, in order:
240
+ 1. `cd {repo}` (or stay at cwd for single-repo)
241
+ 2. Check current branch: `git branch --show-current`
242
+ 3. Check if `feat/{name}` exists:
243
+ - Exists + we're resuming → switch to it: `git checkout feat/{name}`
244
+ - Exists + not resuming → switch to it (prior work)
245
+ - Does not exist → create it: `git checkout -b feat/{name}`
246
+ 4. Confirm the branch.
247
+ 5. `cd -` (return to parent)
248
+
249
+ **STATE UPDATE**: Add a `**Repos**:` line to STATE.md header listing the affected repos and the branch name:
250
+ ```markdown
251
+ **Repos**: cli-shopnosis-shopper-app, cli-shopnosis-shopper-server
252
+ **Branch**: feat/{name}
253
+ ```
254
+
255
+ Report: "Working on branch `feat/{name}` in {N} repo(s): {list}"
157
256
 
158
257
  ---
159
258
 
@@ -181,10 +280,10 @@ Count the `- [ ]` uncompleted tasks in the current phase.
181
280
  Use the Task tool to launch the showcase agent (`subagent_type="showcase"`) with the plan context and any reference files from `{{TASKS_DIR}}/references/`.
182
281
 
183
282
  **For `/implement` mode:**
184
- Use the Task tool to launch the implement agent (`subagent_type="implement"`) with the plan name and instruction to work on the current phase only (e.g., "Execute Phase 1 only, then stop").
283
+ Use the Task tool to launch the implement agent (`subagent_type="implement"`) with the plan name and instruction to work on the current phase only (e.g., "Execute Phase 1 only, then stop"). **Multi-repo mode**: include in the prompt the list of affected repos and their paths so the agent writes files into the correct sub-directories (file paths in the plan should already be prefixed with the repo name).
185
284
 
186
285
  **For `/parallelize` mode:**
187
- Use the Task tool to launch the parallelize orchestrator (`subagent_type="parallelize"`) with the plan name and instruction to work on the current phase only.
286
+ Use the Task tool to launch the parallelize orchestrator (`subagent_type="parallelize"`) with the plan name and instruction to work on the current phase only. **Multi-repo mode**: include the list of affected repos in the prompt.
188
287
 
189
288
  Wait for the agent to complete. Review its summary.
190
289
 
@@ -194,11 +293,24 @@ Present the blockers to the user and ask how to proceed. Do NOT continue until b
194
293
  #### 4c. Commit the Phase
195
294
 
196
295
  **COMMIT CHECKPOINT**: After each phase completes:
296
+
297
+ **Single-repo mode**:
197
298
  - Use the Task tool to launch the commit agent (`subagent_type="commit"`) with context describing what was accomplished in this phase
198
299
  - The commit agent will determine the appropriate prefix (`feat:`, `fix:`, `refactor:`, `chore:`, etc.) based on the nature of the changes
199
300
  - The commit message should reference the plan and phase (e.g., "feat: implement user authentication (PLAN_AUTH Phase 1)")
200
301
 
201
- **STATE UPDATE**: Read and update `{{STATE_FILE}}`:
302
+ **Multi-repo mode**:
303
+ - Before the commit loop, capture the parent directory: `PARENT_DIR=$(pwd)`.
304
+ - For each repo in `AFFECTED_REPOS`:
305
+ 1. `cd "$PARENT_DIR/{repo}"` (use the absolute path — never rely on `cd -` chains)
306
+ 2. Check `git status --short` — if empty, skip this repo for this phase (no changes here).
307
+ 3. If there are changes, launch the commit agent (`subagent_type="commit"`) with context including (a) what was accomplished in this phase, and (b) which repo this is. The commit runs inside the repo's working directory.
308
+ - After the loop, **unconditionally** return: `cd "$PARENT_DIR"`.
309
+ - Confirm cwd is the parent before the STATE.md update below (run `pwd` to verify).
310
+ - A single phase may produce commits in multiple repos; that's expected.
311
+ - Record the resulting commit hashes per repo for the final report.
312
+
313
+ **STATE UPDATE** (always from the parent dir — STATE.md lives at `$PARENT_DIR/{{STATE_FILE}}`): Read and update `{{STATE_FILE}}`:
202
314
  - Increment `**Phase**` to the next phase number
203
315
  - Keep `**Status**` as `🚧 In Progress`
204
316
  - Update `**Updated**` timestamp
@@ -216,7 +328,9 @@ After committing and updating STATE.md, check if there are more phases remaining
216
328
 
217
329
  ### Step 5: Validate & Fix
218
330
 
219
- After all phases are implemented and committed, run validation. Each step uses a subagent:
331
+ After all phases are implemented and committed, run validation. Each step uses a subagent.
332
+
333
+ **Multi-repo mode**: every validation step below runs **once per affected repo**, with `cd {repo}` before launching the agent. Aggregate results per repo into the final report. A failure in one repo does not short-circuit the others — validate all, then report aggregated findings and decide together.
220
334
 
221
335
  #### 5a. Audit
222
336
 
@@ -293,7 +407,9 @@ Review security report:
293
407
  - Update `**Updated**` timestamp
294
408
  - Update all task statuses in the task tables under `## Plans` to reflect final state
295
409
 
296
- After everything is done (or stopped), provide a final summary:
410
+ After everything is done (or stopped), provide a final summary.
411
+
412
+ **Single-repo mode**:
297
413
 
298
414
  ```markdown
299
415
  **Autopilot Complete**
@@ -305,7 +421,6 @@ After everything is done (or stopped), provide a final summary:
305
421
  **Commits Made**:
306
422
  - `{hash}` {commit message 1}
307
423
  - `{hash}` {commit message 2}
308
- - `{hash}` {commit message 3}
309
424
 
310
425
  **What Was Done**:
311
426
  - [Phase 1 summary]
@@ -322,6 +437,45 @@ After everything is done (or stopped), provide a final summary:
322
437
  - Or continue working: `/autopilot` (will resume from STATE.md)
323
438
  ```
324
439
 
440
+ **Multi-repo mode**:
441
+
442
+ ```markdown
443
+ **Autopilot Complete (multi-repo)**
444
+
445
+ **Plan**: {NAME}
446
+ **Branch**: `feat/{name}` (same across all affected repos)
447
+ **Status**: {Complete / Partially Complete}
448
+
449
+ **Per-repo results**:
450
+
451
+ ### {repo-name-1}
452
+ - Branch: `feat/{name}`
453
+ - Commits:
454
+ - `{hash}` {commit message}
455
+ - `{hash}` {commit message}
456
+ - Next: `cd {repo-name-1} && gh pr create`
457
+
458
+ ### {repo-name-2}
459
+ - Branch: `feat/{name}`
460
+ - Commits:
461
+ - `{hash}` {commit message}
462
+ - Next: `cd {repo-name-2} && gh pr create`
463
+
464
+ **What Was Done**:
465
+ - [Phase 1 summary]
466
+ - [Phase 2 summary]
467
+
468
+ **Validation Results**:
469
+ - Audit: {result per repo}
470
+ - Tests: {result per repo}
471
+ - Security: {result per repo}
472
+
473
+ **Next Steps**:
474
+ - Review changes in each repo individually.
475
+ - Open one PR per repo (they can reference each other's branch name).
476
+ - Or resume: `/autopilot` will pick up from STATE.md.
477
+ ```
478
+
325
479
  ---
326
480
 
327
481
  ## Commit Checkpoint Rules
@@ -352,6 +506,19 @@ Autopilot commits **early and often** using the commit agent (`subagent_type="co
352
506
  - BUT always stop for: blockers and validation failures that can't be auto-fixed
353
507
  - Never force-push, delete branches, or make destructive changes without asking
354
508
 
509
+ ### Multi-Repo Mode
510
+ - **Trigger**: multi-repo mode activates whenever the plan references child directories that are git repos — regardless of whether the parent (cwd) is itself a git repo. The parent is never branched in this mode.
511
+ - Three scenarios it handles:
512
+ 1. Parent is NOT a git repo + children are → multi-repo.
513
+ 2. Parent IS a git repo (meta-repo) + children are + plan mentions them → multi-repo, meta-repo untouched.
514
+ 3. Parent IS a git repo + no children mentioned in plan → single-repo (plain case).
515
+ - The same branch name (`feat/{name}`) is created in every "affected" child repo.
516
+ - Commits run per-repo: `cd {repo}`, check `git status`, launch commit agent, `cd -`.
517
+ - Validation (audit / test / security / a11y) runs per-repo. Failures in one repo don't short-circuit others — validate all, report together.
518
+ - STATE.md lives at the parent level and is NOT committed by autopilot; it's a coordination artifact. If the parent is itself a meta-repo and the user wants to version STATE.md/plan updates, they can do so manually via `/commit` in the parent — autopilot does not touch the parent.
519
+ - The plan document should prefix file paths with the repo directory name (e.g., `cli-shopnosis-shopper-server/src/models/...`) so the implement/parallelize agents write into the right sub-directory, and so the grep-for-mentions step correctly detects affected repos.
520
+ - If the user passes `--repos repoA,repoB`, override auto-detection with that explicit list.
521
+
355
522
  ### Compose Existing Agents
356
523
  - Use the existing subagent types: `bootstrap`, `plan`, `implement`, `parallelize`, `showcase`, `audit`, `test`, `secure`, `a11y`, `commit`, `update`
357
524
  - Do NOT try to do their jobs inline — delegate to specialists
@@ -14,13 +14,23 @@ $ARGUMENTS
14
14
 
15
15
  ## Instructions
16
16
 
17
- 1. If no API key is available, stop and tell the user to set `GEMINI_API_KEY` or `FAL_KEY`.
17
+ 1. **API key check.** If no API key is available, stop and tell the user to set `GEMINI_API_KEY` or `FAL_KEY`.
18
18
 
19
- 2. Determine `api`: "gemini" if GEMINI_API_KEY is available, "fal" otherwise.
19
+ 2. **Determine `model`** one of `nano-banana-2`, `gpt-image-2`, or `both`. Resolve in this order; first match wins:
20
+ 1. **Explicit flag** in `$ARGUMENTS`: `--model=nano-banana-2`, `--model=gpt-image-2`, or `--model=both`. Strip the flag from the prompt.
21
+ 2. **Prefix**: `nano:`, `gpt:`, or `both:` at the start. Strip it.
22
+ 3. **Natural language mention**: phrases like "with gpt-image-2", "use gpt image", "using gpt", "with nano banana", "using nano", "with both models", "compare both", "render with both". Map to the right model and remove the directive cleanly from the prompt.
23
+ 4. **Auto-heuristic** — only if none of the above matched. Bias conservatively toward `nano-banana-2` since gpt-image-2 is materially more expensive on fal:
24
+ - **Strong text-rendering signals** → `gpt-image-2`. Only triggers when the user clearly wants legible text rendered: quoted strings the prompt asks to render (`"..."`, `'...'` paired with verbs like "that says", "with the words", "reading", "labeled"), or explicit "render this text", "billboard that reads", "sign that says", "headline:", "caption:", "infographic with text". Soft typography hints alone ("logo", "poster", "book cover", "magazine cover") do **not** trigger gpt — those go to nano.
25
+ - **Otherwise** → `nano-banana-2` (default — covers people, scenes, products, soft typography, and ambiguous cases).
20
26
 
21
- 3. Check if the user included any image file paths. If yes, mode is "edit". If no, mode is "generate".
27
+ 3. **Determine `api`** based on `model`:
28
+ - `gpt-image-2` or `both` → `fal` (requires `FAL_KEY`; if missing, stop and tell the user).
29
+ - `nano-banana-2` → `gemini` if `GEMINI_API_KEY` is available, else `fal`.
22
30
 
23
- 4. Determine `aspect_ratio` and `resolution`:
31
+ 4. **Mode**: if the user included any image file paths, `mode` is `edit`. Otherwise `generate`.
32
+
33
+ 5. **Determine `aspect_ratio` and `resolution`** (used by nano-banana-2; mapped to `image_size` preset by the agent for gpt-image-2):
24
34
  - If the user explicitly requests a size or ratio (e.g., "16:9", "square", "4K"), use that.
25
35
  - If the user describes where the image will be used, infer the best fit:
26
36
  - Hero banner / website header → `16:9`, `2K`
@@ -34,17 +44,21 @@ $ARGUMENTS
34
44
  - Valid aspect ratios: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`
35
45
  - Valid resolutions: `1K`, `2K`, `4K`
36
46
 
37
- 5. Enhance the user's description into a detailed prompt (~100 words max). Add lighting, composition, camera angle, style, mood — stay faithful to the original request.
47
+ 6. Enhance the user's description into a detailed prompt (~100 words max). Add lighting, composition, camera angle, style, mood — stay faithful to the original request. Do NOT strip out text the user wants rendered in the image (quoted strings, headlines, etc.) — preserve it verbatim.
38
48
 
39
- 6. Derive a short snake_case name (e.g., `mountain_cabin`).
49
+ 7. Derive a short snake_case name (e.g., `mountain_cabin`).
40
50
 
41
- 7. Launch the imagine agent via Task tool with `subagent_type="imagine"` passing:
51
+ 8. Launch the imagine agent via Task tool with `subagent_type="imagine"` passing:
42
52
  - `prompt`: the enhanced prompt text
43
- - `api`: "gemini" or "fal"
44
- - `mode`: "generate" or "edit"
53
+ - `model`: `nano-banana-2`, `gpt-image-2`, or `both`
54
+ - `api`: `gemini` or `fal`
55
+ - `mode`: `generate` or `edit`
45
56
  - `name`: the snake_case name
46
- - `aspect_ratio`: e.g., "16:9"
47
- - `resolution`: e.g., "2K"
57
+ - `aspect_ratio`: e.g., `16:9`
58
+ - `resolution`: e.g., `2K`
48
59
  - `reference_images`: list of absolute file paths (if edit mode)
49
60
 
50
- 8. After the agent returns, use the Read tool to display `generated/imagine_{name}.png` inline. Show the path.
61
+ 9. After the agent returns, display the output(s) inline with the Read tool:
62
+ - `model=nano-banana-2` or `gpt-image-2` → `generated/imagine_{name}.png`
63
+ - `model=both` → `generated/imagine_{name}_nano.png` AND `generated/imagine_{name}_gpt.png`
64
+ Show the path(s).
@@ -43,58 +43,73 @@ Parse the brief for: presentation type, audience, slide count, key points, and s
43
43
 
44
44
  ### If the brief is empty or vague:
45
45
 
46
- Conduct a focused discovery questionnaire. Ask questions **one at a time**, adapting based on previous answers. Don't dump all questions at once this should feel like a conversation.
46
+ Conduct a focused discovery using the **AskUserQuestion tool** for interactive selection. The user should be able to click/select options rather than typing numbers. Adapt follow-up questions based on previous answers.
47
47
 
48
48
  #### First, determine the repo context:
49
49
 
50
50
  Check the "Existing Brand Brief", "Project Identity", "Package Description", and "Product Features & Stats" sections above. If meaningful product information was detected (README with clear positioning, product features, stats, metrics, or an existing `design/brand-brief.md`), this is a **brand-rich repo** — the codebase contains enough to derive brand identity, product messaging, and content automatically.
51
51
 
52
- #### Always ask (every context):
53
-
54
- **Q1: What's the presentation for?**
55
- - Product launch
56
- - Investor pitch
57
- - Conference talk
58
- - Team update
59
- - Sales demo
60
- - Workshop
61
- - Custom (describe)
62
-
63
- **Q2: Who's the audience?**
64
- - Investors
65
- - Developers
66
- - Customers
67
- - Team / internal
68
- - Executives
69
- - Conference attendees
70
- - Custom (describe)
71
-
72
- **Q3: How many slides?** (default: 10-12)
73
-
74
- **Q4: Key points to cover?**
75
- - List specific topics, features, stats, or talking points
76
- - Or say "derive from codebase" to auto-extract from README, features, and product info
77
-
78
- #### Only ask in bare repos (no brand or product info detected):
79
-
80
- If no README positioning, brand brief, features, or product info was found, the agent has nothing to derive from — so you need to ask:
81
-
82
- **Q5: What's the brand/style direction?**
83
- - Minimal / editorial (whitespace, typography-driven)
84
- - Bold / high-contrast (oversized type, strong colors)
85
- - Dark / premium (dark backgrounds, glow effects, sleek)
86
- - Technical / developer (terminal aesthetics, monospace)
87
- - Corporate / clean (structured, professional)
88
- - Playful / colorful (gradients, rounded shapes, vibrant)
89
-
90
- **Q6: What content should the deck cover?**
91
- (Free text — outline the narrative arc, key arguments, data points, or story beats)
92
-
93
- #### In brand-rich repos, skip Q5-Q6:
52
+ #### Round 1 — Core questions (single AskUserQuestion call, 3 questions):
53
+
54
+ **Q1** (header: "Presentation type", multiSelect: false):
55
+ Question: "What's the presentation for?"
56
+ Options:
57
+ - label: "Product launch" / description: "Announce a new product, feature, or version"
58
+ - label: "Investor pitch" / description: "Fundraising deck — vision, traction, the ask"
59
+ - label: "Conference talk" / description: "Keynote or session for an audience of peers"
60
+ - label: "Sales demo" / description: "Walk a prospect through product value and pricing"
61
+
62
+ **Q2** (header: "Audience", multiSelect: false):
63
+ Question: "Who's the audience?"
64
+ Options:
65
+ - label: "Investors" / description: "VCs, angels, or strategic capital partners"
66
+ - label: "Developers" / description: "Technical practitioners and engineering teams"
67
+ - label: "Customers / prospects" / description: "Buyers, end users, or decision-makers"
68
+ - label: "Team / internal" / description: "Colleagues, executives, or cross-functional peers"
69
+
70
+ **Q3** (header: "Slide count", multiSelect: false):
71
+ Question: "How many slides should the deck have?"
72
+ Options:
73
+ - label: "6-8 slides" / description: "Tight lightning-talk pacing"
74
+ - label: "10-12 slides (Recommended)" / description: "Standard pitch / launch length"
75
+ - label: "15-18 slides" / description: "Deeper narrative with room for demo and proof"
76
+ - label: "20+ slides" / description: "Long-form workshop or detailed walkthrough"
77
+
78
+ #### Round 2 Content direction (single AskUserQuestion call, 1 question):
79
+
80
+ **Q4** (header: "Key points", multiSelect: false):
81
+ Question: "What should the deck cover?"
82
+ Options:
83
+ - label: "Derive from codebase" / description: "Auto-extract from README, features, and product info"
84
+ - label: "Narrative arc" / description: "Problem solution → proof → CTA"
85
+ - label: "Feature-led" / description: "Core capabilities with demos and use cases"
86
+ - label: "Metrics-led" / description: "Traction, growth, and data-driven highlights"
87
+
88
+ #### Round 3 Brand & style (only for bare repos, single AskUserQuestion call):
89
+
90
+ Only ask these if **no brand files, README positioning, or product info were detected**. In brand-rich repos, skip to confirmation.
91
+
92
+ **Q1** (header: "Style", multiSelect: false):
93
+ Question: "What visual style fits your brand?"
94
+ Options:
95
+ - label: "Minimal / editorial" / description: "Whitespace, typography-driven, structural grids"
96
+ - label: "Bold / dark premium" / description: "High-contrast, oversized type, dark backgrounds, glow"
97
+ - label: "Technical / developer" / description: "Terminal mockups, monospace, code aesthetics"
98
+ - label: "Corporate / clean" / description: "Structured, professional, restrained palette"
99
+
100
+ **Q2** (header: "Tone", multiSelect: false):
101
+ Question: "What's the tone of voice for the deck?"
102
+ Options:
103
+ - label: "Confident / bold" / description: "Declarative, punchy, no hedging"
104
+ - label: "Warm / conversational" / description: "Approachable, human, inviting"
105
+ - label: "Authoritative / precise" / description: "Data-driven, measured, expert"
106
+ - label: "Playful / energetic" / description: "Witty, spirited, brand-forward"
107
+
108
+ #### In brand-rich repos, skip Round 3:
94
109
 
95
110
  The agent will automatically analyze the codebase for brand identity, product features, stats, and messaging. Visual style and content direction will be derived from the existing design system and product information. The user can still override any of these when confirming the brief.
96
111
 
97
- After gathering answers, **summarize the complete brief and ask for confirmation** before launching the agent. Include what will be auto-derived from the codebase so the user can correct anything.
112
+ After gathering all answers, **summarize the complete brief and ask for confirmation** before launching the agent. Include what will be auto-derived from the codebase so the user can correct anything.
98
113
 
99
114
  ### Launching the Agent
100
115
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allthingsclaude/blueprints",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "Claude Code commands and agents for enhanced AI-assisted development workflows",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",