Skill

nano-banana

Install
1
Install the plugin
$
npx claudepluginhub pigfoot/claude-code-hubs --plugin superpowers

Want just this skill?

Add to a custom plugin, then install with one command.

Description

Use when users request image generation, AI art creation, image editing with Gemini models, need help crafting prompts, or want brand-styled imagery. Handles both direct generation and interactive prompt design.

Tool Access

This skill is limited to using the following tools:

Bash Write Read AskUserQuestion
Supporting Assets
View in Repository
assets/README.md
assets/logos/README.md
assets/logos/trendlife-2026-logo-light.png
assets/templates/README.md
references/batch-generation.md
references/brand-styles.md
references/guide.md
references/slide-deck-styles.md
scripts/generate_images.py
scripts/logo_overlay.py
Skill Content

Nano Banana

Unified image generation workflow using a fixed Python script with JSON configuration. Eliminates AI hallucinations by avoiding dynamic code generation.

Supports two modes:

  • Unified Generation: All image requests use generate_images.py with JSON config
  • Interactive Prompting: Guide user through prompt design with proven techniques

🚨 CRITICAL: Read This First

API Selection Rule

BEFORE writing ANY code, determine which API to use

model = os.environ.get("NANO_BANANA_MODEL") or "gemini-3-pro-image-preview"

# Select API based on model name
if "imagen" in model.lower():
    use_imagen_api = True   # → generate_images()
else:
    use_imagen_api = False  # → generate_content()

Two COMPLETELY DIFFERENT APIs

These are NOT interchangeable. Using the wrong API will cause errors.

Gemini ImageImagen
API Methodgenerate_content()generate_images()
Config TypeGenerateContentConfigGenerateImagesConfig
Modelsgemini-*-image*imagen-*
Prompt Formatcontents=[prompt] (array)prompt=prompt (string)
Responseresponse.partsresponse.generated_images
Special Configresponse_modalities=['IMAGE']Not used

Example model detection

# These trigger Imagen API:
"imagen-4.0-generate-001" → generate_images()
"custom-imagen-v2" → generate_images()

# These trigger Gemini API:
"gemini-3-pro-image-preview" → generate_content()
"gemini-2.5-flash-image" → generate_content()
"custom-gemini-image" → generate_content()

āŒ DOES NOT EXIST - Never Use These

If you find yourself writing these, STOP - you are using the wrong API:

āŒ Wrong (Does NOT exist)āœ… Correct
types.ImageGenerationConfigUse GenerateContentConfig (Gemini) or GenerateImagesConfig (Imagen)
generate_images() + Gemini modelUse generate_content() for Gemini models
generate_content() + Imagen modelUse generate_images() for Imagen models
response_modalities in ImagenOnly use with Gemini's GenerateContentConfig

NANO_BANANA_MODEL: NEVER Override

Rule: If NANO_BANANA_MODEL is set, use it EXACTLY as-is.

āŒ WRONG - Do NOT do this:

model = os.environ.get("NANO_BANANA_MODEL", "gemini-3-pro-image")
if not model.endswith("-preview"):
    model = f"{model}-preview"  # āŒ NEVER modify user's model name

āœ… CORRECT:

model = os.environ.get("NANO_BANANA_MODEL")
if not model:
    # Only choose default when NANO_BANANA_MODEL is NOT set
    model = "gemini-3-pro-image-preview"
# Use model EXACTLY as-is - do NOT add suffixes or change names

Why this matters

  • Custom endpoints have their own model names (e.g., gemini-3-pro-image without -preview)
  • User explicitly set the model they want
  • DO NOT apply Google's naming conventions to custom endpoints

When to Use

  • Image generation ("draw", "create", "generate"), slides, presentations
  • Image editing with AI
  • Prompt help ("help me craft", "improve my prompt")
  • Brand styles ("use style trend", "notebooklm style")
  • Reproducible generation ("use seed 42", "regenerate that image")

Mode selection

  • Interactive Prompting: User asks for prompt help OR prompt too vague (<5 words)
  • Unified Generation: User provides detailed prompt (uses generate_images.py)

Parsing User Intent for Seed & Temperature

Extract seed from user message

  • "seed 42" → "seed": 42
  • "use seed 392664860" → "seed": 392664860
  • "regenerate with the same seed" → Use seed from previous results JSON
  • "seed: 123" (inline) → "seed": 123

Extract temperature from user message

  • "temperature 0.5" → "temperature": 0.5
  • "temp 1.5" → "temperature": 1.5
  • "lower temperature" → "temperature": 0.5 (suggest conservative value)
  • "higher temperature" → "temperature": 1.5 (suggest exploratory value)
  • "more creative" → "temperature": 1.5
  • "temperature: 0.8" (inline) → "temperature": 0.8

