@scenerok/cli 1.0.8 → 1.0.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 (43) hide show
  1. package/dist/commands/skills.d.ts.map +1 -1
  2. package/dist/commands/skills.js +9 -34
  3. package/package.json +3 -2
  4. package/skills/{aider → shared}/SKILL.md +31 -10
  5. package/skills/{claude → shared}/vidscript-guide.md +32 -3
  6. package/skills/{claude → shared}/vidscript-sample.md +1 -1
  7. package/skills/{codex → shared}/vidscript-strict.md +53 -8
  8. package/skills/aider/vidscript-guide.md +0 -383
  9. package/skills/aider/vidscript-sample.md +0 -30
  10. package/skills/aider/vidscript-strict.md +0 -113
  11. package/skills/claude/SKILL.md +0 -194
  12. package/skills/claude/vidscript-strict.md +0 -113
  13. package/skills/codex/SKILL.md +0 -194
  14. package/skills/codex/vidscript-guide.md +0 -383
  15. package/skills/codex/vidscript-sample.md +0 -30
  16. package/skills/cursor/SKILL.md +0 -194
  17. package/skills/cursor/vidscript-guide.md +0 -383
  18. package/skills/cursor/vidscript-sample.md +0 -30
  19. package/skills/cursor/vidscript-strict.md +0 -113
  20. package/skills/opencode/SKILL.md +0 -194
  21. package/skills/opencode/vidscript-guide.md +0 -383
  22. package/skills/opencode/vidscript-sample.md +0 -30
  23. package/skills/opencode/vidscript-strict.md +0 -113
  24. package/skills/skills/aider/SKILL.md +0 -194
  25. package/skills/skills/aider/vidscript-guide.md +0 -383
  26. package/skills/skills/aider/vidscript-sample.md +0 -30
  27. package/skills/skills/aider/vidscript-strict.md +0 -113
  28. package/skills/skills/claude/SKILL.md +0 -194
  29. package/skills/skills/claude/vidscript-guide.md +0 -383
  30. package/skills/skills/claude/vidscript-sample.md +0 -30
  31. package/skills/skills/claude/vidscript-strict.md +0 -113
  32. package/skills/skills/codex/SKILL.md +0 -194
  33. package/skills/skills/codex/vidscript-guide.md +0 -383
  34. package/skills/skills/codex/vidscript-sample.md +0 -30
  35. package/skills/skills/codex/vidscript-strict.md +0 -113
  36. package/skills/skills/cursor/SKILL.md +0 -194
  37. package/skills/skills/cursor/vidscript-guide.md +0 -383
  38. package/skills/skills/cursor/vidscript-sample.md +0 -30
  39. package/skills/skills/cursor/vidscript-strict.md +0 -113
  40. package/skills/skills/opencode/SKILL.md +0 -194
  41. package/skills/skills/opencode/vidscript-guide.md +0 -383
  42. package/skills/skills/opencode/vidscript-sample.md +0 -30
  43. package/skills/skills/opencode/vidscript-strict.md +0 -113
