@vibeframe/mcp-server 0.115.2 → 0.115.3
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/index.js +938 -647
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -191,8 +191,8 @@ var init_api_keys = __esm({
|
|
|
191
191
|
envVar: "OPENAI_API_KEY",
|
|
192
192
|
label: "OpenAI",
|
|
193
193
|
showInSetup: true,
|
|
194
|
-
setupDescription: "gpt-image-2 image gen (
|
|
195
|
-
envExampleComment: "OpenAI API Key (Whisper transcription, gpt-4o-mini-tts narration, gpt-image-2
|
|
194
|
+
setupDescription: "gpt-image-2.5 image gen ($), gpt-4o-mini-tts narration, Whisper transcribe, Agent",
|
|
195
|
+
envExampleComment: "OpenAI API Key (Whisper transcription, gpt-4o-mini-tts narration, gpt-image-2.5 text-to-image)",
|
|
196
196
|
envExampleUrl: "https://platform.openai.com/api-keys",
|
|
197
197
|
keyFormat: { prefix: /^sk-/, example: "sk-..." }
|
|
198
198
|
});
|
|
@@ -267,8 +267,7 @@ var init_api_keys = __esm({
|
|
|
267
267
|
setupDescription: "v2.5/v3 video \u2014 std ($$) and pro ($$$) modes",
|
|
268
268
|
envExampleComment: "Kling API Key (Kling video generation)",
|
|
269
269
|
envExampleUrl: "https://platform.klingai.com/",
|
|
270
|
-
envExampleExtraLines: ["
|
|
271
|
-
keyFormat: { prefix: /:/, example: "ACCESS_KEY:SECRET_KEY" }
|
|
270
|
+
envExampleExtraLines: ["API key from the Kling console (legacy ACCESS_KEY:SECRET_KEY also works)"]
|
|
272
271
|
});
|
|
273
272
|
defineApiKey({
|
|
274
273
|
configKey: "replicate",
|
|
@@ -458,18 +457,20 @@ var GEMINI_DEFAULT_TEXT_MODEL, GEMINI_AGENT_DEFAULT_TEXT_MODEL, GEMINI_TEXT_MODE
|
|
|
458
457
|
var init_gemini_models = __esm({
|
|
459
458
|
"../ai-providers/dist/gemini/gemini-models.js"() {
|
|
460
459
|
"use strict";
|
|
461
|
-
GEMINI_DEFAULT_TEXT_MODEL = "gemini-3.
|
|
462
|
-
GEMINI_AGENT_DEFAULT_TEXT_MODEL =
|
|
460
|
+
GEMINI_DEFAULT_TEXT_MODEL = "gemini-3.8-flash";
|
|
461
|
+
GEMINI_AGENT_DEFAULT_TEXT_MODEL = GEMINI_DEFAULT_TEXT_MODEL;
|
|
463
462
|
GEMINI_TEXT_MODEL_ALIASES = {
|
|
464
463
|
flash: GEMINI_DEFAULT_TEXT_MODEL,
|
|
465
464
|
latest: GEMINI_DEFAULT_TEXT_MODEL,
|
|
466
|
-
"flash-3.
|
|
465
|
+
"flash-3.8": GEMINI_DEFAULT_TEXT_MODEL,
|
|
466
|
+
"flash-3.5": "gemini-3.5-flash",
|
|
467
467
|
"flash-3": "gemini-3-flash-preview",
|
|
468
468
|
"flash-2.5": "gemini-2.5-flash",
|
|
469
|
-
pro: "gemini-
|
|
470
|
-
"pro-3.1": "gemini-3.1-pro-preview"
|
|
469
|
+
pro: "gemini-3.1-pro-preview",
|
|
470
|
+
"pro-3.1": "gemini-3.1-pro-preview",
|
|
471
|
+
"pro-2.5": "gemini-2.5-pro"
|
|
471
472
|
};
|
|
472
|
-
GEMINI_TEXT_MODEL_HELP = "flash/latest (Gemini 3.
|
|
473
|
+
GEMINI_TEXT_MODEL_HELP = "flash/latest (Gemini 3.8 Flash), flash-3.8, flash-3.5, flash-3, flash-2.5, pro (Gemini 3.1 Pro), pro-3.1, pro-2.5, or a full gemini-* model ID";
|
|
473
474
|
}
|
|
474
475
|
});
|
|
475
476
|
|
|
@@ -656,7 +657,6 @@ UNIVERSAL RULES:
|
|
|
656
657
|
system_instruction: { parts: [{ text: systemPrompt }] },
|
|
657
658
|
contents: [{ role: "user", parts: [{ text: userPrompt }] }],
|
|
658
659
|
generationConfig: {
|
|
659
|
-
temperature: 0.8,
|
|
660
660
|
maxOutputTokens: 16384
|
|
661
661
|
}
|
|
662
662
|
})
|
|
@@ -757,7 +757,7 @@ Return the complete modified component as JSON.`
|
|
|
757
757
|
]
|
|
758
758
|
}
|
|
759
759
|
],
|
|
760
|
-
generationConfig: {
|
|
760
|
+
generationConfig: { maxOutputTokens: 16384 }
|
|
761
761
|
})
|
|
762
762
|
});
|
|
763
763
|
if (!response.ok) {
|
|
@@ -807,10 +807,11 @@ var init_gemini_motion = __esm({
|
|
|
807
807
|
gemini: GEMINI_DEFAULT_TEXT_MODEL,
|
|
808
808
|
flash: GEMINI_DEFAULT_TEXT_MODEL,
|
|
809
809
|
latest: GEMINI_DEFAULT_TEXT_MODEL,
|
|
810
|
-
"flash-3.
|
|
810
|
+
"flash-3.8": GEMINI_DEFAULT_TEXT_MODEL,
|
|
811
|
+
"flash-3.5": "gemini-3.5-flash",
|
|
811
812
|
"flash-3": "gemini-3-flash-preview",
|
|
812
813
|
"flash-2.5": "gemini-2.5-flash",
|
|
813
|
-
pro: "gemini-
|
|
814
|
+
pro: "gemini-3.1-pro-preview",
|
|
814
815
|
"2.5-pro": "gemini-2.5-pro",
|
|
815
816
|
"3.1-pro": "gemini-3.1-pro-preview",
|
|
816
817
|
"pro-3.1": "gemini-3.1-pro-preview"
|
|
@@ -922,7 +923,6 @@ var init_storyboard_prompt = __esm({
|
|
|
922
923
|
async function analyzeContent(api, content, targetDuration, options) {
|
|
923
924
|
const creativity = options?.creativity || "low";
|
|
924
925
|
const systemPrompt = buildStoryboardSystemPrompt(targetDuration, creativity);
|
|
925
|
-
const temperature = creativity === "high" ? 1 : 0.7;
|
|
926
926
|
try {
|
|
927
927
|
const payload = {
|
|
928
928
|
system_instruction: {
|
|
@@ -932,7 +932,6 @@ async function analyzeContent(api, content, targetDuration, options) {
|
|
|
932
932
|
parts: [{ text: buildStoryboardUserMessage(content) }]
|
|
933
933
|
}],
|
|
934
934
|
generationConfig: {
|
|
935
|
-
temperature,
|
|
936
935
|
maxOutputTokens: 4096
|
|
937
936
|
}
|
|
938
937
|
};
|
|
@@ -1003,7 +1002,15 @@ var init_http = __esm({
|
|
|
1003
1002
|
});
|
|
1004
1003
|
|
|
1005
1004
|
// ../ai-providers/dist/gemini/GeminiProvider.js
|
|
1006
|
-
|
|
1005
|
+
function resolveVeoModel(alias) {
|
|
1006
|
+
if (Object.hasOwn(VEO_MODEL_ALIASES, alias)) {
|
|
1007
|
+
return VEO_MODEL_ALIASES[alias];
|
|
1008
|
+
}
|
|
1009
|
+
const valid = Object.keys(VEO_MODEL_ALIASES).join(", ");
|
|
1010
|
+
const hint = alias === "3.0" ? " Veo 3.0 was shut down by Google on 2025-11-12." : "";
|
|
1011
|
+
throw new Error(`Unknown Veo model "${alias}". Valid: ${valid}.${hint}`);
|
|
1012
|
+
}
|
|
1013
|
+
var VEO_MODEL_ALIASES, MODEL_MAP, GeminiProvider, geminiProvider;
|
|
1007
1014
|
var init_GeminiProvider = __esm({
|
|
1008
1015
|
"../ai-providers/dist/gemini/GeminiProvider.js"() {
|
|
1009
1016
|
"use strict";
|
|
@@ -1011,11 +1018,19 @@ var init_GeminiProvider = __esm({
|
|
|
1011
1018
|
init_gemini_models();
|
|
1012
1019
|
init_gemini_storyboard();
|
|
1013
1020
|
init_http();
|
|
1021
|
+
VEO_MODEL_ALIASES = {
|
|
1022
|
+
"3.1": "veo-3.1-generate-preview",
|
|
1023
|
+
"3.1-fast": "veo-3.1-fast-generate-preview"
|
|
1024
|
+
};
|
|
1014
1025
|
MODEL_MAP = {
|
|
1015
|
-
"flash": "gemini-
|
|
1016
|
-
"3.1-flash": "gemini-3.1-flash-image
|
|
1017
|
-
"latest": "gemini-3.1-flash-image
|
|
1018
|
-
"
|
|
1026
|
+
"flash": "gemini-3.1-flash-image",
|
|
1027
|
+
"3.1-flash": "gemini-3.1-flash-image",
|
|
1028
|
+
"latest": "gemini-3.1-flash-image",
|
|
1029
|
+
"lite": "gemini-3.1-flash-lite-image",
|
|
1030
|
+
"pro": "gemini-3-pro-image",
|
|
1031
|
+
"gemini-3.1-flash-image": "gemini-3.1-flash-image",
|
|
1032
|
+
"gemini-3.1-flash-lite-image": "gemini-3.1-flash-lite-image",
|
|
1033
|
+
"gemini-3-pro-image": "gemini-3-pro-image",
|
|
1019
1034
|
"gemini-2.5-flash-image": "gemini-2.5-flash-image",
|
|
1020
1035
|
"gemini-3.1-flash-image-preview": "gemini-3.1-flash-image-preview",
|
|
1021
1036
|
"gemini-3-pro-image-preview": "gemini-3-pro-image-preview"
|
|
@@ -1324,7 +1339,7 @@ var init_GeminiProvider = __esm({
|
|
|
1324
1339
|
contents: [{ parts: [{ text: prompt3 }] }],
|
|
1325
1340
|
generationConfig
|
|
1326
1341
|
};
|
|
1327
|
-
const is31Flash = modelId
|
|
1342
|
+
const is31Flash = modelId.startsWith("gemini-3.1-flash-image");
|
|
1328
1343
|
if (options.imageSearchGrounding && is31Flash) {
|
|
1329
1344
|
payload.tools = [{ googleSearch: { searchTypes: { webSearch: {}, imageSearch: {} } } }];
|
|
1330
1345
|
} else if (options.grounding && isPro) {
|
|
@@ -1552,7 +1567,6 @@ var init_GeminiProvider = __esm({
|
|
|
1552
1567
|
videoPart.video_metadata = videoMetadata;
|
|
1553
1568
|
}
|
|
1554
1569
|
const generationConfig = {
|
|
1555
|
-
temperature: 0.4,
|
|
1556
1570
|
maxOutputTokens: 8192
|
|
1557
1571
|
};
|
|
1558
1572
|
if (options.lowResolution) {
|
|
@@ -1634,7 +1648,6 @@ var init_GeminiProvider = __esm({
|
|
|
1634
1648
|
}
|
|
1635
1649
|
}));
|
|
1636
1650
|
const generationConfig = {
|
|
1637
|
-
temperature: 0.4,
|
|
1638
1651
|
maxOutputTokens: 8192
|
|
1639
1652
|
};
|
|
1640
1653
|
if (options.lowResolution) {
|
|
@@ -1734,7 +1747,6 @@ Respond with ONLY the JSON array, no other text.`;
|
|
|
1734
1747
|
body: JSON.stringify({
|
|
1735
1748
|
contents: [{ parts: [{ text: prompt3 }] }],
|
|
1736
1749
|
generationConfig: {
|
|
1737
|
-
temperature: 0.3,
|
|
1738
1750
|
maxOutputTokens: 1024
|
|
1739
1751
|
}
|
|
1740
1752
|
})
|
|
@@ -1828,7 +1840,7 @@ Respond with ONLY the JSON array, no other text.`;
|
|
|
1828
1840
|
return refineMotion({ apiKey: this.apiKey, baseUrl: this.baseUrl }, existingCode, instructions, options);
|
|
1829
1841
|
}
|
|
1830
1842
|
/**
|
|
1831
|
-
* Generate a storyboard from script content using Gemini
|
|
1843
|
+
* Generate a storyboard from script content using the default Gemini Flash model.
|
|
1832
1844
|
* Alternative to ClaudeProvider.analyzeContent for when Claude is unavailable.
|
|
1833
1845
|
*/
|
|
1834
1846
|
async analyzeContent(content, targetDuration, options) {
|
|
@@ -1843,43 +1855,47 @@ Respond with ONLY the JSON array, no other text.`;
|
|
|
1843
1855
|
});
|
|
1844
1856
|
|
|
1845
1857
|
// ../ai-providers/dist/gemini/gemini-omni.js
|
|
1846
|
-
function
|
|
1847
|
-
const
|
|
1848
|
-
|
|
1849
|
-
return refs3[0];
|
|
1850
|
-
const ref2 = options.referenceImage;
|
|
1851
|
-
if (typeof ref2 === "string" && ref2) {
|
|
1858
|
+
function frameImages(options) {
|
|
1859
|
+
const frames = [];
|
|
1860
|
+
const toInline = (ref2) => {
|
|
1852
1861
|
const m2 = ref2.match(/^data:(.+?);base64,(.*)$/);
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1862
|
+
return m2 ? { mimeType: m2[1], base64: m2[2] } : { mimeType: "image/png", base64: ref2 };
|
|
1863
|
+
};
|
|
1864
|
+
if (options.referenceImages?.[0]?.base64)
|
|
1865
|
+
frames.push(options.referenceImages[0]);
|
|
1866
|
+
else if (typeof options.referenceImage === "string" && options.referenceImage) {
|
|
1867
|
+
frames.push(toInline(options.referenceImage));
|
|
1856
1868
|
}
|
|
1857
|
-
|
|
1869
|
+
if (frames.length > 0 && options.lastFrame)
|
|
1870
|
+
frames.push(toInline(options.lastFrame));
|
|
1871
|
+
return frames;
|
|
1858
1872
|
}
|
|
1859
|
-
function
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
const nested = findVideoUrl(v4);
|
|
1867
|
-
if (nested)
|
|
1868
|
-
return nested;
|
|
1869
|
-
}
|
|
1873
|
+
function findOmniVideo(response) {
|
|
1874
|
+
for (const step of response.steps ?? []) {
|
|
1875
|
+
if (step.type !== "model_output")
|
|
1876
|
+
continue;
|
|
1877
|
+
const video = step.content?.find((c2) => c2.type === "video");
|
|
1878
|
+
if (video)
|
|
1879
|
+
return video;
|
|
1870
1880
|
}
|
|
1871
|
-
return
|
|
1881
|
+
return response.output_video;
|
|
1882
|
+
}
|
|
1883
|
+
function fileIdFromUri(uri) {
|
|
1884
|
+
return uri.match(/files\/([^/?:]+)/)?.[1];
|
|
1872
1885
|
}
|
|
1873
|
-
var OMNI_MODEL,
|
|
1886
|
+
var OMNI_MODEL, API_ROOT, FILE_POLL_INTERVAL_MS, FILE_POLL_TIMEOUT_MS, OmniProvider, omniProvider;
|
|
1874
1887
|
var init_gemini_omni = __esm({
|
|
1875
1888
|
"../ai-providers/dist/gemini/gemini-omni.js"() {
|
|
1876
1889
|
"use strict";
|
|
1877
|
-
|
|
1878
|
-
|
|
1890
|
+
init_http();
|
|
1891
|
+
OMNI_MODEL = "gemini-omni-1.1-flash";
|
|
1892
|
+
API_ROOT = "https://generativelanguage.googleapis.com";
|
|
1893
|
+
FILE_POLL_INTERVAL_MS = 3e3;
|
|
1894
|
+
FILE_POLL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
1879
1895
|
OmniProvider = class {
|
|
1880
1896
|
constructor() {
|
|
1881
1897
|
this.id = "omni";
|
|
1882
|
-
this.label = "Gemini Omni
|
|
1898
|
+
this.label = "Gemini Omni 1.1 Flash";
|
|
1883
1899
|
}
|
|
1884
1900
|
async initialize(config4) {
|
|
1885
1901
|
this.apiKey = config4.apiKey;
|
|
@@ -1892,22 +1908,23 @@ var init_gemini_omni = __esm({
|
|
|
1892
1908
|
return { id: "", status: "failed", error: "GOOGLE_API_KEY not configured for Gemini Omni" };
|
|
1893
1909
|
}
|
|
1894
1910
|
const opts = options ?? { prompt: prompt3 };
|
|
1895
|
-
const
|
|
1896
|
-
const
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
inputs.push({ inline_data: { mime_type: image.mimeType, data: image.base64 } });
|
|
1901
|
-
}
|
|
1911
|
+
const frames = frameImages(opts);
|
|
1912
|
+
const input3 = frames.length === 0 ? prompt3 : [
|
|
1913
|
+
...frames.map((f2) => ({ type: "image", data: f2.base64, mime_type: f2.mimeType })),
|
|
1914
|
+
{ type: "text", text: prompt3 }
|
|
1915
|
+
];
|
|
1902
1916
|
const body = {
|
|
1903
1917
|
model: OMNI_MODEL,
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1918
|
+
input: input3,
|
|
1919
|
+
response_format: {
|
|
1920
|
+
type: "video",
|
|
1921
|
+
aspect_ratio: opts.aspectRatio === "9:16" ? "9:16" : "16:9",
|
|
1922
|
+
resolution: opts.resolution ?? "720p",
|
|
1923
|
+
delivery: "uri"
|
|
1907
1924
|
}
|
|
1908
1925
|
};
|
|
1909
1926
|
try {
|
|
1910
|
-
const res = await fetch(
|
|
1927
|
+
const res = await fetch(`${API_ROOT}/v1beta/interactions`, {
|
|
1911
1928
|
method: "POST",
|
|
1912
1929
|
headers: { "Content-Type": "application/json", "x-goog-api-key": this.apiKey },
|
|
1913
1930
|
body: JSON.stringify(body)
|
|
@@ -1917,33 +1934,52 @@ var init_gemini_omni = __esm({
|
|
|
1917
1934
|
return {
|
|
1918
1935
|
id: "",
|
|
1919
1936
|
status: "failed",
|
|
1920
|
-
error: `Gemini Omni
|
|
1937
|
+
error: `Gemini Omni request failed: HTTP ${res.status} - ${text.slice(0, 300)}`
|
|
1921
1938
|
};
|
|
1922
1939
|
}
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1940
|
+
const parsed = JSON.parse(text);
|
|
1941
|
+
const id = parsed.id ?? "";
|
|
1942
|
+
const video = findOmniVideo(parsed);
|
|
1943
|
+
if (!video?.uri) {
|
|
1944
|
+
const reason = parsed.error?.message ?? `status ${parsed.status ?? "unknown"}`;
|
|
1945
|
+
return { id, status: "failed", error: `Gemini Omni returned no video (${reason})` };
|
|
1928
1946
|
}
|
|
1929
|
-
const
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
};
|
|
1947
|
+
const fileId = fileIdFromUri(video.uri);
|
|
1948
|
+
if (!fileId) {
|
|
1949
|
+
return { id, status: "failed", error: `Gemini Omni returned an unexpected video URI: ${video.uri}` };
|
|
1950
|
+
}
|
|
1951
|
+
const ready = await this.waitForFile(fileId);
|
|
1952
|
+
if (ready !== "ACTIVE") {
|
|
1953
|
+
return { id, status: "failed", error: `Gemini Omni video file ended in state ${ready}` };
|
|
1937
1954
|
}
|
|
1938
|
-
return {
|
|
1955
|
+
return {
|
|
1956
|
+
id,
|
|
1957
|
+
status: "completed",
|
|
1958
|
+
videoUrl: `${API_ROOT}/download/v1beta/files/${fileId}:download?alt=media`
|
|
1959
|
+
};
|
|
1939
1960
|
} catch (err) {
|
|
1940
1961
|
return {
|
|
1941
1962
|
id: "",
|
|
1942
1963
|
status: "failed",
|
|
1943
|
-
error: `Gemini Omni
|
|
1964
|
+
error: `Gemini Omni error: ${err instanceof Error ? err.message : String(err)}`
|
|
1944
1965
|
};
|
|
1945
1966
|
}
|
|
1946
1967
|
}
|
|
1968
|
+
/** Poll the Files API until the generated video is downloadable. */
|
|
1969
|
+
async waitForFile(fileId) {
|
|
1970
|
+
const deadline = Date.now() + FILE_POLL_TIMEOUT_MS;
|
|
1971
|
+
for (; ; ) {
|
|
1972
|
+
const res = await fetch(`${API_ROOT}/v1beta/files/${fileId}`, {
|
|
1973
|
+
headers: { "x-goog-api-key": this.apiKey }
|
|
1974
|
+
});
|
|
1975
|
+
const state = res.ok ? (await res.json()).state : `HTTP ${res.status}`;
|
|
1976
|
+
if (state !== "PROCESSING")
|
|
1977
|
+
return state ?? "UNKNOWN";
|
|
1978
|
+
if (Date.now() > deadline)
|
|
1979
|
+
return "TIMEOUT";
|
|
1980
|
+
await sleep(FILE_POLL_INTERVAL_MS);
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1947
1983
|
};
|
|
1948
1984
|
omniProvider = new OmniProvider();
|
|
1949
1985
|
}
|
|
@@ -1977,14 +2013,16 @@ var init_gemini = __esm({
|
|
|
1977
2013
|
label: "Veo",
|
|
1978
2014
|
apiKey: "google",
|
|
1979
2015
|
kinds: ["video"],
|
|
1980
|
-
resolverPriority:
|
|
2016
|
+
// No resolverPriority: the Veo 3.1 previews shut down on 2026-10-22, so
|
|
2017
|
+
// Veo is explicit-only (`-p veo`) and Omni is the Google default.
|
|
1981
2018
|
commandsUnlocked: ["generate video -p veo"]
|
|
1982
2019
|
});
|
|
1983
2020
|
defineProvider({
|
|
1984
2021
|
id: "omni",
|
|
1985
|
-
label: "Gemini Omni
|
|
2022
|
+
label: "Gemini Omni",
|
|
1986
2023
|
apiKey: "google",
|
|
1987
2024
|
kinds: ["video"],
|
|
2025
|
+
resolverPriority: { video: 3 },
|
|
1988
2026
|
commandsUnlocked: ["generate video -p omni"]
|
|
1989
2027
|
});
|
|
1990
2028
|
}
|
|
@@ -1993,8 +2031,7 @@ var init_gemini = __esm({
|
|
|
1993
2031
|
// ../ai-providers/dist/openai/openai-storyboard.js
|
|
1994
2032
|
async function analyzeContent2(apiKey, content, targetDuration, options) {
|
|
1995
2033
|
const creativity = options?.creativity || "low";
|
|
1996
|
-
const systemPrompt = buildStoryboardSystemPrompt(targetDuration, creativity);
|
|
1997
|
-
const temperature = creativity === "high" ? 1 : 0.7;
|
|
2034
|
+
const systemPrompt = buildStoryboardSystemPrompt(targetDuration, creativity) + '\n\nWrap the array in a JSON object: {"segments": [ ...segment objects... ]}.';
|
|
1998
2035
|
try {
|
|
1999
2036
|
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
2000
2037
|
method: "POST",
|
|
@@ -2003,13 +2040,13 @@ async function analyzeContent2(apiKey, content, targetDuration, options) {
|
|
|
2003
2040
|
Authorization: `Bearer ${apiKey}`
|
|
2004
2041
|
},
|
|
2005
2042
|
body: JSON.stringify({
|
|
2006
|
-
model: "gpt-5-mini",
|
|
2043
|
+
model: "gpt-5.4-mini",
|
|
2007
2044
|
messages: [
|
|
2008
2045
|
{ role: "system", content: systemPrompt },
|
|
2009
2046
|
{ role: "user", content: buildStoryboardUserMessage(content) }
|
|
2010
2047
|
],
|
|
2011
|
-
|
|
2012
|
-
|
|
2048
|
+
// Reasoning tokens count against this cap.
|
|
2049
|
+
max_completion_tokens: 16384,
|
|
2013
2050
|
response_format: { type: "json_object" }
|
|
2014
2051
|
})
|
|
2015
2052
|
});
|
|
@@ -2066,7 +2103,7 @@ var init_OpenAIProvider = __esm({
|
|
|
2066
2103
|
this.iconUrl = "/icons/openai.svg";
|
|
2067
2104
|
this.isAvailable = true;
|
|
2068
2105
|
this.baseUrl = "https://api.openai.com/v1";
|
|
2069
|
-
this.model = "gpt-5-mini";
|
|
2106
|
+
this.model = "gpt-5.4-mini";
|
|
2070
2107
|
}
|
|
2071
2108
|
async initialize(config4) {
|
|
2072
2109
|
this.apiKey = config4.apiKey;
|
|
@@ -2162,7 +2199,6 @@ Or if clarification needed:
|
|
|
2162
2199
|
{ role: "system", content: systemPrompt },
|
|
2163
2200
|
{ role: "user", content: instruction }
|
|
2164
2201
|
],
|
|
2165
|
-
temperature: 0.2,
|
|
2166
2202
|
response_format: { type: "json_object" }
|
|
2167
2203
|
})
|
|
2168
2204
|
});
|
|
@@ -2373,8 +2409,9 @@ Each segment should be 3-10 seconds long.`;
|
|
|
2373
2409
|
Authorization: `Bearer ${this.apiKey}`
|
|
2374
2410
|
},
|
|
2375
2411
|
body: JSON.stringify({
|
|
2376
|
-
model: "gpt-5-mini",
|
|
2377
|
-
|
|
2412
|
+
model: "gpt-5.4-mini",
|
|
2413
|
+
// Reasoning tokens count against this cap.
|
|
2414
|
+
max_completion_tokens: 16384,
|
|
2378
2415
|
response_format: { type: "json_object" },
|
|
2379
2416
|
messages: [
|
|
2380
2417
|
{ role: "system", content: systemPrompt },
|
|
@@ -2407,7 +2444,7 @@ ${videoAnalysis}` }
|
|
|
2407
2444
|
}
|
|
2408
2445
|
}
|
|
2409
2446
|
/**
|
|
2410
|
-
* Generate a storyboard from script content using GPT-5
|
|
2447
|
+
* Generate a storyboard from script content using GPT-5.4 mini.
|
|
2411
2448
|
* Alternative to ClaudeProvider.analyzeContent for when Claude is unavailable.
|
|
2412
2449
|
*/
|
|
2413
2450
|
async analyzeContent(content, targetDuration, options) {
|
|
@@ -2455,10 +2492,12 @@ async function callClaude(params, opts) {
|
|
|
2455
2492
|
},
|
|
2456
2493
|
body: JSON.stringify({
|
|
2457
2494
|
model: params.model,
|
|
2458
|
-
|
|
2459
|
-
|
|
2495
|
+
// Claude 5.x thinks by default and thinking tokens count against
|
|
2496
|
+
// max_tokens, so a small cap can end before any text is written.
|
|
2497
|
+
max_tokens: Math.max(opts.maxTokens, CLAUDE_MIN_MAX_TOKENS),
|
|
2460
2498
|
messages: opts.messages,
|
|
2461
|
-
system: opts.system
|
|
2499
|
+
system: opts.system,
|
|
2500
|
+
...opts.jsonSchema ? { output_config: { format: { type: "json_schema", schema: opts.jsonSchema } } } : {}
|
|
2462
2501
|
})
|
|
2463
2502
|
});
|
|
2464
2503
|
if (!response.ok) {
|
|
@@ -2480,9 +2519,11 @@ function extractJsonArray(text) {
|
|
|
2480
2519
|
const match2 = text.match(/\[[\s\S]*\]/);
|
|
2481
2520
|
return match2 ? match2[0] : null;
|
|
2482
2521
|
}
|
|
2522
|
+
var CLAUDE_MIN_MAX_TOKENS;
|
|
2483
2523
|
var init_claude_api = __esm({
|
|
2484
2524
|
"../ai-providers/dist/claude/claude-api.js"() {
|
|
2485
2525
|
"use strict";
|
|
2526
|
+
CLAUDE_MIN_MAX_TOKENS = 16e3;
|
|
2486
2527
|
}
|
|
2487
2528
|
});
|
|
2488
2529
|
|
|
@@ -2518,7 +2559,8 @@ MANDATORY ADAPTATION RULES:
|
|
|
2518
2559
|
const text = await callClaude(api, {
|
|
2519
2560
|
system: systemPrompt,
|
|
2520
2561
|
messages: [{ role: "user", content: userContent }],
|
|
2521
|
-
maxTokens: 16e3
|
|
2562
|
+
maxTokens: 16e3,
|
|
2563
|
+
jsonSchema: MOTION_COMPONENT_SCHEMA
|
|
2522
2564
|
});
|
|
2523
2565
|
const jsonStr = extractJsonObject(text);
|
|
2524
2566
|
if (!jsonStr) {
|
|
@@ -2593,7 +2635,8 @@ Modification instructions: ${instructions}
|
|
|
2593
2635
|
|
|
2594
2636
|
Return the complete modified component as JSON.`
|
|
2595
2637
|
}],
|
|
2596
|
-
maxTokens: 16e3
|
|
2638
|
+
maxTokens: 16e3,
|
|
2639
|
+
jsonSchema: MOTION_COMPONENT_SCHEMA
|
|
2597
2640
|
});
|
|
2598
2641
|
const jsonStr = extractJsonObject(text);
|
|
2599
2642
|
if (!jsonStr)
|
|
@@ -2622,15 +2665,13 @@ async function analyzeContent3(api, content, targetDuration, options) {
|
|
|
2622
2665
|
const creativity = options?.creativity || "low";
|
|
2623
2666
|
const systemPrompt = buildStoryboardSystemPrompt(targetDuration, creativity);
|
|
2624
2667
|
try {
|
|
2625
|
-
const temperature = creativity === "high" ? 1 : 0.7;
|
|
2626
2668
|
const text = await callClaude(api, {
|
|
2627
2669
|
system: systemPrompt,
|
|
2628
2670
|
messages: [{
|
|
2629
2671
|
role: "user",
|
|
2630
2672
|
content: buildStoryboardUserMessage(content)
|
|
2631
2673
|
}],
|
|
2632
|
-
maxTokens: 4096
|
|
2633
|
-
temperature
|
|
2674
|
+
maxTokens: 4096
|
|
2634
2675
|
});
|
|
2635
2676
|
const jsonStr = extractJsonArray(text);
|
|
2636
2677
|
if (!jsonStr) {
|
|
@@ -2987,11 +3028,22 @@ UNIVERSAL RULES:
|
|
|
2987
3028
|
- Both entrance AND exit animations
|
|
2988
3029
|
- whiteSpace: "nowrap" on all text`;
|
|
2989
3030
|
}
|
|
3031
|
+
var MOTION_COMPONENT_SCHEMA;
|
|
2990
3032
|
var init_claude_motion = __esm({
|
|
2991
3033
|
"../ai-providers/dist/claude/claude-motion.js"() {
|
|
2992
3034
|
"use strict";
|
|
2993
3035
|
init_claude_api();
|
|
2994
3036
|
init_storyboard_prompt();
|
|
3037
|
+
MOTION_COMPONENT_SCHEMA = {
|
|
3038
|
+
type: "object",
|
|
3039
|
+
properties: {
|
|
3040
|
+
name: { type: "string" },
|
|
3041
|
+
code: { type: "string" },
|
|
3042
|
+
description: { type: "string" }
|
|
3043
|
+
},
|
|
3044
|
+
required: ["name", "code", "description"],
|
|
3045
|
+
additionalProperties: false
|
|
3046
|
+
};
|
|
2995
3047
|
}
|
|
2996
3048
|
});
|
|
2997
3049
|
|
|
@@ -3753,6 +3805,7 @@ var ClaudeProvider, claudeProvider;
|
|
|
3753
3805
|
var init_ClaudeProvider = __esm({
|
|
3754
3806
|
"../ai-providers/dist/claude/ClaudeProvider.js"() {
|
|
3755
3807
|
"use strict";
|
|
3808
|
+
init_claude_api();
|
|
3756
3809
|
init_claude_motion();
|
|
3757
3810
|
init_claude_analysis();
|
|
3758
3811
|
init_claude_viral();
|
|
@@ -3766,7 +3819,7 @@ var init_ClaudeProvider = __esm({
|
|
|
3766
3819
|
this.iconUrl = "/icons/claude.svg";
|
|
3767
3820
|
this.isAvailable = true;
|
|
3768
3821
|
this.baseUrl = "https://api.anthropic.com/v1";
|
|
3769
|
-
this.model = "claude-sonnet-
|
|
3822
|
+
this.model = "claude-sonnet-5-5";
|
|
3770
3823
|
}
|
|
3771
3824
|
async initialize(config4) {
|
|
3772
3825
|
this.apiKey = config4.apiKey;
|
|
@@ -3870,7 +3923,7 @@ Or if clarification needed:
|
|
|
3870
3923
|
},
|
|
3871
3924
|
body: JSON.stringify({
|
|
3872
3925
|
model: this.model,
|
|
3873
|
-
max_tokens:
|
|
3926
|
+
max_tokens: CLAUDE_MIN_MAX_TOKENS,
|
|
3874
3927
|
messages: [{ role: "user", content: instruction }],
|
|
3875
3928
|
system: systemPrompt
|
|
3876
3929
|
})
|
|
@@ -3940,7 +3993,7 @@ Respond with JSON array:
|
|
|
3940
3993
|
},
|
|
3941
3994
|
body: JSON.stringify({
|
|
3942
3995
|
model: this.model,
|
|
3943
|
-
max_tokens:
|
|
3996
|
+
max_tokens: CLAUDE_MIN_MAX_TOKENS,
|
|
3944
3997
|
messages: [{
|
|
3945
3998
|
role: "user",
|
|
3946
3999
|
content: `Clips: ${JSON.stringify(clipsInfo)}
|
|
@@ -4069,8 +4122,8 @@ Instruction: ${instruction}`
|
|
|
4069
4122
|
}
|
|
4070
4123
|
};
|
|
4071
4124
|
ClaudeProvider.MOTION_MODELS = {
|
|
4072
|
-
sonnet: "claude-sonnet-
|
|
4073
|
-
opus: "claude-opus-
|
|
4125
|
+
sonnet: "claude-sonnet-5-5",
|
|
4126
|
+
opus: "claude-opus-5-5",
|
|
4074
4127
|
"opus-4-6": "claude-opus-4-6"
|
|
4075
4128
|
};
|
|
4076
4129
|
claudeProvider = new ClaudeProvider();
|
|
@@ -4408,7 +4461,7 @@ function resolveVoiceId(input3) {
|
|
|
4408
4461
|
const availableVoices = Object.keys(KNOWN_VOICES).join(", ");
|
|
4409
4462
|
throw new Error(`Unknown voice "${input3}". Available voices: ${availableVoices}. You can also use a custom voice ID from your ElevenLabs account.`);
|
|
4410
4463
|
}
|
|
4411
|
-
var KNOWN_VOICES, TTS_429_MAX_RETRIES, TTS_429_RETRY_DELAY_MS, ElevenLabsProvider, elevenLabsProvider;
|
|
4464
|
+
var KNOWN_VOICES, TTS_429_MAX_RETRIES, TTS_429_RETRY_DELAY_MS, ELEVENLABS_MUSIC_MODEL, ElevenLabsProvider, elevenLabsProvider;
|
|
4412
4465
|
var init_ElevenLabsProvider = __esm({
|
|
4413
4466
|
"../ai-providers/dist/elevenlabs/ElevenLabsProvider.js"() {
|
|
4414
4467
|
"use strict";
|
|
@@ -4445,6 +4498,7 @@ var init_ElevenLabsProvider = __esm({
|
|
|
4445
4498
|
};
|
|
4446
4499
|
TTS_429_MAX_RETRIES = 1;
|
|
4447
4500
|
TTS_429_RETRY_DELAY_MS = 2e3;
|
|
4501
|
+
ELEVENLABS_MUSIC_MODEL = "music_v2_5";
|
|
4448
4502
|
ElevenLabsProvider = class {
|
|
4449
4503
|
constructor() {
|
|
4450
4504
|
this.id = "elevenlabs";
|
|
@@ -4525,9 +4579,10 @@ var init_ElevenLabsProvider = __esm({
|
|
|
4525
4579
|
stability: options.stability ?? 0.5,
|
|
4526
4580
|
similarity_boost: options.similarityBoost ?? 0.75,
|
|
4527
4581
|
style: options.style ?? 0,
|
|
4528
|
-
use_speaker_boost: true
|
|
4529
|
-
|
|
4530
|
-
|
|
4582
|
+
use_speaker_boost: true,
|
|
4583
|
+
// The API reads speed only inside voice_settings.
|
|
4584
|
+
...options.speed !== void 0 && { speed: options.speed }
|
|
4585
|
+
}
|
|
4531
4586
|
})
|
|
4532
4587
|
});
|
|
4533
4588
|
if (response.status === 429 && attempt < TTS_429_MAX_RETRIES) {
|
|
@@ -4597,7 +4652,7 @@ var init_ElevenLabsProvider = __esm({
|
|
|
4597
4652
|
prompt_influence: options.promptInfluence ?? 0.3
|
|
4598
4653
|
};
|
|
4599
4654
|
if (options.duration !== void 0) {
|
|
4600
|
-
const duration = Math.max(0.5, Math.min(
|
|
4655
|
+
const duration = Math.max(0.5, Math.min(30, options.duration));
|
|
4601
4656
|
body.duration_seconds = duration;
|
|
4602
4657
|
}
|
|
4603
4658
|
const response = await fetch(`${this.baseUrl}/sound-generation`, {
|
|
@@ -4642,7 +4697,7 @@ var init_ElevenLabsProvider = __esm({
|
|
|
4642
4697
|
try {
|
|
4643
4698
|
const body = {
|
|
4644
4699
|
prompt: prompt3,
|
|
4645
|
-
model_id:
|
|
4700
|
+
model_id: ELEVENLABS_MUSIC_MODEL
|
|
4646
4701
|
};
|
|
4647
4702
|
if (options.duration !== void 0) {
|
|
4648
4703
|
const duration = Math.max(3, Math.min(600, options.duration));
|
|
@@ -4853,6 +4908,55 @@ var init_elevenlabs = __esm({
|
|
|
4853
4908
|
});
|
|
4854
4909
|
|
|
4855
4910
|
// ../ai-providers/dist/kokoro/KokoroProvider.js
|
|
4911
|
+
function splitForKokoro(text, maxChars = KOKORO_MAX_CHUNK_CHARS) {
|
|
4912
|
+
const pieces = (part, pattern) => part.length <= maxChars ? [part] : part.split(pattern).filter((p2) => p2.trim().length > 0);
|
|
4913
|
+
const units2 = text.trim().split(/(?<=[.!?…])\s+/).flatMap((sentence) => pieces(sentence, /(?<=[,;:])\s+/)).flatMap((clause) => {
|
|
4914
|
+
if (clause.length <= maxChars)
|
|
4915
|
+
return [clause];
|
|
4916
|
+
const words = [];
|
|
4917
|
+
let line = "";
|
|
4918
|
+
for (const word of clause.split(/\s+/)) {
|
|
4919
|
+
if (line && line.length + word.length + 1 > maxChars) {
|
|
4920
|
+
words.push(line);
|
|
4921
|
+
line = word;
|
|
4922
|
+
} else {
|
|
4923
|
+
line = line ? `${line} ${word}` : word;
|
|
4924
|
+
}
|
|
4925
|
+
}
|
|
4926
|
+
if (line)
|
|
4927
|
+
words.push(line);
|
|
4928
|
+
return words;
|
|
4929
|
+
});
|
|
4930
|
+
const chunks = [];
|
|
4931
|
+
for (const unit of units2) {
|
|
4932
|
+
const last3 = chunks.at(-1);
|
|
4933
|
+
if (last3 !== void 0 && last3.length + unit.length + 1 <= maxChars) {
|
|
4934
|
+
chunks[chunks.length - 1] = `${last3} ${unit}`;
|
|
4935
|
+
} else {
|
|
4936
|
+
chunks.push(unit);
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
return chunks;
|
|
4940
|
+
}
|
|
4941
|
+
function encodeFloatWav(samples, sampleRate) {
|
|
4942
|
+
const dataBytes = samples.length * 4;
|
|
4943
|
+
const buffer = Buffer.alloc(44 + dataBytes);
|
|
4944
|
+
buffer.write("RIFF", 0, "ascii");
|
|
4945
|
+
buffer.writeUInt32LE(36 + dataBytes, 4);
|
|
4946
|
+
buffer.write("WAVE", 8, "ascii");
|
|
4947
|
+
buffer.write("fmt ", 12, "ascii");
|
|
4948
|
+
buffer.writeUInt32LE(16, 16);
|
|
4949
|
+
buffer.writeUInt16LE(3, 20);
|
|
4950
|
+
buffer.writeUInt16LE(1, 22);
|
|
4951
|
+
buffer.writeUInt32LE(sampleRate, 24);
|
|
4952
|
+
buffer.writeUInt32LE(sampleRate * 4, 28);
|
|
4953
|
+
buffer.writeUInt16LE(4, 32);
|
|
4954
|
+
buffer.writeUInt16LE(32, 34);
|
|
4955
|
+
buffer.write("data", 36, "ascii");
|
|
4956
|
+
buffer.writeUInt32LE(dataBytes, 40);
|
|
4957
|
+
Buffer.from(samples.buffer, samples.byteOffset, dataBytes).copy(buffer, 44);
|
|
4958
|
+
return buffer;
|
|
4959
|
+
}
|
|
4856
4960
|
async function loadKokoroRuntime() {
|
|
4857
4961
|
if (factoryOverride)
|
|
4858
4962
|
return { factory: factoryOverride, device: "cpu" };
|
|
@@ -4890,7 +4994,7 @@ async function loadBundledKokoroRuntime(runtimeDir = process.env.VIBE_KOKORO_RUN
|
|
|
4890
4994
|
if (!base2)
|
|
4891
4995
|
return null;
|
|
4892
4996
|
try {
|
|
4893
|
-
const { readFile: readFile48, writeFile:
|
|
4997
|
+
const { readFile: readFile48, writeFile: writeFile51, mkdir: mkdir33 } = await import("node:fs/promises");
|
|
4894
4998
|
const { join: join79, resolve: resolve86 } = await import("node:path");
|
|
4895
4999
|
const { pathToFileURL: pathToFileURL2 } = await import("node:url");
|
|
4896
5000
|
const { homedir: homedir8 } = await import("node:os");
|
|
@@ -4911,8 +5015,8 @@ async function loadBundledKokoroRuntime(runtimeDir = process.env.VIBE_KOKORO_RUN
|
|
|
4911
5015
|
async put(key2, response) {
|
|
4912
5016
|
try {
|
|
4913
5017
|
const buf = Buffer.from(await response.arrayBuffer());
|
|
4914
|
-
await
|
|
4915
|
-
await
|
|
5018
|
+
await mkdir33(cacheRoot, { recursive: true });
|
|
5019
|
+
await writeFile51(join79(cacheRoot, encodeURIComponent(String(key2))), buf);
|
|
4916
5020
|
} catch {
|
|
4917
5021
|
}
|
|
4918
5022
|
}
|
|
@@ -4961,12 +5065,13 @@ function normaliseEvent(raw2) {
|
|
|
4961
5065
|
total: typeof r2.total === "number" ? r2.total : void 0
|
|
4962
5066
|
};
|
|
4963
5067
|
}
|
|
4964
|
-
var KOKORO_DEFAULT_VOICE, KOKORO_MODEL_ID, modelPromise, factoryOverride, KokoroProvider, kokoroProvider;
|
|
5068
|
+
var KOKORO_DEFAULT_VOICE, KOKORO_MODEL_ID, KOKORO_MAX_CHUNK_CHARS, modelPromise, factoryOverride, KokoroProvider, kokoroProvider;
|
|
4965
5069
|
var init_KokoroProvider = __esm({
|
|
4966
5070
|
"../ai-providers/dist/kokoro/KokoroProvider.js"() {
|
|
4967
5071
|
"use strict";
|
|
4968
5072
|
KOKORO_DEFAULT_VOICE = "af_heart";
|
|
4969
5073
|
KOKORO_MODEL_ID = "onnx-community/Kokoro-82M-v1.0-ONNX";
|
|
5074
|
+
KOKORO_MAX_CHUNK_CHARS = 300;
|
|
4970
5075
|
modelPromise = null;
|
|
4971
5076
|
factoryOverride = null;
|
|
4972
5077
|
KokoroProvider = class {
|
|
@@ -4993,11 +5098,32 @@ var init_KokoroProvider = __esm({
|
|
|
4993
5098
|
}
|
|
4994
5099
|
try {
|
|
4995
5100
|
const model = await loadModel(options.onProgress);
|
|
4996
|
-
const
|
|
5101
|
+
const voiceOptions = {
|
|
4997
5102
|
voice: options.voice ?? KOKORO_DEFAULT_VOICE,
|
|
4998
5103
|
speed: options.speed ?? 1
|
|
4999
|
-
}
|
|
5000
|
-
const
|
|
5104
|
+
};
|
|
5105
|
+
const chunks = splitForKokoro(text);
|
|
5106
|
+
let buffer;
|
|
5107
|
+
if (chunks.length === 1) {
|
|
5108
|
+
buffer = Buffer.from((await model.generate(chunks[0], voiceOptions)).toWav());
|
|
5109
|
+
} else {
|
|
5110
|
+
const parts = [];
|
|
5111
|
+
let sampleRate = 24e3;
|
|
5112
|
+
for (const chunk of chunks) {
|
|
5113
|
+
const audio = await model.generate(chunk, voiceOptions);
|
|
5114
|
+
if (!audio.audio)
|
|
5115
|
+
throw new Error("Kokoro returned no raw samples to join");
|
|
5116
|
+
parts.push(audio.audio);
|
|
5117
|
+
sampleRate = audio.sampling_rate ?? sampleRate;
|
|
5118
|
+
}
|
|
5119
|
+
const samples = new Float32Array(parts.reduce((n2, part) => n2 + part.length, 0));
|
|
5120
|
+
let offset = 0;
|
|
5121
|
+
for (const part of parts) {
|
|
5122
|
+
samples.set(part, offset);
|
|
5123
|
+
offset += part.length;
|
|
5124
|
+
}
|
|
5125
|
+
buffer = encodeFloatWav(samples, sampleRate);
|
|
5126
|
+
}
|
|
5001
5127
|
return {
|
|
5002
5128
|
success: true,
|
|
5003
5129
|
audioBuffer: buffer,
|
|
@@ -5032,11 +5158,12 @@ var init_kokoro = __esm({
|
|
|
5032
5158
|
});
|
|
5033
5159
|
|
|
5034
5160
|
// ../ai-providers/dist/openai-image/OpenAIImageProvider.js
|
|
5035
|
-
var DEFAULT_MODEL, OpenAIImageProvider, openaiImageProvider;
|
|
5161
|
+
var OPENAI_IMAGE_DEFAULT_MODEL, DEFAULT_MODEL, OpenAIImageProvider, openaiImageProvider;
|
|
5036
5162
|
var init_OpenAIImageProvider = __esm({
|
|
5037
5163
|
"../ai-providers/dist/openai-image/OpenAIImageProvider.js"() {
|
|
5038
5164
|
"use strict";
|
|
5039
|
-
|
|
5165
|
+
OPENAI_IMAGE_DEFAULT_MODEL = "gpt-image-2.5-sunburst";
|
|
5166
|
+
DEFAULT_MODEL = OPENAI_IMAGE_DEFAULT_MODEL;
|
|
5040
5167
|
OpenAIImageProvider = class {
|
|
5041
5168
|
constructor() {
|
|
5042
5169
|
this.id = "openai-image";
|
|
@@ -5058,7 +5185,7 @@ var init_OpenAIImageProvider = __esm({
|
|
|
5058
5185
|
}
|
|
5059
5186
|
/**
|
|
5060
5187
|
* Generate images from text prompt
|
|
5061
|
-
* Uses GPT Image
|
|
5188
|
+
* Uses GPT Image 2.5 Sunburst by default
|
|
5062
5189
|
*/
|
|
5063
5190
|
async generateImage(prompt3, options = {}) {
|
|
5064
5191
|
if (!this.apiKey) {
|
|
@@ -5068,28 +5195,20 @@ var init_OpenAIImageProvider = __esm({
|
|
|
5068
5195
|
};
|
|
5069
5196
|
}
|
|
5070
5197
|
const model = options.model || DEFAULT_MODEL;
|
|
5071
|
-
const isGPTImage = model === "gpt-image-1.5" || model === "gpt-image-2";
|
|
5072
5198
|
try {
|
|
5073
5199
|
const body = {
|
|
5074
5200
|
model,
|
|
5075
5201
|
prompt: prompt3,
|
|
5076
5202
|
n: options.n || 1
|
|
5077
5203
|
};
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
body.size = options.size;
|
|
5087
|
-
}
|
|
5088
|
-
} else {
|
|
5089
|
-
body.response_format = "url";
|
|
5090
|
-
body.size = options.size || "1024x1024";
|
|
5091
|
-
body.quality = options.quality === "high" ? "hd" : options.quality || "standard";
|
|
5092
|
-
body.style = options.style || "vivid";
|
|
5204
|
+
const qualityMap = {
|
|
5205
|
+
standard: "medium",
|
|
5206
|
+
hd: "high"
|
|
5207
|
+
};
|
|
5208
|
+
const quality = options.quality || "medium";
|
|
5209
|
+
body.quality = qualityMap[quality] || quality;
|
|
5210
|
+
if (options.size && options.size !== "auto") {
|
|
5211
|
+
body.size = options.size;
|
|
5093
5212
|
}
|
|
5094
5213
|
const response = await fetch(`${this.baseUrl}/images/generations`, {
|
|
5095
5214
|
method: "POST",
|
|
@@ -5242,49 +5361,6 @@ var init_OpenAIImageProvider = __esm({
|
|
|
5242
5361
|
};
|
|
5243
5362
|
}
|
|
5244
5363
|
}
|
|
5245
|
-
/**
|
|
5246
|
-
* Create image variations (uses DALL-E 2)
|
|
5247
|
-
*/
|
|
5248
|
-
async createVariation(imageBuffer, options = {}) {
|
|
5249
|
-
if (!this.apiKey) {
|
|
5250
|
-
return {
|
|
5251
|
-
success: false,
|
|
5252
|
-
error: "OpenAI API key not configured"
|
|
5253
|
-
};
|
|
5254
|
-
}
|
|
5255
|
-
try {
|
|
5256
|
-
const formData = new FormData();
|
|
5257
|
-
const uint8Array = new Uint8Array(imageBuffer);
|
|
5258
|
-
formData.append("image", new Blob([uint8Array], { type: "image/png" }), "image.png");
|
|
5259
|
-
formData.append("model", "dall-e-2");
|
|
5260
|
-
formData.append("n", String(options.n || 1));
|
|
5261
|
-
formData.append("size", options.size || "1024x1024");
|
|
5262
|
-
const response = await fetch(`${this.baseUrl}/images/variations`, {
|
|
5263
|
-
method: "POST",
|
|
5264
|
-
headers: {
|
|
5265
|
-
Authorization: `Bearer ${this.apiKey}`
|
|
5266
|
-
},
|
|
5267
|
-
body: formData
|
|
5268
|
-
});
|
|
5269
|
-
if (!response.ok) {
|
|
5270
|
-
const error = await response.text();
|
|
5271
|
-
return {
|
|
5272
|
-
success: false,
|
|
5273
|
-
error: `API error: ${response.status} - ${error}`
|
|
5274
|
-
};
|
|
5275
|
-
}
|
|
5276
|
-
const data2 = await response.json();
|
|
5277
|
-
return {
|
|
5278
|
-
success: true,
|
|
5279
|
-
images: data2.data.map((img) => ({ url: img.url }))
|
|
5280
|
-
};
|
|
5281
|
-
} catch (error) {
|
|
5282
|
-
return {
|
|
5283
|
-
success: false,
|
|
5284
|
-
error: error instanceof Error ? error.message : "Unknown error"
|
|
5285
|
-
};
|
|
5286
|
-
}
|
|
5287
|
-
}
|
|
5288
5364
|
};
|
|
5289
5365
|
openaiImageProvider = new OpenAIImageProvider();
|
|
5290
5366
|
}
|
|
@@ -5715,12 +5791,33 @@ var init_runway = __esm({
|
|
|
5715
5791
|
|
|
5716
5792
|
// ../ai-providers/dist/kling/KlingProvider.js
|
|
5717
5793
|
import { createHmac } from "node:crypto";
|
|
5794
|
+
function resolveKlingModel(alias) {
|
|
5795
|
+
const key2 = (alias ?? "v3").trim().toLowerCase();
|
|
5796
|
+
const aliases2 = {
|
|
5797
|
+
v3: "kling-v3",
|
|
5798
|
+
"kling-v3": "kling-v3",
|
|
5799
|
+
"v2.6": "kling-v2-6",
|
|
5800
|
+
"kling-v2-6": "kling-v2-6",
|
|
5801
|
+
"v2.5-turbo": "kling-v2-5-turbo",
|
|
5802
|
+
"v2.5": "kling-v2-5-turbo",
|
|
5803
|
+
"kling-v2-5-turbo": "kling-v2-5-turbo"
|
|
5804
|
+
};
|
|
5805
|
+
if (Object.hasOwn(aliases2, key2))
|
|
5806
|
+
return aliases2[key2];
|
|
5807
|
+
throw new Error(`Unknown Kling model "${alias}". Valid: v3, v2.6, v2.5-turbo.`);
|
|
5808
|
+
}
|
|
5809
|
+
function klingDuration(model, seconds) {
|
|
5810
|
+
const requested = typeof seconds === "number" && Number.isFinite(seconds) ? Math.round(seconds) : 5;
|
|
5811
|
+
if (model === "kling-v3")
|
|
5812
|
+
return String(Math.max(3, Math.min(15, requested)));
|
|
5813
|
+
return requested >= 10 ? "10" : "5";
|
|
5814
|
+
}
|
|
5718
5815
|
var DEFAULT_MODEL4, STD_MODE_MODELS, KlingProvider, klingProvider;
|
|
5719
5816
|
var init_KlingProvider = __esm({
|
|
5720
5817
|
"../ai-providers/dist/kling/KlingProvider.js"() {
|
|
5721
5818
|
"use strict";
|
|
5722
|
-
DEFAULT_MODEL4 = "kling-
|
|
5723
|
-
STD_MODE_MODELS = ["kling-v2-5-turbo", "kling-v2-6", "kling-v3"
|
|
5819
|
+
DEFAULT_MODEL4 = "kling-v3";
|
|
5820
|
+
STD_MODE_MODELS = ["kling-v2-5-turbo", "kling-v2-6", "kling-v3"];
|
|
5724
5821
|
KlingProvider = class {
|
|
5725
5822
|
constructor() {
|
|
5726
5823
|
this.id = "kling";
|
|
@@ -5735,11 +5832,11 @@ var init_KlingProvider = __esm({
|
|
|
5735
5832
|
async initialize(config4) {
|
|
5736
5833
|
if (config4.apiKey) {
|
|
5737
5834
|
const parts = config4.apiKey.split(":");
|
|
5738
|
-
if (parts.length === 2) {
|
|
5835
|
+
if (parts.length === 2 && parts[0] && parts[1]) {
|
|
5739
5836
|
this.accessKey = parts[0];
|
|
5740
5837
|
this.secretKey = parts[1];
|
|
5741
5838
|
} else {
|
|
5742
|
-
this.
|
|
5839
|
+
this.apiKey = config4.apiKey;
|
|
5743
5840
|
}
|
|
5744
5841
|
}
|
|
5745
5842
|
if (config4.baseUrl) {
|
|
@@ -5747,7 +5844,11 @@ var init_KlingProvider = __esm({
|
|
|
5747
5844
|
}
|
|
5748
5845
|
}
|
|
5749
5846
|
isConfigured() {
|
|
5750
|
-
return !!(this.accessKey && this.secretKey);
|
|
5847
|
+
return !!(this.apiKey || this.accessKey && this.secretKey);
|
|
5848
|
+
}
|
|
5849
|
+
/** Bearer value: the API key itself, or a JWT signed from the legacy pair. */
|
|
5850
|
+
bearerToken() {
|
|
5851
|
+
return this.apiKey ?? this.generateToken();
|
|
5751
5852
|
}
|
|
5752
5853
|
/**
|
|
5753
5854
|
* Generate JWT token for Kling API authentication
|
|
@@ -5777,11 +5878,11 @@ var init_KlingProvider = __esm({
|
|
|
5777
5878
|
return {
|
|
5778
5879
|
id: "",
|
|
5779
5880
|
status: "failed",
|
|
5780
|
-
error: "Kling API credentials not configured.
|
|
5881
|
+
error: "Kling API credentials not configured. Set KLING_API_KEY to your Kling API key (or the legacy ACCESS_KEY:SECRET_KEY pair)."
|
|
5781
5882
|
};
|
|
5782
5883
|
}
|
|
5783
5884
|
try {
|
|
5784
|
-
const token = this.
|
|
5885
|
+
const token = this.bearerToken();
|
|
5785
5886
|
const model = options?.model || DEFAULT_MODEL4;
|
|
5786
5887
|
let mode = options?.mode || "std";
|
|
5787
5888
|
if (!STD_MODE_MODELS.includes(model) && mode === "std") {
|
|
@@ -5799,7 +5900,7 @@ var init_KlingProvider = __esm({
|
|
|
5799
5900
|
model_name: model,
|
|
5800
5901
|
mode,
|
|
5801
5902
|
aspect_ratio: aspectRatioMap[options?.aspectRatio || "16:9"] || "16:9",
|
|
5802
|
-
duration: options?.duration
|
|
5903
|
+
duration: klingDuration(model, options?.duration)
|
|
5803
5904
|
};
|
|
5804
5905
|
if (options?.negativePrompt) {
|
|
5805
5906
|
body.negative_prompt = options.negativePrompt;
|
|
@@ -5911,7 +6012,7 @@ var init_KlingProvider = __esm({
|
|
|
5911
6012
|
};
|
|
5912
6013
|
}
|
|
5913
6014
|
try {
|
|
5914
|
-
const token = this.
|
|
6015
|
+
const token = this.bearerToken();
|
|
5915
6016
|
const response = await fetch(`${this.baseUrl}/videos/${type}/${id}`, {
|
|
5916
6017
|
headers: {
|
|
5917
6018
|
"Content-Type": "application/json",
|
|
@@ -5993,11 +6094,11 @@ var init_KlingProvider = __esm({
|
|
|
5993
6094
|
return {
|
|
5994
6095
|
id: "",
|
|
5995
6096
|
status: "failed",
|
|
5996
|
-
error: "Kling API credentials not configured.
|
|
6097
|
+
error: "Kling API credentials not configured. Set KLING_API_KEY to your Kling API key (or the legacy ACCESS_KEY:SECRET_KEY pair)."
|
|
5997
6098
|
};
|
|
5998
6099
|
}
|
|
5999
6100
|
try {
|
|
6000
|
-
const token = this.
|
|
6101
|
+
const token = this.bearerToken();
|
|
6001
6102
|
const body = {
|
|
6002
6103
|
video_id: videoId,
|
|
6003
6104
|
duration: options?.duration || "5"
|
|
@@ -6037,7 +6138,7 @@ var init_KlingProvider = __esm({
|
|
|
6037
6138
|
};
|
|
6038
6139
|
}
|
|
6039
6140
|
try {
|
|
6040
|
-
const token = this.
|
|
6141
|
+
const token = this.bearerToken();
|
|
6041
6142
|
const response = await fetch(`${this.baseUrl}/videos/video-extend/${id}`, {
|
|
6042
6143
|
headers: {
|
|
6043
6144
|
"Content-Type": "application/json",
|
|
@@ -6153,11 +6254,34 @@ var init_kling = __esm({
|
|
|
6153
6254
|
});
|
|
6154
6255
|
|
|
6155
6256
|
// ../ai-providers/dist/grok/GrokProvider.js
|
|
6156
|
-
|
|
6257
|
+
function resolveGrokVideoModel(alias) {
|
|
6258
|
+
const key2 = (alias ?? "1.5").trim().toLowerCase();
|
|
6259
|
+
const aliases2 = {
|
|
6260
|
+
"1.5": "grok-imagine-video-1.5",
|
|
6261
|
+
"grok-imagine-video-1.5": "grok-imagine-video-1.5",
|
|
6262
|
+
lite: "grok-imagine-video-1.5-lite",
|
|
6263
|
+
"1.5-lite": "grok-imagine-video-1.5-lite",
|
|
6264
|
+
"grok-imagine-video-1.5-lite": "grok-imagine-video-1.5-lite",
|
|
6265
|
+
classic: "grok-imagine-video",
|
|
6266
|
+
"grok-imagine-video": "grok-imagine-video"
|
|
6267
|
+
};
|
|
6268
|
+
if (Object.hasOwn(aliases2, key2))
|
|
6269
|
+
return aliases2[key2];
|
|
6270
|
+
throw new Error(`Unknown Grok video model "${alias}". Valid: 1.5, lite, classic.`);
|
|
6271
|
+
}
|
|
6272
|
+
function resolveGrokImageModel(alias) {
|
|
6273
|
+
if (alias === "pro" || alias === "2.0" || alias === "quality" || alias === "grok-imagine-image-2.0") {
|
|
6274
|
+
return { model: "grok-imagine-image-2.0", quality: "medium" };
|
|
6275
|
+
}
|
|
6276
|
+
return { model: "grok-imagine-image" };
|
|
6277
|
+
}
|
|
6278
|
+
var DEFAULT_MODEL5, DEFAULT_VIDEO_RESOLUTION, GROK_VIDEO_RESOLUTIONS, GrokProvider, grokProvider;
|
|
6157
6279
|
var init_GrokProvider = __esm({
|
|
6158
6280
|
"../ai-providers/dist/grok/GrokProvider.js"() {
|
|
6159
6281
|
"use strict";
|
|
6160
|
-
DEFAULT_MODEL5 = "grok-imagine-video";
|
|
6282
|
+
DEFAULT_MODEL5 = "grok-imagine-video-1.5";
|
|
6283
|
+
DEFAULT_VIDEO_RESOLUTION = "720p";
|
|
6284
|
+
GROK_VIDEO_RESOLUTIONS = ["480p", "720p", "1080p"];
|
|
6161
6285
|
GrokProvider = class {
|
|
6162
6286
|
constructor() {
|
|
6163
6287
|
this.id = "grok";
|
|
@@ -6191,6 +6315,7 @@ var init_GrokProvider = __esm({
|
|
|
6191
6315
|
try {
|
|
6192
6316
|
const body = {
|
|
6193
6317
|
model: options.model || "grok-imagine-image",
|
|
6318
|
+
...options.quality ? { quality: options.quality } : {},
|
|
6194
6319
|
prompt: prompt3,
|
|
6195
6320
|
n: options.n || 1,
|
|
6196
6321
|
response_format: options.responseFormat || "url"
|
|
@@ -6258,6 +6383,7 @@ var init_GrokProvider = __esm({
|
|
|
6258
6383
|
const dataUri = `data:image/png;base64,${base64}`;
|
|
6259
6384
|
const body = {
|
|
6260
6385
|
model: options.model || "grok-imagine-image",
|
|
6386
|
+
...options.quality ? { quality: options.quality } : {},
|
|
6261
6387
|
prompt: prompt3,
|
|
6262
6388
|
image: {
|
|
6263
6389
|
url: dataUri,
|
|
@@ -6324,11 +6450,15 @@ var init_GrokProvider = __esm({
|
|
|
6324
6450
|
try {
|
|
6325
6451
|
const duration = Math.round(Math.min(15, Math.max(1, options?.duration || 5)));
|
|
6326
6452
|
const body = {
|
|
6327
|
-
model: DEFAULT_MODEL5,
|
|
6453
|
+
model: options?.model || DEFAULT_MODEL5,
|
|
6328
6454
|
prompt: prompt3,
|
|
6329
6455
|
duration,
|
|
6330
|
-
aspect_ratio: options?.aspectRatio || "16:9"
|
|
6456
|
+
aspect_ratio: options?.aspectRatio || "16:9",
|
|
6457
|
+
resolution: GROK_VIDEO_RESOLUTIONS.includes(options?.resolution ?? "") ? options.resolution : DEFAULT_VIDEO_RESOLUTION
|
|
6331
6458
|
};
|
|
6459
|
+
if (typeof options?.generateAudio === "boolean") {
|
|
6460
|
+
body.generate_audio = options.generateAudio;
|
|
6461
|
+
}
|
|
6332
6462
|
if (options?.referenceImage) {
|
|
6333
6463
|
body.image = { url: options.referenceImage };
|
|
6334
6464
|
}
|
|
@@ -6390,13 +6520,14 @@ var init_GrokProvider = __esm({
|
|
|
6390
6520
|
const statusMap = {
|
|
6391
6521
|
pending: "pending",
|
|
6392
6522
|
done: "completed",
|
|
6393
|
-
expired: "failed"
|
|
6523
|
+
expired: "failed",
|
|
6524
|
+
failed: "failed"
|
|
6394
6525
|
};
|
|
6395
6526
|
return {
|
|
6396
6527
|
id,
|
|
6397
6528
|
status: statusMap[data2.status] || "pending",
|
|
6398
6529
|
videoUrl: data2.video?.url,
|
|
6399
|
-
error: data2.status === "expired" ? "Generation expired" : void 0
|
|
6530
|
+
error: data2.status === "expired" ? "Generation expired" : data2.status === "failed" ? `Generation failed: ${data2.error?.message ?? data2.error?.code ?? "unknown error"}` : void 0
|
|
6400
6531
|
};
|
|
6401
6532
|
} catch (error) {
|
|
6402
6533
|
return {
|
|
@@ -10590,14 +10721,30 @@ var require_src = __commonJS({
|
|
|
10590
10721
|
});
|
|
10591
10722
|
|
|
10592
10723
|
// ../ai-providers/dist/fal/FalProvider.js
|
|
10724
|
+
function resolveSeedanceVariant(alias) {
|
|
10725
|
+
const key2 = (alias ?? "quality").trim().toLowerCase();
|
|
10726
|
+
const aliases2 = {
|
|
10727
|
+
quality: "seedance-2.0",
|
|
10728
|
+
"2.0": "seedance-2.0",
|
|
10729
|
+
"seedance-2.0": "seedance-2.0",
|
|
10730
|
+
fast: "seedance-2.0-fast",
|
|
10731
|
+
"seedance-2.0-fast": "seedance-2.0-fast",
|
|
10732
|
+
"2.5": "seedance-2.5",
|
|
10733
|
+
"seedance-2.5": "seedance-2.5"
|
|
10734
|
+
};
|
|
10735
|
+
if (Object.hasOwn(aliases2, key2))
|
|
10736
|
+
return aliases2[key2];
|
|
10737
|
+
throw new Error(`Unknown Seedance model "${alias}". Valid: quality, fast, 2.5.`);
|
|
10738
|
+
}
|
|
10593
10739
|
function estimateSeedanceVideoCostUsd(opts) {
|
|
10594
10740
|
const shortSide = SEEDANCE_SHORT_SIDE[opts.resolution ?? "720p"] ?? 720;
|
|
10595
10741
|
const [a4, b4] = (opts.aspectRatio ?? "16:9").split(":").map(Number);
|
|
10596
10742
|
const ratioFactor = a4 > 0 && b4 > 0 ? Math.max(a4, b4) / Math.min(a4, b4) : 16 / 9;
|
|
10597
10743
|
const longSide = Math.round(shortSide * ratioFactor);
|
|
10598
10744
|
const tokensPerSecond = shortSide * longSide * 24 / 1024;
|
|
10599
|
-
|
|
10600
|
-
|
|
10745
|
+
const rate = opts.v25 ? shortSide >= 1080 ? SEEDANCE_25_1080P_USD_PER_1K_TOKENS : SEEDANCE_25_USD_PER_1K_TOKENS : SEEDANCE_USD_PER_1K_TOKENS;
|
|
10746
|
+
let usdPerSecond = tokensPerSecond / 1e3 * rate;
|
|
10747
|
+
if (opts.fast && !opts.v25 && shortSide <= 720)
|
|
10601
10748
|
usdPerSecond *= SEEDANCE_FAST_FACTOR;
|
|
10602
10749
|
if (opts.hasVideoReference)
|
|
10603
10750
|
usdPerSecond *= SEEDANCE_VIDEO_REF_FACTOR;
|
|
@@ -10705,34 +10852,42 @@ function normaliseResolution(value) {
|
|
|
10705
10852
|
return "1080p";
|
|
10706
10853
|
return "720p";
|
|
10707
10854
|
}
|
|
10708
|
-
function normaliseDuration(value) {
|
|
10709
|
-
if (typeof value !== "number")
|
|
10710
|
-
return "auto";
|
|
10711
|
-
if (!Number.isFinite(value))
|
|
10855
|
+
function normaliseDuration(value, maxSec) {
|
|
10856
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
10712
10857
|
return "auto";
|
|
10713
|
-
return Math.max(4, Math.min(
|
|
10858
|
+
return String(Math.max(4, Math.min(maxSec, Math.round(value))));
|
|
10714
10859
|
}
|
|
10715
|
-
var import_client, ENDPOINT_TEXT_TO_VIDEO, ENDPOINT_IMAGE_TO_VIDEO, ENDPOINT_REFERENCE_TO_VIDEO, DEFAULT_VARIANT, VALID_RESOLUTIONS, VALID_ASPECTS, SEEDANCE_USD_PER_1K_TOKENS, SEEDANCE_FAST_FACTOR, SEEDANCE_VIDEO_REF_FACTOR, SEEDANCE_SHORT_SIDE, FalProvider, falProvider;
|
|
10860
|
+
var import_client, ENDPOINT_TEXT_TO_VIDEO, ENDPOINT_IMAGE_TO_VIDEO, ENDPOINT_REFERENCE_TO_VIDEO, DEFAULT_VARIANT, MAX_DURATION_SEC, VALID_RESOLUTIONS, VALID_ASPECTS, SEEDANCE_USD_PER_1K_TOKENS, SEEDANCE_25_USD_PER_1K_TOKENS, SEEDANCE_25_1080P_USD_PER_1K_TOKENS, SEEDANCE_FAST_FACTOR, SEEDANCE_VIDEO_REF_FACTOR, SEEDANCE_SHORT_SIDE, FalProvider, falProvider;
|
|
10716
10861
|
var init_FalProvider = __esm({
|
|
10717
10862
|
"../ai-providers/dist/fal/FalProvider.js"() {
|
|
10718
10863
|
"use strict";
|
|
10719
10864
|
import_client = __toESM(require_src(), 1);
|
|
10720
10865
|
ENDPOINT_TEXT_TO_VIDEO = {
|
|
10721
10866
|
"seedance-2.0": "bytedance/seedance-2.0/text-to-video",
|
|
10722
|
-
"seedance-2.0-fast": "bytedance/seedance-2.0/fast/text-to-video"
|
|
10867
|
+
"seedance-2.0-fast": "bytedance/seedance-2.0/fast/text-to-video",
|
|
10868
|
+
"seedance-2.5": "bytedance/seedance-2.5/text-to-video"
|
|
10723
10869
|
};
|
|
10724
10870
|
ENDPOINT_IMAGE_TO_VIDEO = {
|
|
10725
10871
|
"seedance-2.0": "bytedance/seedance-2.0/image-to-video",
|
|
10726
|
-
"seedance-2.0-fast": "bytedance/seedance-2.0/fast/image-to-video"
|
|
10872
|
+
"seedance-2.0-fast": "bytedance/seedance-2.0/fast/image-to-video",
|
|
10873
|
+
"seedance-2.5": "bytedance/seedance-2.5/image-to-video"
|
|
10727
10874
|
};
|
|
10728
10875
|
ENDPOINT_REFERENCE_TO_VIDEO = {
|
|
10729
10876
|
"seedance-2.0": "bytedance/seedance-2.0/reference-to-video",
|
|
10730
|
-
"seedance-2.0-fast": "bytedance/seedance-2.0/fast/reference-to-video"
|
|
10877
|
+
"seedance-2.0-fast": "bytedance/seedance-2.0/fast/reference-to-video",
|
|
10878
|
+
"seedance-2.5": "bytedance/seedance-2.5/reference-to-video"
|
|
10731
10879
|
};
|
|
10732
10880
|
DEFAULT_VARIANT = "seedance-2.0";
|
|
10881
|
+
MAX_DURATION_SEC = {
|
|
10882
|
+
"seedance-2.0": 15,
|
|
10883
|
+
"seedance-2.0-fast": 15,
|
|
10884
|
+
"seedance-2.5": 30
|
|
10885
|
+
};
|
|
10733
10886
|
VALID_RESOLUTIONS = ["480p", "720p", "1080p"];
|
|
10734
10887
|
VALID_ASPECTS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16", "auto"];
|
|
10735
10888
|
SEEDANCE_USD_PER_1K_TOKENS = 0.014;
|
|
10889
|
+
SEEDANCE_25_USD_PER_1K_TOKENS = 0.0214;
|
|
10890
|
+
SEEDANCE_25_1080P_USD_PER_1K_TOKENS = 0.0234;
|
|
10736
10891
|
SEEDANCE_FAST_FACTOR = 0.8;
|
|
10737
10892
|
SEEDANCE_VIDEO_REF_FACTOR = 0.6;
|
|
10738
10893
|
SEEDANCE_SHORT_SIDE = { "480p": 480, "720p": 720, "1080p": 1080 };
|
|
@@ -10787,7 +10942,7 @@ var init_FalProvider = __esm({
|
|
|
10787
10942
|
const endpointId = hasReferences ? ENDPOINT_REFERENCE_TO_VIDEO[variant] : isImageToVideo ? ENDPOINT_IMAGE_TO_VIDEO[variant] : ENDPOINT_TEXT_TO_VIDEO[variant];
|
|
10788
10943
|
const aspect = normaliseAspect(options?.aspectRatio);
|
|
10789
10944
|
const resolution = normaliseResolution(options?.resolution);
|
|
10790
|
-
const duration = normaliseDuration(options?.duration);
|
|
10945
|
+
const duration = normaliseDuration(options?.duration, MAX_DURATION_SEC[variant]);
|
|
10791
10946
|
const input3 = {
|
|
10792
10947
|
prompt: prompt3,
|
|
10793
10948
|
aspect_ratio: aspect,
|
|
@@ -10805,10 +10960,12 @@ var init_FalProvider = __esm({
|
|
|
10805
10960
|
} else if (referenceImage) {
|
|
10806
10961
|
input3.image_url = referenceImage;
|
|
10807
10962
|
}
|
|
10808
|
-
if (
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
|
|
10963
|
+
if (variant !== "seedance-2.5") {
|
|
10964
|
+
if (options?.negativePrompt)
|
|
10965
|
+
input3.negative_prompt = options.negativePrompt;
|
|
10966
|
+
if (typeof options?.seed === "number")
|
|
10967
|
+
input3.seed = options.seed;
|
|
10968
|
+
}
|
|
10812
10969
|
if (typeof options?.generateAudio === "boolean")
|
|
10813
10970
|
input3.generate_audio = options.generateAudio;
|
|
10814
10971
|
if (options?.endUserId)
|
|
@@ -11535,6 +11692,7 @@ var init_replicate = __esm({
|
|
|
11535
11692
|
var dist_exports = {};
|
|
11536
11693
|
__export(dist_exports, {
|
|
11537
11694
|
ClaudeProvider: () => ClaudeProvider,
|
|
11695
|
+
ELEVENLABS_MUSIC_MODEL: () => ELEVENLABS_MUSIC_MODEL,
|
|
11538
11696
|
ElevenLabsProvider: () => ElevenLabsProvider,
|
|
11539
11697
|
FalProvider: () => FalProvider,
|
|
11540
11698
|
GEMINI_AGENT_DEFAULT_TEXT_MODEL: () => GEMINI_AGENT_DEFAULT_TEXT_MODEL,
|
|
@@ -11548,6 +11706,7 @@ __export(dist_exports, {
|
|
|
11548
11706
|
KOKORO_MODEL_ID: () => KOKORO_MODEL_ID,
|
|
11549
11707
|
KlingProvider: () => KlingProvider,
|
|
11550
11708
|
KokoroProvider: () => KokoroProvider,
|
|
11709
|
+
OPENAI_IMAGE_DEFAULT_MODEL: () => OPENAI_IMAGE_DEFAULT_MODEL,
|
|
11551
11710
|
OPENAI_TTS_VOICES: () => OPENAI_TTS_VOICES,
|
|
11552
11711
|
OllamaProvider: () => OllamaProvider,
|
|
11553
11712
|
OmniProvider: () => OmniProvider,
|
|
@@ -11556,6 +11715,7 @@ __export(dist_exports, {
|
|
|
11556
11715
|
OpenAiTtsProvider: () => OpenAiTtsProvider,
|
|
11557
11716
|
ReplicateProvider: () => ReplicateProvider,
|
|
11558
11717
|
RunwayProvider: () => RunwayProvider,
|
|
11718
|
+
VEO_MODEL_ALIASES: () => VEO_MODEL_ALIASES,
|
|
11559
11719
|
WhisperProvider: () => WhisperProvider,
|
|
11560
11720
|
claudeProvider: () => claudeProvider,
|
|
11561
11721
|
defineApiKey: () => defineApiKey,
|
|
@@ -11576,6 +11736,7 @@ __export(dist_exports, {
|
|
|
11576
11736
|
getSetupProviders: () => getSetupProviders,
|
|
11577
11737
|
grokProvider: () => grokProvider,
|
|
11578
11738
|
isGeminiTextModelAlias: () => isGeminiTextModelAlias,
|
|
11739
|
+
klingDuration: () => klingDuration,
|
|
11579
11740
|
klingProvider: () => klingProvider,
|
|
11580
11741
|
kokoroProvider: () => kokoroProvider,
|
|
11581
11742
|
loadBundledKokoroRuntime: () => loadBundledKokoroRuntime,
|
|
@@ -11588,6 +11749,11 @@ __export(dist_exports, {
|
|
|
11588
11749
|
providerRegistry: () => providerRegistry,
|
|
11589
11750
|
replicateProvider: () => replicateProvider,
|
|
11590
11751
|
resolveGeminiTextModel: () => resolveGeminiTextModel,
|
|
11752
|
+
resolveGrokImageModel: () => resolveGrokImageModel,
|
|
11753
|
+
resolveGrokVideoModel: () => resolveGrokVideoModel,
|
|
11754
|
+
resolveKlingModel: () => resolveKlingModel,
|
|
11755
|
+
resolveSeedanceVariant: () => resolveSeedanceVariant,
|
|
11756
|
+
resolveVeoModel: () => resolveVeoModel,
|
|
11591
11757
|
resolveVoiceId: () => resolveVoiceId,
|
|
11592
11758
|
runwayProvider: () => runwayProvider,
|
|
11593
11759
|
whisperProvider: () => whisperProvider
|
|
@@ -20653,8 +20819,14 @@ __export(ai_video_exports, {
|
|
|
20653
20819
|
executeVideoGenerate: () => executeVideoGenerate,
|
|
20654
20820
|
executeVideoStatus: () => executeVideoStatus
|
|
20655
20821
|
});
|
|
20656
|
-
import { readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
20657
|
-
import { resolve as resolve3 } from "node:path";
|
|
20822
|
+
import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
20823
|
+
import { dirname as dirname2, resolve as resolve3 } from "node:path";
|
|
20824
|
+
async function saveOutput(output3, buffer) {
|
|
20825
|
+
const outputPath = resolve3(process.cwd(), output3);
|
|
20826
|
+
await mkdir2(dirname2(outputPath), { recursive: true });
|
|
20827
|
+
await writeFile3(outputPath, buffer);
|
|
20828
|
+
return outputPath;
|
|
20829
|
+
}
|
|
20658
20830
|
async function executeVideoGenerate(options) {
|
|
20659
20831
|
const {
|
|
20660
20832
|
prompt: prompt3,
|
|
@@ -20671,6 +20843,8 @@ async function executeVideoGenerate(options) {
|
|
|
20671
20843
|
resolution,
|
|
20672
20844
|
veoModel = "3.1-fast",
|
|
20673
20845
|
seedanceModel = "quality",
|
|
20846
|
+
grokModel,
|
|
20847
|
+
klingModel,
|
|
20674
20848
|
generateAudio,
|
|
20675
20849
|
output: output3,
|
|
20676
20850
|
wait = true,
|
|
@@ -20725,7 +20899,7 @@ async function executeVideoGenerate(options) {
|
|
|
20725
20899
|
});
|
|
20726
20900
|
falImage = upload.url;
|
|
20727
20901
|
}
|
|
20728
|
-
const model = seedanceModel
|
|
20902
|
+
const model = resolveSeedanceVariant(seedanceModel);
|
|
20729
20903
|
const result = await fal.generateVideo(prompt3, {
|
|
20730
20904
|
prompt: prompt3,
|
|
20731
20905
|
referenceImage: references.length > 0 ? void 0 : falImage,
|
|
@@ -20742,8 +20916,7 @@ async function executeVideoGenerate(options) {
|
|
|
20742
20916
|
let outputPath;
|
|
20743
20917
|
if (output3 && result.videoUrl) {
|
|
20744
20918
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
20745
|
-
outputPath =
|
|
20746
|
-
await writeFile3(outputPath, buffer);
|
|
20919
|
+
outputPath = await saveOutput(output3, buffer);
|
|
20747
20920
|
}
|
|
20748
20921
|
return {
|
|
20749
20922
|
success: true,
|
|
@@ -20774,8 +20947,7 @@ async function executeVideoGenerate(options) {
|
|
|
20774
20947
|
let outputPath;
|
|
20775
20948
|
if (output3 && finalResult.videoUrl) {
|
|
20776
20949
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
20777
|
-
outputPath =
|
|
20778
|
-
await writeFile3(outputPath, buffer);
|
|
20950
|
+
outputPath = await saveOutput(output3, buffer);
|
|
20779
20951
|
}
|
|
20780
20952
|
return {
|
|
20781
20953
|
success: true,
|
|
@@ -20801,6 +20973,7 @@ async function executeVideoGenerate(options) {
|
|
|
20801
20973
|
}
|
|
20802
20974
|
const result = await kling.generateVideo(prompt3, {
|
|
20803
20975
|
prompt: prompt3,
|
|
20976
|
+
model: resolveKlingModel(klingModel),
|
|
20804
20977
|
referenceImage: klingImage,
|
|
20805
20978
|
duration,
|
|
20806
20979
|
aspectRatio: ratio,
|
|
@@ -20819,8 +20992,7 @@ async function executeVideoGenerate(options) {
|
|
|
20819
20992
|
let outputPath;
|
|
20820
20993
|
if (output3 && finalResult.videoUrl) {
|
|
20821
20994
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
20822
|
-
outputPath =
|
|
20823
|
-
await writeFile3(outputPath, buffer);
|
|
20995
|
+
outputPath = await saveOutput(output3, buffer);
|
|
20824
20996
|
}
|
|
20825
20997
|
return {
|
|
20826
20998
|
success: true,
|
|
@@ -20834,12 +21006,7 @@ async function executeVideoGenerate(options) {
|
|
|
20834
21006
|
} else if (provider === "veo") {
|
|
20835
21007
|
const gemini = new GeminiProvider();
|
|
20836
21008
|
await gemini.initialize({ apiKey: key2 });
|
|
20837
|
-
const
|
|
20838
|
-
"3.0": "veo-3.0-generate-preview",
|
|
20839
|
-
"3.1": "veo-3.1-generate-preview",
|
|
20840
|
-
"3.1-fast": "veo-3.1-fast-generate-preview"
|
|
20841
|
-
};
|
|
20842
|
-
const model = veoModelMap[veoModel] || "veo-3.1-fast-generate-preview";
|
|
21009
|
+
const model = resolveVeoModel(veoModel);
|
|
20843
21010
|
const veoDuration = duration <= 6 ? 6 : 8;
|
|
20844
21011
|
const result = await gemini.generateVideo(prompt3, {
|
|
20845
21012
|
prompt: prompt3,
|
|
@@ -20860,8 +21027,7 @@ async function executeVideoGenerate(options) {
|
|
|
20860
21027
|
let outputPath;
|
|
20861
21028
|
if (output3 && finalResult.videoUrl) {
|
|
20862
21029
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
20863
|
-
outputPath =
|
|
20864
|
-
await writeFile3(outputPath, buffer);
|
|
21030
|
+
outputPath = await saveOutput(output3, buffer);
|
|
20865
21031
|
}
|
|
20866
21032
|
return {
|
|
20867
21033
|
success: true,
|
|
@@ -20876,9 +21042,12 @@ async function executeVideoGenerate(options) {
|
|
|
20876
21042
|
await grok.initialize({ apiKey: key2 });
|
|
20877
21043
|
const result = await grok.generateVideo(prompt3, {
|
|
20878
21044
|
prompt: prompt3,
|
|
21045
|
+
model: resolveGrokVideoModel(grokModel),
|
|
20879
21046
|
referenceImage,
|
|
20880
21047
|
duration,
|
|
20881
|
-
aspectRatio: ratio
|
|
21048
|
+
aspectRatio: ratio,
|
|
21049
|
+
resolution,
|
|
21050
|
+
generateAudio
|
|
20882
21051
|
});
|
|
20883
21052
|
if (result.status === "failed")
|
|
20884
21053
|
return { success: false, error: result.error || "Grok generation failed" };
|
|
@@ -20891,8 +21060,7 @@ async function executeVideoGenerate(options) {
|
|
|
20891
21060
|
let outputPath;
|
|
20892
21061
|
if (output3 && finalResult.videoUrl) {
|
|
20893
21062
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
20894
|
-
outputPath =
|
|
20895
|
-
await writeFile3(outputPath, buffer);
|
|
21063
|
+
outputPath = await saveOutput(output3, buffer);
|
|
20896
21064
|
}
|
|
20897
21065
|
return {
|
|
20898
21066
|
success: true,
|
|
@@ -20909,7 +21077,8 @@ async function executeVideoGenerate(options) {
|
|
|
20909
21077
|
const result = await omni.generateVideo(prompt3, {
|
|
20910
21078
|
prompt: prompt3,
|
|
20911
21079
|
referenceImage,
|
|
20912
|
-
aspectRatio: ratio
|
|
21080
|
+
aspectRatio: ratio,
|
|
21081
|
+
resolution
|
|
20913
21082
|
});
|
|
20914
21083
|
if (result.status !== "completed" || !result.videoUrl) {
|
|
20915
21084
|
return { success: false, error: result.error || "Gemini Omni generation failed" };
|
|
@@ -20917,8 +21086,7 @@ async function executeVideoGenerate(options) {
|
|
|
20917
21086
|
let outputPath;
|
|
20918
21087
|
if (output3) {
|
|
20919
21088
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
20920
|
-
outputPath =
|
|
20921
|
-
await writeFile3(outputPath, buffer);
|
|
21089
|
+
outputPath = await saveOutput(output3, buffer);
|
|
20922
21090
|
}
|
|
20923
21091
|
return {
|
|
20924
21092
|
success: true,
|
|
@@ -21014,8 +21182,7 @@ async function executeVideoStatus(options) {
|
|
|
21014
21182
|
let outputPath;
|
|
21015
21183
|
if (output3 && result.videoUrl) {
|
|
21016
21184
|
const buffer = await downloadVideo(result.videoUrl);
|
|
21017
|
-
outputPath =
|
|
21018
|
-
await writeFile3(outputPath, buffer);
|
|
21185
|
+
outputPath = await saveOutput(output3, buffer);
|
|
21019
21186
|
}
|
|
21020
21187
|
return {
|
|
21021
21188
|
success: true,
|
|
@@ -21037,8 +21204,7 @@ async function executeVideoStatus(options) {
|
|
|
21037
21204
|
let outputPath;
|
|
21038
21205
|
if (output3 && result.videoUrl) {
|
|
21039
21206
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
21040
|
-
outputPath =
|
|
21041
|
-
await writeFile3(outputPath, buffer);
|
|
21207
|
+
outputPath = await saveOutput(output3, buffer);
|
|
21042
21208
|
}
|
|
21043
21209
|
return {
|
|
21044
21210
|
success: true,
|
|
@@ -21059,8 +21225,7 @@ async function executeVideoStatus(options) {
|
|
|
21059
21225
|
let outputPath;
|
|
21060
21226
|
if (output3 && result.videoUrl) {
|
|
21061
21227
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
21062
|
-
outputPath =
|
|
21063
|
-
await writeFile3(outputPath, buffer);
|
|
21228
|
+
outputPath = await saveOutput(output3, buffer);
|
|
21064
21229
|
}
|
|
21065
21230
|
return {
|
|
21066
21231
|
success: true,
|
|
@@ -21082,8 +21247,7 @@ async function executeVideoStatus(options) {
|
|
|
21082
21247
|
let outputPath;
|
|
21083
21248
|
if (output3 && result.videoUrl) {
|
|
21084
21249
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
21085
|
-
outputPath =
|
|
21086
|
-
await writeFile3(outputPath, buffer);
|
|
21250
|
+
outputPath = await saveOutput(output3, buffer);
|
|
21087
21251
|
}
|
|
21088
21252
|
return {
|
|
21089
21253
|
success: true,
|
|
@@ -21153,8 +21317,7 @@ async function executeVideoExtend(options) {
|
|
|
21153
21317
|
let outputPath;
|
|
21154
21318
|
if (output3 && finalResult.videoUrl) {
|
|
21155
21319
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
21156
|
-
outputPath =
|
|
21157
|
-
await writeFile3(outputPath, buffer);
|
|
21320
|
+
outputPath = await saveOutput(output3, buffer);
|
|
21158
21321
|
}
|
|
21159
21322
|
return {
|
|
21160
21323
|
success: true,
|
|
@@ -21169,12 +21332,7 @@ async function executeVideoExtend(options) {
|
|
|
21169
21332
|
if (!key2) return { success: false, error: "GOOGLE_API_KEY required" };
|
|
21170
21333
|
const gemini = new GeminiProvider();
|
|
21171
21334
|
await gemini.initialize({ apiKey: key2 });
|
|
21172
|
-
const
|
|
21173
|
-
"3.0": "veo-3.0-generate-preview",
|
|
21174
|
-
"3.1": "veo-3.1-generate-preview",
|
|
21175
|
-
"3.1-fast": "veo-3.1-fast-generate-preview"
|
|
21176
|
-
};
|
|
21177
|
-
const model = veoModelMap[veoModel] || "veo-3.1-generate-preview";
|
|
21335
|
+
const model = resolveVeoModel(veoModel);
|
|
21178
21336
|
const result = await gemini.extendVideo(videoId, prompt3, {
|
|
21179
21337
|
duration,
|
|
21180
21338
|
model
|
|
@@ -21189,8 +21347,7 @@ async function executeVideoExtend(options) {
|
|
|
21189
21347
|
let outputPath;
|
|
21190
21348
|
if (output3 && finalResult.videoUrl) {
|
|
21191
21349
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
21192
|
-
outputPath =
|
|
21193
|
-
await writeFile3(outputPath, buffer);
|
|
21350
|
+
outputPath = await saveOutput(output3, buffer);
|
|
21194
21351
|
}
|
|
21195
21352
|
return {
|
|
21196
21353
|
success: true,
|
|
@@ -21252,8 +21409,8 @@ var init_music_status = __esm({
|
|
|
21252
21409
|
|
|
21253
21410
|
// ../cli/src/commands/_shared/build-asset-metadata.ts
|
|
21254
21411
|
import { existsSync, readFileSync } from "node:fs";
|
|
21255
|
-
import { mkdir as
|
|
21256
|
-
import { dirname as
|
|
21412
|
+
import { mkdir as mkdir3, writeFile as writeFile4 } from "node:fs/promises";
|
|
21413
|
+
import { dirname as dirname3, join } from "node:path";
|
|
21257
21414
|
function assetMetadataPath(kind3, beatId) {
|
|
21258
21415
|
return `.vibeframe/assets/${kind3}-${beatId}.json`;
|
|
21259
21416
|
}
|
|
@@ -21301,7 +21458,7 @@ async function writeAssetMetadata(opts) {
|
|
|
21301
21458
|
cachePath: opts.cachePath,
|
|
21302
21459
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
21303
21460
|
};
|
|
21304
|
-
await
|
|
21461
|
+
await mkdir3(dirname3(abs), { recursive: true });
|
|
21305
21462
|
await writeFile4(abs, JSON.stringify(metadata, null, 2) + "\n", "utf-8");
|
|
21306
21463
|
}
|
|
21307
21464
|
var init_build_asset_metadata = __esm({
|
|
@@ -22260,7 +22417,7 @@ var init_storyboard_edit = __esm({
|
|
|
22260
22417
|
|
|
22261
22418
|
// ../cli/src/commands/_shared/storyboard-source.ts
|
|
22262
22419
|
import { existsSync as existsSync2 } from "node:fs";
|
|
22263
|
-
import { mkdir as
|
|
22420
|
+
import { mkdir as mkdir4, readdir, readFile as readFile4, rename, rm, writeFile as writeFile6 } from "node:fs/promises";
|
|
22264
22421
|
import { basename, join as join3 } from "node:path";
|
|
22265
22422
|
function sceneFileFrom(dir, filename) {
|
|
22266
22423
|
const stem = filename.replace(/\.mdx?$/i, "");
|
|
@@ -22373,7 +22530,7 @@ ${(0, import_yaml5.stringify)(data2, { lineWidth: 0 }).trimEnd()}
|
|
|
22373
22530
|
};
|
|
22374
22531
|
}
|
|
22375
22532
|
async function writeMigration(projectDir, plan2) {
|
|
22376
|
-
await
|
|
22533
|
+
await mkdir4(join3(projectDir, SCENES_DIRNAME), { recursive: true });
|
|
22377
22534
|
for (const file of plan2.scenes) {
|
|
22378
22535
|
await writeFile6(join3(projectDir, file.path), file.contents, "utf-8");
|
|
22379
22536
|
}
|
|
@@ -22395,7 +22552,7 @@ function strayBeatIssues(strayBeatIds) {
|
|
|
22395
22552
|
async function upsertScene(projectDir, opts) {
|
|
22396
22553
|
const beatId = deriveBeatId(opts.beatId);
|
|
22397
22554
|
const dir = join3(projectDir, SCENES_DIRNAME);
|
|
22398
|
-
await
|
|
22555
|
+
await mkdir4(dir, { recursive: true });
|
|
22399
22556
|
const cues = {};
|
|
22400
22557
|
if (opts.duration !== void 0) cues.duration = opts.duration;
|
|
22401
22558
|
if (opts.narration?.trim()) cues.narration = opts.narration.trim();
|
|
@@ -22467,22 +22624,22 @@ var init_storyboard_source = __esm({
|
|
|
22467
22624
|
// ../cli/src/commands/_shared/status-jobs.ts
|
|
22468
22625
|
import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
|
|
22469
22626
|
import { existsSync as existsSync3, statSync } from "node:fs";
|
|
22470
|
-
import { copyFile, mkdir as
|
|
22471
|
-
import { dirname as
|
|
22627
|
+
import { copyFile, mkdir as mkdir5, readFile as readFile5, readdir as readdir2, rename as rename2, stat, writeFile as writeFile7 } from "node:fs/promises";
|
|
22628
|
+
import { dirname as dirname4, join as join4, parse as parse2, relative, resolve as resolve5 } from "node:path";
|
|
22472
22629
|
function isLocalJob(record) {
|
|
22473
22630
|
return record.jobType === "build" || record.jobType === "render";
|
|
22474
22631
|
}
|
|
22475
22632
|
function findProjectRoot(start = process.cwd()) {
|
|
22476
22633
|
let dir = resolve5(start);
|
|
22477
22634
|
try {
|
|
22478
|
-
if (existsSync3(dir) && statSync(dir).isFile()) dir =
|
|
22635
|
+
if (existsSync3(dir) && statSync(dir).isFile()) dir = dirname4(dir);
|
|
22479
22636
|
} catch {
|
|
22480
22637
|
}
|
|
22481
22638
|
for (; ; ) {
|
|
22482
22639
|
if (existsSync3(join4(dir, "vibe.config.json")) || existsSync3(join4(dir, "STORYBOARD.md"))) {
|
|
22483
22640
|
return dir;
|
|
22484
22641
|
}
|
|
22485
|
-
const parent =
|
|
22642
|
+
const parent = dirname4(dir);
|
|
22486
22643
|
if (parent === dir) return resolve5(start);
|
|
22487
22644
|
dir = parent;
|
|
22488
22645
|
}
|
|
@@ -22549,7 +22706,7 @@ async function createAndWriteJobRecord(opts) {
|
|
|
22549
22706
|
}
|
|
22550
22707
|
async function writeJobRecord(record) {
|
|
22551
22708
|
const dir = jobsDir(record.projectDir);
|
|
22552
|
-
await
|
|
22709
|
+
await mkdir5(dir, { recursive: true });
|
|
22553
22710
|
const path16 = jobRecordPath(record.id, record.projectDir);
|
|
22554
22711
|
const tmp = `${path16}.${randomUUID2()}.tmp`;
|
|
22555
22712
|
await writeFile7(tmp, JSON.stringify(stripUndefined2(record), null, 2) + "\n", "utf-8");
|
|
@@ -22597,7 +22754,7 @@ async function refreshJobRecord(record, opts = {}) {
|
|
|
22597
22754
|
try {
|
|
22598
22755
|
if (record.jobType === "generate-video") {
|
|
22599
22756
|
const output3 = resolveRefreshOutput(record, opts);
|
|
22600
|
-
if (output3) await
|
|
22757
|
+
if (output3) await mkdir5(dirname4(output3), { recursive: true });
|
|
22601
22758
|
const result = await executeVideoStatus({
|
|
22602
22759
|
taskId: record.providerTaskId,
|
|
22603
22760
|
provider: record.provider,
|
|
@@ -22880,14 +23037,14 @@ async function downloadUrl(url, outputPath) {
|
|
|
22880
23037
|
const response = await fetch(url);
|
|
22881
23038
|
if (!response.ok) throw new Error(`Download failed: HTTP ${response.status}`);
|
|
22882
23039
|
const buffer = Buffer.from(await response.arrayBuffer());
|
|
22883
|
-
await
|
|
23040
|
+
await mkdir5(dirname4(outputPath), { recursive: true });
|
|
22884
23041
|
await writeFile7(outputPath, buffer);
|
|
22885
23042
|
return outputPath;
|
|
22886
23043
|
}
|
|
22887
23044
|
async function maybeCacheOutput(record) {
|
|
22888
23045
|
if (record.status !== "completed" || !record.outputPath || !record.cachePath) return;
|
|
22889
23046
|
try {
|
|
22890
|
-
await
|
|
23047
|
+
await mkdir5(dirname4(record.cachePath), { recursive: true });
|
|
22891
23048
|
await copyFile(record.outputPath, record.cachePath);
|
|
22892
23049
|
} catch {
|
|
22893
23050
|
}
|
|
@@ -23471,7 +23628,7 @@ var init_project_config = __esm({
|
|
|
23471
23628
|
});
|
|
23472
23629
|
|
|
23473
23630
|
// ../cli/src/commands/_shared/scene-project.ts
|
|
23474
|
-
import { mkdir as
|
|
23631
|
+
import { mkdir as mkdir6, readFile as readFile7, writeFile as writeFile8, access as access3 } from "node:fs/promises";
|
|
23475
23632
|
import { resolve as resolve7, basename as basename2 } from "node:path";
|
|
23476
23633
|
function isSceneKind(value) {
|
|
23477
23634
|
return VALID_SCENE_KINDS.includes(value);
|
|
@@ -24083,11 +24240,11 @@ async function scaffoldSceneProject(opts) {
|
|
|
24083
24240
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
24084
24241
|
const profile = opts.profile ?? "full";
|
|
24085
24242
|
const kind3 = opts.kind ?? DEFAULT_SCENE_KIND;
|
|
24086
|
-
await
|
|
24243
|
+
await mkdir6(dir, { recursive: true });
|
|
24087
24244
|
if (profile === "full") {
|
|
24088
|
-
await
|
|
24089
|
-
await
|
|
24090
|
-
await
|
|
24245
|
+
await mkdir6(resolve7(dir, "compositions"), { recursive: true });
|
|
24246
|
+
await mkdir6(resolve7(dir, "assets"), { recursive: true });
|
|
24247
|
+
await mkdir6(resolve7(dir, "renders"), { recursive: true });
|
|
24091
24248
|
}
|
|
24092
24249
|
const created = [];
|
|
24093
24250
|
const skipped2 = [];
|
|
@@ -87788,7 +87945,7 @@ var require_yauzl = __commonJS({
|
|
|
87788
87945
|
// ../../node_modules/.pnpm/@puppeteer+browsers@3.0.6_yauzl@2.10.0/node_modules/@puppeteer/browsers/lib/fileUtil.js
|
|
87789
87946
|
import { spawnSync, spawn, execFile as execFile2 } from "node:child_process";
|
|
87790
87947
|
import { constants as constants2, createReadStream, createWriteStream as createWriteStream2 } from "node:fs";
|
|
87791
|
-
import { mkdir as
|
|
87948
|
+
import { mkdir as mkdir8, readdir as readdir4, symlink as symlink2 } from "node:fs/promises";
|
|
87792
87949
|
import * as path9 from "node:path";
|
|
87793
87950
|
import { Stream, Writable as Writable2 } from "node:stream";
|
|
87794
87951
|
import { pipeline } from "node:stream/promises";
|
|
@@ -87798,12 +87955,12 @@ async function unpackArchive(archivePath, folderPath) {
|
|
|
87798
87955
|
folderPath = path9.resolve(process.cwd(), folderPath);
|
|
87799
87956
|
}
|
|
87800
87957
|
if (archivePath.endsWith(".zip")) {
|
|
87801
|
-
await
|
|
87958
|
+
await mkdir8(folderPath, { recursive: true });
|
|
87802
87959
|
await extractZip(archivePath, folderPath);
|
|
87803
87960
|
} else if (archivePath.endsWith(".tar.bz2")) {
|
|
87804
87961
|
await extractTar(archivePath, folderPath, "bzip2");
|
|
87805
87962
|
} else if (archivePath.endsWith(".dmg")) {
|
|
87806
|
-
await
|
|
87963
|
+
await mkdir8(folderPath);
|
|
87807
87964
|
await installDMG(archivePath, folderPath);
|
|
87808
87965
|
} else if (archivePath.endsWith(".exe")) {
|
|
87809
87966
|
const result = spawnSync(archivePath, [`/ExtractDir=${folderPath}`], {
|
|
@@ -87991,10 +88148,10 @@ async function extractZipEntry(zipFile, entry, folderPath) {
|
|
|
87991
88148
|
const mode = unixMode === 0 ? isDirectory2 ? 493 : 420 : unixMode & 511;
|
|
87992
88149
|
const destination = path9.join(folderPath, entry.fileName);
|
|
87993
88150
|
if (isDirectory2) {
|
|
87994
|
-
await
|
|
88151
|
+
await mkdir8(destination, { recursive: true, mode });
|
|
87995
88152
|
return;
|
|
87996
88153
|
}
|
|
87997
|
-
await
|
|
88154
|
+
await mkdir8(path9.dirname(destination), { recursive: true });
|
|
87998
88155
|
const readStream = await promisify2(zipFile.openReadStream.bind(zipFile))(entry);
|
|
87999
88156
|
if (isSymlink) {
|
|
88000
88157
|
const chunks = [];
|
|
@@ -88162,7 +88319,7 @@ var init_ProgressBar = __esm({
|
|
|
88162
88319
|
import assert3 from "node:assert";
|
|
88163
88320
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
88164
88321
|
import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
|
|
88165
|
-
import { mkdir as
|
|
88322
|
+
import { mkdir as mkdir9, unlink } from "node:fs/promises";
|
|
88166
88323
|
import os6 from "node:os";
|
|
88167
88324
|
import path10 from "node:path";
|
|
88168
88325
|
function debugTime(label) {
|
|
@@ -88215,7 +88372,7 @@ async function installWithProviders(options) {
|
|
|
88215
88372
|
}
|
|
88216
88373
|
debugInstall?.(`Successfully got URL from ${provider.getName()}: ${url}`);
|
|
88217
88374
|
if (!existsSync5(browserRoot)) {
|
|
88218
|
-
await
|
|
88375
|
+
await mkdir9(browserRoot, { recursive: true });
|
|
88219
88376
|
}
|
|
88220
88377
|
return await installUrl(url, options, provider);
|
|
88221
88378
|
} catch (err) {
|
|
@@ -88288,7 +88445,7 @@ async function installUrl(url, options, provider) {
|
|
|
88288
88445
|
const browserRoot = cache.browserRoot(options.browser);
|
|
88289
88446
|
const archivePath = path10.join(browserRoot, `${options.buildId}-${fileName}`);
|
|
88290
88447
|
if (!existsSync5(browserRoot)) {
|
|
88291
|
-
await
|
|
88448
|
+
await mkdir9(browserRoot, { recursive: true });
|
|
88292
88449
|
}
|
|
88293
88450
|
if (options.expectedHash) {
|
|
88294
88451
|
debugInstall?.(`Using provided checksum for ${fileName}: ${options.expectedHash}`);
|
|
@@ -89079,18 +89236,18 @@ var init_cliui = __esm({
|
|
|
89079
89236
|
});
|
|
89080
89237
|
|
|
89081
89238
|
// ../../node_modules/.pnpm/escalade@3.2.0/node_modules/escalade/sync/index.mjs
|
|
89082
|
-
import { dirname as
|
|
89239
|
+
import { dirname as dirname7, resolve as resolve10 } from "path";
|
|
89083
89240
|
import { readdirSync, statSync as statSync2 } from "fs";
|
|
89084
89241
|
function sync_default(start, callback) {
|
|
89085
89242
|
let dir = resolve10(".", start);
|
|
89086
89243
|
let tmp, stats = statSync2(dir);
|
|
89087
89244
|
if (!stats.isDirectory()) {
|
|
89088
|
-
dir =
|
|
89245
|
+
dir = dirname7(dir);
|
|
89089
89246
|
}
|
|
89090
89247
|
while (true) {
|
|
89091
89248
|
tmp = callback(dir, readdirSync(dir));
|
|
89092
89249
|
if (tmp) return resolve10(dir, tmp);
|
|
89093
|
-
dir =
|
|
89250
|
+
dir = dirname7(tmp = dir);
|
|
89094
89251
|
if (tmp === dir) break;
|
|
89095
89252
|
}
|
|
89096
89253
|
}
|
|
@@ -90359,7 +90516,7 @@ var require_get_caller_file = __commonJS({
|
|
|
90359
90516
|
import { notStrictEqual, strictEqual } from "assert";
|
|
90360
90517
|
import { inspect } from "util";
|
|
90361
90518
|
import { fileURLToPath } from "url";
|
|
90362
|
-
import { basename as basename4, dirname as
|
|
90519
|
+
import { basename as basename4, dirname as dirname8, extname as extname2, relative as relative3, resolve as resolve13, join as join7 } from "path";
|
|
90363
90520
|
import { createRequire as createRequire2 } from "node:module";
|
|
90364
90521
|
import { readFileSync as readFileSync5, readdirSync as readdirSync2 } from "node:fs";
|
|
90365
90522
|
var import_get_caller_file, __dirname2, mainFilename, require3, esm_default;
|
|
@@ -90392,7 +90549,7 @@ var init_esm2 = __esm({
|
|
|
90392
90549
|
Parser: lib_default,
|
|
90393
90550
|
path: {
|
|
90394
90551
|
basename: basename4,
|
|
90395
|
-
dirname:
|
|
90552
|
+
dirname: dirname8,
|
|
90396
90553
|
extname: extname2,
|
|
90397
90554
|
relative: relative3,
|
|
90398
90555
|
resolve: resolve13,
|
|
@@ -95599,7 +95756,7 @@ var init_PuppeteerNode = __esm({
|
|
|
95599
95756
|
import { spawn as spawn3, spawnSync as spawnSync3 } from "node:child_process";
|
|
95600
95757
|
import fs8 from "node:fs";
|
|
95601
95758
|
import os10 from "node:os";
|
|
95602
|
-
import { dirname as
|
|
95759
|
+
import { dirname as dirname9 } from "node:path";
|
|
95603
95760
|
import { PassThrough } from "node:stream";
|
|
95604
95761
|
function countFrames(startTimestamp, previousTimestamp, timestamp, fps) {
|
|
95605
95762
|
const end = Math.round((timestamp - startTimestamp) * fps);
|
|
@@ -95723,7 +95880,7 @@ var init_ScreenRecorder = __esm({
|
|
|
95723
95880
|
filters2.push(formatArgs.splice(vf, 2).at(-1) ?? "");
|
|
95724
95881
|
}
|
|
95725
95882
|
if (path16) {
|
|
95726
|
-
fs8.mkdirSync(
|
|
95883
|
+
fs8.mkdirSync(dirname9(path16), { recursive: overwrite });
|
|
95727
95884
|
}
|
|
95728
95885
|
this.#process = spawn3(
|
|
95729
95886
|
ffmpegPath,
|
|
@@ -96910,7 +97067,7 @@ import {
|
|
|
96910
97067
|
symlinkSync,
|
|
96911
97068
|
writeFileSync as writeFileSync6
|
|
96912
97069
|
} from "node:fs";
|
|
96913
|
-
import { basename as basename42, dirname as
|
|
97070
|
+
import { basename as basename42, dirname as dirname112, isAbsolute as isAbsolute42, join as join21, relative as relative22, resolve as resolve122 } from "node:path";
|
|
96914
97071
|
import {
|
|
96915
97072
|
basename as basename32,
|
|
96916
97073
|
join as join20,
|
|
@@ -124195,7 +124352,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
124195
124352
|
writeFileSync6(join21(compileDir, "index.html"), compiled.html, "utf-8");
|
|
124196
124353
|
for (const [srcPath, html] of compiled.subCompositions) {
|
|
124197
124354
|
const outPath = join21(compileDir, srcPath);
|
|
124198
|
-
mkdirSync9(
|
|
124355
|
+
mkdirSync9(dirname112(outPath), { recursive: true });
|
|
124199
124356
|
writeFileSync6(outPath, html, "utf-8");
|
|
124200
124357
|
}
|
|
124201
124358
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
@@ -124204,7 +124361,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
124204
124361
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
124205
124362
|
continue;
|
|
124206
124363
|
}
|
|
124207
|
-
mkdirSync9(
|
|
124364
|
+
mkdirSync9(dirname112(outPath), { recursive: true });
|
|
124208
124365
|
copyFileSync3(absolutePath, outPath);
|
|
124209
124366
|
}
|
|
124210
124367
|
if (includeSummary) {
|
|
@@ -267045,7 +267202,7 @@ ${allInlineStyles}`.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
|
267045
267202
|
materializePathModule = {
|
|
267046
267203
|
resolve: resolve122,
|
|
267047
267204
|
join: join21,
|
|
267048
|
-
dirname:
|
|
267205
|
+
dirname: dirname112,
|
|
267049
267206
|
basename: basename42,
|
|
267050
267207
|
relative: relative22,
|
|
267051
267208
|
isAbsolute: isAbsolute42
|
|
@@ -269905,7 +270062,7 @@ __export(scene_render_exports, {
|
|
|
269905
270062
|
});
|
|
269906
270063
|
import { execFile as execFile4 } from "node:child_process";
|
|
269907
270064
|
import { existsSync as existsSync49 } from "node:fs";
|
|
269908
|
-
import { mkdir as
|
|
270065
|
+
import { mkdir as mkdir13, readFile as readFile17, stat as stat5, writeFile as writeFile16 } from "node:fs/promises";
|
|
269909
270066
|
import { resolve as resolve33, relative as relative9, dirname as dirname26, basename as basename8, join as join61, isAbsolute as isAbsolute8 } from "node:path";
|
|
269910
270067
|
import { promisify as promisify4 } from "node:util";
|
|
269911
270068
|
function qualityToCrf(quality = "standard") {
|
|
@@ -270051,7 +270208,7 @@ async function executeSceneRender(opts = {}) {
|
|
|
270051
270208
|
}
|
|
270052
270209
|
const projectName = projectConfig.config.name;
|
|
270053
270210
|
const outputPath = opts.output ? resolve33(projectDir, opts.output) : defaultOutputPath({ projectDir, projectName, format: opts.format, beatId: opts.beatId });
|
|
270054
|
-
await
|
|
270211
|
+
await mkdir13(dirname26(outputPath), { recursive: true });
|
|
270055
270212
|
const config4 = buildRenderConfig({
|
|
270056
270213
|
fps: opts.fps,
|
|
270057
270214
|
quality: opts.quality,
|
|
@@ -270247,7 +270404,7 @@ async function prepareBeatRenderRoot(opts) {
|
|
|
270247
270404
|
durationSec,
|
|
270248
270405
|
narrationPath
|
|
270249
270406
|
});
|
|
270250
|
-
await
|
|
270407
|
+
await mkdir13(dirname26(join61(opts.projectDir, root2)), { recursive: true });
|
|
270251
270408
|
await writeFile16(join61(opts.projectDir, root2), html, "utf-8");
|
|
270252
270409
|
return {
|
|
270253
270410
|
success: true,
|
|
@@ -270532,7 +270689,7 @@ var init_design_parse = __esm({
|
|
|
270532
270689
|
|
|
270533
270690
|
// ../cli/src/commands/_shared/compose-aivideo.ts
|
|
270534
270691
|
import { existsSync as existsSync50 } from "node:fs";
|
|
270535
|
-
import { mkdir as
|
|
270692
|
+
import { mkdir as mkdir14, readFile as readFile18, writeFile as writeFile17 } from "node:fs/promises";
|
|
270536
270693
|
import { join as join63, resolve as resolve34 } from "node:path";
|
|
270537
270694
|
function headingDescriptor(heading) {
|
|
270538
270695
|
const stripped = heading.replace(/^\s*beat\s+/i, "");
|
|
@@ -270695,7 +270852,7 @@ async function composeAiVideo(opts) {
|
|
|
270695
270852
|
}
|
|
270696
270853
|
clipRels.push(rel);
|
|
270697
270854
|
}
|
|
270698
|
-
await
|
|
270855
|
+
await mkdir14(join63(projectDir, "assets"), { recursive: true });
|
|
270699
270856
|
const bgRel = "assets/bg-full.mp4";
|
|
270700
270857
|
const concatArgs = buildBgConcatArgs(
|
|
270701
270858
|
clipRels.map((r2) => join63(projectDir, r2)),
|
|
@@ -270703,7 +270860,7 @@ async function composeAiVideo(opts) {
|
|
|
270703
270860
|
);
|
|
270704
270861
|
await execSafe("ffmpeg", concatArgs, { timeout: 6e5 });
|
|
270705
270862
|
const totalDurationSec = await probeDurationSec(join63(projectDir, bgRel));
|
|
270706
|
-
await
|
|
270863
|
+
await mkdir14(join63(projectDir, "compositions"), { recursive: true });
|
|
270707
270864
|
const sceneFiles = [];
|
|
270708
270865
|
for (let i3 = 0; i3 < beats.length; i3++) {
|
|
270709
270866
|
const beat = beats[i3];
|
|
@@ -270852,7 +271009,7 @@ var init_compose_aivideo = __esm({
|
|
|
270852
271009
|
|
|
270853
271010
|
// ../cli/src/commands/_shared/footage-assemble.ts
|
|
270854
271011
|
import { existsSync as existsSync51 } from "node:fs";
|
|
270855
|
-
import { mkdir as
|
|
271012
|
+
import { mkdir as mkdir15, writeFile as writeFile18 } from "node:fs/promises";
|
|
270856
271013
|
import { dirname as dirname27, isAbsolute as isAbsolute9, join as join64, resolve as resolve35 } from "node:path";
|
|
270857
271014
|
function planFootageTimeline(inputs, opts = {}) {
|
|
270858
271015
|
if (inputs.length === 0) {
|
|
@@ -271182,7 +271339,7 @@ async function executeFootageAssemble(opts) {
|
|
|
271182
271339
|
if (opts.dryRun) {
|
|
271183
271340
|
return { success: true, dryRun: true, outputPath, report };
|
|
271184
271341
|
}
|
|
271185
|
-
await
|
|
271342
|
+
await mkdir15(dirname27(outputPath), { recursive: true });
|
|
271186
271343
|
const args = buildFootageAssembleArgs({
|
|
271187
271344
|
sources: sourceRels.map((s2) => ({ path: join64(projectDir, s2.rel), kind: s2.kind })),
|
|
271188
271345
|
plan: plan2,
|
|
@@ -271543,6 +271700,37 @@ var init_composer_resolve = __esm({
|
|
|
271543
271700
|
}
|
|
271544
271701
|
});
|
|
271545
271702
|
|
|
271703
|
+
// ../cli/src/commands/_shared/build-video-providers.ts
|
|
271704
|
+
function isBuildVideoProvider(value) {
|
|
271705
|
+
return BUILD_VIDEO_PROVIDERS.includes(value);
|
|
271706
|
+
}
|
|
271707
|
+
function resolveBuildVideoProvider(value) {
|
|
271708
|
+
const provider = String(value ?? "seedance").toLowerCase();
|
|
271709
|
+
if (provider === "fal") return "seedance";
|
|
271710
|
+
return isBuildVideoProvider(provider) ? provider : "seedance";
|
|
271711
|
+
}
|
|
271712
|
+
function videoProviderConfigKey(provider) {
|
|
271713
|
+
switch (provider) {
|
|
271714
|
+
case "seedance":
|
|
271715
|
+
case "fal":
|
|
271716
|
+
return "fal";
|
|
271717
|
+
case "grok":
|
|
271718
|
+
return "xai";
|
|
271719
|
+
case "veo":
|
|
271720
|
+
case "omni":
|
|
271721
|
+
return "google";
|
|
271722
|
+
default:
|
|
271723
|
+
return provider;
|
|
271724
|
+
}
|
|
271725
|
+
}
|
|
271726
|
+
var BUILD_VIDEO_PROVIDERS;
|
|
271727
|
+
var init_build_video_providers = __esm({
|
|
271728
|
+
"../cli/src/commands/_shared/build-video-providers.ts"() {
|
|
271729
|
+
"use strict";
|
|
271730
|
+
BUILD_VIDEO_PROVIDERS = ["seedance", "grok", "kling", "runway", "omni", "veo"];
|
|
271731
|
+
}
|
|
271732
|
+
});
|
|
271733
|
+
|
|
271546
271734
|
// ../cli/src/commands/_shared/build-plan.ts
|
|
271547
271735
|
import { existsSync as existsSync54 } from "node:fs";
|
|
271548
271736
|
import { dirname as dirname28, join as join65, resolve as resolve37 } from "node:path";
|
|
@@ -272217,12 +272405,7 @@ function normalizeImageProvider(value) {
|
|
|
272217
272405
|
return provider || "openai";
|
|
272218
272406
|
}
|
|
272219
272407
|
function normalizeVideoProvider(value) {
|
|
272220
|
-
|
|
272221
|
-
if (provider === "fal") return "seedance";
|
|
272222
|
-
if (provider === "seedance" || provider === "grok" || provider === "kling" || provider === "runway" || provider === "veo") {
|
|
272223
|
-
return provider;
|
|
272224
|
-
}
|
|
272225
|
-
return "seedance";
|
|
272408
|
+
return resolveBuildVideoProvider(value);
|
|
272226
272409
|
}
|
|
272227
272410
|
function normalizeMusicProvider(value) {
|
|
272228
272411
|
const provider = String(value ?? "elevenlabs").toLowerCase();
|
|
@@ -272234,7 +272417,7 @@ function imageConfigKey(provider) {
|
|
|
272234
272417
|
return "openai";
|
|
272235
272418
|
}
|
|
272236
272419
|
function videoConfigKey(provider) {
|
|
272237
|
-
return provider
|
|
272420
|
+
return videoProviderConfigKey(provider);
|
|
272238
272421
|
}
|
|
272239
272422
|
function composerConfigKey(provider) {
|
|
272240
272423
|
return provider === "claude" ? "anthropic" : provider === "gemini" ? "google" : "openai";
|
|
@@ -272278,6 +272461,7 @@ var init_build_plan = __esm({
|
|
|
272278
272461
|
init_project_config();
|
|
272279
272462
|
init_scene_project();
|
|
272280
272463
|
init_storyboard_edit();
|
|
272464
|
+
init_build_video_providers();
|
|
272281
272465
|
VIDEO_COST_USD = 5;
|
|
272282
272466
|
MUSIC_COST_USD = 0.5;
|
|
272283
272467
|
ELEVENLABS_NARRATION_COST_USD = 0.05;
|
|
@@ -272456,7 +272640,7 @@ function registerMusicCommand(parent) {
|
|
|
272456
272640
|
console.log();
|
|
272457
272641
|
console.log(`Saved to: ${source_default.bold(outputPath)}`);
|
|
272458
272642
|
console.log(`Duration: ${duration}s`);
|
|
272459
|
-
console.log(`Provider: ElevenLabs (
|
|
272643
|
+
console.log(`Provider: ElevenLabs (${ELEVENLABS_MUSIC_MODEL})`);
|
|
272460
272644
|
if (options.instrumental) console.log(`Mode: Instrumental`);
|
|
272461
272645
|
console.log();
|
|
272462
272646
|
} else {
|
|
@@ -272596,6 +272780,48 @@ var init_scene_build_mode = __esm({
|
|
|
272596
272780
|
}
|
|
272597
272781
|
});
|
|
272598
272782
|
|
|
272783
|
+
// ../cli/src/utils/image-file.ts
|
|
272784
|
+
import { rm as rm6, writeFile as writeFile20 } from "node:fs/promises";
|
|
272785
|
+
import { extname as extname12 } from "node:path";
|
|
272786
|
+
function detectImageFormat(buffer) {
|
|
272787
|
+
if (buffer.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
|
|
272788
|
+
return "png";
|
|
272789
|
+
}
|
|
272790
|
+
if (buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) return "jpeg";
|
|
272791
|
+
if (buffer.toString("ascii", 0, 4) === "RIFF" && buffer.toString("ascii", 8, 12) === "WEBP") {
|
|
272792
|
+
return "webp";
|
|
272793
|
+
}
|
|
272794
|
+
return void 0;
|
|
272795
|
+
}
|
|
272796
|
+
async function writeImageFile(path16, buffer) {
|
|
272797
|
+
const wanted = EXTENSION_FORMATS[extname12(path16).toLowerCase()];
|
|
272798
|
+
const actual = detectImageFormat(buffer);
|
|
272799
|
+
if (!wanted || !actual || wanted === actual) {
|
|
272800
|
+
await writeFile20(path16, buffer);
|
|
272801
|
+
return;
|
|
272802
|
+
}
|
|
272803
|
+
const source3 = `${path16}.source.${actual === "jpeg" ? "jpg" : actual}`;
|
|
272804
|
+
await writeFile20(source3, buffer);
|
|
272805
|
+
try {
|
|
272806
|
+
await execSafe("ffmpeg", ["-y", "-loglevel", "error", "-i", source3, "-frames:v", "1", path16]);
|
|
272807
|
+
} finally {
|
|
272808
|
+
await rm6(source3, { force: true });
|
|
272809
|
+
}
|
|
272810
|
+
}
|
|
272811
|
+
var EXTENSION_FORMATS;
|
|
272812
|
+
var init_image_file = __esm({
|
|
272813
|
+
"../cli/src/utils/image-file.ts"() {
|
|
272814
|
+
"use strict";
|
|
272815
|
+
init_exec_safe();
|
|
272816
|
+
EXTENSION_FORMATS = {
|
|
272817
|
+
".png": "png",
|
|
272818
|
+
".jpg": "jpeg",
|
|
272819
|
+
".jpeg": "jpeg",
|
|
272820
|
+
".webp": "webp"
|
|
272821
|
+
};
|
|
272822
|
+
}
|
|
272823
|
+
});
|
|
272824
|
+
|
|
272599
272825
|
// ../cli/src/commands/_shared/scene-build.ts
|
|
272600
272826
|
var scene_build_exports = {};
|
|
272601
272827
|
__export(scene_build_exports, {
|
|
@@ -272604,7 +272830,7 @@ __export(scene_build_exports, {
|
|
|
272604
272830
|
resolveSceneBuildMode: () => resolveSceneBuildMode
|
|
272605
272831
|
});
|
|
272606
272832
|
import { existsSync as existsSync56, readFileSync as readFileSync21 } from "node:fs";
|
|
272607
|
-
import { copyFile as copyFile4, mkdir as
|
|
272833
|
+
import { copyFile as copyFile4, mkdir as mkdir16, readFile as readFile19, rm as rm7, writeFile as writeFile21 } from "node:fs/promises";
|
|
272608
272834
|
import { dirname as dirname29, join as join66, resolve as resolve40 } from "node:path";
|
|
272609
272835
|
function readProjectKindSync(projectDir) {
|
|
272610
272836
|
try {
|
|
@@ -273458,7 +273684,7 @@ async function dispatchNarration(beat, ctx) {
|
|
|
273458
273684
|
};
|
|
273459
273685
|
}
|
|
273460
273686
|
if (existsSync56(cacheAbs) && !ctx.force) {
|
|
273461
|
-
await
|
|
273687
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
273462
273688
|
await copyFile4(cacheAbs, abs);
|
|
273463
273689
|
await writeAssetMetadata({
|
|
273464
273690
|
projectDir: ctx.projectDir,
|
|
@@ -273489,14 +273715,14 @@ async function dispatchNarration(beat, ctx) {
|
|
|
273489
273715
|
ctx.onProgress({ type: "narration-failed", beatId: beat.id, error });
|
|
273490
273716
|
return { status: "failed", error };
|
|
273491
273717
|
}
|
|
273492
|
-
await
|
|
273493
|
-
await
|
|
273718
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
273719
|
+
await writeFile21(abs, result.audioBuffer);
|
|
273494
273720
|
for (const otherExt of ["mp3", "wav"]) {
|
|
273495
273721
|
const sibling = join66(ctx.projectDir, `assets/narration-${beat.id}.${otherExt}`);
|
|
273496
|
-
if (sibling !== abs && existsSync56(sibling)) await
|
|
273722
|
+
if (sibling !== abs && existsSync56(sibling)) await rm7(sibling, { force: true });
|
|
273497
273723
|
}
|
|
273498
|
-
await
|
|
273499
|
-
await
|
|
273724
|
+
await mkdir16(dirname29(cacheAbs), { recursive: true });
|
|
273725
|
+
await writeFile21(cacheAbs, result.audioBuffer);
|
|
273500
273726
|
await writeAssetMetadata({
|
|
273501
273727
|
projectDir: ctx.projectDir,
|
|
273502
273728
|
kind: "narration",
|
|
@@ -273552,8 +273778,8 @@ async function dispatchTranscript(beat, narrationPath, narrationFresh, ctx) {
|
|
|
273552
273778
|
return "skipped";
|
|
273553
273779
|
}
|
|
273554
273780
|
try {
|
|
273555
|
-
await
|
|
273556
|
-
await
|
|
273781
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
273782
|
+
await writeFile21(abs, JSON.stringify(words, null, 2), "utf-8");
|
|
273557
273783
|
} catch (err) {
|
|
273558
273784
|
ctx.onProgress({
|
|
273559
273785
|
type: "transcript-skipped",
|
|
@@ -273641,7 +273867,7 @@ async function buildCharacters(characters, ctx) {
|
|
|
273641
273867
|
}
|
|
273642
273868
|
const cacheAbs = join66(ctx.projectDir, cache.path);
|
|
273643
273869
|
if (existsSync56(cacheAbs) && !ctx.force) {
|
|
273644
|
-
await
|
|
273870
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
273645
273871
|
await copyFile4(cacheAbs, abs);
|
|
273646
273872
|
await writeAssetMetadata({
|
|
273647
273873
|
projectDir: ctx.projectDir,
|
|
@@ -273674,10 +273900,10 @@ async function buildCharacters(characters, ctx) {
|
|
|
273674
273900
|
ctx.onProgress({ type: "character-failed", name: character.name, error: generated.error });
|
|
273675
273901
|
continue;
|
|
273676
273902
|
}
|
|
273677
|
-
await
|
|
273678
|
-
await
|
|
273679
|
-
await
|
|
273680
|
-
await
|
|
273903
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
273904
|
+
await writeImageFile(abs, generated.buffer);
|
|
273905
|
+
await mkdir16(dirname29(cacheAbs), { recursive: true });
|
|
273906
|
+
await writeImageFile(cacheAbs, generated.buffer);
|
|
273681
273907
|
await writeAssetMetadata({
|
|
273682
273908
|
projectDir: ctx.projectDir,
|
|
273683
273909
|
kind: "character",
|
|
@@ -273746,7 +273972,7 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
273746
273972
|
}
|
|
273747
273973
|
const cacheAbs = join66(ctx.projectDir, cache.path);
|
|
273748
273974
|
if (existsSync56(cacheAbs) && !ctx.force) {
|
|
273749
|
-
await
|
|
273975
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
273750
273976
|
await copyFile4(cacheAbs, abs);
|
|
273751
273977
|
await writeAssetMetadata({
|
|
273752
273978
|
projectDir: ctx.projectDir,
|
|
@@ -273776,11 +274002,11 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
273776
274002
|
ctx.onProgress({ type: "backdrop-failed", beatId: beat.id, error });
|
|
273777
274003
|
return { status: "failed", error };
|
|
273778
274004
|
}
|
|
273779
|
-
await
|
|
274005
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
273780
274006
|
const buffer = generated.buffer;
|
|
273781
|
-
await
|
|
273782
|
-
await
|
|
273783
|
-
await
|
|
274007
|
+
await writeImageFile(abs, buffer);
|
|
274008
|
+
await mkdir16(dirname29(cacheAbs), { recursive: true });
|
|
274009
|
+
await writeImageFile(cacheAbs, buffer);
|
|
273784
274010
|
await writeAssetMetadata({
|
|
273785
274011
|
projectDir: ctx.projectDir,
|
|
273786
274012
|
kind: "backdrop",
|
|
@@ -273824,7 +274050,7 @@ async function generateBackdropImage(prompt3, ctx, ratio) {
|
|
|
273824
274050
|
const result2 = await provider2.generateImage(prompt3, {
|
|
273825
274051
|
// CLI input is free-form; an alias the provider doesn't know fails the
|
|
273826
274052
|
// API call and surfaces as a beat-scoped backdrop/keyframe error.
|
|
273827
|
-
model: ctx.imageModel ??
|
|
274053
|
+
model: ctx.imageModel ?? OPENAI_IMAGE_DEFAULT_MODEL,
|
|
273828
274054
|
size: ctx.imageSize,
|
|
273829
274055
|
quality: ctx.imageQuality
|
|
273830
274056
|
});
|
|
@@ -273909,7 +274135,7 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
|
273909
274135
|
}
|
|
273910
274136
|
const cacheAbs = join66(ctx.projectDir, cache.path);
|
|
273911
274137
|
if (existsSync56(cacheAbs) && !ctx.force) {
|
|
273912
|
-
await
|
|
274138
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
273913
274139
|
await copyFile4(cacheAbs, abs);
|
|
273914
274140
|
await writeAssetMetadata({
|
|
273915
274141
|
projectDir: ctx.projectDir,
|
|
@@ -273939,10 +274165,10 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
|
273939
274165
|
const identityLock = "Keep the EXACT same person and face as the reference image(s): identical facial features (eyes, nose shape, jawline), skin tone and complexion, hairstyle, hair color, and wardrobe. Do not restyle or change the face. Change only the scene, pose, framing, and lighting. ";
|
|
273940
274166
|
const generated = sheetBuffers.length > 0 ? await editKeyframeImage(`${identityLock}${keyframeCue}`, sheetBuffers, imgCtx, ratio) : await generateBackdropImage(keyframeCue, imgCtx, ratio);
|
|
273941
274167
|
if (!generated.success) return { status: "failed", error: generated.error };
|
|
273942
|
-
await
|
|
273943
|
-
await
|
|
273944
|
-
await
|
|
273945
|
-
await
|
|
274168
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
274169
|
+
await writeImageFile(abs, generated.buffer);
|
|
274170
|
+
await mkdir16(dirname29(cacheAbs), { recursive: true });
|
|
274171
|
+
await writeImageFile(cacheAbs, generated.buffer);
|
|
273946
274172
|
await writeAssetMetadata({
|
|
273947
274173
|
projectDir: ctx.projectDir,
|
|
273948
274174
|
kind: "keyframe",
|
|
@@ -274038,7 +274264,7 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
274038
274264
|
}
|
|
274039
274265
|
const cacheAbs = join66(ctx.projectDir, cache.path);
|
|
274040
274266
|
if (existsSync56(cacheAbs) && !ctx.force) {
|
|
274041
|
-
await
|
|
274267
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
274042
274268
|
await copyFile4(cacheAbs, abs);
|
|
274043
274269
|
await writeAssetMetadata({
|
|
274044
274270
|
projectDir: ctx.projectDir,
|
|
@@ -274115,7 +274341,7 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
274115
274341
|
}
|
|
274116
274342
|
}
|
|
274117
274343
|
if (result.status === "completed" && existsSync56(abs)) {
|
|
274118
|
-
await
|
|
274344
|
+
await mkdir16(dirname29(cacheAbs), { recursive: true });
|
|
274119
274345
|
await copyFile4(abs, cacheAbs);
|
|
274120
274346
|
await writeAssetMetadata({
|
|
274121
274347
|
projectDir: ctx.projectDir,
|
|
@@ -274217,7 +274443,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
274217
274443
|
}
|
|
274218
274444
|
const cacheAbs = join66(ctx.projectDir, cache.path);
|
|
274219
274445
|
if (existsSync56(cacheAbs) && !ctx.force) {
|
|
274220
|
-
await
|
|
274446
|
+
await mkdir16(dirname29(abs), { recursive: true });
|
|
274221
274447
|
await copyFile4(cacheAbs, abs);
|
|
274222
274448
|
await writeAssetMetadata({
|
|
274223
274449
|
projectDir: ctx.projectDir,
|
|
@@ -274295,7 +274521,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
274295
274521
|
ctx.onProgress({ type: "music-failed", beatId: beat.id, error });
|
|
274296
274522
|
return { status: "failed", error };
|
|
274297
274523
|
}
|
|
274298
|
-
await
|
|
274524
|
+
await mkdir16(dirname29(cacheAbs), { recursive: true });
|
|
274299
274525
|
await copyFile4(abs, cacheAbs);
|
|
274300
274526
|
await writeAssetMetadata({
|
|
274301
274527
|
projectDir: ctx.projectDir,
|
|
@@ -274559,14 +274785,6 @@ async function safeAudioDuration(absPath) {
|
|
|
274559
274785
|
return void 0;
|
|
274560
274786
|
}
|
|
274561
274787
|
}
|
|
274562
|
-
function resolveBuildVideoProvider(value) {
|
|
274563
|
-
const provider = String(value ?? "seedance").toLowerCase();
|
|
274564
|
-
if (provider === "fal") return "seedance";
|
|
274565
|
-
if (provider === "seedance" || provider === "grok" || provider === "kling" || provider === "runway" || provider === "veo") {
|
|
274566
|
-
return provider;
|
|
274567
|
-
}
|
|
274568
|
-
return "seedance";
|
|
274569
|
-
}
|
|
274570
274788
|
function resolveBuildMusicProvider(value) {
|
|
274571
274789
|
const provider = String(value ?? "elevenlabs").toLowerCase();
|
|
274572
274790
|
return provider === "replicate" ? "replicate" : "elevenlabs";
|
|
@@ -274578,8 +274796,7 @@ function stringOrUndefined4(value) {
|
|
|
274578
274796
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
274579
274797
|
}
|
|
274580
274798
|
async function apiKeyForVideoProvider(provider, projectDir) {
|
|
274581
|
-
|
|
274582
|
-
return getApiKeyFromConfig(providerKey, { cwd: projectDir });
|
|
274799
|
+
return getApiKeyFromConfig(videoProviderConfigKey(provider), { cwd: projectDir });
|
|
274583
274800
|
}
|
|
274584
274801
|
async function finalizeBuildResult(projectDir, startedAt, result, reportResult = result) {
|
|
274585
274802
|
const reportPath = join66(projectDir, "build-report.json");
|
|
@@ -274602,7 +274819,7 @@ async function finalizeBuildResult(projectDir, startedAt, result, reportResult =
|
|
|
274602
274819
|
const withMeta = decorate(result);
|
|
274603
274820
|
const reportMeta = reportResult === result ? withMeta : decorate(reportResult);
|
|
274604
274821
|
try {
|
|
274605
|
-
await
|
|
274822
|
+
await writeFile21(
|
|
274606
274823
|
reportPath,
|
|
274607
274824
|
JSON.stringify(toBuildReport(projectDir, reportMeta), null, 2) + "\n",
|
|
274608
274825
|
"utf-8"
|
|
@@ -274855,6 +275072,8 @@ var init_scene_build = __esm({
|
|
|
274855
275072
|
init_scene_repair();
|
|
274856
275073
|
init_tts_resolve();
|
|
274857
275074
|
init_scene_build_mode();
|
|
275075
|
+
init_image_file();
|
|
275076
|
+
init_build_video_providers();
|
|
274858
275077
|
init_scene_build_mode();
|
|
274859
275078
|
BEAT_PRIMITIVES_CONCURRENCY = 4;
|
|
274860
275079
|
}
|
|
@@ -274967,8 +275186,8 @@ __export(ai_audio_exports, {
|
|
|
274967
275186
|
executeTranscribe: () => executeTranscribe,
|
|
274968
275187
|
executeVoiceClone: () => executeVoiceClone
|
|
274969
275188
|
});
|
|
274970
|
-
import { resolve as resolve43, dirname as dirname30, basename as basename9, extname as
|
|
274971
|
-
import { readFile as readFile20, writeFile as
|
|
275189
|
+
import { resolve as resolve43, dirname as dirname30, basename as basename9, extname as extname13 } from "node:path";
|
|
275190
|
+
import { readFile as readFile20, writeFile as writeFile23 } from "node:fs/promises";
|
|
274972
275191
|
import { existsSync as existsSync57 } from "node:fs";
|
|
274973
275192
|
async function executeTranscribe(options) {
|
|
274974
275193
|
const { audioPath, language, output: output3, format: format4, apiKey } = options;
|
|
@@ -274990,7 +275209,7 @@ async function executeTranscribe(options) {
|
|
|
274990
275209
|
outputPath = resolve43(process.cwd(), output3);
|
|
274991
275210
|
const fmt = detectFormat(output3, format4);
|
|
274992
275211
|
const content = formatTranscript(result, fmt);
|
|
274993
|
-
await
|
|
275212
|
+
await writeFile23(outputPath, content, "utf-8");
|
|
274994
275213
|
}
|
|
274995
275214
|
return {
|
|
274996
275215
|
success: true,
|
|
@@ -275018,7 +275237,7 @@ async function executeIsolate(options) {
|
|
|
275018
275237
|
return { success: false, error: result.error || "Audio isolation failed" };
|
|
275019
275238
|
}
|
|
275020
275239
|
const outputPath = resolve43(process.cwd(), output3);
|
|
275021
|
-
await
|
|
275240
|
+
await writeFile23(outputPath, result.audioBuffer);
|
|
275022
275241
|
return { success: true, outputPath };
|
|
275023
275242
|
} catch (error) {
|
|
275024
275243
|
return { success: false, error: `Audio isolation failed: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -275064,7 +275283,7 @@ async function executeDub(options) {
|
|
|
275064
275283
|
if (!openaiKey) return { success: false, error: "OPENAI_API_KEY required for Whisper transcription" };
|
|
275065
275284
|
if (!anthropicKey) return { success: false, error: "ANTHROPIC_API_KEY required for Claude translation" };
|
|
275066
275285
|
if (!analyzeOnly && !elevenlabsKey) return { success: false, error: "ELEVENLABS_API_KEY required for TTS" };
|
|
275067
|
-
const ext =
|
|
275286
|
+
const ext = extname13(absPath).toLowerCase();
|
|
275068
275287
|
const isVideo = [".mp4", ".mov", ".avi", ".mkv", ".webm"].includes(ext);
|
|
275069
275288
|
let audioPath = absPath;
|
|
275070
275289
|
if (isVideo) {
|
|
@@ -275129,7 +275348,7 @@ ${segmentTexts}`,
|
|
|
275129
275348
|
translated: translatedSegments[i3]?.text || s2.text
|
|
275130
275349
|
}))
|
|
275131
275350
|
};
|
|
275132
|
-
await
|
|
275351
|
+
await writeFile23(timingPath, JSON.stringify(timingData, null, 2));
|
|
275133
275352
|
}
|
|
275134
275353
|
return {
|
|
275135
275354
|
success: true,
|
|
@@ -275149,10 +275368,10 @@ ${segmentTexts}`,
|
|
|
275149
275368
|
}
|
|
275150
275369
|
}
|
|
275151
275370
|
const combinedBuffer = Buffer.concat(dubbedBuffers);
|
|
275152
|
-
const outputExt = isVideo ? ".mp3" :
|
|
275153
|
-
const defaultOutputPath2 = resolve43(dirname30(absPath), `${basename9(absPath,
|
|
275371
|
+
const outputExt = isVideo ? ".mp3" : extname13(absPath);
|
|
275372
|
+
const defaultOutputPath2 = resolve43(dirname30(absPath), `${basename9(absPath, extname13(absPath))}-${language}${outputExt}`);
|
|
275154
275373
|
const finalOutputPath = resolve43(process.cwd(), output3 || defaultOutputPath2);
|
|
275155
|
-
await
|
|
275374
|
+
await writeFile23(finalOutputPath, combinedBuffer);
|
|
275156
275375
|
if (isVideo && audioPath !== absPath) {
|
|
275157
275376
|
try {
|
|
275158
275377
|
const { unlink: unlink6 } = await import("node:fs/promises");
|
|
@@ -275187,7 +275406,7 @@ async function executeDuck(options) {
|
|
|
275187
275406
|
const absVoicePath = resolve43(process.cwd(), voicePath);
|
|
275188
275407
|
if (!existsSync57(absMusicPath)) return { success: false, error: `Music file not found: ${absMusicPath}` };
|
|
275189
275408
|
if (!existsSync57(absVoicePath)) return { success: false, error: `Voice file not found: ${absVoicePath}` };
|
|
275190
|
-
const defaultOutput = resolve43(dirname30(absMusicPath), `${basename9(absMusicPath,
|
|
275409
|
+
const defaultOutput = resolve43(dirname30(absMusicPath), `${basename9(absMusicPath, extname13(absMusicPath))}-ducked${extname13(absMusicPath)}`);
|
|
275191
275410
|
const outputPath = resolve43(process.cwd(), output3 || defaultOutput);
|
|
275192
275411
|
const filter3 = `[1:a]asplit=2[sc][mix];[0:a][sc]sidechaincompress=threshold=${threshold}dB:ratio=${ratio}:attack=${attack}:release=${release}[ducked];[ducked][mix]amix=inputs=2:duration=longest`;
|
|
275193
275412
|
await execSafe("ffmpeg", [
|
|
@@ -275452,7 +275671,7 @@ var init_silence_cut = __esm({
|
|
|
275452
275671
|
|
|
275453
275672
|
// ../cli/src/commands/_shared/edit/jump-cut.ts
|
|
275454
275673
|
import { existsSync as existsSync59 } from "node:fs";
|
|
275455
|
-
import { readFile as readFile23, writeFile as
|
|
275674
|
+
import { readFile as readFile23, writeFile as writeFile24, mkdir as mkdir17 } from "node:fs/promises";
|
|
275456
275675
|
import { join as join67 } from "node:path";
|
|
275457
275676
|
async function transcribeWithWords(audioPath, apiKey, language) {
|
|
275458
275677
|
const audioBuffer = await readFile23(audioPath);
|
|
@@ -275532,7 +275751,7 @@ async function executeJumpCut(options) {
|
|
|
275532
275751
|
}
|
|
275533
275752
|
try {
|
|
275534
275753
|
const tmpDir = `/tmp/vibe_jumpcut_${Date.now()}`;
|
|
275535
|
-
await
|
|
275754
|
+
await mkdir17(tmpDir, { recursive: true });
|
|
275536
275755
|
const audioPath = join67(tmpDir, "audio.wav");
|
|
275537
275756
|
try {
|
|
275538
275757
|
await execSafe(
|
|
@@ -275611,7 +275830,7 @@ async function executeJumpCut(options) {
|
|
|
275611
275830
|
}
|
|
275612
275831
|
const concatList = segmentPaths.map((p2) => `file '${p2}'`).join("\n");
|
|
275613
275832
|
const listPath = join67(tmpDir, "concat.txt");
|
|
275614
|
-
await
|
|
275833
|
+
await writeFile24(listPath, concatList);
|
|
275615
275834
|
await execSafe(
|
|
275616
275835
|
"ffmpeg",
|
|
275617
275836
|
[
|
|
@@ -275638,8 +275857,8 @@ async function executeJumpCut(options) {
|
|
|
275638
275857
|
};
|
|
275639
275858
|
} finally {
|
|
275640
275859
|
try {
|
|
275641
|
-
const { rm:
|
|
275642
|
-
await
|
|
275860
|
+
const { rm: rm11 } = await import("node:fs/promises");
|
|
275861
|
+
await rm11(tmpDir, { recursive: true, force: true });
|
|
275643
275862
|
} catch {
|
|
275644
275863
|
}
|
|
275645
275864
|
}
|
|
@@ -275716,7 +275935,7 @@ __export(remotion_exports, {
|
|
|
275716
275935
|
wrapComponentWithImage: () => wrapComponentWithImage,
|
|
275717
275936
|
wrapComponentWithVideo: () => wrapComponentWithVideo
|
|
275718
275937
|
});
|
|
275719
|
-
import { writeFile as
|
|
275938
|
+
import { writeFile as writeFile25, mkdir as mkdir18, rm as rm8, copyFile as copyFile5 } from "node:fs/promises";
|
|
275720
275939
|
import { existsSync as existsSync60 } from "node:fs";
|
|
275721
275940
|
import { join as join68 } from "node:path";
|
|
275722
275941
|
import { tmpdir as tmpdir9 } from "node:os";
|
|
@@ -275738,7 +275957,7 @@ async function ensureRemotionInstalled() {
|
|
|
275738
275957
|
}
|
|
275739
275958
|
async function scaffoldRemotionProject(componentCode, componentName, opts) {
|
|
275740
275959
|
const dir = join68(tmpdir9(), `vibe_motion_${Date.now()}`);
|
|
275741
|
-
await
|
|
275960
|
+
await mkdir18(dir, { recursive: true });
|
|
275742
275961
|
const deps = {
|
|
275743
275962
|
remotion: REMOTION_VERSION,
|
|
275744
275963
|
"@remotion/cli": REMOTION_VERSION,
|
|
@@ -275756,7 +275975,7 @@ async function scaffoldRemotionProject(componentCode, componentName, opts) {
|
|
|
275756
275975
|
dependencies: deps
|
|
275757
275976
|
};
|
|
275758
275977
|
const packageJsonStr = JSON.stringify(packageJson, null, 2);
|
|
275759
|
-
await
|
|
275978
|
+
await writeFile25(join68(dir, "package.json"), packageJsonStr);
|
|
275760
275979
|
const tsconfig = {
|
|
275761
275980
|
compilerOptions: {
|
|
275762
275981
|
target: "ES2020",
|
|
@@ -275768,8 +275987,8 @@ async function scaffoldRemotionProject(componentCode, componentName, opts) {
|
|
|
275768
275987
|
skipLibCheck: true
|
|
275769
275988
|
}
|
|
275770
275989
|
};
|
|
275771
|
-
await
|
|
275772
|
-
await
|
|
275990
|
+
await writeFile25(join68(dir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
|
|
275991
|
+
await writeFile25(join68(dir, "Component.tsx"), componentCode);
|
|
275773
275992
|
const rootCode = `import { registerRoot, Composition } from "remotion";
|
|
275774
275993
|
import { ${componentName} } from "./Component";
|
|
275775
275994
|
|
|
@@ -275788,7 +276007,7 @@ const Root = () => {
|
|
|
275788
276007
|
|
|
275789
276008
|
registerRoot(Root);
|
|
275790
276009
|
`;
|
|
275791
|
-
await
|
|
276010
|
+
await writeFile25(join68(dir, "Root.tsx"), rootCode);
|
|
275792
276011
|
const depsHash = createHash11("md5").update(packageJsonStr).digest("hex").slice(0, 12);
|
|
275793
276012
|
const cacheMarker = join68(REMOTION_CACHE_DIR, `.deps-${depsHash}`);
|
|
275794
276013
|
const cachedModules = join68(REMOTION_CACHE_DIR, "node_modules");
|
|
@@ -275802,15 +276021,15 @@ registerRoot(Root);
|
|
|
275802
276021
|
} else {
|
|
275803
276022
|
await this_npmInstall(dir);
|
|
275804
276023
|
try {
|
|
275805
|
-
await
|
|
275806
|
-
await
|
|
276024
|
+
await mkdir18(REMOTION_CACHE_DIR, { recursive: true });
|
|
276025
|
+
await writeFile25(join68(REMOTION_CACHE_DIR, "package.json"), packageJsonStr);
|
|
275807
276026
|
if (existsSync60(join68(dir, "node_modules"))) {
|
|
275808
276027
|
const { rename: rename7, symlink: symlink4 } = await import("node:fs/promises");
|
|
275809
276028
|
await rename7(join68(dir, "node_modules"), cachedModules).catch(() => {
|
|
275810
276029
|
});
|
|
275811
276030
|
await symlink4(cachedModules, join68(dir, "node_modules"), "dir").catch(() => {
|
|
275812
276031
|
});
|
|
275813
|
-
await
|
|
276032
|
+
await writeFile25(cacheMarker, depsHash);
|
|
275814
276033
|
}
|
|
275815
276034
|
} catch {
|
|
275816
276035
|
}
|
|
@@ -275910,7 +276129,7 @@ async function renderMotion(options) {
|
|
|
275910
276129
|
stderr: ${stderr}` : ""}`);
|
|
275911
276130
|
return { success: false, error: `Remotion render failed: ${msg}` };
|
|
275912
276131
|
} finally {
|
|
275913
|
-
await
|
|
276132
|
+
await rm8(dir, { recursive: true, force: true }).catch(() => {
|
|
275914
276133
|
});
|
|
275915
276134
|
}
|
|
275916
276135
|
}
|
|
@@ -275979,7 +276198,7 @@ async function renderWithEmbeddedImage(options) {
|
|
|
275979
276198
|
);
|
|
275980
276199
|
try {
|
|
275981
276200
|
const publicDir = join68(dir, "public");
|
|
275982
|
-
await
|
|
276201
|
+
await mkdir18(publicDir, { recursive: true });
|
|
275983
276202
|
await copyFile5(options.imagePath, join68(publicDir, options.imageFileName));
|
|
275984
276203
|
const entryPoint = join68(dir, "Root.tsx");
|
|
275985
276204
|
const mp4Out = options.outputPath.replace(/\.\w+$/, ".mp4");
|
|
@@ -276002,7 +276221,7 @@ async function renderWithEmbeddedImage(options) {
|
|
|
276002
276221
|
const msg = error instanceof Error ? error.message : String(error);
|
|
276003
276222
|
return { success: false, error: `Remotion image embed render failed: ${msg}` };
|
|
276004
276223
|
} finally {
|
|
276005
|
-
await
|
|
276224
|
+
await rm8(dir, { recursive: true, force: true }).catch(() => {
|
|
276006
276225
|
});
|
|
276007
276226
|
}
|
|
276008
276227
|
}
|
|
@@ -276043,7 +276262,7 @@ async function renderWithEmbeddedVideo(options) {
|
|
|
276043
276262
|
);
|
|
276044
276263
|
try {
|
|
276045
276264
|
const publicDir = join68(dir, "public");
|
|
276046
|
-
await
|
|
276265
|
+
await mkdir18(publicDir, { recursive: true });
|
|
276047
276266
|
await copyFile5(options.videoPath, join68(publicDir, options.videoFileName));
|
|
276048
276267
|
const entryPoint = join68(dir, "Root.tsx");
|
|
276049
276268
|
const mp4VideoOnly = options.outputPath.replace(/\.\w+$/, "_video_only.mp4");
|
|
@@ -276079,14 +276298,14 @@ async function renderWithEmbeddedVideo(options) {
|
|
|
276079
276298
|
"-shortest",
|
|
276080
276299
|
mp4Out
|
|
276081
276300
|
], { timeout: 12e4 });
|
|
276082
|
-
await
|
|
276301
|
+
await rm8(mp4VideoOnly, { force: true }).catch(() => {
|
|
276083
276302
|
});
|
|
276084
276303
|
return { success: true, outputPath: mp4Out };
|
|
276085
276304
|
} catch (error) {
|
|
276086
276305
|
const msg = error instanceof Error ? error.message : String(error);
|
|
276087
276306
|
return { success: false, error: `Remotion video embed render failed: ${msg}` };
|
|
276088
276307
|
} finally {
|
|
276089
|
-
await
|
|
276308
|
+
await rm8(dir, { recursive: true, force: true }).catch(() => {
|
|
276090
276309
|
});
|
|
276091
276310
|
}
|
|
276092
276311
|
}
|
|
@@ -276467,8 +276686,8 @@ var init_remotion = __esm({
|
|
|
276467
276686
|
|
|
276468
276687
|
// ../cli/src/commands/_shared/edit/caption.ts
|
|
276469
276688
|
import { existsSync as existsSync61 } from "node:fs";
|
|
276470
|
-
import { readFile as readFile24, writeFile as
|
|
276471
|
-
import { dirname as dirname31, basename as basename10, extname as
|
|
276689
|
+
import { readFile as readFile24, writeFile as writeFile26, mkdir as mkdir19 } from "node:fs/promises";
|
|
276690
|
+
import { dirname as dirname31, basename as basename10, extname as extname14, join as join69 } from "node:path";
|
|
276472
276691
|
function getCaptionForceStyle(style, fontSize, fontColor, position) {
|
|
276473
276692
|
const alignment = position === "top" ? 8 : position === "center" ? 5 : 2;
|
|
276474
276693
|
const marginV = position === "center" ? 0 : 30;
|
|
@@ -276514,7 +276733,7 @@ async function executeCaption(options) {
|
|
|
276514
276733
|
}
|
|
276515
276734
|
try {
|
|
276516
276735
|
const tmpDir = `/tmp/vibe_caption_${Date.now()}`;
|
|
276517
|
-
await
|
|
276736
|
+
await mkdir19(tmpDir, { recursive: true });
|
|
276518
276737
|
const audioPath = join69(tmpDir, "audio.wav");
|
|
276519
276738
|
const srtPath = join69(tmpDir, "captions.srt");
|
|
276520
276739
|
try {
|
|
@@ -276547,7 +276766,7 @@ async function executeCaption(options) {
|
|
|
276547
276766
|
};
|
|
276548
276767
|
}
|
|
276549
276768
|
const srtContent = formatSRT(transcriptResult.segments);
|
|
276550
|
-
await
|
|
276769
|
+
await writeFile26(srtPath, srtContent);
|
|
276551
276770
|
const { width, height } = await getVideoResolution(videoPath);
|
|
276552
276771
|
const fontSize = customFontSize || Math.round(height / 18);
|
|
276553
276772
|
let hasSubtitles = false;
|
|
@@ -276587,9 +276806,9 @@ async function executeCaption(options) {
|
|
|
276587
276806
|
const outputDir2 = dirname31(outputPath);
|
|
276588
276807
|
const outputSrtPath2 = join69(
|
|
276589
276808
|
outputDir2,
|
|
276590
|
-
basename10(outputPath,
|
|
276809
|
+
basename10(outputPath, extname14(outputPath)) + ".srt"
|
|
276591
276810
|
);
|
|
276592
|
-
await
|
|
276811
|
+
await writeFile26(outputSrtPath2, srtContent);
|
|
276593
276812
|
return { success: false, error: `${remotionErr}
|
|
276594
276813
|
SRT saved to: ${outputSrtPath2}` };
|
|
276595
276814
|
}
|
|
@@ -276626,9 +276845,9 @@ SRT saved to: ${outputSrtPath2}` };
|
|
|
276626
276845
|
const outputDir2 = dirname31(outputPath);
|
|
276627
276846
|
const outputSrtPath2 = join69(
|
|
276628
276847
|
outputDir2,
|
|
276629
|
-
basename10(outputPath,
|
|
276848
|
+
basename10(outputPath, extname14(outputPath)) + ".srt"
|
|
276630
276849
|
);
|
|
276631
|
-
await
|
|
276850
|
+
await writeFile26(outputSrtPath2, srtContent);
|
|
276632
276851
|
return {
|
|
276633
276852
|
success: false,
|
|
276634
276853
|
error: `${renderResult.error}
|
|
@@ -276639,9 +276858,9 @@ SRT saved to: ${outputSrtPath2}`
|
|
|
276639
276858
|
const outputDir = dirname31(outputPath);
|
|
276640
276859
|
const outputSrtPath = join69(
|
|
276641
276860
|
outputDir,
|
|
276642
|
-
basename10(outputPath,
|
|
276861
|
+
basename10(outputPath, extname14(outputPath)) + ".srt"
|
|
276643
276862
|
);
|
|
276644
|
-
await
|
|
276863
|
+
await writeFile26(outputSrtPath, srtContent);
|
|
276645
276864
|
return {
|
|
276646
276865
|
success: true,
|
|
276647
276866
|
outputPath,
|
|
@@ -276650,8 +276869,8 @@ SRT saved to: ${outputSrtPath2}`
|
|
|
276650
276869
|
};
|
|
276651
276870
|
} finally {
|
|
276652
276871
|
try {
|
|
276653
|
-
const { rm:
|
|
276654
|
-
await
|
|
276872
|
+
const { rm: rm11 } = await import("node:fs/promises");
|
|
276873
|
+
await rm11(tmpDir, { recursive: true, force: true });
|
|
276655
276874
|
} catch {
|
|
276656
276875
|
}
|
|
276657
276876
|
}
|
|
@@ -276812,7 +277031,7 @@ var init_fade = __esm({
|
|
|
276812
277031
|
|
|
276813
277032
|
// ../cli/src/commands/_shared/edit/translate-srt.ts
|
|
276814
277033
|
import { existsSync as existsSync65 } from "node:fs";
|
|
276815
|
-
import { readFile as readFile25, writeFile as
|
|
277034
|
+
import { readFile as readFile25, writeFile as writeFile27 } from "node:fs/promises";
|
|
276816
277035
|
async function executeTranslateSrt(options) {
|
|
276817
277036
|
const {
|
|
276818
277037
|
srtPath,
|
|
@@ -276855,15 +277074,14 @@ ${textsToTranslate}`;
|
|
|
276855
277074
|
Authorization: `Bearer ${openaiKey}`
|
|
276856
277075
|
},
|
|
276857
277076
|
body: JSON.stringify({
|
|
276858
|
-
model: "gpt-5-mini",
|
|
276859
|
-
messages: [{ role: "user", content: translatePrompt }]
|
|
276860
|
-
temperature: 0.3
|
|
277077
|
+
model: "gpt-5.4-mini",
|
|
277078
|
+
messages: [{ role: "user", content: translatePrompt }]
|
|
276861
277079
|
})
|
|
276862
277080
|
});
|
|
276863
277081
|
if (!response.ok) {
|
|
276864
277082
|
return {
|
|
276865
277083
|
success: false,
|
|
276866
|
-
error: `OpenAI API error: ${response.status} ${response.statusText}`
|
|
277084
|
+
error: `OpenAI API error: ${response.status} ${response.statusText}: ${await response.text()}`
|
|
276867
277085
|
};
|
|
276868
277086
|
}
|
|
276869
277087
|
const data2 = await response.json();
|
|
@@ -276884,15 +277102,15 @@ ${textsToTranslate}`;
|
|
|
276884
277102
|
"anthropic-version": "2023-06-01"
|
|
276885
277103
|
},
|
|
276886
277104
|
body: JSON.stringify({
|
|
276887
|
-
model: "claude-sonnet-
|
|
276888
|
-
max_tokens:
|
|
277105
|
+
model: "claude-sonnet-5-5",
|
|
277106
|
+
max_tokens: 16e3,
|
|
276889
277107
|
messages: [{ role: "user", content: translatePrompt }]
|
|
276890
277108
|
})
|
|
276891
277109
|
});
|
|
276892
277110
|
if (!response.ok) {
|
|
276893
277111
|
return {
|
|
276894
277112
|
success: false,
|
|
276895
|
-
error: `Claude API error: ${response.status} ${response.statusText}`
|
|
277113
|
+
error: `Claude API error: ${response.status} ${response.statusText}: ${await response.text()}`
|
|
276896
277114
|
};
|
|
276897
277115
|
}
|
|
276898
277116
|
const data2 = await response.json();
|
|
@@ -276916,7 +277134,7 @@ ${textsToTranslate}`;
|
|
|
276916
277134
|
}
|
|
276917
277135
|
}
|
|
276918
277136
|
const translatedSrt = formatSRT(translatedSegments);
|
|
276919
|
-
await
|
|
277137
|
+
await writeFile27(outputPath, translatedSrt);
|
|
276920
277138
|
return {
|
|
276921
277139
|
success: true,
|
|
276922
277140
|
outputPath,
|
|
@@ -277168,7 +277386,7 @@ var init_ai_edit = __esm({
|
|
|
277168
277386
|
});
|
|
277169
277387
|
|
|
277170
277388
|
// ../cli/src/commands/ai-edit-cli.ts
|
|
277171
|
-
import { resolve as resolve45, extname as
|
|
277389
|
+
import { resolve as resolve45, extname as extname15, basename as basename11 } from "node:path";
|
|
277172
277390
|
import { existsSync as existsSync67 } from "node:fs";
|
|
277173
277391
|
function registerEditCommands(aiCommand) {
|
|
277174
277392
|
aiCommand.command("silence-cut").alias("sc").description("Remove silent segments from video (FFmpeg default, or Gemini for smart detection)").argument("<video>", "Video file path").option("-o, --output <path>", "Output file path (default: <name>-cut.<ext>)").option("--noise <dB>", "Silence threshold in dB (default: -30)", "-30").option("-d, --min-duration <seconds>", "Minimum silence duration to cut (default: 0.5)", "0.5").option("--padding <seconds>", "Padding around non-silent segments (default: 0.1)", "0.1").option("--analyze-only", "(deprecated - use `vibe detect silence`) Only detect silence, don't cut").option("--use-gemini", "Use Gemini Video Understanding for context-aware silence detection").option("-m, --model <model>", "Gemini model (default: flash)").option("--low-res", "Low resolution mode for longer videos (Gemini only)").option("-k, --api-key <key>", "Google API key override (or set GOOGLE_API_KEY env)").option("--dry-run", "Preview parameters without executing").addHelpText("after", `
|
|
@@ -277192,7 +277410,7 @@ No API key needed (FFmpeg only). Use --use-gemini for smart detection (requires
|
|
|
277192
277410
|
if (!commandExists("ffmpeg")) {
|
|
277193
277411
|
exitWithError(generalError("FFmpeg not found. Install with: brew install ffmpeg (macOS) or apt install ffmpeg (Linux). Run `vibe doctor` for details."));
|
|
277194
277412
|
}
|
|
277195
|
-
const ext =
|
|
277413
|
+
const ext = extname15(videoPath);
|
|
277196
277414
|
const name = basename11(videoPath, ext);
|
|
277197
277415
|
const outputPath = options.output || `${name}-cut${ext}`;
|
|
277198
277416
|
const useGemini = options.useGemini || false;
|
|
@@ -277322,7 +277540,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
277322
277540
|
if (!apiKey) {
|
|
277323
277541
|
exitWithError(authError("OPENAI_API_KEY", "OpenAI"));
|
|
277324
277542
|
}
|
|
277325
|
-
const ext =
|
|
277543
|
+
const ext = extname15(videoPath);
|
|
277326
277544
|
const name = basename11(videoPath, ext);
|
|
277327
277545
|
const outputPath = options.output || `${name}-captioned${ext}`;
|
|
277328
277546
|
const spinner2 = ora("Starting caption process...").start();
|
|
@@ -277396,7 +277614,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
277396
277614
|
});
|
|
277397
277615
|
return;
|
|
277398
277616
|
}
|
|
277399
|
-
const ext =
|
|
277617
|
+
const ext = extname15(inputPath);
|
|
277400
277618
|
const name = basename11(inputPath, ext);
|
|
277401
277619
|
const outputPath = options.output || `${name}-denoised${ext}`;
|
|
277402
277620
|
const spinner2 = ora("Applying noise reduction...").start();
|
|
@@ -277464,7 +277682,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
277464
277682
|
});
|
|
277465
277683
|
return;
|
|
277466
277684
|
}
|
|
277467
|
-
const ext =
|
|
277685
|
+
const ext = extname15(videoPath);
|
|
277468
277686
|
const name = basename11(videoPath, ext);
|
|
277469
277687
|
const outputPath = options.output || `${name}-faded${ext}`;
|
|
277470
277688
|
const spinner2 = ora("Applying fade effects...").start();
|
|
@@ -277542,7 +277760,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
277542
277760
|
if (!apiKey) {
|
|
277543
277761
|
exitWithError(authError(envKey, providerName));
|
|
277544
277762
|
}
|
|
277545
|
-
const ext =
|
|
277763
|
+
const ext = extname15(srtPath);
|
|
277546
277764
|
const name = basename11(srtPath, ext);
|
|
277547
277765
|
const outputPath = options.output || `${name}-${options.target}${ext}`;
|
|
277548
277766
|
const spinner2 = ora(`Translating to ${options.target}...`).start();
|
|
@@ -277620,7 +277838,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
277620
277838
|
if (!apiKey) {
|
|
277621
277839
|
exitWithError(authError("OPENAI_API_KEY", "OpenAI"));
|
|
277622
277840
|
}
|
|
277623
|
-
const ext =
|
|
277841
|
+
const ext = extname15(videoPath);
|
|
277624
277842
|
const name = basename11(videoPath, ext);
|
|
277625
277843
|
const outputPath = options.output || `${name}-jumpcut${ext}`;
|
|
277626
277844
|
const fillers = options.fillers ? options.fillers.split(",").map((f2) => f2.trim()) : void 0;
|
|
@@ -278080,7 +278298,7 @@ var init_project_resolver = __esm({
|
|
|
278080
278298
|
|
|
278081
278299
|
// ../cli/src/commands/_shared/execute-fill-gaps.ts
|
|
278082
278300
|
import { existsSync as existsSync68 } from "node:fs";
|
|
278083
|
-
import { readFile as readFile26, writeFile as
|
|
278301
|
+
import { readFile as readFile26, writeFile as writeFile28, mkdir as mkdir20, rename as renameFs } from "node:fs/promises";
|
|
278084
278302
|
import { resolve as resolve47, dirname as dirname32 } from "node:path";
|
|
278085
278303
|
function detectVideoGaps(videoClips, totalDuration) {
|
|
278086
278304
|
const gaps = [];
|
|
@@ -278291,14 +278509,14 @@ async function executeFillGaps(options) {
|
|
|
278291
278509
|
if (!kling.isConfigured()) {
|
|
278292
278510
|
return {
|
|
278293
278511
|
success: false,
|
|
278294
|
-
error: "Invalid KLING_API_KEY (
|
|
278512
|
+
error: "Invalid KLING_API_KEY (set your Kling API key, or the legacy ACCESS_KEY:SECRET_KEY pair)",
|
|
278295
278513
|
humanLines
|
|
278296
278514
|
};
|
|
278297
278515
|
}
|
|
278298
278516
|
const projectDir = dirname32(filePath);
|
|
278299
278517
|
const footageDir = options.dir ? resolve47(process.cwd(), options.dir) : resolve47(projectDir, "footage");
|
|
278300
278518
|
if (!existsSync68(footageDir)) {
|
|
278301
|
-
await
|
|
278519
|
+
await mkdir20(footageDir, { recursive: true });
|
|
278302
278520
|
}
|
|
278303
278521
|
humanLines.push("Generating AI Videos");
|
|
278304
278522
|
const imgbbApiKey = options.imgbbApiKey || await getApiKey("IMGBB_API_KEY", "imgbb", void 0);
|
|
@@ -278363,13 +278581,13 @@ async function executeFillGaps(options) {
|
|
|
278363
278581
|
let generatedDuration = 0;
|
|
278364
278582
|
const generatedVideos = [];
|
|
278365
278583
|
const initialDuration = Math.min(10, targetDuration);
|
|
278366
|
-
const
|
|
278367
|
-
onProgress(`Generating ${
|
|
278584
|
+
const klingDuration2 = initialDuration > 5 ? "10" : "5";
|
|
278585
|
+
onProgress(`Generating ${klingDuration2}s video with Kling...`);
|
|
278368
278586
|
const prompt3 = options.prompt || "Continue the scene naturally with subtle motion";
|
|
278369
278587
|
const result = await kling.generateVideo(prompt3, {
|
|
278370
278588
|
prompt: prompt3,
|
|
278371
278589
|
referenceImage: frameUrl,
|
|
278372
|
-
duration: parseInt(
|
|
278590
|
+
duration: parseInt(klingDuration2),
|
|
278373
278591
|
aspectRatio: options.ratio || "16:9",
|
|
278374
278592
|
mode: options.mode || "std"
|
|
278375
278593
|
});
|
|
@@ -278392,8 +278610,8 @@ async function executeFillGaps(options) {
|
|
|
278392
278610
|
const videoPath = resolve47(footageDir, videoFileName);
|
|
278393
278611
|
onProgress("Downloading generated video...");
|
|
278394
278612
|
const videoBuffer = await downloadVideo(finalResult.videoUrl);
|
|
278395
|
-
await
|
|
278396
|
-
generatedDuration = finalResult.duration || parseInt(
|
|
278613
|
+
await writeFile28(videoPath, videoBuffer);
|
|
278614
|
+
generatedDuration = finalResult.duration || parseInt(klingDuration2);
|
|
278397
278615
|
generatedVideos.push(videoPath);
|
|
278398
278616
|
humanLines.push(` Generated: ${videoFileName} (${generatedDuration}s)`);
|
|
278399
278617
|
let segmentIndex = 1;
|
|
@@ -278462,11 +278680,11 @@ async function executeFillGaps(options) {
|
|
|
278462
278680
|
`gap-fill-${gap.start.toFixed(2)}-${gap.end.toFixed(2)}-seg${segmentIndex}.mp4`
|
|
278463
278681
|
);
|
|
278464
278682
|
const segVideoBuffer = await downloadVideo(segFinalResult.videoUrl);
|
|
278465
|
-
await
|
|
278683
|
+
await writeFile28(segVideoPath, segVideoBuffer);
|
|
278466
278684
|
const concatListPath = resolve47(footageDir, `concat-${gap.start.toFixed(2)}.txt`);
|
|
278467
278685
|
const concatList = generatedVideos.map((v4) => `file '${v4}'`).join("\n") + `
|
|
278468
278686
|
file '${segVideoPath}'`;
|
|
278469
|
-
await
|
|
278687
|
+
await writeFile28(concatListPath, concatList);
|
|
278470
278688
|
const concatOutputPath = resolve47(
|
|
278471
278689
|
footageDir,
|
|
278472
278690
|
`gap-fill-${gap.start.toFixed(2)}-${gap.end.toFixed(2)}-merged.mp4`
|
|
@@ -278524,7 +278742,7 @@ file '${segVideoPath}'`;
|
|
|
278524
278742
|
let outputPath = filePath;
|
|
278525
278743
|
if (generatedCount > 0) {
|
|
278526
278744
|
outputPath = options.output ? resolve47(process.cwd(), options.output) : filePath;
|
|
278527
|
-
await
|
|
278745
|
+
await writeFile28(outputPath, JSON.stringify(project.toJSON(), null, 2));
|
|
278528
278746
|
humanLines.push(`\u2714 Filled ${generatedCount} gap(s) with AI-generated video`);
|
|
278529
278747
|
humanLines.push(`Project saved: ${outputPath}`);
|
|
278530
278748
|
} else {
|
|
@@ -278618,7 +278836,7 @@ __export(ai_motion_exports, {
|
|
|
278618
278836
|
});
|
|
278619
278837
|
import { resolve as resolve48 } from "node:path";
|
|
278620
278838
|
import { existsSync as existsSync69 } from "node:fs";
|
|
278621
|
-
import { readFile as readFile27, writeFile as
|
|
278839
|
+
import { readFile as readFile27, writeFile as writeFile29 } from "node:fs/promises";
|
|
278622
278840
|
async function getOptionalGoogleApiKey() {
|
|
278623
278841
|
const configKey = await getApiKeyFromConfig("google");
|
|
278624
278842
|
if (configKey) return configKey;
|
|
@@ -278788,7 +279006,7 @@ Use this video understanding to place motion graphics in safe zones, match the c
|
|
|
278788
279006
|
const defaultOutput = options.video || options.image ? "motion-output.mp4" : options.render ? "motion.webm" : "motion.tsx";
|
|
278789
279007
|
const outputPath = resolve48(process.cwd(), options.output || defaultOutput);
|
|
278790
279008
|
const codePath = outputPath.replace(/\.\w+$/, ".tsx");
|
|
278791
|
-
await
|
|
279009
|
+
await writeFile29(codePath, component.code, "utf-8");
|
|
278792
279010
|
const shouldRender = options.render || !!options.video || !!options.image;
|
|
278793
279011
|
if (!shouldRender) {
|
|
278794
279012
|
return { success: true, codePath, componentName: component.name };
|
|
@@ -279024,8 +279242,8 @@ var init_ai_motion = __esm({
|
|
|
279024
279242
|
init_output();
|
|
279025
279243
|
init_validate();
|
|
279026
279244
|
MODEL_MAP2 = {
|
|
279027
|
-
sonnet: { provider: "claude", modelId: "claude-sonnet-
|
|
279028
|
-
opus: { provider: "claude", modelId: "claude-opus-
|
|
279245
|
+
sonnet: { provider: "claude", modelId: "claude-sonnet-5-5" },
|
|
279246
|
+
opus: { provider: "claude", modelId: "claude-opus-5-5" },
|
|
279029
279247
|
"opus-4-6": { provider: "claude", modelId: "claude-opus-4-6" },
|
|
279030
279248
|
gemini: { provider: "gemini", modelId: GEMINI_DEFAULT_TEXT_MODEL },
|
|
279031
279249
|
"gemini-2.5-pro": { provider: "gemini", modelId: "gemini-2.5-pro" },
|
|
@@ -279267,7 +279485,7 @@ __export(project_builder_exports, {
|
|
|
279267
279485
|
buildTempProject: () => buildTempProject,
|
|
279268
279486
|
resolveSourceUrl: () => resolveSourceUrl
|
|
279269
279487
|
});
|
|
279270
|
-
import { mkdtemp as mkdtemp5, mkdir as
|
|
279488
|
+
import { mkdtemp as mkdtemp5, mkdir as mkdir21, copyFile as copyFile6, writeFile as writeFile30, rm as rm9, readdir as readdir7 } from "node:fs/promises";
|
|
279271
279489
|
import { existsSync as existsSync70 } from "node:fs";
|
|
279272
279490
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
279273
279491
|
import { createRequire as createRequire4 } from "node:module";
|
|
@@ -279275,7 +279493,7 @@ import * as path15 from "node:path";
|
|
|
279275
279493
|
async function buildTempProject(state, projectFileDir) {
|
|
279276
279494
|
const dir = await mkdtemp5(path15.join(tmpdir10(), "vibeframe-hf-"));
|
|
279277
279495
|
const assetsDir = path15.join(dir, "assets");
|
|
279278
|
-
await
|
|
279496
|
+
await mkdir21(assetsDir, { recursive: true });
|
|
279279
279497
|
const copied = /* @__PURE__ */ new Map();
|
|
279280
279498
|
for (const source3 of state.sources) {
|
|
279281
279499
|
if (copied.has(source3.id)) continue;
|
|
@@ -279291,10 +279509,10 @@ async function buildTempProject(state, projectFileDir) {
|
|
|
279291
279509
|
await copyLottieRuntime(dir);
|
|
279292
279510
|
}
|
|
279293
279511
|
const html = generateCompositionHtml(state);
|
|
279294
|
-
await
|
|
279512
|
+
await writeFile30(path15.join(dir, "index.html"), html, "utf-8");
|
|
279295
279513
|
return {
|
|
279296
279514
|
dir,
|
|
279297
|
-
cleanup: () =>
|
|
279515
|
+
cleanup: () => rm9(dir, { recursive: true, force: true })
|
|
279298
279516
|
};
|
|
279299
279517
|
}
|
|
279300
279518
|
async function copyLottieRuntime(tempDir) {
|
|
@@ -279305,7 +279523,7 @@ async function copyLottieRuntime(tempDir) {
|
|
|
279305
279523
|
const wasmSrc = path15.join(path15.dirname(webEntry), "dotlottie-player.wasm");
|
|
279306
279524
|
const vendorDir = path15.join(tempDir, "vendor");
|
|
279307
279525
|
const wcDest = path15.join(vendorDir, "dotlottie-wc");
|
|
279308
|
-
await
|
|
279526
|
+
await mkdir21(wcDest, { recursive: true });
|
|
279309
279527
|
for (const file of await readdir7(wcDistDir)) {
|
|
279310
279528
|
if (file.endsWith(".map") || file.endsWith(".d.ts")) continue;
|
|
279311
279529
|
await copyFile6(path15.join(wcDistDir, file), path15.join(wcDest, file));
|
|
@@ -279413,9 +279631,9 @@ __export(motion_overlay_exports, {
|
|
|
279413
279631
|
executeMotionOverlay: () => executeMotionOverlay,
|
|
279414
279632
|
registerMotionOverlayCommand: () => registerMotionOverlayCommand
|
|
279415
279633
|
});
|
|
279416
|
-
import { mkdir as
|
|
279634
|
+
import { mkdir as mkdir23 } from "node:fs/promises";
|
|
279417
279635
|
import { existsSync as existsSync71 } from "node:fs";
|
|
279418
|
-
import { basename as basename13, dirname as dirname34, extname as
|
|
279636
|
+
import { basename as basename13, dirname as dirname34, extname as extname16, resolve as resolve50 } from "node:path";
|
|
279419
279637
|
function normalizeUnderstand2(value) {
|
|
279420
279638
|
return value === "off" || value === "required" || value === "auto" ? value : "auto";
|
|
279421
279639
|
}
|
|
@@ -279438,7 +279656,7 @@ function assertValidRequest(options) {
|
|
|
279438
279656
|
return "Provide a motion description, or pass --asset <logo.json|logo.lottie>.";
|
|
279439
279657
|
}
|
|
279440
279658
|
if (hasAsset) {
|
|
279441
|
-
const ext =
|
|
279659
|
+
const ext = extname16(options.asset).toLowerCase();
|
|
279442
279660
|
if (ext !== ".json" && ext !== ".lottie") {
|
|
279443
279661
|
return "Lottie overlay asset must be a .json or .lottie file.";
|
|
279444
279662
|
}
|
|
@@ -279561,7 +279779,7 @@ async function executeMotionOverlay(options) {
|
|
|
279561
279779
|
const scale = Math.max(0.01, Math.min(2, numberOption(options.scale, position === "full" ? 1 : 0.25)));
|
|
279562
279780
|
const opacity = Math.max(0, Math.min(1, numberOption(options.opacity, 1)));
|
|
279563
279781
|
const loop = options.loop ?? true;
|
|
279564
|
-
await
|
|
279782
|
+
await mkdir23(dirname34(outputPath), { recursive: true });
|
|
279565
279783
|
const backend = createHyperframesBackend();
|
|
279566
279784
|
const result2 = await backend.render({
|
|
279567
279785
|
projectState: buildLottieTimelineState({
|
|
@@ -279587,7 +279805,7 @@ async function executeMotionOverlay(options) {
|
|
|
279587
279805
|
return { success: true, outputPath, provider: "lottie" };
|
|
279588
279806
|
}
|
|
279589
279807
|
const duration = options.duration ?? await ffprobeDuration(absVideo).catch(() => void 0);
|
|
279590
|
-
await
|
|
279808
|
+
await mkdir23(dirname34(outputPath), { recursive: true });
|
|
279591
279809
|
const result = await executeMotion({
|
|
279592
279810
|
description: options.description.trim(),
|
|
279593
279811
|
video: absVideo,
|
|
@@ -279716,7 +279934,7 @@ __export(edit_cmd_exports, {
|
|
|
279716
279934
|
executeUpscale: () => executeUpscale
|
|
279717
279935
|
});
|
|
279718
279936
|
import { resolve as resolve51, dirname as dirname35 } from "node:path";
|
|
279719
|
-
import { readFile as readFile28, writeFile as
|
|
279937
|
+
import { readFile as readFile28, writeFile as writeFile31, mkdir as mkdir24 } from "node:fs/promises";
|
|
279720
279938
|
async function executeGrade(options) {
|
|
279721
279939
|
const { videoPath, style, preset: preset3, output: output3, analyzeOnly, apiKey } = options;
|
|
279722
279940
|
try {
|
|
@@ -279909,6 +280127,7 @@ var init_edit_cmd = __esm({
|
|
|
279909
280127
|
init_output();
|
|
279910
280128
|
init_validate();
|
|
279911
280129
|
init_cost_tier();
|
|
280130
|
+
init_image_file();
|
|
279912
280131
|
editCommand = new Command("edit").alias("ed").description(
|
|
279913
280132
|
"Edit and post-process media (silence-cut, caption, grade, reframe, upscale...)"
|
|
279914
280133
|
).addHelpText(
|
|
@@ -280344,7 +280563,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
280344
280563
|
console.log();
|
|
280345
280564
|
if (options.keyframes) {
|
|
280346
280565
|
const keyframesPath = resolve51(process.cwd(), options.keyframes);
|
|
280347
|
-
await
|
|
280566
|
+
await writeFile31(keyframesPath, JSON.stringify(cropKeyframes, null, 2));
|
|
280348
280567
|
console.log(source_default.green(`Keyframes saved to: ${keyframesPath}`));
|
|
280349
280568
|
}
|
|
280350
280569
|
if (options.analyzeOnly) {
|
|
@@ -280368,7 +280587,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
280368
280587
|
exitWithError(generalError(`Reframe failed: ${msg}`));
|
|
280369
280588
|
}
|
|
280370
280589
|
});
|
|
280371
|
-
editCommand.command("image").description("Edit image(s) using AI (Gemini, OpenAI, or Grok)").argument("<images...>", "Input image file(s) followed by edit prompt").option("-p, --provider <provider>", "Provider: gemini (default), openai, grok", "gemini").option("-k, --api-key <key>", "API key (or set env variable)").option("-o, --output <path>", "Output file path", "edited.png").option("-m, --model <model>", "Model: flash
|
|
280590
|
+
editCommand.command("image").description("Edit image(s) using AI (Gemini, OpenAI, or Grok)").argument("<images...>", "Input image file(s) followed by edit prompt").option("-p, --provider <provider>", "Provider: gemini (default), openai, grok", "gemini").option("-k, --api-key <key>", "API key (or set env variable)").option("-o, --output <path>", "Output file path", "edited.png").option("-m, --model <model>", "Model: flash, lite, pro (Gemini); pro (Grok)", "flash").option("-r, --ratio <ratio>", "Output aspect ratio").option("--size <resolution>", "Resolution: 1K, 2K, 4K (Gemini Pro only)").option("--dry-run", "Preview parameters without executing").action(async (args, options) => {
|
|
280372
280591
|
const startedAt = Date.now();
|
|
280373
280592
|
try {
|
|
280374
280593
|
if (args.length < 2) {
|
|
@@ -280427,14 +280646,16 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
280427
280646
|
const grok = new GrokProvider();
|
|
280428
280647
|
await grok.initialize({ apiKey });
|
|
280429
280648
|
result = await grok.editImage(imageBuffers[0], prompt3, {
|
|
280649
|
+
...resolveGrokImageModel(options.model),
|
|
280430
280650
|
aspectRatio: options.ratio
|
|
280431
280651
|
});
|
|
280432
280652
|
} else {
|
|
280433
280653
|
const editModelNames = {
|
|
280434
|
-
flash: "gemini-
|
|
280435
|
-
"3.1-flash": "gemini-3.1-flash-image
|
|
280436
|
-
latest: "gemini-3.1-flash-image
|
|
280437
|
-
|
|
280654
|
+
flash: "gemini-3.1-flash-image",
|
|
280655
|
+
"3.1-flash": "gemini-3.1-flash-image",
|
|
280656
|
+
latest: "gemini-3.1-flash-image",
|
|
280657
|
+
lite: "gemini-3.1-flash-lite-image",
|
|
280658
|
+
pro: "gemini-3-pro-image"
|
|
280438
280659
|
};
|
|
280439
280660
|
const editModelName = editModelNames[options.model] || editModelNames.flash;
|
|
280440
280661
|
spinner2.text = `Editing with ${editModelName}...`;
|
|
@@ -280445,15 +280666,6 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
280445
280666
|
aspectRatio: options.ratio,
|
|
280446
280667
|
resolution: options.size
|
|
280447
280668
|
});
|
|
280448
|
-
const fallbackModels = ["latest", "3.1-flash"];
|
|
280449
|
-
if (!result.success && fallbackModels.includes(options.model)) {
|
|
280450
|
-
spinner2.text = `${source_default.dim(result.error || `${editModelName} failed`)} \u2014 retrying with flash...`;
|
|
280451
|
-
result = await gemini.editImage(imageBuffers, prompt3, {
|
|
280452
|
-
model: "flash",
|
|
280453
|
-
aspectRatio: options.ratio,
|
|
280454
|
-
resolution: options.size
|
|
280455
|
-
});
|
|
280456
|
-
}
|
|
280457
280669
|
}
|
|
280458
280670
|
if (!result.success || !result.images || result.images.length === 0) {
|
|
280459
280671
|
spinner2.fail(result.error || "Image editing failed");
|
|
@@ -280463,14 +280675,14 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
280463
280675
|
const img = result.images[0];
|
|
280464
280676
|
const outputPath = resolve51(process.cwd(), options.output);
|
|
280465
280677
|
const saveImage = async () => {
|
|
280466
|
-
await
|
|
280678
|
+
await mkdir24(dirname35(outputPath), { recursive: true });
|
|
280467
280679
|
if (img.base64) {
|
|
280468
280680
|
const buffer = Buffer.from(img.base64, "base64");
|
|
280469
|
-
await
|
|
280681
|
+
await writeImageFile(outputPath, buffer);
|
|
280470
280682
|
} else if (img.url) {
|
|
280471
280683
|
const resp = await fetch(img.url);
|
|
280472
280684
|
const arrayBuf = await resp.arrayBuffer();
|
|
280473
|
-
await
|
|
280685
|
+
await writeImageFile(outputPath, Buffer.from(arrayBuf));
|
|
280474
280686
|
}
|
|
280475
280687
|
};
|
|
280476
280688
|
const resultModel = result.model;
|
|
@@ -280690,7 +280902,7 @@ __export(ai_image_exports, {
|
|
|
280690
280902
|
executeThumbnailBestFrame: () => executeThumbnailBestFrame
|
|
280691
280903
|
});
|
|
280692
280904
|
import { resolve as resolve54, dirname as dirname37 } from "node:path";
|
|
280693
|
-
import { readFile as readFile29,
|
|
280905
|
+
import { readFile as readFile29, mkdir as mkdir26 } from "node:fs/promises";
|
|
280694
280906
|
import { existsSync as existsSync74 } from "node:fs";
|
|
280695
280907
|
async function executeImageGenerate(options) {
|
|
280696
280908
|
const {
|
|
@@ -280733,8 +280945,8 @@ async function executeImageGenerate(options) {
|
|
|
280733
280945
|
return { success: false, error: "No image data available" };
|
|
280734
280946
|
}
|
|
280735
280947
|
outputPath = resolve54(process.cwd(), output3);
|
|
280736
|
-
await
|
|
280737
|
-
await
|
|
280948
|
+
await mkdir26(dirname37(outputPath), { recursive: true });
|
|
280949
|
+
await writeImageFile(outputPath, buffer);
|
|
280738
280950
|
}
|
|
280739
280951
|
return {
|
|
280740
280952
|
success: true,
|
|
@@ -280768,8 +280980,8 @@ async function executeImageGenerate(options) {
|
|
|
280768
280980
|
const img = result.images[0];
|
|
280769
280981
|
if (img.base64) {
|
|
280770
280982
|
outputPath = resolve54(process.cwd(), output3);
|
|
280771
|
-
await
|
|
280772
|
-
await
|
|
280983
|
+
await mkdir26(dirname37(outputPath), { recursive: true });
|
|
280984
|
+
await writeImageFile(outputPath, Buffer.from(img.base64, "base64"));
|
|
280773
280985
|
}
|
|
280774
280986
|
}
|
|
280775
280987
|
return {
|
|
@@ -280782,10 +280994,11 @@ async function executeImageGenerate(options) {
|
|
|
280782
280994
|
} else if (provider === "grok") {
|
|
280783
280995
|
const key2 = apiKey || process.env.XAI_API_KEY;
|
|
280784
280996
|
if (!key2) return { success: false, error: "XAI_API_KEY required" };
|
|
280785
|
-
const
|
|
280786
|
-
await
|
|
280787
|
-
const result = await
|
|
280788
|
-
|
|
280997
|
+
const grok = new GrokProvider();
|
|
280998
|
+
await grok.initialize({ apiKey: key2 });
|
|
280999
|
+
const result = await grok.generateImage(prompt3, {
|
|
281000
|
+
...resolveGrokImageModel(model),
|
|
281001
|
+
aspectRatio: ratio,
|
|
280789
281002
|
n: count
|
|
280790
281003
|
});
|
|
280791
281004
|
if (!result.success || !result.images) {
|
|
@@ -280804,8 +281017,8 @@ async function executeImageGenerate(options) {
|
|
|
280804
281017
|
return { success: false, error: "No image data available" };
|
|
280805
281018
|
}
|
|
280806
281019
|
outputPath = resolve54(process.cwd(), output3);
|
|
280807
|
-
await
|
|
280808
|
-
await
|
|
281020
|
+
await mkdir26(dirname37(outputPath), { recursive: true });
|
|
281021
|
+
await writeImageFile(outputPath, buffer);
|
|
280809
281022
|
}
|
|
280810
281023
|
return {
|
|
280811
281024
|
success: true,
|
|
@@ -280863,8 +281076,8 @@ async function executeGeminiEdit(options) {
|
|
|
280863
281076
|
let outputPath;
|
|
280864
281077
|
if (img.base64) {
|
|
280865
281078
|
outputPath = resolve54(process.cwd(), output3);
|
|
280866
|
-
await
|
|
280867
|
-
await
|
|
281079
|
+
await mkdir26(dirname37(outputPath), { recursive: true });
|
|
281080
|
+
await writeImageFile(outputPath, Buffer.from(img.base64, "base64"));
|
|
280868
281081
|
}
|
|
280869
281082
|
return {
|
|
280870
281083
|
success: true,
|
|
@@ -280938,6 +281151,7 @@ var init_ai_image = __esm({
|
|
|
280938
281151
|
"use strict";
|
|
280939
281152
|
init_dist();
|
|
280940
281153
|
init_exec_safe();
|
|
281154
|
+
init_image_file();
|
|
280941
281155
|
}
|
|
280942
281156
|
});
|
|
280943
281157
|
|
|
@@ -280949,7 +281163,7 @@ __export(ai_analyze_exports, {
|
|
|
280949
281163
|
registerAnalyzeCommands: () => registerAnalyzeCommands
|
|
280950
281164
|
});
|
|
280951
281165
|
import { readFile as readFile30 } from "node:fs/promises";
|
|
280952
|
-
import { extname as
|
|
281166
|
+
import { extname as extname17, resolve as resolve55 } from "node:path";
|
|
280953
281167
|
import { existsSync as existsSync75 } from "node:fs";
|
|
280954
281168
|
async function executeGeminiVideo(options) {
|
|
280955
281169
|
try {
|
|
@@ -281006,7 +281220,7 @@ async function executeAnalyze(options) {
|
|
|
281006
281220
|
const isYouTube = source3.includes("youtube.com") || source3.includes("youtu.be");
|
|
281007
281221
|
const isImageUrl = /^https?:\/\/.+\.(png|jpg|jpeg|webp|gif)(\?.*)?$/i.test(source3);
|
|
281008
281222
|
const isVideoUrl = /^https?:\/\/.+\.(mp4|mov|webm)(\?.*)?$/i.test(source3);
|
|
281009
|
-
const ext =
|
|
281223
|
+
const ext = extname17(source3).toLowerCase();
|
|
281010
281224
|
const imageExts = [".png", ".jpg", ".jpeg", ".webp", ".gif"];
|
|
281011
281225
|
const videoExts = [".mp4", ".mov", ".webm", ".avi", ".mkv"];
|
|
281012
281226
|
const isLocalImage = imageExts.includes(ext);
|
|
@@ -281414,7 +281628,7 @@ async function executeSoundEffect(options) {
|
|
|
281414
281628
|
}
|
|
281415
281629
|
}
|
|
281416
281630
|
function registerSoundEffectCommand(parent) {
|
|
281417
|
-
parent.command("sound-effect").description("Generate sound effect using ElevenLabs").argument("<prompt>", "Description of the sound effect").option("-k, --api-key <key>", "ElevenLabs API key (or set ELEVENLABS_API_KEY env)").option("-o, --output <path>", "Output audio file path", "sound-effect.mp3").option("-d, --duration <seconds>", "Duration in seconds (0.5-
|
|
281631
|
+
parent.command("sound-effect").description("Generate sound effect using ElevenLabs").argument("<prompt>", "Description of the sound effect").option("-k, --api-key <key>", "ElevenLabs API key (or set ELEVENLABS_API_KEY env)").option("-o, --output <path>", "Output audio file path", "sound-effect.mp3").option("-d, --duration <seconds>", "Duration in seconds (0.5-30, default: auto)").option("--prompt-influence <value>", "Prompt influence (0-1, default: 0.3)").option("--dry-run", "Preview parameters without executing").action(async (prompt3, options) => {
|
|
281418
281632
|
const startedAt = Date.now();
|
|
281419
281633
|
try {
|
|
281420
281634
|
rejectControlChars(prompt3);
|
|
@@ -281714,9 +281928,9 @@ var init_speech = __esm({
|
|
|
281714
281928
|
});
|
|
281715
281929
|
|
|
281716
281930
|
// ../cli/src/commands/generate/thumbnail.ts
|
|
281717
|
-
import { resolve as resolve64, dirname as dirname38, basename as basename17, extname as
|
|
281931
|
+
import { resolve as resolve64, dirname as dirname38, basename as basename17, extname as extname18 } from "node:path";
|
|
281718
281932
|
import { existsSync as existsSync79 } from "node:fs";
|
|
281719
|
-
import { writeFile as writeFile37, mkdir as
|
|
281933
|
+
import { writeFile as writeFile37, mkdir as mkdir27 } from "node:fs/promises";
|
|
281720
281934
|
function registerThumbnailCommand(parent) {
|
|
281721
281935
|
parent.command("thumbnail").description("Generate video thumbnail (DALL-E) or extract best frame from video (Gemini)").argument("[description]", "Thumbnail description (for DALL-E generation)").option("-k, --api-key <key>", "API key (OpenAI for generation, Google for best-frame)").option("-o, --output <path>", "Output file path").option("--style <style>", "Platform style: youtube, instagram, tiktok, twitter").option("--best-frame <video>", "Extract best thumbnail frame from video using Gemini AI").option("--prompt <prompt>", "Custom prompt for best-frame analysis").option("--model <model>", `Gemini model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").action(async (description, options) => {
|
|
281722
281936
|
const startedAt = Date.now();
|
|
@@ -281739,7 +281953,7 @@ function registerThumbnailCommand(parent) {
|
|
|
281739
281953
|
);
|
|
281740
281954
|
}
|
|
281741
281955
|
const apiKey2 = await requireApiKey("GOOGLE_API_KEY", "Google", options.apiKey);
|
|
281742
|
-
const name = basename17(options.bestFrame,
|
|
281956
|
+
const name = basename17(options.bestFrame, extname18(options.bestFrame));
|
|
281743
281957
|
const outputPath = options.output || `${name}-thumbnail.png`;
|
|
281744
281958
|
const spinner3 = ora("Analyzing video for best frame...").start();
|
|
281745
281959
|
const result2 = await executeThumbnailBestFrame({
|
|
@@ -281807,7 +282021,7 @@ function registerThumbnailCommand(parent) {
|
|
|
281807
282021
|
throw new Error("No image data available");
|
|
281808
282022
|
}
|
|
281809
282023
|
outputPath = resolve64(process.cwd(), options.output);
|
|
281810
|
-
await
|
|
282024
|
+
await mkdir27(dirname38(outputPath), { recursive: true });
|
|
281811
282025
|
await writeFile37(outputPath, buffer);
|
|
281812
282026
|
}
|
|
281813
282027
|
outputSuccess({
|
|
@@ -281838,7 +282052,7 @@ function registerThumbnailCommand(parent) {
|
|
|
281838
282052
|
throw new Error("No image data available");
|
|
281839
282053
|
}
|
|
281840
282054
|
const outputPath = resolve64(process.cwd(), options.output);
|
|
281841
|
-
await
|
|
282055
|
+
await mkdir27(dirname38(outputPath), { recursive: true });
|
|
281842
282056
|
await writeFile37(outputPath, buffer);
|
|
281843
282057
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
281844
282058
|
} catch {
|
|
@@ -281869,7 +282083,7 @@ var init_thumbnail = __esm({
|
|
|
281869
282083
|
import { resolve as resolve65 } from "node:path";
|
|
281870
282084
|
import { writeFile as writeFile38 } from "node:fs/promises";
|
|
281871
282085
|
function registerVideoExtendCommand(parent) {
|
|
281872
|
-
parent.command("video-extend", { hidden: true }).description("Extend video duration (Kling by video ID, Veo by operation name)").argument("<id>", "Kling video ID or Veo operation name").option("-p, --provider <provider>", "Provider: kling, veo", "kling").option("-k, --api-key <key>", "API key (KLING_API_KEY or GOOGLE_API_KEY)").option("-o, --output <path>", "Output file path").option("--prompt <text>", "Continuation prompt").option("-d, --duration <sec>", "Duration: 5 or 10 (Kling), 4/6/8 (Veo)", "5").option("--negative <prompt>", "Negative prompt (what to avoid, Kling only)").option("--veo-model <model>", "Veo model: 3.
|
|
282086
|
+
parent.command("video-extend", { hidden: true }).description("Extend video duration (Kling by video ID, Veo by operation name)").argument("<id>", "Kling video ID or Veo operation name").option("-p, --provider <provider>", "Provider: kling, veo", "kling").option("-k, --api-key <key>", "API key (KLING_API_KEY or GOOGLE_API_KEY)").option("-o, --output <path>", "Output file path").option("--prompt <text>", "Continuation prompt").option("-d, --duration <sec>", "Duration: 5 or 10 (Kling), 4/6/8 (Veo)", "5").option("--negative <prompt>", "Negative prompt (what to avoid, Kling only)").option("--veo-model <model>", "Veo model: 3.1, 3.1-fast", "3.1").option("--no-wait", "Start extension and return task ID without waiting").option("--dry-run", "Preview parameters without executing").action(async (id, options) => {
|
|
281873
282087
|
const startedAt = Date.now();
|
|
281874
282088
|
try {
|
|
281875
282089
|
const provider = (options.provider || "kling").toLowerCase();
|
|
@@ -281987,12 +282201,7 @@ function registerVideoExtendCommand(parent) {
|
|
|
281987
282201
|
const spinner2 = ora("Initializing Veo...").start();
|
|
281988
282202
|
const gemini = new GeminiProvider();
|
|
281989
282203
|
await gemini.initialize({ apiKey });
|
|
281990
|
-
const
|
|
281991
|
-
"3.0": "veo-3.0-generate-preview",
|
|
281992
|
-
"3.1": "veo-3.1-generate-preview",
|
|
281993
|
-
"3.1-fast": "veo-3.1-fast-generate-preview"
|
|
281994
|
-
};
|
|
281995
|
-
const veoModel = veoModelMap[options.veoModel] || "veo-3.1-generate-preview";
|
|
282204
|
+
const veoModel = resolveVeoModel(options.veoModel);
|
|
281996
282205
|
spinner2.text = "Starting video extension...";
|
|
281997
282206
|
const result = await gemini.extendVideo(id, options.prompt, {
|
|
281998
282207
|
duration: parseInt(options.duration),
|
|
@@ -282153,10 +282362,15 @@ var init_provider_resolver = __esm({
|
|
|
282153
282362
|
|
|
282154
282363
|
// ../cli/src/commands/_shared/openai-image.ts
|
|
282155
282364
|
function resolveOpenAIImageModel(modelAlias) {
|
|
282156
|
-
const
|
|
282365
|
+
const alias = modelAlias?.trim() ?? "";
|
|
282366
|
+
for (const [id, model] of Object.entries(OPENAI_IMAGE_MODELS)) {
|
|
282367
|
+
if (alias === id || model.aliases.includes(alias)) {
|
|
282368
|
+
return { openaiModel: id, modelLabel: model.label };
|
|
282369
|
+
}
|
|
282370
|
+
}
|
|
282157
282371
|
return {
|
|
282158
|
-
openaiModel:
|
|
282159
|
-
modelLabel:
|
|
282372
|
+
openaiModel: OPENAI_IMAGE_DEFAULT_MODEL,
|
|
282373
|
+
modelLabel: OPENAI_IMAGE_MODELS[OPENAI_IMAGE_DEFAULT_MODEL].label
|
|
282160
282374
|
};
|
|
282161
282375
|
}
|
|
282162
282376
|
async function executeOpenAIImageGenerate(prompt3, options, ctx) {
|
|
@@ -282172,17 +282386,24 @@ async function executeOpenAIImageGenerate(prompt3, options, ctx) {
|
|
|
282172
282386
|
});
|
|
282173
282387
|
return { result, openaiModel, modelLabel };
|
|
282174
282388
|
}
|
|
282389
|
+
var OPENAI_IMAGE_MODELS;
|
|
282175
282390
|
var init_openai_image2 = __esm({
|
|
282176
282391
|
"../cli/src/commands/_shared/openai-image.ts"() {
|
|
282177
282392
|
"use strict";
|
|
282178
282393
|
init_dist();
|
|
282394
|
+
OPENAI_IMAGE_MODELS = {
|
|
282395
|
+
"gpt-image-2.5-sunburst": { label: "GPT Image 2.5 Sunburst", aliases: ["2.5", "sunburst"] },
|
|
282396
|
+
"gpt-image-2.5-flare": { label: "GPT Image 2.5 Flare", aliases: ["flare", "2.5-flare"] },
|
|
282397
|
+
"gpt-image-2": { label: "GPT Image 2", aliases: ["2"] },
|
|
282398
|
+
"gpt-image-1.5": { label: "GPT Image 1.5", aliases: ["1.5"] }
|
|
282399
|
+
};
|
|
282179
282400
|
}
|
|
282180
282401
|
});
|
|
282181
282402
|
|
|
282182
282403
|
// ../cli/src/commands/generate/image.ts
|
|
282183
282404
|
import { resolve as resolve66, dirname as dirname39 } from "node:path";
|
|
282184
282405
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
282185
|
-
import {
|
|
282406
|
+
import { mkdir as mkdir28 } from "node:fs/promises";
|
|
282186
282407
|
function registerImageCommand(parent) {
|
|
282187
282408
|
parent.command("image").alias("img").description("Generate image using AI (Gemini, OpenAI gpt-image, Grok, or Runway)").argument("[prompt]", "Image description prompt (interactive if omitted)").option(
|
|
282188
282409
|
"-p, --provider <provider>",
|
|
@@ -282193,7 +282414,7 @@ function registerImageCommand(parent) {
|
|
|
282193
282414
|
"1:1"
|
|
282194
282415
|
).option("--quality <quality>", "Quality: standard, hd (openai only)", "standard").option("--style <style>", "Style: vivid, natural (openai only)", "vivid").option("--count <n>", "Number of images to generate", "1").option(
|
|
282195
282416
|
"-m, --model <model>",
|
|
282196
|
-
"Model. Gemini: flash
|
|
282417
|
+
"Model. Gemini: flash (default), lite, pro. OpenAI: 2.5 (default), flare, 2, 1.5. Grok: pro"
|
|
282197
282418
|
).option("--dry-run", "Preview parameters without executing").addHelpText(
|
|
282198
282419
|
"after",
|
|
282199
282420
|
`
|
|
@@ -282296,7 +282517,7 @@ Examples:
|
|
|
282296
282517
|
const apiKey = await requireApiKey(envKey, providerName, options.apiKey);
|
|
282297
282518
|
const spinner2 = ora(`Generating image with ${providerName}...`).start();
|
|
282298
282519
|
if (provider === "openai") {
|
|
282299
|
-
const { result, modelLabel } = await executeOpenAIImageGenerate(prompt3, options, {
|
|
282520
|
+
const { result, modelLabel, openaiModel } = await executeOpenAIImageGenerate(prompt3, options, {
|
|
282300
282521
|
apiKey
|
|
282301
282522
|
});
|
|
282302
282523
|
if (!result.success || !result.images) {
|
|
@@ -282319,14 +282540,16 @@ Examples:
|
|
|
282319
282540
|
} else {
|
|
282320
282541
|
throw new Error("No image data available");
|
|
282321
282542
|
}
|
|
282322
|
-
await
|
|
282323
|
-
await
|
|
282543
|
+
await mkdir28(dirname39(outputPath), { recursive: true });
|
|
282544
|
+
await writeImageFile(outputPath, buffer);
|
|
282324
282545
|
}
|
|
282325
282546
|
outputSuccess({
|
|
282326
282547
|
command: "generate image",
|
|
282327
282548
|
startedAt,
|
|
282328
282549
|
data: {
|
|
282329
282550
|
provider: "openai",
|
|
282551
|
+
model: modelLabel,
|
|
282552
|
+
modelId: openaiModel,
|
|
282330
282553
|
images: result.images.map((img) => ({
|
|
282331
282554
|
url: img.url,
|
|
282332
282555
|
revisedPrompt: img.revisedPrompt
|
|
@@ -282366,8 +282589,8 @@ Examples:
|
|
|
282366
282589
|
throw new Error("No image data available");
|
|
282367
282590
|
}
|
|
282368
282591
|
const outputPath = resolve66(process.cwd(), options.output);
|
|
282369
|
-
await
|
|
282370
|
-
await
|
|
282592
|
+
await mkdir28(dirname39(outputPath), { recursive: true });
|
|
282593
|
+
await writeImageFile(outputPath, buffer);
|
|
282371
282594
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
282372
282595
|
} catch (err) {
|
|
282373
282596
|
saveSpinner.fail(
|
|
@@ -282376,7 +282599,7 @@ Examples:
|
|
|
282376
282599
|
}
|
|
282377
282600
|
}
|
|
282378
282601
|
} else if (provider === "gemini") {
|
|
282379
|
-
const validGeminiModels = ["flash", "3.1-flash", "latest", "pro"];
|
|
282602
|
+
const validGeminiModels = ["flash", "3.1-flash", "latest", "lite", "pro"];
|
|
282380
282603
|
if (options.model && !validGeminiModels.includes(options.model)) {
|
|
282381
282604
|
console.warn(
|
|
282382
282605
|
source_default.yellow(
|
|
@@ -282409,26 +282632,17 @@ Examples:
|
|
|
282409
282632
|
const gemini = new GeminiProvider();
|
|
282410
282633
|
await gemini.initialize({ apiKey });
|
|
282411
282634
|
const geminiModelNames = {
|
|
282412
|
-
flash: "Nano Banana",
|
|
282635
|
+
flash: "Nano Banana 2",
|
|
282413
282636
|
"3.1-flash": "Nano Banana 2",
|
|
282414
282637
|
latest: "Nano Banana 2",
|
|
282638
|
+
lite: "Nano Banana 2 Lite",
|
|
282415
282639
|
pro: "Nano Banana Pro"
|
|
282416
282640
|
};
|
|
282417
|
-
const
|
|
282418
|
-
|
|
282641
|
+
const usedLabel = geminiModelNames[options.model] || "Nano Banana 2";
|
|
282642
|
+
const result = await gemini.generateImage(prompt3, {
|
|
282419
282643
|
model: options.model,
|
|
282420
282644
|
aspectRatio: options.ratio
|
|
282421
282645
|
});
|
|
282422
|
-
let usedLabel = modelLabel;
|
|
282423
|
-
const fallbackModels = ["latest", "3.1-flash"];
|
|
282424
|
-
if (!result.success && options.model && fallbackModels.includes(options.model)) {
|
|
282425
|
-
spinner2.text = `${source_default.dim(result.error || "Failed")} \u2014 retrying with Nano Banana (flash)...`;
|
|
282426
|
-
result = await gemini.generateImage(prompt3, {
|
|
282427
|
-
model: "flash",
|
|
282428
|
-
aspectRatio: options.ratio
|
|
282429
|
-
});
|
|
282430
|
-
usedLabel = "Nano Banana (fallback)";
|
|
282431
|
-
}
|
|
282432
282646
|
if (!result.success || !result.images) {
|
|
282433
282647
|
spinner2.fail(result.error || "Image generation failed");
|
|
282434
282648
|
exitWithError(apiError(result.error || "Image generation failed", true));
|
|
@@ -282441,16 +282655,17 @@ Examples:
|
|
|
282441
282655
|
if (outputPath && result.images.length > 0) {
|
|
282442
282656
|
const img = result.images[0];
|
|
282443
282657
|
const buffer = Buffer.from(img.base64, "base64");
|
|
282444
|
-
await
|
|
282445
|
-
await
|
|
282658
|
+
await mkdir28(dirname39(outputPath), { recursive: true });
|
|
282659
|
+
await writeImageFile(outputPath, buffer);
|
|
282446
282660
|
}
|
|
282447
282661
|
outputSuccess({
|
|
282448
282662
|
command: "generate image",
|
|
282449
282663
|
startedAt,
|
|
282450
|
-
warnings:
|
|
282664
|
+
warnings: [],
|
|
282451
282665
|
data: {
|
|
282452
282666
|
provider: "gemini",
|
|
282453
282667
|
model: usedLabel,
|
|
282668
|
+
modelId: result.model,
|
|
282454
282669
|
images: result.images.map((img) => ({
|
|
282455
282670
|
mimeType: img.mimeType
|
|
282456
282671
|
})),
|
|
@@ -282474,8 +282689,8 @@ Examples:
|
|
|
282474
282689
|
const img = result.images[0];
|
|
282475
282690
|
const buffer = Buffer.from(img.base64, "base64");
|
|
282476
282691
|
const outputPath = resolve66(process.cwd(), options.output);
|
|
282477
|
-
await
|
|
282478
|
-
await
|
|
282692
|
+
await mkdir28(dirname39(outputPath), { recursive: true });
|
|
282693
|
+
await writeImageFile(outputPath, buffer);
|
|
282479
282694
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
282480
282695
|
} catch (err) {
|
|
282481
282696
|
saveSpinner.fail(
|
|
@@ -282513,6 +282728,7 @@ Examples:
|
|
|
282513
282728
|
options.ratio = "1:1";
|
|
282514
282729
|
}
|
|
282515
282730
|
const result = await grok.generateImage(prompt3, {
|
|
282731
|
+
...resolveGrokImageModel(options.model),
|
|
282516
282732
|
aspectRatio: options.ratio || "1:1",
|
|
282517
282733
|
n: parseInt(options.count)
|
|
282518
282734
|
});
|
|
@@ -282534,14 +282750,15 @@ Examples:
|
|
|
282534
282750
|
} else {
|
|
282535
282751
|
throw new Error("No image data available");
|
|
282536
282752
|
}
|
|
282537
|
-
await
|
|
282538
|
-
await
|
|
282753
|
+
await mkdir28(dirname39(outputPath), { recursive: true });
|
|
282754
|
+
await writeImageFile(outputPath, buffer);
|
|
282539
282755
|
}
|
|
282540
282756
|
outputSuccess({
|
|
282541
282757
|
command: "generate image",
|
|
282542
282758
|
startedAt,
|
|
282543
282759
|
data: {
|
|
282544
282760
|
provider: "grok",
|
|
282761
|
+
modelId: resolveGrokImageModel(options.model).model,
|
|
282545
282762
|
images: result.images.map((img) => ({ url: img.url })),
|
|
282546
282763
|
outputPath
|
|
282547
282764
|
}
|
|
@@ -282575,8 +282792,8 @@ Examples:
|
|
|
282575
282792
|
throw new Error("No image data available");
|
|
282576
282793
|
}
|
|
282577
282794
|
const outputPath = resolve66(process.cwd(), options.output);
|
|
282578
|
-
await
|
|
282579
|
-
await
|
|
282795
|
+
await mkdir28(dirname39(outputPath), { recursive: true });
|
|
282796
|
+
await writeImageFile(outputPath, buffer);
|
|
282580
282797
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
282581
282798
|
} catch (err) {
|
|
282582
282799
|
saveSpinner.fail(
|
|
@@ -282658,6 +282875,7 @@ var init_image2 = __esm({
|
|
|
282658
282875
|
init_validate();
|
|
282659
282876
|
init_provider_resolver();
|
|
282660
282877
|
init_openai_image2();
|
|
282878
|
+
init_image_file();
|
|
282661
282879
|
}
|
|
282662
282880
|
});
|
|
282663
282881
|
|
|
@@ -283606,11 +283824,11 @@ var init_dist5 = __esm({
|
|
|
283606
283824
|
|
|
283607
283825
|
// ../cli/src/commands/generate/video.ts
|
|
283608
283826
|
import { resolve as resolve67 } from "node:path";
|
|
283609
|
-
import { readFile as readFile36, writeFile as
|
|
283827
|
+
import { readFile as readFile36, writeFile as writeFile39 } from "node:fs/promises";
|
|
283610
283828
|
function registerVideoCommand(parent) {
|
|
283611
283829
|
parent.command("video").alias("vid").description("Generate video using AI (Seedance, Grok, Kling, Runway, Veo, or Gemini Omni)").argument("[prompt]", "Text prompt describing the video (interactive if omitted)").option(
|
|
283612
283830
|
"-p, --provider <provider>",
|
|
283613
|
-
"Provider: seedance (ByteDance Seedance 2.0 via fal.ai), grok, kling, runway,
|
|
283831
|
+
"Provider: seedance (ByteDance Seedance 2.0 via fal.ai), grok, kling, runway, omni (Gemini Omni 1.1 Flash; Google default), veo (Veo 3.1 preview, shuts down 2026-10-22). `fal` is a deprecated v0.x alias for seedance and will be removed in 1.0."
|
|
283614
283832
|
).option(
|
|
283615
283833
|
"-k, --api-key <key>",
|
|
283616
283834
|
"API key (or set FAL_API_KEY / XAI_API_KEY / RUNWAY_API_SECRET / KLING_API_KEY / GOOGLE_API_KEY env)"
|
|
@@ -283623,12 +283841,12 @@ function registerVideoCommand(parent) {
|
|
|
283623
283841
|
"Aspect ratio: 16:9, 9:16, or 1:1 (auto-detected from image if omitted)"
|
|
283624
283842
|
).option("--seed <number>", "Random seed for reproducibility (Runway only)").option("--mode <mode>", "Generation mode: std or pro (Kling only)", "std").option(
|
|
283625
283843
|
"--seedance-model <model>",
|
|
283626
|
-
"Seedance variant: quality
|
|
283844
|
+
"Seedance variant: quality (2.0), fast, or 2.5 (fal.ai only)",
|
|
283627
283845
|
"quality"
|
|
283628
|
-
).option("--negative <prompt>", "Negative prompt - what to avoid (Kling/Veo)").option("--resolution <res>", "Video resolution: 480p, 720p, 1080p, or 4k depending on provider").option("--last-frame <path>", "Last frame image for frame interpolation (Veo) or Seedance end frame").option("--end-image <path>", "Ending frame image for Seedance image-to-video").option(
|
|
283846
|
+
).option("--grok-model <model>", "Grok video model: 1.5 (default), lite, classic", "1.5").option("--kling-model <model>", "Kling model: v3 (default), v2.6, v2.5-turbo", "v3").option("--negative <prompt>", "Negative prompt - what to avoid (Kling/Veo)").option("--resolution <res>", "Video resolution: 480p, 720p, 1080p, or 4k depending on provider").option("--last-frame <path>", "Last frame image for frame interpolation (Veo) or Seedance end frame").option("--end-image <path>", "Ending frame image for Seedance image-to-video").option(
|
|
283629
283847
|
"--ref-images <paths...>",
|
|
283630
283848
|
"Reference images for Seedance reference-to-video or Veo character consistency"
|
|
283631
|
-
).option("--ref-videos <paths...>", "Reference videos for Seedance reference-to-video").option("--ref-audio <paths...>", "Reference audio for Seedance reference-to-video").option("--no-generate-audio", "Disable native audio when the provider supports it").option("--person <mode>", "Person generation: allow_all, allow_adult (Veo only)").option("--veo-model <model>", "Veo model: 3.
|
|
283849
|
+
).option("--ref-videos <paths...>", "Reference videos for Seedance reference-to-video").option("--ref-audio <paths...>", "Reference audio for Seedance reference-to-video").option("--no-generate-audio", "Disable native audio when the provider supports it").option("--person <mode>", "Person generation: allow_all, allow_adult (Veo only)").option("--veo-model <model>", "Veo model: 3.1, 3.1-fast (default: 3.1-fast)", "3.1-fast").option(
|
|
283632
283850
|
"--runway-model <model>",
|
|
283633
283851
|
"Runway model: gen4.5 (default, text+image-to-video), gen4_turbo (image-to-video only)",
|
|
283634
283852
|
"gen4.5"
|
|
@@ -283689,7 +283907,7 @@ Examples:
|
|
|
283689
283907
|
exitWithError(
|
|
283690
283908
|
usageError(
|
|
283691
283909
|
`Invalid provider: ${provider}`,
|
|
283692
|
-
"Available providers: seedance, grok, kling, runway,
|
|
283910
|
+
"Available providers: seedance, grok, kling, runway, omni, veo. `fal` is a deprecated alias for seedance."
|
|
283693
283911
|
)
|
|
283694
283912
|
);
|
|
283695
283913
|
}
|
|
@@ -283757,13 +283975,7 @@ Examples:
|
|
|
283757
283975
|
options.ratio = "16:9";
|
|
283758
283976
|
}
|
|
283759
283977
|
if (options.dryRun) {
|
|
283760
|
-
const costUsd = provider === "seedance" || provider === "fal" ?
|
|
283761
|
-
durationSec: Number(options.duration) || 5,
|
|
283762
|
-
resolution: options.resolution,
|
|
283763
|
-
aspectRatio: options.ratio,
|
|
283764
|
-
fast: options.seedanceModel === "fast",
|
|
283765
|
-
hasVideoReference: Boolean(options.refVideos)
|
|
283766
|
-
}) : void 0;
|
|
283978
|
+
const costUsd = provider === "seedance" || provider === "fal" ? realRunCost(provider, options).costUsd : void 0;
|
|
283767
283979
|
outputSuccess({
|
|
283768
283980
|
command: "generate video",
|
|
283769
283981
|
startedAt,
|
|
@@ -283781,6 +283993,8 @@ Examples:
|
|
|
283781
283993
|
resolution: options.resolution,
|
|
283782
283994
|
veoModel: options.veoModel,
|
|
283783
283995
|
seedanceModel: options.seedanceModel,
|
|
283996
|
+
grokModel: options.grokModel,
|
|
283997
|
+
klingModel: options.klingModel,
|
|
283784
283998
|
refImages: options.refImages,
|
|
283785
283999
|
refVideos: options.refVideos,
|
|
283786
284000
|
refAudio: options.refAudio,
|
|
@@ -283802,7 +284016,7 @@ Examples:
|
|
|
283802
284016
|
runway: "Runway",
|
|
283803
284017
|
kling: "Kling",
|
|
283804
284018
|
veo: "Veo",
|
|
283805
|
-
omni: "Gemini Omni
|
|
284019
|
+
omni: "Gemini Omni 1.1 Flash",
|
|
283806
284020
|
grok: "Grok",
|
|
283807
284021
|
seedance: "Seedance 2.0 via fal.ai"
|
|
283808
284022
|
};
|
|
@@ -283901,6 +284115,7 @@ Examples:
|
|
|
283901
284115
|
}
|
|
283902
284116
|
result = await kling.generateVideo(prompt3, {
|
|
283903
284117
|
prompt: prompt3,
|
|
284118
|
+
model: resolveKlingModel(options.klingModel),
|
|
283904
284119
|
referenceImage: klingImage,
|
|
283905
284120
|
duration: parseInt(options.duration),
|
|
283906
284121
|
aspectRatio: options.ratio,
|
|
@@ -283950,12 +284165,7 @@ Examples:
|
|
|
283950
284165
|
} else if (provider === "veo") {
|
|
283951
284166
|
const gemini = new GeminiProvider();
|
|
283952
284167
|
await gemini.initialize({ apiKey });
|
|
283953
|
-
const
|
|
283954
|
-
"3.0": "veo-3.0-generate-preview",
|
|
283955
|
-
"3.1": "veo-3.1-generate-preview",
|
|
283956
|
-
"3.1-fast": "veo-3.1-fast-generate-preview"
|
|
283957
|
-
};
|
|
283958
|
-
const veoModel = veoModelMap[options.veoModel] || "veo-3.1-fast-generate-preview";
|
|
284168
|
+
const veoModel = resolveVeoModel(options.veoModel);
|
|
283959
284169
|
const veoDuration = parseInt(options.duration) <= 6 ? 6 : 8;
|
|
283960
284170
|
let lastFrame;
|
|
283961
284171
|
if (options.lastFrame) {
|
|
@@ -284029,9 +284239,12 @@ Examples:
|
|
|
284029
284239
|
await grok.initialize({ apiKey });
|
|
284030
284240
|
result = await grok.generateVideo(prompt3, {
|
|
284031
284241
|
prompt: prompt3,
|
|
284242
|
+
model: resolveGrokVideoModel(options.grokModel),
|
|
284032
284243
|
referenceImage,
|
|
284033
284244
|
duration: parseInt(options.duration),
|
|
284034
|
-
aspectRatio: options.ratio
|
|
284245
|
+
aspectRatio: options.ratio,
|
|
284246
|
+
resolution: options.resolution,
|
|
284247
|
+
generateAudio: options.generateAudio
|
|
284035
284248
|
});
|
|
284036
284249
|
if (result.status === "failed") {
|
|
284037
284250
|
spinner2.fail(result.error || "Failed to start generation");
|
|
@@ -284121,9 +284334,8 @@ Examples:
|
|
|
284121
284334
|
exitWithError(apiError(message, true));
|
|
284122
284335
|
}
|
|
284123
284336
|
}
|
|
284124
|
-
|
|
284125
|
-
|
|
284126
|
-
const falModel = seedanceModel === "fast" || seedanceModel === "seedance-2.0-fast" ? "seedance-2.0-fast" : "seedance-2.0";
|
|
284337
|
+
const falModel = resolveSeedanceVariant(options.seedanceModel);
|
|
284338
|
+
spinner2.text = `Generating video with fal.ai ${falModel} (this may take 1-3 minutes)...`;
|
|
284127
284339
|
result = await fal.generateVideo(prompt3, {
|
|
284128
284340
|
prompt: prompt3,
|
|
284129
284341
|
referenceImage: seedanceReferences.length > 0 ? void 0 : falImage,
|
|
@@ -284140,11 +284352,20 @@ Examples:
|
|
|
284140
284352
|
} else if (provider === "omni") {
|
|
284141
284353
|
const omni = new OmniProvider();
|
|
284142
284354
|
await omni.initialize({ apiKey });
|
|
284143
|
-
spinner2.text = "Generating video with Gemini Omni
|
|
284355
|
+
spinner2.text = "Generating video with Gemini Omni 1.1 Flash...";
|
|
284356
|
+
let lastFrame;
|
|
284357
|
+
if (options.lastFrame) {
|
|
284358
|
+
const lastFramePath = resolve67(process.cwd(), options.lastFrame);
|
|
284359
|
+
const ext = options.lastFrame.toLowerCase().split(".").pop();
|
|
284360
|
+
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
284361
|
+
lastFrame = `data:${mimeType};base64,${(await readFile36(lastFramePath)).toString("base64")}`;
|
|
284362
|
+
}
|
|
284144
284363
|
result = await omni.generateVideo(prompt3, {
|
|
284145
284364
|
prompt: prompt3,
|
|
284146
284365
|
referenceImage,
|
|
284147
|
-
|
|
284366
|
+
lastFrame,
|
|
284367
|
+
aspectRatio: options.ratio,
|
|
284368
|
+
resolution: options.resolution
|
|
284148
284369
|
});
|
|
284149
284370
|
finalResult = result;
|
|
284150
284371
|
}
|
|
@@ -284158,14 +284379,14 @@ Examples:
|
|
|
284158
284379
|
if (options.output && finalResult.videoUrl) {
|
|
284159
284380
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
284160
284381
|
outputPath = resolve67(process.cwd(), options.output);
|
|
284161
|
-
await
|
|
284382
|
+
await writeFile39(outputPath, buffer);
|
|
284162
284383
|
}
|
|
284163
284384
|
const cost = realRunCost(provider, options);
|
|
284164
284385
|
outputSuccess({
|
|
284165
284386
|
command: "generate video",
|
|
284166
284387
|
startedAt,
|
|
284167
284388
|
costUsd: cost.costUsd,
|
|
284168
|
-
warnings: cost.warnings,
|
|
284389
|
+
warnings: provider === "veo" ? [VEO_SHUTDOWN_WARNING, ...cost.warnings] : cost.warnings,
|
|
284169
284390
|
data: {
|
|
284170
284391
|
provider,
|
|
284171
284392
|
taskId: result?.id,
|
|
@@ -284177,6 +284398,9 @@ Examples:
|
|
|
284177
284398
|
return;
|
|
284178
284399
|
}
|
|
284179
284400
|
console.log();
|
|
284401
|
+
if (provider === "veo") {
|
|
284402
|
+
console.log(source_default.yellow(VEO_SHUTDOWN_WARNING));
|
|
284403
|
+
}
|
|
284180
284404
|
if (finalResult.videoUrl) {
|
|
284181
284405
|
console.log(`Video URL: ${finalResult.videoUrl}`);
|
|
284182
284406
|
}
|
|
@@ -284189,7 +284413,7 @@ Examples:
|
|
|
284189
284413
|
try {
|
|
284190
284414
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
284191
284415
|
const outputPath = resolve67(process.cwd(), options.output);
|
|
284192
|
-
await
|
|
284416
|
+
await writeFile39(outputPath, buffer);
|
|
284193
284417
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
284194
284418
|
} catch (err) {
|
|
284195
284419
|
downloadSpinner.fail(
|
|
@@ -284204,12 +284428,14 @@ Examples:
|
|
|
284204
284428
|
}
|
|
284205
284429
|
function realRunCost(provider, options) {
|
|
284206
284430
|
if (provider === "seedance" || provider === "fal") {
|
|
284431
|
+
const variant = resolveSeedanceVariant(options.seedanceModel);
|
|
284207
284432
|
return {
|
|
284208
284433
|
costUsd: estimateSeedanceVideoCostUsd({
|
|
284209
284434
|
durationSec: Number(options.duration) || 5,
|
|
284210
284435
|
resolution: options.resolution,
|
|
284211
284436
|
aspectRatio: options.ratio,
|
|
284212
|
-
fast:
|
|
284437
|
+
fast: variant === "seedance-2.0-fast",
|
|
284438
|
+
v25: variant === "seedance-2.5",
|
|
284213
284439
|
hasVideoReference: Boolean(options.refVideos)
|
|
284214
284440
|
}),
|
|
284215
284441
|
warnings: []
|
|
@@ -284299,6 +284525,7 @@ function printVideoStarted(providerLabel, taskId, taskType) {
|
|
|
284299
284525
|
console.log(`Task ID: ${source_default.bold(taskId)}`);
|
|
284300
284526
|
if (taskType) console.log(`Type: ${taskType}`);
|
|
284301
284527
|
}
|
|
284528
|
+
var VEO_SHUTDOWN_WARNING;
|
|
284302
284529
|
var init_video = __esm({
|
|
284303
284530
|
"../cli/src/commands/generate/video.ts"() {
|
|
284304
284531
|
"use strict";
|
|
@@ -284314,6 +284541,7 @@ var init_video = __esm({
|
|
|
284314
284541
|
init_upload_host();
|
|
284315
284542
|
init_ai_helpers();
|
|
284316
284543
|
init_status_jobs();
|
|
284544
|
+
VEO_SHUTDOWN_WARNING = "Veo 3.1 preview models shut down on 2026-10-22. Use `-p omni` (Gemini Omni 1.1 Flash) instead.";
|
|
284317
284545
|
}
|
|
284318
284546
|
});
|
|
284319
284547
|
|
|
@@ -284333,7 +284561,7 @@ var init_sanitize = __esm({
|
|
|
284333
284561
|
|
|
284334
284562
|
// ../cli/src/commands/generate/storyboard.ts
|
|
284335
284563
|
import { resolve as resolve68 } from "node:path";
|
|
284336
|
-
import { writeFile as
|
|
284564
|
+
import { writeFile as writeFile40 } from "node:fs/promises";
|
|
284337
284565
|
async function executeStoryboard(options) {
|
|
284338
284566
|
const { content, duration, creativity = "low", output: output3, apiKey } = options;
|
|
284339
284567
|
try {
|
|
@@ -284352,7 +284580,7 @@ async function executeStoryboard(options) {
|
|
|
284352
284580
|
let outputPath;
|
|
284353
284581
|
if (output3) {
|
|
284354
284582
|
outputPath = resolve68(process.cwd(), output3);
|
|
284355
|
-
await
|
|
284583
|
+
await writeFile40(outputPath, JSON.stringify(segments, null, 2), "utf-8");
|
|
284356
284584
|
}
|
|
284357
284585
|
return { success: true, segments, segmentCount: segments.length, outputPath };
|
|
284358
284586
|
} catch (error) {
|
|
@@ -298150,7 +298378,7 @@ var init_openai3 = __esm({
|
|
|
298150
298378
|
OpenAIAdapter = class {
|
|
298151
298379
|
provider = "openai";
|
|
298152
298380
|
client = null;
|
|
298153
|
-
model = "gpt-5-mini";
|
|
298381
|
+
model = "gpt-5.4-mini";
|
|
298154
298382
|
async initialize(apiKey) {
|
|
298155
298383
|
this.client = new openai_default({ apiKey });
|
|
298156
298384
|
}
|
|
@@ -301699,7 +301927,7 @@ var init_claude2 = __esm({
|
|
|
301699
301927
|
ClaudeAdapter = class {
|
|
301700
301928
|
provider = "claude";
|
|
301701
301929
|
client = null;
|
|
301702
|
-
model = "claude-sonnet-
|
|
301930
|
+
model = "claude-sonnet-5-5";
|
|
301703
301931
|
async initialize(apiKey) {
|
|
301704
301932
|
this.client = new sdk_default({ apiKey });
|
|
301705
301933
|
}
|
|
@@ -301724,6 +301952,13 @@ var init_claude2 = __esm({
|
|
|
301724
301952
|
content: msg.content
|
|
301725
301953
|
});
|
|
301726
301954
|
} else if (msg.role === "assistant") {
|
|
301955
|
+
if (msg.providerContent) {
|
|
301956
|
+
claudeMessages.push({
|
|
301957
|
+
role: "assistant",
|
|
301958
|
+
content: msg.providerContent
|
|
301959
|
+
});
|
|
301960
|
+
continue;
|
|
301961
|
+
}
|
|
301727
301962
|
const content = [];
|
|
301728
301963
|
if (msg.content) {
|
|
301729
301964
|
content.push({ type: "text", text: msg.content });
|
|
@@ -301745,16 +301980,17 @@ var init_claude2 = __esm({
|
|
|
301745
301980
|
});
|
|
301746
301981
|
}
|
|
301747
301982
|
} else if (msg.role === "tool") {
|
|
301748
|
-
|
|
301749
|
-
|
|
301750
|
-
|
|
301751
|
-
|
|
301752
|
-
|
|
301753
|
-
|
|
301754
|
-
|
|
301755
|
-
|
|
301756
|
-
|
|
301757
|
-
|
|
301983
|
+
const result = {
|
|
301984
|
+
type: "tool_result",
|
|
301985
|
+
tool_use_id: msg.toolCallId,
|
|
301986
|
+
content: msg.content
|
|
301987
|
+
};
|
|
301988
|
+
const last3 = claudeMessages.at(-1);
|
|
301989
|
+
if (last3?.role === "user" && Array.isArray(last3.content)) {
|
|
301990
|
+
last3.content.push(result);
|
|
301991
|
+
} else {
|
|
301992
|
+
claudeMessages.push({ role: "user", content: [result] });
|
|
301993
|
+
}
|
|
301758
301994
|
}
|
|
301759
301995
|
}
|
|
301760
301996
|
const claudeTools = tools2.map((tool) => ({
|
|
@@ -301768,7 +302004,8 @@ var init_claude2 = __esm({
|
|
|
301768
302004
|
}));
|
|
301769
302005
|
const response = await this.client.messages.create({
|
|
301770
302006
|
model: this.model,
|
|
301771
|
-
|
|
302007
|
+
// Thinking tokens count against this cap on Claude 5.x.
|
|
302008
|
+
max_tokens: 16e3,
|
|
301772
302009
|
system: systemPrompt,
|
|
301773
302010
|
messages: claudeMessages,
|
|
301774
302011
|
tools: claudeTools.length > 0 ? claudeTools : void 0
|
|
@@ -301795,7 +302032,8 @@ var init_claude2 = __esm({
|
|
|
301795
302032
|
return {
|
|
301796
302033
|
content: textContent2,
|
|
301797
302034
|
toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
301798
|
-
finishReason
|
|
302035
|
+
finishReason,
|
|
302036
|
+
providerContent: response.content
|
|
301799
302037
|
};
|
|
301800
302038
|
}
|
|
301801
302039
|
};
|
|
@@ -302760,17 +302998,51 @@ var init_dist6 = __esm({
|
|
|
302760
302998
|
// ../cli/src/agent/adapters/gemini.ts
|
|
302761
302999
|
var gemini_exports = {};
|
|
302762
303000
|
__export(gemini_exports, {
|
|
302763
|
-
GeminiAdapter: () => GeminiAdapter
|
|
303001
|
+
GeminiAdapter: () => GeminiAdapter,
|
|
303002
|
+
toGeminiSchema: () => toGeminiSchema
|
|
302764
303003
|
});
|
|
302765
|
-
|
|
303004
|
+
function toGeminiSchema(schema) {
|
|
303005
|
+
if (Array.isArray(schema)) return schema.map(toGeminiSchema);
|
|
303006
|
+
if (!schema || typeof schema !== "object") return schema;
|
|
303007
|
+
const out = {};
|
|
303008
|
+
for (const [key2, value] of Object.entries(schema)) {
|
|
303009
|
+
if (!GEMINI_SCHEMA_KEYS.has(key2)) continue;
|
|
303010
|
+
if (key2 === "properties" && value && typeof value === "object") {
|
|
303011
|
+
out.properties = Object.fromEntries(
|
|
303012
|
+
Object.entries(value).map(([name, prop2]) => [name, toGeminiSchema(prop2)])
|
|
303013
|
+
);
|
|
303014
|
+
} else if (key2 === "items") {
|
|
303015
|
+
out.items = toGeminiSchema(value);
|
|
303016
|
+
} else {
|
|
303017
|
+
out[key2] = value;
|
|
303018
|
+
}
|
|
303019
|
+
}
|
|
303020
|
+
return out;
|
|
303021
|
+
}
|
|
303022
|
+
var GEMINI_SCHEMA_KEYS, GeminiAdapter;
|
|
302766
303023
|
var init_gemini2 = __esm({
|
|
302767
303024
|
"../cli/src/agent/adapters/gemini.ts"() {
|
|
302768
303025
|
"use strict";
|
|
302769
303026
|
init_dist6();
|
|
303027
|
+
init_dist();
|
|
303028
|
+
GEMINI_SCHEMA_KEYS = /* @__PURE__ */ new Set([
|
|
303029
|
+
"type",
|
|
303030
|
+
"format",
|
|
303031
|
+
"description",
|
|
303032
|
+
"nullable",
|
|
303033
|
+
"enum",
|
|
303034
|
+
"items",
|
|
303035
|
+
"properties",
|
|
303036
|
+
"required",
|
|
303037
|
+
"minItems",
|
|
303038
|
+
"maxItems",
|
|
303039
|
+
"minimum",
|
|
303040
|
+
"maximum"
|
|
303041
|
+
]);
|
|
302770
303042
|
GeminiAdapter = class {
|
|
302771
303043
|
provider = "gemini";
|
|
302772
303044
|
client = null;
|
|
302773
|
-
model =
|
|
303045
|
+
model = GEMINI_AGENT_DEFAULT_TEXT_MODEL;
|
|
302774
303046
|
async initialize(apiKey) {
|
|
302775
303047
|
this.client = new GoogleGenerativeAI(apiKey);
|
|
302776
303048
|
}
|
|
@@ -302792,7 +303064,12 @@ var init_gemini2 = __esm({
|
|
|
302792
303064
|
description: tool.description,
|
|
302793
303065
|
parameters: {
|
|
302794
303066
|
type: SchemaType.OBJECT,
|
|
302795
|
-
properties:
|
|
303067
|
+
properties: Object.fromEntries(
|
|
303068
|
+
Object.entries(tool.parameters.properties).map(([name, prop2]) => [
|
|
303069
|
+
name,
|
|
303070
|
+
toGeminiSchema(prop2)
|
|
303071
|
+
])
|
|
303072
|
+
),
|
|
302796
303073
|
required: tool.parameters.required
|
|
302797
303074
|
}
|
|
302798
303075
|
}))
|
|
@@ -302811,6 +303088,10 @@ var init_gemini2 = __esm({
|
|
|
302811
303088
|
parts: [{ text: msg.content }]
|
|
302812
303089
|
});
|
|
302813
303090
|
} else if (msg.role === "assistant") {
|
|
303091
|
+
if (msg.providerContent) {
|
|
303092
|
+
geminiContents.push({ role: "model", parts: msg.providerContent });
|
|
303093
|
+
continue;
|
|
303094
|
+
}
|
|
302814
303095
|
const parts = [];
|
|
302815
303096
|
if (msg.content) {
|
|
302816
303097
|
parts.push({ text: msg.content });
|
|
@@ -302832,16 +303113,19 @@ var init_gemini2 = __esm({
|
|
|
302832
303113
|
});
|
|
302833
303114
|
}
|
|
302834
303115
|
} else if (msg.role === "tool") {
|
|
302835
|
-
|
|
302836
|
-
|
|
302837
|
-
|
|
302838
|
-
|
|
302839
|
-
|
|
302840
|
-
|
|
302841
|
-
|
|
302842
|
-
|
|
302843
|
-
|
|
302844
|
-
|
|
303116
|
+
const part = {
|
|
303117
|
+
functionResponse: {
|
|
303118
|
+
name: msg.toolCallId.split(":::")[0] || "unknown",
|
|
303119
|
+
// Extract function name from id
|
|
303120
|
+
response: { result: msg.content }
|
|
303121
|
+
}
|
|
303122
|
+
};
|
|
303123
|
+
const last3 = geminiContents.at(-1);
|
|
303124
|
+
if (last3?.role === "user" && last3.parts.every((p2) => "functionResponse" in p2)) {
|
|
303125
|
+
last3.parts.push(part);
|
|
303126
|
+
} else {
|
|
303127
|
+
geminiContents.push({ role: "user", parts: [part] });
|
|
303128
|
+
}
|
|
302845
303129
|
}
|
|
302846
303130
|
}
|
|
302847
303131
|
const result = await model.generateContent({
|
|
@@ -302878,7 +303162,8 @@ var init_gemini2 = __esm({
|
|
|
302878
303162
|
return {
|
|
302879
303163
|
content: textContent2,
|
|
302880
303164
|
toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
302881
|
-
finishReason
|
|
303165
|
+
finishReason,
|
|
303166
|
+
providerContent: candidate.content.parts
|
|
302882
303167
|
};
|
|
302883
303168
|
}
|
|
302884
303169
|
};
|
|
@@ -303081,7 +303366,7 @@ var init_xai = __esm({
|
|
|
303081
303366
|
XAIAdapter = class {
|
|
303082
303367
|
provider = "xai";
|
|
303083
303368
|
client = null;
|
|
303084
|
-
model = "grok-4
|
|
303369
|
+
model = "grok-4.3";
|
|
303085
303370
|
async initialize(apiKey) {
|
|
303086
303371
|
this.client = new openai_default({
|
|
303087
303372
|
apiKey,
|
|
@@ -303381,7 +303666,7 @@ __export(detect_exports, {
|
|
|
303381
303666
|
executeDetectScenes: () => executeDetectScenes,
|
|
303382
303667
|
executeDetectSilence: () => executeDetectSilence
|
|
303383
303668
|
});
|
|
303384
|
-
import { readFile as readFile41, writeFile as
|
|
303669
|
+
import { readFile as readFile41, writeFile as writeFile44 } from "node:fs/promises";
|
|
303385
303670
|
import { resolve as resolve74, basename as basename20 } from "node:path";
|
|
303386
303671
|
async function executeDetectScenes(options) {
|
|
303387
303672
|
try {
|
|
@@ -303420,7 +303705,7 @@ async function executeDetectScenes(options) {
|
|
|
303420
303705
|
}));
|
|
303421
303706
|
if (options.outputPath) {
|
|
303422
303707
|
const outputPath = resolve74(process.cwd(), options.outputPath);
|
|
303423
|
-
await
|
|
303708
|
+
await writeFile44(outputPath, JSON.stringify({ source: absPath, totalDuration, threshold, scenes: result }, null, 2), "utf-8");
|
|
303424
303709
|
}
|
|
303425
303710
|
return { success: true, scenes: result, totalDuration };
|
|
303426
303711
|
} catch (error) {
|
|
@@ -303467,7 +303752,7 @@ async function executeDetectSilence(options) {
|
|
|
303467
303752
|
}
|
|
303468
303753
|
if (options.outputPath) {
|
|
303469
303754
|
const outputPath = resolve74(process.cwd(), options.outputPath);
|
|
303470
|
-
await
|
|
303755
|
+
await writeFile44(outputPath, JSON.stringify({ source: absPath, silences }, null, 2), "utf-8");
|
|
303471
303756
|
}
|
|
303472
303757
|
return { success: true, silences };
|
|
303473
303758
|
} catch (error) {
|
|
@@ -303516,7 +303801,7 @@ async function executeDetectBeats(options) {
|
|
|
303516
303801
|
}
|
|
303517
303802
|
if (options.outputPath) {
|
|
303518
303803
|
const outputPath = resolve74(process.cwd(), options.outputPath);
|
|
303519
|
-
await
|
|
303804
|
+
await writeFile44(outputPath, JSON.stringify({ source: absPath, beatCount: beats.length, beats }, null, 2), "utf-8");
|
|
303520
303805
|
}
|
|
303521
303806
|
return { success: true, beats, beatCount: beats.length };
|
|
303522
303807
|
} catch (error) {
|
|
@@ -303620,7 +303905,7 @@ var init_detect = __esm({
|
|
|
303620
303905
|
duration: (i3 < scenes.length - 1 ? scenes[i3 + 1].timestamp : totalDuration) - s2.timestamp
|
|
303621
303906
|
}))
|
|
303622
303907
|
};
|
|
303623
|
-
await
|
|
303908
|
+
await writeFile44(outputPath, JSON.stringify(result, null, 2), "utf-8");
|
|
303624
303909
|
console.log(source_default.green(`Saved to: ${outputPath}`));
|
|
303625
303910
|
}
|
|
303626
303911
|
if (options.project) {
|
|
@@ -303650,7 +303935,7 @@ var init_detect = __esm({
|
|
|
303650
303935
|
sourceEndOffset: end
|
|
303651
303936
|
});
|
|
303652
303937
|
}
|
|
303653
|
-
await
|
|
303938
|
+
await writeFile44(projectPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
303654
303939
|
console.log(source_default.green(`Added ${scenes.length} clips to project`));
|
|
303655
303940
|
}
|
|
303656
303941
|
} catch (error) {
|
|
@@ -303732,7 +304017,7 @@ var init_detect = __esm({
|
|
|
303732
304017
|
console.log();
|
|
303733
304018
|
if (options.output) {
|
|
303734
304019
|
const outputPath = resolve74(process.cwd(), options.output);
|
|
303735
|
-
await
|
|
304020
|
+
await writeFile44(
|
|
303736
304021
|
outputPath,
|
|
303737
304022
|
JSON.stringify({ source: absPath, silences }, null, 2),
|
|
303738
304023
|
"utf-8"
|
|
@@ -303817,7 +304102,7 @@ var init_detect = __esm({
|
|
|
303817
304102
|
console.log();
|
|
303818
304103
|
if (options.output) {
|
|
303819
304104
|
const outputPath = resolve74(process.cwd(), options.output);
|
|
303820
|
-
await
|
|
304105
|
+
await writeFile44(
|
|
303821
304106
|
outputPath,
|
|
303822
304107
|
JSON.stringify({ source: absPath, beatCount: beats.length, beats }, null, 2),
|
|
303823
304108
|
"utf-8"
|
|
@@ -304411,7 +304696,7 @@ init_scene_project();
|
|
|
304411
304696
|
init_project_config();
|
|
304412
304697
|
init_cost_tier();
|
|
304413
304698
|
import { resolve as resolve29, relative as relative8, dirname as dirname24 } from "node:path";
|
|
304414
|
-
import { mkdir as
|
|
304699
|
+
import { mkdir as mkdir12, readFile as readFile14, writeFile as writeFile15, access as access4, copyFile as copyFile3 } from "node:fs/promises";
|
|
304415
304700
|
import { existsSync as existsSync46 } from "node:fs";
|
|
304416
304701
|
|
|
304417
304702
|
// ../cli/src/commands/_shared/scene-html-emit.ts
|
|
@@ -304891,7 +305176,7 @@ init_storyboard_parse();
|
|
|
304891
305176
|
init_storyboard_source();
|
|
304892
305177
|
init_root_sync();
|
|
304893
305178
|
import { existsSync as existsSync44 } from "node:fs";
|
|
304894
|
-
import { mkdir as
|
|
305179
|
+
import { mkdir as mkdir11, writeFile as writeFile13 } from "node:fs/promises";
|
|
304895
305180
|
import { join as join58, resolve as resolve26 } from "node:path";
|
|
304896
305181
|
async function executeSceneSubmit(opts) {
|
|
304897
305182
|
const projectDir = resolve26(opts.projectDir);
|
|
@@ -304985,7 +305270,7 @@ async function executeSceneSubmit(opts) {
|
|
|
304985
305270
|
return { ...base2, success: true };
|
|
304986
305271
|
}
|
|
304987
305272
|
const absPath = join58(projectDir, scenePath);
|
|
304988
|
-
await
|
|
305273
|
+
await mkdir11(join58(projectDir, "compositions"), { recursive: true });
|
|
304989
305274
|
await writeFile13(absPath, html.endsWith("\n") ? html : `${html}
|
|
304990
305275
|
`, "utf-8");
|
|
304991
305276
|
return {
|
|
@@ -305576,7 +305861,7 @@ async function executeSceneAdd(opts) {
|
|
|
305576
305861
|
}
|
|
305577
305862
|
audioRelPath = `assets/narration-${id}.${ext}`;
|
|
305578
305863
|
audioAbsPath = resolve29(projectDir, audioRelPath);
|
|
305579
|
-
await
|
|
305864
|
+
await mkdir12(dirname24(audioAbsPath), { recursive: true });
|
|
305580
305865
|
await copyFile3(sourceAbs, audioAbsPath);
|
|
305581
305866
|
try {
|
|
305582
305867
|
narrationDuration = await getAudioDuration(audioAbsPath);
|
|
@@ -305609,7 +305894,7 @@ async function executeSceneAdd(opts) {
|
|
|
305609
305894
|
}
|
|
305610
305895
|
audioRelPath = `assets/narration-${id}.${resolution.audioExtension}`;
|
|
305611
305896
|
audioAbsPath = resolve29(projectDir, audioRelPath);
|
|
305612
|
-
await
|
|
305897
|
+
await mkdir12(dirname24(audioAbsPath), { recursive: true });
|
|
305613
305898
|
await writeFile15(audioAbsPath, tts.audioBuffer);
|
|
305614
305899
|
try {
|
|
305615
305900
|
narrationDuration = await getAudioDuration(audioAbsPath);
|
|
@@ -305672,7 +305957,7 @@ async function executeSceneAdd(opts) {
|
|
|
305672
305957
|
const img = imageResult.images[0];
|
|
305673
305958
|
imageRelPath = `assets/scene-${id}.png`;
|
|
305674
305959
|
imageAbsPath = resolve29(projectDir, imageRelPath);
|
|
305675
|
-
await
|
|
305960
|
+
await mkdir12(dirname24(imageAbsPath), { recursive: true });
|
|
305676
305961
|
let buffer;
|
|
305677
305962
|
if (img.base64) {
|
|
305678
305963
|
buffer = Buffer.from(img.base64, "base64");
|
|
@@ -305699,7 +305984,7 @@ async function executeSceneAdd(opts) {
|
|
|
305699
305984
|
}
|
|
305700
305985
|
imageRelPath = `assets/scene-${id}.png`;
|
|
305701
305986
|
imageAbsPath = resolve29(projectDir, imageRelPath);
|
|
305702
|
-
await
|
|
305987
|
+
await mkdir12(dirname24(imageAbsPath), { recursive: true });
|
|
305703
305988
|
const buffer = Buffer.from(imageResult.images[0].base64, "base64");
|
|
305704
305989
|
await writeFile15(imageAbsPath, buffer);
|
|
305705
305990
|
}
|
|
@@ -305718,7 +306003,7 @@ async function executeSceneAdd(opts) {
|
|
|
305718
306003
|
}
|
|
305719
306004
|
lottieRelPath = `assets/lottie-${id}.${ext}`;
|
|
305720
306005
|
lottieAbsPath = resolve29(projectDir, lottieRelPath);
|
|
305721
|
-
await
|
|
306006
|
+
await mkdir12(dirname24(lottieAbsPath), { recursive: true });
|
|
305722
306007
|
await copyFile3(sourceAbs, lottieAbsPath);
|
|
305723
306008
|
lottieInput = {
|
|
305724
306009
|
src: lottieRelPath,
|
|
@@ -305788,7 +306073,7 @@ async function executeSceneAdd(opts) {
|
|
|
305788
306073
|
transcript: transcriptWords,
|
|
305789
306074
|
lottie: lottieInput
|
|
305790
306075
|
});
|
|
305791
|
-
await
|
|
306076
|
+
await mkdir12(dirname24(scenePath), { recursive: true });
|
|
305792
306077
|
await writeFile15(scenePath, sceneHtml, "utf-8");
|
|
305793
306078
|
opts.onProgress?.("Updating root composition...");
|
|
305794
306079
|
let start = 0;
|
|
@@ -306005,6 +306290,7 @@ init_scene_build();
|
|
|
306005
306290
|
init_install_skill();
|
|
306006
306291
|
init_compose_prompts();
|
|
306007
306292
|
init_scene_repair();
|
|
306293
|
+
init_build_video_providers();
|
|
306008
306294
|
var SCENE_PRESETS2 = [
|
|
306009
306295
|
"simple",
|
|
306010
306296
|
"announcement",
|
|
@@ -306404,12 +306690,12 @@ var sceneBuildSchema = z3.object({
|
|
|
306404
306690
|
"TTS provider override. Default 'auto' (elevenlabs key > openai key > local kokoro)."
|
|
306405
306691
|
),
|
|
306406
306692
|
voice: z3.string().optional().describe("TTS voice id (provider-specific)."),
|
|
306407
|
-
imageProvider: z3.enum(["openai"]).optional().describe("Image provider for backdrops. Default 'openai' (gpt-image-2)."),
|
|
306408
|
-
videoProvider: z3.enum(
|
|
306693
|
+
imageProvider: z3.enum(["openai"]).optional().describe("Image provider for backdrops. Default 'openai' (gpt-image-2.5-sunburst)."),
|
|
306694
|
+
videoProvider: z3.enum(BUILD_VIDEO_PROVIDERS).optional().describe("Video provider for per-beat video cues. Default seedance."),
|
|
306409
306695
|
musicProvider: z3.enum(["elevenlabs", "replicate"]).optional().describe("Music provider for per-beat music cues. Default elevenlabs."),
|
|
306410
306696
|
imageQuality: z3.enum(["standard", "hd"]).optional().describe("OpenAI image quality. Default 'standard'."),
|
|
306411
306697
|
imageModel: z3.string().optional().describe(
|
|
306412
|
-
"Image model for keyframes/backdrops/character sheets (gemini: flash|pro, openai: gpt-image-2). Provider default when omitted."
|
|
306698
|
+
"Image model for keyframes/backdrops/character sheets (gemini: flash|lite|pro, openai: gpt-image-2.5-sunburst|gpt-image-2.5-flare|gpt-image-2). Provider default when omitted."
|
|
306413
306699
|
),
|
|
306414
306700
|
imageSize: z3.enum(["1024x1024", "1536x1024", "1024x1536"]).optional().describe("OpenAI image size. Default '1536x1024' (cinematic 16:9-ish)."),
|
|
306415
306701
|
maxCostUsd: z3.number().optional().describe("Fail before provider spend when estimated cost exceeds this USD cap."),
|
|
@@ -306842,7 +307128,7 @@ init_api_key();
|
|
|
306842
307128
|
init_exec_safe();
|
|
306843
307129
|
init_remotion();
|
|
306844
307130
|
import { resolve as resolve53, dirname as dirname36, basename as basename14 } from "node:path";
|
|
306845
|
-
import { writeFile as
|
|
307131
|
+
import { writeFile as writeFile33, mkdir as mkdir25, rm as rm10 } from "node:fs/promises";
|
|
306846
307132
|
import { existsSync as existsSync73 } from "node:fs";
|
|
306847
307133
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
306848
307134
|
var ASS_STYLES = ["karaoke-sweep", "typewriter"];
|
|
@@ -306994,7 +307280,7 @@ async function executeAnimatedCaption(options) {
|
|
|
306994
307280
|
}
|
|
306995
307281
|
const effectiveFontSize = fontSize ?? Math.round(height * 0.04);
|
|
306996
307282
|
const tmpAudioDir = resolve53(tmpdir11(), `vf-ac-${Date.now()}`);
|
|
306997
|
-
await
|
|
307283
|
+
await mkdir25(tmpAudioDir, { recursive: true });
|
|
306998
307284
|
const audioPath = resolve53(tmpAudioDir, "audio.wav");
|
|
306999
307285
|
await execSafe("ffmpeg", [
|
|
307000
307286
|
"-y",
|
|
@@ -307011,13 +307297,13 @@ async function executeAnimatedCaption(options) {
|
|
|
307011
307297
|
], { timeout: 12e4 });
|
|
307012
307298
|
const apiKey = await getApiKey("OPENAI_API_KEY", "OpenAI");
|
|
307013
307299
|
if (!apiKey) {
|
|
307014
|
-
await
|
|
307300
|
+
await rm10(tmpAudioDir, { recursive: true, force: true }).catch(() => {
|
|
307015
307301
|
});
|
|
307016
307302
|
return { success: false, error: "OPENAI_API_KEY required for Whisper transcription. Run 'vibe setup' or set OPENAI_API_KEY in .env" };
|
|
307017
307303
|
}
|
|
307018
307304
|
const transcript = await transcribeWithWords(audioPath, apiKey, language);
|
|
307019
307305
|
if (!transcript.words || transcript.words.length === 0) {
|
|
307020
|
-
await
|
|
307306
|
+
await rm10(tmpAudioDir, { recursive: true, force: true }).catch(() => {
|
|
307021
307307
|
});
|
|
307022
307308
|
return { success: false, error: "No words detected in transcription" };
|
|
307023
307309
|
}
|
|
@@ -307025,7 +307311,7 @@ async function executeAnimatedCaption(options) {
|
|
|
307025
307311
|
const absOutputPath = resolve53(process.cwd(), outputPath);
|
|
307026
307312
|
const outDir = dirname36(absOutputPath);
|
|
307027
307313
|
if (!existsSync73(outDir)) {
|
|
307028
|
-
await
|
|
307314
|
+
await mkdir25(outDir, { recursive: true });
|
|
307029
307315
|
}
|
|
307030
307316
|
if (tier === "ass") {
|
|
307031
307317
|
const assContent = generateASS(
|
|
@@ -307034,7 +307320,7 @@ async function executeAnimatedCaption(options) {
|
|
|
307034
307320
|
{ highlightColor, fontSize: effectiveFontSize, position, width, height }
|
|
307035
307321
|
);
|
|
307036
307322
|
const assPath = resolve53(tmpAudioDir, "captions.ass");
|
|
307037
|
-
await
|
|
307323
|
+
await writeFile33(assPath, assContent, "utf-8");
|
|
307038
307324
|
const escapedAssPath = assPath.replace(/\\/g, "\\\\").replace(/:/g, "\\:");
|
|
307039
307325
|
await execSafe("ffmpeg", [
|
|
307040
307326
|
"-y",
|
|
@@ -307071,12 +307357,12 @@ async function executeAnimatedCaption(options) {
|
|
|
307071
307357
|
outputPath: absOutputPath
|
|
307072
307358
|
});
|
|
307073
307359
|
if (!renderResult.success) {
|
|
307074
|
-
await
|
|
307360
|
+
await rm10(tmpAudioDir, { recursive: true, force: true }).catch(() => {
|
|
307075
307361
|
});
|
|
307076
307362
|
return { success: false, error: renderResult.error };
|
|
307077
307363
|
}
|
|
307078
307364
|
}
|
|
307079
|
-
await
|
|
307365
|
+
await rm10(tmpAudioDir, { recursive: true, force: true }).catch(() => {
|
|
307080
307366
|
});
|
|
307081
307367
|
return {
|
|
307082
307368
|
success: true,
|
|
@@ -307485,7 +307771,7 @@ var editImageTool = defineTool({
|
|
|
307485
307771
|
imagePaths: z5.array(z5.string()).describe("Input image file path(s)"),
|
|
307486
307772
|
prompt: z5.string().describe("Edit instruction"),
|
|
307487
307773
|
output: z5.string().optional().describe("Output file path (default: edited.png)"),
|
|
307488
|
-
model: z5.enum(["flash", "3.1-flash", "latest", "pro"]).optional().describe("Gemini model (default: flash)"),
|
|
307774
|
+
model: z5.enum(["flash", "3.1-flash", "latest", "lite", "pro"]).optional().describe("Gemini model (default: flash = Nano Banana 2)"),
|
|
307489
307775
|
ratio: z5.string().optional().describe("Output aspect ratio"),
|
|
307490
307776
|
resolution: z5.string().optional().describe("Resolution: 1K, 2K, 4K (Pro only)")
|
|
307491
307777
|
}),
|
|
@@ -309338,7 +309624,7 @@ var generateSoundEffectTool = defineTool({
|
|
|
309338
309624
|
schema: z7.object({
|
|
309339
309625
|
prompt: z7.string().describe("Description of the sound effect"),
|
|
309340
309626
|
output: z7.string().optional().describe("Output audio file path (default: sound-effect.mp3)"),
|
|
309341
|
-
duration: z7.number().optional().describe("Duration in seconds (0.5-
|
|
309627
|
+
duration: z7.number().optional().describe("Duration in seconds (0.5-30, default: auto)"),
|
|
309342
309628
|
promptInfluence: z7.number().optional().describe("Prompt influence 0-1 (default: 0.3)")
|
|
309343
309629
|
}),
|
|
309344
309630
|
async execute(args) {
|
|
@@ -309415,7 +309701,7 @@ var generateImageTool = defineTool({
|
|
|
309415
309701
|
ratio: z7.string().optional().describe("Aspect ratio for Gemini (1:1, 16:9, 9:16, 4:3, 3:4, etc.)"),
|
|
309416
309702
|
quality: z7.string().optional().describe("Quality for OpenAI: standard, hd"),
|
|
309417
309703
|
count: z7.number().optional().describe("Number of images (default: 1)"),
|
|
309418
|
-
model: z7.string().optional().describe("
|
|
309704
|
+
model: z7.string().optional().describe("Image model. Gemini: flash (default), lite, pro. OpenAI: 2.5 (default), flare, 2, 1.5. Grok: pro")
|
|
309419
309705
|
}),
|
|
309420
309706
|
async execute(args) {
|
|
309421
309707
|
const result = await executeImageGenerate(args);
|
|
@@ -309478,9 +309764,11 @@ var generateVideoTool = defineTool({
|
|
|
309478
309764
|
mode: z7.string().optional().describe("Kling mode: std or pro"),
|
|
309479
309765
|
negative: z7.string().optional().describe("Negative prompt (Seedance/Kling/Veo)"),
|
|
309480
309766
|
resolution: z7.string().optional().describe("Resolution: 480p, 720p, 1080p, or 4k depending on provider"),
|
|
309481
|
-
veoModel: z7.string().optional().describe("Veo model: 3.
|
|
309767
|
+
veoModel: z7.string().optional().describe("Veo model: 3.1, 3.1-fast"),
|
|
309482
309768
|
runwayModel: z7.string().optional().describe("Runway model: gen4.5, gen4_turbo"),
|
|
309483
|
-
seedanceModel: z7.string().optional().describe("Seedance variant: quality
|
|
309769
|
+
seedanceModel: z7.string().optional().describe("Seedance variant: quality (2.0), fast, or 2.5 (fal.ai only)"),
|
|
309770
|
+
grokModel: z7.string().optional().describe("Grok video model: 1.5 (default), lite, classic"),
|
|
309771
|
+
klingModel: z7.string().optional().describe("Kling model: v3 (default), v2.6, v2.5-turbo"),
|
|
309484
309772
|
generateAudio: z7.boolean().optional().describe("Generate native synchronized audio when supported"),
|
|
309485
309773
|
output: z7.string().optional().describe("Output file path (downloads video)"),
|
|
309486
309774
|
wait: z7.boolean().optional().describe("Wait for completion (default: true)")
|
|
@@ -309552,7 +309840,7 @@ var generateVideoExtendTool = defineTool({
|
|
|
309552
309840
|
prompt: z7.string().optional().describe("Continuation prompt"),
|
|
309553
309841
|
duration: z7.number().optional().describe("Duration in seconds"),
|
|
309554
309842
|
negative: z7.string().optional().describe("Negative prompt (Kling)"),
|
|
309555
|
-
veoModel: z7.string().optional().describe("Veo model: 3.
|
|
309843
|
+
veoModel: z7.string().optional().describe("Veo model: 3.1, 3.1-fast"),
|
|
309556
309844
|
output: z7.string().optional().describe("Output file path"),
|
|
309557
309845
|
wait: z7.boolean().optional().describe("Wait for completion (default: true)")
|
|
309558
309846
|
}),
|
|
@@ -309588,7 +309876,7 @@ var generateTools = [
|
|
|
309588
309876
|
|
|
309589
309877
|
// ../cli/src/tools/manifest/storyboard.ts
|
|
309590
309878
|
import { existsSync as existsSync81 } from "node:fs";
|
|
309591
|
-
import { readFile as readFile38, writeFile as
|
|
309879
|
+
import { readFile as readFile38, writeFile as writeFile42 } from "node:fs/promises";
|
|
309592
309880
|
import { resolve as resolve70 } from "node:path";
|
|
309593
309881
|
import { z as z9 } from "zod";
|
|
309594
309882
|
init_storyboard_parse();
|
|
@@ -309596,7 +309884,7 @@ init_storyboard_edit();
|
|
|
309596
309884
|
|
|
309597
309885
|
// ../cli/src/commands/_shared/storyboard-revise.ts
|
|
309598
309886
|
import { existsSync as existsSync80 } from "node:fs";
|
|
309599
|
-
import { readFile as readFile37, writeFile as
|
|
309887
|
+
import { readFile as readFile37, writeFile as writeFile41 } from "node:fs/promises";
|
|
309600
309888
|
import { join as join74, resolve as resolve69 } from "node:path";
|
|
309601
309889
|
|
|
309602
309890
|
// ../cli/src/agent/adapters/index.ts
|
|
@@ -309765,7 +310053,7 @@ async function executeStoryboardRevision(opts) {
|
|
|
309765
310053
|
if (loaded.layout === "bundle") {
|
|
309766
310054
|
await rewriteBundleFromMarkdown(projectDir, storyboardMd);
|
|
309767
310055
|
} else {
|
|
309768
|
-
await
|
|
310056
|
+
await writeFile41(storyboardPath, storyboardMd, "utf-8");
|
|
309769
310057
|
}
|
|
309770
310058
|
}
|
|
309771
310059
|
const changedBeats = unique5([...diffChangedBeats(currentStoryboard, storyboardMd), ...payload.changedBeats]);
|
|
@@ -309943,6 +310231,7 @@ function stripUndefined4(value) {
|
|
|
309943
310231
|
|
|
309944
310232
|
// ../cli/src/tools/manifest/storyboard.ts
|
|
309945
310233
|
init_build_plan();
|
|
310234
|
+
init_build_video_providers();
|
|
309946
310235
|
var PROJECT_DIR_DESCRIPTION3 = "Project directory. Defaults to the surface's cwd; in MCP hosts, relative paths resolve under the configured server workspace.";
|
|
309947
310236
|
var projectDirSchema = z9.object({
|
|
309948
310237
|
projectDir: z9.string().optional().describe(PROJECT_DIR_DESCRIPTION3)
|
|
@@ -310063,7 +310352,7 @@ var storyboardSetTool = defineTool({
|
|
|
310063
310352
|
value,
|
|
310064
310353
|
unset: args.unset
|
|
310065
310354
|
});
|
|
310066
|
-
await
|
|
310355
|
+
await writeFile42(file.path, next, "utf-8");
|
|
310067
310356
|
return {
|
|
310068
310357
|
success: true,
|
|
310069
310358
|
data: { beat: args.beat, key: args.key },
|
|
@@ -310095,7 +310384,7 @@ var storyboardMoveTool = defineTool({
|
|
|
310095
310384
|
beatId: args.beat,
|
|
310096
310385
|
afterBeatId: args.after
|
|
310097
310386
|
});
|
|
310098
|
-
await
|
|
310387
|
+
await writeFile42(file.path, next, "utf-8");
|
|
310099
310388
|
return {
|
|
310100
310389
|
success: true,
|
|
310101
310390
|
data: { beat: args.beat, after: args.after },
|
|
@@ -310160,7 +310449,7 @@ var planTool = defineTool({
|
|
|
310160
310449
|
imageProvider: z9.string().optional().describe("Image provider override."),
|
|
310161
310450
|
imageQuality: z9.enum(["standard", "hd"]).optional().describe("Image quality override."),
|
|
310162
310451
|
imageSize: z9.string().optional().describe("Image size override."),
|
|
310163
|
-
videoProvider: z9.enum(
|
|
310452
|
+
videoProvider: z9.enum(BUILD_VIDEO_PROVIDERS).optional().describe("Video provider override."),
|
|
310164
310453
|
musicProvider: z9.enum(["elevenlabs", "replicate"]).optional().describe("Music provider override."),
|
|
310165
310454
|
composer: z9.enum(["claude", "openai", "gemini"]).optional().describe("Composer provider override."),
|
|
310166
310455
|
force: z9.boolean().optional().describe("Plan regeneration even when outputs exist.")
|
|
@@ -310249,14 +310538,14 @@ var designValidateTool = defineTool({
|
|
|
310249
310538
|
var designTools = [designValidateTool];
|
|
310250
310539
|
|
|
310251
310540
|
// ../cli/src/tools/manifest/remix.ts
|
|
310252
|
-
import { writeFile as
|
|
310541
|
+
import { writeFile as writeFile46 } from "node:fs/promises";
|
|
310253
310542
|
import { tmpdir as tmpdir12 } from "node:os";
|
|
310254
310543
|
import { join as join76 } from "node:path";
|
|
310255
310544
|
import { z as z11 } from "zod";
|
|
310256
310545
|
|
|
310257
310546
|
// ../cli/src/commands/ai-highlights.ts
|
|
310258
|
-
import { readFile as readFile40, writeFile as
|
|
310259
|
-
import { resolve as resolve73, dirname as dirname40, basename as basename19, extname as
|
|
310547
|
+
import { readFile as readFile40, writeFile as writeFile43, mkdir as mkdir29 } from "node:fs/promises";
|
|
310548
|
+
import { resolve as resolve73, dirname as dirname40, basename as basename19, extname as extname19 } from "node:path";
|
|
310260
310549
|
import { existsSync as existsSync83 } from "node:fs";
|
|
310261
310550
|
init_dist();
|
|
310262
310551
|
init_engine();
|
|
@@ -310291,7 +310580,7 @@ async function executeHighlights(options) {
|
|
|
310291
310580
|
if (!existsSync83(absPath)) {
|
|
310292
310581
|
return { success: false, highlights: [], totalDuration: 0, totalHighlightDuration: 0, error: `File not found: ${absPath}` };
|
|
310293
310582
|
}
|
|
310294
|
-
const ext =
|
|
310583
|
+
const ext = extname19(absPath).toLowerCase();
|
|
310295
310584
|
const videoExtensions = [".mp4", ".mov", ".avi", ".mkv", ".webm", ".m4v"];
|
|
310296
310585
|
const isVideo = videoExtensions.includes(ext);
|
|
310297
310586
|
const targetDuration = options.duration;
|
|
@@ -310436,7 +310725,7 @@ Analyze both what is SHOWN (visual cues, actions, expressions) and what is SAID
|
|
|
310436
310725
|
};
|
|
310437
310726
|
if (options.output) {
|
|
310438
310727
|
const outputPath = resolve73(process.cwd(), options.output);
|
|
310439
|
-
await
|
|
310728
|
+
await writeFile43(outputPath, JSON.stringify({
|
|
310440
310729
|
sourceFile: absPath,
|
|
310441
310730
|
totalDuration: sourceDuration,
|
|
310442
310731
|
criteria: options.criteria || "all",
|
|
@@ -310471,7 +310760,7 @@ Analyze both what is SHOWN (visual cues, actions, expressions) and what is SAID
|
|
|
310471
310760
|
}
|
|
310472
310761
|
}
|
|
310473
310762
|
const projectPath = resolve73(process.cwd(), options.project);
|
|
310474
|
-
await
|
|
310763
|
+
await writeFile43(projectPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
310475
310764
|
extractResult.projectPath = projectPath;
|
|
310476
310765
|
}
|
|
310477
310766
|
return extractResult;
|
|
@@ -310620,7 +310909,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
310620
310909
|
}
|
|
310621
310910
|
const outputDir = options.outputDir ? resolve73(process.cwd(), options.outputDir) : dirname40(absPath);
|
|
310622
310911
|
if (options.outputDir && !existsSync83(outputDir)) {
|
|
310623
|
-
await
|
|
310912
|
+
await mkdir29(outputDir, { recursive: true });
|
|
310624
310913
|
}
|
|
310625
310914
|
const result = {
|
|
310626
310915
|
success: true,
|
|
@@ -310628,7 +310917,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
310628
310917
|
};
|
|
310629
310918
|
for (let i3 = 0; i3 < selectedHighlights.length; i3++) {
|
|
310630
310919
|
const h2 = selectedHighlights[i3];
|
|
310631
|
-
const baseName = basename19(absPath,
|
|
310920
|
+
const baseName = basename19(absPath, extname19(absPath));
|
|
310632
310921
|
const outputPath = resolve73(outputDir, `${baseName}-short-${i3 + 1}.mp4`);
|
|
310633
310922
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
310634
310923
|
"-v",
|
|
@@ -310698,7 +310987,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
310698
310987
|
// ../cli/src/pipeline/executor.ts
|
|
310699
310988
|
var import_yaml8 = __toESM(require_dist3(), 1);
|
|
310700
310989
|
import { resolve as resolve75 } from "node:path";
|
|
310701
|
-
import { readFile as readFile42, writeFile as
|
|
310990
|
+
import { readFile as readFile42, writeFile as writeFile45, mkdir as mkdir30 } from "node:fs/promises";
|
|
310702
310991
|
import { existsSync as existsSync84 } from "node:fs";
|
|
310703
310992
|
|
|
310704
310993
|
// ../cli/src/pipeline/resolver.ts
|
|
@@ -310760,6 +311049,7 @@ function findUnresolvedRefs(params, availableStepIds) {
|
|
|
310760
311049
|
init_output();
|
|
310761
311050
|
init_config();
|
|
310762
311051
|
init_provider_resolver();
|
|
311052
|
+
init_build_video_providers();
|
|
310763
311053
|
var ACTION_METADATA = {
|
|
310764
311054
|
"generate-image": { id: "generate-image", title: "Generate image", category: "generate", command: "generate image", outputs: ["image"] },
|
|
310765
311055
|
"generate-video": { id: "generate-video", title: "Generate video", category: "generate", command: "generate video", outputs: ["video"], requiredKeys: ["provider-dependent"] },
|
|
@@ -310833,7 +311123,7 @@ async function resolvePipelineVideoProvider(provider) {
|
|
|
310833
311123
|
if (explicit === "fal") return "seedance";
|
|
310834
311124
|
if (explicit) return explicit;
|
|
310835
311125
|
await loadProviderDefaults();
|
|
310836
|
-
return resolveProvider("video")?.name ?? "grok";
|
|
311126
|
+
return resolveBuildVideoProvider(resolveProvider("video")?.name ?? "grok");
|
|
310837
311127
|
}
|
|
310838
311128
|
function providerKeyForImage(provider) {
|
|
310839
311129
|
switch (provider) {
|
|
@@ -310859,6 +311149,7 @@ function providerKeyForVideo(provider) {
|
|
|
310859
311149
|
case "runway":
|
|
310860
311150
|
return "runway";
|
|
310861
311151
|
case "veo":
|
|
311152
|
+
case "omni":
|
|
310862
311153
|
return "google";
|
|
310863
311154
|
default:
|
|
310864
311155
|
return void 0;
|
|
@@ -311110,7 +311401,7 @@ var CHECKPOINT_FILE = ".pipeline-state.yaml";
|
|
|
311110
311401
|
async function executePipeline(manifest2, options = {}) {
|
|
311111
311402
|
await ensureActionsRegistered();
|
|
311112
311403
|
const outputDir = resolve75(process.cwd(), options.outputDir || `${manifest2.name}-output`);
|
|
311113
|
-
await
|
|
311404
|
+
await mkdir30(outputDir, { recursive: true });
|
|
311114
311405
|
const completedSteps = /* @__PURE__ */ new Map();
|
|
311115
311406
|
const results = [];
|
|
311116
311407
|
const startTime = Date.now();
|
|
@@ -311235,7 +311526,7 @@ async function executePipeline(manifest2, options = {}) {
|
|
|
311235
311526
|
data: s2.data
|
|
311236
311527
|
}))
|
|
311237
311528
|
};
|
|
311238
|
-
await
|
|
311529
|
+
await writeFile45(
|
|
311239
311530
|
resolve75(outputDir, CHECKPOINT_FILE),
|
|
311240
311531
|
(0, import_yaml8.stringify)(checkpoint, { indent: 2 }),
|
|
311241
311532
|
"utf-8"
|
|
@@ -311390,7 +311681,7 @@ var pipelineRunTool = defineTool({
|
|
|
311390
311681
|
let tempPath;
|
|
311391
311682
|
if (args.pipelineYaml) {
|
|
311392
311683
|
tempPath = join76(tmpdir12(), `vibe-mcp-pipeline-${Date.now()}.yaml`);
|
|
311393
|
-
await
|
|
311684
|
+
await writeFile46(tempPath, args.pipelineYaml, "utf-8");
|
|
311394
311685
|
resolvedPath = tempPath;
|
|
311395
311686
|
}
|
|
311396
311687
|
try {
|
|
@@ -311527,7 +311818,7 @@ var detectTools = [
|
|
|
311527
311818
|
|
|
311528
311819
|
// ../cli/src/tools/manifest/timeline.ts
|
|
311529
311820
|
import { z as z13 } from "zod";
|
|
311530
|
-
import { mkdir as
|
|
311821
|
+
import { mkdir as mkdir31, writeFile as writeFile48 } from "node:fs/promises";
|
|
311531
311822
|
import { basename as basename21, resolve as resolve76 } from "node:path";
|
|
311532
311823
|
init_engine();
|
|
311533
311824
|
init_project_resolver();
|
|
@@ -311535,7 +311826,7 @@ init_project_resolver();
|
|
|
311535
311826
|
// ../cli/src/tools/manifest/_project-io.ts
|
|
311536
311827
|
init_engine();
|
|
311537
311828
|
init_project_resolver();
|
|
311538
|
-
import { readFile as readFile43, writeFile as
|
|
311829
|
+
import { readFile as readFile43, writeFile as writeFile47 } from "node:fs/promises";
|
|
311539
311830
|
async function loadProject(projectPath, cwd) {
|
|
311540
311831
|
const absPath = await resolveTimelineFile(projectPath, cwd);
|
|
311541
311832
|
const content = await readFile43(absPath, "utf-8");
|
|
@@ -311543,7 +311834,7 @@ async function loadProject(projectPath, cwd) {
|
|
|
311543
311834
|
return { project: Project.fromJSON(data2), absPath };
|
|
311544
311835
|
}
|
|
311545
311836
|
async function saveProject(absPath, project) {
|
|
311546
|
-
await
|
|
311837
|
+
await writeFile47(absPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
311547
311838
|
}
|
|
311548
311839
|
|
|
311549
311840
|
// ../cli/src/tools/manifest/timeline.ts
|
|
@@ -311583,10 +311874,10 @@ var timelineCreateTool = defineTool({
|
|
|
311583
311874
|
outputPath = resolve76(ctx.workingDirectory, args.outputPath);
|
|
311584
311875
|
} else {
|
|
311585
311876
|
const dirPath = resolve76(ctx.workingDirectory, args.name);
|
|
311586
|
-
await
|
|
311877
|
+
await mkdir31(dirPath, { recursive: true });
|
|
311587
311878
|
outputPath = resolve76(dirPath, TIMELINE_FILENAME);
|
|
311588
311879
|
}
|
|
311589
|
-
await
|
|
311880
|
+
await writeFile48(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
311590
311881
|
return {
|
|
311591
311882
|
success: true,
|
|
311592
311883
|
data: { name: projectName, outputPath },
|
|
@@ -311884,7 +312175,7 @@ var timelineTools = [
|
|
|
311884
312175
|
// ../cli/src/tools/manifest/project.ts
|
|
311885
312176
|
import { z as z14 } from "zod";
|
|
311886
312177
|
import { resolve as resolve78 } from "node:path";
|
|
311887
|
-
import { writeFile as
|
|
312178
|
+
import { writeFile as writeFile49 } from "node:fs/promises";
|
|
311888
312179
|
init_engine();
|
|
311889
312180
|
|
|
311890
312181
|
// ../cli/src/commands/_shared/project-list.ts
|
|
@@ -312042,7 +312333,7 @@ var projectCreateTool = defineTool({
|
|
|
312042
312333
|
const outputPath = resolve78(ctx.workingDirectory, args.outputPath ?? `${args.name}.vibe.json`);
|
|
312043
312334
|
const project = new Project(args.name);
|
|
312044
312335
|
if (args.fps) project.setFrameRate(args.fps);
|
|
312045
|
-
await
|
|
312336
|
+
await writeFile49(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
312046
312337
|
return {
|
|
312047
312338
|
success: true,
|
|
312048
312339
|
data: { name: args.name, outputPath },
|
|
@@ -312763,8 +313054,8 @@ var exportVideoTool = defineTool({
|
|
|
312763
313054
|
var exportTools = [exportVideoTool];
|
|
312764
313055
|
|
|
312765
313056
|
// ../cli/src/tools/manifest/agent-only.ts
|
|
312766
|
-
import { readFile as readFile46, writeFile as
|
|
312767
|
-
import { resolve as resolve81, join as join78, basename as basename23, extname as
|
|
313057
|
+
import { readFile as readFile46, writeFile as writeFile50, readdir as readdir11, stat as stat10, access as access7, unlink as unlink5 } from "node:fs/promises";
|
|
313058
|
+
import { resolve as resolve81, join as join78, basename as basename23, extname as extname20 } from "node:path";
|
|
312768
313059
|
import { z as z16 } from "zod";
|
|
312769
313060
|
init_engine();
|
|
312770
313061
|
init_exec_safe();
|
|
@@ -312787,7 +313078,7 @@ function formatSize(bytes) {
|
|
|
312787
313078
|
return `${size.toFixed(1)}${units2[unit]}`;
|
|
312788
313079
|
}
|
|
312789
313080
|
function detectMediaType(filePath) {
|
|
312790
|
-
const ext =
|
|
313081
|
+
const ext = extname20(filePath).toLowerCase();
|
|
312791
313082
|
if ([".mp4", ".mov", ".avi", ".mkv", ".webm", ".m4v"].includes(ext)) return "video";
|
|
312792
313083
|
if ([".mp3", ".wav", ".aac", ".flac", ".ogg", ".m4a"].includes(ext)) return "audio";
|
|
312793
313084
|
if ([".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"].includes(ext)) return "image";
|
|
@@ -312814,7 +313105,7 @@ function isMediaFile(filePath) {
|
|
|
312814
313105
|
".webp",
|
|
312815
313106
|
".bmp"
|
|
312816
313107
|
];
|
|
312817
|
-
return mediaExts.includes(
|
|
313108
|
+
return mediaExts.includes(extname20(filePath).toLowerCase());
|
|
312818
313109
|
}
|
|
312819
313110
|
async function getMediaDuration2(filePath) {
|
|
312820
313111
|
try {
|
|
@@ -312897,7 +313188,7 @@ var fsWriteTool = defineTool({
|
|
|
312897
313188
|
async execute(args, ctx) {
|
|
312898
313189
|
try {
|
|
312899
313190
|
const absPath = resolve81(ctx.workingDirectory, args.path);
|
|
312900
|
-
await
|
|
313191
|
+
await writeFile50(absPath, args.content, "utf-8");
|
|
312901
313192
|
return { success: true, data: { bytes: args.content.length }, humanLines: [`File written: ${args.path} (${formatSize(args.content.length)})`] };
|
|
312902
313193
|
} catch (error) {
|
|
312903
313194
|
return { success: false, error: `Failed to write file: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -312960,7 +313251,7 @@ var batchImportTool = defineTool({
|
|
|
312960
313251
|
if (entry.isDirectory() && recursive) {
|
|
312961
313252
|
await scanDir(entryPath);
|
|
312962
313253
|
} else if (entry.isFile()) {
|
|
312963
|
-
const ext =
|
|
313254
|
+
const ext = extname20(entry.name).toLowerCase();
|
|
312964
313255
|
const matchesFilter = !filterExts || filterExts.includes(ext);
|
|
312965
313256
|
if (matchesFilter && isMediaFile(entryPath)) mediaFiles.push(entryPath);
|
|
312966
313257
|
}
|
|
@@ -312983,7 +313274,7 @@ var batchImportTool = defineTool({
|
|
|
312983
313274
|
const source3 = project.addSource({ name: mediaName, type: mediaType, url: mediaFile, duration });
|
|
312984
313275
|
addedSources.push({ id: source3.id, name: mediaName, type: mediaType });
|
|
312985
313276
|
}
|
|
312986
|
-
await
|
|
313277
|
+
await writeFile50(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
312987
313278
|
return {
|
|
312988
313279
|
success: true,
|
|
312989
313280
|
data: { count: addedSources.length, sources: addedSources },
|
|
@@ -313053,7 +313344,7 @@ var batchConcatTool = defineTool({
|
|
|
313053
313344
|
createdClips.push({ id: clip.id, sourceName: source3.name, startTime: currentTime, duration: source3.duration });
|
|
313054
313345
|
currentTime += source3.duration + gap;
|
|
313055
313346
|
}
|
|
313056
|
-
await
|
|
313347
|
+
await writeFile50(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
313057
313348
|
const totalDuration = currentTime - gap - startTime;
|
|
313058
313349
|
return {
|
|
313059
313350
|
success: true,
|
|
@@ -313116,7 +313407,7 @@ var batchApplyEffectTool = defineTool({
|
|
|
313116
313407
|
});
|
|
313117
313408
|
if (effect) appliedEffects.push({ clipId: clip.id, effectId: effect.id });
|
|
313118
313409
|
}
|
|
313119
|
-
await
|
|
313410
|
+
await writeFile50(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
313120
313411
|
return {
|
|
313121
313412
|
success: true,
|
|
313122
313413
|
data: { applied: appliedEffects.length, effectType: args.effectType },
|
|
@@ -313185,7 +313476,7 @@ var timelineClearTool = defineTool({
|
|
|
313185
313476
|
removed.sources++;
|
|
313186
313477
|
}
|
|
313187
313478
|
}
|
|
313188
|
-
await
|
|
313479
|
+
await writeFile50(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
313189
313480
|
const parts = [];
|
|
313190
313481
|
if (removed.clips > 0) parts.push(`${removed.clips} clips`);
|
|
313191
313482
|
if (removed.tracks > 0) parts.push(`${removed.tracks} tracks`);
|
|
@@ -313236,7 +313527,7 @@ var projectSetTool = defineTool({
|
|
|
313236
313527
|
project.setFrameRate(args.fps);
|
|
313237
313528
|
updates.push(`Frame Rate: ${args.fps} fps`);
|
|
313238
313529
|
}
|
|
313239
|
-
await
|
|
313530
|
+
await writeFile50(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
313240
313531
|
return {
|
|
313241
313532
|
success: true,
|
|
313242
313533
|
data: { updates },
|
|
@@ -313606,7 +313897,7 @@ var mediaConcatTool = defineTool({
|
|
|
313606
313897
|
} else {
|
|
313607
313898
|
const tempList = resolve81(ctx.workingDirectory, `concat-list-${Date.now()}.txt`);
|
|
313608
313899
|
const listContent = args.inputs.map((i3) => `file '${resolve81(ctx.workingDirectory, i3)}'`).join("\n");
|
|
313609
|
-
await
|
|
313900
|
+
await writeFile50(tempList, listContent, "utf-8");
|
|
313610
313901
|
try {
|
|
313611
313902
|
await execSafe(
|
|
313612
313903
|
"ffmpeg",
|
|
@@ -315058,7 +315349,7 @@ function handleCliFlags(argv, version2) {
|
|
|
315058
315349
|
}
|
|
315059
315350
|
|
|
315060
315351
|
// src/index.ts
|
|
315061
|
-
if (handleCliFlags(process.argv.slice(2), "0.115.
|
|
315352
|
+
if (handleCliFlags(process.argv.slice(2), "0.115.3")) {
|
|
315062
315353
|
process.exit(0);
|
|
315063
315354
|
}
|
|
315064
315355
|
console.log = (...args) => console.error(...args);
|
|
@@ -315071,7 +315362,7 @@ var server = new Server(
|
|
|
315071
315362
|
{
|
|
315072
315363
|
name: "vibeframe",
|
|
315073
315364
|
// Stamped with the package version by build.js at bundle time.
|
|
315074
|
-
version: "0.115.
|
|
315365
|
+
version: "0.115.3"
|
|
315075
315366
|
},
|
|
315076
315367
|
{
|
|
315077
315368
|
capabilities: {
|