@scenerok/cli 1.0.4 → 1.0.5

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 (57) hide show
  1. package/dist/commands/skills.d.ts.map +1 -1
  2. package/dist/commands/skills.js +42 -1
  3. package/dist/commands/validate.d.ts.map +1 -1
  4. package/dist/commands/validate.js +26 -4
  5. package/dist/lib/api.d.ts +2 -0
  6. package/dist/lib/api.d.ts.map +1 -1
  7. package/examples/system/3-tips-fitness.vid +45 -0
  8. package/examples/system/ecom-product-launch.vid +31 -0
  9. package/examples/system/glitch-title.vid +17 -0
  10. package/examples/system/meme-remix.vid +15 -0
  11. package/examples/system/minimal-text-reel.vid +11 -0
  12. package/examples/system/product-launch.vid +18 -0
  13. package/examples/system/rokmilk-chocolate-promo.vid +24 -0
  14. package/examples/system/testimonial-cut.vid +16 -0
  15. package/examples/system/ugc-testimonial-voiceover.vid +33 -0
  16. package/examples/system/voice-visual-promo.vid +21 -0
  17. package/package.json +2 -1
  18. package/skills/aider/SKILL.md +18 -8
  19. package/skills/aider/vidscript-guide.md +29 -9
  20. package/skills/aider/vidscript-sample.md +22 -14
  21. package/skills/aider/vidscript-strict.md +95 -0
  22. package/skills/claude/SKILL.md +18 -8
  23. package/skills/claude/vidscript-guide.md +26 -7
  24. package/skills/claude/vidscript-sample.md +22 -14
  25. package/skills/claude/vidscript-strict.md +95 -0
  26. package/skills/codex/SKILL.md +18 -8
  27. package/skills/codex/vidscript-guide.md +29 -9
  28. package/skills/codex/vidscript-sample.md +22 -14
  29. package/skills/codex/vidscript-strict.md +95 -0
  30. package/skills/cursor/SKILL.md +18 -8
  31. package/skills/cursor/vidscript-guide.md +29 -9
  32. package/skills/cursor/vidscript-sample.md +22 -14
  33. package/skills/cursor/vidscript-strict.md +95 -0
  34. package/skills/opencode/SKILL.md +18 -8
  35. package/skills/opencode/vidscript-guide.md +29 -9
  36. package/skills/opencode/vidscript-sample.md +22 -14
  37. package/skills/opencode/vidscript-strict.md +95 -0
  38. package/skills/skills/aider/SKILL.md +190 -0
  39. package/skills/skills/aider/vidscript-guide.md +375 -0
  40. package/skills/skills/aider/vidscript-sample.md +29 -0
  41. package/skills/skills/aider/vidscript-strict.md +95 -0
  42. package/skills/skills/claude/SKILL.md +190 -0
  43. package/skills/skills/claude/vidscript-guide.md +375 -0
  44. package/skills/skills/claude/vidscript-sample.md +29 -0
  45. package/skills/skills/claude/vidscript-strict.md +95 -0
  46. package/skills/skills/codex/SKILL.md +190 -0
  47. package/skills/skills/codex/vidscript-guide.md +375 -0
  48. package/skills/skills/codex/vidscript-sample.md +29 -0
  49. package/skills/skills/codex/vidscript-strict.md +95 -0
  50. package/skills/skills/cursor/SKILL.md +190 -0
  51. package/skills/skills/cursor/vidscript-guide.md +375 -0
  52. package/skills/skills/cursor/vidscript-sample.md +29 -0
  53. package/skills/skills/cursor/vidscript-strict.md +95 -0
  54. package/skills/skills/opencode/SKILL.md +190 -0
  55. package/skills/skills/opencode/vidscript-guide.md +375 -0
  56. package/skills/skills/opencode/vidscript-sample.md +29 -0
  57. package/skills/skills/opencode/vidscript-strict.md +95 -0
