@milenyumai/film-kit 2.2.0 → 2.3.0

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.
Files changed (55) hide show
  1. package/README.md +68 -17
  2. package/build/index.d.ts +1 -1
  3. package/build/lib/cli.js +2 -2
  4. package/build/lib/film-kit.js +6 -4
  5. package/build/lib/storyboard-reference/adapters/kling30.js +3 -1
  6. package/build/lib/storyboard-reference/adapters/seedance20.d.ts +4 -0
  7. package/build/lib/storyboard-reference/adapters/seedance20.js +72 -13
  8. package/build/lib/storyboard-reference/adapters/veo31.js +3 -1
  9. package/build/lib/storyboard-reference/index.d.ts +1 -1
  10. package/build/lib/storyboard-reference/output-writer.js +84 -6
  11. package/build/lib/storyboard-reference/prompt-bundle-builder.js +295 -8
  12. package/build/lib/storyboard-reference/request-normalizer.js +8 -4
  13. package/build/lib/storyboard-reference/storyboard-interpreter.d.ts +3 -1
  14. package/build/lib/storyboard-reference/storyboard-interpreter.js +21 -1
  15. package/build/lib/storyboard-reference/types.d.ts +151 -2
  16. package/build/lib/storyboard-reference/validators.js +2 -5
  17. package/build/lib/templates.js +10 -6
  18. package/content/ARCHITECTURE.md +4 -4
  19. package/content/MASTER.md +2 -2
  20. package/content/RULES.md +4 -4
  21. package/content/agents/prompt-engineer.md +7 -7
  22. package/content/skills/prompt-structure/SKILL.md +14 -11
  23. package/content/skills/reference-locking/SKILL.md +6 -4
  24. package/content/skills/semantic-consistency/SKILL.md +1 -1
  25. package/content/skills/storyboard-reference/SKILL.md +54 -13
  26. package/content/workflows/generate-storyboard.md +37 -16
  27. package/content/workflows/generate.md +7 -7
  28. package/content/workflows/safety-check.md +2 -2
  29. package/package.json +1 -1
  30. package/packages/gpt-image-smart/content/skills/storyboard-reference/SKILL.md +104 -12
  31. package/packages/gpt-image-smart/content/workflows/generate-storyboard.md +89 -12
  32. package/packages/hybrid/content/skills/storyboard-reference/SKILL.md +104 -12
  33. package/packages/hybrid/content/workflows/generate-storyboard.md +89 -12
  34. package/packages/hybrid-smart/content/skills/storyboard-reference/SKILL.md +104 -12
  35. package/packages/hybrid-smart/content/workflows/generate-storyboard.md +89 -12
  36. package/packages/multi/build/cli.js +39 -0
  37. package/packages/multi/build/index.d.ts +1 -1
  38. package/packages/multi/build/lib/configure.js +208 -1
  39. package/packages/multi/build/lib/defaults.d.ts +3 -1
  40. package/packages/multi/build/lib/defaults.js +32 -0
  41. package/packages/multi/build/lib/templates.js +146 -60
  42. package/packages/multi/build/lib/types.d.ts +16 -0
  43. package/packages/multi/content/agents/continuity-editor.md +6 -6
  44. package/packages/multi/content/agents/delivery-editor.md +2 -2
  45. package/packages/multi/content/agents/lead-director.md +18 -10
  46. package/packages/multi/content/agents/semantic-auditor.md +4 -5
  47. package/packages/multi/content/agents/shot-generator.md +9 -27
  48. package/packages/multi/content/skills/storyboard-reference/SKILL.md +104 -12
  49. package/packages/multi/content/workflows/chain-multi.md +4 -4
  50. package/packages/multi/content/workflows/generate-multi.md +6 -6
  51. package/packages/multi/content/workflows/generate-storyboard.md +89 -12
  52. package/packages/multi/content/workflows/generate-teammate.md +8 -14
  53. package/packages/multi/content/workflows/safety-check-multi.md +7 -11
  54. package/packages/studio/content/skills/storyboard-reference/SKILL.md +104 -12
  55. package/packages/studio/content/workflows/generate-storyboard.md +89 -12
@@ -1,19 +1,96 @@
1
1
  ---
2
- description: Generate storyboard-reference prompt bundles from character reference, storyboard reference, and video brief
2
+ description: Generate character sheet prompts, per-shot GPT Image 2 storyboard prompts, and model-aware video prompt bundles from character references and a video brief
3
3
  ---
4
4
 
5
- # /generate-storyboard
5
+ # /generate-storyboard - Storyboard Reference Video Prompt Mode
6
6
 
