generate-image
Generate images using Gemini 3 Image (Nano Banana). Use for thumbnails, carousels, infographics, social graphics, product photos.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Generate images using Gemini 3 Image (Nano Banana). Use for thumbnails, carousels, infographics, social graphics, product photos.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
MANDATORY pre-flight check that runs BEFORE any content plan or generation. Classifies the topic, verifies project/brand/product context, resolves the required reusable assets (characters, products, logos, voices) from the asset registry, and provides/generates whatever is missing — saving paths for reuse. Use whenever the user asks to plan a campaign, make a marketing plan, or create/generate any image, video, voiceover, or music.
Generate music using Gemini Lyria. Use for background music, jingles, intros, soundtracks, and complete songs WITH sung vocals — Lyria 3 sings your exact lyrics (8 languages, rap/sung delivery).
Generate video content using Gemini Veo. Use when user asks to create video, TikTok ad, Instagram Reel, YouTube video, product video, explainer.
Generate voiceover audio using Gemini TTS. Use for narration, voiceovers, podcasts, multi-speaker dialogue.
Write the words — scroll-stopping hooks, framework-driven scripts, and platform-ready captions with hashtags. Use when the user needs hook ideas, a video/ad script, ad copy, post captions, or says "what should I post", "write a script", "give me hooks", "write the caption".
Analyze a reference video (YouTube URL or local file) into a scene-by-scene breakdown — timecodes, shot types, camera moves, on-screen text, spoken lines — plus a recreation blueprint with per-scene video prompts and VO script. Use when the user says "analyze this video", "I want to create something like that", "recreate this video", "break down this YouTube video", or pastes a video link they want to emulate.
| 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 |
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.
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>' # or @args.json for long prompts
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 thepreview-pickskill. Don't blind-spend on a single high-res gen.
ALWAYS ask the user:
Does this image include a person/character?
If yes, ask:
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"]' # character id from the content plan
node workflows/cli.cjs resolveAsset '["{name}","prod-main"]'
# → { "ok": true, "existing": ["..."], "missing": [] }
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.cat projects/{name}/templates/project.md
cat projects/{name}/templates/brand.md
cat workflows/WORKFLOWS.md
Problem: Each image generation creates a NEW random person.
Solution: Use the SAME character reference image for ALL images.
Resolve the character from the registry:
node workflows/cli.cjs loadAssetConfig '["{name}"]'
node workflows/cli.cjs resolveAsset '["{name}","char-main"]' # → { "ok": true, "existing": ["..."], "missing": [] }
If char.ok → reuse the SAME ref file (its validated, on-disk path):
# referenceImagePath = the resolved char.existing[0] 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:
# Step 1: Generate the character keyframe one time
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"}'
# Step 2: Save to the registry so every future image/carousel reuses it
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>"}]'
# Step 3: Use it as the reference
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"]' # ref = char.existing[0]
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"}'
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).
# Reuse an existing product reference — if ok, pass existing[0] as referenceImagePath
node workflows/cli.cjs resolveAsset '["{name}","prod-main"]' # → { "ok": true, "existing": ["..."], "missing": [] }
# After generating a NEW product image/mockup, save it for reuse:
# source: "generated" | "provided" | "mockup" (pre-launch)
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: mockupa pre-launch product with no photo.
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:
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.pure-white-packshot +
multi-angle + texture-closeup + in-hand-scale)."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".
Does this image include a person/character?
What type of image?
generateSingleImage() or generateImageVariation()generateCarousel() or generateCarouselFromRef()Platform? (determines aspect ratio)
Reference images? Two kinds — resolve BOTH before writing any prompt:
resolveAsset from the registry;
never re-describe a registered subject.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.
| 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.
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"}'
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"}'
# Use character image from assets 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"}'
# Step 1: Generate character keyframe and save to assets
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"}'
# Step 2: Use keyframe for all subsequent images
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"}'
# All slides use same character reference
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"}'
When multiple assets exist, prioritize:
NOTE: API supports ONE reference image per request. If you need both character AND product:
❌ NEVER include:
✅ Only describe visuals:
Text is added via design tools in post-production.
[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
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
| 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]' # project name + estimated cost
<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.createGenerationManifest /
addManifestEntry CLI commands (AGENT-GUIDE Step 5).Save to: projects/{name}/output-contents/{date}/
image.png or thumbnail.pngslide-01.png, slide-02.png, etc.projects/{name}/assets/characters/char-main-front.png| Platform | Ratio | Resolution |
|---|---|---|
| Instagram feed | 1:1 | 1080x1080 |
| Instagram portrait | 4:5 | 1080x1350 |
| Instagram story | 9:16 | 1080x1920 |
| YouTube thumbnail | 16:9 | 1280x720 |
| 1:1 | 1080x1080 | |
| 16:9 | 1200x630 |
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).
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).
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.