Combined examples

User: "Generate a robot image, seed 42, temperature 0.8"
→ Config: {"slides": [{"number": 1, "prompt": "robot", "seed": 42, "temperature": 0.8}]}

User: "Regenerate that image with seed 392664860"
→ Config: {"slides": [{"number": 1, "prompt": "<previous_prompt>", "seed": 392664860}]}

User: "Create 3 slides with same seed 100"
→ Config: {"seed": 100, "slides": [{...}, {...}, {...}]}

If user asks about reproducibility

  • Explain that seed enables regenerating the same image
  • Mention that results JSON automatically records seeds
  • Show example of how to use seed from previous generation

Style Detection

Detect: style: "trendlife", style: "notebooklm", or natural language ("use trendlife style", "notebooklm style")

Styles

  • TrendLife: Trend Micro's TrendLife product brand (Trend Red #D71920) with automatic logo overlay
  • NotebookLM: Clean presentation aesthetic (āš ļø NEVER use "NotebookLM" brand/logo in prompts)

Priority: Inline spec → Ask in Interactive Mode → No style (Direct Mode default)


Logo Overlay (TrendLife Style)

TrendLife style includes automatic logo overlay

When style: "trendlife" is detected:

  1. Generate slide image with TrendLife colors (no logo in prompt)
  2. Detect layout type from prompt content
  3. Apply logo overlay with logo_overlay.overlay_logo()
  4. Output final image with logo

Layout Detection Rules

Automatic detection based on keywords

  • "title slide", "cover slide", "opening" → title layout (15% logo, bottom-right)
  • "end slide", "closing", "thank you", "conclusion" → end layout (20% logo, center-bottom)
  • "divider", "section break" → divider layout (15% logo, bottom-right)
  • Slide number 1 (no keywords) → title layout (assumed opener)
  • Default → content layout (12% logo, bottom-right)

Manual Logo Overlay Override

Use when you need custom logo positioning:

IMPORTANT: This script must be run with uv run to ensure dependencies are available.

#!/usr/bin/env python3
# /// script
# dependencies = ["pillow"]
# ///
# Run with: uv run --managed-python your_script.py

# After image generation, before final output
from pathlib import Path
import sys

# Import logo overlay module
sys.path.insert(0, str(Path(__file__).parent))
from logo_overlay import overlay_logo, detect_layout_type

# Detect layout type (or specify manually)
layout_type = detect_layout_type(prompt, slide_number=1)
# Or override: layout_type = 'title'  # 'title', 'content', 'divider', 'end'

# Logo path
logo_path = Path(__file__).parent / 'assets/logos/trendlife-2026-logo-light.png'

# Apply logo overlay
output_with_logo = output_path.with_stem(output_path.stem + '_with_logo')
overlay_logo(
    background_path=output_path,
    logo_path=logo_path,
    output_path=output_with_logo,
    layout_type=layout_type,
    opacity=1.0  # Optional: 0.0-1.0
)

# Replace original with logo version
output_with_logo.replace(output_path)

Style Trigger Keywords

Explicit: style: "trendlife"

Natural Language

  • "trendlife style"
  • "use trendlife"
  • "trendlife brand"
  • "trendlife presentation"

Quick Reference

API Selection (CRITICAL - Check First)

Model Name ContainsAPI to UseConfig Type
imagengenerate_images()GenerateImagesConfig
Anything elsegenerate_content()GenerateContentConfig

See CRITICAL section above for complete details

Unified Generation Workflow

All image generation uses the same fixed Python script with JSON config:

  1. Create Config: Write JSON to system temp directory (NOT skill directory)
    • Use Write tool with path: {temp_dir}/nano-banana-config-{timestamp}.json
    • Get temp_dir from user's OS temp location (cross-platform)
  2. Execute Script: uv run --managed-python scripts/generate_images.py --config <temp_config_path>
    • Script path is relative to skill directory
    • CRITICAL: Use relative path to script WITHOUT changing directory (no cd command)
    • WRONG: cd scripts && uv run --managed-python generate_images.py ... āŒ
    • CORRECT: uv run --managed-python scripts/generate_images.py ... āœ…
    • This ensures execution cwd remains in user's project directory, so relative paths in config work correctly
  3. Track Progress: Monitor progress/results files (for background tasks)
  4. Return Paths: Report generated image locations

IMPORTANT

  • Always write config to system temp directory, NEVER to skill base directory
  • Always use scripts/generate_images.py for the script path (relative to skill directory)

Config Requirements

