@vibeo/cli 0.3.4 → 0.4.0

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.
@@ -0,0 +1,23 @@
1
+ import { bundleForEditor } from "@vibeo/renderer";
2
+
3
+ export async function startEditor(entry: string, port: number): Promise<void> {
4
+ console.log(`Starting editor server...`);
5
+ console.log(` Entry: ${entry}`);
6
+
7
+ const bundleResult = await bundleForEditor(entry, port);
8
+
9
+ console.log(`\n Editor running at ${bundleResult.url}`);
10
+ console.log(` Press Ctrl+C to stop\n`);
11
+
12
+ const shutdown = async () => {
13
+ console.log("\nShutting down editor server...");
14
+ await bundleResult.cleanup();
15
+ process.exit(0);
16
+ };
17
+
18
+ process.on("SIGINT", shutdown);
19
+ process.on("SIGTERM", shutdown);
20
+
21
+ // Block forever
22
+ await new Promise(() => {});
23
+ }
@@ -1,25 +1,33 @@
1
1
  import { resolve, 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
  // ---------------------------------------------------------------------------
7
- // Embedded skill content (so it works from npm without the skills/ dir)
8
+ // Skill loader resolves from the CLI package's own skills/ directory
8
9
  // ---------------------------------------------------------------------------
9
10
 
11
+ const SKILL_NAMES = ["vibeo-core", "vibeo-audio", "vibeo-effects", "vibeo-extras", "vibeo-rendering", "vibeo-editor", "vibeo-tiktok"];
12
+
10
13
  async function loadSkills(): Promise<Record<string, string>> {
11
- // Try to load from the repo's skills/ directory first
14
+ // Resolve from this file's location — skills/ is shipped alongside dist/ in the npm package
15
+ const thisFile = fileURLToPath(import.meta.url);
16
+ const thisDir = dirname(thisFile);
17
+
18
+ // From dist/commands/install-skills.js → ../../skills
19
+ // From src/commands/install-skills.ts → ../../skills
12
20
  const candidates = [
13
- join(dirname(import.meta.url.replace("file://", "")), "../../../../skills"),
14
- join(process.cwd(), "skills"),
21
+ join(thisDir, "..", "..", "skills"), // from dist/commands/ or src/commands/
22
+ join(thisDir, "..", "..", "..", "skills"), // from deeper nesting
23
+ join(process.cwd(), "skills"), // from project root
15
24
  ];
16
25
 
17
26
  for (const dir of candidates) {
18
- const names = ["vibeo-core", "vibeo-audio", "vibeo-effects", "vibeo-extras", "vibeo-rendering"];
19
27
  const skills: Record<string, string> = {};
20
28
  let found = true;
21
29
 
22
- for (const name of names) {
30
+ for (const name of SKILL_NAMES) {
23
31
  const path = join(dir, name, "SKILL.md");
24
32
  if (existsSync(path)) {
25
33
  skills[name] = await readFile(path, "utf-8");
@@ -32,78 +40,11 @@ async function loadSkills(): Promise<Record<string, string>> {
32
40
  if (found) return skills;
33
41
  }
34
42
 
35
- // Fallback: generate a minimal combined skill from --llms-full output
36
- return {
37
- vibeo: getEmbeddedSkill(),
38
- };
39
- }
40
-
41
- function getEmbeddedSkill(): string {
42
- return `# Vibeo — React Video Framework
43
-
44
- Vibeo is a React-based programmatic video framework. Write video compositions as React components, preview in the browser, and render to video with FFmpeg.
45
-
46
- ## Quick Reference
47
-
48
- \`\`\`bash
49
- # Get full CLI docs
50
- bunx @vibeo/cli --llms-full
51
-
52
- # Create a project
53
- bunx @vibeo/cli create my-video --template basic
54
-
55
- # Preview
56
- bunx @vibeo/cli preview --entry src/index.tsx
57
-
58
- # Render
59
- bunx @vibeo/cli render --entry src/index.tsx --composition MyComp
60
-
61
- # List compositions
62
- bunx @vibeo/cli list --entry src/index.tsx
63
- \`\`\`
64
-
65
- ## Packages
66
-
67
- - \`@vibeo/core\` — Composition, Sequence, Loop, useCurrentFrame, useVideoConfig, interpolate, easing
68
- - \`@vibeo/audio\` — Audio/Video components, 48kHz sync, volume curves, audio mixing
69
- - \`@vibeo/effects\` — useKeyframes, useSpring, Transition (fade/wipe/slide/dissolve), useAudioData
70
- - \`@vibeo/extras\` — Subtitle (SRT/VTT), AudioWaveform, AudioSpectrogram, SceneGraph, AudioMix
71
- - \`@vibeo/player\` — Interactive Player component with controls
72
- - \`@vibeo/renderer\` — Headless rendering via Playwright + FFmpeg
73
- - \`@vibeo/cli\` — CLI with incur (supports --llms, --mcp, --schema)
74
-
75
- ## Core Pattern
76
-
77
- \`\`\`tsx
78
- import { Composition, Sequence, VibeoRoot, useCurrentFrame, useVideoConfig, interpolate } from "@vibeo/core";
79
-
80
- function MyScene() {
81
- const frame = useCurrentFrame();
82
- const { width, height, fps } = useVideoConfig();
83
- const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: "clamp" });
84
- return <div style={{ width, height, opacity }}>Hello</div>;
85
- }
86
-
87
- export function Root() {
88
- return (
89
- <VibeoRoot>
90
- <Composition id="MyComp" component={MyScene} width={1920} height={1080} fps={30} durationInFrames={150} />
91
- </VibeoRoot>
43
+ throw new Error(
44
+ "Could not find skill files. Make sure the @vibeo/cli package is installed correctly.",
92
45
  );
93
46
  }
94
- \`\`\`
95
-
96
- ## Key Math
97
47
 
98
- - Frame to time: \`time = frame / fps\`
99
- - Samples per frame (audio): \`(48000 * 2) / fps\`
100
- - Media time with playback rate: uses interpolation with rate scaling
101
- - Sequence relative frame: \`absoluteFrame - (cumulatedFrom + relativeFrom)\`
102
- - Loop iteration: \`floor(currentFrame / durationInFrames)\`
103
-
104
- For full API details, run \`bunx @vibeo/cli --llms-full\` or \`bunx @vibeo/cli <command> --schema\`.
105
- `;
106
- }
107
48
 
108
49
  // ---------------------------------------------------------------------------
109
50
  // LLM tool targets
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
+ import { startEditor } from "./commands/editor.js";
9
10
 
10
11
  const cli = Cli.create("vibeo", {
11
12
  description: "React-based programmatic video framework CLI",
@@ -108,6 +109,20 @@ 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
+ await startEditor(resolve(c.options.entry), c.options.port);
123
+ },
124
+ });
125
+
111
126
  cli.command("install-skills", {
112
127
  description:
113
128
  "Install Vibeo skill/rule files for all supported LLM coding tools (Claude, Codex, Cursor, Gemini, OpenCode, Aider)",