@vibeframe/cli 0.106.6 → 0.106.8
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/_shared/scene-render.d.ts +18 -0
- package/dist/index.js +164 -30
- package/dist/tools/adapters/mcp.js +56 -4
- package/dist/tools/manifest/index.js +110 -15
- package/dist/tools/manifest/scene.d.ts +6 -0
- package/package.json +3 -3
|
@@ -17,6 +17,7 @@ import { type SceneAspect } from "./scene-project.js";
|
|
|
17
17
|
export type RenderFps = 24 | 30 | 60;
|
|
18
18
|
export type RenderQuality = "draft" | "standard" | "high";
|
|
19
19
|
export type RenderFormat = "mp4" | "webm" | "mov";
|
|
20
|
+
export type RenderOpenAction = "open" | "reveal";
|
|
20
21
|
export interface SceneRenderOptions {
|
|
21
22
|
/** Project directory (defaults to cwd). */
|
|
22
23
|
projectDir?: string;
|
|
@@ -33,6 +34,10 @@ export interface SceneRenderOptions {
|
|
|
33
34
|
/** Hyperframes capture worker count. Default 1 (the existing backend's
|
|
34
35
|
* default — auto-worker mode times out on small comps). */
|
|
35
36
|
workers?: number;
|
|
37
|
+
/** Open the rendered media in the OS default app after a successful render. */
|
|
38
|
+
openAfterRender?: boolean;
|
|
39
|
+
/** Reveal the rendered media in Finder/file manager after a successful render. */
|
|
40
|
+
revealInFinder?: boolean;
|
|
36
41
|
signal?: AbortSignal;
|
|
37
42
|
onProgress?: (pct: number, stage: string) => void;
|
|
38
43
|
}
|
|
@@ -42,6 +47,13 @@ export interface SceneRenderResult {
|
|
|
42
47
|
beat?: string | null;
|
|
43
48
|
root?: string;
|
|
44
49
|
outputPath?: string;
|
|
50
|
+
absoluteOutputPath?: string;
|
|
51
|
+
openCommand?: string;
|
|
52
|
+
revealCommand?: string;
|
|
53
|
+
opened?: boolean;
|
|
54
|
+
revealed?: boolean;
|
|
55
|
+
openError?: string;
|
|
56
|
+
revealError?: string;
|
|
45
57
|
durationMs?: number;
|
|
46
58
|
framesRendered?: number;
|
|
47
59
|
totalFrames?: number;
|
|
@@ -59,6 +71,11 @@ export interface SceneRenderResult {
|
|
|
59
71
|
error?: string;
|
|
60
72
|
retryWith?: string[];
|
|
61
73
|
}
|
|
74
|
+
export interface MediaOpenCommand {
|
|
75
|
+
command: string;
|
|
76
|
+
args: string[];
|
|
77
|
+
display: string;
|
|
78
|
+
}
|
|
62
79
|
/** Map a quality preset to an x264 CRF (lower = higher quality). */
|
|
63
80
|
export declare function qualityToCrf(quality?: RenderQuality): number;
|
|
64
81
|
/**
|
|
@@ -85,6 +102,7 @@ export declare function buildRenderConfig(opts: {
|
|
|
85
102
|
workers?: number;
|
|
86
103
|
entryFile?: string;
|
|
87
104
|
}): RenderConfig;
|
|
105
|
+
export declare function buildMediaOpenCommand(action: RenderOpenAction, filePath: string, platform?: NodeJS.Platform): MediaOpenCommand;
|
|
88
106
|
/**
|
|
89
107
|
* Render a scene project. Mirrors the contract of the existing Hyperframes
|
|
90
108
|
* backend (preflight → execute → structured result), but skips the
|
package/dist/index.js
CHANGED
|
@@ -31472,11 +31472,11 @@ registerRoot(Root);
|
|
|
31472
31472
|
return dir;
|
|
31473
31473
|
}
|
|
31474
31474
|
async function this_npmInstall(dir) {
|
|
31475
|
-
const { execFile:
|
|
31476
|
-
const { promisify:
|
|
31477
|
-
const
|
|
31475
|
+
const { execFile: execFile3 } = await import("node:child_process");
|
|
31476
|
+
const { promisify: promisify3 } = await import("node:util");
|
|
31477
|
+
const execFileAsync3 = promisify3(execFile3);
|
|
31478
31478
|
try {
|
|
31479
|
-
await
|
|
31479
|
+
await execFileAsync3("npm", ["install", "--prefer-offline", "--no-audit", "--no-fund"], {
|
|
31480
31480
|
cwd: dir,
|
|
31481
31481
|
timeout: 18e4
|
|
31482
31482
|
});
|
|
@@ -31500,13 +31500,13 @@ async function renderMotion(options) {
|
|
|
31500
31500
|
);
|
|
31501
31501
|
try {
|
|
31502
31502
|
const entryPoint = join9(dir, "Root.tsx");
|
|
31503
|
-
const { execFile:
|
|
31504
|
-
const { promisify:
|
|
31505
|
-
const
|
|
31503
|
+
const { execFile: execFile3 } = await import("node:child_process");
|
|
31504
|
+
const { promisify: promisify3 } = await import("node:util");
|
|
31505
|
+
const execFileAsync3 = promisify3(execFile3);
|
|
31506
31506
|
if (transparent) {
|
|
31507
31507
|
const webmOut = options.outputPath.replace(/\.\w+$/, ".webm");
|
|
31508
31508
|
try {
|
|
31509
|
-
await
|
|
31509
|
+
await execFileAsync3("npx", [
|
|
31510
31510
|
"remotion",
|
|
31511
31511
|
"render",
|
|
31512
31512
|
entryPoint,
|
|
@@ -31523,7 +31523,7 @@ async function renderMotion(options) {
|
|
|
31523
31523
|
} catch {
|
|
31524
31524
|
}
|
|
31525
31525
|
try {
|
|
31526
|
-
await
|
|
31526
|
+
await execFileAsync3("npx", [
|
|
31527
31527
|
"remotion",
|
|
31528
31528
|
"render",
|
|
31529
31529
|
entryPoint,
|
|
@@ -31543,7 +31543,7 @@ async function renderMotion(options) {
|
|
|
31543
31543
|
}
|
|
31544
31544
|
}
|
|
31545
31545
|
const mp4Out = options.outputPath.replace(/\.\w+$/, ".mp4");
|
|
31546
|
-
await
|
|
31546
|
+
await execFileAsync3("npx", [
|
|
31547
31547
|
"remotion",
|
|
31548
31548
|
"render",
|
|
31549
31549
|
entryPoint,
|
|
@@ -59857,15 +59857,18 @@ var init_scene_audio_mux = __esm({
|
|
|
59857
59857
|
// src/commands/_shared/scene-render.ts
|
|
59858
59858
|
var scene_render_exports = {};
|
|
59859
59859
|
__export(scene_render_exports, {
|
|
59860
|
+
buildMediaOpenCommand: () => buildMediaOpenCommand,
|
|
59860
59861
|
buildRenderConfig: () => buildRenderConfig,
|
|
59861
59862
|
defaultOutputPath: () => defaultOutputPath,
|
|
59862
59863
|
executeSceneRender: () => executeSceneRender,
|
|
59863
59864
|
prepareBeatRenderRoot: () => prepareBeatRenderRoot,
|
|
59864
59865
|
qualityToCrf: () => qualityToCrf2
|
|
59865
59866
|
});
|
|
59867
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
59866
59868
|
import { existsSync as existsSync46 } from "node:fs";
|
|
59867
59869
|
import { mkdir as mkdir24, readFile as readFile43, stat as stat8, writeFile as writeFile48 } from "node:fs/promises";
|
|
59868
59870
|
import { resolve as resolve62, relative as relative11, dirname as dirname22, basename as basename21, join as join22, isAbsolute as isAbsolute6 } from "node:path";
|
|
59871
|
+
import { promisify as promisify2 } from "node:util";
|
|
59869
59872
|
import {
|
|
59870
59873
|
createRenderJob,
|
|
59871
59874
|
executeRenderJob
|
|
@@ -59892,6 +59895,38 @@ function buildRenderConfig(opts) {
|
|
|
59892
59895
|
workers: opts.workers ?? 1
|
|
59893
59896
|
};
|
|
59894
59897
|
}
|
|
59898
|
+
function buildMediaOpenCommand(action, filePath, platform3 = process.platform) {
|
|
59899
|
+
if (platform3 === "darwin") {
|
|
59900
|
+
const args = action === "reveal" ? ["-R", filePath] : [filePath];
|
|
59901
|
+
return {
|
|
59902
|
+
command: "open",
|
|
59903
|
+
args,
|
|
59904
|
+
display: ["open", ...args].map(quoteCliArg).join(" ")
|
|
59905
|
+
};
|
|
59906
|
+
}
|
|
59907
|
+
if (platform3 === "win32") {
|
|
59908
|
+
if (action === "reveal") {
|
|
59909
|
+
const args2 = [`/select,${filePath}`];
|
|
59910
|
+
return {
|
|
59911
|
+
command: "explorer",
|
|
59912
|
+
args: args2,
|
|
59913
|
+
display: ["explorer", ...args2].map(quoteCliArg).join(" ")
|
|
59914
|
+
};
|
|
59915
|
+
}
|
|
59916
|
+
const args = ["/c", "start", "", filePath];
|
|
59917
|
+
return {
|
|
59918
|
+
command: "cmd",
|
|
59919
|
+
args,
|
|
59920
|
+
display: ["cmd", ...args].map(quoteCliArg).join(" ")
|
|
59921
|
+
};
|
|
59922
|
+
}
|
|
59923
|
+
const target = action === "reveal" ? dirname22(filePath) : filePath;
|
|
59924
|
+
return {
|
|
59925
|
+
command: "xdg-open",
|
|
59926
|
+
args: [target],
|
|
59927
|
+
display: ["xdg-open", target].map(quoteCliArg).join(" ")
|
|
59928
|
+
};
|
|
59929
|
+
}
|
|
59895
59930
|
async function executeSceneRender(opts = {}) {
|
|
59896
59931
|
const projectDir = resolve62(opts.projectDir ?? ".");
|
|
59897
59932
|
const projectConfig = await readProjectConfig(projectDir);
|
|
@@ -60015,6 +60050,9 @@ async function executeSceneRender(opts = {}) {
|
|
|
60015
60050
|
beat: opts.beatId ?? null,
|
|
60016
60051
|
root,
|
|
60017
60052
|
outputPath: relative11(process.cwd(), outputPath) || outputPath,
|
|
60053
|
+
absoluteOutputPath: outputPath,
|
|
60054
|
+
openCommand: buildMediaOpenCommand("open", outputPath).display,
|
|
60055
|
+
revealCommand: buildMediaOpenCommand("reveal", outputPath).display,
|
|
60018
60056
|
durationMs: Date.now() - start,
|
|
60019
60057
|
framesRendered: job.framesRendered,
|
|
60020
60058
|
totalFrames: job.totalFrames,
|
|
@@ -60025,12 +60063,38 @@ async function executeSceneRender(opts = {}) {
|
|
|
60025
60063
|
audioMuxApplied,
|
|
60026
60064
|
audioMuxWarning
|
|
60027
60065
|
};
|
|
60066
|
+
if (opts.revealInFinder) {
|
|
60067
|
+
try {
|
|
60068
|
+
await runMediaOpenAction("reveal", outputPath);
|
|
60069
|
+
result.revealed = true;
|
|
60070
|
+
} catch (err) {
|
|
60071
|
+
result.revealed = false;
|
|
60072
|
+
result.revealError = err instanceof Error ? err.message : String(err);
|
|
60073
|
+
}
|
|
60074
|
+
}
|
|
60075
|
+
if (opts.openAfterRender) {
|
|
60076
|
+
try {
|
|
60077
|
+
await runMediaOpenAction("open", outputPath);
|
|
60078
|
+
result.opened = true;
|
|
60079
|
+
} catch (err) {
|
|
60080
|
+
result.opened = false;
|
|
60081
|
+
result.openError = err instanceof Error ? err.message : String(err);
|
|
60082
|
+
}
|
|
60083
|
+
}
|
|
60028
60084
|
result.reportPath = await writeRenderReport(projectDir, {
|
|
60029
60085
|
...result,
|
|
60030
60086
|
outputPath
|
|
60031
60087
|
});
|
|
60032
60088
|
return result;
|
|
60033
60089
|
}
|
|
60090
|
+
async function runMediaOpenAction(action, filePath) {
|
|
60091
|
+
const cmd = buildMediaOpenCommand(action, filePath);
|
|
60092
|
+
await execFileAsync2(cmd.command, cmd.args);
|
|
60093
|
+
}
|
|
60094
|
+
function quoteCliArg(value) {
|
|
60095
|
+
if (/^[A-Za-z0-9_/@%+=:,.-]+$/.test(value)) return value;
|
|
60096
|
+
return `"${value.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
60097
|
+
}
|
|
60034
60098
|
async function safeStat(p) {
|
|
60035
60099
|
try {
|
|
60036
60100
|
return await stat8(p);
|
|
@@ -60201,6 +60265,13 @@ async function writeRenderReport(projectDir, result) {
|
|
|
60201
60265
|
beat: result.beat ?? null,
|
|
60202
60266
|
root: result.root,
|
|
60203
60267
|
outputPath: result.outputPath,
|
|
60268
|
+
absoluteOutputPath: result.absoluteOutputPath,
|
|
60269
|
+
openCommand: result.openCommand,
|
|
60270
|
+
revealCommand: result.revealCommand,
|
|
60271
|
+
opened: result.opened,
|
|
60272
|
+
revealed: result.revealed,
|
|
60273
|
+
openError: result.openError,
|
|
60274
|
+
revealError: result.revealError,
|
|
60204
60275
|
fps: result.fps,
|
|
60205
60276
|
quality: result.quality,
|
|
60206
60277
|
format: result.format,
|
|
@@ -60245,6 +60316,7 @@ function escapeAttr(value) {
|
|
|
60245
60316
|
function unique4(items) {
|
|
60246
60317
|
return [...new Set(items.filter((item) => Boolean(item)))];
|
|
60247
60318
|
}
|
|
60319
|
+
var execFileAsync2;
|
|
60248
60320
|
var init_scene_render = __esm({
|
|
60249
60321
|
"src/commands/_shared/scene-render.ts"() {
|
|
60250
60322
|
"use strict";
|
|
@@ -60254,6 +60326,7 @@ var init_scene_render = __esm({
|
|
|
60254
60326
|
init_scene_audio_mux();
|
|
60255
60327
|
init_project_config();
|
|
60256
60328
|
init_scene_project();
|
|
60329
|
+
execFileAsync2 = promisify2(execFile2);
|
|
60257
60330
|
}
|
|
60258
60331
|
});
|
|
60259
60332
|
|
|
@@ -67341,7 +67414,9 @@ var init_scene2 = __esm({
|
|
|
67341
67414
|
fps: external_exports.number().optional().describe("Frames per second. Must be 24, 30, or 60. Default 30."),
|
|
67342
67415
|
quality: external_exports.enum(["draft", "standard", "high"]).optional().describe("Quality preset. Default 'standard'."),
|
|
67343
67416
|
format: external_exports.enum(["mp4", "webm", "mov"]).optional().describe("Container format. Default 'mp4'."),
|
|
67344
|
-
workers: external_exports.number().optional().describe("Capture worker count (1-16). Default 1.")
|
|
67417
|
+
workers: external_exports.number().optional().describe("Capture worker count (1-16). Default 1."),
|
|
67418
|
+
openAfterRender: external_exports.boolean().optional().describe("Open the rendered video in the OS default app after render. Default false."),
|
|
67419
|
+
revealInFinder: external_exports.boolean().optional().describe("Reveal the rendered video in Finder/file manager after render. Default false.")
|
|
67345
67420
|
});
|
|
67346
67421
|
sceneRenderTool = defineTool({
|
|
67347
67422
|
name: "render",
|
|
@@ -67359,7 +67434,9 @@ var init_scene2 = __esm({
|
|
|
67359
67434
|
fps: args.fps,
|
|
67360
67435
|
quality: args.quality,
|
|
67361
67436
|
format: args.format,
|
|
67362
|
-
workers: args.workers
|
|
67437
|
+
workers: args.workers,
|
|
67438
|
+
openAfterRender: args.openAfterRender,
|
|
67439
|
+
revealInFinder: args.revealInFinder
|
|
67363
67440
|
});
|
|
67364
67441
|
if (!result.success) {
|
|
67365
67442
|
return { success: false, error: result.error ?? "render failed" };
|
|
@@ -67368,6 +67445,13 @@ var init_scene2 = __esm({
|
|
|
67368
67445
|
success: true,
|
|
67369
67446
|
data: {
|
|
67370
67447
|
outputPath: result.outputPath,
|
|
67448
|
+
absoluteOutputPath: result.absoluteOutputPath,
|
|
67449
|
+
openCommand: result.openCommand,
|
|
67450
|
+
revealCommand: result.revealCommand,
|
|
67451
|
+
opened: result.opened,
|
|
67452
|
+
revealed: result.revealed,
|
|
67453
|
+
openError: result.openError,
|
|
67454
|
+
revealError: result.revealError,
|
|
67371
67455
|
beat: result.beat,
|
|
67372
67456
|
root: result.root,
|
|
67373
67457
|
reportPath: result.reportPath,
|
|
@@ -67376,13 +67460,24 @@ var init_scene2 = __esm({
|
|
|
67376
67460
|
totalFrames: result.totalFrames,
|
|
67377
67461
|
fps: result.fps,
|
|
67378
67462
|
quality: result.quality,
|
|
67379
|
-
format: result.format
|
|
67463
|
+
format: result.format,
|
|
67464
|
+
audioCount: result.audioCount,
|
|
67465
|
+
audioMuxApplied: result.audioMuxApplied,
|
|
67466
|
+
audioMuxWarning: result.audioMuxWarning
|
|
67380
67467
|
},
|
|
67381
67468
|
humanLines: [
|
|
67382
|
-
`\u2705 Render complete: ${result.outputPath}`,
|
|
67469
|
+
`\u2705 Render complete: ${result.absoluteOutputPath ?? result.outputPath}`,
|
|
67383
67470
|
` duration: ${((result.durationMs ?? 0) / 1e3).toFixed(1)}s`,
|
|
67384
67471
|
` frames: ${result.framesRendered ?? "?"}${result.totalFrames ? ` / ${result.totalFrames}` : ""}`,
|
|
67385
|
-
` config: ${result.fps}fps \xB7 ${result.quality} \xB7 ${result.format}
|
|
67472
|
+
` config: ${result.fps}fps \xB7 ${result.quality} \xB7 ${result.format}`,
|
|
67473
|
+
` audio: ${result.audioCount && result.audioCount > 0 ? `${result.audioCount} track${result.audioCount === 1 ? "" : "s"} muxed` : "silent"}`,
|
|
67474
|
+
...result.openCommand ? [` open: ${result.openCommand}`] : [],
|
|
67475
|
+
...result.revealCommand ? [` reveal: ${result.revealCommand}`] : [],
|
|
67476
|
+
` inspect: vibe inspect render ${projectDir} --cheap --json`,
|
|
67477
|
+
...result.opened ? [` opened: yes`] : [],
|
|
67478
|
+
...result.revealed ? [` revealed: yes`] : [],
|
|
67479
|
+
...result.openError ? [` open warning: ${result.openError}`] : [],
|
|
67480
|
+
...result.revealError ? [` reveal warning: ${result.revealError}`] : []
|
|
67386
67481
|
]
|
|
67387
67482
|
};
|
|
67388
67483
|
}
|
|
@@ -72028,7 +72123,7 @@ init_source();
|
|
|
72028
72123
|
// package.json
|
|
72029
72124
|
var package_default = {
|
|
72030
72125
|
name: "@vibeframe/cli",
|
|
72031
|
-
version: "0.106.
|
|
72126
|
+
version: "0.106.8",
|
|
72032
72127
|
description: "VibeFrame CLI - agentic video workflow runtime",
|
|
72033
72128
|
private: false,
|
|
72034
72129
|
license: "MIT",
|
|
@@ -80703,7 +80798,18 @@ function resolveHostSelection(selection) {
|
|
|
80703
80798
|
return [selection];
|
|
80704
80799
|
}
|
|
80705
80800
|
function vibeframeMcpJson(host, projectDir) {
|
|
80706
|
-
|
|
80801
|
+
if (host.id !== "claude-desktop") return { ...VIBEFRAME_MCP_JSON };
|
|
80802
|
+
const workspace = resolve53(projectDir);
|
|
80803
|
+
if (process.platform === "win32") {
|
|
80804
|
+
return {
|
|
80805
|
+
command: "cmd.exe",
|
|
80806
|
+
args: ["/d", "/s", "/c", `cd /d ${cmdQuote(workspace)} && npx -y @vibeframe/mcp-server`]
|
|
80807
|
+
};
|
|
80808
|
+
}
|
|
80809
|
+
return {
|
|
80810
|
+
command: "bash",
|
|
80811
|
+
args: ["-lc", `cd ${shellQuote(workspace)} && exec npx -y @vibeframe/mcp-server`]
|
|
80812
|
+
};
|
|
80707
80813
|
}
|
|
80708
80814
|
function renderHostSnippet(host, projectDir) {
|
|
80709
80815
|
if (host.configKind === "codex-toml") return CODEX_MCP_BLOCK.trimEnd();
|
|
@@ -80768,9 +80874,9 @@ async function inspectHost(host, projectDir) {
|
|
|
80768
80874
|
const json = JSON.parse(content);
|
|
80769
80875
|
configured = hasVibeframeMcpServer(json);
|
|
80770
80876
|
const server = readVibeframeMcpServer(json);
|
|
80771
|
-
if (host.id === "claude-desktop" && configured && !server
|
|
80877
|
+
if (host.id === "claude-desktop" && configured && !isAnchoredClaudeDesktopServer(server)) {
|
|
80772
80878
|
warnings.push(
|
|
80773
|
-
"Claude Desktop vibeframe MCP config
|
|
80879
|
+
"Claude Desktop vibeframe MCP config is not workspace-anchored; run `vibe host setup claude-desktop <workspace> --write` to anchor relative paths."
|
|
80774
80880
|
);
|
|
80775
80881
|
}
|
|
80776
80882
|
}
|
|
@@ -80794,17 +80900,17 @@ async function mergeMcpJson(configPath, opts) {
|
|
|
80794
80900
|
const mcpServers = typeof root.mcpServers === "object" && root.mcpServers !== null && !Array.isArray(root.mcpServers) ? root.mcpServers : {};
|
|
80795
80901
|
if (mcpServers.vibeframe && !opts.force) {
|
|
80796
80902
|
const existing = mcpServers.vibeframe;
|
|
80797
|
-
if (
|
|
80903
|
+
if (canUpgradeDefaultServer(existing, opts.server)) {
|
|
80798
80904
|
root.mcpServers = {
|
|
80799
80905
|
...mcpServers,
|
|
80800
|
-
vibeframe:
|
|
80906
|
+
vibeframe: opts.server
|
|
80801
80907
|
};
|
|
80802
80908
|
await mkdir22(dirname18(configPath), { recursive: true });
|
|
80803
80909
|
if (exists && opts.backup) {
|
|
80804
80910
|
await writeFile44(`${configPath}.bak-${timestamp()}`, await readFile37(configPath, "utf-8"), "utf-8");
|
|
80805
80911
|
}
|
|
80806
80912
|
await writeFile44(configPath, JSON.stringify(root, null, 2) + "\n", "utf-8");
|
|
80807
|
-
return { path: configPath, status: "merged", reason: "
|
|
80913
|
+
return { path: configPath, status: "merged", reason: "anchored existing default vibeframe MCP server" };
|
|
80808
80914
|
}
|
|
80809
80915
|
return {
|
|
80810
80916
|
path: configPath,
|
|
@@ -80874,14 +80980,24 @@ function readVibeframeMcpServer(value) {
|
|
|
80874
80980
|
if (!server || typeof server !== "object" || Array.isArray(server)) return null;
|
|
80875
80981
|
return server;
|
|
80876
80982
|
}
|
|
80877
|
-
function
|
|
80878
|
-
if (!
|
|
80983
|
+
function isAnchoredClaudeDesktopServer(server) {
|
|
80984
|
+
if (!server) return false;
|
|
80985
|
+
if (server.command === "bash" && Array.isArray(server.args)) {
|
|
80986
|
+
return server.args[0] === "-lc" && typeof server.args[1] === "string" && server.args[1].includes("exec npx -y @vibeframe/mcp-server");
|
|
80987
|
+
}
|
|
80988
|
+
if (server.command === "cmd.exe" && Array.isArray(server.args)) {
|
|
80989
|
+
return server.args.some((arg) => typeof arg === "string" && arg.includes("npx -y @vibeframe/mcp-server"));
|
|
80990
|
+
}
|
|
80991
|
+
return false;
|
|
80992
|
+
}
|
|
80993
|
+
function canUpgradeDefaultServer(existing, target) {
|
|
80879
80994
|
if (!existing || typeof existing !== "object" || Array.isArray(existing)) return false;
|
|
80880
80995
|
const current = existing;
|
|
80881
|
-
if (current.cwd) return false;
|
|
80882
|
-
if (current.command !== target.command) return false;
|
|
80883
80996
|
if (!Array.isArray(current.args)) return false;
|
|
80884
|
-
|
|
80997
|
+
if (current.command === target.command && JSON.stringify(current.args) === JSON.stringify(target.args)) {
|
|
80998
|
+
return false;
|
|
80999
|
+
}
|
|
81000
|
+
return current.command === VIBEFRAME_MCP_JSON.command && JSON.stringify(current.args) === JSON.stringify(VIBEFRAME_MCP_JSON.args);
|
|
80885
81001
|
}
|
|
80886
81002
|
function hostNextSteps(host) {
|
|
80887
81003
|
if (host.id === "codex") {
|
|
@@ -80921,6 +81037,12 @@ function ensureTrailingNewline(value) {
|
|
|
80921
81037
|
function escapeRegExp3(value) {
|
|
80922
81038
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
80923
81039
|
}
|
|
81040
|
+
function shellQuote(value) {
|
|
81041
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
81042
|
+
}
|
|
81043
|
+
function cmdQuote(value) {
|
|
81044
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
81045
|
+
}
|
|
80924
81046
|
|
|
80925
81047
|
// src/commands/_shared/init-templates.ts
|
|
80926
81048
|
var AGENTS_MD = `# AGENTS.md
|
|
@@ -82704,7 +82826,7 @@ import { resolve as resolve65 } from "node:path";
|
|
|
82704
82826
|
var VALID_FPS = [24, 30, 60];
|
|
82705
82827
|
var VALID_QUALITIES = ["draft", "standard", "high"];
|
|
82706
82828
|
var VALID_FORMATS = ["mp4", "webm", "mov"];
|
|
82707
|
-
var renderCommand = new Command("render").description("Render a VibeFrame video project to MP4/WebM/MOV").argument("[project-dir]", "Video project directory", ".").option("-o, --out <path>", "Output file (default: renders/<name>-<timestamp>.<format>)").option("--root <file>", "Root composition file", "index.html").option("--beat <id>", "Render only one storyboard beat using a temporary root").option("--fps <n>", `Frames per second: ${VALID_FPS.join("|")}`, "30").option("--quality <q>", `Quality preset: ${VALID_QUALITIES.join("|")}`, "standard").option("--format <f>", `Output container: ${VALID_FORMATS.join("|")}`, "mp4").option("--workers <n>", "Capture workers (1-16, default 1)", "1").option("--dry-run", "Preview parameters without rendering").addHelpText("after", `
|
|
82829
|
+
var renderCommand = new Command("render").description("Render a VibeFrame video project to MP4/WebM/MOV").argument("[project-dir]", "Video project directory", ".").option("-o, --out <path>", "Output file (default: renders/<name>-<timestamp>.<format>)").option("--root <file>", "Root composition file", "index.html").option("--beat <id>", "Render only one storyboard beat using a temporary root").option("--fps <n>", `Frames per second: ${VALID_FPS.join("|")}`, "30").option("--quality <q>", `Quality preset: ${VALID_QUALITIES.join("|")}`, "standard").option("--format <f>", `Output container: ${VALID_FORMATS.join("|")}`, "mp4").option("--workers <n>", "Capture workers (1-16, default 1)", "1").option("--open", "Open the rendered video in the OS default app after render").option("--reveal", "Reveal the rendered video in Finder/file manager after render").option("--dry-run", "Preview parameters without rendering").addHelpText("after", `
|
|
82708
82830
|
Examples:
|
|
82709
82831
|
$ vibe render my-video
|
|
82710
82832
|
$ vibe render my-video -o renders/final.mp4 --quality high
|
|
@@ -82724,7 +82846,9 @@ Alias note: this is the project-level entrypoint for \`vibe scene render\`.`).ac
|
|
|
82724
82846
|
fps,
|
|
82725
82847
|
quality,
|
|
82726
82848
|
format,
|
|
82727
|
-
workers
|
|
82849
|
+
workers,
|
|
82850
|
+
openAfterRender: Boolean(options.open),
|
|
82851
|
+
revealInFinder: Boolean(options.reveal)
|
|
82728
82852
|
};
|
|
82729
82853
|
if (options.dryRun) {
|
|
82730
82854
|
if (!isJsonMode() && !isQuietMode()) {
|
|
@@ -82749,6 +82873,8 @@ Alias note: this is the project-level entrypoint for \`vibe scene render\`.`).ac
|
|
|
82749
82873
|
quality,
|
|
82750
82874
|
format,
|
|
82751
82875
|
workers,
|
|
82876
|
+
openAfterRender: Boolean(options.open),
|
|
82877
|
+
revealInFinder: Boolean(options.reveal),
|
|
82752
82878
|
onProgress: (pct, stage) => {
|
|
82753
82879
|
if (spinner2) spinner2.text = `Rendering [${Math.round(pct * 100)}%] ${stage}`;
|
|
82754
82880
|
}
|
|
@@ -82779,6 +82905,8 @@ function printRenderDryRun(projectDirArg, params) {
|
|
|
82779
82905
|
console.log(` Format: ${source_default.bold(params.format)}`);
|
|
82780
82906
|
console.log(` Quality/FPS: ${source_default.bold(`${params.quality} / ${params.fps}`)}`);
|
|
82781
82907
|
console.log(` Workers: ${source_default.bold(String(params.workers))}`);
|
|
82908
|
+
if (params.openAfterRender) console.log(` Open: ${source_default.bold("yes")}`);
|
|
82909
|
+
if (params.revealInFinder) console.log(` Reveal: ${source_default.bold("yes")}`);
|
|
82782
82910
|
console.log();
|
|
82783
82911
|
console.log(source_default.dim("No browser capture, FFmpeg mux, or video files were created."));
|
|
82784
82912
|
}
|
|
@@ -82787,7 +82915,7 @@ function printRenderResult(spinner2, result) {
|
|
|
82787
82915
|
console.log();
|
|
82788
82916
|
console.log(source_default.bold.cyan("Output"));
|
|
82789
82917
|
console.log(source_default.dim("-".repeat(60)));
|
|
82790
|
-
console.log(` File: ${source_default.bold(result.outputPath)}`);
|
|
82918
|
+
console.log(` File: ${source_default.bold(result.absoluteOutputPath ?? result.outputPath)}`);
|
|
82791
82919
|
if (result.beat) console.log(` Beat: ${result.beat}`);
|
|
82792
82920
|
if (result.root) console.log(` Root: ${result.root}`);
|
|
82793
82921
|
console.log(` Format: ${result.format ?? "mp4"}`);
|
|
@@ -82800,6 +82928,12 @@ function printRenderResult(spinner2, result) {
|
|
|
82800
82928
|
console.log(` Audio: ${audio}`);
|
|
82801
82929
|
}
|
|
82802
82930
|
if (result.audioMuxWarning) console.log(source_default.yellow(` Warning: ${result.audioMuxWarning}`));
|
|
82931
|
+
if (result.openCommand) console.log(` Open: ${source_default.dim(result.openCommand)}`);
|
|
82932
|
+
if (result.revealCommand) console.log(` Reveal: ${source_default.dim(result.revealCommand)}`);
|
|
82933
|
+
if (result.opened) console.log(source_default.green(" Opened: yes"));
|
|
82934
|
+
if (result.revealed) console.log(source_default.green(" Revealed: yes"));
|
|
82935
|
+
if (result.openError) console.log(source_default.yellow(` Open warn: ${result.openError}`));
|
|
82936
|
+
if (result.revealError) console.log(source_default.yellow(` Reveal warn: ${result.revealError}`));
|
|
82803
82937
|
}
|
|
82804
82938
|
function parseFps(value) {
|
|
82805
82939
|
const n = Number.parseInt(value, 10);
|
|
@@ -109,6 +109,56 @@ function zodToJsonSchema(schema) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// src/tools/adapters/mcp.ts
|
|
112
|
+
function formatConsolePart(value) {
|
|
113
|
+
if (typeof value === "string") return value;
|
|
114
|
+
if (value instanceof Error) return value.stack ?? value.message;
|
|
115
|
+
try {
|
|
116
|
+
return JSON.stringify(value);
|
|
117
|
+
} catch {
|
|
118
|
+
return String(value);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function invokeWriteCallback(encodingOrCallback, callback) {
|
|
122
|
+
const cb = typeof encodingOrCallback === "function" ? encodingOrCallback : typeof callback === "function" ? callback : void 0;
|
|
123
|
+
if (cb) queueMicrotask(() => cb());
|
|
124
|
+
}
|
|
125
|
+
function formatStdoutChunk(chunk, encodingOrCallback) {
|
|
126
|
+
if (Buffer.isBuffer(chunk)) {
|
|
127
|
+
const encoding = typeof encodingOrCallback === "string" ? encodingOrCallback : "utf8";
|
|
128
|
+
return chunk.toString(encoding);
|
|
129
|
+
}
|
|
130
|
+
return String(chunk);
|
|
131
|
+
}
|
|
132
|
+
async function withCapturedStdout(fn) {
|
|
133
|
+
const originalWrite = process.stdout.write;
|
|
134
|
+
const originalConsoleLog = console.log;
|
|
135
|
+
const originalConsoleInfo = console.info;
|
|
136
|
+
const originalConsoleDebug = console.debug;
|
|
137
|
+
let captured = "";
|
|
138
|
+
const captureConsole = (...values) => {
|
|
139
|
+
captured += `${values.map(formatConsolePart).join(" ")}
|
|
140
|
+
`;
|
|
141
|
+
};
|
|
142
|
+
process.stdout.write = (chunk, encodingOrCallback, callback) => {
|
|
143
|
+
captured += formatStdoutChunk(chunk, encodingOrCallback);
|
|
144
|
+
invokeWriteCallback(encodingOrCallback, callback);
|
|
145
|
+
return true;
|
|
146
|
+
};
|
|
147
|
+
console.log = captureConsole;
|
|
148
|
+
console.info = captureConsole;
|
|
149
|
+
console.debug = captureConsole;
|
|
150
|
+
try {
|
|
151
|
+
return await fn();
|
|
152
|
+
} finally {
|
|
153
|
+
process.stdout.write = originalWrite;
|
|
154
|
+
console.log = originalConsoleLog;
|
|
155
|
+
console.info = originalConsoleInfo;
|
|
156
|
+
console.debug = originalConsoleDebug;
|
|
157
|
+
if (captured.trim() && process.env.VIBE_MCP_DEBUG_STDIO === "1") {
|
|
158
|
+
process.stderr.write(captured);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
112
162
|
function formatZodError(err) {
|
|
113
163
|
const missing = err.issues.filter((i) => {
|
|
114
164
|
if (i.code !== "invalid_type") return false;
|
|
@@ -155,10 +205,12 @@ function buildMcpDispatcher(manifest) {
|
|
|
155
205
|
};
|
|
156
206
|
}
|
|
157
207
|
try {
|
|
158
|
-
const result = await
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
208
|
+
const result = await withCapturedStdout(
|
|
209
|
+
() => tool.execute(parsed.data, {
|
|
210
|
+
workingDirectory: process.cwd(),
|
|
211
|
+
surface: "mcp"
|
|
212
|
+
})
|
|
213
|
+
);
|
|
162
214
|
const text = result.success ? JSON.stringify({ success: true, ...result.data }) : result.data ? JSON.stringify({
|
|
163
215
|
success: false,
|
|
164
216
|
error: result.error ?? "unknown error",
|
|
@@ -29537,15 +29537,18 @@ var init_scene_audio_mux = __esm({
|
|
|
29537
29537
|
// src/commands/_shared/scene-render.ts
|
|
29538
29538
|
var scene_render_exports = {};
|
|
29539
29539
|
__export(scene_render_exports, {
|
|
29540
|
+
buildMediaOpenCommand: () => buildMediaOpenCommand,
|
|
29540
29541
|
buildRenderConfig: () => buildRenderConfig,
|
|
29541
29542
|
defaultOutputPath: () => defaultOutputPath,
|
|
29542
29543
|
executeSceneRender: () => executeSceneRender,
|
|
29543
29544
|
prepareBeatRenderRoot: () => prepareBeatRenderRoot,
|
|
29544
29545
|
qualityToCrf: () => qualityToCrf
|
|
29545
29546
|
});
|
|
29547
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
29546
29548
|
import { existsSync as existsSync11 } from "node:fs";
|
|
29547
29549
|
import { mkdir as mkdir6, readFile as readFile12, stat as stat2, writeFile as writeFile11 } from "node:fs/promises";
|
|
29548
29550
|
import { resolve as resolve15, relative as relative6, dirname as dirname5, basename as basename3, join as join10, isAbsolute } from "node:path";
|
|
29551
|
+
import { promisify as promisify2 } from "node:util";
|
|
29549
29552
|
import {
|
|
29550
29553
|
createRenderJob,
|
|
29551
29554
|
executeRenderJob
|
|
@@ -29572,6 +29575,38 @@ function buildRenderConfig(opts) {
|
|
|
29572
29575
|
workers: opts.workers ?? 1
|
|
29573
29576
|
};
|
|
29574
29577
|
}
|
|
29578
|
+
function buildMediaOpenCommand(action, filePath, platform = process.platform) {
|
|
29579
|
+
if (platform === "darwin") {
|
|
29580
|
+
const args = action === "reveal" ? ["-R", filePath] : [filePath];
|
|
29581
|
+
return {
|
|
29582
|
+
command: "open",
|
|
29583
|
+
args,
|
|
29584
|
+
display: ["open", ...args].map(quoteCliArg).join(" ")
|
|
29585
|
+
};
|
|
29586
|
+
}
|
|
29587
|
+
if (platform === "win32") {
|
|
29588
|
+
if (action === "reveal") {
|
|
29589
|
+
const args2 = [`/select,${filePath}`];
|
|
29590
|
+
return {
|
|
29591
|
+
command: "explorer",
|
|
29592
|
+
args: args2,
|
|
29593
|
+
display: ["explorer", ...args2].map(quoteCliArg).join(" ")
|
|
29594
|
+
};
|
|
29595
|
+
}
|
|
29596
|
+
const args = ["/c", "start", "", filePath];
|
|
29597
|
+
return {
|
|
29598
|
+
command: "cmd",
|
|
29599
|
+
args,
|
|
29600
|
+
display: ["cmd", ...args].map(quoteCliArg).join(" ")
|
|
29601
|
+
};
|
|
29602
|
+
}
|
|
29603
|
+
const target = action === "reveal" ? dirname5(filePath) : filePath;
|
|
29604
|
+
return {
|
|
29605
|
+
command: "xdg-open",
|
|
29606
|
+
args: [target],
|
|
29607
|
+
display: ["xdg-open", target].map(quoteCliArg).join(" ")
|
|
29608
|
+
};
|
|
29609
|
+
}
|
|
29575
29610
|
async function executeSceneRender(opts = {}) {
|
|
29576
29611
|
const projectDir = resolve15(opts.projectDir ?? ".");
|
|
29577
29612
|
const projectConfig = await readProjectConfig(projectDir);
|
|
@@ -29695,6 +29730,9 @@ async function executeSceneRender(opts = {}) {
|
|
|
29695
29730
|
beat: opts.beatId ?? null,
|
|
29696
29731
|
root,
|
|
29697
29732
|
outputPath: relative6(process.cwd(), outputPath) || outputPath,
|
|
29733
|
+
absoluteOutputPath: outputPath,
|
|
29734
|
+
openCommand: buildMediaOpenCommand("open", outputPath).display,
|
|
29735
|
+
revealCommand: buildMediaOpenCommand("reveal", outputPath).display,
|
|
29698
29736
|
durationMs: Date.now() - start,
|
|
29699
29737
|
framesRendered: job.framesRendered,
|
|
29700
29738
|
totalFrames: job.totalFrames,
|
|
@@ -29705,12 +29743,38 @@ async function executeSceneRender(opts = {}) {
|
|
|
29705
29743
|
audioMuxApplied,
|
|
29706
29744
|
audioMuxWarning
|
|
29707
29745
|
};
|
|
29746
|
+
if (opts.revealInFinder) {
|
|
29747
|
+
try {
|
|
29748
|
+
await runMediaOpenAction("reveal", outputPath);
|
|
29749
|
+
result.revealed = true;
|
|
29750
|
+
} catch (err) {
|
|
29751
|
+
result.revealed = false;
|
|
29752
|
+
result.revealError = err instanceof Error ? err.message : String(err);
|
|
29753
|
+
}
|
|
29754
|
+
}
|
|
29755
|
+
if (opts.openAfterRender) {
|
|
29756
|
+
try {
|
|
29757
|
+
await runMediaOpenAction("open", outputPath);
|
|
29758
|
+
result.opened = true;
|
|
29759
|
+
} catch (err) {
|
|
29760
|
+
result.opened = false;
|
|
29761
|
+
result.openError = err instanceof Error ? err.message : String(err);
|
|
29762
|
+
}
|
|
29763
|
+
}
|
|
29708
29764
|
result.reportPath = await writeRenderReport(projectDir, {
|
|
29709
29765
|
...result,
|
|
29710
29766
|
outputPath
|
|
29711
29767
|
});
|
|
29712
29768
|
return result;
|
|
29713
29769
|
}
|
|
29770
|
+
async function runMediaOpenAction(action, filePath) {
|
|
29771
|
+
const cmd = buildMediaOpenCommand(action, filePath);
|
|
29772
|
+
await execFileAsync2(cmd.command, cmd.args);
|
|
29773
|
+
}
|
|
29774
|
+
function quoteCliArg(value) {
|
|
29775
|
+
if (/^[A-Za-z0-9_/@%+=:,.-]+$/.test(value)) return value;
|
|
29776
|
+
return `"${value.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
29777
|
+
}
|
|
29714
29778
|
async function safeStat(p) {
|
|
29715
29779
|
try {
|
|
29716
29780
|
return await stat2(p);
|
|
@@ -29881,6 +29945,13 @@ async function writeRenderReport(projectDir, result) {
|
|
|
29881
29945
|
beat: result.beat ?? null,
|
|
29882
29946
|
root: result.root,
|
|
29883
29947
|
outputPath: result.outputPath,
|
|
29948
|
+
absoluteOutputPath: result.absoluteOutputPath,
|
|
29949
|
+
openCommand: result.openCommand,
|
|
29950
|
+
revealCommand: result.revealCommand,
|
|
29951
|
+
opened: result.opened,
|
|
29952
|
+
revealed: result.revealed,
|
|
29953
|
+
openError: result.openError,
|
|
29954
|
+
revealError: result.revealError,
|
|
29884
29955
|
fps: result.fps,
|
|
29885
29956
|
quality: result.quality,
|
|
29886
29957
|
format: result.format,
|
|
@@ -29925,6 +29996,7 @@ function escapeAttr(value) {
|
|
|
29925
29996
|
function unique(items) {
|
|
29926
29997
|
return [...new Set(items.filter((item) => Boolean(item)))];
|
|
29927
29998
|
}
|
|
29999
|
+
var execFileAsync2;
|
|
29928
30000
|
var init_scene_render = __esm({
|
|
29929
30001
|
"src/commands/_shared/scene-render.ts"() {
|
|
29930
30002
|
"use strict";
|
|
@@ -29934,6 +30006,7 @@ var init_scene_render = __esm({
|
|
|
29934
30006
|
init_scene_audio_mux();
|
|
29935
30007
|
init_project_config();
|
|
29936
30008
|
init_scene_project();
|
|
30009
|
+
execFileAsync2 = promisify2(execFile2);
|
|
29937
30010
|
}
|
|
29938
30011
|
});
|
|
29939
30012
|
|
|
@@ -35843,11 +35916,11 @@ registerRoot(Root);
|
|
|
35843
35916
|
return dir;
|
|
35844
35917
|
}
|
|
35845
35918
|
async function this_npmInstall(dir) {
|
|
35846
|
-
const { execFile:
|
|
35847
|
-
const { promisify:
|
|
35848
|
-
const
|
|
35919
|
+
const { execFile: execFile3 } = await import("node:child_process");
|
|
35920
|
+
const { promisify: promisify3 } = await import("node:util");
|
|
35921
|
+
const execFileAsync3 = promisify3(execFile3);
|
|
35849
35922
|
try {
|
|
35850
|
-
await
|
|
35923
|
+
await execFileAsync3("npm", ["install", "--prefer-offline", "--no-audit", "--no-fund"], {
|
|
35851
35924
|
cwd: dir,
|
|
35852
35925
|
timeout: 18e4
|
|
35853
35926
|
});
|
|
@@ -35871,13 +35944,13 @@ async function renderMotion(options) {
|
|
|
35871
35944
|
);
|
|
35872
35945
|
try {
|
|
35873
35946
|
const entryPoint = join16(dir, "Root.tsx");
|
|
35874
|
-
const { execFile:
|
|
35875
|
-
const { promisify:
|
|
35876
|
-
const
|
|
35947
|
+
const { execFile: execFile3 } = await import("node:child_process");
|
|
35948
|
+
const { promisify: promisify3 } = await import("node:util");
|
|
35949
|
+
const execFileAsync3 = promisify3(execFile3);
|
|
35877
35950
|
if (transparent) {
|
|
35878
35951
|
const webmOut = options.outputPath.replace(/\.\w+$/, ".webm");
|
|
35879
35952
|
try {
|
|
35880
|
-
await
|
|
35953
|
+
await execFileAsync3("npx", [
|
|
35881
35954
|
"remotion",
|
|
35882
35955
|
"render",
|
|
35883
35956
|
entryPoint,
|
|
@@ -35894,7 +35967,7 @@ async function renderMotion(options) {
|
|
|
35894
35967
|
} catch {
|
|
35895
35968
|
}
|
|
35896
35969
|
try {
|
|
35897
|
-
await
|
|
35970
|
+
await execFileAsync3("npx", [
|
|
35898
35971
|
"remotion",
|
|
35899
35972
|
"render",
|
|
35900
35973
|
entryPoint,
|
|
@@ -35914,7 +35987,7 @@ async function renderMotion(options) {
|
|
|
35914
35987
|
}
|
|
35915
35988
|
}
|
|
35916
35989
|
const mp4Out = options.outputPath.replace(/\.\w+$/, ".mp4");
|
|
35917
|
-
await
|
|
35990
|
+
await execFileAsync3("npx", [
|
|
35918
35991
|
"remotion",
|
|
35919
35992
|
"render",
|
|
35920
35993
|
entryPoint,
|
|
@@ -52583,7 +52656,9 @@ var sceneRenderSchema = external_exports.object({
|
|
|
52583
52656
|
fps: external_exports.number().optional().describe("Frames per second. Must be 24, 30, or 60. Default 30."),
|
|
52584
52657
|
quality: external_exports.enum(["draft", "standard", "high"]).optional().describe("Quality preset. Default 'standard'."),
|
|
52585
52658
|
format: external_exports.enum(["mp4", "webm", "mov"]).optional().describe("Container format. Default 'mp4'."),
|
|
52586
|
-
workers: external_exports.number().optional().describe("Capture worker count (1-16). Default 1.")
|
|
52659
|
+
workers: external_exports.number().optional().describe("Capture worker count (1-16). Default 1."),
|
|
52660
|
+
openAfterRender: external_exports.boolean().optional().describe("Open the rendered video in the OS default app after render. Default false."),
|
|
52661
|
+
revealInFinder: external_exports.boolean().optional().describe("Reveal the rendered video in Finder/file manager after render. Default false.")
|
|
52587
52662
|
});
|
|
52588
52663
|
var sceneRenderTool = defineTool({
|
|
52589
52664
|
name: "render",
|
|
@@ -52601,7 +52676,9 @@ var sceneRenderTool = defineTool({
|
|
|
52601
52676
|
fps: args.fps,
|
|
52602
52677
|
quality: args.quality,
|
|
52603
52678
|
format: args.format,
|
|
52604
|
-
workers: args.workers
|
|
52679
|
+
workers: args.workers,
|
|
52680
|
+
openAfterRender: args.openAfterRender,
|
|
52681
|
+
revealInFinder: args.revealInFinder
|
|
52605
52682
|
});
|
|
52606
52683
|
if (!result.success) {
|
|
52607
52684
|
return { success: false, error: result.error ?? "render failed" };
|
|
@@ -52610,6 +52687,13 @@ var sceneRenderTool = defineTool({
|
|
|
52610
52687
|
success: true,
|
|
52611
52688
|
data: {
|
|
52612
52689
|
outputPath: result.outputPath,
|
|
52690
|
+
absoluteOutputPath: result.absoluteOutputPath,
|
|
52691
|
+
openCommand: result.openCommand,
|
|
52692
|
+
revealCommand: result.revealCommand,
|
|
52693
|
+
opened: result.opened,
|
|
52694
|
+
revealed: result.revealed,
|
|
52695
|
+
openError: result.openError,
|
|
52696
|
+
revealError: result.revealError,
|
|
52613
52697
|
beat: result.beat,
|
|
52614
52698
|
root: result.root,
|
|
52615
52699
|
reportPath: result.reportPath,
|
|
@@ -52618,13 +52702,24 @@ var sceneRenderTool = defineTool({
|
|
|
52618
52702
|
totalFrames: result.totalFrames,
|
|
52619
52703
|
fps: result.fps,
|
|
52620
52704
|
quality: result.quality,
|
|
52621
|
-
format: result.format
|
|
52705
|
+
format: result.format,
|
|
52706
|
+
audioCount: result.audioCount,
|
|
52707
|
+
audioMuxApplied: result.audioMuxApplied,
|
|
52708
|
+
audioMuxWarning: result.audioMuxWarning
|
|
52622
52709
|
},
|
|
52623
52710
|
humanLines: [
|
|
52624
|
-
`\u2705 Render complete: ${result.outputPath}`,
|
|
52711
|
+
`\u2705 Render complete: ${result.absoluteOutputPath ?? result.outputPath}`,
|
|
52625
52712
|
` duration: ${((result.durationMs ?? 0) / 1e3).toFixed(1)}s`,
|
|
52626
52713
|
` frames: ${result.framesRendered ?? "?"}${result.totalFrames ? ` / ${result.totalFrames}` : ""}`,
|
|
52627
|
-
` config: ${result.fps}fps \xB7 ${result.quality} \xB7 ${result.format}
|
|
52714
|
+
` config: ${result.fps}fps \xB7 ${result.quality} \xB7 ${result.format}`,
|
|
52715
|
+
` audio: ${result.audioCount && result.audioCount > 0 ? `${result.audioCount} track${result.audioCount === 1 ? "" : "s"} muxed` : "silent"}`,
|
|
52716
|
+
...result.openCommand ? [` open: ${result.openCommand}`] : [],
|
|
52717
|
+
...result.revealCommand ? [` reveal: ${result.revealCommand}`] : [],
|
|
52718
|
+
` inspect: vibe inspect render ${projectDir} --cheap --json`,
|
|
52719
|
+
...result.opened ? [` opened: yes`] : [],
|
|
52720
|
+
...result.revealed ? [` revealed: yes`] : [],
|
|
52721
|
+
...result.openError ? [` open warning: ${result.openError}`] : [],
|
|
52722
|
+
...result.revealError ? [` reveal warning: ${result.revealError}`] : []
|
|
52628
52723
|
]
|
|
52629
52724
|
};
|
|
52630
52725
|
}
|
|
@@ -108,6 +108,8 @@ export declare const sceneRenderTool: import("../define-tool.js").ToolDefinition
|
|
|
108
108
|
quality: z.ZodOptional<z.ZodEnum<["draft", "standard", "high"]>>;
|
|
109
109
|
format: z.ZodOptional<z.ZodEnum<["mp4", "webm", "mov"]>>;
|
|
110
110
|
workers: z.ZodOptional<z.ZodNumber>;
|
|
111
|
+
openAfterRender: z.ZodOptional<z.ZodBoolean>;
|
|
112
|
+
revealInFinder: z.ZodOptional<z.ZodBoolean>;
|
|
111
113
|
}, "strip", z.ZodTypeAny, {
|
|
112
114
|
output?: string | undefined;
|
|
113
115
|
fps?: number | undefined;
|
|
@@ -117,6 +119,8 @@ export declare const sceneRenderTool: import("../define-tool.js").ToolDefinition
|
|
|
117
119
|
root?: string | undefined;
|
|
118
120
|
beat?: string | undefined;
|
|
119
121
|
workers?: number | undefined;
|
|
122
|
+
openAfterRender?: boolean | undefined;
|
|
123
|
+
revealInFinder?: boolean | undefined;
|
|
120
124
|
}, {
|
|
121
125
|
output?: string | undefined;
|
|
122
126
|
fps?: number | undefined;
|
|
@@ -126,6 +130,8 @@ export declare const sceneRenderTool: import("../define-tool.js").ToolDefinition
|
|
|
126
130
|
root?: string | undefined;
|
|
127
131
|
beat?: string | undefined;
|
|
128
132
|
workers?: number | undefined;
|
|
133
|
+
openAfterRender?: boolean | undefined;
|
|
134
|
+
revealInFinder?: boolean | undefined;
|
|
129
135
|
}>>;
|
|
130
136
|
export declare const sceneBuildTool: import("../define-tool.js").ToolDefinition<z.ZodObject<{
|
|
131
137
|
projectDir: z.ZodOptional<z.ZodString>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/cli",
|
|
3
|
-
"version": "0.106.
|
|
3
|
+
"version": "0.106.8",
|
|
4
4
|
"description": "VibeFrame CLI - agentic video workflow runtime",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
"tsx": "^4.21.0",
|
|
84
84
|
"typescript": "^5.3.3",
|
|
85
85
|
"vitest": "^1.2.2",
|
|
86
|
-
"@vibeframe/ai-providers": "0.106.
|
|
87
|
-
"@vibeframe/core": "0.106.
|
|
86
|
+
"@vibeframe/ai-providers": "0.106.8",
|
|
87
|
+
"@vibeframe/core": "0.106.8"
|
|
88
88
|
},
|
|
89
89
|
"engines": {
|
|
90
90
|
"node": ">=20"
|