octocode-cli 1.3.0 → 1.5.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 +129 -28
- package/out/chunks/chunk-7476PETK.js +309 -0
- package/out/chunks/chunk-CVNNNSMQ.js +26 -0
- package/out/chunks/chunk-OQBJTZWK.js +60 -0
- package/out/chunks/chunk-UCZCF3BQ.js +9 -0
- package/out/chunks/command-help-specs-JZXVSLZ5.js +8 -0
- package/out/chunks/commands-XBFPLHSQ.js +8 -0
- package/out/chunks/help-P7TCOYAJ.js +10 -0
- package/out/chunks/main-help-ULF5PAQY.js +10 -0
- package/out/chunks/prompts-5E6VKRX5.js +8 -0
- package/out/chunks/spinner-URV2OX6O.js +8 -0
- package/out/chunks/tool-command-M6VA7P2F.js +8 -0
- package/out/octocode-cli.js +1 -1
- package/package.json +5 -3
- package/skills/README.md +60 -58
- package/skills/agentic-flow-best-practices/SKILL.md +280 -0
- package/skills/agentic-flow-best-practices/references/agent-collaboration-patterns.md +75 -0
- package/skills/agentic-flow-best-practices/references/pr-review-agent-example.md +47 -0
- package/skills/agentic-flow-best-practices/references/resources.md +112 -0
- package/skills/octocode-brainstorming/.env.example +11 -0
- package/skills/octocode-brainstorming/SKILL.md +262 -0
- package/skills/octocode-brainstorming/scripts/tavily-search.mjs +138 -0
- package/skills/octocode-chrome-devtools/README.md +541 -0
- package/skills/octocode-chrome-devtools/SKILL.md +197 -0
- package/skills/octocode-chrome-devtools/agents/openai.yaml +7 -0
- package/skills/octocode-chrome-devtools/references/CDP_AGENT_REFERENCE.md +401 -0
- package/skills/octocode-chrome-devtools/references/CHROME_FLAGS.md +234 -0
- package/skills/octocode-chrome-devtools/references/INTENTS.md +108 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_AUTH.md +179 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_AUTOMATION.md +214 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_DEBUG.md +329 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_ENVIRONMENT.md +237 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_INSPECT.md +263 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_STORAGE_CONSENT.md +214 -0
- package/skills/octocode-chrome-devtools/references/RECOVERY.md +39 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS.md +43 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS_ASYNC_WORKERS.md +345 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS_BROWSER.md +403 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS_OBSERVE.md +275 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS_SPECIAL.md +18 -0
- package/skills/octocode-chrome-devtools/scripts/cdp-runner.mjs +503 -0
- package/skills/octocode-chrome-devtools/scripts/cdp-sandbox.mjs +123 -0
- package/skills/octocode-chrome-devtools/scripts/cdp-template.mjs +81 -0
- package/skills/octocode-chrome-devtools/scripts/octocode-chrome-devtools.vpn.example.json +8 -0
- package/skills/octocode-chrome-devtools/scripts/open-browser.mjs +362 -0
- package/skills/octocode-chrome-devtools/scripts/sourcemap-resolver.mjs +193 -0
- package/skills/octocode-chrome-devtools/scripts/undercover.mjs +226 -0
- package/skills/octocode-design/README.md +2 -2
- package/skills/octocode-documentation-writer/README.md +1 -1
- package/skills/octocode-engineer/README.md +1 -1
- package/skills/octocode-engineer/SKILL.md +137 -306
- package/skills/octocode-engineer/references/cli-reference.md +13 -0
- package/skills/octocode-engineer/references/output-files.md +3 -3
- package/skills/octocode-engineer/scripts/run.js +146 -146
- package/skills/octocode-engineer/src/pipeline/main.ts +1 -17
- package/skills/octocode-engineer/src/pipeline/progress.ts +4 -0
- package/skills/octocode-engineer/src/reporting/summary-md.test.ts +48 -0
- package/skills/octocode-engineer/src/reporting/summary-md.ts +43 -2
- package/skills/octocode-install/SKILL.md +1 -1
- package/skills/octocode-pull-request-reviewer/README.md +5 -5
- package/skills/octocode-pull-request-reviewer/SKILL.md +1 -1
- package/skills/octocode-research/AGENTS.md +1 -1
- package/skills/octocode-research/README.md +2 -2
- package/skills/octocode-research/docs/ARCHITECTURE.md +1 -1
- package/skills/octocode-research/scripts/server.js +184 -239
- package/skills/octocode-research/src/routes/github.ts +4 -21
- package/skills/octocode-research/src/routes/local.ts +4 -21
- package/skills/octocode-research/src/utils/fileContentTransform.ts +44 -0
- package/skills/octocode-search-skill/SKILL.md +337 -0
- package/skills/octocode-search-skill/references/agent-skills-guide.md +177 -0
- package/skills/octocode-search-skill/references/discovery-surfaces.md +162 -0
- package/skills/octocode-search-skill/references/fetch-and-create-locally.md +57 -0
- package/skills/octocode-search-skill/references/install-reference.md +130 -0
- package/skills/octocode-search-skill/references/references-template.md +27 -0
- package/skills/octocode-search-skill/references/references.md +62 -0
- package/skills/octocode-slides/README.md +307 -0
- package/skills/octocode-slides/SKILL.md +410 -0
- package/skills/octocode-slides/references/01-brief.md +156 -0
- package/skills/octocode-slides/references/02-research.md +149 -0
- package/skills/octocode-slides/references/03-outline.md +172 -0
- package/skills/octocode-slides/references/04-design.md +301 -0
- package/skills/octocode-slides/references/05-implementation.md +213 -0
- package/skills/octocode-slides/references/06-review.md +258 -0
- package/skills/octocode-slides/references/animation.md +281 -0
- package/skills/octocode-slides/references/design-system.md +316 -0
- package/skills/octocode-slides/references/html-templates.md +673 -0
- package/skills/octocode-slides/references/image-generation.md +448 -0
- package/skills/octocode-slides/references/resources.md +840 -0
- package/skills/octocode-slides/references/slide-rules.md +541 -0
- package/skills/octocode-slides/references/wireframes.md +727 -0
- package/skills/octocode-slides/scripts/animation.js +182 -0
- package/skills/octocode-slides/scripts/base.css +353 -0
- package/skills/octocode-slides/scripts/base.html +655 -0
- package/skills/octocode-slides/scripts/generate_image.py +221 -0
- package/skills/octocode-slides/scripts/navbridge.js +79 -0
- package/skills/octocode-slides/scripts/presenter.js +316 -0
- package/skills/octocode-slides/scripts/slide.html +248 -0
- package/skills/octocode-stats/SKILL.md +73 -0
- package/skills/octocode-stats/assets/template.html +1332 -0
- package/skills/octocode-stats/scripts/build_dashboard.mjs +407 -0
- package/out/chunks/chunk-LH4AZJPA.js +0 -389
- package/out/chunks/command-help-specs-CQ3RBLP6.js +0 -8
- package/out/chunks/commands-M3QTWKWE.js +0 -51
- package/out/chunks/help-XPXP46ZT.js +0 -10
- package/out/chunks/main-help-HXFAFHPG.js +0 -10
- package/out/chunks/tool-command-VHFLPIHY.js +0 -8
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
# Image Generation — Nano Banana 2 (Gemini 3.1 Flash Image)
|
|
2
|
+
|
|
3
|
+
> **Status:** Opt-in. The default image rule in `references/05-implementation.md` is still "do not silently generate". This doc tells you **how** to generate when the user explicitly asks for it, and how to keep the output consistent with the deck's design system.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## TL;DR — which path
|
|
8
|
+
|
|
9
|
+
| Path | Use when | Auth | Effort |
|
|
10
|
+
|------|----------|------|--------|
|
|
11
|
+
| **A — Direct API via `google-genai` SDK** (default) | Standard case. Stable, scriptable, no third party. | `GEMINI_API_KEY` (AI Studio) | Add `scripts/generate_image.py`, set `GEMINI_API_KEY`. |
|
|
12
|
+
| **B — Third-party CLI (`belt` from inference.sh)** | User already on inference.sh, wants one-liner shell calls, or needs Google Search grounding out of the box. | `belt login` (inference.sh account) | `npm i -g @inferencesh/cli`, `belt login`. |
|
|
13
|
+
| **C — Gemini CLI + `mcp-nanobanana-go` MCP server** | User is already using Gemini CLI day-to-day and has a GCP project. Image generation via native MCP tool-calling. | Google Cloud ADC (`gcloud auth application-default login`) + `GOOGLE_CLOUD_PROJECT` | Install the Go binary MCP server + configure `~/.gemini/settings.json`. See Path C below. |
|
|
14
|
+
|
|
15
|
+
> **Note on the official `gemini` CLI**: The CLI itself does **not** have a built-in `generate image` command. Images are only possible via Path C (an MCP server that plugs into Gemini CLI). Do not propose "just run `gemini generate image …`" — that does not exist.
|
|
16
|
+
|
|
17
|
+
**Model code:** `gemini-3.1-flash-image-preview` (Nano Banana 2). For maximum factual accuracy / studio quality, swap to `gemini-3-pro-image-preview` (Nano Banana Pro). Legacy = `gemini-2.5-flash-image` (Nano Banana 1, original).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## When to invoke during the six-phase flow
|
|
22
|
+
|
|
23
|
+
Image generation is a **Phase 5 (Implementation)** decision, never a Phase 1–4 ask. Trigger conditions, all required:
|
|
24
|
+
|
|
25
|
+
1. The user has **explicitly opted in** ("generate images", "make the hero image", "create the assets"). Implicit opt-in (e.g. `slide notes` say `IMAGE`) is not enough.
|
|
26
|
+
2. The slide's outline row gives a concrete `data-expected` description (subject, style, mood, composition).
|
|
27
|
+
3. The deck's `DESIGN.md` has a locked aesthetic — colors, lighting, style — so generated images don't fight the theme.
|
|
28
|
+
4. Required credentials are available: `GEMINI_API_KEY` (Path A/B) or GCP ADC + `GOOGLE_CLOUD_PROJECT` (Path C).
|
|
29
|
+
|
|
30
|
+
If any condition is missing → keep the `image-ph` / `image-ph-bleed` placeholder. Never half-generate.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Path A — Direct API (recommended)
|
|
35
|
+
|
|
36
|
+
### Setup
|
|
37
|
+
|
|
38
|
+
Drop a one-file helper into the **skill** (not the deck) so every generated deck shares the same script:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
skills/octocode-slides/scripts/generate_image.py ← new helper
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The helper is a thin wrapper around `google-genai`:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from google import genai
|
|
48
|
+
from google.genai import types
|
|
49
|
+
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
|
|
50
|
+
response = client.models.generate_content(
|
|
51
|
+
model="gemini-3.1-flash-image-preview",
|
|
52
|
+
contents=[prompt, *reference_images],
|
|
53
|
+
config=types.GenerateContentConfig(
|
|
54
|
+
response_modalities=["TEXT", "IMAGE"],
|
|
55
|
+
image_config=types.ImageConfig(image_size=resolution, aspect_ratio=ratio),
|
|
56
|
+
),
|
|
57
|
+
)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Full reference implementation: [`intellectronica/agent-skills/skills/nano-banana-2/scripts/generate_image.py`](https://github.com/intellectronica/agent-skills/blob/main/skills/nano-banana-2/scripts/generate_image.py).
|
|
61
|
+
|
|
62
|
+
### Invocation
|
|
63
|
+
|
|
64
|
+
Always run from the deck root (`.octocode/slides/{{slideName}}/`) so the image lands in `assets/` next to where the slide references it:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cd .octocode/slides/{{slideName}}
|
|
68
|
+
uv run /absolute/path/to/skills/octocode-slides/scripts/generate_image.py \
|
|
69
|
+
--prompt "<prompt>" \
|
|
70
|
+
--filename "assets/{{slug}}-{{timestamp}}.png" \
|
|
71
|
+
--resolution 2K \
|
|
72
|
+
--aspect-ratio 16:9
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Flags
|
|
76
|
+
|
|
77
|
+
| Flag | Default | Slide guidance |
|
|
78
|
+
|------|---------|---------------|
|
|
79
|
+
| `--prompt` | required | Use the Slide Image Prompt template below |
|
|
80
|
+
| `--filename` | required | `assets/{{slug}}-yyyy-mm-dd-hh-mm-ss.png` — slug matches the slide file |
|
|
81
|
+
| `--resolution` | `1K` | `1K` for inline / decorative · `2K` for `slide--two-col` half · `4K` only for full-bleed `slide--image` |
|
|
82
|
+
| `--aspect-ratio` | model default | `16:9` matches the 1280×720 slide canvas · `1:1` for inline tiles · `2:3` / `3:4` for portrait insets |
|
|
83
|
+
| `--input-image` | none | Repeat up to 14 times for character/object consistency across the deck |
|
|
84
|
+
| `--api-key` | `GEMINI_API_KEY` env | Use the env var; pass the flag only when a per-deck key is required |
|
|
85
|
+
|
|
86
|
+
### Environment
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
export GEMINI_API_KEY="..." # get from https://aistudio.google.com/apikey
|
|
90
|
+
command -v uv >/dev/null # required
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If `uv` is not installed: `brew install uv` (macOS) or `curl -LsSf https://astral.sh/uv/install.sh | sh`.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Path B — Third-party CLI (`belt`)
|
|
98
|
+
|
|
99
|
+
Only when the user explicitly prefers inference.sh, or the deck needs Google Search grounding (real-time facts in images — weather, news, current events):
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
belt login
|
|
103
|
+
belt app run google/gemini-3-1-flash-image-preview --input '{
|
|
104
|
+
"prompt": "<prompt>",
|
|
105
|
+
"aspect_ratio": "16:9",
|
|
106
|
+
"resolution": "2K",
|
|
107
|
+
"enable_google_search": true,
|
|
108
|
+
"images": ["assets/reference.png"]
|
|
109
|
+
}'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Save the returned image into `assets/{{slug}}-{{timestamp}}.png` manually (the CLI prints a URL/path; download with `curl`).
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Path C — Gemini CLI + `mcp-nanobanana-go` (official Google MCP)
|
|
117
|
+
|
|
118
|
+
Use when the user is already working inside Gemini CLI and has a Google Cloud project.
|
|
119
|
+
|
|
120
|
+
### How it works
|
|
121
|
+
|
|
122
|
+
[`mcp-nanobanana-go`](https://github.com/GoogleCloudPlatform/vertex-ai-creative-studio/tree/main/experiments/mcp-genmedia/mcp-genmedia-go/mcp-nanobanana-go) is an official Google MCP server that exposes `nanobanana_image_generation` as a tool. When configured in Gemini CLI, the agent can call it directly during a session — no Python, no `uv`.
|
|
123
|
+
|
|
124
|
+
### Setup
|
|
125
|
+
|
|
126
|
+
**1. Install the MCP server binary:**
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
curl -sL https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-creative-studio/main/experiments/mcp-genmedia/mcp-genmedia-go/install-online.sh | bash
|
|
130
|
+
# Adds mcp-nanobanana-go to ~/.local/bin — ensure that is on $PATH
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**2. Set required env vars:**
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
export GOOGLE_CLOUD_PROJECT="your-gcp-project-id"
|
|
137
|
+
export GOOGLE_CLOUD_LOCATION="us-central1" # optional, this is the default
|
|
138
|
+
gcloud auth application-default login # once — sets up ADC
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**3. Configure Gemini CLI** (`~/.gemini/settings.json`):
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"mcpServers": {
|
|
146
|
+
"nanobanana": {
|
|
147
|
+
"command": "mcp-nanobanana-go",
|
|
148
|
+
"args": [],
|
|
149
|
+
"env": {
|
|
150
|
+
"GOOGLE_CLOUD_PROJECT": "${GOOGLE_CLOUD_PROJECT}",
|
|
151
|
+
"GOOGLE_CLOUD_LOCATION": "${GOOGLE_CLOUD_LOCATION}"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**4. Install the image-artist skill** (optional but recommended — teaches Gemini CLI prompting best practices):
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
cp -r /path/to/vertex-ai-creative-studio/experiments/mcp-genmedia/skills/genmedia-image-artist \
|
|
162
|
+
~/.gemini/skills/
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Invocation
|
|
166
|
+
|
|
167
|
+
Inside a Gemini CLI session, just describe what you want. The agent calls `nanobanana_image_generation` automatically:
|
|
168
|
+
|
|
169
|
+
```text
|
|
170
|
+
> Generate a cinematic hero image of a futuristic city at dusk, 16:9, for the title slide
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Output goes to the `GENMEDIA_BUCKET` GCS bucket, or you can specify a local path in the prompt.
|
|
174
|
+
|
|
175
|
+
### Env vars for Path C
|
|
176
|
+
|
|
177
|
+
| Variable | Required | Default | Notes |
|
|
178
|
+
|----------|----------|---------|-------|
|
|
179
|
+
| `GOOGLE_CLOUD_PROJECT` | Yes | — | Your GCP project ID |
|
|
180
|
+
| `GOOGLE_CLOUD_LOCATION` | No | `us-central1` | Vertex AI region |
|
|
181
|
+
| `GENMEDIA_BUCKET` | No | — | Default GCS output bucket |
|
|
182
|
+
| `ALLOW_UNSAFE_MODELS` | No | `false` | Bypass model validation for pre-release strings |
|
|
183
|
+
|
|
184
|
+
Auth uses [Application Default Credentials](https://cloud.google.com/docs/authentication/application-default-credentials) — **not** `GEMINI_API_KEY`. ADC resolves in this order: `gcloud auth application-default login` → service account key file (`GOOGLE_APPLICATION_CREDENTIALS`).
|
|
185
|
+
|
|
186
|
+
### Path C vs Path A — when to choose
|
|
187
|
+
|
|
188
|
+
| | Path A (Python SDK) | Path C (Gemini CLI MCP) |
|
|
189
|
+
|-|---------------------|------------------------|
|
|
190
|
+
| Auth | `GEMINI_API_KEY` from AI Studio | GCP ADC + project |
|
|
191
|
+
| Control | Full programmatic control | Agent-driven, conversational |
|
|
192
|
+
| Scripting | `uv run generate_image.py …` | Gemini CLI session |
|
|
193
|
+
| Billing | AI Studio quota | Vertex AI quota |
|
|
194
|
+
| Reference images | Up to 14 via `--input-image` | Via `images` param in tool call |
|
|
195
|
+
| Best for | Automated slide builds, CI | Interactive sessions, rapid iteration |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Slide Image Prompt template
|
|
200
|
+
|
|
201
|
+
The slide's `data-expected` description is too thin to send to the model directly. Expand it through this template — same shape as `references/04-design.md`'s design tokens, so generated images stay consistent with the theme:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
Create a {{layout}} image of: {{subject}}.
|
|
205
|
+
Style: {{style}} — anchored to the deck's visual system ({{primary_color}}, {{accent_color}}, {{mood}}).
|
|
206
|
+
Composition: {{shot}} ({{focal_point}} dominant, {{rule_of_thirds | centered | rule_of_fifths}}).
|
|
207
|
+
Lighting: {{lighting}}.
|
|
208
|
+
Background: {{background}} — must work behind {{light | dark}} caption overlay.
|
|
209
|
+
Negative space: leave {{top | bottom | left | right}} {{30%}} clear for text.
|
|
210
|
+
Avoid: text, watermarks, logos, hands with malformed fingers, signature artifacts, clichéd stock-photo poses.
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
For full-bleed `slide--image` slides, the `.image-overlay` gradient sits on top — generate **without** built-in text; let the slide system render the caption.
|
|
214
|
+
|
|
215
|
+
### Style anchors (pick one per deck, write into `DESIGN.md`)
|
|
216
|
+
|
|
217
|
+
| Style | When |
|
|
218
|
+
|-------|------|
|
|
219
|
+
| `photorealistic, editorial photography, 50mm` | Executive / business decks, real-world subjects |
|
|
220
|
+
| `clean vector illustration, flat color, geometric` | Product / SaaS, technical concepts |
|
|
221
|
+
| `3D render, soft studio lighting, isometric` | Architecture, infrastructure diagrams as hero |
|
|
222
|
+
| `watercolor / hand-drawn` | Storytelling decks, education, non-technical audiences |
|
|
223
|
+
| `cinematic, anamorphic, shallow depth of field` | Mood / opener / closer slides |
|
|
224
|
+
|
|
225
|
+
Pick **one** style for the whole deck. Mixing styles is visual slop — counts against Visual Slop Test signal #5 (palette inconsistency).
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Resolution × slide-type matrix
|
|
230
|
+
|
|
231
|
+
| Slide type | Resolution | Aspect ratio | Why |
|
|
232
|
+
|------------|-----------|--------------|-----|
|
|
233
|
+
| `slide--image` (full-bleed) | `4K` | `16:9` | Edges visible at presentation zoom |
|
|
234
|
+
| `slide--two-col` (image side) | `2K` | `4:5` or `1:1` | Half the canvas — 2K is the sweet spot |
|
|
235
|
+
| Inline tile in `content` / `stats` | `1K` | `1:1` | Decorative, small |
|
|
236
|
+
| Portrait inset (speaker, product) | `2K` | `2:3` or `3:4` | Vertical composition |
|
|
237
|
+
| Thumbnail / draft pass | `512px` | match final | Iterate prompt cheaply, then re-run at target res |
|
|
238
|
+
|
|
239
|
+
**Workflow:** draft at `512px` until the prompt is right, then re-run at the target resolution. Don't burn 4K calls on prompt iteration.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Character / object consistency across slides
|
|
244
|
+
|
|
245
|
+
When the deck reuses a subject (mascot, product, recurring person) on multiple slides, use the **reference-image** flag so the model sees the same subject every time:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
uv run generate_image.py \
|
|
249
|
+
--prompt "<scene description>. Keep subject identity from reference image." \
|
|
250
|
+
--filename "assets/scene-2.png" \
|
|
251
|
+
--input-image "assets/scene-1.png" \
|
|
252
|
+
--resolution 2K
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Up to **14** reference images per call. For a campaign:
|
|
256
|
+
- pass the product render once
|
|
257
|
+
- pass the brand mark once
|
|
258
|
+
- pass any prior generated scenes
|
|
259
|
+
|
|
260
|
+
This is the only reliable way to stop the model from drifting between slides.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Asset save location (path contract)
|
|
265
|
+
|
|
266
|
+
Generated images live in **the deck's `assets/` folder**, never in the skill folder:
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
.octocode/slides/{{slideName}}/
|
|
270
|
+
├── assets/
|
|
271
|
+
│ ├── {{slug}}-yyyy-mm-dd-hh-mm-ss.png ← generated
|
|
272
|
+
│ ├── {{slug}}-yyyy-mm-dd-hh-mm-ss-1k.png ← draft (delete after final)
|
|
273
|
+
│ └── user-provided.png ← untouched
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Slides reference them with the existing one-level-up pattern: `../assets/{{filename}}`. No change to the path contract in `SKILL.md → Output structure`.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Integration with existing image-handling rule
|
|
281
|
+
|
|
282
|
+
`references/05-implementation.md` currently says:
|
|
283
|
+
|
|
284
|
+
> *For any missing image, do not search, download, generate, or silently substitute an image. Render the `PLACEHOLDER` component...*
|
|
285
|
+
|
|
286
|
+
This still holds as the default. **Generation is opt-in.** The decision table becomes:
|
|
287
|
+
|
|
288
|
+
| Image status in brief | What to do in HTML |
|
|
289
|
+
|-----------------------|--------------------|
|
|
290
|
+
| `ready` — file path provided | `<img src="../assets/{{filename}}">` |
|
|
291
|
+
| `placeholder` — user will provide later | `image-ph` / `image-ph-bleed` component |
|
|
292
|
+
| `generate` — user opted in **and** `data-expected` is concrete | Run `generate_image.py` → save to `assets/` → `<img>` it. Keep the `data-expected` on the element as a comment for traceability. |
|
|
293
|
+
| anything ambiguous | Treat as `placeholder` |
|
|
294
|
+
|
|
295
|
+
The `data-expected` attribute is what becomes (after expansion via the Slide Image Prompt template) the `--prompt` to the helper.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Phase 6 review checks for generated images
|
|
300
|
+
|
|
301
|
+
Add these to the Slop / handoff pass when any image was generated:
|
|
302
|
+
|
|
303
|
+
- [ ] **Style consistency** — every generated image uses the same `Style anchor` from `DESIGN.md`. Mixed styles = automatic Visual Slop hit.
|
|
304
|
+
- [ ] **No hallucinated text** — model-rendered text on the image (sign, billboard, UI mock) is checked against the deck's claim. If text doesn't match, regenerate with `Avoid: text, signs, UI text` and add real text in HTML overlay.
|
|
305
|
+
- [ ] **Hands, faces, fingers** — Nano Banana 2 is good but not perfect. Spot-check at 4K; if a hand is malformed, regenerate or crop.
|
|
306
|
+
- [ ] **No watermark / signature** — sometimes the model adds a fake signature corner; reroll if present.
|
|
307
|
+
- [ ] **Caption legibility** — for full-bleed images with overlay text, verify the overlay gradient still reads against the generated image. Adjust gradient stops in slide CSS if needed.
|
|
308
|
+
- [ ] **Provenance note** — every generated image is marked in `request.md → Images` with model code, prompt, and timestamp. Counts as Content Slop signal #3 (uncited source) if missing.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Cost & rate-limit notes
|
|
313
|
+
|
|
314
|
+
| Resolution | Approx. credits per image | Notes |
|
|
315
|
+
|-----------|--------------------------|-------|
|
|
316
|
+
| `512px` | lowest | Iterate freely |
|
|
317
|
+
| `1K` | low | Default |
|
|
318
|
+
| `2K` | ~2× 1K | Most slide images |
|
|
319
|
+
| `4K` | ~4× 1K | Reserve for full-bleed final |
|
|
320
|
+
|
|
321
|
+
The Gemini 3.1 Flash Image Preview tier is rate-limited per minute and per day. For a 20-slide deck with 6 images, expect ~10–12 API calls (drafts + finals). Don't generate during Phase 4 previews — wait for the design direction to lock.
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Quick recipes
|
|
326
|
+
|
|
327
|
+
**Full-bleed hero, photorealistic:**
|
|
328
|
+
```bash
|
|
329
|
+
uv run scripts/generate_image.py \
|
|
330
|
+
--prompt "Wide cinematic shot: empty modern office at blue hour, desks lit only by laptop screens, deep shadows, anamorphic lens flare. Negative space on right 40% for caption overlay. Avoid: people, text, signage." \
|
|
331
|
+
--filename "assets/title-2026-05-10-22-14-00.png" \
|
|
332
|
+
--resolution 4K --aspect-ratio 16:9
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
**Two-column product render, vector style:**
|
|
336
|
+
```bash
|
|
337
|
+
uv run scripts/generate_image.py \
|
|
338
|
+
--prompt "Clean isometric vector illustration of a server rack, flat colors matching #0EA5E9 primary and #F59E0B accent, white background, no text, no shadows beyond soft drop." \
|
|
339
|
+
--filename "assets/architecture-2026-05-10-22-15-30.png" \
|
|
340
|
+
--resolution 2K --aspect-ratio 4:5
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Iterate on a draft until prompt is right:**
|
|
344
|
+
```bash
|
|
345
|
+
for variant in "morning fog" "blue hour" "neon rain"; do
|
|
346
|
+
uv run scripts/generate_image.py \
|
|
347
|
+
--prompt "Tokyo street, $variant, cinematic, no text" \
|
|
348
|
+
--filename "assets/draft-${variant// /-}.png" \
|
|
349
|
+
--resolution 512px --aspect-ratio 16:9
|
|
350
|
+
done
|
|
351
|
+
# Then re-run the winner at 4K with the same prompt.
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## When to escalate to Nano Banana Pro
|
|
357
|
+
|
|
358
|
+
Swap `--model gemini-3-pro-image-preview` (and adjust the helper accordingly) when:
|
|
359
|
+
|
|
360
|
+
- The image must be **factually accurate** (real building, real product, branded element). Pro has stronger world knowledge.
|
|
361
|
+
- The slide is the **deck's one surprise moment** (see SKILL.md → Storytelling → "One surprise per deck"). Pay the quality premium once.
|
|
362
|
+
- The audience is **Executive** depth — fewer slides, each carrying more weight.
|
|
363
|
+
|
|
364
|
+
Otherwise stay on Flash Image (Nano Banana 2) — the speed difference matters more during iteration than the quality delta in slide-scale viewing.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Env Params Best Practice — How to Pass API Keys to Skills
|
|
369
|
+
|
|
370
|
+
This section documents the canonical pattern for declaring and resolving environment parameters in any skill that calls external APIs.
|
|
371
|
+
|
|
372
|
+
### Resolution order (two-layer pattern)
|
|
373
|
+
|
|
374
|
+
The `intellectronica/agent-skills` nano-banana reference implementation defines the authoritative precedence:
|
|
375
|
+
|
|
376
|
+
1. `--api-key` CLI argument — use when the user provides a key inline during the chat session, or when a per-deck override is required.
|
|
377
|
+
2. `GEMINI_API_KEY` environment variable — the ambient default; set once in the shell profile and forget.
|
|
378
|
+
3. If neither is found → **exit loudly** with clear instructions for both options.
|
|
379
|
+
|
|
380
|
+
```python
|
|
381
|
+
def get_api_key(provided_key: str | None) -> str | None:
|
|
382
|
+
if provided_key:
|
|
383
|
+
return provided_key
|
|
384
|
+
return os.environ.get("GEMINI_API_KEY")
|
|
385
|
+
|
|
386
|
+
api_key = get_api_key(args.api_key)
|
|
387
|
+
if not api_key:
|
|
388
|
+
print("Error: No API key provided.", file=sys.stderr)
|
|
389
|
+
print(" 1. Provide --api-key argument", file=sys.stderr)
|
|
390
|
+
print(" 2. Set GEMINI_API_KEY environment variable", file=sys.stderr)
|
|
391
|
+
sys.exit(1)
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### How to document env vars in a SKILL.md
|
|
395
|
+
|
|
396
|
+
Declare env requirements in a `## Prerequisites` section at the top, before any workflow steps. Use a table — agents scan tables faster than prose.
|
|
397
|
+
|
|
398
|
+
**`## Prerequisites`**
|
|
399
|
+
|
|
400
|
+
**`### Environment`**
|
|
401
|
+
|
|
402
|
+
| Variable | Required | How to get it | Setup |
|
|
403
|
+
|----------|----------|---------------|-------|
|
|
404
|
+
| `GEMINI_API_KEY` | Yes (Path A/B) | [AI Studio](https://aistudio.google.com/apikey) | `export GEMINI_API_KEY="..."` |
|
|
405
|
+
| `GOOGLE_CLOUD_PROJECT` | Yes (Path C) | GCP Console | `export GOOGLE_CLOUD_PROJECT="my-project"` |
|
|
406
|
+
| `GOOGLE_CLOUD_LOCATION` | No (Path C) | — | Defaults to `us-central1` |
|
|
407
|
+
|
|
408
|
+
**`### Setup check`**
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
# Path A
|
|
412
|
+
echo $GEMINI_API_KEY && command -v uv
|
|
413
|
+
# Path C
|
|
414
|
+
gcloud auth application-default print-access-token && echo $GOOGLE_CLOUD_PROJECT
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Rules
|
|
418
|
+
|
|
419
|
+
- **Never hardcode keys** in SKILL.md examples. Use `"..."` or `"your-key-here"` as placeholders.
|
|
420
|
+
- **Never commit `.env` files** containing real keys.
|
|
421
|
+
- **Prefer env vars over CLI args** for ambient credentials. Reserve `--api-key` for explicit per-invocation overrides.
|
|
422
|
+
- **Fail loudly** — a missing key should print the exact export command the user needs, not a generic error.
|
|
423
|
+
- **Document the source** — link to where the user gets the key (AI Studio, GCP Console, etc.).
|
|
424
|
+
- **For GCP tools** — use ADC (`gcloud auth application-default login`), not service account keys, for local development. Document the command explicitly.
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## References
|
|
429
|
+
|
|
430
|
+
### Path A — Direct API
|
|
431
|
+
- **Reference helper script:** [`intellectronica/agent-skills/skills/nano-banana-2/scripts/generate_image.py`](https://github.com/intellectronica/agent-skills/blob/main/skills/nano-banana-2/scripts/generate_image.py)
|
|
432
|
+
- **Nano Banana 2 SKILL.md (canonical API key pattern):** [`intellectronica/agent-skills/skills/nano-banana-2/SKILL.md`](https://github.com/intellectronica/agent-skills/blob/main/skills/nano-banana-2/SKILL.md)
|
|
433
|
+
- **Official model docs:** [ai.google.dev/gemini-api/docs/image-generation](https://ai.google.dev/gemini-api/docs/image-generation)
|
|
434
|
+
- **API key:** [aistudio.google.com/apikey](https://aistudio.google.com/apikey)
|
|
435
|
+
|
|
436
|
+
### Path B — Third-party CLI
|
|
437
|
+
- **`belt` CLI:** [`inference-sh/skills/tools/image/nano-banana-2`](https://github.com/inference-sh/skills/tree/main/tools/image/nano-banana-2)
|
|
438
|
+
- **Grounded generation pipeline:** [`GeeveGeorge/openNanoBanana`](https://github.com/GeeveGeorge/openNanoBanana)
|
|
439
|
+
|
|
440
|
+
### Path C — Gemini CLI MCP
|
|
441
|
+
- **`mcp-nanobanana-go` server:** [`GoogleCloudPlatform/vertex-ai-creative-studio/experiments/mcp-genmedia/mcp-genmedia-go/mcp-nanobanana-go`](https://github.com/GoogleCloudPlatform/vertex-ai-creative-studio/tree/main/experiments/mcp-genmedia/mcp-genmedia-go/mcp-nanobanana-go)
|
|
442
|
+
- **Easy installer:** [`install-online.sh`](https://github.com/GoogleCloudPlatform/vertex-ai-creative-studio/blob/main/experiments/mcp-genmedia/mcp-genmedia-go/install-online.sh)
|
|
443
|
+
- **`genmedia-image-artist` skill:** [`GoogleCloudPlatform/vertex-ai-creative-studio/experiments/mcp-genmedia/skills/genmedia-image-artist/SKILL.md`](https://github.com/GoogleCloudPlatform/vertex-ai-creative-studio/blob/main/experiments/mcp-genmedia/skills/genmedia-image-artist/SKILL.md)
|
|
444
|
+
- **ENV_VARS reference:** [`mcp-genmedia-go/ENV_VARS.md`](https://github.com/GoogleCloudPlatform/vertex-ai-creative-studio/blob/main/experiments/mcp-genmedia/mcp-genmedia-go/ENV_VARS.md)
|
|
445
|
+
- **Gemini CLI repo:** [`google-gemini/gemini-cli`](https://github.com/google-gemini/gemini-cli)
|
|
446
|
+
|
|
447
|
+
### Shared / Pro
|
|
448
|
+
- **Alternative skill (Pro variant):** [`steipete/agent-scripts/skills/nano-banana-pro`](https://github.com/steipete/agent-scripts/tree/main/skills/nano-banana-pro)
|