Minimal Config (recommended)

{
  "slides": [{"number": 1, "prompt": "...", "style": "trendlife"}],
  "output_dir": "./001-feature-name/"  // MUST use NNN-short-name format
}

Full Config (optional fields)

{
  "slides": [
    {
      "number": 1,
      "prompt": "...",
      "style": "trendlife",
      "layout": "featured",  // Optional: "featured" or "content" (auto-detect if omitted)
      "temperature": 0.8,    // Optional: 0.0-2.0 per-slide override
      "seed": 42             // Optional: integer for reproducible generation
    }
  ],
  "output_dir": "./001-feature-name/",  // MUST use NNN-short-name format
  "format": "webp",      // Optional: webp (default, RECOMMENDED), png, jpg
  "quality": 90,         // Optional: 1-100 (default: 90)
  "temperature": 1.0,    // Optional: 0.0-2.0 global default (default: 1.0)
  "seed": 12345          // Optional: integer global default (default: auto-generate)
}

Format Selection Guide

  • webp (RECOMMENDED): Default format, automatically uses lossless compression for presentation styles (trendlife, professional, data-viz). Same quality as PNG but 25-35% smaller file size.
  • png: Only use if webp compatibility is a concern (rare). Larger file size.
  • jpg: For photos only, not suitable for slides/diagrams (lossy compression).

Layout Field (TrendLife Only)

Purpose: Control logo integration strategy for TrendLife brand slides

Valid values:

  • "featured" - For title slides, dividers, and closing slides

    • Logo is used as reference image during AI generation (Gemini only)
    • AI naturally integrates logo into the overall design
    • Provides creative, professional branding
    • Note: Imagen API doesn't support reference images, so logo is overlaid instead
  • "content" - For content/information slides

    • Logo is overlaid in bottom-right corner (50px, 25px padding)
    • Fixed positioning ensures logo doesn't interfere with content
    • Consistent across all content slides
  • Omitted or null - Auto-detection (backwards compatibility)

    • System attempts to detect layout from prompt keywords
    • Less reliable than explicit specification

When to use each:

// Title/cover slides
{"number": 1, "prompt": "Product Launch 2026", "style": "trendlife", "layout": "featured"}

// Section dividers
{"number": 3, "prompt": "Part 2: Technical Details", "style": "trendlife", "layout": "featured"}

// Closing slides
{"number": 6, "prompt": "Thank You", "style": "trendlife", "layout": "featured"}

// Content slides (everything else)
{"number": 2, "prompt": "Key features and benefits", "style": "trendlife", "layout": "content"}
{"number": 4, "prompt": "Performance metrics", "style": "trendlife", "layout": "content"}

