@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 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
@@ -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
- if (targetExists && !overwrite) {
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 = renderContentTemplate(rawContent, templateVars);
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
- if (fileExists && !isRuntimeModelFile && !resolved.overwrite) {
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
  }
@@ -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: input?.enabled ?? referenceMode === "storyboard-reference",
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 && /planned storyboard phase transitions/i.test(output.promptText),
135
+ : !hasNoCutsRule && /storyboard-motivated cuts/i.test(output.promptText),
126
136
  musicNone: /Music: NONE/i.test(output.promptText)
127
137
  };
128
138
  const issues = [