@lalalic/markcut 2.2.7 → 2.2.9

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 (48) hide show
  1. package/package.json +2 -1
  2. package/skills/markcut/SKILL.md +0 -2
  3. package/skills/markcut/docs/markdown-descriptive.md +1 -1
  4. package/src/config.mjs +60 -63
  5. package/src/descriptive/resolve.ts +3 -2
  6. package/src/player/browser.tsx +3 -1
  7. package/src/player/bundle/player.js +7 -2
  8. package/src/player/components/SceneThumbnails.tsx +3 -1
  9. package/src/player/pipeline.mjs +64 -21
  10. package/src/player/server.mjs +11 -2
  11. package/src/render/cli.mjs +42 -69
  12. package/src/vision/cli.mjs +21 -45
  13. package/skills/markcut/docs/template.md +0 -212
  14. package/skills/markcut/docs/templates/courseware/TEMPLATE.md +0 -526
  15. package/skills/markcut/docs/templates/courseware/agents/reviewer.md +0 -84
  16. package/skills/markcut/docs/templates/courseware/prompts/fix.md +0 -30
  17. package/skills/markcut/docs/templates/courseware/prompts/outline.md +0 -58
  18. package/skills/markcut/docs/templates/courseware/prompts/scene.md +0 -70
  19. package/skills/markcut/docs/templates/deep-dive/TEMPLATE.md +0 -354
  20. package/skills/markcut/docs/templates/deep-dive/agents/researcher.md +0 -69
  21. package/skills/markcut/docs/templates/deep-dive/agents/reviewer.md +0 -108
  22. package/skills/markcut/docs/templates/deep-dive/prompts/fix.md +0 -28
  23. package/skills/markcut/docs/templates/deep-dive/prompts/outline.md +0 -102
  24. package/skills/markcut/docs/templates/deep-dive/prompts/script.md +0 -64
  25. package/skills/markcut/docs/templates/illustrated-book/TEMPLATE.md +0 -356
  26. package/skills/markcut/docs/templates/illustrated-book/agents/reviewer.md +0 -115
  27. package/skills/markcut/docs/templates/illustrated-book/prompts/fix.md +0 -29
  28. package/skills/markcut/docs/templates/illustrated-book/prompts/illustration.md +0 -35
  29. package/skills/markcut/docs/templates/illustrated-book/prompts/story.md +0 -69
  30. package/skills/markcut/docs/templates/short-film/TEMPLATE.md +0 -385
  31. package/skills/markcut/docs/templates/short-film/agents/reviewer.md +0 -115
  32. package/skills/markcut/docs/templates/short-film/prompts/fix.md +0 -29
  33. package/skills/markcut/docs/templates/short-film/prompts/screenplay.md +0 -101
  34. package/skills/markcut/docs/templates/short-film/prompts/storyboard.md +0 -54
  35. package/skills/markcut/docs/templates/short-video/TEMPLATE.md +0 -301
  36. package/skills/markcut/docs/templates/short-video/agents/reviewer.md +0 -94
  37. package/skills/markcut/docs/templates/short-video/prompts/fix.md +0 -27
  38. package/skills/markcut/docs/templates/short-video/prompts/script.md +0 -65
  39. package/skills/markcut/docs/templates/vlog/TEMPLATE.md +0 -326
  40. package/skills/markcut/docs/templates/vlog/agents/reviewer.md +0 -89
  41. package/skills/markcut/docs/templates/vlog/agents/story-writer.md +0 -100
  42. package/skills/markcut/docs/templates/vlog/prompts/bgm-select.md +0 -38
  43. package/skills/markcut/docs/templates/vlog/prompts/group-clips.md +0 -93
  44. package/skills/markcut/docs/templates/vlog/prompts/local-context.md +0 -59
  45. package/skills/markcut/docs/templates/vlog/prompts/outline.md +0 -56
  46. package/skills/markcut/docs/templates/vlog/prompts/review-fix.md +0 -27
  47. package/skills/markcut/docs/templates/vlog/prompts/storyboard.md +0 -41
  48. package/src/render/cli.test.ts +0 -13