IMPORTANT: When generating JSON configs for TrendLife presentations:

  1. Analyze each slide's purpose (not just keywords)
  2. Title/cover/divider/closing → "layout": "featured"
  3. Information/data/content → "layout": "content"
  4. Always specify layout explicitly for TrendLife slides (don't rely on auto-detection)

Temperature & Seed Parameters

⚔ NEW: Reproducible Generation

Seed Parameter (Recommended)

Purpose: Enable reproducible image generation

How it works

  • Same seed + same prompt + same temperature = visually identical image
  • Default: Auto-generated timestamp-based seed (recorded in results JSON)
  • Use case: "I like this image, regenerate it exactly"

Seed: User natural language patterns

  • "use seed 42"
  • "regenerate with seed 392664860"
  • "same seed as before"
  • "seed: 123" (inline spec)

Config examples

// Global seed (all slides use same seed)
{"seed": 42, "slides": [...]}

// Per-slide seed (each slide has different seed)
{"slides": [
  {"number": 1, "prompt": "...", "seed": 42},
  {"number": 2, "prompt": "...", "seed": 123}
]}

// No seed specified (auto-generate and record)
{"slides": [...]}  // Results JSON will contain: "seed": 1738051234

Results tracking

  • All generated images record their actual seed in {output_dir}/generation-results.json
  • Example output:
{
  "outputs": [
    {"slide": 1, "path": "slide-01.png", "seed": 392664860, "temperature": 1.0}
  ]
}

Temperature Parameter (Experimental)

Purpose: Control randomness in generation (0.0-2.0)

Official guidance: Gemini 3 recommends keeping default value 1.0

Effect

  • āš ļø Limited impact observed in testing - changes output but effect is unpredictable
  • No clear "low temperature = conservative, high temperature = creative" pattern
  • Changes generation result when combined with same seed

Temperature: User natural language patterns

  • "temperature 0.5"
  • "use lower temperature"
  • "more creative (temperature 1.5)"
  • "temperature: 0.8" (inline spec)

Recommendation

  • āœ… Use seed for reproducibility (highly effective)
  • āš ļø Use temperature conservatively for experimentation only
  • šŸ’” Keep default 1.0 unless exploring variations

Priority rules

  • slide.temperature > config.temperature > 1.0 (default)
  • slide.seed > config.seed > auto-generate

Field Rules

  • āœ… output_dir MUST be relative path with NNN-short-name format: ./001-feature-name/
    • NNN = 3-digit number (001, 002, etc.)
    • short-name = brief descriptive name (lowercase, hyphens)
    • Examples: ./001-ai-safety/, ./002-threat-detection/, ./003-user-onboarding/
  • āŒ NO absolute paths (breaks cross-platform)
  • āŒ NO plain names without numbers (e.g., ./slides/ is WRONG)
  • āŒ NO model field (use NANO_BANANA_MODEL env var)

Output Directory Behavior

  • Relative paths resolve to user's current working directory
  • Script is executed with absolute path, but cwd remains in user's directory
  • Use sequential numbering for different presentation topics

Example: Config File Creation

# Linux/macOS: Write to /tmp/
Write tool: /tmp/nano-banana-config-1234567890.json

# Windows: Write to %TEMP%
Write tool: C:/Users/<user>/AppData/Local/Temp/nano-banana-config-1234567890.json

Multi-Slide Generation

  • Any slide count → Uses same workflow (generate_images.py)
  • 5+ slides → Automatic background execution with progress tracking
  • Context efficient → <500 tokens for any slide count

Complete workflow details: See references/batch-generation.md

Interactive Prompting Mode

StepAction
1. GatherCheck for reference images, style specs
2. ClarifyAsk 2-4 questions about output type, subject, style
3. Select TechniqueChoose from 16+ patterns (see references/guide.md)
4. Generate PromptApply technique, brand style, aspect ratio
5. PresentShow prompt with explanation and variations
6. ExecuteGenerate image with crafted prompt

Interactive Prompting Mode

When to use: User requests prompt help ("help me craft", "improve my prompt") or prompt is too vague (<5 words).

Workflow

  1. Gather - Check for reference images, existing prompts, inline style specs (style: "trend")
  2. Clarify - Use AskUserQuestion: Output type? Subject? Style preference?
  3. Select Technique - Choose from 16+ patterns in references/guide.md
  4. Generate Prompt - Apply technique + brand style + aspect ratio
  5. Present - Show prompt with explanation and variations
  6. Execute - Generate using unified generation workflow (generate_images.py)

Brand Style Integration

  • NotebookLM style (style: "notebooklm"):

    • Apply aesthetic: polished tech infographic, clean slide layout, minimal text
    • āš ļø NEVER use "NotebookLM" brand/logo/name in prompts (trademark violation)
    • āœ… Use: "clean professional presentation aesthetic", "modern tech infographic style"
    • See references/slide-deck-styles.md for complete specs
  • Trend Micro style (style: "trend"):

    • Colors: Trend Red (#d71920), Guardian Red (#6f0000), Grays (#58595b-#e6e7e8)
    • See references/brand-styles.md for complete specs

Complete techniques and examples: See references/guide.md

Debugging

Most Common Errors

ErrorQuick Fix
GEMINI_API_KEY not setexport GEMINI_API_KEY="your-key"
Model not foundCheck exact model name, use -preview suffix if needed
Wrong API usedCheck CRITICAL section: Gemini vs Imagen
ModuleNotFoundErrorVerify # dependencies = ["google-genai", "pillow"]
No image generatedCheck response.parts (Gemini) or response.generated_images (Imagen)
Invalid aspect ratioUse exact strings: "16:9", "1:1", "9:16" (with quotes)

Debug Steps

  1. Verify API key: echo $GEMINI_API_KEY
  2. Test with simple prompt: "A red circle"
  3. Check response object: print(response.parts) or print(response.generated_images)
  4. Review CRITICAL section if API errors occur

Common Mistakes

MistakeFix
Using types.ImageGenerationConfigDoes NOT exist - use GenerateContentConfig or GenerateImagesConfig
Using generate_images() with GeminiUse generate_content() for Gemini models
Using generate_content() with ImagenUse generate_images() for Imagen models
Overriding NANO_BANANA_MODEL when setUse model EXACTLY as-is - don't add suffixes
Using google-generativeai (old library)Use google-genai (new library)
Using text models for image genUse image models only (gemini-*-image* or imagen-*)
Saving to flat filesUse NNN-short-name/ directories
Using PIL to draw/editUse Gemini/Imagen API with image in contents

Example Workflows

Scenario 1: First Generation (Auto Seed)

User: "Generate a modern office interior"

Assistant actions:
1. Create config WITHOUT seed (auto-generate):
   {
     "slides": [{"number": 1, "prompt": "Modern office interior with natural lighting"}],
     "output_dir": "./001-office-design/"
   }
2. Execute: uv run --managed-python scripts/generate_images.py --config {temp_config}
3. Read results: ./001-office-design/generation-results.json
   → {"outputs": [{"slide": 1, "path": "slide-01.png", "seed": 392664860}]}
4. Report to user: "Generated at ./001-office-design/slide-01.png (seed: 392664860)"

Scenario 2: Reproduce Previous Image

User: "I love that office image! Regenerate it with seed 392664860"

Assistant actions:
1. Create config WITH seed:
   {
     "slides": [{"number": 1, "prompt": "Modern office interior with natural lighting", "seed": 392664860}],
     "output_dir": "./002-office-design-v2/"
   }
2. Execute script
3. Result: Visually identical image

Scenario 3: Explore Variations

User: "Generate 3 variations of a robot holding flowers, use different temperatures"

Assistant actions:
1. Create config with per-slide temperatures:
   {
     "seed": 42,  // Same seed for comparison
     "slides": [
       {"number": 1, "prompt": "A cute robot holding flowers", "temperature": 0.5},
       {"number": 2, "prompt": "A cute robot holding flowers", "temperature": 1.0},
       {"number": 3, "prompt": "A cute robot holding flowers", "temperature": 1.5}
     ],
     "output_dir": "./003-robot-variations/"
   }
2. Execute script
3. Result: 3 different compositions (temperature effect)

Scenario 4: Batch with Consistent Style

User: "Create 5 presentation slides with TrendLife style, use same seed"

Assistant actions:
1. Create config with global seed and appropriate layout for each slide:
   {
     "seed": 12345,
     "slides": [
       {"number": 1, "prompt": "AI Safety: Building Secure Systems", "style": "trendlife", "layout": "featured"},  // Title
       {"number": 2, "prompt": "Key features overview", "style": "trendlife", "layout": "content"},  // Content
       {"number": 3, "prompt": "Technical architecture", "style": "trendlife", "layout": "content"},  // Content
       {"number": 4, "prompt": "Use cases and benefits", "style": "trendlife", "layout": "content"},  // Content
       {"number": 5, "prompt": "Thank You - Contact Us", "style": "trendlife", "layout": "featured"}  // Closing
     ],
     "output_dir": "./004-ai-safety-deck/"
   }
2. Execute in background (5+ slides)
3. Monitor progress file
4. Results:
   - Slide 1 (featured): Logo integrated naturally by AI into title design
   - Slides 2-4 (content): Logo overlaid in bottom-right corner
   - Slide 5 (featured): Logo integrated naturally by AI into closing design
   - All slides use seed 12345 for visual consistency

Common Errors and Solutions

If script execution fails, check these common issues:

1. "Logo file is Git LFS pointer" or "cannot identify image file"

Most common issue: User doesn't have Git LFS installed

  • Logo files are managed by Git LFS - without it, you get text pointer files instead of images

  • Solution:

    # Install Git LFS (once per machine)
    git lfs install
    
    # Pull actual files (in the plugin directory)
    git lfs pull
    
  • Git LFS install: https://git-lfs.com/

  • After installing, re-run the image generation command

2. "command not found: uv"

3. "Python 3.14+ recommended" or "Python 3.9+ required"

  • First run with --managed-python downloads Python 3.14+ automatically
  • If download fails, user can pre-install: uv python install 3.14
  • Script supports Python 3.9+ as fallback but 3.14+ is recommended
  • Check: Internet connection and disk space

4. Permission denied or download errors

  • Check write permissions in uv cache directory (usually ~/.local/share/uv/)
  • Verify: Firewall/proxy settings allow uv to download Python

5. Missing dependencies (google-genai, pillow)

  • Dependencies are automatically installed by uv run via PEP 723 metadata
  • If user bypasses uv and runs script directly with python, they'll see standard ImportError
  • Solution: Always use uv run --managed-python scripts/generate_images.py

References

  • Advanced workflows: references/guide.md (thinking, search grounding, 16+ prompting techniques)
  • Brand styles: references/brand-styles.md (Trend Micro specs)
  • Slide decks: references/slide-deck-styles.md (NotebookLM aesthetic, infographics, data viz)
  • Experiments: ../EXPERIMENT_RESULTS.md (temperature & seed testing results)
Stats
Stars4
Forks0
Last CommitFeb 8, 2026
Actions

Similar Skills