7
- Read `.agent/model-profile.md`, `safety-compliance`, `reference-locking`, `storyboard-reference`, `semantic-consistency`, `visual-modes`, `audio-design` when needed, and `prompt-structure`.
7
+ ## Preconditions
8
8
 
9
- Flow:
9
+ - Character reference image exists.
10
+ - User brief or scenario text exists.
11
+ - Optional storyboard guide images may exist, but they are not required.
12
+ - `storyboard-reference` mode is explicitly requested or configured.
10
13
 
11
- 1. Bind `@character1` as `character_identity`, exact lock.
12
- 2. Bind `@storyboard1` as `storyboard_plan`, staging only.
13
- 3. Interpret storyboard panels: 1 continuous arc, 2-4 internal phases, 5+ split shots.
14
- 4. Build `visual_world`, continuity anchors, and model-specific prompts.
15
- 5. Generate Seedance, Veo, and Kling prompt sections for the requested model subset.
16
- 6. Run QA for reference lock, storyboard role separation, model grammar, avoid line, audio plan, and safety.
17
- 7. Write all outputs under `$OUTPUT_DIR`.
14
+ ## Read Order
18
15
 
19
- Fail closed on missing refs, empty brief, public figure likeness, trademark/logo risk, unsafe visual requests, missing avoid line, or invalid Kling block structure.
16
+ 1. `.agent/model-profile.md`
17
+ 2. `.agent/skills/safety-compliance/SKILL.md`
18
+ 3. `.agent/skills/reference-locking/SKILL.md`
19
+ 4. `.agent/skills/storyboard-reference/SKILL.md`
20
+ 5. `.agent/skills/semantic-consistency/SKILL.md`
21
+ 6. `.agent/skills/visual-modes/SKILL.md`
22
+ 7. `.agent/skills/audio-design/SKILL.md` when dialogue, SFX, ambience, or voiceover exists
23
+ 8. `.agent/skills/prompt-structure/SKILL.md`
24
+
25
+ ## Flow
26
+
27
+ 1. Confirm asset roles:
28
+ - `@character1`, `@character2`, ...: `character_identity`, exact lock
29
+ - optional `@storyboard1`, `@storyboard2`, ...: external storyboard guides, staging only
30
+ 2. Generate one GPT Image 2 character sheet prompt per character reference:
31
+ - 16:9 production storyboard sheet
32
+ - front full body, back full body, left profile, right profile, three-quarter full body, close-up face
33
+ - exact identity, wardrobe, accessories, and visible props
34
+ - no labels, text, logos, watermarks, alternate designs, or extra characters
35
+ 3. Confirm target models: `veo31`, `seedance-2.0`, `kling-3.0`, or a user-provided subset.
36
+ 4. Select shot storyboard panel budget:
37
+ - 4-6 seconds: 1-2 panels/phases
38
+ - 7-10 seconds: 2-3 panels/phases
39
+ - 11-15 seconds: 3-4 panels/phases
40
+ - 5+ distinct phases: split into multiple `SHOTNN.md` files
41
+ 5. Build `visual_world`:
42
+ - environment
43
+ - lighting
44
+ - foreground/midground/background
45
+ - screen direction
46
+ - continuity anchors
47
+ 6. Generate one GPT Image 2 storyboard prompt per shot:
48
+ - use character sheets as the only identity source
49
+ - use optional storyboard guide only for composition, blocking, camera, timing, and rhythm
50
+ - include previous shot handoff and next shot handoff
51
+ - preserve shared location, lighting, screen direction, action rhythm, and scene continuity
52
+ 7. Build model prompt bundle:
53
+ - Seedance dynamic image mapping: character sheets first, generated shot storyboard next
54
+ - Veo visual-planning prompt with full audio direction
55
+ - Kling block-structured storyboard route
56
+ 8. Run QA gates:
57
+ - reference lock
58
+ - storyboard role separation
59
+ - model grammar
60
+ - avoid/negative prompt
61
+ - audio plan
62
+ - safety
63
+ 9. Write outputs under `$OUTPUT_DIR`.
64
+
65
+ ## CLI Equivalent
66
+
67
+ ```bash
68
+ npx @milenyumai/film-kit generate-storyboard \
69
+ --character-ref ./refs/character.png \
70
+ --brief ./scenario.md \
71
+ --models veo31,seedance-2.0,kling-3.0 \
72
+ --duration 8 \
73
+ --aspect 16:9 \
74
+ --output-dir ./outputs
75
+ ```
76
+
77
+ Optional external storyboard guide:
78
+
79
+ ```bash
80
+ npx @milenyumai/film-kit generate-storyboard \
81
+ --character-ref ./refs/character.png \
82
+ --storyboard-ref ./refs/storyboard-guide.png \
83
+ --brief ./scenario.md \
84
+ --models seedance-2.0
85
+ ```
86
+
87
+ ## Fail-Closed Rules
88
+
89
+ - Missing character reference: stop and request a valid reference.
90
+ - Empty brief: stop and request a brief.
91
+ - Public figure / real-person likeness / trademark risk: stop or safely anonymize before prompt generation.
92
+ - 5+ storyboard phases: do not compress into one prompt; split shots.
93
+ - Missing GPT Image 2 character sheet prompt: output is invalid.
94
+ - Missing GPT Image 2 per-shot storyboard prompt: output is invalid.
95
+ - Missing `Avoid` / negative prompt: output is invalid.
96
+ - Kling prompt missing required block structure: output is invalid.
@@ -5,6 +5,7 @@ const command = args[0];
5
5
  const overwrite = args.includes("--overwrite") || args.includes("-f");