@@ -1 +1 @@
1
- {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/commands/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkIpC,eAAO,MAAM,aAAa,SA4DvB,CAAC"}
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/commands/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwGpC,eAAO,MAAM,aAAa,SA4DvB,CAAC"}
@@ -4,64 +4,39 @@ import { existsSync, copyFileSync, mkdirSync, readdirSync } from 'node:fs';
4
4
  import { join, dirname } from 'node:path';
5
5
  import { homedir } from 'node:os';
6
6
  function getPlatformConfig(platform) {
7
- const cwd = process.cwd();
8
7
  const configs = {
9
8
  opencode: {
10
9
  name: 'OpenCode',
11
10
  skillDir: join(homedir(), '.agents/skills/scenerok'),
12
- files: [
13
- { source: 'skills/opencode/SKILL.md', dest: 'SKILL.md' },
14
- { source: 'skills/opencode/vidscript-guide.md', dest: 'vidscript-guide.md' },
15
- { source: 'skills/opencode/vidscript-sample.md', dest: 'vidscript-sample.md' },
16
- { source: 'skills/opencode/vidscript-strict.md', dest: 'vidscript-strict.md' },
17
- ],
18
11
  },
19
12
  claude: {
20
13
  name: 'Claude Code',
21
14
  skillDir: join(homedir(), '.claude/skills/scenerok'),
22
- files: [
23
- { source: 'skills/claude/SKILL.md', dest: 'SKILL.md' },
24
- { source: 'skills/claude/vidscript-guide.md', dest: 'vidscript-guide.md' },
25
- { source: 'skills/claude/vidscript-sample.md', dest: 'vidscript-sample.md' },
26
- { source: 'skills/claude/vidscript-strict.md', dest: 'vidscript-strict.md' },
27
- ],
28
15
  },
29
16
  codex: {
30
17
  name: 'Codex',
31
18
  skillDir: join(homedir(), '.codex/skills/scenerok'),
32
- files: [
33
- { source: 'skills/codex/SKILL.md', dest: 'SKILL.md' },
34
- { source: 'skills/codex/vidscript-guide.md', dest: 'vidscript-guide.md' },
35
- { source: 'skills/codex/vidscript-sample.md', dest: 'vidscript-sample.md' },
36
- { source: 'skills/codex/vidscript-strict.md', dest: 'vidscript-strict.md' },
37
- ],
38
19
  },
39
20
  cursor: {
40
21
  name: 'Cursor',
41
22
  skillDir: join(homedir(), '.cursor/skills/scenerok'),
42
- files: [
43
- { source: 'skills/cursor/SKILL.md', dest: 'SKILL.md' },
44
- { source: 'skills/cursor/vidscript-guide.md', dest: 'vidscript-guide.md' },
45
- { source: 'skills/cursor/vidscript-sample.md', dest: 'vidscript-sample.md' },
46
- { source: 'skills/cursor/vidscript-strict.md', dest: 'vidscript-strict.md' },
47
- ],
48
23
  },
49
24
  aider: {
50
25
  name: 'Aider',
51
26
  skillDir: join(homedir(), '.aider/skills/scenerok'),
52
- files: [
53
- { source: 'skills/aider/SKILL.md', dest: 'SKILL.md' },
54
- { source: 'skills/aider/vidscript-guide.md', dest: 'vidscript-guide.md' },
55
- { source: 'skills/aider/vidscript-sample.md', dest: 'vidscript-sample.md' },
56
- { source: 'skills/aider/vidscript-strict.md', dest: 'vidscript-strict.md' },
57
- ],
58
27
  },
59
28
  };
60
29
  return configs[platform] || null;
61
30
  }
31
+ const sharedSkillFiles = [
32
+ 'SKILL.md',
33
+ 'vidscript-guide.md',
34
+ 'vidscript-sample.md',
35
+ 'vidscript-strict.md',
36
+ ].map((name) => ({ source: `skills/shared/${name}`, dest: name }));
62
37
  async function findSkillSource(sourcePath) {
63
- // Check relative to node_modules/@scenerok/cli (scoped package)
64
- const modulePath = join(dirname(new URL(import.meta.url).pathname), '../../../..', sourcePath);
38
+ // Check relative to the installed @scenerok/cli package.
39
+ const modulePath = join(dirname(new URL(import.meta.url).pathname), '../..', sourcePath);
65
40
  if (existsSync(modulePath))
66
41
  return modulePath;
67
42
  // Check relative to CWD
@@ -127,7 +102,7 @@ export const skillsCommand = new Command('skills')
127
102
  if (!existsSync(config.skillDir)) {
128
103
  mkdirSync(config.skillDir, { recursive: true });
129
104
  }
130
- for (const file of config.files) {
105
+ for (const file of sharedSkillFiles) {
131
106
  const source = await findSkillSource(file.source);
132
107
  const dest = join(config.skillDir, file.dest);
133
108
  if (!source) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scenerok/cli",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "SceneRok CLI - Create videos from your terminal and agent workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,7 +16,8 @@
16
16
  "scripts": {
17
17
  "build": "tsc",
18
18
  "dev": "tsc --watch",
19
- "prepublishOnly": "npm run build"
19
+ "sync:skills": "node ../../scripts/sync-scenerok-skills.mjs",
20
+ "prepublishOnly": "npm run sync:skills && npm run build"
20
21
  },
21
22
  "keywords": [
22
23
  "scenerok",
@@ -7,11 +7,11 @@ description: >-
7
7
  SceneRok, scenerok CLI, or terminal/agent video generation.
8
8
  ---
9
9
 
10
- # SceneRok Skill for Aider
10
+ # SceneRok Agent Skill
11
11
 
12
12
  ## Overview
13
13
 
14
- You are a VidScript composer and video generation expert integrated with Aider. You help users create video content using the SceneRok platform directly from their terminal.
14
+ You are a VidScript composer and video generation expert integrated with your agent. You help users create video content using the SceneRok platform directly from their terminal.
15
15
 
16
16
  ## Capabilities
17
17
 
@@ -21,6 +21,7 @@ You are a VidScript composer and video generation expert integrated with Aider.
21
21
  - Check render status and retrieve output
22
22
  - Guide users through video creation workflows
23
23
  - Fill template placeholders and customize system templates
24
+ - When the user gives a product or website URL, use available browser or screenshot tools to capture real site visuals for VidScript assets
24
25
 
25
26
  ## VidScript Language
26
27
 
@@ -28,7 +29,7 @@ VidScript is a declarative language for describing video compositions using time
28
29
 
29
30
  ### Core Concepts
30
31
 
31
- **Inputs** - Declare video sources:
32
+ **Inputs** - Declare video/image sources:
32
33
  ```vidscript
33
34
  input hero = "https://cdn.example.com/hero.mp4"
34
35
  input logo = "/uploads/logo.png"
@@ -91,7 +92,7 @@ import xai from "@scenerok/xai"
91
92
  import eleven from "@elevenlabs/music"
92
93
  import motion from "@scenerok/basic-animations"
93
94
 
94
- [-] = video xai.imagine("Cinematic product shot", aspect_ratio: "9:16", duration: 5)
95
+ [-] = video xai.imagine("Cinematic product shot, premium lighting, no text, no words, no letters, no captions, no logos, no watermark, no readable UI copy", aspect_ratio: "9:16", duration: 5)
95
96
  [-] = audio xai.tts("Welcome to SceneRok", voice: "eve")
96
97
 
97
98
  # ElevenLabs music package functions require an import alias.
@@ -117,17 +118,37 @@ input hero = "{{hero_clip}}"
117
118
 
118
119
  1. **Understand the goal** — What video does the user want? (promo, testimonial, meme, etc.)
119
120
  2. **Plan the structure** — Time blocks, durations, inputs
120
- 3. **Gather assets** — Video URLs or local paths
121
- 4. **Compose VidScript** — Write the full script
122
- 5. **Validate** — Run `scenerok validate script.vid`
123
- 6. **Render** — Run `scenerok render script.vid --watch`
124
- 7. **Deliver** — Share the download URL when complete
121
+ 3. **Gather assets** — Video URLs, local paths, or captured website screenshots/images; when the user provides a URL, use browser screenshot capability if available
122
+ 4. **Probe asset dimensions** — Inspect every local or downloaded image/video before placing it. Use `ffprobe` for video/audio, `sips -g pixelWidth -g pixelHeight file` on macOS images, or `identify file` when ImageMagick is available.
123
+ 5. **Compose VidScript** — Write the full script using measured dimensions, aspect-ratio-preserving scale, centered/safe-area placement, and entry/exit animation beats for each visual asset
124
+ 6. **Validate** — Run `scenerok validate script.vid`
125
+ 7. **Render** — Run `scenerok render script.vid --watch`
126
+ 8. **Deliver** — Share the download URL when complete
127
+
128
+ ## Website URL Asset Workflow
129
+
130
+ When the user provides a product, company, landing page, app store listing, or ecommerce URL, treat the site as the primary visual source for the video.
131
+
132
+ 1. Visit the URL with an available browser tool before composing the final VidScript.
133
+ 2. Capture screenshots of useful page states: hero section, product detail, pricing or offer section, testimonials, checkout/app preview, and any visual proof points.
134
+ 3. Detect and save usable product images, app screenshots, brand marks, and logos from the page when available. Prefer direct image assets only when they are accessible and clearly match the product; otherwise use browser screenshots.
135
+ 4. Probe saved asset dimensions before composing. Record width, height, aspect ratio, and duration if video; never guess dimensions from filenames or screenshots.
136
+ 5. Use those screenshots or images as VidScript input assets and build the ad from real product visuals. Crop, resize, overlay text, add filters, and sequence them into a promo.
137
+ 6. Scale assets from their measured aspect ratio to fit the output frame and safe areas. For 1080x1920 ads, keep primary visuals inside roughly 80-88% of frame width and reserve enough top/bottom room for text.
138
+ 7. Animate visual assets intentionally: use entry animations such as `motion.popIn`, `motion.riseIn`, or `motion.slideY`; use short exit fade/slide segments when a clean transition is needed. For static plates, split the asset into a main segment and a final 0.4-0.7s segment with `motion.fadeOut(...)` to create a real exit.
139
+ 8. Use generative visuals such as `xai.imagine` only as a fallback, background texture, transition, or supplemental shot when real website assets are missing, low quality, or the user explicitly asks for generated footage.
140
+ 9. For every generated visual prompt, explicitly require a clean scene with no text, no words, no letters, no captions, no logos, no watermarks, and no readable UI copy. AI video generation often corrupts text; all final titles, offers, captions, CTAs, prices, and labels must be created with VidScript `text` primitives.
141
+ 10. Do not invent product claims. Extract copy, pricing, feature names, social proof, and CTA language from the site or ask the user.
125
142
 
126
143
  ## Best Practices
127
144
 
128
145
  - **Use dynamic timeblocks** — `[-]` auto-advances the cursor, reducing calculation errors
129
146
  - **Use `prev` for offsets** — `[prev + 0.5s .. prev + 2s]` for gaps between content
130
147
  - **Named arguments for clarity** — `hero.Trim(start: 0s, end: 5s)` over `hero.Trim(0s, 5s)`
148
+ - **Prefer real website assets for URL-based ads** — browser screenshots, product images, app screenshots, and logos should come before fully generative clips
149
+ - **Probe before placing** — get exact dimensions for every real asset, calculate scale from aspect ratio, and set `width`, `height`, `x`, and `y` explicitly
150
+ - **Animate assets, not only text** — give product screenshots/logos/cards a clear entrance and a clean exit; split static visuals into main and fade-out segments if needed
151
+ - **Keep generated media text-free** — prompts for AI-generated images/videos must explicitly say no text, no words, no letters, no captions, no logos, no watermarks, and no readable UI copy; add all final copy with VidScript `text` primitives
131
152
  - Use 1080x1920 for vertical content (TikTok/Instagram)
132
153
  - Use 1920x1080 for horizontal content (YouTube)
133
154
  - Hook viewers in the first 3 seconds
@@ -167,7 +188,7 @@ If a render fails:
167
188
  Always ask clarifying questions about:
168
189
  - Target platform (TikTok, Instagram, YouTube, etc.)
169
190
  - Brand colors and fonts
170
- - Existing assets (video clips, logo, etc.)
191
+ - Existing assets, product URLs, browser-captured screenshots, logos, and page images
171
192
  - Desired duration and style
172
193
  - Whether they want to start from a template or from scratch
173
194
 
@@ -8,7 +8,11 @@ VidScript is a declarative DSL for composing short-form videos. Write a script,
8
8
  2. **Validate early** — `scenerok validate file.vid` (errors show as `Line N:C — message`).
9
9
  3. **Music package syntax** — `import eleven from "@elevenlabs/music"`, then call `eleven.music(...)`, `eleven.generateMusic(...)`, or `eleven.composeMusic(...)`.
10
10
  4. **Copy working examples** — see `examples/system/` in this skill folder (e.g. `minimal-text-reel.vid`, `ecom-product-launch.vid`, `rokmilk-chocolate-promo.vid`).
11
- 5. **Strict rules** — see `vidscript-strict.md` for invalid patterns (bare `xai.imagine`, bare `eleven.music(...)` without import, trailing params after direct plugin calls, nested quotes in prompts).
11
+ 5. **URL assets first** — if the user gives a website or product URL and browser screenshot tools are available, capture real page screenshots, product images, app screenshots, and logos for VidScript `input` assets before using generated visuals.
12
+ 6. **Probe asset dimensions** — before placing real assets, inspect width, height, and duration with `ffprobe`, `sips`, or `identify`; then scale from the measured aspect ratio and set explicit `width`, `height`, `x`, and `y`.
13
+ 7. **Animate real assets** — visual inputs should have entry motion and, where transitions matter, an exit beat. For static plates, split into a main segment and a short final `motion.fadeOut(...)` segment.
14
+ 8. **Generated media has no text** — prompts for AI-generated images/videos must explicitly ask for no text, no words, no letters, no captions, no logos, no watermarks, and no readable UI copy. Use VidScript `text` primitives for all final copy.
15
+ 9. **Strict rules** — see `vidscript-strict.md` for invalid patterns (bare `xai.imagine`, bare `eleven.music(...)` without import, trailing params after direct plugin calls, nested quotes in prompts).
12
16
 
13
17
  ### Common validation failures
14
18
 
@@ -39,7 +43,28 @@ input hero = "https://cdn.example.com/hero.mp4"
39
43
  input logo = "./assets/logo.png"
40
44
  ```
41
45
 
42
- Supports HTTP(S) URLs, `/uploads/` paths, and local paths.
46
+ Supports HTTP(S) URLs, `/uploads/` paths, and local paths for video/image assets.
47
+
48
+ For ads based on a supplied URL, use browser tools to capture real website screenshots and save product images or logos when available. Declare those files as inputs and use them in the composition before reaching for generated clips.
49
+
50
+ After declaring or downloading assets, probe dimensions before placing them:
51
+
52
+ ```bash
53
+ ffprobe -v error -select_streams v:0 -show_entries stream=width,height,duration -of csv=p=0 asset.mp4
54
+ sips -g pixelWidth -g pixelHeight asset.png
55
+ identify asset.webp
56
+ ```
57
+
58
+ Use the measured width and height to preserve aspect ratio. For a 1080x1920 vertical ad, a common centered fit is:
59
+
60
+ ```text
61
+ scaledWidth = min(assetWidth * scale, 900)
62
+ scaledHeight = scaledWidth / (assetWidth / assetHeight)
63
+ x = (1080 - scaledWidth) / 2
64
+ y = chosen safe-area top offset
65
+ ```
66
+
67
+ Do not guess asset size. Tiny logos, wide screenshots, and tall app screenshots need different scale and placement.
43
68
 
44
69
  ### Output Declaration
45
70
 
@@ -233,7 +258,7 @@ import xai from "@scenerok/xai"
233
258
  import eleven from "@elevenlabs/music"
234
259
  import motion from "@scenerok/basic-animations"
235
260
 
236
- [-] = video xai.imagine("Cinematic product shot", aspect_ratio: "9:16", duration: 5)
261
+ [-] = video xai.imagine("Cinematic product shot, premium lighting, no text, no words, no letters, no captions, no logos, no watermark, no readable UI copy", aspect_ratio: "9:16", duration: 5)
237
262
  [-] = audio xai.tts("Welcome to SceneRok", voice: "eve")
238
263
 
239
264
  # ElevenLabs music package functions require an import alias.
@@ -272,6 +297,10 @@ import motion from "@scenerok/basic-animations"
272
297
 
273
298
  [-] = video hero, animate: [motion.fadeIn(0.5s), motion.slideY(-40, 0, 1.2s)]
274
299
 
300
+ # Static asset with measured 4:3-ish aspect ratio, centered in a vertical 1080x1920 frame.
301
+ [0s .. 3.4s] = video app_screen, width: 760, height: 615, x: 160, y: 300, animate: [motion.riseIn(0.6s, 70), motion.float(2.4s, 8)]
302
+ [3.4s .. 4s] = video app_screen, width: 760, height: 615, x: 160, y: 300, animate: motion.fadeOut(0.6s)
303
+
275
304
  [0s .. 2s] = text "Title", animate: {
276
305
  type: "fade",
277
306
  from: { opacity: 0 },
@@ -15,7 +15,7 @@ input cta_text = "{{cta_text | visit your nearest grocery store}}"
15
15
  [2s .. 4.5s] = text hook_text, font: "Outfit", size: 52, color: "#FFFFFF", x: "50%", y: "45%", align: center, stroke: "#3E1C00", stroke_width: 3, animate: motion.riseIn(0.8s)
16
16
 
17
17
  [-] = video xai.imagine(
18
- "Premium lifestyle product shot of " + product_name + " chocolate milk in 250ml carton, cinematic lighting, 9:16 vertical",
18
+ "Premium lifestyle product shot of " + product_name + " chocolate milk in 250ml carton, cinematic lighting, 9:16 vertical, no text, no words, no letters, no captions, no logos, no watermark, no readable UI copy",
19
19
  aspect_ratio: "9:16",
20
20
  duration: 6
21
21
  )
@@ -14,20 +14,65 @@ Without the owning import, calls like `xai.imagine`, `xai.tts`, `eleven.music`,
14
14
 
15
15
  **Never** call package functions without importing the package alias first.
16
16
 
17
- ## Rule 2: Use registered plugin surfaces
17
+ ## Rule 2: Prefer real URL assets before generative media
18
+
19
+ When the user gives a product, company, ecommerce, landing page, or app URL and you have browser/screenshot capability, visit the page and capture useful screenshots first. Save hero sections, product views, app screenshots, pricing/offer sections, testimonials, and detectable logos or brand marks as local image assets. Use those assets in VidScript `input` declarations and compose the ad around real product visuals.
20
+
21
+ Only use `xai.imagine` or other fully generative visuals when site assets are unavailable, too low quality, needed as background/transition material, or explicitly requested by the user. Do not invent claims; use website copy or ask the user.
22
+
23
+ ## Rule 2.5: Probe real asset dimensions before placement
24
+
25
+ Before writing `width`, `height`, `x`, or `y` for a real image/video/screenshot/logo, inspect the actual asset dimensions and duration:
26
+
27
+ ```bash
28
+ ffprobe -v error -select_streams v:0 -show_entries stream=width,height,duration -of csv=p=0 asset.mp4
29
+ sips -g pixelWidth -g pixelHeight asset.png
30
+ identify asset.webp
31
+ ```
32
+
33
+ Use measured aspect ratio and safe-area math. Do not guess sizes or blindly resize every asset to the same box. Center visuals with explicit pixel placement when possible:
34
+
35
+ ```text
36
+ x = (outputWidth - scaledWidth) / 2
37
+ y = safeAreaTop
38
+ ```
39
+
40
+ Add entry motion to real assets, not only text. When a static visual needs a clean exit, split it:
41
+
42
+ ```vidscript
43
+ import motion from "@scenerok/basic-animations"
44
+
45
+ [0s .. 3.4s] = video product, width: 760, height: 615, x: 160, y: 300, animate: [motion.riseIn(0.6s, 70), motion.float(2.4s, 8)]
46
+ [3.4s .. 4s] = video product, width: 760, height: 615, x: 160, y: 300, animate: motion.fadeOut(0.6s)
47
+ ```
48
+
49
+ ## Rule 3: Generated media prompts must forbid text
50
+
51
+ AI-generated images and videos must not contain readable text. In every prompt for generated visual media, explicitly ask for no text, no words, no letters, no captions, no logos, no watermarks, and no readable UI copy. SceneRok has strong text primitives; all final titles, subtitles, offers, prices, feature labels, disclaimers, and CTAs must be added with VidScript `text` instructions instead of being baked into generated media.
52
+
53
+ Good prompt pattern:
54
+
55
+ ```vidscript
56
+ [-] = video xai.imagine("Clean cinematic product background, premium lighting, no text, no words, no letters, no captions, no logos, no watermark, no readable UI copy", aspect_ratio: "9:16", duration: 5)
57
+ [0.5s .. 3s] = text "Launch offer", style: title, color: "#FFFFFF", x: "50%", y: "30%", stroke: "#000000", stroke_width: 3
58
+ ```
59
+
60
+ Invalid: asking the generator for signs, labels, packaging text, app UI text, title cards, lower thirds, prices, CTA buttons, or any readable copy.
61
+
62
+ ## Rule 4: Use registered plugin surfaces
18
63
 
19
64
  ```vidscript
20
65
  import xai from "@scenerok/xai"
21
66
  import eleven from "@elevenlabs/music"
22
67
 
23
- [-] = video xai.imagine("Prompt here", aspect_ratio: "9:16", duration: 5)
68
+ [-] = video xai.imagine("Prompt here, no text, no words, no letters, no captions, no logos, no watermark, no readable UI copy", aspect_ratio: "9:16", duration: 5)
24
69
  [-] = audio xai.tts("Voiceover line", voice: "eve")
25
70
  [0s .. 15s] = audio eleven.music("Warm premium music bed", duration: 15, instrumental: true)
26
71
  ```
27
72
 
28
73
  For ElevenLabs music, import `@elevenlabs/music` and use `eleven.music(...)`, `eleven.generateMusic(...)`, or `eleven.composeMusic(...)`.
29
74
 
30
- ## Rule 3: Time ranges use `..`
75
+ ## Rule 5: Time ranges use `..`
31
76
 
32
77
  ```vidscript
33
78
  [0s .. 5s] = text "Hello"
@@ -35,17 +80,17 @@ For ElevenLabs music, import `@elevenlabs/music` and use `eleven.music(...)`, `e
35
80
 
36
81
  Not `[0s - 5s]`.
37
82
 
38
- ## Rule 4: Text params stay on one line
83
+ ## Rule 6: Text params stay on one line
39
84
 
40
85
  ```vidscript
41
86
  [0.5s .. 3s] = text "Headline", font: "Inter", size: 64, color: "#FFFFFF", x: "50%", y: "30%", align: center
42
87
  ```
43
88
 
44
- ## Rule 5: Quote safety in prompts
89
+ ## Rule 7: Quote safety in prompts
45
90
 
46
91
  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).
47
92
 
48
- ## Rule 6: Audio syntax
93
+ ## Rule 8: Audio syntax
49
94
 
50
95
  ```vidscript
51
96
  import xai from "@scenerok/xai"
@@ -65,7 +110,7 @@ let bed = eleven.music("Soft premium ad music", duration: 15, instrumental: true
65
110
 
66
111
  **Invalid:** `eleven.generateMusic(...)` without `import eleven from "@elevenlabs/music"`.
67
112
 
68
- ## Rule 7: Filters
113
+ ## Rule 9: Filters
69
114
 
70
115
  ```vidscript
71
116
  [0s .. 15s] = filter "vignette", intensity: 0.3
@@ -74,7 +119,7 @@ let bed = eleven.music("Soft premium ad music", duration: 15, instrumental: true
74
119
 
75
120
  `saturation` uses `value`, not `intensity`.
76
121
 
77
- ## Rule 8: Always end with output
122
+ ## Rule 10: Always end with output
78
123
 
79
124
  ```vidscript
80
125
  output to "video.mp4", resolution: "1080x1920", fps: 30