@@ -0,0 +1,375 @@
1
+ # VidScript Language Reference (v2)
2
+
3
+ VidScript is a declarative DSL for composing short-form videos. Write a script, render an MP4.
4
+
5
+ ## Agent quick start (read before composing)
6
+
7
+ 1. **Import plugins** — `import xai from "@scenerok/xai"` before `xai.imagine`, `xai.tts`, or `animate: fadeIn(...)`.
8
+ 2. **Validate early** — `scenerok validate file.vid` (errors show as `Line N:C — message`).
9
+ 3. **Copy working examples** — see `examples/system/` in this skill folder (e.g. `minimal-text-reel.vid`, `ecom-product-launch.vid`, `rokmilk-chocolate-promo.vid`).
10
+ 4. **Strict rules** — see `vidscript-strict.md` for invalid patterns (bare `xai.imagine`, `audio music(...), volume:`, nested quotes in prompts).
11
+
12
+ ### Common validation failures
13
+
14
+ | Symptom | Fix |
15
+ |---------|-----|
16
+ | `Unknown function 'xai.imagine'` | Add `import xai from "@scenerok/xai"` at top |
17
+ | `Unknown function 'fadeIn'` | Same import (animation helpers are plugin-backed) |
18
+ | `Expected ... but "," found` | Do not put `, volume:` after a plugin call on the same line |
19
+ | Parse error on imagine prompt | Remove nested `"` quotes inside the prompt string |
20
+
21
+ ## Program Structure
22
+
23
+ A VidScript program is a sequence of statements separated by newlines.
24
+
25
+ ```vidscript
26
+ # Single-line comment
27
+ /* Multi-line
28
+ comment */
29
+ ```
30
+
31
+ ## Statements
32
+
33
+ ### Input Declaration
34
+
35
+ ```vidscript
36
+ input hero = "https://cdn.example.com/hero.mp4"
37
+ input logo = "./assets/logo.png"
38
+ ```
39
+
40
+ Supports HTTP(S) URLs, `/uploads/` paths, and local paths.
41
+
42
+ ### Output Declaration
43
+
44
+ ```vidscript
45
+ output to "video.mp4", resolution: "1080x1920", fps: 30
46
+ output to "reel.mp4", resolution: "720x1280", format: "mp4", codec: "h264", bitrate: "5M", background: "#0D0D0D"
47
+ ```
48
+
49
+ | Option | Type | Default | Description |
50
+ |--------|------|---------|-------------|
51
+ | `resolution` | string | `"1080x1920"` | Width×Height or single number |
52
+ | `fps` | number | `30` | Frames per second |
53
+ | `format` | string | `"mp4"` | Container format |
54
+ | `codec` | string | `"h264"` | Video codec |
55
+ | `bitrate` | string | `"5M"` | Encoding bitrate |
56
+ | `background` | string | `"#000000"` | Background color hex |
57
+
58
+ ### Variable Assignment
59
+
60
+ ```vidscript
61
+ let brandColor = "#6366F1"
62
+ let fadeTime = 0.5s
63
+ let titleSize = 72
64
+ let clipName = "hero"
65
+ ```
66
+
67
+ Variables can hold strings, numbers, time literals, and object expressions. Variables are evaluated at compile time.
68
+
69
+ ### Import / Export (Module System)
70
+
71
+ ```vidscript
72
+ # Export a constant
73
+ export const BRAND_COLOR = "#FF5733"
74
+
75
+ # Export a timeline
76
+ export timeline intro(clip: string, title_text: string) {
77
+ [-] = clip
78
+ [- 2s] = text title_text, size: 72
79
+ }
80
+
81
+ # Import from another file
82
+ import { intro, BRAND_COLOR } from "./timelines.vid"
83
+
84
+ # Import namespace
85
+ import * as transitions from "@scenerok/transitions"
86
+
87
+ # Use a timeline
88
+ use intro at 0s .. 5s with { clip: hero, title_text: "Hello" }
89
+ ```
90
+
91
+ ## Time Blocks
92
+
93
+ Time blocks are the core of VidScript. They define when instructions execute on the timeline.
94
+
95
+ ### Dynamic Playhead (recommended)
96
+
97
+ ```vidscript
98
+ [-] = hero # auto-append: starts after previous block
99
+ [- 3s] = text "Title", size: 72 # auto-start, last 3 seconds
100
+ [- 2.5s] = filter "glow", intensity: 0.8
101
+ ```
102
+
103
+ The playhead cursor (`prev`) tracks where the timeline is. Each `[-]` block advances the cursor by the block's content duration. `[- duration]` advances by an explicit duration.
104
+
105
+ ### Explicit Range
106
+
107
+ ```vidscript
108
+ [0s .. 5s] = hero # absolute range
109
+ [0.5s .. 3s] = text "Hello" # explicit times
110
+ [prev + 1s .. prev + 4s] = filter "glow" # expression-based
111
+ ```
112
+
113
+ Use `..` (not `-`) as the range separator to avoid ambiguity with subtraction.
114
+
115
+ ### Time Formats
116
+
117
+ ```vidscript
118
+ 5s # 5 seconds
119
+ 300ms # 300 milliseconds
120
+ frame 90 # 90 frames at 30fps = 3 seconds
121
+ 0:30 # 30 seconds
122
+ 1:30:00 # 1 hour 30 minutes
123
+ ```
124
+
125
+ ### The `prev` Keyword
126
+
127
+ `prev` refers to the current playhead position — the end time of the previous block.
128
+
129
+ ```vidscript
130
+ [- 2s] = text "Hello" # plays from cursor to cursor+2s
131
+ [prev + 1s .. prev + 3s] = filter "glow" # 1s after text ends, for 2s
132
+ ```
133
+
134
+ ## Instructions (inside time blocks)
135
+
136
+ Multiple instructions in the same time block go on separate lines:
137
+
138
+ ```vidscript
139
+ [0s .. 5s] = hero
140
+ hero.Trim(start: 0s, end: 5s)
141
+ hero.Speed(factor: 1.5)
142
+ ```
143
+
144
+ ### Clip Reference
145
+
146
+ ```vidscript
147
+ [-] = hero # just play the input clip
148
+ ```
149
+
150
+ ### Text Overlay
151
+
152
+ ```vidscript
153
+ [- 3s] = text "Hello World", font: "Bebas Neue", x: "50%", y: "45%", align: center, color: "#FFFFFF", size: 72, stroke: "#000000", stroke_width: 3, letter_spacing: 4, shadow_color: "#FF0055", shadow_blur: 8
154
+ ```
155
+
156
+ | Param | Type | Description |
157
+ |-------|------|-------------|
158
+ | `style` | string | `title` (64px), `subtitle` (54px), `caption` (36px), or `default` (48px) |
159
+ | `position` | string | `center`, `top`, `bottom`, `top-left`, `top-right`, `bottom-left`, `bottom-right` |
160
+ | `x` | number \| string | Horizontal position. Number = px from left. `"50%"` = percent of width. Overrides `position`. |
161
+ | `y` | number \| string | Vertical position. Number = px from top. `"50%"` = percent of height. Overrides `position`. |
162
+ | `color` | string | Hex color |
163
+ | `size` | number | Font size in pixels |
164
+ | `font` | string | Font family. System fonts or Google Fonts: `"Inter"`, `"Bebas Neue"`, `"Space Grotesk"`, `"Outfit"`, etc. |
165
+ | `align` | string | `left`, `center`, `right`. Default: `center` |
166
+ | `line_height` | number | Line height multiplier for multi-line text. Default: 1.2 |
167
+ | `letter_spacing` | number | Extra letter spacing in pixels. Default: 0 |
168
+ | `rotation` | number | Rotation in degrees. Positive = clockwise. Default: 0 |
169
+ | `opacity` | number | Opacity 0–1. Default: 1 |
170
+ | `stroke` | string | Outline color |
171
+ | `stroke_width` | number | Outline thickness |
172
+ | `shadow_color` | string | Drop shadow color |
173
+ | `shadow_blur` | number | Shadow blur radius |
174
+ | `shadow_offset_x` | number | Shadow horizontal offset |
175
+ | `shadow_offset_y` | number | Shadow vertical offset |
176
+ | `animation` | string | Parsed but not yet rendered |
177
+
178
+ Params are optional and comma-separated. Params can be on the same line as the content.
179
+
180
+ ### Video Methods
181
+
182
+ ```vidscript
183
+ hero.Trim(start: 0s, end: 5s) # trim clip (positional: hero.Trim(0s, 5s))
184
+ hero.Resize(width: 720, height: 1280) # resize (positional: hero.Resize(720, 1280))
185
+ hero.Speed(factor: 1.5) # playback rate
186
+ hero.Loop(count: 3) # loop count
187
+ hero.Opacity(value: 0.5, duration: 2s) # opacity with duration
188
+ ```
189
+
190
+ Arguments can be positional or named using `:`.
191
+
192
+ ### Compositing
193
+
194
+ ```vidscript
195
+ hero.Overlay(logo, x: 50, y: 100, opacity: 0.8)
196
+ hero.Composite(overlay, x: 0, y: 0, opacity: 0.5, mode: "screen")
197
+ ```
198
+
199
+ | Param | Type | Description |
200
+ |-------|------|-------------|
201
+ | `x` | number | Horizontal offset |
202
+ | `y` | number | Vertical offset |
203
+ | `opacity` | number | 0–1 transparency |
204
+ | `mode` | string | Blend mode for Composite |
205
+
206
+ ### Filters
207
+
208
+ ```vidscript
209
+ [- 2s] = filter "glow", intensity: 0.8
210
+ [0s .. 5s] = filter "vignette", intensity: 0.3
211
+ ```
212
+
213
+ Built-in filters: `monochrome`, `sepia`, `blur`, `chromatic`, `glitch`, `vignette`, `contrast`, `saturation`, `brightness`.
214
+
215
+ ### Shaders
216
+
217
+ ```vidscript
218
+ import shader glow from "shader-pack/glow.glsl"
219
+
220
+ [0s .. 5s] = shader glow, intensity: 0.8
221
+ ```
222
+
223
+ ### Audio
224
+
225
+ ```vidscript
226
+ audio music, volume: 0.5, fade_in: 1s, fade_out: 2s
227
+ ```
228
+
229
+ Audio sources can be MP3 inputs, audio plugin results, or the embedded audio stream from an input video. Video clips are visually silent unless you explicitly add `audio clip`.
230
+
231
+ | Param | Type | Description |
232
+ |-------|------|-------------|
233
+ | `volume` | number | 0–1 |
234
+ | `fade_in` | number | Fade-in duration (seconds) |
235
+ | `fade_out` | number | Fade-out duration (seconds) |
236
+
237
+ ### Plugin Calls
238
+
239
+ ```vidscript
240
+ import xai from "@scenerok/xai"
241
+
242
+ [-] = video xai.imagine("Cinematic product shot", aspect_ratio: "9:16", duration: 5)
243
+ [-] = audio xai.tts("Welcome to SceneRok", voice: "eve")
244
+ ```
245
+
246
+ Plugins require an explicit default import. The server registers `@scenerok/xai` when API keys are configured. Plugin calls run at compile time and must appear **inside time blocks**, not in `let` assignments.
247
+
248
+ **Invalid (will not validate):**
249
+
250
+ ```vidscript
251
+ [-] = video xai.imagine("...") # missing import
252
+ [-] = audio music("..."), volume: 0.5 # trailing params after plugin call
253
+ let clip = xai.imagine("...") # plugin assigned to variable
254
+ ```
255
+
256
+ ## Animations, Effects & Plugins (v2 Extensibility)
257
+
258
+ VidScript v2 uses a **minimal-grammar, plugin-first** architecture for animations and effects.
259
+
260
+ Instead of adding dozens of animation keywords to the language, we use two powerful parameters:
261
+
262
+ - `animate:`
263
+ - `effects:`
264
+
265
+ These accept either plugin function calls or plain object descriptors.
266
+
267
+ ### animate: parameter
268
+
269
+ Attach animations to **any** text or video surface.
270
+
271
+ ```vidscript
272
+ text "Hello", animate: fadeIn(0.8s)
273
+
274
+ video hero, animate: [fadeIn(0.5s), slideY(-40, 0, 1.2s)]
275
+
276
+ text "Title", animate: {
277
+ type: "fade",
278
+ from: { opacity: 0 },
279
+ to: { opacity: 1 },
280
+ start: 0,
281
+ end: 1.5
282
+ }
283
+ ```
284
+
285
+ ### effects: parameter
286
+
287
+ Attach post-processing effects, with support for animated parameters.
288
+
289
+ ```vidscript
290
+ text "Dramatic", effects: [grayscale(intensity: 0.8)]
291
+
292
+ video hero, effects: [{
293
+ name: "glitch",
294
+ strength: animate: { type: "fade", from: { strength: 0 }, to: { strength: 1 } }
295
+ }]
296
+ ```
297
+
298
+ ### Currently Available Animation Functions (`basic-animations` plugin)
299
+
300
+ | Function | Description |
301
+ |---------------------------|------------------------------|
302
+ | `fadeIn(duration?)` | Opacity 0 → 1 |
303
+ | `fadeOut(duration?)` | Opacity 1 → 0 |
304
+ | `slideX(from, to, dur?)` | Horizontal slide |
305
+ | `slideY(from, to, dur?)` | Vertical slide |
306
+ | `popIn(duration?)` | Scale + fade entrance |
307
+ | `riseIn(duration?, dist?)` | Upward fade entrance |
308
+ | `swingIn(duration?)` | Rotating slide/fade |
309
+ | `glitchIn(duration?)` | Jitter + flash entrance |
310
+ | `float(duration?, amp?)` | Gentle vertical bob |
311
+ | `typewriter(duration?)` | Character reveal |
312
+
313
+ More plugins (advanced text animations, pixel effects, 3D, etc.) are planned.
314
+
315
+ The full architecture and IR details live in `plan-v1/29-surface-animation-effect-plugin-architecture.md`.
316
+
317
+ ## Expressions
318
+
319
+ Used in time specs, `let` values, and function arguments:
320
+
321
+ ```vidscript
322
+ let x = 5s # Time literals
323
+ let y = x * 2 # Arithmetic
324
+ let prompt = "Scene: " + title_text # String concatenation
325
+ let z = prev + 0.5s # Playhead reference
326
+ let a = { primary: "#FF5733" } # Objects
327
+ ```
328
+
329
+ Operators: `+`, `-`, `*`, `/` with standard precedence.
330
+
331
+ ## Template Placeholders
332
+
333
+ ```vidscript
334
+ [- 3s] = text "{{headline | Default Text}}", color: "{{color | #FFFFFF}}"
335
+ ```
336
+
337
+ Placeholders are filled before parsing via `fillPlaceholders()`.
338
+
339
+ ## CLI Commands
340
+
341
+ ```bash
342
+ # Authenticate
343
+ scenerok auth login
344
+
345
+ # Validate a script
346
+ scenerok validate my-video.vid
347
+
348
+ # Render a video
349
+ scenerok project upload my-video.vid --assets ./assets --render --watch --download ./renders
350
+ scenerok project render <project-id> --watch --download ./renders
351
+ scenerok render my-video.vid --project-id <project-id> --watch
352
+ scenerok cache pull
353
+
354
+ # Check render status
355
+ scenerok status <render-id>
356
+
357
+ # Install agent skills
358
+ scenerok skills install <platform>
359
+
360
+ # Set API secrets for plugins
361
+ scenerok secrets set ELEVENLABS_API_KEY=your-key
362
+ ```
363
+
364
+ ## Best Practices
365
+
366
+ 1. **Use dynamic timeblocks** — `[-]` auto-advances the cursor, reducing calculation errors
367
+ 2. **Use `prev` for offsets** — `[prev + 0.5s .. prev + 2s]` for gaps after previous content
368
+ 3. **1080×1920 for vertical** (TikTok, Reels, Shorts), **1920×1080 for horizontal** (YouTube)
369
+ 4. **Hook viewers in the first 3 seconds** — place the most compelling content early
370
+ 5. **High-contrast text** — use `stroke` and `stroke_width` on text overlays over video
371
+ 6. **Test with `scenerok validate` first** — catch syntax errors before spending render credits
372
+ 7. **Keep text content short** — text disappears when the time block ends
373
+ 8. **One instruction per line** — each instruction inside a timeblock goes on its own line
374
+ 9. **Text-only auto blocks** — `[-] = text ...` lasts 2 seconds by default; use `[- 3s]` for custom timing
375
+ 10. **Named arguments are clearer** — `hero.Trim(start: 0s, end: 5s)` over `hero.Trim(0s, 5s)`
@@ -0,0 +1,29 @@
1
+ # VidScript v2 Sample — Product promo with generated video
2
+
3
+ Copy this shape for promos that use xAI-generated clips. Run `scenerok validate` before `scenerok render`.
4
+
5
+ ```vidscript
6
+ import xai from "@scenerok/xai"
7
+
8
+ input product_name = "{{product_name | RokMilk}}"
9
+ input hook_text = "{{hook_text | Chocolate Milkshake}}"
10
+ input cta_text = "{{cta_text | visit your nearest grocery store}}"
11
+
12
+ [0s .. 2.5s] = text product_name, font: "Bebas Neue", size: 80, color: "#FFD700", x: "50%", y: "20%", align: center, stroke: "#3E1C00", stroke_width: 4, animate: fadeIn(0.6s)
13
+
14
+ [2s .. 4.5s] = text hook_text, font: "Outfit", size: 52, color: "#FFFFFF", x: "50%", y: "45%", align: center, stroke: "#3E1C00", stroke_width: 3, animate: riseIn(0.8s)
15
+
16
+ [-] = video xai.imagine(
17
+ "Premium lifestyle product shot of " + product_name + " chocolate milk in 250ml carton, cinematic lighting, 9:16 vertical",
18
+ aspect_ratio: "9:16",
19
+ duration: 6
20
+ )
21
+
22
+ [8s .. 11s] = text cta_text, font: "Bebas Neue", size: 48, color: "#FFD700", x: "50%", y: "80%", align: center, stroke: "#3E1C00", stroke_width: 4, animate: fadeIn(0.8s)
23
+
24
+ [0s .. 12s] = filter "vignette", intensity: 0.3
25
+
26
+ output to "product-promo.mp4", resolution: "1080x1920", fps: 30
27
+ ```
28
+
29
+ For clips you already have (no xAI), start from `examples/system/product-launch.vid` instead.
@@ -0,0 +1,95 @@
1
+ # VidScript v2 — Strict Agent Reference
2
+
3
+ Follow these rules exactly. When in doubt, copy a file from `examples/system/` (installed with `scenerok skills install`).
4
+
5
+ ## Rule 1: Plugin imports are mandatory
6
+
7
+ ```vidscript
8
+ import xai from "@scenerok/xai"
9
+ ```
10
+
11
+ Without this line, `xai.imagine`, `xai.tts`, and animation helpers like `fadeIn` fail validation.
12
+
13
+ **Never** call `video xai.imagine(...)` or `animate: fadeIn(...)` without the import above.
14
+
15
+ ## Rule 2: Put plugin calls directly in time blocks
16
+
17
+ ```vidscript
18
+ [-] = video xai.imagine("Prompt here", aspect_ratio: "9:16", duration: 5)
19
+ [-] = audio xai.tts("Voiceover line", voice: "eve")
20
+ ```
21
+
22
+ **Never** assign plugins to variables: `let clip = xai.imagine(...)` is invalid.
23
+
24
+ ## Rule 3: Time ranges use `..`
25
+
26
+ ```vidscript
27
+ [0s .. 5s] = text "Hello"
28
+ ```
29
+
30
+ Not `[0s - 5s]`.
31
+
32
+ ## Rule 4: Text params stay on one line
33
+
34
+ ```vidscript
35
+ [0.5s .. 3s] = text "Headline", font: "Inter", size: 64, color: "#FFFFFF", x: "50%", y: "30%", align: center
36
+ ```
37
+
38
+ ## Rule 5: Quote safety in prompts
39
+
40
+ Use only straight `"` inside `xai.imagine("...")`. Do not nest quotes inside the prompt string (e.g. avoid `"RokMilk"` inside the prompt — say `labeled RokMilk` without extra quotes).
41
+
42
+ ## Rule 6: Audio syntax
43
+
44
+ ```vidscript
45
+ [-] = audio xai.tts("Spoken line", voice: "eve", speed: 1.0)
46
+ ```
47
+
48
+ **Invalid:** `audio music("...", duration: 15), volume: 0.35` — trailing `, volume` after a plugin call is a parse error.
49
+
50
+ Music/generative audio plugins require their own `import` when available; do not invent bare `music(...)` calls.
51
+
52
+ ## Rule 7: Filters
53
+
54
+ ```vidscript
55
+ [0s .. 15s] = filter "vignette", intensity: 0.3
56
+ [0s .. 15s] = filter "saturation", value: 1.12
57
+ ```
58
+
59
+ `saturation` uses `value`, not `intensity`.
60
+
61
+ ## Rule 8: Always end with output
62
+
63
+ ```vidscript
64
+ output to "video.mp4", resolution: "1080x1920", fps: 30
65
+ ```
66
+
67
+ Do **not** use legacy `config { }` blocks — they are not part of VidScript v2.
68
+
69
+ ## Animations (after import)
70
+
71
+ ```vidscript
72
+ [0s .. 2s] = text "Launch", x: "50%", y: "50%", animate: popIn(0.7s)
73
+ ```
74
+
75
+ Available: `fadeIn`, `fadeOut`, `slideX`, `slideY`, `popIn`, `riseIn`, `swingIn`, `glitchIn`, `float`, `typewriter`.
76
+
77
+ ## Validate before render
78
+
79
+ ```bash
80
+ scenerok validate my-video.vid
81
+ ```
82
+
83
+ Each error line includes `Line N:C — message` when the server returns location info.
84
+
85
+ ## Bundled examples
86
+
87
+ | File | Use case |
88
+ |------|----------|
89
+ | `minimal-text-reel.vid` | Text-only, no API keys |
90
+ | `product-launch.vid` | User video input + text + vignette |
91
+ | `ecom-product-launch.vid` | xAI product visuals + CTA |
92
+ | `3-tips-fitness.vid` | Multiple `[-]` blocks + xAI per segment |
93
+ | `rokmilk-chocolate-promo.vid` | 15s generated-video promo pattern |
94
+
95
+ Full grammar: https://scenerok.com/docs/vidscript