@@ -1,28 +0,0 @@
1
- # Prompt: Apply Reviewer Findings
2
-
3
- > Fill every `{placeholder}`, then execute in your own context.
4
-
5
- ---
6
-
7
- Apply the reviewer findings below to `{deep_dive_md_path}` with minimal, targeted edits.
8
-
9
- Reviewer findings (JSON):
10
-
11
- {findings_json}
12
-
13
- Rules:
14
- - Address every `blocker` and `major` finding. Minor findings when trivially fixable.
15
- - Unsupported factual claim → add a source citation scene or qualify the language ("some argue...").
16
- - Missing counterpoint → insert a counterpoint section after the last angle, before synthesis.
17
- - Hook too weak → rewrite hook as a question, contradiction, or provocative claim.
18
- - Low visual variety → change some scene types (turn a claim scene into an evidence scene, add a transition scene).
19
- - BGM too loud → reduce volume (0.05–0.08), ensure `foreground:true`.
20
- - No citations on screen → add citation scenes for sourced claims.
21
- - Duration off → adjust script word count (target × 2.5–3 w/s).
22
-
23
- After editing, list what changed:
24
- ```
25
- - <finding id>: <section> — <one-line description>
26
- ```
27
-
28
- Then re-render and re-review.
@@ -1,102 +0,0 @@
1
- # Prompt: Deep Dive Outline — Research + Narrative Arc
2
-
3
- > Fill every `{placeholder}`, then execute in your own context.
4
- > This is the most critical step: research thoroughly, then structure the arc.
5
-
6
- ---
7
-
8
- You are outlining a {depth} {tone} deep-dive video essay on: **{topic}**.
9
-
10
- Source material: {source_material}
11
- Language: {language}
12
- Target duration: {duration_min} minutes
13
-
14
- ## Phase A — Research
15
-
16
- Use web search to research the topic thoroughly. Find:
17
-
18
- 1. **Key facts** — what is definitively known? Provide sources (URLs) for each.
19
- 2. **Key statistics** — notable numbers with sources.
20
- 3. **Expert quotes** — notable people who have weighed in, with attributions.
21
- 4. **Historical context** — how did we get here? Key dates/events.
22
- 5. **Controversies / debates** — what are the main disagreements? Who holds each view?
23
- 6. **Current state** — what's happening now? Latest developments.
24
- 7. **Broader implications** — why does this matter beyond the topic itself?
25
-
26
- ## Phase B — Narrative arc
27
-
28
- From the research, design the arc:
29
-
30
- ### Hook
31
- What's the most arresting angle? A question, contradiction, or provocative claim that makes someone stop scrolling and watch.
32
-
33
- ### Context
34
- What 2-3 background facts does the audience absolutely need to understand the argument?
35
-
36
- ### Thesis
37
- Your central argument or framing in one sentence.
38
-
39
- ### Angles (perspectives / evidence blocks)
40
- For each angle:
41
- - **Angle title**: short label (e.g. "The Economic Argument", "The Ethical Dimension")
42
- - **Key claims**: 2-5 sub-points with evidence for each
43
- - **Sources**: URLs or citations for each claim
44
- - **Visual idea**: what kind of visuals support this angle
45
-
46
- ### Counterpoint
47
- The strongest opposing view. State it fairly (steel-man). Provide the best sources that support this position.
48
-
49
- ### Synthesis / Rebuttal
50
- How do the evidence and counterpoint resolve? Is there a clear winner, or is the answer nuanced?
51
-
52
- ### Conclusion
53
- Broader implication. What should the viewer take away? What questions remain?
54
-
55
- ## Output format
56
-
57
- ```
58
- ## Research Summary
59
-
60
- ### Key Facts
61
- - <fact> (source: <url>)
62
- - ...
63
-
64
- ### Key Statistics
65
- - <stat> (source: <url>)
66
-
67
- ### Expert Quotes
68
- - "<quote>" — <person>, <context> (source: <url>)
69
-
70
- ### Controversies
71
- - <debate>: view A (proponents) vs view B (proponents)
72
-
73
- ---
74
-
75
- ## Narrative Arc
76
-
77
- Hook: <30-word hook line>
78
-
79
- Context: <2-3 background facts the audience needs>
80
-
81
- Thesis: <one-sentence argument>
82
-
83
- ### Angle 1: <title>
84
- - <claim> (source) → <visual idea>
85
- - <claim> (source) → <visual idea>
86
-
87
- ### Counterpoint: <title>
88
- - <claim> (source)
89
-
90
- ### Synthesis
91
- - <resolution>
92
-
93
- ### Conclusion
94
- - <takeaway>
95
- ```
96
-
97
- ## Rules
98
-
99
- - Every factual claim must have a source URL. If you cannot find a source, mark it as "⚠️ unverified".
100
- - The hook must be a question, contradiction, or provocative claim — not a statement of intent.
101
- - The counterpoint must be steel-manned (the strongest version of the opposing view).
102
- - The synthesis should acknowledge nuance if the evidence doesn't clearly favor one side.
@@ -1,64 +0,0 @@
1
- # Prompt: Deep Dive Scene Script
2
-
3
- > Fill every `{placeholder}`, then execute in your own context.
4
- > Run once per angle/section from the outline.
5
-
6
- ---
7
-
8
- You are writing one section of a {tone} deep-dive video essay on "{topic}".
9
-
10
- Section from outline:
11
-
12
- {outline_section}
13
-
14
- ## Rules
15
-
16
- ### Scene types for this section
17
-
18
- Choose scene types that create visual variety. Aim for at least 2 different types in this section:
19
-
20
- - **Claim scene**: state a point, then support it. `layout:parallel`, visual + subtitle + script.
21
- - **Evidence scene**: show data, a quote, or a case study. Bold text for the key number/quote.
22
- - **Source citation**: brief attribution overlay. Subtle styling.
23
- - **Comparison**: two ideas side-by-side. Use `SplitComparison` component.
24
- - **Transition**: short bridge between ideas. 3-5s, metaphorical visual.
25
-
26
- ### Visual prompts (`src:auto prompt:"..."`)
27
- - Make every visual count. Avoid generic stock footage descriptions.
28
- - For abstract concepts, use metaphorical or atmospheric descriptions.
29
- - Include style/lighting/mood in the prompt (e.g., "cinematic, warm lighting, shallow depth of field").
30
- - For data/evidence scenes, describe a visual representation of the data.
31
-
32
- ### Narration
33
- - Scene-level hook: start each scene with a reason to keep watching.
34
- - 2.5-3 words/second. A 15s scene ≈ 40-45 words.
35
- - Cite sources in the narration: "According to..." "A 2023 study found..."
36
- - End with a hook into the next scene or section.
37
- - No filler phrases.
38
-
39
- ### On-screen text (subtitle)
40
- - Key claims: 36-48px, bold, centered.
41
- - Data/statistics: 40-56px, colored (`#ffd700` for emphasis).
42
- - Quotes: 32-40px, with quotation marks, citation below.
43
- - Citations: 18-24px, italic, subtle color.
44
- - Max 15 words per subtitle frame. For longer quotes, split across frames.
45
-
46
- ### Effects
47
- - Use `effect:fadeIn` for citation overlays.
48
- - Use `effect:slideInRight` for evidence reveals.
49
- - Use `effect:zoomIn` for dramatic moments.
50
-
51
- ## Output format
52
-
53
- ```
54
- ### Section: <Name>
55
-
56
- #### Scene 1: <Scene type>
57
- layout:parallel
58
- - image src:auto prompt:"<visual prompt>" effect:<effect> duration:<s>
59
- - subtitle src:"<on-screen text>" duration:<s> type:Typewriter fontSize:<px>
60
- style:"<css>"
61
- - script "<narration>"
62
-
63
- #### Scene 2: ...
64
- ```
@@ -1,356 +0,0 @@
1
- ---
2
- name: illustrated-book
3
- description: Turn a story, poem, or topic into an animated illustrated picture-book video — narrated text with full-screen illustrations, gentle animations, and page-turn pacing.
4
- when-to-use: children's stories, illustrated poetry, art books, fables, visual storytelling, any content that pairs written text with consistent-style illustrations
5
- engine: "@lalalic/markcut — run via `npx @lalalic/markcut`"
6
- ---
7
-
8
- # Illustrated Book (多媒体绘本) Template
9
-
10
- Follow this file top to bottom. Read the markcut skill (`SKILL.md` → `docs/markdown-descriptive.md`) first if you have not.
11
-
12
- ```mermaid
13
- flowchart LR
14
- Input[📥 Story / Poem / Topic] --> Text[✍️ story.md<br/>text + page breakdown]
15
- Text --> Pages[📋 page plan + text per spread]
16
- Style[🎨 art style] --> Illustrations[🖼️ illustration.md<br/>per-page visual prompts]
17
- Pages --> Illustrations
18
- Illustrations --> Book[📄 book.md]
19
- BGM["🎵 BGM (optional)"] --> Book
20
- Book --> Render[🎬 npx markcut render]
21
- Render --> MP4[📺 final.mp4]
22
- MP4 --> Reviewer[🔍 reviewer agent]
23
- Reviewer -->|FAIL| Fix[🔧 fix]
24
- Fix --> Book
25
- Reviewer -->|PASS| Done[✅ Done]
26
- ```
27
-
28
- | Path | Runs in | Purpose |
29
- |---|---|---|
30
- | `TEMPLATE.md` | your context | everything |
31
- | `prompts/*.md` | your context | fill-in prompts you execute |
32
- | `agents/*.md` | separate session | subagent definitions |
33
-
34
- ## 0. Prerequisites
35
-
36
- - `npx @lalalic/markcut` runnable
37
- - `ffmpeg`/`ffprobe`/`exiftool` on PATH
38
-
39
- ## 1. Inputs — collect before starting
40
-
41
- | Input | Required | Default | Notes |
42
- |---|---|---|---|
43
- | Story / text / topic | **yes** | — | the text to illustrate. Can be: a complete story, a poem, a topic to write about, or an existing text to adapt |
44
- | Source material | no | — | optional: URL, PDF, or existing text to adapt as picture book |
45
- | Book type | no | `story` | `story` (narrative arc), `poetry` (verse-by-verse), `educational` (fact-based, like a nature guide), `wordless` (images only, minimal text) |
46
- | Art style | **yes** | — | the illustration style for ALL pages. Must be consistent. Examples: "watercolor, soft pastels, children's book illustration style", "ink wash painting, traditional Chinese style", "digital painting, studio Ghibli inspired, warm lighting", "woodcut print style, high contrast black and white", "vintage botanical illustration, sepia tones". This single style string is injected into every TTI prompt. |
47
- | Language | no | en | narration and on-screen text language |
48
- | Reading pace | no | `moderate` | `slow` (3-4s per line, ~10s per spread), `moderate` (2-3s per line, ~7s per spread), `fast` (1.5-2s per line, ~5s per spread) |
49
- | Voice | no | | mlx-audio voice. Prefer warm, expressive voices for storytelling |
50
- | BGM mood | no | `ambient` | optional background music. "soft piano", "ambient nature", "lullaby", or "none" |
51
- | Pages | no | auto | target number of spreads/pages. Auto-calculated from text if not set |
52
-
53
- **Style consistency rule**: The `art_style` string is THE single source of truth for illustration style. Every visual prompt across all pages must incorporate this style string. Art style inconsistency is a blocker — the reviewer checks for it.
54
-
55
- ## 2. Scene grammar — book structure
56
-
57
- ### Overview
58
-
59
- ```
60
- # video ← root: width:1920 height:1080 fps:30 layout:series
61
- │ subtitle:{fontSize:"40px",fontFamily:"Georgia,serif"}
62
- │ transition:fade(0.5)
63
- ├── - audio isBackground:true src:bgm.mp3 volume:0.08 (optional)
64
-
65
- ├── ## Cover ← Title + author + establishing illustration
66
- │ layout:parallel
67
- │ - image src:auto prompt:"<cover visual, art_style>" duration:6 effect:zoomIn
68
- │ - subtitle src:"<Title>" duration:6
69
- │ fontSize:"64px" style:"fontWeight:bold;text-shadow:0 4px 20px rgba(0,0,0,.6)"
70
- │ - subtitle src:"by <Author>" duration:6 start:3
71
- │ fontSize:"32px" style:"fontStyle:italic;color:#ccc"
72
- │ - script "<title and author, read aloud>"
73
-
74
- ├── ## Spread 1 ← Story content: one spread per scene
75
- │ layout:parallel
76
- │ - image src:auto prompt:"<illustration for this spread, art_style>" duration:8 effect:zoomIn
77
- │ - subtitle src:"<story text — one spread's worth>" duration:8
78
- │ style:"position:absolute;bottom:80px;left:60px;right:60px;text-align:center;
79
- │ text-shadow:0 2px 10px rgba(0,0,0,.5);line-height:1.6"
80
- │ - script "<narration reading the text>"
81
-
82
- ├── ## Spread 2
83
- │ ...
84
-
85
- └── ## Colophon ← Credits, "The End", copyright
86
- layout:parallel
87
- - image src:auto prompt:"<closing visual, art_style>" duration:6 effect:fadeIn
88
- - subtitle src:"The End" duration:6
89
- fontSize:"56px" style:"fontWeight:bold;text-shadow:0 4px 20px rgba(0,0,0,.6)"
90
- - subtitle src:"<credits>" duration:6 start:4 fontSize:"24px" style:"color:#aaa"
91
- - script "<closing narration>"
92
- ```
93
-
94
- ### Timing per spread (reading pace)
95
-
96
- | Pace | Words per spread | Duration per spread | Lines per spread |
97
- |---|---|---|---|
98
- | slow | 15–25 | 8–12s | 2–4 |
99
- | moderate | 10–20 | 5–8s | 1–3 |
100
- | fast | 8–15 | 4–6s | 1–2 |
101
-
102
- Total duration = sum of all spread durations + cover (6s) + colophon (6s).
103
-
104
- ### Illustration effect
105
-
106
- Each illustration should have a subtle **Ken Burns** (slow zoom or pan) effect to add life:
107
-
108
- ```markdown
109
- - image src:auto prompt:"<prompt>" duration:8 effect:zoomIn
110
- ```
111
-
112
- For variety, alternate between:
113
- - `effect:zoomIn` — slow zoom into the illustration
114
- - `effect:fadeIn` — gentle fade, good for emotional/spread transitions
115
-
116
- Avoid fast or bouncy effects (`bounceIn`, `slideInRight`) — they break the book-like calm.
117
-
118
- ### On-screen text styling
119
-
120
- Book text should feel like a book page, not a video caption:
121
-
122
- ```markdown
123
- - subtitle src:"The little fox walked through the ancient forest,\nwhere the trees whispered secrets to the wind."
124
- duration:8
125
- style:"position:absolute;bottom:80px;left:60px;right:60px;text-align:center;
126
- font-family:'Georgia',serif;font-size:40px;line-height:1.6;
127
- text-shadow:0 2px 10px rgba(0,0,0,.5);color:#f5f5f7"
128
- ```
129
-
130
- Key rules:
131
- - `font-family`: serif (Georgia, Merriweather, Noto Serif) for book feel
132
- - `text-align: center` for storybook elegance
133
- - `line-height: 1.6` for readability
134
- - Bottom-positioned to overlay the illustration without covering the main subject
135
- - Text shadow for legibility over illustrations
136
- - Use `\n` in subtitle text for line breaks between sentences
137
-
138
- ### Scene types (within a book)
139
-
140
- | Scene | Purpose | Visual | Duration |
141
- |---|---|---|---|
142
- | Cover | Title, author, establishing illustration | main artwork | 6s |
143
- | Spread×N | Story content, one illustration per spread | scene-specific | 5–12s each |
144
- | Colophon | Credits, "The End" | closing artwork | 6s |
145
-
146
- Optional additional scenes:
147
- - **Dedication**: "For my daughter" — after cover, 3s
148
- - **Title page**: simplified cover — after dedication, 4s
149
- - **Half-title**: before main content — 3s
150
-
151
- ### Page count guide
152
-
153
- | Text length | Recommended spreads | Total duration |
154
- |---|---|---|
155
- | Very short (poem, 20-50 words) | 3–5 | 30–60s |
156
- | Short story (100-300 words) | 5–10 | 45–90s |
157
- | Medium (300-600 words) | 8–15 | 60–120s |
158
- | Long (600-1000 words) | 12–20 | 90–180s |
159
-
160
- ## 3. Authoring rules — the picture-book bar
161
-
162
- ### Illustration prompts
163
-
164
- This is the most critical part. Every illustration prompt must:
165
-
166
- 1. **Include the art style string** verbatim. Every prompt ends with: `, {art_style}`
167
- 2. **Describe a specific scene** from the text for that spread. Don't be generic.
168
- 3. **Include composition guidance**: "wide shot", "close-up on character", "view from above"
169
- 4. **Include lighting/mood**: "warm morning light", "moonlit", "misty"
170
- 5. **Exclude text/typography** from the image prompt — text is added via the subtitle node.
171
-
172
- Example:
173
- ```markdown
174
- - image src:auto
175
- prompt:"A little red fox standing at the edge of a dark ancient forest, looking back over its shoulder, warm golden sunlight streaming through the trees, cinematic composition, watercolor, soft pastels, children's book illustration style"
176
- duration:8 effect:zoomIn
177
- ```
178
-
179
- **Character consistency** (important for stories with characters):
180
- - Describe the same character appearance across prompts: "the little red fox with a white-tipped tail"
181
- - If the story has named characters, describe their visual appearance in the first prompt and reference it in subsequent prompts: "the same little fox, now crossing a bridge..."
182
- - For human characters: describe age, clothing color, distinct features
183
-
184
- ### Text adaptation
185
-
186
- - **One spread = one narrative unit**: A spread contains 1-4 sentences that form a complete story beat. Don't split a single sentence across spreads, and don't cram unrelated sentences into one spread.
187
- - **End-of-spread hook**: Where possible, end a spread with a line that creates gentle anticipation for the next spread ("But little did she know...")
188
- - **On-screen text**: Display ALL the text for that spread. Don't truncate or summarize. The viewer reads along as the narrator speaks.
189
- - **Subtitle text = narration text**: They should match exactly, or the subtitle can be a slightly shorter version if the narration elaborates. If they differ, note it.
190
-
191
- ### Narration
192
-
193
- - **Expressive reading**: Write the narration to be read expressively, not monotonously. Use punctuation for pacing: em-dashes for pauses, ellipses for suspense.
194
- - **Pace**: Match the `reading_pace`. A moderate pace ≈ 3 words/second.
195
- - **Voice**: Prefer warm, expressive TTS voices (JennyNeural, etc.). Avoid flat instructional voices.
196
- - **Character voices** (optional): For dialogue-heavy stories, consider using different TTS voices per character, or add parenthetical tone guidance: `"she whispered"`, `"he boomed"`.
197
-
198
- ### BGM (optional but recommended)
199
-
200
- ```markdown
201
- - audio isBackground:true foreground:true src:bgm.mp3 volume:0.08
202
- ```
203
-
204
- - Volume: 0.05–0.10. The narration is the star.
205
- - Genre: soft piano, acoustic guitar, ambient nature, lullaby, string quartet — depending on mood.
206
- - If the story has an emotional arc, the BGM should follow it (brighter for happy scenes, softer for sad).
207
-
208
- ### Typography / subtitle style
209
-
210
- - **Font**: serif (Georgia, Merriweather, Noto Serif) for literary feel
211
- - **Size**: 36–44px for main text; 56–64px for title; 24–28px for credits
212
- - **Color**: `#f5f5f7` (off-white) over dark backgrounds; `#1a1a2e` (dark) over light backgrounds
213
- - **Position**: bottom 60–100px (lower third), centered
214
- - **Line spacing**: `line-height: 1.6`
215
- - **Text shadow**: always — illustrations are unpredictable in brightness
216
-
217
- ### Multi-language (variants)
218
-
219
- - Same `# <lang>` variant block pattern.
220
- - For translated stories, ensure the translation preserves the rhythm and pacing of the original. A line that's 8 words in English might be 12 in Chinese — adjust the spread duration accordingly.
221
-
222
- ### Frame / border effect (optional)
223
-
224
- To reinforce the "book" feel, overlay a subtle frame or border:
225
-
226
- ```markdown
227
- - component isBackground:true jsx:"<div style='position:absolute;inset:0;border:30px solid #2a1f14;pointer-events:none' />"
228
- ```
229
-
230
- Or use a CSS stylesheet with a vignette:
231
- ```css
232
- .book-frame {
233
- position: absolute;
234
- inset: 0;
235
- box-shadow: inset 0 0 80px rgba(0,0,0,.4);
236
- pointer-events: none;
237
- }
238
- ```
239
-
240
- ## 4. Components & styles
241
-
242
- ### Optional: Ken Burns zoom component
243
-
244
- For more controlled Ken Burns effect than `effect:zoomIn` provides:
245
- ```jsx
246
- export function KenBurnsImage({ src, duration, zoomAmount = 1.15 }) {
247
- const frame = useCurrentFrame();
248
- const { fps } = useVideoConfig();
249
- const progress = frame / (duration * fps);
250
- const scale = 1 + (zoomAmount - 1) * Math.min(progress, 1);
251
- return (
252
- <Img src={src} style={{
253
- width: '100%', height: '100%', objectFit: 'cover',
254
- transform: `scale(${scale})`,
255
- transformOrigin: 'center center',
256
- }} />
257
- );
258
- }
259
- ```
260
-
261
- ### Stylesheet (for book frame overlay)
262
-
263
- ```css
264
- ~~~css stylesheet
265
- .book-page {
266
- position: absolute;
267
- inset: 30px;
268
- box-shadow: inset 0 0 60px rgba(0,0,0,.3);
269
- pointer-events: none;
270
- border: 2px solid rgba(255,255,255,.08);
271
- border-radius: 4px;
272
- }
273
- ~~~
274
- ```
275
-
276
- Then use: `- component isBackground:true jsx:"<div className='book-page' />"` at root level.
277
-
278
- ### Theme knobs
279
-
280
- | Knob | Default | Effect |
281
- |---|---|---|
282
- | Font family | `Georgia, serif` | Typography feel |
283
- | Text color | `#f5f5f7` | Legibility over illustrations |
284
- | Frame border | `none` or `30px solid #2a1f14` | Book frame feel |
285
- | Ken Burns zoom | `1.0`–`1.15` | Illustration animation intensity |
286
-
287
- ## 5. Workflow
288
-
289
- ### Phase 0: Text preparation
290
-
291
- 1. **Read / write the text** — Given the topic or source material, determine the text. For an existing story: read and adapt it into 1-4 sentence spreads. For a topic: write an original short story or poetic text.
292
-
293
- 2. **Determine art style** — If the user didn't provide an art style, suggest 2-3 options based on the text's mood (e.g., "watercolor, soft pastels" for a gentle story; "ink wash" for a philosophical tale; "digital painting, warm lighting" for an adventure).
294
-
295
- ### Phase 1: Page plan
296
-
297
- 3. **Split text into spreads** — Fill `prompts/story.md` with the full text and art style. This produces:
298
- - Per-spread text (1-4 sentences each)
299
- - Per-spread illustration description (what to show)
300
- - Total page count and estimated duration
301
-
302
- **Key rule**: Each spread must form a coherent narrative unit. A spread should feel complete on its own while hooking into the next.
303
-
304
- ### Phase 2: Illustration prompts
305
-
306
- 4. **Generate illustration prompts** — Fill `prompts/illustration.md` per spread. This writes the detailed TTI prompt for each illustration, ensuring:
307
- - The `art_style` string is appended verbatim to every prompt
308
- - Character descriptions stay consistent across spreads
309
- - Composition and lighting vary to avoid visual monotony
310
-
311
- 5. **(Optional) Generate illustrations** — If ITT CLI is available, run it for each prompt to generate the actual images. Store in `.markcut/generated/media/` with page-number filenames. If ITT is unavailable, leave `src:auto` in place — the render pipeline will resolve them.
312
-
313
- ### Phase 3: Assemble
314
-
315
- 6. **Assemble book.md** — Write the markcut markdown file using §2 grammar:
316
- - Root config: 1920×1080, serif subtitle font, TTS voice, optional BGM
317
- - Cover scene with title + author
318
- - Spread scenes with illustration + text + narration
319
- - Colophon with credits
320
- - Optional: dedication, title page
321
- - Consistent `effect:zoomIn` or `effect:fadeIn` on all illustrations
322
-
323
- 7. **Render** — `npx @lalalic/markcut render book.md`. On errors: fix and re-render, max 3 per error.
324
-
325
- ### Phase 4: Review
326
-
327
- 8. **Review (quality gate)** — Run `agents/reviewer.md` in a fresh separate session. Pass: `book.md`, rendered MP4, `TEMPLATE.md`, target duration, language, art style, book type. Returns `{verdict, findings[]}`.
328
-
329
- 9. **Fix loop** — On FAIL: fill `prompts/fix.md` with findings, edit, re-render, re-review. Max 3 iterations, then escalate.
330
-
331
- ## 6. Quality gate — exit criteria
332
-
333
- Done only when ALL hold:
334
-
335
- - [ ] reviewer verdict = `PASS` (zero blocker/major findings)
336
- - [ ] total duration within ±15% of target
337
- - [ ] structure matches §2 (cover → spreads×N → colophon)
338
- - [ ] art style is **consistent** across ALL illustrations — spot-check 3 prompts/images, compare the style string/visual output
339
- - [ ] character descriptions are consistent across spreads (same appearance, clothing, features)
340
- - [ ] each spread contains 1-4 sentences that form a coherent narrative unit
341
- - [ ] on-screen text matches narration (subtitle ≈ script) for each spread
342
- - [ ] illustration effect is subtle (`zoomIn` or `fadeIn`) — no bouncy/fast effects
343
- - [ ] no blank/black frames; illustrations are rendered correctly
344
- - [ ] STT transcript matches script lines (≥90% content match)
345
- - [ ] typography uses serif font, adequate text shadow, readable size (≥36px)
346
- - [ ] reading pace is consistent with chosen pace (checked via average words/second across spreads)
347
- - [ ] BGM (if present) is ducked under narration, volume ≤ 0.10
348
- - [ ] no text/typography in the generated images (text is only in subtitle nodes)
349
-
350
- ## 7. Reference
351
-
352
- - Golden example: See `tests/fixtures/templates/courseware.md` for the template format.
353
- - For illustration prompts: always append ", {art_style}" to every TTI prompt.
354
- - Effect reference: use `effect:zoomIn` (slow, default) or `effect:fadeIn` (gentle) for all illustrations.
355
- - Subtitle styling: serif font, centered, bottom-positioned, text-shadow always set.
356
- - Ken Burns intensity controlled via `effect:zoomIn` → the effect duration determines zoom speed.
@@ -1,115 +0,0 @@
1
- ---
2
- name: illustrated-book-reviewer
3
- description: Read-only quality gate for animated picture-book videos. Checks art style consistency, character continuity, text-narration match, typography, and pacing.
4
- context: fresh
5
- mode: read-only
6
- tools: read file, bash (ffmpeg/ffprobe, STT CLI), image understanding
7
- ---
8
-
9
- # System prompt
10
-
11
- You are a strict QA reviewer for animated illustrated picture-book videos. You review; you **never edit** any file.
12
-
13
- ## Inputs (provided in the task)
14
- - `book_md` — absolute path to the generated book markdown
15
- - `mp4` — absolute path to the rendered video
16
- - `template_md` — absolute path to this `TEMPLATE.md`
17
- - `duration_min` — target duration
18
- - `language` — expected language
19
- - `art_style` — the canonical art style string
20
- - `book_type` — story | poetry | educational | wordless
21
-
22
- ## Procedure
23
-
24
- ### 1. Static review (source vs rulebook)
25
-
26
- **Structure** (§2):
27
- - Cover scene present (first scene after root — title + author).
28
- - Spread scenes (content) between cover and colophon.
29
- - Colophon scene present (last scene — "The End" + credits).
30
- - Scene count matches the text length (5-20 spreads typical).
31
-
32
- **Art style consistency**:
33
- - Read every `prompt:"..."` on every `- image` node.
34
- - Check if ALL prompts contain the `art_style` string (or an equivalent consistent style).
35
- - If any prompt lacks the art style string or uses a different style → major finding.
36
- - If character descriptions are inconsistent (different colors, features, clothing across spreads where they should be the same) → major finding.
37
-
38
- **Text-narration match**:
39
- - For each spread scene, compare the `subtitle src:"..."` text with the `- script "..."` text.
40
- - They should match exactly, OR the subtitle can be a shorter version of the script.
41
- - If they contradict or differ significantly → major finding.
42
-
43
- **Typography**:
44
- - Subtitle `fontFamily` should be serif (Georgia, Merriweather, Noto Serif, etc.).
45
- - Font size ≥ 36px.
46
- - `text-shadow` present for legibility.
47
- - Text is positioned in lower portion of frame (bottom 60-100px).
48
-
49
- **Illustration effects**:
50
- - Every image node should have `effect:zoomIn` or `effect:fadeIn` (subtle Ken Burns).
51
- - No fast/bouncy effects (`bounceIn`, `slideInRight`, `flipIn`).
52
-
53
- **Text in images**:
54
- - Check image prompts for words like "text", "title", "letter", "word", "typography", "writing" — flag if found (text should only be in subtitle nodes).
55
-
56
- **Per-spread coherence**:
57
- - Each spread's subtitle text should contain 1-4 sentences forming a coherent narrative unit.
58
- - Spot-check 3 spreads: does the text + illustration feel like one story beat?
59
-
60
- ### 2. Dynamic review
61
- - `ffprobe`: duration (compare to target ±15%), resolution, audio streams.
62
- - Extract 8 frames (cover, 2 early spreads, 2 mid spreads, 2 late spreads, colophon).
63
- - For each: not blank/black, has illustration + text overlay, text is legible.
64
- - Check art style consistency across frames: do the illustrations look like they belong to the same book?
65
- - Check character consistency: does the character look the same across frames?
66
- - Extract audio → STT. Compare against all `- script "..."` lines. ≥90% match.
67
- - Check BGM presence (if configured): audio stream present, not silent, not clipping.
68
-
69
- ### 3. Report
70
-
71
- Severity: `blocker` (blank frames, no illustrations, no cover or colophon) · `major` (art style inconsistent, character inconsistency, text-narration mismatch, wrong font, no subtle effect, duration >20% off) · `minor` (font slightly small, spacing, minor timing)
72
-
73
- Output exactly this JSON:
74
-
75
- ```json
76
- {
77
- "verdict": "PASS | FAIL",
78
- "measured": {
79
- "duration_s": 0,
80
- "target_s": 0,
81
- "resolution": "",
82
- "stt_match_pct": 0,
83
- "spread_count": 0
84
- },
85
- "findings": [
86
- {
87
- "id": "F1",
88
- "severity": "blocker | major | minor",
89
- "scene": "<spread name or 'global'>",
90
- "check": "<which rule>",
91
- "issue": "<what is wrong>",
92
- "evidence": "<source line / frame path / STT excerpt>",
93
- "fix_hint": "<one-line suggestion>"
94
- }
95
- ]
96
- }
97
- ```
98
-
99
- `PASS` requires zero `blocker` and zero `major` findings.
100
-
101
- # Task template
102
-
103
- ```
104
- Review an animated picture-book video against its template.
105
-
106
- book_md: {book_md}
107
- mp4: {mp4}
108
- template_md: {template_md}
109
- duration_min: {duration_min}
110
- language: {language}
111
- art_style: {art_style}
112
- book_type: {book_type}
113
-
114
- Follow your procedure. Use whisper-cli (whisper.cpp) for STT if python whisper is unavailable. Save frames under a review directory. Spot-check 3 spreads for text-narration match and art style consistency. Output the verdict JSON only.
115
- ```