| name | generate-image |
| description | Generate images using Gemini 3 Image (Nano Banana). Use for thumbnails, carousels, infographics, social graphics, product photos. |
| allowed-tools | Bash Read Write Edit Glob Grep |
Generate Image
โ ๏ธ STOP: COMPLETE THIS CHECKLIST BEFORE WRITING ANY CODE
You MUST complete ALL steps below and SHOW output to user before generating.
โก Step 0: RUN content-preflight (classify topic/visual mode, resolve required assets)
โก Step 1: ASK user "Does this image include a person/character?"
โก Step 2: Look up the character/product in the asset registry (resolveAsset) โ SHOW result
โก Step 3: If a locked character asset exists โ TELL user you will reuse its ref files
โก Step 4: READ project.md and brand.md templates
โก Step 5: ASK user to confirm workflow selection
โก Step 6: THEN generate using workflow function
DO NOT skip to code. DO NOT assume. SHOW each step.
CRITICAL: CALL THE WORKFLOW CLI โ DO NOT WRITE A SCRIPT
DO NOT write raw API calls. DO NOT author a .cjs/.ts file that imports these
functions. RUN the workflow as a CLI command:
node workflows/cli.cjs <command> '<json-args>'
Image commands: generateSingleImage, generateImageVariation, generateCarousel,
generateCarouselFromRef, generateImageOptions, finalizeImage, generateStoryboard,
generateCharacterSheet, analyzeImage. Example:
node workflows/cli.cjs generateSingleImage \
'{"prompt":"...","outputPath":"projects/{name}/output-contents/thumb.png","aspectRatio":"9:16"}'
For each command's argument shape: Read workflows/WORKFLOWS.md.
Expensive image (thumbnail, hero, ad, 2K/4K)? Offer the user cheap options first:
generateImageOptions() (512px) โ they pick โ finalizeImage() at 2K. See the
preview-pick skill. Don't blind-spend on a single high-res gen.
MANDATORY STEPS BEFORE GENERATING (DO NOT SKIP)
Step 1: Ask About Person/Character (REQUIRED)
ALWAYS ask the user:
-
Does this image include a person/character?
- Yes โ Need character reference OR will generate one
- No โ Product-only or abstract image
-
If yes, ask:
- Do you have a character reference image in assets?
- Should we generate a character keyframe first?
Step 2: Look Up Assets in the Registry (REQUIRED) - SHOW RESULTS TO USER
Don't guess from filenames. Read the project's asset registry โ it records every
reusable character/product with validated paths. (Pre-flight usually populated it already;
see skills/content-preflight/SKILL.md.)
node workflows/cli.cjs loadAssetConfig '["{name}"]'
node workflows/cli.cjs resolveAsset '["{name}","char-main"]'
node workflows/cli.cjs resolveAsset '["{name}","prod-main"]'
Then TELL the user what you found:
Asset registry (projects/{name}/config/assets.yaml):
โ character char-main โ 3 refs, locked (will reuse for consistency)
โ product prod-main โ 2 refs
Reusing char-main's reference images โ not regenerating the character.
char.ok === true โ pass char.existing[...] as the reference image(s). Do not
re-describe or regenerate a locked character.
char.ok === false โ resolve via pre-flight's provide/generate flow, then
registerAsset(...) so it's saved for next time.
- Priority: character reference > product reference when the image has a person.
Step 3: Read Project Templates (REQUIRED)
cat projects/{name}/templates/project.md
cat projects/{name}/templates/brand.md
Step 4: Read Workflow Documentation (REQUIRED)
cat workflows/WORKFLOWS.md
CHARACTER CONSISTENCY (CRITICAL)
Problem: Each image generation creates a NEW random person.
Solution: Use the SAME character reference image for ALL images.
Workflow for Character Consistency (registry-driven):
-
Resolve the character from the registry:
node workflows/cli.cjs loadAssetConfig '["{name}"]'
node workflows/cli.cjs resolveAsset '["{name}","char-main"]'
-
If char.ok โ reuse the SAME ref file (its validated, on-disk path):
node workflows/cli.cjs generateImageVariation '{"referenceImagePath":"projects/{name}/assets/characters/char-main-front.png","prompt":"Same person in office setting","outputPath":"projects/{name}/output-contents/image.png"}'
-
If not (no asset yet) โ generate ONCE, then register it:
node workflows/cli.cjs generateSingleImage '{"prompt":"Woman in her 30s, dark hair, professional attire, neutral expression, facing camera","outputPath":"projects/{name}/assets/characters/char-main-front.png","aspectRatio":"1:1","imageSize":"1K"}'
node workflows/cli.cjs registerAsset '["{name}","characters",{"id":"char-main","label":"Main character","source":"generated","status":"ready","locked":true,"files":{"front":"assets/characters/char-main-front.png"}},{"date":"<today ISO>"}]'
node workflows/cli.cjs generateImageVariation '{"referenceImagePath":"projects/{name}/assets/characters/char-main-front.png","prompt":"Same person in different setting...","outputPath":"projects/{name}/output-contents/variation.png"}'
-
For carousels with consistent character โ resolve once, pass the ref to every slide:
node workflows/cli.cjs resolveAsset '["{name}","char-main"]'
node workflows/cli.cjs generateCarouselFromRef '{"referenceImagePath":"projects/{name}/assets/characters/char-main-front.png","slides":[{"prompt":"Same person in scene 1"},{"prompt":"Same person in scene 2"},{"prompt":"Same person in scene 3"}],"outputDir":"projects/{name}/output-contents/carousel"}'
PRODUCT CONSISTENCY (same pattern as characters)
Products are registry assets too โ resolve before generating, and register a generated
product shot/mockup so it's reused (don't re-mockup the same product each time).
node workflows/cli.cjs resolveAsset '["{name}","prod-main"]'
node workflows/cli.cjs registerAsset '["{name}","products",{"id":"prod-main","label":"Hero product","source":"generated","status":"ready","files":["assets/products/prod-main-front.png"],"key_features":["feature 1","feature 2"]},{"date":"<today ISO>"}]'
A real product you can photograph should be provided, not mockup-generated โ ask for
a photo first. Only source: mockup a pre-launch product with no photo.
PRODUCT SHOTS (e-commerce) โ use the preset library
For "product photo", "packshot", "listing image", "lifestyle shot", "seasonal
version", "ad variations from this photo": read
workflows/PRODUCT-SHOT-GUIDE.md first. 26 tested presets ship as the
productShot field on generateImageVariation.
The flow:
- Get the real product photo โ resolve
prod-* from the registry (or
ask the user for one). A messy supplier/phone photo is a fine base.
Never generate the product itself from text.
- Ask which channel โ marketplace listing / own-site PDP / paid ads /
email-banner / Instagram. Propose the preset set from the guide's
channel table (e.g. marketplace โ
pure-white-packshot +
multi-angle + texture-closeup + in-hand-scale).
- Draft cheap โ approve โ finalize sharp: iterate with
"imageModel":"lite" ($0.0336), then regenerate the approved direction
at "imageSize":"2K".
node workflows/cli.cjs generateImageVariation '{"referenceImagePath":"<prod-main existing[0]>","productShot":"pure-white-packshot","prompt":"The ceramic honey jar with the gold lid.","outputPath":"โฆ/packshot-white.png","aspectRatio":"1:1","imageSize":"2K"}'
The preset supplies scene + lighting + a fidelity clause (exact
shape/branding/label preserved โ appended automatically); your prompt
carries only the specifics (product name, props, surface/light swaps).
QA every shot vs the reference with reviewOutput โ label text and
proportions must match; marketplaces treat the image as the trust signal.
Presets involving people (model-usage, hands-*, in-hand-scale) need
"personGeneration":"allow".
REQUIRED QUESTIONS
Always ask these questions:
-
Does this image include a person/character?
- Yes โ Check for character reference in assets
- No โ Product or abstract image
-
What type of image?
- Single image โ
generateSingleImage() or generateImageVariation()
- Carousel โ
generateCarousel() or generateCarouselFromRef()
-
Platform? (determines aspect ratio)
-
Reference images? Two kinds โ resolve BOTH before writing any prompt:
- Identity refs (character/product/logo) โ
resolveAsset from the registry;
never re-describe a registered subject.
- Style refs (the LOOK: past thumbnails/posts, an aesthetic the user likes) โ
check
style_references in the registry; if none, ask once: "Any existing
images/thumbnails whose style I should match?" Pass them via
referenceImagePaths with their role stated ("style only, not subject") and
mirror their palette/layout in the prompt. Save + register new ones for reuse.
-
For carousels: How many slides? (style refs apply to EVERY slide โ one look
across the set)
-
Part of a series/campaign? (product-shot campaign, film keyframes, episode
art) โ the project should have a locked templates/style-block.md โ prepend it
verbatim to EVERY image prompt of the series. If it doesn't exist yet, create it
with the user from templates/style-block.template.md (variant C for product
campaigns) before generating. One-off image โ brand.md aesthetic is enough.
WORKFLOW SELECTION
| User Wants | Has Person? | Has Reference? | Use Workflow |
|---|
| Single image (no person) | No | No | generateSingleImage() |
| Product image | No | YES | generateImageVariation() |
| Image with person | YES | No | generateSingleImage() (generate keyframe first) |
| Image with person | YES | YES | generateImageVariation() |
| Carousel (no person) | No | No | generateCarousel() |
| Carousel with person | YES | YES | generateCarouselFromRef() |
RULE: If image has person AND character image exists โ ALWAYS use character image as reference.
WORKFLOW EXAMPLES
1. Single Image (no person)
node workflows/cli.cjs generateSingleImage '{"prompt":"Smartwatch on marble surface, soft studio lighting, product photography","outputPath":"projects/my-project/output-contents/product.png","aspectRatio":"1:1","imageSize":"1K"}'
2. Image Variation with Product Reference
node workflows/cli.cjs generateImageVariation '{"referenceImagePath":"projects/my-project/assets/product-watch.png","prompt":"Same product on wooden desk, morning light, minimalist setting","outputPath":"projects/my-project/output-contents/variation.png","aspectRatio":"1:1","imageSize":"1K"}'
3. Image with Character Reference (RECOMMENDED for consistency)
node workflows/cli.cjs generateImageVariation '{"referenceImagePath":"projects/my-project/assets/characters/char-main-front.png","prompt":"Same person in modern office, checking smartwatch, professional lighting","outputPath":"projects/my-project/output-contents/lifestyle.png","aspectRatio":"9:16","imageSize":"1K"}'
4. Generating Character Keyframe First
node workflows/cli.cjs generateSingleImage '{"prompt":"Professional woman in her 30s, dark hair, neutral expression, business casual attire, facing camera, clean background","outputPath":"projects/my-project/assets/characters/char-main-front.png","aspectRatio":"1:1","imageSize":"1K","personGeneration":"allow"}'
node workflows/cli.cjs generateImageVariation '{"referenceImagePath":"projects/my-project/assets/characters/char-main-front.png","prompt":"Same person smiling while checking smartwatch in gym","outputPath":"projects/my-project/output-contents/gym-scene.png"}'
5. Carousel with Consistent Character
node workflows/cli.cjs generateCarouselFromRef '{"referenceImagePath":"projects/my-project/assets/characters/char-main-front.png","slides":[{"prompt":"Same person waking up, checking watch"},{"prompt":"Same person at gym, mid-workout"},{"prompt":"Same person at office, productive"},{"prompt":"Same person relaxing at home, peaceful"}],"outputDir":"projects/my-project/output-contents/lifestyle-carousel","aspectRatio":"1:1","imageSize":"1K"}'
REFERENCE IMAGE PRIORITY
When multiple assets exist, prioritize:
- Character image (if image has person) โ Use for character consistency
- Product image (if product-focused) โ Use for product consistency
NOTE: API supports ONE reference image per request. If you need both character AND product:
- Use character reference for image generation
- Describe product in the prompt
- Or generate separate product shots
CRITICAL: NO TEXT IN IMAGE PROMPTS (for carousels)
โ NEVER include:
- "Text says..."
- "Caption reads..."
- "Title: 5 Tips"
โ
Only describe visuals:
- Subject and action
- Environment/setting
- Lighting and mood
- Camera angle
Text is added via design tools in post-production.
IMAGE PROMPT STRUCTURE
[SUBJECT] in [ENVIRONMENT], [LIGHTING],
[COMPOSITION/ANGLE], [STYLE], [MOOD]
Example:
Professional woman checking Apple Watch in modern minimalist office,
soft natural window light, medium close-up shot,
lifestyle photography style, confident and productive mood
Prompt Templates by Type
Product Shot:
[Product] in [context/setting], [lighting style],
[camera angle], professional product photography,
[aesthetic] style
Lifestyle Image with Person:
[Person from reference] [using/with product] in [environment],
[natural/studio lighting], authentic [mood],
lifestyle photography, relatable
Thumbnail:
[Subject with expression], [background],
bold high contrast, eye-catching,
[platform] thumbnail style, 16:9
COST REFERENCE
| Resolution | Cost/image |
|---|
| 1K | $0.067 |
| 2K | $0.10 |
| 4K | $0.15 |
Example: 10-slide carousel at 1K = ~$0.67
Check the budget cap BEFORE generating (the CLI hard-stops at BUDGET_EXCEEDED):
node workflows/cli.cjs checkBudget '["{name}", 0.67]'
PIPELINE-FIRST + AUDIT TRAIL (MANDATORY)
- Author the pipeline before generating โ even for a single image: save
<content-id>.pipeline.json IN the content folder (nodes = CLI commands,
{{node.data.field}} refs wire outputs to inputs), then
node workflows/cli.cjs runPipeline @<file>. See workflows/pipelines/README.md.
- prompts.txt in every content folder โ the exact image prompt(s); update on
EVERY retry with a one-line RESULT note.
- Manifest โ log each generation via the
createGenerationManifest /
addManifestEntry CLI commands (AGENT-GUIDE Step 5).
OUTPUT
Save to: projects/{name}/output-contents/{date}/
- Single:
image.png or thumbnail.png
- Carousel:
slide-01.png, slide-02.png, etc.
- Character keyframes:
projects/{name}/assets/characters/char-main-front.png
PLATFORM SPECS
| Platform | Ratio | Resolution |
|---|
| Instagram feed | 1:1 | 1080x1080 |
| Instagram portrait | 4:5 | 1080x1350 |
| Instagram story | 9:16 | 1080x1920 |
| YouTube thumbnail | 16:9 | 1280x720 |
| LinkedIn | 1:1 | 1080x1080 |
| Facebook | 16:9 | 1200x630 |
Text on images โ renderSlideStill (Remotion, $0)
Never ask the image model to render typography for final slides. Generate the
background text-free, then:
node workflows/cli.cjs renderSlideStill '{"backgroundPath":"โฆ","headline":"โฆ","sub":"โฆ","footer":"โฆ","logoPath":"โฆ","scrim":true,"outputPath":"โฆ"}'
(real Sora/Inter fonts, frosted scrim for busy backgrounds โ see WORKFLOWS.md ยง Remotion).
Baked-in text โ imageModel "pro" (Nano Banana Pro, 2026-07-05)
For images that must CONTAIN typography (quote cards, posters, stat cards):
generateSingleImage {..., "imageModel":"pro"} โ Gemini 3 Pro Image, $0.134,
state-of-the-art text rendering. Prompt with the exact text in quotes + font
style + color + position. ALWAYS QA spelling afterward (reviewOutput). Remotion
remains the $0 option and guarantees fonts; pro wins when you want the type
integrated INTO the art (texture, perspective, lighting).
Bulk / previews โ imageModel "lite" (Nano Banana 2 Lite, 2026-07-05)
For at-scale generation and cheap previews before committing to flash/pro:
generateSingleImage {..., "imageModel":"lite"} โ Gemini 3.1 Flash Lite Image
(gemini-3.1-flash-lite-image), $0.0336/image flat at any size โ half the cost
of flash 1K. Quality is below flash; don't use it for final hero images or
anything with typography. Ideal for /preview-pick option rounds and background
plates.