@milenyumai/film-kit 2.3.1 → 2.3.2
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 +18 -1
- package/build/cli.js +2 -1
- package/build/lib/cli.js +4 -0
- package/build/lib/configure.js +494 -17
- package/build/lib/defaults.js +3 -1
- package/build/lib/storyboard-reference/adapters/seedance20.js +11 -1
- package/build/lib/storyboard-reference/index.d.ts +1 -1
- package/build/lib/storyboard-reference/index.js +1 -1
- package/build/lib/storyboard-reference/output-writer.js +3 -0
- package/build/lib/storyboard-reference/prompt-bundle-builder.js +45 -5
- package/build/lib/storyboard-reference/types.d.ts +3 -0
- package/build/lib/storyboard-reference/validators.d.ts +4 -2
- package/build/lib/storyboard-reference/validators.js +74 -17
- package/build/lib/templates.js +144 -36
- package/content/workflows/generate-storyboard.md +16 -0
- package/package.json +1 -1
- package/packages/studio/build/lib/configure.js +4 -4
package/README.md
CHANGED
|
@@ -126,6 +126,16 @@ Use this mode when the source material is a character reference image plus a bri
|
|
|
126
126
|
|
|
127
127
|
Initialize a Seedance storyboard-reference runtime:
|
|
128
128
|
|
|
129
|
+
```bash
|
|
130
|
+
npx @milenyumai/film-kit init \
|
|
131
|
+
--preset single \
|
|
132
|
+
--model seedance-2.0 \
|
|
133
|
+
--reference-mode storyboard-reference \
|
|
134
|
+
--max-storyboard-phases 4
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
For multi-agent storyboard-reference generation:
|
|
138
|
+
|
|
129
139
|
```bash
|
|
130
140
|
npx @milenyumai/film-kit init \
|
|
131
141
|
--preset multi \
|
|
@@ -177,15 +187,21 @@ Outputs:
|
|
|
177
187
|
- `outputs/shots/SHOTNN.md`
|
|
178
188
|
- `outputs/reports/STORYBOARD-REFERENCE-QA.md`
|
|
179
189
|
|
|
190
|
+
In a project initialized with `--reference-mode storyboard-reference`, `/generate` is mode-guarded to use the storyboard-reference workflow. It will not generate start/end frame packages. If no character reference is available through `--character-ref`, an in-context image, or `refs/character.png`, generation stops and asks for one.
|
|
191
|
+
|
|
180
192
|
Rules:
|
|
181
193
|
|
|
182
194
|
- `@character1` is used once to create a 16:9 character sheet prompt with front, back, side, three-quarter, and face close-up views.
|
|
195
|
+
- GPT Image 2 still prompts use `REFERENCE LOCK`, `Keep same`, `Change only`, and `Avoid` sections so character identity, wardrobe, props, and materials stay immutable unless explicitly changed.
|
|
183
196
|
- Each `SHOTNN.md` includes a professional `GPT IMAGE 2 STORYBOARD PROMPT`; the generated shot storyboard controls composition, blocking, camera, timing, and editorial phase order only.
|
|
184
197
|
- Storyboard prompts use production-board grammar: rough black-and-white pencil panels, strong silhouettes, visible body/camera momentum, and optional color-coded planning annotations. Seedance is instructed to follow the panel order while ignoring arrows, notes, labels, and timestamps in the rendered video.
|
|
185
198
|
- Seedance provider-facing tokens map generated character sheets first (`@Image1`, `@Image2`, ...) and the generated shot storyboard next. Legacy lowercase aliases remain documented in runtime text.
|
|
199
|
+
- Speaking shots must bind `Audio Plan.activeSpeakerKey` back to project-level `voiceCast`; broken voice bindings fail QA.
|
|
200
|
+
- Public-figure, celebrity, likeness, logo, trademark, or brand references in the brief, dialogue metadata, or reference metadata are blocked unless safely anonymized first.
|
|
186
201
|
- Phase budget: 4-6s uses 1-2 phases, 7-10s uses 2-3 phases, and 11-15s uses 3-4 phases.
|
|
187
202
|
- 5+ storyboard phases are split into multiple `SHOTNN.md` files by default.
|
|
188
203
|
- Multi-phase storyboards use planned phase transitions instead of forcing `No scene cuts throughout, one continuous shot.`
|
|
204
|
+
- Seeing `ILK FRAME`, `İLK FRAME`, or `SON FRAME` in main storyboard-reference shot output means the old start/end runtime leaked in; treat that output as failed and rerun after reinitializing with `--reference-mode storyboard-reference`.
|
|
189
205
|
- Existing start/end workflows stay unchanged and remain the default.
|
|
190
206
|
|
|
191
207
|
CLI flags for direct storyboard bundle generation:
|
|
@@ -435,7 +451,8 @@ Generated specialist and render QA flows now explicitly fail on:
|
|
|
435
451
|
Studio render QA also records render-level verdicts such as:
|
|
436
452
|
|
|
437
453
|
- `reference_drift_status`
|
|
438
|
-
- `start_end_contract_status`
|
|
454
|
+
- `start_end_contract_status` in start/end mode
|
|
455
|
+
- `storyboard_reference_status` and `storyboard_handoff_status` in storyboard-reference mode
|
|
439
456
|
|
|
440
457
|
## Seedance Runtime Coverage
|
|
441
458
|
|
package/build/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { parseCliCommand, renderCliUsage } from "./lib/cli.js";
|
|
3
3
|
import { configureFilmKit } from "./lib/film-kit.js";
|
|
4
|
-
import { buildStoryboardReferencePromptBundles, writeStoryboardReferenceOutputs } from "./lib/storyboard-reference/index.js";
|
|
4
|
+
import { assertStoryboardReferenceBuildPass, buildStoryboardReferencePromptBundles, writeStoryboardReferenceOutputs } from "./lib/storyboard-reference/index.js";
|
|
5
5
|
const args = process.argv.slice(2);
|
|
6
6
|
try {
|
|
7
7
|
const parsed = await parseCliCommand(args, process.cwd());
|
|
@@ -15,6 +15,7 @@ try {
|
|
|
15
15
|
}
|
|
16
16
|
console.log("🎬 Film-Kit: Generating storyboard-reference prompt bundle...\n");
|
|
17
17
|
const buildResult = buildStoryboardReferencePromptBundles(parsed.storyboardRequest);
|
|
18
|
+
assertStoryboardReferenceBuildPass(buildResult);
|
|
18
19
|
const writeResult = await writeStoryboardReferenceOutputs(buildResult, process.cwd());
|
|
19
20
|
console.log(`✅ Files written: ${writeResult.written.length}`);
|
|
20
21
|
writeResult.written.forEach(file => console.log(` ${file}`));
|
package/build/lib/cli.js
CHANGED
|
@@ -417,6 +417,9 @@ async function parseGenerateStoryboardCommand(args, rootDir) {
|
|
|
417
417
|
if (!brief) {
|
|
418
418
|
throw new Error("generate-storyboard requires --brief.");
|
|
419
419
|
}
|
|
420
|
+
if (characterRefs.length === 0) {
|
|
421
|
+
throw new Error("generate-storyboard requires --character-ref.");
|
|
422
|
+
}
|
|
420
423
|
const request = {
|
|
421
424
|
mode: "storyboard-reference",
|
|
422
425
|
targetModels,
|
|
@@ -524,6 +527,7 @@ generate-storyboard flags:
|
|
|
524
527
|
--audio-intent SFX/ambience direction
|
|
525
528
|
--style-intent Visual style direction
|
|
526
529
|
--storyboard-panel-count-hint Panel/phase count hint; 5+ panels split into multiple SHOTNN files
|
|
530
|
+
--max-storyboard-phases Upper bound per SHOTNN storyboard phase count
|
|
527
531
|
|
|
528
532
|
Install:
|
|
529
533
|
npm install --save-dev @milenyumai/film-kit
|
package/build/lib/configure.js
CHANGED
|
@@ -52,17 +52,73 @@ async function copyContentFiles(rootDir, overwrite, templateVars, targetRoot = "
|
|
|
52
52
|
const targetRelative = `${targetRoot}/${file.relativePath}`;
|
|
53
53
|
const targetAbsolute = join(rootDir, targetRelative);
|
|
54
54
|
const targetExists = await exists(targetAbsolute);
|
|
55
|
-
|
|
55
|
+
const forceModeSensitiveRewrite = templateVars.storyboardReferenceActive && isStoryboardModeSensitiveContent(file.relativePath);
|
|
56
|
+
if (targetExists && !overwrite && !forceModeSensitiveRewrite) {
|
|
56
57
|
skipped.push(targetRelative);
|
|
57
58
|
continue;
|
|
58
59
|
}
|
|
59
60
|
const rawContent = await readFile(file.absolutePath, "utf8");
|
|
60
|
-
const content =
|
|
61
|
+
const content = renderModeSensitiveContent(file.relativePath, rawContent, templateVars);
|
|
61
62
|
await writeText(targetAbsolute, content);
|
|
62
63
|
written.push(targetRelative);
|
|
63
64
|
}
|
|
64
65
|
return { written, skipped };
|
|
65
66
|
}
|
|
67
|
+
const STORYBOARD_MODE_SENSITIVE_CONTENT = new Set([
|
|
68
|
+
"workflows/generate.md",
|
|
69
|
+
"workflows/chain.md",
|
|
70
|
+
"workflows/safety-check.md",
|
|
71
|
+
"workflows/finish.md",
|
|
72
|
+
"workflows/recover.md",
|
|
73
|
+
"skills/frame-chaining/SKILL.md",
|
|
74
|
+
"skills/coverage-system/SKILL.md",
|
|
75
|
+
"skills/prompt-structure/SKILL.md"
|
|
76
|
+
]);
|
|
77
|
+
const STORYBOARD_MODE_SENSITIVE_PROJECT_FILES = new Set([
|
|
78
|
+
"AGENTS.md",
|
|
79
|
+
"CLAUDE.md",
|
|
80
|
+
".cursorrules",
|
|
81
|
+
".cursor/rules/global.mdc",
|
|
82
|
+
".claude/CLAUDE.md",
|
|
83
|
+
".claude/agents/prompt-engineer.md",
|
|
84
|
+
".claude/rules/generate-flow.md",
|
|
85
|
+
".claude/rules/output-contract.md",
|
|
86
|
+
".github/copilot-instructions.md",
|
|
87
|
+
".github/instructions/shotforge.instructions.md",
|
|
88
|
+
".agent/skills/shotforge-generate/SKILL.md",
|
|
89
|
+
".agents/skills/shotforge-generate/SKILL.md",
|
|
90
|
+
".agents/skills/film-kit-codex-images/SKILL.md",
|
|
91
|
+
".agent/workflows/codex-images.md",
|
|
92
|
+
".codex/agents/prompt-engineer.toml"
|
|
93
|
+
]);
|
|
94
|
+
function isStoryboardModeSensitiveContent(relativePath) {
|
|
95
|
+
return STORYBOARD_MODE_SENSITIVE_CONTENT.has(relativePath);
|
|
96
|
+
}
|
|
97
|
+
function renderModeSensitiveContent(relativePath, rawContent, vars) {
|
|
98
|
+
if (!vars.storyboardReferenceActive) {
|
|
99
|
+
return renderContentTemplate(rawContent, vars);
|
|
100
|
+
}
|
|
101
|
+
switch (relativePath) {
|
|
102
|
+
case "workflows/generate.md":
|
|
103
|
+
return buildStoryboardGenerateWorkflow(vars);
|
|
104
|
+
case "workflows/chain.md":
|
|
105
|
+
return buildStoryboardChainWorkflow(vars);
|
|
106
|
+
case "workflows/safety-check.md":
|
|
107
|
+
return buildStoryboardSafetyCheckWorkflow(vars);
|
|
108
|
+
case "workflows/finish.md":
|
|
109
|
+
return buildStoryboardFinishWorkflow(vars);
|
|
110
|
+
case "workflows/recover.md":
|
|
111
|
+
return buildStoryboardRecoverWorkflow(vars);
|
|
112
|
+
case "skills/frame-chaining/SKILL.md":
|
|
113
|
+
return buildStoryboardFrameChainingSkill(vars);
|
|
114
|
+
case "skills/coverage-system/SKILL.md":
|
|
115
|
+
return buildStoryboardCoverageSkill(vars);
|
|
116
|
+
case "skills/prompt-structure/SKILL.md":
|
|
117
|
+
return buildStoryboardPromptStructureSkill(vars);
|
|
118
|
+
default:
|
|
119
|
+
return renderContentTemplate(rawContent, vars);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
66
122
|
function renderContentTemplate(content, vars) {
|
|
67
123
|
return content
|
|
68
124
|
.replaceAll("$OUTPUT_DIR", vars.outputDir)
|
|
@@ -70,8 +126,429 @@ function renderContentTemplate(content, vars) {
|
|
|
70
126
|
.replaceAll("$MODEL_DISPLAY", vars.modelDisplayName)
|
|
71
127
|
.replaceAll("$MODEL", vars.model)
|
|
72
128
|
.replaceAll("$KLING_PRESET", vars.klingPreset)
|
|
129
|
+
.replaceAll("$REFERENCE_MODE", vars.referenceMode)
|
|
130
|
+
.replaceAll("$MAX_STORYBOARD_PHASES", String(vars.maxStoryboardPhases))
|
|
73
131
|
.replaceAll("$ARGUMENTS", "");
|
|
74
132
|
}
|
|
133
|
+
function buildStoryboardGenerateWorkflow(vars) {
|
|
134
|
+
return `---
|
|
135
|
+
description: Generate storyboard-reference prompt bundles from character references and a brief. Storyboard mode forbids start/end frame output.
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
# /generate - Storyboard Reference Mode
|
|
139
|
+
|
|
140
|
+
## Fail-Closed Mode Gate
|
|
141
|
+
|
|
142
|
+
- Active workflow: \`generate-storyboard\`.
|
|
143
|
+
- Reference mode: \`storyboard-reference\`.
|
|
144
|
+
- Start/end frame generation: disabled.
|
|
145
|
+
- \`/generate\` MUST follow this storyboard-reference workflow. Do not use the legacy start/end shot template.
|
|
146
|
+
- Missing character reference is a blocker. If the user did not provide \`--character-ref\`, an in-context character image, or \`refs/character.png\`, stop and request one.
|
|
147
|
+
- Empty brief is a blocker. Use the active editor markdown first, then \`${vars.scenarioHint}\`.
|
|
148
|
+
- Forbidden in generated \`SHOTNN.md\`: \`ILK FRAME\`, \`İLK FRAME\`, \`SON FRAME\`, \`SHOTNN_START\`, \`SHOTNN_END\`, exact first-frame reuse instructions, and mandatory Start+End transition fields.
|
|
149
|
+
|
|
150
|
+
## Model Profile
|
|
151
|
+
|
|
152
|
+
- Read \`.agent/model-profile.md\` before planning.
|
|
153
|
+
- Active model: \`${vars.model}\` (\`${vars.modelDisplayName}\`)
|
|
154
|
+
- Reference mode: \`storyboard-reference\`
|
|
155
|
+
- Max storyboard phases per shot: ${vars.maxStoryboardPhases}
|
|
156
|
+
|
|
157
|
+
## Required Outputs
|
|
158
|
+
|
|
159
|
+
\`\`\`text
|
|
160
|
+
${vars.outputDir}/
|
|
161
|
+
├── storyboard-reference-plan.json
|
|
162
|
+
├── reference-prep/
|
|
163
|
+
│ └── CHARACTER-SHEET-*.md
|
|
164
|
+
├── storyboard-prompts/
|
|
165
|
+
│ └── SHOTNN-GPT-IMAGE-2-STORYBOARD.md
|
|
166
|
+
├── prompt-bundles/
|
|
167
|
+
│ └── SHOTNN.bundle.json
|
|
168
|
+
├── shots/
|
|
169
|
+
│ └── SHOTNN.md
|
|
170
|
+
└── reports/
|
|
171
|
+
└── STORYBOARD-REFERENCE-QA.md
|
|
172
|
+
\`\`\`
|
|
173
|
+
|
|
174
|
+
## Flow
|
|
175
|
+
|
|
176
|
+
1. Confirm asset roles:
|
|
177
|
+
- character references: identity, face, body proportions, wardrobe, accessories, and visible props
|
|
178
|
+
- optional storyboard guide references: composition, blocking, camera, timing, and action rhythm only
|
|
179
|
+
2. Generate one GPT Image 2 character sheet prompt per character reference:
|
|
180
|
+
- 16:9 production storyboard sheet
|
|
181
|
+
- front full body, back full body, left profile, right profile, three-quarter full body, close-up face
|
|
182
|
+
- no labels, text, logos, watermarks, alternate designs, or extra characters
|
|
183
|
+
3. Build \`${vars.outputDir}/storyboard-reference-plan.json\` with:
|
|
184
|
+
- \`referenceMode: "storyboard-reference"\`
|
|
185
|
+
- \`storyboardReferenceMode.enabled: true\`
|
|
186
|
+
- \`maxStoryboardPhases: ${vars.maxStoryboardPhases}\`
|
|
187
|
+
- \`voiceCast\` when dialogue or narration exists
|
|
188
|
+
- \`visual_world\` for camera, lens, lighting, scale, reflection, physics, screen direction, and continuity anchors
|
|
189
|
+
4. Split the scenario into shots by dramatic beat. Use this phase budget:
|
|
190
|
+
- 4-6 seconds: 1-2 phases
|
|
191
|
+
- 7-10 seconds: 2-3 phases
|
|
192
|
+
- 11-15 seconds: 3-4 phases
|
|
193
|
+
- 5+ distinct phases: split into separate \`SHOTNN.md\` files
|
|
194
|
+
5. For each shot, write a GPT Image 2 storyboard prompt:
|
|
195
|
+
- use character sheets as the only identity source
|
|
196
|
+
- use optional storyboard guides only for staging and timing
|
|
197
|
+
- include previous-shot handoff and next-shot handoff
|
|
198
|
+
- preserve shared \`visual_world\`, lighting, screen direction, and action rhythm
|
|
199
|
+
6. Build model-ready video prompt bundles:
|
|
200
|
+
- Seedance: character sheet tokens first, generated shot storyboard token next
|
|
201
|
+
- Veo: visual planning prompt with full audio direction
|
|
202
|
+
- Kling: block-structured storyboard route, not a mandatory Start+End frame route
|
|
203
|
+
7. Keep coverage inside the same \`SHOTNN.md\`; coverage uses storyboard planning prompts and does not request separate start/end still prompts.
|
|
204
|
+
8. Run QA and write \`${vars.outputDir}/reports/STORYBOARD-REFERENCE-QA.md\`.
|
|
205
|
+
|
|
206
|
+
## Required SHOTNN.md Sections
|
|
207
|
+
|
|
208
|
+
Each storyboard-reference shot file must include:
|
|
209
|
+
|
|
210
|
+
- \`Model Control\`
|
|
211
|
+
- \`Input Asset Roles\`
|
|
212
|
+
- \`Reference Asset Requirements\`
|
|
213
|
+
- \`GPT Image 2 Character Sheet Prompt\` or a link to the generated character sheet prompt
|
|
214
|
+
- \`GPT Image 2 SHOTNN Storyboard Prompt\`
|
|
215
|
+
- \`Storyboard Plan\`
|
|
216
|
+
- \`Audio Plan\`
|
|
217
|
+
- \`${vars.model === "seedance-2.0" ? "Seedance 2.0 Ready Video Prompt" : "Model-Ready Video Prompt"}\`
|
|
218
|
+
- \`Coverage Shots\`
|
|
219
|
+
- \`QA Verdict\`
|
|
220
|
+
|
|
221
|
+
## QA Verdict
|
|
222
|
+
|
|
223
|
+
Reject the output if:
|
|
224
|
+
|
|
225
|
+
- any main shot uses start/end frame sections or exact first-frame reuse instructions
|
|
226
|
+
- character identity is sourced from storyboard drawings, text, panel borders, watermarks, logos, or alternate designs
|
|
227
|
+
- storyboard phases exceed ${vars.maxStoryboardPhases} in one \`SHOTNN.md\`
|
|
228
|
+
- coverage is split into separate files
|
|
229
|
+
- \`storyboard_reference_status\` or \`storyboard_handoff_status\` is fail
|
|
230
|
+
`;
|
|
231
|
+
}
|
|
232
|
+
function buildStoryboardChainWorkflow(vars) {
|
|
233
|
+
return `---
|
|
234
|
+
description: Continue storyboard-reference projects using storyboard handoff continuity, not start/end frame chaining.
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
# /chain - Storyboard Reference Continuation
|
|
238
|
+
|
|
239
|
+
## Mode Gate
|
|
240
|
+
|
|
241
|
+
- Reference mode: \`storyboard-reference\`.
|
|
242
|
+
- Continue from the previous shot's \`Storyboard Plan\` final handoff.
|
|
243
|
+
- Do not extract or reuse end-frame assets.
|
|
244
|
+
- Do not create \`ILK FRAME\` / \`SON FRAME\` sections.
|
|
245
|
+
|
|
246
|
+
## Steps
|
|
247
|
+
|
|
248
|
+
1. Read \`.agent/model-profile.md\`.
|
|
249
|
+
2. Read \`${vars.outputDir}/storyboard-reference-plan.json\` and \`${vars.outputDir}/_index.md\` if present.
|
|
250
|
+
3. Read the last completed \`${vars.outputDir}/shots/SHOTNN.md\`.
|
|
251
|
+
4. Extract:
|
|
252
|
+
- final storyboard phase
|
|
253
|
+
- final action state
|
|
254
|
+
- camera direction and lens family
|
|
255
|
+
- lighting and screen direction
|
|
256
|
+
- character identity references
|
|
257
|
+
5. Create the next shot with a matching opening \`Storyboard Plan\` handoff.
|
|
258
|
+
6. Keep coverage in the same shot file.
|
|
259
|
+
7. Update \`${vars.outputDir}/storyboard-reference-plan.json\`, prompt bundles, reports, and index.
|
|
260
|
+
|
|
261
|
+
## Exit Gate
|
|
262
|
+
|
|
263
|
+
- \`storyboard_handoff_status: pass\`
|
|
264
|
+
- \`storyboard_reference_status: pass\`
|
|
265
|
+
- no forbidden start/end frame sections
|
|
266
|
+
`;
|
|
267
|
+
}
|
|
268
|
+
function buildStoryboardSafetyCheckWorkflow(vars) {
|
|
269
|
+
return `---
|
|
270
|
+
description: Validate storyboard-reference outputs, role separation, safety, and handoff continuity.
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
# /safety-check - Storyboard Reference Validation
|
|
274
|
+
|
|
275
|
+
## Mode Gate
|
|
276
|
+
|
|
277
|
+
- Reference mode: \`storyboard-reference\`.
|
|
278
|
+
- Validate storyboard prompt bundles and \`SHOTNN.md\` files.
|
|
279
|
+
- Do not require start/end frame sections, frame reuse text, or Start+End transition fields.
|
|
280
|
+
|
|
281
|
+
## Checklist
|
|
282
|
+
|
|
283
|
+
1. Safety and name policy
|
|
284
|
+
- no real names in visual prompts or summaries
|
|
285
|
+
- dialogue naming follows \`${vars.outputDir}/storyboard-reference-plan.json\`
|
|
286
|
+
- public figure, trademark, and unsafe likeness risks are anonymized or blocked
|
|
287
|
+
2. Storyboard-reference format
|
|
288
|
+
- each shot contains \`Input Asset Roles\`, \`Reference Asset Requirements\`, \`GPT Image 2 SHOTNN Storyboard Prompt\`, \`Storyboard Plan\`, \`Audio Plan\`, model-ready video prompt, coverage, and \`QA Verdict\`
|
|
289
|
+
- \`GPT Image 2 Character Sheet Prompt\` exists in the shot or \`${vars.outputDir}/reference-prep/\`
|
|
290
|
+
- no main shot contains \`ILK FRAME\`, \`İLK FRAME\`, \`SON FRAME\`, \`SHOTNN_START\`, \`SHOTNN_END\`, or exact first-frame reuse instructions
|
|
291
|
+
3. Role separation
|
|
292
|
+
- character sheets control identity, body, wardrobe, accessories, and visible props
|
|
293
|
+
- generated shot storyboards control composition, blocking, camera, timing, and action rhythm only
|
|
294
|
+
- storyboard text, borders, logos, watermarks, and alternate designs are never identity sources
|
|
295
|
+
4. Continuity and semantic consistency
|
|
296
|
+
- \`storyboard-reference-plan.json\` contains \`visual_world\`
|
|
297
|
+
- each \`Storyboard Plan\` phase aligns with camera, lens, lighting, scale, reflection, physics, and screen direction
|
|
298
|
+
- shot-to-shot handoff uses storyboard state, not end-frame reuse
|
|
299
|
+
- phases are capped at ${vars.maxStoryboardPhases}; 5+ distinct phases are split
|
|
300
|
+
5. Audio and coverage
|
|
301
|
+
- \`voiceCast\` exists when dialogue or narration exists
|
|
302
|
+
- every speaking video prompt has \`Audio Plan\`
|
|
303
|
+
- coverage stays in the same \`SHOTNN.md\` and does not request start/end still prompts
|
|
304
|
+
|
|
305
|
+
## Report Contract
|
|
306
|
+
|
|
307
|
+
Write \`${vars.outputDir}/reports/STORYBOARD-REFERENCE-QA.md\`:
|
|
308
|
+
|
|
309
|
+
\`\`\`markdown
|
|
310
|
+
# STORYBOARD REFERENCE QA
|
|
311
|
+
|
|
312
|
+
- overall_status: pass/fail
|
|
313
|
+
- safety_status: pass/fail
|
|
314
|
+
- visual_name_leak_status: pass/fail
|
|
315
|
+
- dialogue_name_policy_status: pass/fail
|
|
316
|
+
- storyboard_reference_status: pass/fail
|
|
317
|
+
- storyboard_handoff_status: pass/fail
|
|
318
|
+
- role_separation_status: pass/fail
|
|
319
|
+
- visual_world_status: pass/fail
|
|
320
|
+
- audio_plan_status: pass/fail
|
|
321
|
+
- coverage_status: pass/fail
|
|
322
|
+
- forbidden_start_end_status: pass/fail
|
|
323
|
+
- blockers:
|
|
324
|
+
- none
|
|
325
|
+
|
|
326
|
+
## Findings
|
|
327
|
+
- [concise list]
|
|
328
|
+
|
|
329
|
+
## Fixes Applied
|
|
330
|
+
- [concise list or none]
|
|
331
|
+
\`\`\`
|
|
332
|
+
|
|
333
|
+
Rules:
|
|
334
|
+
- If any field is fail, \`overall_status\` is fail.
|
|
335
|
+
- Do not mark pass while blockers remain.
|
|
336
|
+
`;
|
|
337
|
+
}
|
|
338
|
+
function buildStoryboardFinishWorkflow(vars) {
|
|
339
|
+
return `---
|
|
340
|
+
description: Finalize storyboard-reference prompt packages after storyboard QA passes.
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
# /finish - Storyboard Reference Completion
|
|
344
|
+
|
|
345
|
+
## Mode Gate
|
|
346
|
+
|
|
347
|
+
- Reference mode: \`storyboard-reference\`.
|
|
348
|
+
- Completion depends on \`${vars.outputDir}/reports/STORYBOARD-REFERENCE-QA.md\`, not start/end frame reports.
|
|
349
|
+
|
|
350
|
+
## Validate Files
|
|
351
|
+
|
|
352
|
+
1. \`${vars.outputDir}/storyboard-reference-plan.json\` exists.
|
|
353
|
+
2. \`${vars.outputDir}/reference-prep/\` contains character sheet prompt files.
|
|
354
|
+
3. \`${vars.outputDir}/storyboard-prompts/\` contains per-shot GPT Image 2 storyboard prompts.
|
|
355
|
+
4. \`${vars.outputDir}/prompt-bundles/\` contains model prompt bundles.
|
|
356
|
+
5. Every \`${vars.outputDir}/shots/SHOTNN.md\` contains the required storyboard-reference sections.
|
|
357
|
+
6. Coverage stays in the same \`SHOTNN.md\`.
|
|
358
|
+
7. No generated shot contains forbidden start/end frame sections or exact first-frame reuse instructions.
|
|
359
|
+
8. \`storyboard_reference_status\` and \`storyboard_handoff_status\` are pass.
|
|
360
|
+
|
|
361
|
+
## Final Summary
|
|
362
|
+
|
|
363
|
+
Write \`${vars.outputDir}/FINAL-SUMMARY.md\` with:
|
|
364
|
+
|
|
365
|
+
- total storyboard-reference shots
|
|
366
|
+
- character sheet prompts
|
|
367
|
+
- storyboard prompt files
|
|
368
|
+
- prompt bundles
|
|
369
|
+
- model targets
|
|
370
|
+
- QA status
|
|
371
|
+
- unresolved blockers
|
|
372
|
+
- final verdict
|
|
373
|
+
|
|
374
|
+
Do not declare completion unless \`STORYBOARD-REFERENCE-QA.md\` is pass.
|
|
375
|
+
`;
|
|
376
|
+
}
|
|
377
|
+
function buildStoryboardRecoverWorkflow(vars) {
|
|
378
|
+
return `---
|
|
379
|
+
description: Recover storyboard-reference outputs when QA or delivery gates fail.
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
# /recover - Storyboard Reference Recovery
|
|
383
|
+
|
|
384
|
+
## Trigger Conditions
|
|
385
|
+
|
|
386
|
+
- \`STORYBOARD-REFERENCE-QA.md\` is fail or missing
|
|
387
|
+
- character reference is missing
|
|
388
|
+
- \`storyboard-reference-plan.json\` is missing or contradictory
|
|
389
|
+
- any shot is missing required storyboard-reference sections
|
|
390
|
+
- any shot contains forbidden start/end frame sections or exact first-frame reuse instructions
|
|
391
|
+
- storyboard phases exceed ${vars.maxStoryboardPhases}
|
|
392
|
+
- role separation fails
|
|
393
|
+
- storyboard handoff continuity fails
|
|
394
|
+
|
|
395
|
+
## Steps
|
|
396
|
+
|
|
397
|
+
1. Identify failed files and fields.
|
|
398
|
+
2. Fix only affected character sheet prompts, storyboard prompts, prompt bundles, or shot files.
|
|
399
|
+
3. Preserve accepted character references and \`visual_world\`.
|
|
400
|
+
4. Split overloaded storyboard phases instead of compressing them.
|
|
401
|
+
5. Remove forbidden start/end frame sections from storyboard-reference shots.
|
|
402
|
+
6. Re-run \`/safety-check\`.
|
|
403
|
+
7. Update \`${vars.outputDir}/_index.md\` and \`${vars.outputDir}/FINAL-SUMMARY.md\` if they exist.
|
|
404
|
+
|
|
405
|
+
## Exit Criteria
|
|
406
|
+
|
|
407
|
+
- \`${vars.outputDir}/reports/STORYBOARD-REFERENCE-QA.md\` exists
|
|
408
|
+
- \`overall_status: pass\`
|
|
409
|
+
- \`storyboard_reference_status: pass\`
|
|
410
|
+
- \`storyboard_handoff_status: pass\`
|
|
411
|
+
- \`forbidden_start_end_status: pass\`
|
|
412
|
+
`;
|
|
413
|
+
}
|
|
414
|
+
function buildStoryboardFrameChainingSkill(vars) {
|
|
415
|
+
return `---
|
|
416
|
+
name: frame-chaining
|
|
417
|
+
description: Storyboard-reference continuity protocol. In this mode, continuity is handled by storyboard handoff notes rather than start/end frame assets.
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
# Storyboard Handoff Continuity
|
|
421
|
+
|
|
422
|
+
## Mode Gate
|
|
423
|
+
|
|
424
|
+
- Reference mode: \`storyboard-reference\`.
|
|
425
|
+
- Start/end frame generation: disabled.
|
|
426
|
+
- Do not create first-frame or last-frame still sections.
|
|
427
|
+
- Do not use exact end-frame-to-first-frame reuse text.
|
|
428
|
+
|
|
429
|
+
## Core Principle
|
|
430
|
+
|
|
431
|
+
Every shot's final \`Storyboard Plan\` phase must hand off clearly into the next shot's opening \`Storyboard Plan\` phase.
|
|
432
|
+
|
|
433
|
+
Continuity is enforced through:
|
|
434
|
+
|
|
435
|
+
- shared \`${vars.outputDir}/storyboard-reference-plan.json -> visual_world\`
|
|
436
|
+
- character sheet identity locks
|
|
437
|
+
- camera direction and screen direction
|
|
438
|
+
- lighting direction and color temperature
|
|
439
|
+
- action state at the end of one shot and start of the next
|
|
440
|
+
- foreground/midground/background scale and subject placement
|
|
441
|
+
|
|
442
|
+
## Handoff Fields
|
|
443
|
+
|
|
444
|
+
Each \`SHOTNN.md\` must include in \`Storyboard Plan\`:
|
|
445
|
+
|
|
446
|
+
- \`entry_handoff\`: previous shot state or first-shot opening state
|
|
447
|
+
- \`timeline_phases\`: 1-${vars.maxStoryboardPhases} purposeful phases
|
|
448
|
+
- \`exit_handoff\`: final action, camera, lighting, and staging state for the next shot
|
|
449
|
+
- \`continuity_mode\`: \`continuous-shot\` or \`multi-shot-storyboard\`
|
|
450
|
+
|
|
451
|
+
## Chain Break Equivalent
|
|
452
|
+
|
|
453
|
+
Use \`storyboard_handoff_reset\` only for:
|
|
454
|
+
|
|
455
|
+
- location change
|
|
456
|
+
- time jump
|
|
457
|
+
- dream, memory, or flashback
|
|
458
|
+
- deliberate camera-axis reset
|
|
459
|
+
- intentionally discontinuous montage
|
|
460
|
+
|
|
461
|
+
State the reason and the new \`visual_world\` deltas explicitly.
|
|
462
|
+
`;
|
|
463
|
+
}
|
|
464
|
+
function buildStoryboardCoverageSkill(_vars) {
|
|
465
|
+
return `---
|
|
466
|
+
name: coverage-system
|
|
467
|
+
description: Storyboard-reference coverage protocol. Coverage remains mandatory inside each SHOTNN.md without separate start/end still prompts.
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
# Coverage System - Storyboard Reference Mode
|
|
471
|
+
|
|
472
|
+
## Core Rule
|
|
473
|
+
|
|
474
|
+
Every main shot still needs 2-3 coverage beats in the same \`SHOTNN.md\`.
|
|
475
|
+
|
|
476
|
+
## Storyboard Mode Differences
|
|
477
|
+
|
|
478
|
+
- Coverage does not request separate first-frame or last-frame still prompts.
|
|
479
|
+
- Coverage is planned as editorial support inside the same storyboard-reference package.
|
|
480
|
+
- Coverage must preserve character sheet identity locks and shared \`visual_world\`.
|
|
481
|
+
- Coverage may include reaction, over-the-shoulder, insert, cutaway, extreme close-up, or wide cutaway beats.
|
|
482
|
+
|
|
483
|
+
## Required Coverage Fields
|
|
484
|
+
|
|
485
|
+
Each coverage item includes:
|
|
486
|
+
|
|
487
|
+
- coverage type
|
|
488
|
+
- Turkish summary when the surrounding runtime uses Turkish summaries
|
|
489
|
+
- storyboard planning prompt or concise shot plan
|
|
490
|
+
- model-ready video prompt
|
|
491
|
+
- audio plan when speech, SFX, ambience, or voiceover matters
|
|
492
|
+
- Avoid line
|
|
493
|
+
|
|
494
|
+
Do not split coverage into separate files.
|
|
495
|
+
`;
|
|
496
|
+
}
|
|
497
|
+
function buildStoryboardPromptStructureSkill(vars) {
|
|
498
|
+
return `---
|
|
499
|
+
name: prompt-structure
|
|
500
|
+
description: Storyboard-reference prompt structure for GPT Image 2 character sheets, per-shot storyboards, and model-ready video prompts.
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
# Prompt Structure - Storyboard Reference Mode
|
|
504
|
+
|
|
505
|
+
## Mode Gate
|
|
506
|
+
|
|
507
|
+
- Reference mode: \`storyboard-reference\`.
|
|
508
|
+
- Active workflow: \`generate-storyboard\`.
|
|
509
|
+
- Start/end frame generation: disabled.
|
|
510
|
+
- Main shot start/end frame sections are forbidden.
|
|
511
|
+
|
|
512
|
+
## Required Order
|
|
513
|
+
|
|
514
|
+
1. Confirm character reference assets.
|
|
515
|
+
2. Generate GPT Image 2 character sheet prompts.
|
|
516
|
+
3. Generate one GPT Image 2 storyboard prompt per shot.
|
|
517
|
+
4. Interpret the storyboard into a \`Storyboard Plan\`.
|
|
518
|
+
5. Generate model-ready video prompt bundles.
|
|
519
|
+
6. Add coverage inside the same \`SHOTNN.md\`.
|
|
520
|
+
7. Run storyboard-reference QA.
|
|
521
|
+
|
|
522
|
+
## Character Sheet Prompt
|
|
523
|
+
|
|
524
|
+
- 16:9 production storyboard sheet
|
|
525
|
+
- front full body, back full body, left profile, right profile, three-quarter full body, close-up face
|
|
526
|
+
- exact identity, wardrobe, accessories, and visible props
|
|
527
|
+
- no labels, text, logos, watermarks, alternate designs, or extra characters
|
|
528
|
+
|
|
529
|
+
## SHOTNN Storyboard Prompt
|
|
530
|
+
|
|
531
|
+
- 16:9 GPT Image 2 production storyboard
|
|
532
|
+
- professional rough storyboard style
|
|
533
|
+
- use character sheets as the only identity source
|
|
534
|
+
- use optional storyboard guides only for composition, blocking, camera, timing, and rhythm
|
|
535
|
+
- include entry and exit handoff notes
|
|
536
|
+
- cap timeline phases at ${vars.maxStoryboardPhases}; split 5+ distinct phases
|
|
537
|
+
|
|
538
|
+
## Model-Ready Video Prompt
|
|
539
|
+
|
|
540
|
+
- Declare input asset roles before action prose.
|
|
541
|
+
- Character sheet tokens lock identity, body, wardrobe, accessories, and props.
|
|
542
|
+
- Generated shot storyboard token controls composition, blocking, camera direction, timing, and action progression only.
|
|
543
|
+
- Use no-cuts wording only for a true uninterrupted camera move.
|
|
544
|
+
- For multi-phase storyboard shots, describe planned phase transitions directly.
|
|
545
|
+
- Include audio direction and Avoid line.
|
|
546
|
+
|
|
547
|
+
## Forbidden Output
|
|
548
|
+
|
|
549
|
+
Do not emit main-shot \`ILK FRAME\`, \`İLK FRAME\`, \`SON FRAME\`, \`SHOTNN_START\`, \`SHOTNN_END\`, or exact first-frame reuse instructions in storyboard-reference mode.
|
|
550
|
+
`;
|
|
551
|
+
}
|
|
75
552
|
function getModelDisplayName(model) {
|
|
76
553
|
if (model === "kling-3.0")
|
|
77
554
|
return "Kling 3.0";
|
|
@@ -139,27 +616,26 @@ export async function configureAgents(options = {}) {
|
|
|
139
616
|
if (copyContent !== undefined)
|
|
140
617
|
merged.copyContent = copyContent;
|
|
141
618
|
const resolved = resolveOptions(merged);
|
|
619
|
+
const storyboardReferenceActive = resolved.referenceMode === "storyboard-reference" && resolved.storyboardReferenceMode.enabled;
|
|
620
|
+
const templateVars = {
|
|
621
|
+
outputDir: resolved.outputDir,
|
|
622
|
+
scenarioHint: resolved.scenarioHint,
|
|
623
|
+
model: resolved.model,
|
|
624
|
+
klingPreset: getKlingPresetDisplay(resolved.model, resolved.klingPreset),
|
|
625
|
+
modelDisplayName: getModelDisplayName(resolved.model),
|
|
626
|
+
referenceMode: resolved.referenceMode,
|
|
627
|
+
storyboardReferenceActive,
|
|
628
|
+
maxStoryboardPhases: resolved.storyboardReferenceMode.maxStoryboardPhases
|
|
629
|
+
};
|
|
142
630
|
if (resolved.platforms.includes("claude")) {
|
|
143
631
|
await removeStaleClaudeArtifacts(resolved.rootDir);
|
|
144
632
|
}
|
|
145
633
|
// 1. Copy content files (.agent/ system) if enabled
|
|
146
634
|
const contentResult = resolved.copyContent
|
|
147
|
-
? await copyContentFiles(resolved.rootDir, resolved.overwrite,
|
|
148
|
-
outputDir: resolved.outputDir,
|
|
149
|
-
scenarioHint: resolved.scenarioHint,
|
|
150
|
-
model: resolved.model,
|
|
151
|
-
klingPreset: getKlingPresetDisplay(resolved.model, resolved.klingPreset),
|
|
152
|
-
modelDisplayName: getModelDisplayName(resolved.model)
|
|
153
|
-
})
|
|
635
|
+
? await copyContentFiles(resolved.rootDir, resolved.overwrite, templateVars)
|
|
154
636
|
: { written: [], skipped: [] };
|
|
155
637
|
const codexSkillMirrorResult = resolved.copyContent && resolved.platforms.includes("codex")
|
|
156
|
-
? await copyContentFiles(resolved.rootDir, resolved.overwrite,
|
|
157
|
-
outputDir: resolved.outputDir,
|
|
158
|
-
scenarioHint: resolved.scenarioHint,
|
|
159
|
-
model: resolved.model,
|
|
160
|
-
klingPreset: getKlingPresetDisplay(resolved.model, resolved.klingPreset),
|
|
161
|
-
modelDisplayName: getModelDisplayName(resolved.model)
|
|
162
|
-
}, ".agents", true)
|
|
638
|
+
? await copyContentFiles(resolved.rootDir, resolved.overwrite, templateVars, ".agents", true)
|
|
163
639
|
: { written: [], skipped: [] };
|
|
164
640
|
// 2. Generate platform-specific config files
|
|
165
641
|
const files = buildProjectFiles(resolved);
|
|
@@ -169,7 +645,8 @@ export async function configureAgents(options = {}) {
|
|
|
169
645
|
const absolutePath = join(resolved.rootDir, relativePath);
|
|
170
646
|
const fileExists = await exists(absolutePath);
|
|
171
647
|
const isRuntimeModelFile = relativePath === ".agent/model-profile.md";
|
|
172
|
-
|
|
648
|
+
const isStoryboardModeSensitiveProjectFile = storyboardReferenceActive && STORYBOARD_MODE_SENSITIVE_PROJECT_FILES.has(relativePath);
|
|
649
|
+
if (fileExists && !isRuntimeModelFile && !isStoryboardModeSensitiveProjectFile && !resolved.overwrite) {
|
|
173
650
|
skipped.push(relativePath);
|
|
174
651
|
continue;
|
|
175
652
|
}
|
package/build/lib/defaults.js
CHANGED
|
@@ -17,7 +17,9 @@ export function normalizeStoryboardReferenceConfig(input, referenceMode) {
|
|
|
17
17
|
throw new Error("Invalid storyboardReferenceMode.maxStoryboardPhases. Expected a positive integer.");
|
|
18
18
|
}
|
|
19
19
|
return {
|
|
20
|
-
enabled:
|
|
20
|
+
enabled: referenceMode === "storyboard-reference"
|
|
21
|
+
? true
|
|
22
|
+
: input?.enabled ?? DEFAULT_STORYBOARD_REFERENCE_CONFIG.enabled,
|
|
21
23
|
maxStoryboardPhases,
|
|
22
24
|
defaultCharacterRefRole: "character_identity",
|
|
23
25
|
defaultStoryboardRefRole: "storyboard_plan",
|
|
@@ -54,6 +54,12 @@ export class Seedance20PromptAdapter extends BaseVideoModelPromptAdapter {
|
|
|
54
54
|
const promptText = `${this.formatCharacterRoleLine(input)}
|
|
55
55
|
${this.formatStoryboardRoleLine(input)}
|
|
56
56
|
|
|
57
|
+
[REFERENCE ROLES]
|
|
58
|
+
- Identity reference: ${characterTokenText} locks face, hair, body proportions, wardrobe, accessories, visible props, and material continuity.
|
|
59
|
+
- Camera reference: ${storyboardToken} controls composition, camera direction, framing, screen direction, shot order, and lens rhythm only.
|
|
60
|
+
- Action reference: ${storyboardToken} controls blocking, pose logic, timing, action rhythm, phase order, and emotional progression only.
|
|
61
|
+
- Audio reference: use the Audio Plan text below for dialogue, SFX, ambience, and music intent; do not infer audio from storyboard annotations unless explicitly requested.
|
|
62
|
+
|
|
57
63
|
${continuityInstruction}
|
|
58
64
|
|
|
59
65
|
[CORE INTENT]
|
|
@@ -119,10 +125,14 @@ Avoid: identity drift, face drift, outfit drift, storyboard text, panel borders,
|
|
|
119
125
|
? hasNoCutsRule
|
|
120
126
|
: /left-to-right, top-to-bottom/i.test(output.promptText)
|
|
121
127
|
&& /Do not reinterpret actions, poses, camera angles, emotional progression/i.test(output.promptText),
|
|
128
|
+
separatesReferenceRoles: /Identity reference:/i.test(output.promptText)
|
|
129
|
+
&& /Camera reference:/i.test(output.promptText)
|
|
130
|
+
&& /Action reference:/i.test(output.promptText)
|
|
131
|
+
&& /Audio reference:/i.test(output.promptText),
|
|
122
132
|
blocksStoryboardIdentitySources: /Storyboard text, panel borders, arrows, colored marks, lens notes, watermark, logo, and alternate character design are never identity sources/i.test(output.promptText),
|
|
123
133
|
continuityMode: continuityMode === "continuous-shot"
|
|
124
134
|
? hasNoCutsRule
|
|
125
|
-
: !hasNoCutsRule && /
|
|
135
|
+
: !hasNoCutsRule && /storyboard-motivated cuts/i.test(output.promptText),
|
|
126
136
|
musicNone: /Music: NONE/i.test(output.promptText)
|
|
127
137
|
};
|
|
128
138
|
const issues = [
|