@vibeo/cli 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/install-skills.d.ts.map +1 -1
- package/dist/commands/install-skills.js +22 -83
- package/dist/commands/install-skills.js.map +1 -1
- package/package.json +2 -1
- package/skills/vibeo-audio/SKILL.md +283 -0
- package/skills/vibeo-core/SKILL.md +380 -0
- package/skills/vibeo-effects/SKILL.md +432 -0
- package/skills/vibeo-extras/SKILL.md +457 -0
- package/skills/vibeo-rendering/SKILL.md +364 -0
- package/src/commands/install-skills.ts +25 -82
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-skills.d.ts","sourceRoot":"","sources":["../../src/commands/install-skills.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"install-skills.d.ts","sourceRoot":"","sources":["../../src/commands/install-skills.ts"],"names":[],"mappings":"AA6JA,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EAAE,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CAAE,CAAC,CAuBlD;AAED,eAAO,MAAM,iBAAiB;;;GAG3B,CAAC"}
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import { join, dirname } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
import { mkdir, writeFile, readFile } from "node:fs/promises";
|
|
3
4
|
import { existsSync } from "node:fs";
|
|
4
5
|
import { homedir } from "node:os";
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
|
-
//
|
|
7
|
+
// Skill loader — resolves from the CLI package's own skills/ directory
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
9
|
+
const SKILL_NAMES = ["vibeo-core", "vibeo-audio", "vibeo-effects", "vibeo-extras", "vibeo-rendering"];
|
|
8
10
|
async function loadSkills() {
|
|
9
|
-
//
|
|
11
|
+
// Resolve from this file's location — skills/ is shipped alongside dist/ in the npm package
|
|
12
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
13
|
+
const thisDir = dirname(thisFile);
|
|
14
|
+
// From dist/commands/install-skills.js → ../../skills
|
|
15
|
+
// From src/commands/install-skills.ts → ../../skills
|
|
10
16
|
const candidates = [
|
|
11
|
-
join(
|
|
12
|
-
join(
|
|
17
|
+
join(thisDir, "..", "..", "skills"), // from dist/commands/ or src/commands/
|
|
18
|
+
join(thisDir, "..", "..", "..", "skills"), // from deeper nesting
|
|
19
|
+
join(process.cwd(), "skills"), // from project root
|
|
13
20
|
];
|
|
14
21
|
for (const dir of candidates) {
|
|
15
|
-
const names = ["vibeo-core", "vibeo-audio", "vibeo-effects", "vibeo-extras", "vibeo-rendering"];
|
|
16
22
|
const skills = {};
|
|
17
23
|
let found = true;
|
|
18
|
-
for (const name of
|
|
24
|
+
for (const name of SKILL_NAMES) {
|
|
19
25
|
const path = join(dir, name, "SKILL.md");
|
|
20
26
|
if (existsSync(path)) {
|
|
21
27
|
skills[name] = await readFile(path, "utf-8");
|
|
@@ -28,97 +34,30 @@ async function loadSkills() {
|
|
|
28
34
|
if (found)
|
|
29
35
|
return skills;
|
|
30
36
|
}
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
vibeo: getEmbeddedSkill(),
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function getEmbeddedSkill() {
|
|
37
|
-
return `# Vibeo — React Video Framework
|
|
38
|
-
|
|
39
|
-
Vibeo is a React-based programmatic video framework. Write video compositions as React components, preview in the browser, and render to video with FFmpeg.
|
|
40
|
-
|
|
41
|
-
## Quick Reference
|
|
42
|
-
|
|
43
|
-
\`\`\`bash
|
|
44
|
-
# Get full CLI docs
|
|
45
|
-
bunx @vibeo/cli --llms-full
|
|
46
|
-
|
|
47
|
-
# Create a project
|
|
48
|
-
bunx @vibeo/cli create my-video --template basic
|
|
49
|
-
|
|
50
|
-
# Preview
|
|
51
|
-
bunx @vibeo/cli preview --entry src/index.tsx
|
|
52
|
-
|
|
53
|
-
# Render
|
|
54
|
-
bunx @vibeo/cli render --entry src/index.tsx --composition MyComp
|
|
55
|
-
|
|
56
|
-
# List compositions
|
|
57
|
-
bunx @vibeo/cli list --entry src/index.tsx
|
|
58
|
-
\`\`\`
|
|
59
|
-
|
|
60
|
-
## Packages
|
|
61
|
-
|
|
62
|
-
- \`@vibeo/core\` — Composition, Sequence, Loop, useCurrentFrame, useVideoConfig, interpolate, easing
|
|
63
|
-
- \`@vibeo/audio\` — Audio/Video components, 48kHz sync, volume curves, audio mixing
|
|
64
|
-
- \`@vibeo/effects\` — useKeyframes, useSpring, Transition (fade/wipe/slide/dissolve), useAudioData
|
|
65
|
-
- \`@vibeo/extras\` — Subtitle (SRT/VTT), AudioWaveform, AudioSpectrogram, SceneGraph, AudioMix
|
|
66
|
-
- \`@vibeo/player\` — Interactive Player component with controls
|
|
67
|
-
- \`@vibeo/renderer\` — Headless rendering via Playwright + FFmpeg
|
|
68
|
-
- \`@vibeo/cli\` — CLI with incur (supports --llms, --mcp, --schema)
|
|
69
|
-
|
|
70
|
-
## Core Pattern
|
|
71
|
-
|
|
72
|
-
\`\`\`tsx
|
|
73
|
-
import { Composition, Sequence, VibeoRoot, useCurrentFrame, useVideoConfig, interpolate } from "@vibeo/core";
|
|
74
|
-
|
|
75
|
-
function MyScene() {
|
|
76
|
-
const frame = useCurrentFrame();
|
|
77
|
-
const { width, height, fps } = useVideoConfig();
|
|
78
|
-
const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: "clamp" });
|
|
79
|
-
return <div style={{ width, height, opacity }}>Hello</div>;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function Root() {
|
|
83
|
-
return (
|
|
84
|
-
<VibeoRoot>
|
|
85
|
-
<Composition id="MyComp" component={MyScene} width={1920} height={1080} fps={30} durationInFrames={150} />
|
|
86
|
-
</VibeoRoot>
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
\`\`\`
|
|
90
|
-
|
|
91
|
-
## Key Math
|
|
92
|
-
|
|
93
|
-
- Frame to time: \`time = frame / fps\`
|
|
94
|
-
- Samples per frame (audio): \`(48000 * 2) / fps\`
|
|
95
|
-
- Media time with playback rate: uses interpolation with rate scaling
|
|
96
|
-
- Sequence relative frame: \`absoluteFrame - (cumulatedFrom + relativeFrom)\`
|
|
97
|
-
- Loop iteration: \`floor(currentFrame / durationInFrames)\`
|
|
98
|
-
|
|
99
|
-
For full API details, run \`bunx @vibeo/cli --llms-full\` or \`bunx @vibeo/cli <command> --schema\`.
|
|
100
|
-
`;
|
|
37
|
+
throw new Error("Could not find skill files. Make sure the @vibeo/cli package is installed correctly.");
|
|
101
38
|
}
|
|
102
39
|
const home = homedir();
|
|
103
40
|
const TARGETS = [
|
|
104
41
|
{
|
|
105
42
|
name: "claude",
|
|
106
|
-
description: "Claude Code (~/.claude/skills
|
|
43
|
+
description: "Claude Code (~/.claude/skills/<name>/SKILL.md + project .claude/skills/<name>/SKILL.md)",
|
|
107
44
|
async install(skills, cwd) {
|
|
108
45
|
const files = [];
|
|
109
|
-
// Global skills directory
|
|
46
|
+
// Global skills directory — each skill in its own dir with SKILL.md
|
|
110
47
|
const globalDir = join(home, ".claude", "skills");
|
|
111
|
-
await mkdir(globalDir, { recursive: true });
|
|
112
48
|
for (const [name, content] of Object.entries(skills)) {
|
|
113
|
-
const
|
|
49
|
+
const skillDir = join(globalDir, name);
|
|
50
|
+
await mkdir(skillDir, { recursive: true });
|
|
51
|
+
const path = join(skillDir, "SKILL.md");
|
|
114
52
|
await writeFile(path, content);
|
|
115
53
|
files.push(path);
|
|
116
54
|
}
|
|
117
|
-
// Project-level .claude/skills
|
|
55
|
+
// Project-level .claude/skills/<name>/SKILL.md
|
|
118
56
|
const projectDir = join(cwd, ".claude", "skills");
|
|
119
|
-
await mkdir(projectDir, { recursive: true });
|
|
120
57
|
for (const [name, content] of Object.entries(skills)) {
|
|
121
|
-
const
|
|
58
|
+
const skillDir = join(projectDir, name);
|
|
59
|
+
await mkdir(skillDir, { recursive: true });
|
|
60
|
+
const path = join(skillDir, "SKILL.md");
|
|
122
61
|
await writeFile(path, content);
|
|
123
62
|
files.push(path);
|
|
124
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../../src/commands/install-skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../../src/commands/install-skills.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# Vibeo Audio (`@vibeo/audio`)
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
`@vibeo/audio` provides frame-accurate audio synchronization, audio mixing, volume curves, and the `<Audio>` and `<Video>` media components. It handles the critical math for syncing HTML media elements to Vibeo's frame-based timeline.
|
|
6
|
+
|
|
7
|
+
**When to use**: Whenever your composition includes audio or video media files.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## API Reference
|
|
12
|
+
|
|
13
|
+
### Components
|
|
14
|
+
|
|
15
|
+
#### `Audio`
|
|
16
|
+
Renders an audio element synced to the Vibeo timeline.
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
<Audio
|
|
20
|
+
src="/music.mp3"
|
|
21
|
+
volume={0.8}
|
|
22
|
+
startFrom={30}
|
|
23
|
+
endAt={150}
|
|
24
|
+
playbackRate={1}
|
|
25
|
+
muted={false}
|
|
26
|
+
/>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
#### `Video`
|
|
30
|
+
Renders a video element (visual + audio) synced to the Vibeo timeline.
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
<Video
|
|
34
|
+
src="/clip.mp4"
|
|
35
|
+
volume={(frame) => frame < 30 ? 1 : 0.5}
|
|
36
|
+
startFrom={0}
|
|
37
|
+
endAt={300}
|
|
38
|
+
playbackRate={1.5}
|
|
39
|
+
/>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Common props** (`MediaProps`):
|
|
43
|
+
| Prop | Type | Default | Description |
|
|
44
|
+
|------|------|---------|-------------|
|
|
45
|
+
| `src` | `string` | — | URL or path to the media file |
|
|
46
|
+
| `volume?` | `number \| (frame: number) => number` | `1` | Volume (0-1), or a per-frame function |
|
|
47
|
+
| `playbackRate?` | `number` | `1` | Playback speed multiplier |
|
|
48
|
+
| `startFrom?` | `number` | `0` | Frame in the media to start from |
|
|
49
|
+
| `endAt?` | `number` | — | Frame in the media to stop at |
|
|
50
|
+
| `muted?` | `boolean` | `false` | Mute audio |
|
|
51
|
+
| `loop?` | `boolean` | `false` | Loop the media |
|
|
52
|
+
|
|
53
|
+
`Video` also has `VideoProps` which extends `MediaProps` with standard HTML video attributes.
|
|
54
|
+
|
|
55
|
+
### Hooks
|
|
56
|
+
|
|
57
|
+
#### `useAudioContext(): AudioContext`
|
|
58
|
+
Returns the singleton AudioContext (created at 48kHz sample rate).
|
|
59
|
+
|
|
60
|
+
#### `useMediaSync(options: UseMediaSyncOptions): void`
|
|
61
|
+
Low-level hook that syncs an HTML media element's `currentTime` to the current frame. Used internally by `<Audio>` and `<Video>`.
|
|
62
|
+
|
|
63
|
+
#### `useMediaInTimeline(options: UseMediaInTimelineOptions): MediaTimelineInfo`
|
|
64
|
+
Registers a media element in the timeline and returns timing information including whether the media should be active at the current frame.
|
|
65
|
+
|
|
66
|
+
### Audio Sync Math
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import {
|
|
70
|
+
TARGET_SAMPLE_RATE, // 48000
|
|
71
|
+
TARGET_CHANNELS, // 2
|
|
72
|
+
samplesPerFrame, // (48000 * 2) / fps
|
|
73
|
+
frameToAudioTimestamp, // frame * (1_000_000 / fps) — microseconds
|
|
74
|
+
audioTimeToFrame, // floor(timeInSeconds * fps)
|
|
75
|
+
} from "@vibeo/audio";
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| Constant/Function | Value/Signature | Description |
|
|
79
|
+
|-------------------|-----------------|-------------|
|
|
80
|
+
| `TARGET_SAMPLE_RATE` | `48000` | Fixed sample rate for all audio |
|
|
81
|
+
| `TARGET_CHANNELS` | `2` | Stereo output |
|
|
82
|
+
| `samplesPerFrame(fps)` | `(48000 * 2) / fps` | Samples per video frame |
|
|
83
|
+
| `frameToAudioTimestamp(frame, fps)` | `frame * (1_000_000 / fps)` | Frame to microsecond timestamp |
|
|
84
|
+
| `audioTimeToFrame(time, fps)` | `floor(time * fps)` | Seconds to frame number |
|
|
85
|
+
|
|
86
|
+
**Key numbers**:
|
|
87
|
+
- At 30fps: `samplesPerFrame = 3200`
|
|
88
|
+
- At 60fps: `samplesPerFrame = 1600`
|
|
89
|
+
|
|
90
|
+
### Audio Context Management
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { getAudioContext, destroyAudioContext } from "@vibeo/audio";
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
| Function | Description |
|
|
97
|
+
|----------|-------------|
|
|
98
|
+
| `getAudioContext(options?)` | Get or create the singleton AudioContext at 48kHz |
|
|
99
|
+
| `destroyAudioContext()` | Close and release the AudioContext |
|
|
100
|
+
|
|
101
|
+
### Audio Mixer
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { mixAudio } from "@vibeo/audio";
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`mixAudio(tracks: Int16Array[]): Int16Array` — Sums multiple audio tracks with clipping protection.
|
|
108
|
+
|
|
109
|
+
### Volume Utilities
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { evaluateVolume, buildVolumeArray } from "@vibeo/audio";
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
| Function | Description |
|
|
116
|
+
|----------|-------------|
|
|
117
|
+
| `evaluateVolume(volume, frame)` | Evaluate a `number \| VolumeFunction` at a given frame |
|
|
118
|
+
| `buildVolumeArray(volume, duration, startsAt)` | Build an array of per-frame volume values |
|
|
119
|
+
|
|
120
|
+
### Types
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import type {
|
|
124
|
+
AudioAsset, // Registered audio asset in the timeline
|
|
125
|
+
AudioData, // Decoded audio buffer data
|
|
126
|
+
MediaProps, // Common props for Audio/Video
|
|
127
|
+
VolumeFunction, // (frame: number) => number
|
|
128
|
+
VideoProps, // Video-specific props
|
|
129
|
+
AudioContextOptions,
|
|
130
|
+
UseMediaSyncOptions,
|
|
131
|
+
MediaTimelineInfo,
|
|
132
|
+
UseMediaInTimelineOptions,
|
|
133
|
+
} from "@vibeo/audio";
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Common Patterns
|
|
139
|
+
|
|
140
|
+
### Adding background music
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
function MyVideo() {
|
|
144
|
+
return (
|
|
145
|
+
<>
|
|
146
|
+
<Audio src="/bg-music.mp3" volume={0.3} />
|
|
147
|
+
<Sequence from={0} durationInFrames={90}>
|
|
148
|
+
<TitleCard />
|
|
149
|
+
</Sequence>
|
|
150
|
+
</>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Volume automation (fade in/out)
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<Audio
|
|
159
|
+
src="/narration.mp3"
|
|
160
|
+
volume={(frame) => {
|
|
161
|
+
if (frame < 15) return frame / 15; // fade in over 15 frames
|
|
162
|
+
if (frame > 270) return (300 - frame) / 30; // fade out last 30 frames
|
|
163
|
+
return 1;
|
|
164
|
+
}}
|
|
165
|
+
/>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Syncing audio to video with playback rate
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
<Video
|
|
172
|
+
src="/interview.mp4"
|
|
173
|
+
playbackRate={1.5}
|
|
174
|
+
volume={1}
|
|
175
|
+
startFrom={0}
|
|
176
|
+
/>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The media time formula ensures audio and video stay in sync at any playback rate:
|
|
180
|
+
```
|
|
181
|
+
mediaTime = interpolate(frame, [-1, startFrom, startFrom+1], [-1, startFrom, startFrom+playbackRate]) * msPerFrame / 1000
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Trimming media
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
// Play only frames 60-180 of the source video
|
|
188
|
+
<Video src="/long-clip.mp4" startFrom={60} endAt={180} />
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Duration with trim:
|
|
192
|
+
```
|
|
193
|
+
duration = endAt - startFrom
|
|
194
|
+
actualDuration = floor(duration / playbackRate)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Volume function per-frame evaluation
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
volumes = Array(duration).map((_, i) => volumeFunction(i + startsAt) * mediaVolume)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Gotchas and Tips
|
|
206
|
+
|
|
207
|
+
1. **AudioContext must be 48kHz** — the framework forces `sampleRate: 48000` for consistency.
|
|
208
|
+
|
|
209
|
+
2. **Volume functions receive the sequence-relative frame** (from `useCurrentFrame()`), not the absolute composition frame. Inside a `<Sequence from={60}>`, frame 0 in the volume callback corresponds to composition frame 60.
|
|
210
|
+
|
|
211
|
+
3. **`startFrom` and `endAt` are in media frames**, not composition frames. They trim the source media.
|
|
212
|
+
|
|
213
|
+
4. **Audio mixing uses `Int16Array`** with clipping protection — summed samples are clamped to the `[-32768, 32767]` range.
|
|
214
|
+
|
|
215
|
+
5. **The `<Video>` component** handles both visual rendering and audio sync. You don't need a separate `<Audio>` for a video file's audio track.
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## LLM & Agent Integration
|
|
221
|
+
|
|
222
|
+
Vibeo's CLI is built with [incur](https://github.com/wevm/incur), making it natively discoverable by AI agents and LLMs.
|
|
223
|
+
|
|
224
|
+
### Discovering the API
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Get a compact summary of all CLI commands (ideal for LLM system prompts)
|
|
228
|
+
bunx @vibeo/cli --llms
|
|
229
|
+
|
|
230
|
+
# Get the full manifest with schemas, examples, and argument details
|
|
231
|
+
bunx @vibeo/cli --llms-full
|
|
232
|
+
|
|
233
|
+
# Get JSON Schema for a specific command (useful for structured tool calls)
|
|
234
|
+
bunx @vibeo/cli render --schema
|
|
235
|
+
bunx @vibeo/cli create --schema
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Using as an MCP Server
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Start Vibeo as an MCP (Model Context Protocol) server
|
|
242
|
+
bunx @vibeo/cli --mcp
|
|
243
|
+
|
|
244
|
+
# Register as a persistent MCP server for your agent
|
|
245
|
+
bunx @vibeo/cli mcp add
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
This lets LLMs call `create`, `render`, `preview`, and `list` as structured tool calls through the MCP protocol.
|
|
249
|
+
|
|
250
|
+
### Generating Skill Files
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# Sync skill files to your agent's skill directory
|
|
254
|
+
bunx @vibeo/cli skills add
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
This generates markdown skill files that agents like Claude Code can discover and use to write Vibeo code without reading source.
|
|
258
|
+
|
|
259
|
+
### Agent-Friendly Output
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Output as JSON for programmatic consumption
|
|
263
|
+
bunx @vibeo/cli list --entry src/index.tsx --format json
|
|
264
|
+
|
|
265
|
+
# Output as YAML
|
|
266
|
+
bunx @vibeo/cli list --entry src/index.tsx --format yaml
|
|
267
|
+
|
|
268
|
+
# Filter output to specific keys
|
|
269
|
+
bunx @vibeo/cli list --entry src/index.tsx --filter-output compositions[0].id
|
|
270
|
+
|
|
271
|
+
# Count tokens in output (useful for context window planning)
|
|
272
|
+
bunx @vibeo/cli render --schema --token-count
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### How LLMs Should Use Vibeo
|
|
276
|
+
|
|
277
|
+
1. **Discover commands**: Run `bunx @vibeo/cli --llms` to get the command manifest
|
|
278
|
+
2. **Create a project**: `bunx @vibeo/cli create my-video --template basic`
|
|
279
|
+
3. **Edit `src/index.tsx`**: Write React components using `@vibeo/core` hooks and components
|
|
280
|
+
4. **Preview**: `bunx @vibeo/cli preview --entry src/index.tsx`
|
|
281
|
+
5. **Render**: `bunx @vibeo/cli render --entry src/index.tsx --composition MyComp`
|
|
282
|
+
|
|
283
|
+
All commands accept `--format json` for structured output that LLMs can parse reliably.
|