Skip to content
Content
Skill

/visual-prompt-forge

Generate model-specific prompts from shots.json. Outputs copy-paste-ready prompts for stills (Midjourney, Flux, Ideogram, GPT Image, Nano Banana, Seedream) and motion video (Kling, Veo, Seedance, Hailuo). Also runs a revision mode that reads a critique.json and re-emits prompts

From plugin
shotkit
205 skills
Install
$ npx -y skills add whystrohm/shotkit --skill visual-prompt-forge --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/visual-prompt-forge

Context preview

The summary Claude sees to decide when to auto-load this skill.

Generate model-specific prompts from shots.json. Outputs copy-paste-ready prompts for stills (Midjourney, Flux, Ideogram, GPT Image, Nano Banana, Seedream) and motion video (Kling, Veo, Seedance, Hailuo). Also runs a revision mode that reads a critique.json and re-emits prompts

SKILL.md

visual-prompt-forge.SKILL.md
name: visual-prompt-forge
description: Generate model-specific prompts from shots.json. Outputs copy-paste-ready prompts for stills (Midjourney, Flux, Ideogram, GPT Image, Nano Banana, Seedream) and motion video (Kling, Veo, Seedance, Hailuo). Also runs a revision mode that reads a critique.json and re-emits prompts for only the failed shots, closing the QA loop. Use when the user asks for image or video prompts, mentions any of those generators, wants AI-generated frames for a storyboard, or hands over shots.json. The prompt half of the pipeline. Composes with storyboard-architect upstream, visual-asset-critic downstream.

Visual Prompt Forge

You are turning structured shot data into prompts that work in production. Each image generator rewards a different prompting style, short and high-signal for Midjourney, natural-language for Flux, paragraph-form for GPT Image, text-aware for Ideogram. A prompt that crushes in one will produce slop in another.

This skill adapts. Same shot, different syntax.

When to use

Trigger when the user:

  • Hands over a `shots.json` (or any structured shot list) and asks for prompts
  • Names a specific generator (Midjourney, Flux, Ideogram, GPT Image, Nano Banana, Seedream, Kling, Veo, Seedance, Hailuo)
  • Asks for "image prompts," "Midjourney prompts," "AI prompts," "generation prompts" for a storyboard
  • Wants the same shot adapted to multiple generators

If the user wants to build a storyboard from scratch (no shots.json yet), use `storyboard-architect` first, then chain into this skill.

What you produce

For a given `shots.json` and a list of target generators, produce one file per generator, inside a directory named for the round:

output/prompts/round-1/
├── midjourney.txt          # If targeted
├── flux.txt
├── ideogram.txt
├── gpt-image.txt
├── nano-banana.txt
├── seedream.txt
├── kling.txt               # Motion-aware video, default
├── veo.txt                 # Motion, dialogue/lipsync + native audio
├── seedance.txt            # Motion, multi-shot sequences
└── hailuo.txt              # Motion, budget iteration

Round 1 is the first pass. Revision mode writes `output/prompts/round-2/`, and so on. The round in the path is not decoration: prompt files used to be written to one fixed path per generator, so round 2 destroyed round 1 and the prompt that actually produced most of the surviving frames was gone.

Each file is plain text, one prompt per shot, separated by a blank line and a `# shot_NN` comment. Designed for copy-paste workflows, drop into the generator's UI or pipe into an API.

The five-layer prompt anatomy

Every prompt is composed from these layers. Read `references/prompt-anatomy.md` for the full theory. Quick version:

1. **Brand Lock**, palette, type, mood, "never" list (constant across project) 2. **Series Lock**, character/environment/lighting anchors (constant across storyboard) 3. **Shot Spec**, framing, angle, motion, subject (per shot) 4. **Text Layer**, **never in the prompt**, composited separately 5. **Generator Adapter**, model-specific syntax wrapper

The first four come from `shots.json` and the brand-lock. The fifth is what this skill applies.

Workflow

Step 1. Read inputs

You need:

  • `shots.json` (required), the structured shot list
  • `brand-lock.snapshot.md` (required), referenced from shots.json
  • Target generators (required), ask if not specified

Validate before composing:

python tools/validate_shots.py output/

If the brand-lock is missing or `shots.json` does not validate, stop and tell the user. Don't try to forge prompts from incomplete data.

If `tools/` is not on hand (a Claude.ai upload, or a single-skill install), read the schema from `../storyboard-architect/templates/shots.schema.json` and check by hand. That relative path only resolves when the skills sit side by side; when they don't, ask the user for the schema rather than composing from memory of it.

Step 2. Pick the adapters

For each target generator, read the matching adapter file:

  • `adapters/midjourney.md`
  • `adapters/flux.md`
  • `adapters/ideogram.md`
  • `adapters/gpt-image.md`
  • `adapters/nano-banana.md`
  • `adapters/seedream.md`
  • `adapters/kling.md` (motion video, default)
  • `adapters/veo.md` (motion video, dialogue/lipsync + native audio)
  • `adapters/seedance.md` (motion video, multi-shot sequences)
  • `adapters/hailuo.md` (motion video, budget iteration)

Each adapter file documents the prompting style, parameter syntax, and known pitfalls for that generator. You **must** read the adapter before writing prompts for it. Don't guess from training data, image-gen syntax has churned multiple times.

**`adapters/_capabilities.json` is the single source of truth for per-generator limits** (`max_prompt_words`, `supports_text_render`, `supports_motion`, `aspect_param`, and so on). Read it once at the start and respect those values when composing, and do not target motion on a stills-only generator.

`max_prompt_words` is a ceiling. The range in an adapter `.md` is the recommended target and always sits inside that ceiling, so a `.md` saying "40 to 70 words" under a ceiling of 120 is guidance, not a conflict. Where a fact in a `.md` and a fact in the JSON genuinely disagree, **the JSON wins**.

That rule is now enforced rather than trusted. `tools/validate_capabilities.py` fails the build when an adapter advertises more words than its ceiling, or when an adapter never documents the `aspect_param` the JSON tells you to send. The second check exists because nano-banana's matrix entry said `aspect_ratio` while its adapter said the API expects `aspectRatio`; the precedence rule meant the wrong one won, silently, on every prompt.

Step 3. Compose per shot

For each shot in `shots.json`, for each target generator:

1. Pull brand-lock palette, mood, "never" list 2. Pull series_lock character/environment/lighting 3. Pull shot framing/angle/motion/subject 4. **Strip any on_screen_text r

Read more
Ships withshotkit

The pre-production system we use to ship hundreds of videos a month. Open-sourced.

Get the whole plugin
Stats
20
Stars
5
Forks
Maintained
Maintenance
Python
Language
Apache-2.0
License
1mo ago
Last commit
4mo ago
Created

Repo: whystrohm/shotkit

Other skills on shotkit.