@vibeo/cli 0.3.5 → 0.4.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AA8NA,eAAO,MAAM,cAAc,UAAyB,CAAC;AAErD,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA+DjE"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AA8NA,eAAO,MAAM,cAAc,UAAyB,CAAC;AAErD,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAgEjE"}
@@ -232,6 +232,7 @@ export async function createProject(name, template) {
232
232
  dev: "bun vibeo preview --entry src/index.tsx",
233
233
  build: "bun vibeo render --entry src/index.tsx",
234
234
  list: "bun vibeo list --entry src/index.tsx",
235
+ editor: "bun vibeo editor --entry src/index.tsx",
235
236
  typecheck: "bunx tsc --noEmit",
236
237
  },
237
238
  dependencies: {
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function startEditor(entry: string, port: number): Promise<void>;
2
+ //# sourceMappingURL=editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/commands/editor.ts"],"names":[],"mappings":"AAAA,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB5E"}
@@ -0,0 +1,18 @@
1
+ export async function startEditor(entry, port) {
2
+ console.log(`Starting editor server...`);
3
+ console.log(` Entry: ${entry}`);
4
+ const { bundleForEditor } = await import("@vibeo/renderer");
5
+ const bundleResult = await bundleForEditor(entry, port);
6
+ console.log(`\n Editor running at ${bundleResult.url}`);
7
+ console.log(` Press Ctrl+C to stop\n`);
8
+ const shutdown = async () => {
9
+ console.log("\nShutting down editor server...");
10
+ await bundleResult.cleanup();
11
+ process.exit(0);
12
+ };
13
+ process.on("SIGINT", shutdown);
14
+ process.on("SIGTERM", shutdown);
15
+ // Block forever
16
+ await new Promise(() => { });
17
+ }
18
+ //# sourceMappingURL=editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/commands/editor.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,IAAY;IAC3D,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC;IAEjC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC5D,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAExD,OAAO,CAAC,GAAG,CAAC,yBAAyB,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAExC,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhC,gBAAgB;IAChB,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AAC9B,CAAC"}
@@ -6,7 +6,7 @@ import { homedir } from "node:os";
6
6
  // ---------------------------------------------------------------------------
7
7
  // Skill loader — resolves from the CLI package's own skills/ directory
8
8
  // ---------------------------------------------------------------------------
9
- const SKILL_NAMES = ["vibeo-core", "vibeo-audio", "vibeo-effects", "vibeo-extras", "vibeo-rendering"];
9
+ const SKILL_NAMES = ["vibeo-core", "vibeo-audio", "vibeo-effects", "vibeo-extras", "vibeo-rendering", "vibeo-editor", "vibeo-tiktok"];
10
10
  async function loadSkills() {
11
11
  // Resolve from this file's location — skills/ is shipped alongside dist/ in the npm package
12
12
  const thisFile = fileURLToPath(import.meta.url);
@@ -1 +1 @@
1
- {"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../../src/commands/install-skills.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../../src/commands/install-skills.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { startPreview } from "./commands/preview.js";
6
6
  import { listCompositions } from "./commands/list.js";
7
7
  import { renderVideo } from "./commands/render.js";
8
8
  import { installSkills } from "./commands/install-skills.js";
9
+ // editor imported lazily to avoid crashing when @vibeo/renderer doesn't have bundleForEditor
9
10
  const cli = Cli.create("vibeo", {
10
11
  description: "React-based programmatic video framework CLI",
11
12
  sync: {
@@ -102,6 +103,20 @@ cli.command("list", {
102
103
  return { compositions };
103
104
  },
104
105
  });
106
+ cli.command("editor", {
107
+ description: "Open the visual video editor in the browser",
108
+ options: z.object({
109
+ entry: z.string().describe("Path to the root file with compositions"),
110
+ port: z.number().default(3001).describe("Port for the editor server"),
111
+ }),
112
+ examples: [
113
+ { options: { entry: "src/index.tsx" }, description: "Open editor on default port" },
114
+ ],
115
+ async run(c) {
116
+ const { startEditor } = await import("./commands/editor.js");
117
+ await startEditor(resolve(c.options.entry), c.options.port);
118
+ },
119
+ });
105
120
  cli.command("install-skills", {
106
121
  description: "Install Vibeo skill/rule files for all supported LLM coding tools (Claude, Codex, Cursor, Gemini, OpenCode, Aider)",
107
122
  options: z.object({
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeo/cli",
3
- "version": "0.3.5",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -230,65 +230,124 @@ actualDuration = floor(duration / playbackRate)
230
230
 
231
231
  ---
232
232
 
233
- ## Common Patterns
233
+ ## Platform Format Presets
234
234
 
235
- ### Creating a basic composition
235
+ Use these when the user mentions a platform. **Any time the user says "Short", "Reel", "TikTok", or "vertical" — use 1080x1920 (9:16), not landscape.**
236
236
 
237
- ```tsx
238
- import { Composition, Sequence, useCurrentFrame, interpolate, easeInOut } from "@vibeo/core";
237
+ | Format | Width | Height | FPS | Max Duration | Aliases |
238
+ |--------|-------|--------|-----|-------------|---------|
239
+ | **YouTube** | 1920 | 1080 | 30 | — | landscape, standard |
240
+ | **YouTube 4K** | 3840 | 2160 | 30-60 | — | 4K |
241
+ | **YouTube Short** | 1080 | 1920 | 30-60 | 3 min | vertical |
242
+ | **TikTok** | 1080 | 1920 | 30 | 10 min | |
243
+ | **Instagram Reel** | 1080 | 1920 | 30 | 20 min | |
244
+ | **Instagram Post** | 1080 | 1080 | 30 | 60s | square |
245
+ | **Twitter/X** | 1920 | 1080 | 30 | 2m 20s | 512MB max |
246
+ | **Twitter/X Short** | 1080 | 1920 | 30 | 2m 20s | vertical tweet |
239
247
 
240
- function MyScene() {
241
- const frame = useCurrentFrame();
242
- const opacity = interpolate(frame, [0, 30], [0, 1], { easing: easeInOut });
243
- return <div style={{ opacity }}>Hello Vibeo</div>;
244
- }
248
+ ### Vertical video (9:16) layout tips
245
249
 
246
- // Register in a VibeoRoot
247
- <Composition
248
- id="MyScene"
249
- component={MyScene}
250
- width={1920}
251
- height={1080}
252
- fps={30}
253
- durationInFrames={150}
254
- />
250
+ - **Code blocks**: max ~900px wide, font size 24-28 (larger than landscape)
251
+ - **No side-by-side**: use top/bottom stacks, not left/right splits
252
+ - **Text**: minimum 36px body, 64px+ titles
253
+ - **Safe zones**: avoid top 100px (status bar) and bottom 150px (nav gestures)
254
+ - **Single focus**: one idea per screen, no multi-column layouts
255
+
256
+ ---
257
+
258
+ ## Common Patterns
259
+
260
+ ### Multi-file project structure (use for 3+ scenes)
261
+
262
+ ```
263
+ src/
264
+ ├── index.tsx # Root + Composition registration
265
+ ├── Video.tsx # Scene orchestrator (Sequences)
266
+ ├── scenes/
267
+ │ ├── Intro.tsx
268
+ │ ├── Problem.tsx
269
+ │ ├── Solution.tsx
270
+ │ └── Outro.tsx
271
+ └── components/
272
+ ├── CodeBlock.tsx
273
+ └── AnimatedCard.tsx
255
274
  ```
256
275
 
257
- ### Using Sequence for scene structure
276
+ ### Centralized scene timing (best practice)
277
+
278
+ Define all timing in one place — never hardcode frame numbers in `<Sequence>`:
258
279
 
259
280
  ```tsx
281
+ const SCENES = {
282
+ intro: { from: 0, duration: 120 },
283
+ problem: { from: 120, duration: 300 },
284
+ solution: { from: 420, duration: 450 },
285
+ outro: { from: 870, duration: 90 },
286
+ } as const;
287
+
288
+ const TOTAL = SCENES.outro.from + SCENES.outro.duration;
289
+
260
290
  function MyVideo() {
261
291
  return (
262
292
  <>
263
- <Sequence from={0} durationInFrames={60}>
293
+ <Sequence from={SCENES.intro.from} durationInFrames={SCENES.intro.duration}>
264
294
  <IntroScene />
265
295
  </Sequence>
266
- <Sequence from={60} durationInFrames={90}>
267
- <MainScene />
268
- </Sequence>
269
- <Sequence from={150} durationInFrames={60}>
270
- <OutroScene />
296
+ <Sequence from={SCENES.problem.from} durationInFrames={SCENES.problem.duration}>
297
+ <ProblemScene />
271
298
  </Sequence>
299
+ {/* ... */}
272
300
  </>
273
301
  );
274
302
  }
275
303
  ```
276
304
 
277
- ### Nesting Loops inside Sequences
305
+ ### Looping/pulsing animation
306
+
307
+ Use `frame % N` for repeating effects (pulse, glow, rotate):
308
+
309
+ ```tsx
310
+ const frame = useCurrentFrame();
311
+ const pulse = interpolate(frame % 60, [0, 30, 60], [0.3, 0.6, 0.3]);
312
+ const rotation = (frame % 90) * 4; // 360° every 3 seconds
313
+ ```
314
+
315
+ ### Staggered list/card animation
316
+
317
+ Animate N items with increasing delay:
318
+
319
+ ```tsx
320
+ const frame = useCurrentFrame();
321
+ const items = ["Feature 1", "Feature 2", "Feature 3"];
322
+
323
+ {items.map((item, i) => {
324
+ const delay = 10 + i * 8;
325
+ const opacity = interpolate(frame, [delay, delay + 20], [0, 1], {
326
+ extrapolateLeft: "clamp", extrapolateRight: "clamp",
327
+ });
328
+ const y = interpolate(frame, [delay, delay + 20], [30, 0], {
329
+ easing: easeOut, extrapolateLeft: "clamp", extrapolateRight: "clamp",
330
+ });
331
+ return <div key={i} style={{ opacity, transform: `translateY(${y}px)` }}>{item}</div>;
332
+ })}
333
+ ```
334
+
335
+ ### Overlapping Sequences for manual transitions
336
+
337
+ Alternative to `<Transition>` when you need custom per-scene blend control:
278
338
 
279
339
  ```tsx
280
- <Sequence from={0} durationInFrames={120}>
281
- <Loop durationInFrames={30} times={4}>
282
- <BouncingBall />
283
- </Loop>
340
+ <Sequence from={0} durationInFrames={90}>
341
+ <SceneA /> {/* fade out in last 15 frames */}
342
+ </Sequence>
343
+ <Sequence from={75} durationInFrames={90}>
344
+ <SceneB /> {/* fade in during first 15 frames */}
284
345
  </Sequence>
285
346
  ```
286
347
 
287
348
  ### Multi-segment interpolation
288
349
 
289
350
  ```tsx
290
- const frame = useCurrentFrame();
291
- // Move right, then back, then down
292
351
  const x = interpolate(frame, [0, 30, 60, 90], [0, 200, 0, 0]);
293
352
  const y = interpolate(frame, [0, 30, 60, 90], [0, 0, 0, 200]);
294
353
  ```
@@ -371,10 +430,13 @@ bunx @vibeo/cli render --schema --token-count
371
430
 
372
431
  ### How LLMs Should Use Vibeo
373
432
 
374
- 1. **Discover commands**: Run `bunx @vibeo/cli --llms` to get the command manifest
375
- 2. **Create a project**: `bunx @vibeo/cli create my-video --template basic`
376
- 3. **Edit `src/index.tsx`**: Write React components using `@vibeo/core` hooks and components
377
- 4. **Preview**: `bunx @vibeo/cli preview --entry src/index.tsx`
378
- 5. **Render**: `bunx @vibeo/cli render --entry src/index.tsx --composition MyComp`
433
+ 1. **Create a project**: `bunx @vibeo/cli create my-video --template basic`
434
+ 2. **Install deps**: `cd my-video && bun install`
435
+ 3. **Install Playwright** (required for render/list): `bunx playwright install chromium`
436
+ 4. **Edit `src/index.tsx`**: Write React components using `@vibeo/core` hooks and components
437
+ 5. **Preview**: `bunx @vibeo/cli preview --entry src/index.tsx`
438
+ 6. **Render**: `bunx @vibeo/cli render --entry src/index.tsx --composition MyComp`
439
+
440
+ Step 3 is mandatory — `vibeo render` and `vibeo list` will fail without Playwright browsers installed.
379
441
 
380
442
  All commands accept `--format json` for structured output that LLMs can parse reliably.
@@ -0,0 +1,348 @@
1
+ # Vibeo Editor (`@vibeo/editor`)
2
+
3
+ ## Overview
4
+
5
+ `@vibeo/editor` is a visual video editing studio for Vibeo. It provides a dark-themed, multi-track timeline editor with canvas preview, property editing, drag-and-drop clip manipulation, audio waveforms, subtitle editing, and export controls.
6
+
7
+ **When to use**: When you need a visual editing interface for Vibeo compositions, or when building a custom video editor UI on top of Vibeo.
8
+
9
+ ---
10
+
11
+ ## Quick Start
12
+
13
+ ### CLI (recommended)
14
+
15
+ ```bash
16
+ # Open the editor for a Vibeo project
17
+ bunx @vibeo/cli editor --entry src/index.tsx
18
+
19
+ # With custom port
20
+ bunx @vibeo/cli editor --entry src/index.tsx --port 8080
21
+ ```
22
+
23
+ In a scaffolded project (`bunx @vibeo/cli create my-video`), just run:
24
+
25
+ ```bash
26
+ bun run editor
27
+ ```
28
+
29
+ ### Programmatic
30
+
31
+ ```tsx
32
+ import { Editor } from "@vibeo/editor";
33
+
34
+ const compositions = [
35
+ {
36
+ id: "MyComp",
37
+ name: "My Composition",
38
+ component: MyVideoComponent,
39
+ width: 1920,
40
+ height: 1080,
41
+ fps: 30,
42
+ durationInFrames: 300,
43
+ },
44
+ ];
45
+
46
+ function App() {
47
+ return <Editor compositions={compositions} />;
48
+ }
49
+ ```
50
+
51
+ ---
52
+
53
+ ## API Reference
54
+
55
+ ### `Editor`
56
+
57
+ The root editor component. Renders the full editor UI.
58
+
59
+ ```tsx
60
+ <Editor compositions={compositions} />
61
+ ```
62
+
63
+ **Props:**
64
+ - `compositions` — Array of composition entries:
65
+ - `id: string` — unique composition identifier
66
+ - `name: string` — display name
67
+ - `component: React.ComponentType` — the React component to render
68
+ - `width: number` — composition width in pixels
69
+ - `height: number` — composition height in pixels
70
+ - `fps: number` — frames per second
71
+ - `durationInFrames: number` — total duration in frames
72
+
73
+ ### `EditorProvider`
74
+
75
+ Context provider wrapping the editor state. Use if you need to embed editor components individually.
76
+
77
+ ```tsx
78
+ import { EditorProvider } from "@vibeo/editor";
79
+
80
+ <EditorProvider>
81
+ {/* editor components */}
82
+ </EditorProvider>
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Editor Layout
88
+
89
+ ```
90
+ ┌─────────────────────────────────────────────────────────────┐
91
+ │ Toolbar: [⟲ Undo] [⟳ Redo] CompositionName 100% │
92
+ ├──────────┬─────────────────────────────────┬────────────────┤
93
+ │ SCENES │ │ PROPERTIES │
94
+ │ & TRACKS │ Canvas Preview │ Canvas: W × H │
95
+ │ │ (live composition with │ Duration: N │
96
+ │ 🎬 Scene1│ checkerboard background) │ FPS: 30 │
97
+ │ 🎵 Audio │ │ │
98
+ │ 📝 Subs │ │ EXPORT │
99
+ │ │ │ Codec: H.264 │
100
+ │ [+Add] ├──── |◀ ▶ ▶| 00:00 / 03:33 1x ──│ [Render video] │
101
+ ├──────────┴─────────────────────────────────┴────────────────┤
102
+ │ Timeline: ruler with time markers [- zoom +] │
103
+ │ Track 1: [████ Scene A ████][████ Scene B ████] │
104
+ │ Track 2: [████████ Audio Track ████████] │
105
+ │ Track 3: [Sub1] [Sub2] [Sub3] │
106
+ │ ▲ playhead cursor (draggable) │
107
+ └─────────────────────────────────────────────────────────────┘
108
+ ```
109
+
110
+ ### Panels
111
+
112
+ | Panel | Location | Purpose |
113
+ |-------|----------|---------|
114
+ | Toolbar | Top | Undo/redo, composition name, zoom % |
115
+ | Scene List | Left sidebar | Track list with visibility/mute toggles, "+ Add Track" |
116
+ | Canvas | Center top | Live preview of active composition |
117
+ | Playback Controls | Center middle | Play/pause, frame step, timecode, rate, loop |
118
+ | Timeline | Center bottom | Multi-track clip editor with ruler and playhead |
119
+ | Properties | Right sidebar | Editable props for selected clip, composition info, export |
120
+
121
+ All panels are resizable via drag handles between them.
122
+
123
+ ---
124
+
125
+ ## State Management
126
+
127
+ The editor uses `useReducer` with an immutable state model and undo/redo history.
128
+
129
+ ### EditorState
130
+
131
+ ```ts
132
+ interface EditorState {
133
+ tracks: Track[];
134
+ selectedTrackId: string | null;
135
+ selectedClipId: string | null;
136
+ playing: boolean;
137
+ frame: number;
138
+ fps: number;
139
+ durationInFrames: number;
140
+ compositionWidth: number;
141
+ compositionHeight: number;
142
+ playbackRate: number;
143
+ zoom: number;
144
+ scrollX: number;
145
+ }
146
+ ```
147
+
148
+ ### Track & Clip Types
149
+
150
+ ```ts
151
+ type TrackType = "scene" | "audio" | "subtitle";
152
+
153
+ interface Track {
154
+ id: string;
155
+ name: string;
156
+ type: TrackType;
157
+ clips: Clip[];
158
+ visible: boolean;
159
+ muted: boolean;
160
+ }
161
+
162
+ interface Clip {
163
+ id: string;
164
+ trackId: string;
165
+ name: string;
166
+ from: number; // start frame
167
+ durationInFrames: number;
168
+ type: TrackType;
169
+ data: any; // type-specific data
170
+ }
171
+ ```
172
+
173
+ ### Actions
174
+
175
+ | Action | Description |
176
+ |--------|-------------|
177
+ | `ADD_TRACK` | Add a new track (scene/audio/subtitle) |
178
+ | `REMOVE_TRACK` | Remove a track and all its clips |
179
+ | `ADD_CLIP` | Add a clip to a track |
180
+ | `REMOVE_CLIP` | Remove a clip |
181
+ | `MOVE_CLIP` | Change a clip's `from` position |
182
+ | `RESIZE_CLIP` | Change a clip's `from` and/or `durationInFrames` |
183
+ | `SELECT_CLIP` | Select a clip (highlights in timeline, shows in properties) |
184
+ | `SET_FRAME` | Set the current playhead frame |
185
+ | `SET_PLAYING` | Toggle playback |
186
+ | `SET_ZOOM` | Set timeline zoom level |
187
+ | `UNDO` | Undo last action |
188
+ | `REDO` | Redo undone action |
189
+
190
+ ---
191
+
192
+ ## Timeline
193
+
194
+ ### Clip Colors
195
+
196
+ | Type | Color | Hex |
197
+ |------|-------|-----|
198
+ | Scene | Purple | `#8b5cf6` |
199
+ | Audio | Green | `#22c55e` |
200
+ | Subtitle | Yellow | `#eab308` |
201
+
202
+ ### Timeline Math
203
+
204
+ ```
205
+ pixelsPerFrame = basePixelsPerFrame * zoom (base = 2)
206
+ clipLeft = clip.from * pixelsPerFrame
207
+ clipWidth = clip.durationInFrames * pixelsPerFrame
208
+ cursorLeft = currentFrame * pixelsPerFrame
209
+ totalWidth = durationInFrames * pixelsPerFrame
210
+ ```
211
+
212
+ ### Drag-and-Drop
213
+
214
+ - **Move clip**: drag the clip body to change its `from` position
215
+ - **Resize clip**: drag left/right edges to trim `from`/`durationInFrames`
216
+ - **Minimum**: 1 frame
217
+ - **Snap**: rounds to nearest integer frame
218
+
219
+ ---
220
+
221
+ ## Keyboard Shortcuts
222
+
223
+ | Key | Action |
224
+ |-----|--------|
225
+ | Space | Play / Pause |
226
+ | ArrowLeft | Previous frame |
227
+ | ArrowRight | Next frame |
228
+ | Shift+ArrowLeft | -10 frames |
229
+ | Shift+ArrowRight | +10 frames |
230
+ | Cmd/Ctrl+Z | Undo |
231
+ | Cmd/Ctrl+Shift+Z | Redo |
232
+ | Delete / Backspace | Remove selected clip |
233
+ | Escape | Deselect |
234
+ | ? | Show keyboard shortcuts |
235
+
236
+ ---
237
+
238
+ ## Dark Theme
239
+
240
+ All colors are defined in `@vibeo/editor/theme/colors`:
241
+
242
+ | Token | Value | Usage |
243
+ |-------|-------|-------|
244
+ | `bg` | `#0d1117` | Darkest background |
245
+ | `surface` | `#161b22` | Panel backgrounds |
246
+ | `surfaceHover` | `#1c2333` | Hover states |
247
+ | `border` | `#30363d` | Borders |
248
+ | `text` | `#e6edf3` | Primary text |
249
+ | `textMuted` | `#7d8590` | Secondary text |
250
+ | `accent` | `#58a6ff` | Playhead, selection, focus rings |
251
+ | `scene` | `#8b5cf6` | Scene clip color |
252
+ | `audio` | `#22c55e` | Audio clip color |
253
+ | `subtitle` | `#eab308` | Subtitle clip color |
254
+ | `danger` | `#f85149` | Delete, errors |
255
+
256
+ ---
257
+
258
+ ## Common Patterns
259
+
260
+ ### Adding a scene track with a clip
261
+
262
+ ```ts
263
+ dispatch({ type: "ADD_TRACK", payload: { id: "track-1", name: "Main Scene", type: "scene" } });
264
+ dispatch({
265
+ type: "ADD_CLIP",
266
+ payload: {
267
+ id: "clip-1",
268
+ trackId: "track-1",
269
+ name: "Intro",
270
+ from: 0,
271
+ durationInFrames: 90,
272
+ type: "scene",
273
+ data: { component: IntroScene },
274
+ },
275
+ });
276
+ ```
277
+
278
+ ### Adding an audio track
279
+
280
+ ```ts
281
+ dispatch({ type: "ADD_TRACK", payload: { id: "track-2", name: "Background Music", type: "audio" } });
282
+ dispatch({
283
+ type: "ADD_CLIP",
284
+ payload: {
285
+ id: "clip-2",
286
+ trackId: "track-2",
287
+ name: "Music",
288
+ from: 0,
289
+ durationInFrames: 300,
290
+ type: "audio",
291
+ data: { src: "/music.mp3", volume: 0.8 },
292
+ },
293
+ });
294
+ ```
295
+
296
+ ### Adding subtitle cues
297
+
298
+ ```ts
299
+ dispatch({ type: "ADD_TRACK", payload: { id: "track-3", name: "Subtitles", type: "subtitle" } });
300
+ dispatch({
301
+ type: "ADD_CLIP",
302
+ payload: {
303
+ id: "sub-1",
304
+ trackId: "track-3",
305
+ name: "Welcome",
306
+ from: 15,
307
+ durationInFrames: 75,
308
+ type: "subtitle",
309
+ data: { text: "Welcome to the demo", fontSize: 36, color: "white", position: "bottom" },
310
+ },
311
+ });
312
+ ```
313
+
314
+ ---
315
+
316
+ ## Gotchas
317
+
318
+ 1. **Editor creates its own providers** — it wraps content in `VibeoRoot`, `TimelineProvider`, etc. Don't nest it inside another `VibeoRoot` manually.
319
+
320
+ 2. **Compositions must export a `Root` function** — the CLI editor command imports `{ Root }` from your entry file to register compositions.
321
+
322
+ 3. **The editor renders the Player internally** — it uses `@vibeo/player` to show the canvas preview. Frame sync is handled automatically.
323
+
324
+ 4. **Undo/redo is state-level** — every dispatched action pushes to the history stack. `UNDO`/`REDO` actions navigate the stack.
325
+
326
+ 5. **Timeline zoom range** — 0.1x to 10x. Default is 1x where `pixelsPerFrame = 2`.
327
+
328
+ 6. **Audio waveform** — rendered as canvas bars inside audio clips. If audio analysis isn't available, shows flat placeholder bars.
329
+
330
+ 7. **Subtitle inline editing** — double-click a subtitle cue in the timeline to edit text inline. Press Escape or click outside to save.
331
+
332
+ ---
333
+
334
+ ## LLM & Agent Integration
335
+
336
+ ```bash
337
+ # Get CLI docs including editor command
338
+ bunx @vibeo/cli --llms
339
+
340
+ # Get editor command schema
341
+ bunx @vibeo/cli editor --schema
342
+
343
+ # Install skills for all LLM tools
344
+ bunx @vibeo/cli install-skills
345
+
346
+ # Run as MCP server (includes editor command)
347
+ bunx @vibeo/cli --mcp
348
+ ```
@@ -218,24 +218,27 @@ const scale = useKeyframes(frame, { 0: 1, 15: 1.2, 30: 1 }, { easing: easeInOut
218
218
 
219
219
  ## Spring Animation Guide
220
220
 
221
- ### Snappy UI motion
222
- ```ts
223
- useSpring({ from: 0, to: 1, config: { stiffness: 300, damping: 30 } })
224
- ```
221
+ ### Named Spring Presets
225
222
 
226
- ### Bouncy entrance
227
- ```ts
228
- useSpring({ from: 0, to: 1, config: { stiffness: 400, damping: 10, mass: 1 } })
229
- ```
223
+ | Name | stiffness | damping | mass | Use case |
224
+ |------|-----------|---------|------|----------|
225
+ | **snappy** | 300 | 30 | 1 | UI elements, quick responses |
226
+ | **bouncy** | 400 | 10 | 1 | Playful entrances, logos |
227
+ | **gentle** | 100 | 26 | 1 | Subtle movements, text |
228
+ | **heavy** | 50 | 20 | 3 | Large elements, dramatic reveals |
229
+ | **elastic** | 200 | 8 | 1 | Overshoot effects, attention grabbers |
230
230
 
231
- ### Slow, heavy drag
232
231
  ```ts
232
+ // Snappy
233
+ useSpring({ from: 0, to: 1, config: { stiffness: 300, damping: 30, mass: 1 } })
234
+ // Bouncy
235
+ useSpring({ from: 0, to: 1, config: { stiffness: 400, damping: 10, mass: 1 } })
236
+ // Gentle
237
+ useSpring({ from: 0, to: 1, config: { stiffness: 100, damping: 26, mass: 1 } })
238
+ // Heavy
233
239
  useSpring({ from: 0, to: 1, config: { stiffness: 50, damping: 20, mass: 3 } })
234
- ```
235
-
236
- ### Gentle ease
237
- ```ts
238
- useSpring({ from: 0, to: 1, config: { stiffness: 100, damping: 26 } })
240
+ // Elastic
241
+ useSpring({ from: 0, to: 1, config: { stiffness: 200, damping: 8, mass: 1 } })
239
242
  ```
240
243
 
241
244
  **Tuning guide**:
@@ -349,6 +352,151 @@ function ReactiveBackground({ children }: { children: React.ReactNode }) {
349
352
 
350
353
  ---
351
354
 
355
+ ## CodeBlock Recipe (for developer/tutorial content)
356
+
357
+ The most common component in programming videos. Takes a plain string + optional highlight words:
358
+
359
+ ```tsx
360
+ function CodeBlock({
361
+ code,
362
+ highlights = [],
363
+ fontSize = 24,
364
+ startFrame = 0,
365
+ lineDelay = 3,
366
+ }: {
367
+ code: string;
368
+ highlights?: { word: string; color: string }[];
369
+ fontSize?: number;
370
+ startFrame?: number;
371
+ lineDelay?: number;
372
+ }) {
373
+ const frame = useCurrentFrame();
374
+ const lines = code.split("\n");
375
+
376
+ return (
377
+ <div style={{
378
+ background: "#1e1e2e",
379
+ borderRadius: 12,
380
+ padding: "24px 32px",
381
+ fontFamily: "'SF Mono', 'Cascadia Code', monospace",
382
+ fontSize,
383
+ lineHeight: 1.6,
384
+ overflow: "hidden",
385
+ }}>
386
+ {lines.map((line, i) => {
387
+ const lineFrame = startFrame + i * lineDelay;
388
+ const opacity = interpolate(frame, [lineFrame, lineFrame + 10], [0, 1], {
389
+ extrapolateLeft: "clamp", extrapolateRight: "clamp",
390
+ });
391
+
392
+ let html = line.replace(/&/g, "&amp;").replace(/</g, "&lt;");
393
+ for (const h of highlights) {
394
+ html = html.replaceAll(h.word, `<span style="color:${h.color}">${h.word}</span>`);
395
+ }
396
+
397
+ return (
398
+ <div key={i} style={{ opacity, whiteSpace: "pre" }} dangerouslySetInnerHTML={{ __html: html || "&nbsp;" }} />
399
+ );
400
+ })}
401
+ </div>
402
+ );
403
+ }
404
+
405
+ // Usage:
406
+ <CodeBlock
407
+ code={`function Foo() {\n return <div>hello</div>;\n}`}
408
+ highlights={[{ word: "function", color: "#c678dd" }, { word: "return", color: "#c678dd" }]}
409
+ startFrame={10}
410
+ />
411
+ ```
412
+
413
+ ---
414
+
415
+ ## SVG Animation Recipes
416
+
417
+ ### Spring-scale an SVG (logo entrance)
418
+
419
+ ```tsx
420
+ function AnimatedLogo() {
421
+ const frame = useCurrentFrame();
422
+ const scale = useSpring({ from: 0, to: 1, frame, fps: 30, config: { stiffness: 400, damping: 10 } });
423
+ const rotation = interpolate(frame, [0, 30], [180, 0], { extrapolateRight: "clamp" });
424
+
425
+ return (
426
+ <svg width={200} height={200} style={{
427
+ transform: `scale(${scale}) rotate(${rotation}deg)`,
428
+ filter: `drop-shadow(0 0 ${20 * scale}px rgba(97, 218, 251, 0.6))`,
429
+ }}>
430
+ {/* SVG content */}
431
+ </svg>
432
+ );
433
+ }
434
+ ```
435
+
436
+ ### Rotating SVG with glow
437
+
438
+ ```tsx
439
+ const frame = useCurrentFrame();
440
+ const rotation = (frame % 90) * 4; // full rotation every 3s at 30fps
441
+ const glowIntensity = interpolate(frame % 60, [0, 30, 60], [10, 25, 10]);
442
+
443
+ <svg style={{
444
+ transform: `rotate(${rotation}deg)`,
445
+ filter: `drop-shadow(0 0 ${glowIntensity}px cyan)`,
446
+ }} />
447
+ ```
448
+
449
+ ---
450
+
451
+ ## Split-Screen / Comparison Layout
452
+
453
+ Before/after code comparison — common in tutorial content:
454
+
455
+ ```tsx
456
+ function SplitScreen({
457
+ left,
458
+ right,
459
+ dividerLabel = "VS",
460
+ }: {
461
+ left: React.ReactNode;
462
+ right: React.ReactNode;
463
+ dividerLabel?: string;
464
+ }) {
465
+ const frame = useCurrentFrame();
466
+ const { width, height } = useVideoConfig();
467
+
468
+ // Stagger: left appears first, divider, then right
469
+ const leftOpacity = interpolate(frame, [0, 15], [0, 1], { extrapolateRight: "clamp" });
470
+ const rightOpacity = interpolate(frame, [20, 35], [0, 1], { extrapolateRight: "clamp" });
471
+ const dividerOpacity = interpolate(frame, [10, 20], [0, 1], { extrapolateRight: "clamp" });
472
+
473
+ return (
474
+ <div style={{ display: "flex", width, height }}>
475
+ <div style={{ flex: 1, opacity: leftOpacity, padding: 40 }}>{left}</div>
476
+ <div style={{
477
+ width: 60, display: "flex", alignItems: "center", justifyContent: "center",
478
+ opacity: dividerOpacity, color: "#888", fontSize: 20, fontWeight: 700,
479
+ }}>
480
+ {dividerLabel}
481
+ </div>
482
+ <div style={{ flex: 1, opacity: rightOpacity, padding: 40 }}>{right}</div>
483
+ </div>
484
+ );
485
+ }
486
+ ```
487
+
488
+ For vertical video (9:16), stack top/bottom instead of left/right:
489
+
490
+ ```tsx
491
+ <div style={{ display: "flex", flexDirection: "column", width, height }}>
492
+ <div style={{ flex: 1 }}>{before}</div>
493
+ <div style={{ height: 4, background: "#333" }} />
494
+ <div style={{ flex: 1 }}>{after}</div>
495
+ </div>
496
+ ```
497
+
498
+ ---
499
+
352
500
  ## Gotchas and Tips
353
501
 
354
502
  1. **`useAudioData` returns `null` initially** — always handle the loading state.
@@ -355,10 +355,13 @@ bunx @vibeo/cli render --schema --token-count
355
355
 
356
356
  ### How LLMs Should Use Vibeo
357
357
 
358
- 1. **Discover commands**: Run `bunx @vibeo/cli --llms` to get the command manifest
359
- 2. **Create a project**: `bunx @vibeo/cli create my-video --template basic`
360
- 3. **Edit `src/index.tsx`**: Write React components using `@vibeo/core` hooks and components
361
- 4. **Preview**: `bunx @vibeo/cli preview --entry src/index.tsx`
362
- 5. **Render**: `bunx @vibeo/cli render --entry src/index.tsx --composition MyComp`
358
+ 1. **Create a project**: `bunx @vibeo/cli create my-video --template basic`
359
+ 2. **Install deps**: `cd my-video && bun install`
360
+ 3. **Install Playwright** (REQUIRED for render/list): `bunx playwright install chromium`
361
+ 4. **Edit `src/index.tsx`**: Write React components using `@vibeo/core` hooks and components
362
+ 5. **Preview**: `bunx @vibeo/cli preview --entry src/index.tsx`
363
+ 6. **Render**: `bunx @vibeo/cli render --entry src/index.tsx --composition MyComp`
364
+
365
+ **Step 3 is mandatory** — `vibeo render` and `vibeo list` will fail with a cryptic Playwright error without it. `vibeo preview` works without it (uses Bun.serve, not Playwright).
363
366
 
364
367
  All commands accept `--format json` for structured output that LLMs can parse reliably.
@@ -0,0 +1,319 @@
1
+ # Vibeo TikTok / Short-Form Video Generator
2
+
3
+ Generate TikTok, YouTube Shorts, Instagram Reels, and other vertical (9:16) videos using Vibeo.
4
+
5
+ **Trigger**: user says "TikTok", "Short", "Reel", "vertical video", "short-form", or asks for content for social media platforms.
6
+
7
+ ---
8
+
9
+ ## Format: ALWAYS 1080x1920 (9:16)
10
+
11
+ ```tsx
12
+ <Composition
13
+ id="MyTikTok"
14
+ component={TikTokVideo}
15
+ width={1080}
16
+ height={1920}
17
+ fps={30}
18
+ durationInFrames={450} // 15 seconds
19
+ />
20
+ ```
21
+
22
+ ### Duration Guidelines
23
+
24
+ | Platform | Sweet Spot | Max | Frames @ 30fps |
25
+ |----------|-----------|-----|-----------------|
26
+ | **TikTok** | 15-60s | 10 min | 450-1800 |
27
+ | **YouTube Short** | 30-60s | 3 min | 900-1800 |
28
+ | **Instagram Reel** | 15-30s | 20 min | 450-900 |
29
+ | **Twitter/X** | 15-45s | 2m20s | 450-1350 |
30
+
31
+ ---
32
+
33
+ ## Vertical Layout Rules
34
+
35
+ ### DO
36
+
37
+ ```tsx
38
+ // Stack vertically — top to bottom flow
39
+ <div style={{
40
+ width: 1080, height: 1920,
41
+ display: "flex", flexDirection: "column",
42
+ justifyContent: "center", alignItems: "center",
43
+ padding: "100px 60px 150px", // safe zones: top status bar + bottom nav
44
+ }}>
45
+ <h1 style={{ fontSize: 72, textAlign: "center" }}>Title</h1>
46
+ <div style={{ marginTop: 40 }}>
47
+ {/* Content */}
48
+ </div>
49
+ </div>
50
+ ```
51
+
52
+ ### DON'T
53
+
54
+ - No side-by-side layouts (too narrow at 1080px)
55
+ - No font size < 36px (unreadable on phones)
56
+ - No content in top 100px (status bar) or bottom 150px (nav gestures)
57
+ - No multi-column grids
58
+ - No landscape aspect ratios embedded inside
59
+
60
+ ---
61
+
62
+ ## Complete TikTok Template
63
+
64
+ Hook → Content → CTA pattern (the standard viral format):
65
+
66
+ ```tsx
67
+ import React from "react";
68
+ import {
69
+ Composition, Sequence, VibeoRoot,
70
+ useCurrentFrame, useVideoConfig, interpolate, easeOut, easeInOut,
71
+ } from "@vibeo/core";
72
+
73
+ // ---- Scene Timing (centralized) ----
74
+ const SCENES = {
75
+ hook: { from: 0, duration: 90 }, // 3s — attention grabber
76
+ content: { from: 90, duration: 270 }, // 9s — main content
77
+ cta: { from: 360, duration: 90 }, // 3s — call to action
78
+ } as const;
79
+ const TOTAL = 450; // 15s
80
+
81
+ // ---- Hook Scene (first 3 seconds = make or break) ----
82
+ function HookScene({ text }: { text: string }) {
83
+ const frame = useCurrentFrame();
84
+ const { width, height } = useVideoConfig();
85
+
86
+ const scale = interpolate(frame, [0, 15], [0.5, 1], {
87
+ easing: easeOut, extrapolateRight: "clamp",
88
+ });
89
+ const opacity = interpolate(frame, [0, 10], [0, 1], { extrapolateRight: "clamp" });
90
+
91
+ // Pulsing glow effect
92
+ const glow = interpolate(frame % 30, [0, 15, 30], [0, 15, 0]);
93
+
94
+ return (
95
+ <div style={{
96
+ width, height, display: "flex", justifyContent: "center", alignItems: "center",
97
+ background: "linear-gradient(180deg, #0a0a0a, #1a0a2e)",
98
+ padding: "100px 60px 150px",
99
+ }}>
100
+ <h1 style={{
101
+ fontSize: 80, fontWeight: 900, color: "white",
102
+ textAlign: "center", lineHeight: 1.2,
103
+ opacity, transform: `scale(${scale})`,
104
+ textShadow: `0 0 ${glow}px rgba(138, 92, 246, 0.8)`,
105
+ }}>
106
+ {text}
107
+ </h1>
108
+ </div>
109
+ );
110
+ }
111
+
112
+ // ---- Content Scene (staggered points) ----
113
+ function ContentScene({ points }: { points: string[] }) {
114
+ const frame = useCurrentFrame();
115
+ const { width, height } = useVideoConfig();
116
+
117
+ return (
118
+ <div style={{
119
+ width, height, display: "flex", flexDirection: "column",
120
+ justifyContent: "center", padding: "100px 60px 150px",
121
+ background: "#0a0a0a", gap: 24,
122
+ }}>
123
+ {points.map((point, i) => {
124
+ const delay = 15 + i * 20;
125
+ const opacity = interpolate(frame, [delay, delay + 15], [0, 1], {
126
+ extrapolateLeft: "clamp", extrapolateRight: "clamp",
127
+ });
128
+ const x = interpolate(frame, [delay, delay + 15], [-40, 0], {
129
+ easing: easeOut, extrapolateLeft: "clamp", extrapolateRight: "clamp",
130
+ });
131
+
132
+ return (
133
+ <div key={i} style={{
134
+ opacity, transform: `translateX(${x}px)`,
135
+ display: "flex", alignItems: "center", gap: 16,
136
+ }}>
137
+ <div style={{
138
+ width: 48, height: 48, borderRadius: 12,
139
+ background: "linear-gradient(135deg, #8b5cf6, #06b6d4)",
140
+ display: "flex", alignItems: "center", justifyContent: "center",
141
+ fontSize: 24, fontWeight: 700, color: "white",
142
+ }}>
143
+ {i + 1}
144
+ </div>
145
+ <span style={{ fontSize: 40, color: "white", fontWeight: 600 }}>
146
+ {point}
147
+ </span>
148
+ </div>
149
+ );
150
+ })}
151
+ </div>
152
+ );
153
+ }
154
+
155
+ // ---- CTA Scene ----
156
+ function CTAScene({ text, subtext }: { text: string; subtext: string }) {
157
+ const frame = useCurrentFrame();
158
+ const { width, height } = useVideoConfig();
159
+
160
+ const scale = interpolate(frame, [0, 20], [0.8, 1], {
161
+ easing: easeOut, extrapolateRight: "clamp",
162
+ });
163
+ // Pulsing button effect
164
+ const btnScale = interpolate(frame % 30, [0, 15, 30], [1, 1.05, 1]);
165
+
166
+ return (
167
+ <div style={{
168
+ width, height, display: "flex", flexDirection: "column",
169
+ justifyContent: "center", alignItems: "center",
170
+ background: "linear-gradient(180deg, #0a0a0a, #1a0a2e)",
171
+ padding: "100px 60px 150px", transform: `scale(${scale})`,
172
+ }}>
173
+ <h1 style={{ fontSize: 72, fontWeight: 900, color: "white", textAlign: "center" }}>
174
+ {text}
175
+ </h1>
176
+ <div style={{
177
+ marginTop: 40, padding: "20px 60px", borderRadius: 50,
178
+ background: "linear-gradient(135deg, #8b5cf6, #06b6d4)",
179
+ fontSize: 36, fontWeight: 700, color: "white",
180
+ transform: `scale(${btnScale})`,
181
+ }}>
182
+ {subtext}
183
+ </div>
184
+ </div>
185
+ );
186
+ }
187
+
188
+ // ---- Main Video ----
189
+ function TikTokVideo() {
190
+ return (
191
+ <>
192
+ <Sequence from={SCENES.hook.from} durationInFrames={SCENES.hook.duration}>
193
+ <HookScene text="3 things you didn't know about React" />
194
+ </Sequence>
195
+ <Sequence from={SCENES.content.from} durationInFrames={SCENES.content.duration}>
196
+ <ContentScene points={[
197
+ "Server Components are default",
198
+ "use() replaces useEffect",
199
+ "Actions replace forms",
200
+ ]} />
201
+ </Sequence>
202
+ <Sequence from={SCENES.cta.from} durationInFrames={SCENES.cta.duration}>
203
+ <CTAScene text="Follow for more" subtext="Like & Share →" />
204
+ </Sequence>
205
+ </>
206
+ );
207
+ }
208
+
209
+ // ---- Root ----
210
+ export function Root() {
211
+ return (
212
+ <VibeoRoot>
213
+ <Composition
214
+ id="TikTokVideo"
215
+ component={TikTokVideo}
216
+ width={1080}
217
+ height={1920}
218
+ fps={30}
219
+ durationInFrames={TOTAL}
220
+ />
221
+ </VibeoRoot>
222
+ );
223
+ }
224
+ ```
225
+
226
+ ---
227
+
228
+ ## TikTok Content Patterns
229
+
230
+ ### 1. "Did You Know" / Listicle (most common)
231
+
232
+ ```
233
+ Hook (3s): Bold question or surprising claim
234
+ Content (9-20s): 3-5 staggered points with numbers
235
+ CTA (3s): Follow / Like / Share
236
+ ```
237
+
238
+ ### 2. Before/After
239
+
240
+ ```
241
+ Hook (2s): "Before vs After"
242
+ Before (5s): Show the "bad" version (top half)
243
+ After (5s): Reveal the "good" version (bottom half) — use slide transition
244
+ CTA (3s): "Try it yourself"
245
+ ```
246
+
247
+ For vertical before/after, stack top/bottom:
248
+ ```tsx
249
+ <div style={{ display: "flex", flexDirection: "column", width: 1080, height: 1920 }}>
250
+ <div style={{ flex: 1 }}>{before}</div>
251
+ <div style={{ height: 4, background: "#333" }} />
252
+ <div style={{ flex: 1 }}>{after}</div>
253
+ </div>
254
+ ```
255
+
256
+ ### 3. Code Tutorial
257
+
258
+ ```
259
+ Hook (3s): "This one trick..."
260
+ Code (10-15s): Animated code block, line by line reveal
261
+ Result (5s): Show the output/demo
262
+ CTA (3s): "Link in bio"
263
+ ```
264
+
265
+ Use the CodeBlock recipe from vibeo-effects skill, but with larger font (28px) for vertical.
266
+
267
+ ### 4. Product/Feature Showcase
268
+
269
+ ```
270
+ Hook (3s): Pain point question
271
+ Demo (10s): Screen recording or animated mockup
272
+ Features (5s): 3 key bullets, staggered
273
+ CTA (3s): "Download now"
274
+ ```
275
+
276
+ ---
277
+
278
+ ## Animation Rules for Short-Form
279
+
280
+ 1. **First 3 seconds are everything** — the hook must grab attention immediately. Use scale-in, glow, or spring entrance.
281
+
282
+ 2. **Constant motion** — never have a static frame for more than 1 second. Add subtle pulse, breathing, or background movement.
283
+
284
+ 3. **Text on screen** — most viewers watch without sound. Every key point should have on-screen text.
285
+
286
+ 4. **Fast transitions** — 10-15 frame transitions (0.3-0.5s). No slow fades.
287
+
288
+ 5. **Pulsing/breathing effects** — use `frame % N` for constant subtle animation:
289
+ ```tsx
290
+ const pulse = interpolate(frame % 60, [0, 30, 60], [1, 1.03, 1]);
291
+ ```
292
+
293
+ 6. **Number badges** — always number your points (1, 2, 3). It signals structure and keeps viewers watching.
294
+
295
+ 7. **Bold gradients** — dark backgrounds with vibrant gradient accents. Avoid flat solid colors.
296
+
297
+ ---
298
+
299
+ ## Rendering for Platforms
300
+
301
+ ```bash
302
+ # TikTok / Reels (H.264, most compatible)
303
+ bunx @vibeo/cli render --entry src/index.tsx --composition TikTokVideo --codec h264
304
+
305
+ # High quality (H.265, smaller file)
306
+ bunx @vibeo/cli render --entry src/index.tsx --composition TikTokVideo --codec h265
307
+
308
+ # Twitter/X (needs smaller file, use lower quality)
309
+ bunx @vibeo/cli render --entry src/index.tsx --composition TikTokVideo --codec h264 --quality 60
310
+ ```
311
+
312
+ ### Platform upload limits
313
+
314
+ | Platform | Max File Size | Recommended Codec |
315
+ |----------|--------------|-------------------|
316
+ | TikTok | 287 MB | H.264 |
317
+ | YouTube Shorts | 256 MB | H.264 |
318
+ | Instagram Reels | 650 MB | H.264 |
319
+ | Twitter/X | 512 MB | H.264 |
@@ -246,6 +246,7 @@ export async function createProject(
246
246
  dev: "bun vibeo preview --entry src/index.tsx",
247
247
  build: "bun vibeo render --entry src/index.tsx",
248
248
  list: "bun vibeo list --entry src/index.tsx",
249
+ editor: "bun vibeo editor --entry src/index.tsx",
249
250
  typecheck: "bunx tsc --noEmit",
250
251
  },
251
252
  dependencies: {
@@ -0,0 +1,22 @@
1
+ export async function startEditor(entry: string, port: number): Promise<void> {
2
+ console.log(`Starting editor server...`);
3
+ console.log(` Entry: ${entry}`);
4
+
5
+ const { bundleForEditor } = await import("@vibeo/renderer");
6
+ const bundleResult = await bundleForEditor(entry, port);
7
+
8
+ console.log(`\n Editor running at ${bundleResult.url}`);
9
+ console.log(` Press Ctrl+C to stop\n`);
10
+
11
+ const shutdown = async () => {
12
+ console.log("\nShutting down editor server...");
13
+ await bundleResult.cleanup();
14
+ process.exit(0);
15
+ };
16
+
17
+ process.on("SIGINT", shutdown);
18
+ process.on("SIGTERM", shutdown);
19
+
20
+ // Block forever
21
+ await new Promise(() => {});
22
+ }
@@ -8,7 +8,7 @@ import { homedir } from "node:os";
8
8
  // Skill loader — resolves from the CLI package's own skills/ directory
9
9
  // ---------------------------------------------------------------------------
10
10
 
11
- const SKILL_NAMES = ["vibeo-core", "vibeo-audio", "vibeo-effects", "vibeo-extras", "vibeo-rendering"];
11
+ const SKILL_NAMES = ["vibeo-core", "vibeo-audio", "vibeo-effects", "vibeo-extras", "vibeo-rendering", "vibeo-editor", "vibeo-tiktok"];
12
12
 
13
13
  async function loadSkills(): Promise<Record<string, string>> {
14
14
  // Resolve from this file's location — skills/ is shipped alongside dist/ in the npm package
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ import { startPreview } from "./commands/preview.js";
6
6
  import { listCompositions } from "./commands/list.js";
7
7
  import { renderVideo } from "./commands/render.js";
8
8
  import { installSkills } from "./commands/install-skills.js";
9
+ // editor imported lazily to avoid crashing when @vibeo/renderer doesn't have bundleForEditor
9
10
 
10
11
  const cli = Cli.create("vibeo", {
11
12
  description: "React-based programmatic video framework CLI",
@@ -108,6 +109,21 @@ cli.command("list", {
108
109
  },
109
110
  });
110
111
 
112
+ cli.command("editor", {
113
+ description: "Open the visual video editor in the browser",
114
+ options: z.object({
115
+ entry: z.string().describe("Path to the root file with compositions"),
116
+ port: z.number().default(3001).describe("Port for the editor server"),
117
+ }),
118
+ examples: [
119
+ { options: { entry: "src/index.tsx" }, description: "Open editor on default port" },
120
+ ],
121
+ async run(c) {
122
+ const { startEditor } = await import("./commands/editor.js");
123
+ await startEditor(resolve(c.options.entry), c.options.port);
124
+ },
125
+ });
126
+
111
127
  cli.command("install-skills", {
112
128
  description:
113
129
  "Install Vibeo skill/rule files for all supported LLM coding tools (Claude, Codex, Cursor, Gemini, OpenCode, Aider)",