@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.
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +9 -34
- package/package.json +3 -2
- package/skills/{aider → shared}/SKILL.md +31 -10
- package/skills/{claude → shared}/vidscript-guide.md +32 -3
- package/skills/{claude → shared}/vidscript-sample.md +1 -1
- package/skills/{codex → shared}/vidscript-strict.md +53 -8
- package/skills/aider/vidscript-guide.md +0 -383
- package/skills/aider/vidscript-sample.md +0 -30
- package/skills/aider/vidscript-strict.md +0 -113
- package/skills/claude/SKILL.md +0 -194
- package/skills/claude/vidscript-strict.md +0 -113
- package/skills/codex/SKILL.md +0 -194
- package/skills/codex/vidscript-guide.md +0 -383
- package/skills/codex/vidscript-sample.md +0 -30
- package/skills/cursor/SKILL.md +0 -194
- package/skills/cursor/vidscript-guide.md +0 -383
- package/skills/cursor/vidscript-sample.md +0 -30
- package/skills/cursor/vidscript-strict.md +0 -113
- package/skills/opencode/SKILL.md +0 -194
- package/skills/opencode/vidscript-guide.md +0 -383
- package/skills/opencode/vidscript-sample.md +0 -30
- package/skills/opencode/vidscript-strict.md +0 -113
- package/skills/skills/aider/SKILL.md +0 -194
- package/skills/skills/aider/vidscript-guide.md +0 -383
- package/skills/skills/aider/vidscript-sample.md +0 -30
- package/skills/skills/aider/vidscript-strict.md +0 -113
- package/skills/skills/claude/SKILL.md +0 -194
- package/skills/skills/claude/vidscript-guide.md +0 -383
- package/skills/skills/claude/vidscript-sample.md +0 -30
- package/skills/skills/claude/vidscript-strict.md +0 -113
- package/skills/skills/codex/SKILL.md +0 -194
- package/skills/skills/codex/vidscript-guide.md +0 -383
- package/skills/skills/codex/vidscript-sample.md +0 -30
- package/skills/skills/codex/vidscript-strict.md +0 -113
- package/skills/skills/cursor/SKILL.md +0 -194
- package/skills/skills/cursor/vidscript-guide.md +0 -383
- package/skills/skills/cursor/vidscript-sample.md +0 -30
- package/skills/skills/cursor/vidscript-strict.md +0 -113
- package/skills/skills/opencode/SKILL.md +0 -194
- package/skills/skills/opencode/vidscript-guide.md +0 -383
- package/skills/skills/opencode/vidscript-sample.md +0 -30
- 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;
|
|
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"}
|
package/dist/commands/skills.js
CHANGED
|
@@ -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
|
|
64
|
-
const modulePath = join(dirname(new URL(import.meta.url).pathname), '
|
|
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
|
|
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.
|
|
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
|
-
"
|
|
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
|
|
10
|
+
# SceneRok Agent Skill
|
|
11
11
|
|
|
12
12
|
## Overview
|
|
13
13
|
|
|
14
|
-
You are a VidScript composer and video generation expert integrated with
|
|
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
|
|
121
|
-
4. **
|
|
122
|
-
5. **
|
|
123
|
-
6. **
|
|
124
|
-
7. **
|
|
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
|
|
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. **
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
122
|
+
## Rule 10: Always end with output
|
|
78
123
|
|
|
79
124
|
```vidscript
|
|
80
125
|
output to "video.mp4", resolution: "1080x1920", fps: 30
|