6
6
  const SUPPORTED_MODELS = ["veo31", "kling-3.0", "seedance-2.0"];
7
7
  const SUPPORTED_KLING_PRESETS = ["ultra-realism", "balanced", "custom"];
8
+ const SUPPORTED_REFERENCE_MODES = ["start-end", "storyboard-reference", "hybrid"];
8
9
  function parseFlagValue(flag) {
9
10
  const exactIndex = args.indexOf(flag);
10
11
  if (exactIndex >= 0 && args[exactIndex + 1]) {
@@ -34,11 +35,32 @@ function parseKlingPreset() {
34
35
  }
35
36
  throw new Error(`Invalid --kling-preset value: ${presetRaw}. Supported: ${SUPPORTED_KLING_PRESETS.join(", ")}`);
36
37
  }
38
+ function parseReferenceMode() {
39
+ const modeRaw = parseFlagValue("--reference-mode");
40
+ if (!modeRaw)
41
+ return undefined;
42
+ if (SUPPORTED_REFERENCE_MODES.includes(modeRaw)) {
43
+ return modeRaw;
44
+ }
45
+ throw new Error(`Invalid --reference-mode value: ${modeRaw}. Supported: ${SUPPORTED_REFERENCE_MODES.join(", ")}`);
46
+ }
47
+ function parsePositiveIntegerFlag(flag) {
48
+ const raw = parseFlagValue(flag);
49
+ if (!raw)
50
+ return undefined;
51
+ const value = Number(raw);
52
+ if (!Number.isInteger(value) || value < 1) {
53
+ throw new Error(`Invalid ${flag} value: ${raw}. Expected a positive integer.`);
54
+ }
55
+ return value;
56
+ }
37
57
  if (command === "init") {
38
58
  console.log("🎬 Film-Kit Multi: Configuring multi-agent team...\n");
39
59
  try {
40
60
  const model = parseModel();
41
61
  const klingPreset = parseKlingPreset();
62
+ const referenceMode = parseReferenceMode();
63
+ const maxStoryboardPhases = parsePositiveIntegerFlag("--max-storyboard-phases");
42
64
  const configureOptions = {
43
65
  rootDir: process.cwd(),
44
66
  overwrite
@@ -47,6 +69,21 @@ if (command === "init") {
47
69
  configureOptions.model = model;
48
70
  if (klingPreset)
49
71
  configureOptions.klingPreset = klingPreset;
72
+ if (referenceMode) {
73
+ configureOptions.referenceMode = referenceMode;
74
+ if (referenceMode === "storyboard-reference") {
75
+ configureOptions.storyboardReferenceMode = {
76
+ ...configureOptions.storyboardReferenceMode,
77
+ enabled: true
78
+ };
79
+ }
80
+ }
81
+ if (maxStoryboardPhases !== undefined) {
82
+ configureOptions.storyboardReferenceMode = {
83
+ ...configureOptions.storyboardReferenceMode,
84
+ maxStoryboardPhases
85
+ };
86
+ }
50
87
  const result = await configureMultiAgents(configureOptions);
51
88
  if (result.written.length > 0) {
52
89
  console.log(`✅ Files written: ${result.written.length}`);
@@ -77,7 +114,9 @@ This internal CLI exists only for repository development.
77
114
  Public usage:
78
115
  npx @milenyumai/film-kit init --preset multi
79
116
  npx @milenyumai/film-kit init --preset multi --model veo31|kling-3.0|seedance-2.0
117
+ npx @milenyumai/film-kit init --preset multi --model seedance-2.0 --reference-mode storyboard-reference
80
118
  npx @milenyumai/film-kit init --preset multi --model kling-3.0 --kling-preset ultra-realism|balanced|custom
119
+ npx @milenyumai/film-kit init --preset multi --max-storyboard-phases 4
81
120
  npx @milenyumai/film-kit init --preset multi --overwrite
82
121
  `);
83
122
  }
@@ -1,2 +1,2 @@
1
- export type { KlingPreset, MultiAgentConfigOptions, MultiConfigureResult, SupportedModel } from "./lib/types.js";
1
+ export type { KlingPreset, MultiAgentConfigOptions, MultiConfigureResult, ReferenceMode, StoryboardReferenceConfig, SupportedModel } from "./lib/types.js";
2
2
  export { configureMultiAgents } from "./lib/configure.js";
@@ -112,6 +112,18 @@ async function copyMultiContent(rootDir, overwrite, templateVars) {
112
112
  }
113
113
  function renderContentTemplate(content, vars) {
114
114
  return content
115
+ .replaceAll("$REFERENCE_MODE_CONTRACT", vars.referenceModeContract)
116
+ .replaceAll("$SHOT_FILE_OUTPUT_CONTRACT", vars.shotFileOutputContract)
117
+ .replaceAll("$CONTINUITY_CONTRACT", vars.continuityContract)
118
+ .replaceAll("$SEEDANCE_STORYBOARD_CONTRACT", vars.seedanceStoryboardContract)
119
+ .replaceAll("$SHOT_SELF_CHECK_CONTRACT", vars.selfCheckContract)
120
+ .replaceAll("$SEMANTIC_AUDIT_CONTRACT", vars.semanticAuditContract)
121
+ .replaceAll("$SEMANTIC_REFERENCE_MODE_STATUS_FIELD", vars.semanticReferenceModeStatusField)
122
+ .replaceAll("$SEMANTIC_CONTINUITY_STATUS_FIELD", vars.semanticContinuityStatusField)
123
+ .replaceAll("$STORYBOARD_REFERENCE_POLICY_JSON", vars.storyboardReferencePolicyJson)
124
+ .replaceAll("$CHAINED_ILK_FRAME_EXACT_REUSE_REQUIRED", String(vars.chainedIlkFrameExactReuseRequired))
125
+ .replaceAll("$MAX_STORYBOARD_PHASES", String(vars.maxStoryboardPhases))
126
+ .replaceAll("$REFERENCE_MODE", vars.referenceMode)
115
127
  .replaceAll("$OUTPUT_DIR", vars.outputDir)
116
128
  .replaceAll("$SCENARIO_HINT", vars.scenarioHint)
117
129
  .replaceAll("$MODEL_DISPLAY", vars.modelDisplayName)
@@ -129,6 +141,178 @@ function getModelDisplayName(model) {
129
141
  function getKlingPresetDisplay(model, klingPreset) {
130
142
  return model === "kling-3.0" ? klingPreset : "n/a (Kling-only)";
131
143
  }
144
+ function isSeedanceStoryboardReference(config) {
145
+ return config.model === "seedance-2.0"
146
+ && config.referenceMode === "storyboard-reference"
147
+ && config.storyboardReferenceMode.enabled;
148
+ }
149
+ function buildStoryboardReferencePolicyJson(config) {
150
+ if (!isSeedanceStoryboardReference(config)) {
151
+ return JSON.stringify({
152
+ enabled: false,
153
+ continuity_source: "start_end_frame_chain"
154
+ }, null, 6);
155
+ }
156
+ return JSON.stringify({
157
+ enabled: true,
158
+ max_storyboard_phases: config.storyboardReferenceMode.maxStoryboardPhases,
159
+ recommended_phase_budget: {
160
+ "4-6s": "1-2 storyboard phases",
161
+ "7-10s": "2-3 storyboard phases",
162
+ "11-15s": "3-4 storyboard phases",
163
+ split_at_phase_count: 5,
164
+ split_target: "separate SHOTNN.md files"
165
+ },
166
+ provider_reference_tokens: {
167
+ character_identities: "@Image1..@ImageN generated character sheets",
168
+ storyboard_reference: "next @Image token after character sheets (one character -> @Image2, two characters -> @Image3)",
169
+ legacy_aliases: {
170
+ character_identities: "@image1..@imageN",
171
+ storyboard_reference: "matching lowercase next @image token"
172
+ },
173
+ video_reference: "@video1",
174
+ audio_reference: "@audio1"
175
+ },
176
+ continuity_mode: {
177
+ continuous_shot: "use no-cuts wording only for a single uninterrupted camera move",
178
+ multi_shot_storyboard: "use only planned STORYBOARD PLAN phase transitions; do not add unplanned cuts"
179
+ },
180
+ provider_file_limits: {
181
+ images: 9,
182
+ videos: 3,
183
+ audio: 3,
184
+ total_files: 12,
185
+ duration_seconds: "4-15"
186
+ },
187
+ character_reference_sheets: {
188
+ enabled: true,
189
+ provider: "gpt-image-2",
190
+ generated_once_per_character: true,
191
+ aspect_ratio: "16:9",
192
+ required_views: [
193
+ "front full body",
194
+ "back full body",
195
+ "left profile",
196
+ "right profile",
197
+ "three-quarter full body",
198
+ "close-up face"
199
+ ]
200
+ },
201
+ storyboard_prompt_policy: {
202
+ enabled: true,
203
+ provider: "gpt-image-2",
204
+ generated_per_shot: true,
205
+ aspect_ratio: "16:9",
206
+ panel_budget: "4-6s: 1-2, 7-10s: 2-3, 11-15s: 3-4",
207
+ max_panels_per_shot: config.storyboardReferenceMode.maxStoryboardPhases,
208
+ target_words: "160-240 words per shot storyboard prompt"
209
+ },
210
+ material_roles: {
211
+ "character_sheet_tokens": "identity, face, body proportions, wardrobe, accessories, and visible props",
212
+ "generated_shot_storyboard_token": "composition, blocking, camera direction, timing, and action progression only"
213
+ },
214
+ storyboard_never_identity_source: [
215
+ "storyboard text",
216
+ "panel borders",
217
+ "watermarks",
218
+ "logos",
219
+ "alternate character designs"
220
+ ],
221
+ continuity_source: "shared visual_world plus shot-to-shot storyboard handoff notes",
222
+ require_ilk_son_frames: false,
223
+ shot_handoff_notes_required: true
224
+ }, null, 6);
225
+ }
226
+ function buildReferenceModeContract(config) {
227
+ if (!isSeedanceStoryboardReference(config)) {
228
+ return `Reference mode: \`${config.referenceMode}\` (start/end frame chaining active).
229
+ - Main shots are chained by exact end-frame to first-frame reuse.
230
+ - \`${config.outputDir}/team-plan.json -> visual_world\` still governs perspective, lighting, scale, and identity locks.`;
231
+ }
232
+ return `Reference mode: \`storyboard-reference\` (Seedance 2.0 storyboard-supported runtime).
233
+ - Do not require \`ILK FRAME\` / \`SON FRAME\` sections for main shots in this mode.
234
+ - Generate one 16:9 GPT Image 2 character reference sheet prompt per character once, before shot storyboard work.
235
+ - Each \`SHOTNN.md\` must include a \`GPT IMAGE 2 STORYBOARD PROMPT\` and its own \`STORYBOARD PLAN\` with timeline phases derived from one shared \`${config.outputDir}/team-plan.json -> visual_world\`.
236
+ - \`${config.outputDir}/team-plan.json\` must set \`project.reference_mode: "storyboard-reference"\`, \`storyboard_reference.enabled: true\`, \`storyboard_reference.character_reference_sheets\`, \`storyboard_reference.storyboard_prompt_policy\`, \`storyboard_reference.max_storyboard_phases: ${config.storyboardReferenceMode.maxStoryboardPhases}\`, \`storyboard_reference.recommended_phase_budget\`, \`storyboard_reference.provider_reference_tokens\`, \`storyboard_reference.continuity_mode\`, \`storyboard_reference.provider_file_limits\`, and shot-level handoff notes.
237
+ - Duration policy: 4-6s = 1-2 phases, 7-10s = 2-3 phases, 11-15s = 3-4 phases; 5+ distinct phases split into separate \`SHOTNN.md\` files.
238
+ - Continuity is enforced by shared \`visual_world\`, shot-to-shot storyboard handoff notes, character/reference lock, camera direction, lighting, and action progression.`;
239
+ }
240
+ function buildShotFileOutputContract(config) {
241
+ if (!isSeedanceStoryboardReference(config)) {
242
+ return `1. main shot blocks: \`ILK FRAME\` (or \`İLK FRAME\`), \`SON FRAME\`, \`AUDIO PLAN\`, \`VIDEO\` (or \`VİDEO\`)
243
+ 2. \`ILK/İLK FRAME\` section must always include a fenced code block
244
+ 3. if chained, first-frame code block must contain only: \`Use SHOT[prev]_END as exact first frame\`; any new start-frame prompt requires \`CHAIN BREAK\`
245
+ 4. 2-3 coverage sub-shots in the same file
246
+ 5. image prompt contract (hard requirement):
247
+ - if references exist, \`ILK FRAME\` and \`SON FRAME\` must use \`REFERENCE LOCK\`, \`Keep same\`, and \`Change only\`
248
+ - face/hair/skin/body/wardrobe/accessories/prop design visible in reference are immutable
249
+ - \`SON FRAME\` must preserve the same visual universe and declare only one major semantic delta
250
+ - \`VIDEO\`: minimum 120 words
251
+ - each coverage video prompt: minimum 70 words`;
252
+ }
253
+ return `1. main shot blocks: \`MODEL CONTROL\`, \`INPUT ASSET ROLES\`, \`REFERENCE ASSET REQUIREMENTS\`, \`GPT IMAGE 2 STORYBOARD PROMPT\`, \`STORYBOARD PLAN\`, \`AUDIO PLAN\`, \`SEEDANCE VIDEO PROMPT\`, and coverage
254
+ 2. \`INPUT ASSET ROLES\` must declare generated character sheet tokens (\`@Image1...\`, legacy \`@image1...\`) as identity/wardrobe/props only
255
+ 3. \`INPUT ASSET ROLES\` must declare the generated shot storyboard token (next \`@Image\` after character sheets, legacy lowercase alias such as \`@image2\` for one character) as composition/blocking/camera/timing only
256
+ 4. \`GPT IMAGE 2 STORYBOARD PROMPT\` must be 16:9, professional production storyboard style, 160-240 words, and use character sheets as the only identity source
257
+ 5. \`STORYBOARD PLAN\` must include timeline phases for this shot, capped at ${config.storyboardReferenceMode.maxStoryboardPhases} phases
258
+ 6. every phase must derive from the shared \`team-plan.json -> visual_world\` and include its handoff from the previous shot and handoff to the next shot
259
+ 7. 2-3 coverage sub-shots stay in the same file
260
+ 8. \`SEEDANCE VIDEO PROMPT\`: minimum 120 words; each coverage video prompt: minimum 70 words`;
261
+ }
262
+ function buildContinuityContract(config) {
263
+ if (!isSeedanceStoryboardReference(config)) {
264
+ return `- First shot \`ILK FRAME\` / \`İLK FRAME\` must match assigned chain entry.
265
+ - Chained \`ILK FRAME\` / \`İLK FRAME\` code blocks cannot contain a new camera, lens, lighting, action, or composition prompt.
266
+ - Within your batch: \`SHOT[N]_END\` must match \`SHOT[N+1]_START\`.
267
+ - Coverage shots are standalone and not chained.`;
268
+ }
269
+ return `- Main-shot continuity uses storyboard handoff text, not start/end frame reuse.
270
+ - First shot \`STORYBOARD PLAN\` must match the assigned continuity entry and shared \`${config.outputDir}/team-plan.json -> visual_world\`.
271
+ - Within your batch, each shot's final timeline phase must hand off clearly into the next shot's opening phase.
272
+ - Coverage shots are standalone and not chained.`;
273
+ }
274
+ function buildSeedanceStoryboardContract(config) {
275
+ if (!isSeedanceStoryboardReference(config)) {
276
+ return `- explicit material roles when references exist (\`@Image1\`/\`@image1\`, \`@video1\`, \`@audio1\`)
277
+ - use \`Use @Image1 as the first frame of the scene.\` when first-frame identity lock matters
278
+ - if \`@video1\` is action reference and \`@video2\` is camera reference, say so directly
279
+ - use \`No scene cuts throughout, one continuous shot.\` only for a true uninterrupted camera move
280
+ - use timeline segments only for meaningful internal beats, not decorative micro-actions
281
+ - when continuing a clip, use \`Extend @video1 by [N]s\` rather than rewriting it as a new cut
282
+ - when \`@Image1\`/\`@image1\` locks identity, keep face/body/wardrobe/prop design exact and change only one meaningful beat`;
283
+ }
284
+ return `- generate one 16:9 GPT Image 2 character sheet prompt per character once, then use those sheet images as Seedance identity references
285
+ - declare character sheet tokens (\`@Image1...\`, legacy \`@image1...\`) as identity, face, body proportions, wardrobe, accessories, and visible props
286
+ - declare the generated shot storyboard token (next \`@Image\` after character sheets, legacy lowercase alias such as \`@image2\` for one character) as composition, blocking, camera direction, timing, and action progression only
287
+ - never let storyboard text, panel borders, watermark, logo, alternate character design, or storyboard character design override the identity reference
288
+ - write one \`GPT IMAGE 2 STORYBOARD PROMPT\` per shot before the Seedance prompt; it must be 16:9, professional, 160-240 words, and continuity-aware
289
+ - write per-shot timeline phases under \`STORYBOARD PLAN\`, capped at ${config.storyboardReferenceMode.maxStoryboardPhases} phases
290
+ - follow duration budget: 4-6s = 1-2 phases, 7-10s = 2-3 phases, 11-15s = 3-4 phases; split 5+ phases into separate \`SHOTNN.md\` files
291
+ - use \`No scene cuts throughout, one continuous shot.\` only when that shot's storyboard plan is a single uninterrupted camera move
292
+ - for multi-phase storyboard shots, describe the planned phase changes directly instead of forcing continuous-shot wording
293
+ - when continuing a source clip, use \`Extend @video1 by [N]s\` and still preserve storyboard handoff continuity`;
294
+ }
295
+ function buildSelfCheckContract(config) {
296
+ if (!isSeedanceStoryboardReference(config)) {
297
+ return `- each \`ILK/İLK FRAME\` section contains a code block
298
+ - chained \`ILK/İLK FRAME\` code blocks contain only exact reuse text
299
+ - word-count floors pass for all prompts
300
+ - image prompt contract passes for main stills`;
301
+ }
302
+ return `- each file contains \`INPUT ASSET ROLES\`, \`REFERENCE ASSET REQUIREMENTS\`, \`GPT IMAGE 2 STORYBOARD PROMPT\`, \`STORYBOARD PLAN\`, \`AUDIO PLAN\`, \`SEEDANCE VIDEO PROMPT\`, and coverage
303
+ - no main shot requires \`ILK FRAME\` or \`SON FRAME\` sections
304
+ - storyboard phases are capped at ${config.storyboardReferenceMode.maxStoryboardPhases} and are not decorative micro-beats
305
+ - role separation passes: identity comes from generated character sheet tokens, staging comes from the generated shot storyboard token`;
306
+ }
307
+ function buildSemanticAuditContract(config) {
308
+ if (!isSeedanceStoryboardReference(config)) {
309
+ return `- Start/end pairs keep the declared invariants and change only one major semantic beat unless \`CHAIN BREAK\` is declared.
310
+ - Chained \`ILK/İLK FRAME\` code blocks contain only \`Use SHOT[prev]_END as exact first frame\`; any competing visual prompt is a fail and must become \`CHAIN BREAK\`.`;
311
+ }
312
+ return `- Storyboard-reference shots derive every timeline phase from the shared \`team-plan.json -> visual_world\`.
313
+ - Shot-to-shot continuity is expressed through storyboard handoff notes, consistent camera direction, lighting, character lock, and action progression.
314
+ - Main shots do not require start/end frame pairs or chained first-frame reuse text in storyboard-reference mode.`;
315
+ }
132
316
  async function removePathIfExists(rootDir, relativePath) {
133
317
  const absolutePath = join(rootDir, relativePath);
134
318
  if (await exists(absolutePath)) {
@@ -158,6 +342,8 @@ export async function configureMultiAgents(options = {}) {
158
342
  const batchSize = options.batchSize ?? fromFile?.batchSize;
159
343
  const model = options.model ?? fromFile?.model;
160
344
  const klingPreset = options.klingPreset ?? fromFile?.klingPreset;
345
+ const referenceMode = options.referenceMode ?? fromFile?.referenceMode;
346
+ const storyboardReferenceMode = options.storyboardReferenceMode ?? fromFile?.storyboardReferenceMode;
161
347
  if (outputDir !== undefined)
162
348
  merged.outputDir = outputDir;
163
349
  if (scenarioHint !== undefined)
@@ -176,13 +362,34 @@ export async function configureMultiAgents(options = {}) {
176
362
  merged.model = model;
177
363
  if (klingPreset !== undefined)
178
364
  merged.klingPreset = klingPreset;
365
+ if (referenceMode !== undefined)
366
+ merged.referenceMode = referenceMode;
367
+ if (storyboardReferenceMode !== undefined)
368
+ merged.storyboardReferenceMode = storyboardReferenceMode;
179
369
  const resolved = resolveMultiOptions(merged);
370
+ const seedanceStoryboardReference = isSeedanceStoryboardReference(resolved);
180
371
  const templateVars = {
181
372
  outputDir: resolved.outputDir,
182
373
  scenarioHint: resolved.scenarioHint,
183
374
  model: resolved.model,
184
375
  klingPreset: getKlingPresetDisplay(resolved.model, resolved.klingPreset),
185
- modelDisplayName: getModelDisplayName(resolved.model)
376
+ modelDisplayName: getModelDisplayName(resolved.model),
377
+ referenceMode: resolved.referenceMode,
378
+ maxStoryboardPhases: resolved.storyboardReferenceMode.maxStoryboardPhases,
379
+ chainedIlkFrameExactReuseRequired: !seedanceStoryboardReference,
380
+ storyboardReferencePolicyJson: buildStoryboardReferencePolicyJson(resolved),
381
+ referenceModeContract: buildReferenceModeContract(resolved),
382
+ shotFileOutputContract: buildShotFileOutputContract(resolved),
383
+ continuityContract: buildContinuityContract(resolved),
384
+ seedanceStoryboardContract: buildSeedanceStoryboardContract(resolved),
385
+ selfCheckContract: buildSelfCheckContract(resolved),
386
+ semanticAuditContract: buildSemanticAuditContract(resolved),
387
+ semanticReferenceModeStatusField: seedanceStoryboardReference
388
+ ? "storyboard_reference_status"
389
+ : "start_end_contract_status",
390
+ semanticContinuityStatusField: seedanceStoryboardReference
391
+ ? "storyboard_handoff_status"
392
+ : "chained_ilk_frame_status"
186
393
  };
187
394
  await removeStaleClaudeArtifacts(resolved.rootDir);
188
395
  // Ensure core Film-Kit system files exist (.agent/MASTER.md + skills).
@@ -1,2 +1,4 @@
1
- import type { MultiAgentConfigOptions, ResolvedMultiConfig } from "./types.js";
1
+ import type { MultiAgentConfigOptions, ReferenceMode, ResolvedMultiConfig, StoryboardReferenceConfig } from "./types.js";
2
+ export declare const DEFAULT_STORYBOARD_REFERENCE_CONFIG: StoryboardReferenceConfig;
3
+ export declare function normalizeStoryboardReferenceConfig(input: Partial<StoryboardReferenceConfig> | undefined, referenceMode: ReferenceMode): StoryboardReferenceConfig;
2
4
  export declare function resolveMultiOptions(options: MultiAgentConfigOptions): ResolvedMultiConfig;
@@ -1,12 +1,42 @@
1
1
  const DEFAULT_MODEL = "veo31";
2
2
  const DEFAULT_KLING_PRESET = "ultra-realism";
3
+ const DEFAULT_REFERENCE_MODE = "start-end";
4
+ export const DEFAULT_STORYBOARD_REFERENCE_CONFIG = {
5
+ enabled: false,
6
+ maxStoryboardPhases: 4,
7
+ defaultCharacterRefRole: "character_identity",
8
+ defaultStoryboardRefRole: "storyboard_plan",
9
+ generateAllModelPrompts: true,
10
+ strictReferenceLock: true,
11
+ splitStoryboardOverload: true
12
+ };
13
+ export function normalizeStoryboardReferenceConfig(input, referenceMode) {
14
+ const maxStoryboardPhases = input?.maxStoryboardPhases ?? DEFAULT_STORYBOARD_REFERENCE_CONFIG.maxStoryboardPhases;
15
+ if (!Number.isInteger(maxStoryboardPhases) || maxStoryboardPhases < 1) {
16
+ throw new Error("Invalid storyboardReferenceMode.maxStoryboardPhases. Expected a positive integer.");
17
+ }
18
+ return {
19
+ enabled: input?.enabled ?? referenceMode === "storyboard-reference",
20
+ maxStoryboardPhases,
21
+ defaultCharacterRefRole: "character_identity",
22
+ defaultStoryboardRefRole: "storyboard_plan",
23
+ generateAllModelPrompts: input?.generateAllModelPrompts ?? DEFAULT_STORYBOARD_REFERENCE_CONFIG.generateAllModelPrompts,
24
+ strictReferenceLock: input?.strictReferenceLock ?? DEFAULT_STORYBOARD_REFERENCE_CONFIG.strictReferenceLock,
25
+ splitStoryboardOverload: input?.splitStoryboardOverload ?? DEFAULT_STORYBOARD_REFERENCE_CONFIG.splitStoryboardOverload
26
+ };
27
+ }
3
28
  export function resolveMultiOptions(options) {
4
29
  const warnings = [];
5
30
  const model = options.model ?? DEFAULT_MODEL;
6
31
  const klingPreset = options.klingPreset ?? DEFAULT_KLING_PRESET;
32
+ const referenceMode = options.referenceMode ?? DEFAULT_REFERENCE_MODE;
33
+ const storyboardReferenceMode = normalizeStoryboardReferenceConfig(options.storyboardReferenceMode, referenceMode);
7
34
  if (!options.model) {
8
35
  warnings.push("Model not specified. Falling back to veo31. In the next major release, --model will be required.");
9
36
  }
37
+ if (referenceMode === "storyboard-reference" && !storyboardReferenceMode.enabled) {
38
+ warnings.push("referenceMode is storyboard-reference, but storyboardReferenceMode.enabled is false.");
39
+ }
10
40
  return {
11
41
  rootDir: options.rootDir ?? process.cwd(),
12
42
  outputDir: options.outputDir ?? "./outputs",
@@ -18,6 +48,8 @@ export function resolveMultiOptions(options) {
18
48
  batchSize: options.batchSize ?? 4,
19
49
  model,
20
50
  klingPreset,
51
+ referenceMode,
52
+ storyboardReferenceMode,
21
53
  warnings
22
54
  };
23
55
  }