@vibeframe/mcp-server 0.79.3 → 0.80.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/index.js +489 -368
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -14025,12 +14025,16 @@ function getSetupProviders() {
|
|
|
14025
14025
|
key: k.configKey,
|
|
14026
14026
|
name: k.label,
|
|
14027
14027
|
env: k.envVar,
|
|
14028
|
-
desc: k.setupDescription ?? ""
|
|
14028
|
+
desc: k.setupDescription ?? "",
|
|
14029
|
+
url: k.envExampleUrl
|
|
14029
14030
|
}));
|
|
14030
14031
|
}
|
|
14031
14032
|
function getAllApiKeys() {
|
|
14032
14033
|
return [...apiKeyRegistry.values()];
|
|
14033
14034
|
}
|
|
14035
|
+
function getKeyFormat(configKey) {
|
|
14036
|
+
return apiKeyRegistry.get(configKey)?.keyFormat;
|
|
14037
|
+
}
|
|
14034
14038
|
function getAllProviders() {
|
|
14035
14039
|
return [...providerRegistry2.values()];
|
|
14036
14040
|
}
|
|
@@ -14055,7 +14059,8 @@ var init_api_keys = __esm({
|
|
|
14055
14059
|
showInSetup: true,
|
|
14056
14060
|
setupDescription: "gpt-image-2 image gen ($, default since v0.56), Whisper transcribe, Agent",
|
|
14057
14061
|
envExampleComment: "OpenAI API Key (Whisper transcription, gpt-image-2 \u2014 default text-to-image since v0.56)",
|
|
14058
|
-
envExampleUrl: "https://platform.openai.com/api-keys"
|
|
14062
|
+
envExampleUrl: "https://platform.openai.com/api-keys",
|
|
14063
|
+
keyFormat: { prefix: /^sk-/, example: "sk-..." }
|
|
14059
14064
|
});
|
|
14060
14065
|
defineApiKey({
|
|
14061
14066
|
configKey: "google",
|
|
@@ -14064,7 +14069,8 @@ var init_api_keys = __esm({
|
|
|
14064
14069
|
showInSetup: true,
|
|
14065
14070
|
setupDescription: "Gemini \u2014 image gen (free tier), video analysis ($), Veo ($$)",
|
|
14066
14071
|
envExampleComment: "Google API Key (Gemini auto-edit suggestions, image gen, Veo video)",
|
|
14067
|
-
envExampleUrl: "https://aistudio.google.com/apikey"
|
|
14072
|
+
envExampleUrl: "https://aistudio.google.com/apikey",
|
|
14073
|
+
keyFormat: { prefix: /^AIza/, example: "AIza..." }
|
|
14068
14074
|
});
|
|
14069
14075
|
defineApiKey({
|
|
14070
14076
|
configKey: "anthropic",
|
|
@@ -14073,7 +14079,8 @@ var init_api_keys = __esm({
|
|
|
14073
14079
|
showInSetup: true,
|
|
14074
14080
|
setupDescription: "Claude \u2014 storyboard, color grade, reframe, Agent ($)",
|
|
14075
14081
|
envExampleComment: "Anthropic API Key (Claude motion graphics & storyboarding)",
|
|
14076
|
-
envExampleUrl: "https://console.anthropic.com/"
|
|
14082
|
+
envExampleUrl: "https://console.anthropic.com/",
|
|
14083
|
+
keyFormat: { prefix: /^sk-ant-/, example: "sk-ant-..." }
|
|
14077
14084
|
});
|
|
14078
14085
|
defineApiKey({
|
|
14079
14086
|
configKey: "elevenlabs",
|
|
@@ -14082,7 +14089,8 @@ var init_api_keys = __esm({
|
|
|
14082
14089
|
showInSetup: true,
|
|
14083
14090
|
setupDescription: "TTS ($), SFX, music, voice clone, dubbing \u2014 skip to use local Kokoro",
|
|
14084
14091
|
envExampleComment: "ElevenLabs API Key (text-to-speech \u2014 Kokoro local fallback runs when this is unset, since v0.54)",
|
|
14085
|
-
envExampleUrl: "https://elevenlabs.io/api"
|
|
14092
|
+
envExampleUrl: "https://elevenlabs.io/api",
|
|
14093
|
+
keyFormat: { prefix: /^sk_/, example: "sk_..." }
|
|
14086
14094
|
});
|
|
14087
14095
|
defineApiKey({
|
|
14088
14096
|
configKey: "fal",
|
|
@@ -14100,7 +14108,8 @@ var init_api_keys = __esm({
|
|
|
14100
14108
|
showInSetup: true,
|
|
14101
14109
|
setupDescription: "Grok \u2014 video gen with audio ($$), image ($), Agent",
|
|
14102
14110
|
envExampleComment: "xAI API Key (Grok video generation \u2014 fallback when no FAL_KEY)",
|
|
14103
|
-
envExampleUrl: "https://console.x.ai/"
|
|
14111
|
+
envExampleUrl: "https://console.x.ai/",
|
|
14112
|
+
keyFormat: { prefix: /^xai-/, example: "xai-..." }
|
|
14104
14113
|
});
|
|
14105
14114
|
defineApiKey({
|
|
14106
14115
|
configKey: "runway",
|
|
@@ -14109,7 +14118,8 @@ var init_api_keys = __esm({
|
|
|
14109
14118
|
showInSetup: true,
|
|
14110
14119
|
setupDescription: "Gen-4.5 video generation ($$)",
|
|
14111
14120
|
envExampleComment: "Runway API Secret (Runway Gen-4.5 video generation)",
|
|
14112
|
-
envExampleUrl: "https://app.runwayml.com/settings/api-keys"
|
|
14121
|
+
envExampleUrl: "https://app.runwayml.com/settings/api-keys",
|
|
14122
|
+
keyFormat: { prefix: /^key_/, example: "key_..." }
|
|
14113
14123
|
});
|
|
14114
14124
|
defineApiKey({
|
|
14115
14125
|
configKey: "kling",
|
|
@@ -14119,7 +14129,8 @@ var init_api_keys = __esm({
|
|
|
14119
14129
|
setupDescription: "v2.5/v3 video \u2014 std ($$) and pro ($$$) modes",
|
|
14120
14130
|
envExampleComment: "Kling API Key (Kling video generation)",
|
|
14121
14131
|
envExampleUrl: "https://platform.klingai.com/",
|
|
14122
|
-
envExampleExtraLines: ["Format: ACCESS_KEY:SECRET_KEY"]
|
|
14132
|
+
envExampleExtraLines: ["Format: ACCESS_KEY:SECRET_KEY"],
|
|
14133
|
+
keyFormat: { prefix: /:/, example: "ACCESS_KEY:SECRET_KEY" }
|
|
14123
14134
|
});
|
|
14124
14135
|
defineApiKey({
|
|
14125
14136
|
configKey: "replicate",
|
|
@@ -14128,7 +14139,8 @@ var init_api_keys = __esm({
|
|
|
14128
14139
|
showInSetup: true,
|
|
14129
14140
|
setupDescription: "MusicGen background music ($, max 30s)",
|
|
14130
14141
|
envExampleComment: "Replicate API Token (music generation, video upscale, audio restoration)",
|
|
14131
|
-
envExampleUrl: "https://replicate.com/account/api-tokens"
|
|
14142
|
+
envExampleUrl: "https://replicate.com/account/api-tokens",
|
|
14143
|
+
keyFormat: { prefix: /^r8_/, example: "r8_..." }
|
|
14132
14144
|
});
|
|
14133
14145
|
defineApiKey({
|
|
14134
14146
|
configKey: "openrouter",
|
|
@@ -14137,7 +14149,8 @@ var init_api_keys = __esm({
|
|
|
14137
14149
|
showInSetup: true,
|
|
14138
14150
|
setupDescription: "300+ models via one key \u2014 Agent only (pay per model)",
|
|
14139
14151
|
envExampleComment: "OpenRouter API Key (300+ AI models via unified API, used by `vibe agent`)",
|
|
14140
|
-
envExampleUrl: "https://openrouter.ai/keys"
|
|
14152
|
+
envExampleUrl: "https://openrouter.ai/keys",
|
|
14153
|
+
keyFormat: { prefix: /^sk-or-/, example: "sk-or-..." }
|
|
14141
14154
|
});
|
|
14142
14155
|
defineApiKey({
|
|
14143
14156
|
configKey: "imgbb",
|
|
@@ -24922,6 +24935,7 @@ __export(dist_exports, {
|
|
|
24922
24935
|
getAllProviders: () => getAllProviders,
|
|
24923
24936
|
getBestProviderForCapability: () => getBestProviderForCapability,
|
|
24924
24937
|
getCommandKeyMap: () => getCommandKeyMap,
|
|
24938
|
+
getKeyFormat: () => getKeyFormat,
|
|
24925
24939
|
getProviderEnvVars: () => getProviderEnvVars,
|
|
24926
24940
|
getProvidersFor: () => getProvidersFor,
|
|
24927
24941
|
getSetupProviders: () => getSetupProviders,
|
|
@@ -127672,7 +127686,7 @@ var require_typescript2 = __commonJS({
|
|
|
127672
127686
|
walkUpParenthesizedTypesAndGetParentAndChild: () => walkUpParenthesizedTypesAndGetParentAndChild,
|
|
127673
127687
|
whitespaceOrMapCommentRegExp: () => whitespaceOrMapCommentRegExp,
|
|
127674
127688
|
writeCommentRange: () => writeCommentRange,
|
|
127675
|
-
writeFile: () =>
|
|
127689
|
+
writeFile: () => writeFile44,
|
|
127676
127690
|
writeFileEnsuringDirectories: () => writeFileEnsuringDirectories,
|
|
127677
127691
|
zipWith: () => zipWith
|
|
127678
127692
|
});
|
|
@@ -146315,7 +146329,7 @@ ${lanes.join("\n")}
|
|
|
146315
146329
|
sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath;
|
|
146316
146330
|
return combinePaths(newDirPath, sourceFilePath);
|
|
146317
146331
|
}
|
|
146318
|
-
function
|
|
146332
|
+
function writeFile44(host, diagnostics, fileName, text, writeByteOrderMark, sourceFiles, data) {
|
|
146319
146333
|
host.writeFile(
|
|
146320
146334
|
fileName,
|
|
146321
146335
|
text,
|
|
@@ -147409,15 +147423,15 @@ ${lanes.join("\n")}
|
|
|
147409
147423
|
if (isAccessExpression(name.parent) && isRightSideOfAccessExpression(name)) {
|
|
147410
147424
|
return walkAccessExpression(name.parent);
|
|
147411
147425
|
}
|
|
147412
|
-
function walkAccessExpression(
|
|
147413
|
-
if (
|
|
147414
|
-
const res = action(
|
|
147426
|
+
function walkAccessExpression(access8) {
|
|
147427
|
+
if (access8.kind === 212) {
|
|
147428
|
+
const res = action(access8.name);
|
|
147415
147429
|
if (res !== void 0) {
|
|
147416
147430
|
return res;
|
|
147417
147431
|
}
|
|
147418
|
-
} else if (
|
|
147419
|
-
if (isIdentifier(
|
|
147420
|
-
const res = action(
|
|
147432
|
+
} else if (access8.kind === 213) {
|
|
147433
|
+
if (isIdentifier(access8.argumentExpression) || isStringLiteralLike(access8.argumentExpression)) {
|
|
147434
|
+
const res = action(access8.argumentExpression);
|
|
147421
147435
|
if (res !== void 0) {
|
|
147422
147436
|
return res;
|
|
147423
147437
|
}
|
|
@@ -147425,11 +147439,11 @@ ${lanes.join("\n")}
|
|
|
147425
147439
|
return void 0;
|
|
147426
147440
|
}
|
|
147427
147441
|
}
|
|
147428
|
-
if (isAccessExpression(
|
|
147429
|
-
return walkAccessExpression(
|
|
147442
|
+
if (isAccessExpression(access8.expression)) {
|
|
147443
|
+
return walkAccessExpression(access8.expression);
|
|
147430
147444
|
}
|
|
147431
|
-
if (isIdentifier(
|
|
147432
|
-
return action(
|
|
147445
|
+
if (isIdentifier(access8.expression)) {
|
|
147446
|
+
return action(access8.expression);
|
|
147433
147447
|
}
|
|
147434
147448
|
return void 0;
|
|
147435
147449
|
}
|
|
@@ -156682,11 +156696,11 @@ ${lanes.join("\n")}
|
|
|
156682
156696
|
)
|
|
156683
156697
|
);
|
|
156684
156698
|
}
|
|
156685
|
-
function createESDecorateClassElementAccessObject(name,
|
|
156699
|
+
function createESDecorateClassElementAccessObject(name, access8) {
|
|
156686
156700
|
const properties = [];
|
|
156687
156701
|
properties.push(createESDecorateClassElementAccessHasMethod(name));
|
|
156688
|
-
if (
|
|
156689
|
-
if (
|
|
156702
|
+
if (access8.get) properties.push(createESDecorateClassElementAccessGetMethod(name));
|
|
156703
|
+
if (access8.set) properties.push(createESDecorateClassElementAccessSetMethod(name));
|
|
156690
156704
|
return factory2.createObjectLiteralExpression(properties);
|
|
156691
156705
|
}
|
|
156692
156706
|
function createESDecorateClassElementContextObject(contextIn) {
|
|
@@ -184203,7 +184217,7 @@ ${lanes.join("\n")}
|
|
|
184203
184217
|
return false;
|
|
184204
184218
|
}
|
|
184205
184219
|
function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) {
|
|
184206
|
-
const
|
|
184220
|
+
const access8 = isSymbolAccessibleWorker(
|
|
184207
184221
|
typeSymbol,
|
|
184208
184222
|
enclosingDeclaration,
|
|
184209
184223
|
788968,
|
|
@@ -184212,10 +184226,10 @@ ${lanes.join("\n")}
|
|
|
184212
184226
|
/*allowModules*/
|
|
184213
184227
|
true
|
|
184214
184228
|
);
|
|
184215
|
-
return
|
|
184229
|
+
return access8.accessibility === 0;
|
|
184216
184230
|
}
|
|
184217
184231
|
function isValueSymbolAccessible(typeSymbol, enclosingDeclaration) {
|
|
184218
|
-
const
|
|
184232
|
+
const access8 = isSymbolAccessibleWorker(
|
|
184219
184233
|
typeSymbol,
|
|
184220
184234
|
enclosingDeclaration,
|
|
184221
184235
|
111551,
|
|
@@ -184224,10 +184238,10 @@ ${lanes.join("\n")}
|
|
|
184224
184238
|
/*allowModules*/
|
|
184225
184239
|
true
|
|
184226
184240
|
);
|
|
184227
|
-
return
|
|
184241
|
+
return access8.accessibility === 0;
|
|
184228
184242
|
}
|
|
184229
184243
|
function isSymbolAccessibleByFlags(typeSymbol, enclosingDeclaration, flags) {
|
|
184230
|
-
const
|
|
184244
|
+
const access8 = isSymbolAccessibleWorker(
|
|
184231
184245
|
typeSymbol,
|
|
184232
184246
|
enclosingDeclaration,
|
|
184233
184247
|
flags,
|
|
@@ -184236,7 +184250,7 @@ ${lanes.join("\n")}
|
|
|
184236
184250
|
/*allowModules*/
|
|
184237
184251
|
false
|
|
184238
184252
|
);
|
|
184239
|
-
return
|
|
184253
|
+
return access8.accessibility === 0;
|
|
184240
184254
|
}
|
|
184241
184255
|
function isAnySymbolAccessible(symbols, enclosingDeclaration, initialSymbol, meaning, shouldComputeAliasesToMakeVisible, allowModules) {
|
|
184242
184256
|
if (!length(symbols)) return;
|
|
@@ -204546,19 +204560,19 @@ ${lanes.join("\n")}
|
|
|
204546
204560
|
}
|
|
204547
204561
|
return false;
|
|
204548
204562
|
}
|
|
204549
|
-
function getAccessedPropertyName(
|
|
204550
|
-
if (isPropertyAccessExpression(
|
|
204551
|
-
return
|
|
204563
|
+
function getAccessedPropertyName(access8) {
|
|
204564
|
+
if (isPropertyAccessExpression(access8)) {
|
|
204565
|
+
return access8.name.escapedText;
|
|
204552
204566
|
}
|
|
204553
|
-
if (isElementAccessExpression(
|
|
204554
|
-
return tryGetElementAccessExpressionName(
|
|
204567
|
+
if (isElementAccessExpression(access8)) {
|
|
204568
|
+
return tryGetElementAccessExpressionName(access8);
|
|
204555
204569
|
}
|
|
204556
|
-
if (isBindingElement(
|
|
204557
|
-
const name = getDestructuringPropertyName(
|
|
204570
|
+
if (isBindingElement(access8)) {
|
|
204571
|
+
const name = getDestructuringPropertyName(access8);
|
|
204558
204572
|
return name ? escapeLeadingUnderscores(name) : void 0;
|
|
204559
204573
|
}
|
|
204560
|
-
if (isParameter(
|
|
204561
|
-
return "" +
|
|
204574
|
+
if (isParameter(access8)) {
|
|
204575
|
+
return "" + access8.parent.parameters.indexOf(access8);
|
|
204562
204576
|
}
|
|
204563
204577
|
return void 0;
|
|
204564
204578
|
}
|
|
@@ -205773,9 +205787,9 @@ ${lanes.join("\n")}
|
|
|
205773
205787
|
type = narrowTypeBySwitchOptionalChainContainment(type, flow.node, (t) => !(t.flags & 131072 || t.flags & 128 && t.value === "undefined"));
|
|
205774
205788
|
}
|
|
205775
205789
|
}
|
|
205776
|
-
const
|
|
205777
|
-
if (
|
|
205778
|
-
type = narrowTypeBySwitchOnDiscriminantProperty(type,
|
|
205790
|
+
const access8 = getDiscriminantPropertyAccess(expr, type);
|
|
205791
|
+
if (access8) {
|
|
205792
|
+
type = narrowTypeBySwitchOnDiscriminantProperty(type, access8, flow.node);
|
|
205779
205793
|
}
|
|
205780
205794
|
}
|
|
205781
205795
|
return createFlowType(type, isIncomplete(flowType));
|
|
@@ -205937,26 +205951,26 @@ ${lanes.join("\n")}
|
|
|
205937
205951
|
}
|
|
205938
205952
|
function getDiscriminantPropertyAccess(expr, computedType) {
|
|
205939
205953
|
if (declaredType.flags & 1048576 || computedType.flags & 1048576) {
|
|
205940
|
-
const
|
|
205941
|
-
if (
|
|
205942
|
-
const name = getAccessedPropertyName(
|
|
205954
|
+
const access8 = getCandidateDiscriminantPropertyAccess(expr);
|
|
205955
|
+
if (access8) {
|
|
205956
|
+
const name = getAccessedPropertyName(access8);
|
|
205943
205957
|
if (name) {
|
|
205944
205958
|
const type = declaredType.flags & 1048576 && isTypeSubsetOf(computedType, declaredType) ? declaredType : computedType;
|
|
205945
205959
|
if (isDiscriminantProperty(type, name)) {
|
|
205946
|
-
return
|
|
205960
|
+
return access8;
|
|
205947
205961
|
}
|
|
205948
205962
|
}
|
|
205949
205963
|
}
|
|
205950
205964
|
}
|
|
205951
205965
|
return void 0;
|
|
205952
205966
|
}
|
|
205953
|
-
function narrowTypeByDiscriminant(type,
|
|
205954
|
-
const propName = getAccessedPropertyName(
|
|
205967
|
+
function narrowTypeByDiscriminant(type, access8, narrowType2) {
|
|
205968
|
+
const propName = getAccessedPropertyName(access8);
|
|
205955
205969
|
if (propName === void 0) {
|
|
205956
205970
|
return type;
|
|
205957
205971
|
}
|
|
205958
|
-
const optionalChain = isOptionalChain(
|
|
205959
|
-
const removeNullable = strictNullChecks && (optionalChain || isNonNullAccess(
|
|
205972
|
+
const optionalChain = isOptionalChain(access8);
|
|
205973
|
+
const removeNullable = strictNullChecks && (optionalChain || isNonNullAccess(access8)) && maybeTypeOfKind(
|
|
205960
205974
|
type,
|
|
205961
205975
|
98304
|
|
205962
205976
|
/* Nullable */
|
|
@@ -205976,27 +205990,27 @@ ${lanes.join("\n")}
|
|
|
205976
205990
|
return !(discriminantType.flags & 131072) && !(narrowedPropType.flags & 131072) && areTypesComparable(narrowedPropType, discriminantType);
|
|
205977
205991
|
});
|
|
205978
205992
|
}
|
|
205979
|
-
function narrowTypeByDiscriminantProperty(type,
|
|
205993
|
+
function narrowTypeByDiscriminantProperty(type, access8, operator, value, assumeTrue) {
|
|
205980
205994
|
if ((operator === 37 || operator === 38) && type.flags & 1048576) {
|
|
205981
205995
|
const keyPropertyName = getKeyPropertyName(type);
|
|
205982
|
-
if (keyPropertyName && keyPropertyName === getAccessedPropertyName(
|
|
205996
|
+
if (keyPropertyName && keyPropertyName === getAccessedPropertyName(access8)) {
|
|
205983
205997
|
const candidate = getConstituentTypeForKeyType(type, getTypeOfExpression(value));
|
|
205984
205998
|
if (candidate) {
|
|
205985
205999
|
return operator === (assumeTrue ? 37 : 38) ? candidate : isUnitType(getTypeOfPropertyOfType(candidate, keyPropertyName) || unknownType) ? removeType(type, candidate) : type;
|
|
205986
206000
|
}
|
|
205987
206001
|
}
|
|
205988
206002
|
}
|
|
205989
|
-
return narrowTypeByDiscriminant(type,
|
|
206003
|
+
return narrowTypeByDiscriminant(type, access8, (t) => narrowTypeByEquality(t, operator, value, assumeTrue));
|
|
205990
206004
|
}
|
|
205991
|
-
function narrowTypeBySwitchOnDiscriminantProperty(type,
|
|
205992
|
-
if (data.clauseStart < data.clauseEnd && type.flags & 1048576 && getKeyPropertyName(type) === getAccessedPropertyName(
|
|
206005
|
+
function narrowTypeBySwitchOnDiscriminantProperty(type, access8, data) {
|
|
206006
|
+
if (data.clauseStart < data.clauseEnd && type.flags & 1048576 && getKeyPropertyName(type) === getAccessedPropertyName(access8)) {
|
|
205993
206007
|
const clauseTypes = getSwitchClauseTypes(data.switchStatement).slice(data.clauseStart, data.clauseEnd);
|
|
205994
206008
|
const candidate = getUnionType(map3(clauseTypes, (t) => getConstituentTypeForKeyType(type, t) || unknownType));
|
|
205995
206009
|
if (candidate !== unknownType) {
|
|
205996
206010
|
return candidate;
|
|
205997
206011
|
}
|
|
205998
206012
|
}
|
|
205999
|
-
return narrowTypeByDiscriminant(type,
|
|
206013
|
+
return narrowTypeByDiscriminant(type, access8, (t) => narrowTypeBySwitchOnDiscriminant(t, data));
|
|
206000
206014
|
}
|
|
206001
206015
|
function narrowTypeByTruthiness(type, expr, assumeTrue) {
|
|
206002
206016
|
if (isMatchingReference(reference, expr)) {
|
|
@@ -206013,9 +206027,9 @@ ${lanes.join("\n")}
|
|
|
206013
206027
|
/* NEUndefinedOrNull */
|
|
206014
206028
|
);
|
|
206015
206029
|
}
|
|
206016
|
-
const
|
|
206017
|
-
if (
|
|
206018
|
-
return narrowTypeByDiscriminant(type,
|
|
206030
|
+
const access8 = getDiscriminantPropertyAccess(expr, type);
|
|
206031
|
+
if (access8) {
|
|
206032
|
+
return narrowTypeByDiscriminant(type, access8, (t) => getTypeWithFacts(
|
|
206019
206033
|
t,
|
|
206020
206034
|
assumeTrue ? 4194304 : 8388608
|
|
206021
206035
|
/* Falsy */
|
|
@@ -206643,9 +206657,9 @@ ${lanes.join("\n")}
|
|
|
206643
206657
|
/* NEUndefinedOrNull */
|
|
206644
206658
|
);
|
|
206645
206659
|
}
|
|
206646
|
-
const
|
|
206647
|
-
if (
|
|
206648
|
-
return narrowTypeByDiscriminant(type,
|
|
206660
|
+
const access8 = getDiscriminantPropertyAccess(predicateArgument, type);
|
|
206661
|
+
if (access8) {
|
|
206662
|
+
return narrowTypeByDiscriminant(type, access8, (t) => getNarrowedType(
|
|
206649
206663
|
t,
|
|
206650
206664
|
predicate.type,
|
|
206651
206665
|
assumeTrue,
|
|
@@ -206705,9 +206719,9 @@ ${lanes.join("\n")}
|
|
|
206705
206719
|
/* EQUndefinedOrNull */
|
|
206706
206720
|
);
|
|
206707
206721
|
}
|
|
206708
|
-
const
|
|
206709
|
-
if (
|
|
206710
|
-
return narrowTypeByDiscriminant(type,
|
|
206722
|
+
const access8 = getDiscriminantPropertyAccess(expr, type);
|
|
206723
|
+
if (access8) {
|
|
206724
|
+
return narrowTypeByDiscriminant(type, access8, (t) => getTypeWithFacts(
|
|
206711
206725
|
t,
|
|
206712
206726
|
assumePresent ? 2097152 : 262144
|
|
206713
206727
|
/* EQUndefinedOrNull */
|
|
@@ -255066,7 +255080,7 @@ ${lanes.join("\n")}
|
|
|
255066
255080
|
return;
|
|
255067
255081
|
}
|
|
255068
255082
|
const buildInfo = host.getBuildInfo() || { version };
|
|
255069
|
-
|
|
255083
|
+
writeFile44(
|
|
255070
255084
|
host,
|
|
255071
255085
|
emitterDiagnostics,
|
|
255072
255086
|
buildInfoPath,
|
|
@@ -255278,7 +255292,7 @@ ${lanes.join("\n")}
|
|
|
255278
255292
|
}
|
|
255279
255293
|
if (sourceMapFilePath) {
|
|
255280
255294
|
const sourceMap = sourceMapGenerator.toString();
|
|
255281
|
-
|
|
255295
|
+
writeFile44(
|
|
255282
255296
|
host,
|
|
255283
255297
|
emitterDiagnostics,
|
|
255284
255298
|
sourceMapFilePath,
|
|
@@ -255293,7 +255307,7 @@ ${lanes.join("\n")}
|
|
|
255293
255307
|
}
|
|
255294
255308
|
const text = writer.getText();
|
|
255295
255309
|
const data = { sourceMapUrlPos, diagnostics: transform2.diagnostics };
|
|
255296
|
-
|
|
255310
|
+
writeFile44(host, emitterDiagnostics, jsFilePath, text, !!compilerOptions.emitBOM, sourceFiles, data);
|
|
255297
255311
|
writer.clear();
|
|
255298
255312
|
return !data.skippedDtsWrite;
|
|
255299
255313
|
}
|
|
@@ -261956,9 +261970,9 @@ ${lanes.join("\n")}
|
|
|
261956
261970
|
/*ignoreCase*/
|
|
261957
261971
|
false
|
|
261958
261972
|
)) {
|
|
261959
|
-
const
|
|
261960
|
-
if (
|
|
261961
|
-
const name = removeSuffix(removePrefix(
|
|
261973
|
+
const basename18 = getBaseFileName(a.fileName);
|
|
261974
|
+
if (basename18 === "lib.d.ts" || basename18 === "lib.es6.d.ts") return 0;
|
|
261975
|
+
const name = removeSuffix(removePrefix(basename18, "lib."), ".d.ts");
|
|
261962
261976
|
const index = libs.indexOf(name);
|
|
261963
261977
|
if (index !== -1) return index + 1;
|
|
261964
261978
|
}
|
|
@@ -282050,13 +282064,13 @@ interface Symbol {
|
|
|
282050
282064
|
for (const element of toConvert.elements) {
|
|
282051
282065
|
const propertyName = element.propertyName || element.name;
|
|
282052
282066
|
ts_FindAllReferences_exports.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, (id) => {
|
|
282053
|
-
const
|
|
282067
|
+
const access8 = propertyName.kind === 11 ? factory.createElementAccessExpression(factory.createIdentifier(namespaceImportName), factory.cloneNode(propertyName)) : factory.createPropertyAccessExpression(factory.createIdentifier(namespaceImportName), factory.cloneNode(propertyName));
|
|
282054
282068
|
if (isShorthandPropertyAssignment(id.parent)) {
|
|
282055
|
-
changes.replaceNode(sourceFile, id.parent, factory.createPropertyAssignment(id.text,
|
|
282069
|
+
changes.replaceNode(sourceFile, id.parent, factory.createPropertyAssignment(id.text, access8));
|
|
282056
282070
|
} else if (isExportSpecifier(id.parent)) {
|
|
282057
282071
|
neededNamedImports.add(element);
|
|
282058
282072
|
} else {
|
|
282059
|
-
changes.replaceNode(sourceFile, id,
|
|
282073
|
+
changes.replaceNode(sourceFile, id, access8);
|
|
282060
282074
|
}
|
|
282061
282075
|
});
|
|
282062
282076
|
}
|
|
@@ -323175,7 +323189,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
323175
323189
|
walkUpParenthesizedTypesAndGetParentAndChild: () => walkUpParenthesizedTypesAndGetParentAndChild,
|
|
323176
323190
|
whitespaceOrMapCommentRegExp: () => whitespaceOrMapCommentRegExp,
|
|
323177
323191
|
writeCommentRange: () => writeCommentRange,
|
|
323178
|
-
writeFile: () =>
|
|
323192
|
+
writeFile: () => writeFile44,
|
|
323179
323193
|
writeFileEnsuringDirectories: () => writeFileEnsuringDirectories,
|
|
323180
323194
|
zipWith: () => zipWith
|
|
323181
323195
|
});
|
|
@@ -325704,8 +325718,8 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
325704
325718
|
}
|
|
325705
325719
|
};
|
|
325706
325720
|
for (const file of files) {
|
|
325707
|
-
const
|
|
325708
|
-
if (
|
|
325721
|
+
const basename18 = getBaseFileName(file);
|
|
325722
|
+
if (basename18 === "package.json" || basename18 === "bower.json") {
|
|
325709
325723
|
createProjectWatcher(
|
|
325710
325724
|
file,
|
|
325711
325725
|
"FileWatcher"
|
|
@@ -329377,8 +329391,8 @@ All files are: ${JSON.stringify(names)}`,
|
|
|
329377
329391
|
var _a7;
|
|
329378
329392
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
329379
329393
|
if (!fileOrDirectoryPath) return;
|
|
329380
|
-
const
|
|
329381
|
-
if (((_a7 = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a7.size) && (
|
|
329394
|
+
const basename18 = getBaseFileName(fileOrDirectoryPath);
|
|
329395
|
+
if (((_a7 = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a7.size) && (basename18 === "package.json" || basename18 === "node_modules")) {
|
|
329382
329396
|
result.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
329383
329397
|
var _a23;
|
|
329384
329398
|
(_a23 = project.getModuleSpecifierCache()) == null ? void 0 : _a23.clear();
|
|
@@ -453215,16 +453229,31 @@ var init_project = __esm({
|
|
|
453215
453229
|
}
|
|
453216
453230
|
// ============ Serialization ============
|
|
453217
453231
|
toJSON() {
|
|
453232
|
+
const state = this.getState();
|
|
453218
453233
|
return {
|
|
453219
453234
|
version: "1.0.0",
|
|
453220
|
-
state:
|
|
453235
|
+
state: {
|
|
453236
|
+
project: state.project,
|
|
453237
|
+
tracks: state.tracks,
|
|
453238
|
+
clips: state.clips,
|
|
453239
|
+
sources: state.sources,
|
|
453240
|
+
transitions: state.transitions
|
|
453241
|
+
}
|
|
453221
453242
|
};
|
|
453222
453243
|
}
|
|
453223
453244
|
static fromJSON(data) {
|
|
453224
453245
|
const project = new _Project();
|
|
453225
453246
|
data.state.project.createdAt = new Date(data.state.project.createdAt);
|
|
453226
453247
|
data.state.project.updatedAt = new Date(data.state.project.updatedAt);
|
|
453227
|
-
project.state =
|
|
453248
|
+
project.state = {
|
|
453249
|
+
...data.state,
|
|
453250
|
+
currentTime: 0,
|
|
453251
|
+
isPlaying: false,
|
|
453252
|
+
zoom: 50,
|
|
453253
|
+
scrollX: 0,
|
|
453254
|
+
selectedClipIds: [],
|
|
453255
|
+
selectedTrackId: null
|
|
453256
|
+
};
|
|
453228
453257
|
return project;
|
|
453229
453258
|
}
|
|
453230
453259
|
setFilePath(path14) {
|
|
@@ -453259,10 +453288,45 @@ var init_engine = __esm({
|
|
|
453259
453288
|
}
|
|
453260
453289
|
});
|
|
453261
453290
|
|
|
453291
|
+
// ../cli/src/utils/project-resolver.ts
|
|
453292
|
+
import { access as access5, stat as stat3 } from "node:fs/promises";
|
|
453293
|
+
import { resolve as resolve28 } from "node:path";
|
|
453294
|
+
async function resolveTimelineFile(inputPath, cwd = process.cwd()) {
|
|
453295
|
+
const filePath = resolve28(cwd, inputPath);
|
|
453296
|
+
try {
|
|
453297
|
+
const stats = await stat3(filePath);
|
|
453298
|
+
if (stats.isDirectory()) {
|
|
453299
|
+
const canonical = resolve28(filePath, TIMELINE_FILENAME);
|
|
453300
|
+
try {
|
|
453301
|
+
await access5(canonical);
|
|
453302
|
+
return canonical;
|
|
453303
|
+
} catch {
|
|
453304
|
+
}
|
|
453305
|
+
const legacy = resolve28(filePath, LEGACY_TIMELINE_FILENAME);
|
|
453306
|
+
try {
|
|
453307
|
+
await access5(legacy);
|
|
453308
|
+
return legacy;
|
|
453309
|
+
} catch {
|
|
453310
|
+
return canonical;
|
|
453311
|
+
}
|
|
453312
|
+
}
|
|
453313
|
+
} catch {
|
|
453314
|
+
}
|
|
453315
|
+
return filePath;
|
|
453316
|
+
}
|
|
453317
|
+
var TIMELINE_FILENAME, LEGACY_TIMELINE_FILENAME;
|
|
453318
|
+
var init_project_resolver = __esm({
|
|
453319
|
+
"../cli/src/utils/project-resolver.ts"() {
|
|
453320
|
+
"use strict";
|
|
453321
|
+
TIMELINE_FILENAME = "timeline.json";
|
|
453322
|
+
LEGACY_TIMELINE_FILENAME = "project.vibe.json";
|
|
453323
|
+
}
|
|
453324
|
+
});
|
|
453325
|
+
|
|
453262
453326
|
// ../cli/src/commands/_shared/execute-fill-gaps.ts
|
|
453263
453327
|
import { existsSync as existsSync40 } from "node:fs";
|
|
453264
453328
|
import { readFile as readFile16, writeFile as writeFile16, mkdir as mkdir14, rename as renameFs } from "node:fs/promises";
|
|
453265
|
-
import { resolve as
|
|
453329
|
+
import { resolve as resolve29, dirname as dirname20 } from "node:path";
|
|
453266
453330
|
function detectVideoGaps(videoClips, totalDuration) {
|
|
453267
453331
|
const gaps = [];
|
|
453268
453332
|
const sortedClips = [...videoClips].sort((a, b) => a.startTime - b.startTime);
|
|
@@ -453341,12 +453405,12 @@ async function executeFillGaps(options) {
|
|
|
453341
453405
|
});
|
|
453342
453406
|
const humanLines = [];
|
|
453343
453407
|
try {
|
|
453344
|
-
onProgress("Loading
|
|
453345
|
-
const filePath =
|
|
453408
|
+
onProgress("Loading timeline...");
|
|
453409
|
+
const filePath = await resolveTimelineFile(options.projectPath);
|
|
453346
453410
|
if (!existsSync40(filePath)) {
|
|
453347
453411
|
return {
|
|
453348
453412
|
success: false,
|
|
453349
|
-
error: `
|
|
453413
|
+
error: `Timeline file not found: ${filePath}`,
|
|
453350
453414
|
humanLines
|
|
453351
453415
|
};
|
|
453352
453416
|
}
|
|
@@ -453477,7 +453541,7 @@ async function executeFillGaps(options) {
|
|
|
453477
453541
|
};
|
|
453478
453542
|
}
|
|
453479
453543
|
const projectDir = dirname20(filePath);
|
|
453480
|
-
const footageDir = options.dir ?
|
|
453544
|
+
const footageDir = options.dir ? resolve29(process.cwd(), options.dir) : resolve29(projectDir, "footage");
|
|
453481
453545
|
if (!existsSync40(footageDir)) {
|
|
453482
453546
|
await mkdir14(footageDir, { recursive: true });
|
|
453483
453547
|
}
|
|
@@ -453509,7 +453573,7 @@ async function executeFillGaps(options) {
|
|
|
453509
453573
|
}
|
|
453510
453574
|
onProgress("Extracting frame from preceding clip...");
|
|
453511
453575
|
const frameOffset = clipBefore.sourceStartOffset + clipBefore.duration - 0.1;
|
|
453512
|
-
const framePath =
|
|
453576
|
+
const framePath = resolve29(footageDir, `frame-${gap.start.toFixed(2)}.png`);
|
|
453513
453577
|
try {
|
|
453514
453578
|
await execSafe("ffmpeg", [
|
|
453515
453579
|
"-i",
|
|
@@ -453570,7 +453634,7 @@ async function executeFillGaps(options) {
|
|
|
453570
453634
|
continue;
|
|
453571
453635
|
}
|
|
453572
453636
|
const videoFileName = `gap-fill-${gap.start.toFixed(2)}-${gap.end.toFixed(2)}.mp4`;
|
|
453573
|
-
const videoPath =
|
|
453637
|
+
const videoPath = resolve29(footageDir, videoFileName);
|
|
453574
453638
|
onProgress("Downloading generated video...");
|
|
453575
453639
|
const videoBuffer = await downloadVideo(finalResult.videoUrl);
|
|
453576
453640
|
await writeFile16(videoPath, videoBuffer);
|
|
@@ -453582,7 +453646,7 @@ async function executeFillGaps(options) {
|
|
|
453582
453646
|
const remainingNeeded = targetDuration - generatedDuration;
|
|
453583
453647
|
const segmentDuration = remainingNeeded > 5 ? "10" : "5";
|
|
453584
453648
|
onProgress(`Generating additional ${segmentDuration}s segment...`);
|
|
453585
|
-
const lastFramePath =
|
|
453649
|
+
const lastFramePath = resolve29(
|
|
453586
453650
|
footageDir,
|
|
453587
453651
|
`frame-extend-${gap.start.toFixed(2)}-${segmentIndex}.png`
|
|
453588
453652
|
);
|
|
@@ -453638,17 +453702,17 @@ async function executeFillGaps(options) {
|
|
|
453638
453702
|
);
|
|
453639
453703
|
break;
|
|
453640
453704
|
}
|
|
453641
|
-
const segVideoPath =
|
|
453705
|
+
const segVideoPath = resolve29(
|
|
453642
453706
|
footageDir,
|
|
453643
453707
|
`gap-fill-${gap.start.toFixed(2)}-${gap.end.toFixed(2)}-seg${segmentIndex}.mp4`
|
|
453644
453708
|
);
|
|
453645
453709
|
const segVideoBuffer = await downloadVideo(segFinalResult.videoUrl);
|
|
453646
453710
|
await writeFile16(segVideoPath, segVideoBuffer);
|
|
453647
|
-
const concatListPath =
|
|
453711
|
+
const concatListPath = resolve29(footageDir, `concat-${gap.start.toFixed(2)}.txt`);
|
|
453648
453712
|
const concatList = generatedVideos.map((v) => `file '${v}'`).join("\n") + `
|
|
453649
453713
|
file '${segVideoPath}'`;
|
|
453650
453714
|
await writeFile16(concatListPath, concatList);
|
|
453651
|
-
const concatOutputPath =
|
|
453715
|
+
const concatOutputPath = resolve29(
|
|
453652
453716
|
footageDir,
|
|
453653
453717
|
`gap-fill-${gap.start.toFixed(2)}-${gap.end.toFixed(2)}-merged.mp4`
|
|
453654
453718
|
);
|
|
@@ -453704,7 +453768,7 @@ file '${segVideoPath}'`;
|
|
|
453704
453768
|
humanLines.push("");
|
|
453705
453769
|
let outputPath = filePath;
|
|
453706
453770
|
if (generatedCount > 0) {
|
|
453707
|
-
outputPath = options.output ?
|
|
453771
|
+
outputPath = options.output ? resolve29(process.cwd(), options.output) : filePath;
|
|
453708
453772
|
await writeFile16(outputPath, JSON.stringify(project.toJSON(), null, 2));
|
|
453709
453773
|
humanLines.push(`\u2714 Filled ${generatedCount} gap(s) with AI-generated video`);
|
|
453710
453774
|
humanLines.push(`Project saved: ${outputPath}`);
|
|
@@ -453734,13 +453798,14 @@ var init_execute_fill_gaps = __esm({
|
|
|
453734
453798
|
init_engine();
|
|
453735
453799
|
init_api_key();
|
|
453736
453800
|
init_exec_safe();
|
|
453801
|
+
init_project_resolver();
|
|
453737
453802
|
init_ai_helpers();
|
|
453738
453803
|
}
|
|
453739
453804
|
});
|
|
453740
453805
|
|
|
453741
453806
|
// ../cli/src/commands/ai-fill-gaps.ts
|
|
453742
453807
|
function registerFillGapsCommand(aiCommand) {
|
|
453743
|
-
aiCommand.command("fill-gaps").description("Fill timeline gaps with AI-generated video (Kling image-to-video)").argument("<project>", "
|
|
453808
|
+
aiCommand.command("fill-gaps").description("Fill timeline gaps with AI-generated video (Kling image-to-video)").argument("<project>", "Timeline file or directory").option("-p, --provider <provider>", "AI provider (kling)", "kling").option("-o, --output <path>", "Output project path (default: overwrite)").option("-d, --dir <path>", "Directory to save generated videos").option("--prompt <text>", "Custom prompt for video generation").option("--dry-run", "Show gaps without generating").option("--mode <mode>", "Generation mode: std or pro (Kling)", "std").option("-r, --ratio <ratio>", "Aspect ratio: 16:9, 9:16, or 1:1", "16:9").action(async (projectPath, options) => {
|
|
453744
453809
|
try {
|
|
453745
453810
|
if (options.output) {
|
|
453746
453811
|
validateOutputPath(options.output);
|
|
@@ -453800,14 +453865,14 @@ __export(edit_cmd_exports, {
|
|
|
453800
453865
|
executeSpeedRamp: () => executeSpeedRamp,
|
|
453801
453866
|
executeUpscale: () => executeUpscale
|
|
453802
453867
|
});
|
|
453803
|
-
import { resolve as
|
|
453868
|
+
import { resolve as resolve30, dirname as dirname21 } from "node:path";
|
|
453804
453869
|
import { readFile as readFile17, writeFile as writeFile17, mkdir as mkdir15 } from "node:fs/promises";
|
|
453805
453870
|
async function executeGrade(options) {
|
|
453806
453871
|
const { videoPath, style, preset, output: output3, analyzeOnly, apiKey } = options;
|
|
453807
453872
|
try {
|
|
453808
453873
|
if (!style && !preset) return { success: false, error: "Either style or preset is required" };
|
|
453809
453874
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
453810
|
-
const absPath =
|
|
453875
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453811
453876
|
let gradeResult;
|
|
453812
453877
|
if (preset) {
|
|
453813
453878
|
const claude = new ClaudeProvider();
|
|
@@ -453822,7 +453887,7 @@ async function executeGrade(options) {
|
|
|
453822
453887
|
if (analyzeOnly) {
|
|
453823
453888
|
return { success: true, style: preset || style, description: gradeResult.description, ffmpegFilter: gradeResult.ffmpegFilter };
|
|
453824
453889
|
}
|
|
453825
|
-
const outputPath = output3 ?
|
|
453890
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, "-graded$1");
|
|
453826
453891
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", gradeResult.ffmpegFilter, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
453827
453892
|
return { success: true, outputPath, style: preset || style, description: gradeResult.description, ffmpegFilter: gradeResult.ffmpegFilter };
|
|
453828
453893
|
} catch (error) {
|
|
@@ -453837,7 +453902,7 @@ async function executeSpeedRamp(options) {
|
|
|
453837
453902
|
const claudeKey = apiKey || process.env.ANTHROPIC_API_KEY;
|
|
453838
453903
|
if (!openaiKey) return { success: false, error: "OPENAI_API_KEY required for Whisper transcription" };
|
|
453839
453904
|
if (!claudeKey) return { success: false, error: "ANTHROPIC_API_KEY required for Claude analysis" };
|
|
453840
|
-
const absPath =
|
|
453905
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453841
453906
|
const tempAudio = absPath.replace(/(\.[^.]+)$/, "-temp-audio.mp3");
|
|
453842
453907
|
await execSafe("ffmpeg", ["-i", absPath, "-vn", "-acodec", "libmp3lame", "-q:a", "2", tempAudio, "-y"]);
|
|
453843
453908
|
const whisper = new WhisperProvider();
|
|
@@ -453862,7 +453927,7 @@ async function executeSpeedRamp(options) {
|
|
|
453862
453927
|
if (speedResult.keyframes.length < 2) {
|
|
453863
453928
|
return { success: false, error: "Not enough keyframes for speed ramping" };
|
|
453864
453929
|
}
|
|
453865
|
-
const outputPath = output3 ?
|
|
453930
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, "-ramped$1");
|
|
453866
453931
|
const setpts = `setpts=${(1 / avgSpeed).toFixed(3)}*PTS`;
|
|
453867
453932
|
const atempo = avgSpeed >= 0.5 && avgSpeed <= 2 ? `atempo=${avgSpeed.toFixed(3)}` : "";
|
|
453868
453933
|
if (atempo) {
|
|
@@ -453879,7 +453944,7 @@ async function executeReframe(options) {
|
|
|
453879
453944
|
const { videoPath, aspect = "9:16", output: output3, analyzeOnly } = options;
|
|
453880
453945
|
try {
|
|
453881
453946
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
453882
|
-
const absPath =
|
|
453947
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453883
453948
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
453884
453949
|
"-v",
|
|
453885
453950
|
"error",
|
|
@@ -453914,7 +453979,7 @@ async function executeReframe(options) {
|
|
|
453914
453979
|
keyframeCount: 1
|
|
453915
453980
|
};
|
|
453916
453981
|
}
|
|
453917
|
-
const outputPath = output3 ?
|
|
453982
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, `-${aspect.replace(":", "x")}$1`);
|
|
453918
453983
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", `crop=${cropWidth}:${cropHeight}:${cropX}:${cropY}`, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
453919
453984
|
return { success: true, outputPath, sourceAspect: `${sourceWidth}:${sourceHeight}`, targetAspect: aspect };
|
|
453920
453985
|
} catch (error) {
|
|
@@ -453926,7 +453991,7 @@ async function executeInterpolate(options) {
|
|
|
453926
453991
|
try {
|
|
453927
453992
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
453928
453993
|
if (![2, 4, 8].includes(factor)) return { success: false, error: "Factor must be 2, 4, or 8" };
|
|
453929
|
-
const absPath =
|
|
453994
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453930
453995
|
const { stdout: fpsOut } = await execSafe("ffprobe", [
|
|
453931
453996
|
"-v",
|
|
453932
453997
|
"error",
|
|
@@ -453942,7 +454007,7 @@ async function executeInterpolate(options) {
|
|
|
453942
454007
|
const originalFps = num / (den || 1);
|
|
453943
454008
|
const targetFps = options.fps || originalFps * factor;
|
|
453944
454009
|
const mi = quality === "fast" ? "mi_mode=mci" : "mi_mode=mci:mc_mode=aobmc:me_mode=bidir:vsbmc=1";
|
|
453945
|
-
const outputPath = output3 ?
|
|
454010
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, `-slow${factor}x$1`);
|
|
453946
454011
|
await execSafe("ffmpeg", ["-i", absPath, "-filter:v", `minterpolate='${mi}:fps=${targetFps}',setpts=${factor}*PTS`, "-an", outputPath, "-y"], { timeout: 6e5 });
|
|
453947
454012
|
return { success: true, outputPath, originalFps, targetFps, factor };
|
|
453948
454013
|
} catch (error) {
|
|
@@ -453953,7 +454018,7 @@ async function executeUpscale(options) {
|
|
|
453953
454018
|
const { videoPath, output: output3, scale = 2, quality = "quality" } = options;
|
|
453954
454019
|
try {
|
|
453955
454020
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
453956
|
-
const absPath =
|
|
454021
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453957
454022
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
453958
454023
|
"-v",
|
|
453959
454024
|
"error",
|
|
@@ -453969,7 +454034,7 @@ async function executeUpscale(options) {
|
|
|
453969
454034
|
const targetW = w * scale;
|
|
453970
454035
|
const targetH = h * scale;
|
|
453971
454036
|
const scaleFilter = quality === "quality" ? `scale=${targetW}:${targetH}:flags=lanczos` : `scale=${targetW}:${targetH}`;
|
|
453972
|
-
const outputPath = output3 ?
|
|
454037
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, `-${scale}x$1`);
|
|
453973
454038
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", scaleFilter, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
453974
454039
|
return { success: true, outputPath, originalRes: `${w}x${h}`, targetRes: `${targetW}x${targetH}` };
|
|
453975
454040
|
} catch (error) {
|
|
@@ -454041,7 +454106,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454041
454106
|
dryRun: true,
|
|
454042
454107
|
data: {
|
|
454043
454108
|
params: {
|
|
454044
|
-
videoPath:
|
|
454109
|
+
videoPath: resolve30(process.cwd(), videoPath),
|
|
454045
454110
|
style: options.style || options.preset,
|
|
454046
454111
|
analyzeOnly: options.analyzeOnly || false
|
|
454047
454112
|
}
|
|
@@ -454068,8 +454133,8 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454068
454133
|
}
|
|
454069
454134
|
spinner2.succeed(source_default.green("Color grade analyzed"));
|
|
454070
454135
|
if (isJsonMode()) {
|
|
454071
|
-
const absPath2 =
|
|
454072
|
-
const gradeOutputPath = options.output ?
|
|
454136
|
+
const absPath2 = resolve30(process.cwd(), videoPath);
|
|
454137
|
+
const gradeOutputPath = options.output ? resolve30(process.cwd(), options.output) : absPath2.replace(/(\.[^.]+)$/, "-graded$1");
|
|
454073
454138
|
outputSuccess({
|
|
454074
454139
|
command: "edit grade",
|
|
454075
454140
|
startedAt,
|
|
@@ -454095,8 +454160,8 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454095
454160
|
console.log(source_default.dim("Use without --analyze-only to apply the grade."));
|
|
454096
454161
|
return;
|
|
454097
454162
|
}
|
|
454098
|
-
const absPath =
|
|
454099
|
-
const outputPath = options.output ?
|
|
454163
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454164
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, "-graded$1");
|
|
454100
454165
|
spinner2.start("Applying color grade...");
|
|
454101
454166
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", gradeResult.ffmpegFilter, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
454102
454167
|
spinner2.succeed(source_default.green("Color grade applied"));
|
|
@@ -454126,7 +454191,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454126
454191
|
dryRun: true,
|
|
454127
454192
|
data: {
|
|
454128
454193
|
params: {
|
|
454129
|
-
videoPath:
|
|
454194
|
+
videoPath: resolve30(process.cwd(), videoPath),
|
|
454130
454195
|
texts: options.text,
|
|
454131
454196
|
style: options.style,
|
|
454132
454197
|
fontSize: options.fontSize ? parseInt(options.fontSize) : void 0,
|
|
@@ -454139,8 +454204,8 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454139
454204
|
});
|
|
454140
454205
|
return;
|
|
454141
454206
|
}
|
|
454142
|
-
const absPath =
|
|
454143
|
-
const outputPath = options.output ?
|
|
454207
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454208
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, "-overlay$1");
|
|
454144
454209
|
const spinner2 = ora("Applying text overlays...").start();
|
|
454145
454210
|
const result = await applyTextOverlays({
|
|
454146
454211
|
videoPath: absPath,
|
|
@@ -454198,7 +454263,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454198
454263
|
dryRun: true,
|
|
454199
454264
|
data: {
|
|
454200
454265
|
params: {
|
|
454201
|
-
videoPath:
|
|
454266
|
+
videoPath: resolve30(process.cwd(), videoPath),
|
|
454202
454267
|
style: options.style,
|
|
454203
454268
|
minSpeed: parseFloat(options.minSpeed),
|
|
454204
454269
|
maxSpeed: parseFloat(options.maxSpeed),
|
|
@@ -454210,7 +454275,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454210
454275
|
}
|
|
454211
454276
|
const openaiApiKey = await requireApiKey("OPENAI_API_KEY", "OpenAI");
|
|
454212
454277
|
const claudeApiKey = await requireApiKey("ANTHROPIC_API_KEY", "Anthropic", options.apiKey);
|
|
454213
|
-
const absPath =
|
|
454278
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454214
454279
|
const spinner2 = ora("Extracting audio...").start();
|
|
454215
454280
|
const { stdout: speedRampProbe } = await execSafe("ffprobe", [
|
|
454216
454281
|
"-v",
|
|
@@ -454255,7 +454320,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454255
454320
|
spinner2.succeed(source_default.green(`Found ${speedResult.keyframes.length} speed keyframes`));
|
|
454256
454321
|
if (isJsonMode()) {
|
|
454257
454322
|
const avgSpeed2 = speedResult.keyframes.reduce((sum, kf) => sum + kf.speed, 0) / speedResult.keyframes.length;
|
|
454258
|
-
const speedRampOutputPath = options.output ?
|
|
454323
|
+
const speedRampOutputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, "-ramped$1");
|
|
454259
454324
|
outputSuccess({
|
|
454260
454325
|
command: "edit speed-ramp",
|
|
454261
454326
|
startedAt,
|
|
@@ -454284,7 +454349,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454284
454349
|
return;
|
|
454285
454350
|
}
|
|
454286
454351
|
spinner2.start("Applying speed ramps...");
|
|
454287
|
-
const outputPath = options.output ?
|
|
454352
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, "-ramped$1");
|
|
454288
454353
|
const avgSpeed = speedResult.keyframes.reduce((sum, kf) => sum + kf.speed, 0) / speedResult.keyframes.length;
|
|
454289
454354
|
const setpts = `setpts=${(1 / avgSpeed).toFixed(3)}*PTS`;
|
|
454290
454355
|
const atempo = avgSpeed >= 0.5 && avgSpeed <= 2 ? `atempo=${avgSpeed.toFixed(3)}` : "";
|
|
@@ -454318,7 +454383,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454318
454383
|
dryRun: true,
|
|
454319
454384
|
data: {
|
|
454320
454385
|
params: {
|
|
454321
|
-
videoPath:
|
|
454386
|
+
videoPath: resolve30(process.cwd(), videoPath),
|
|
454322
454387
|
aspect: options.aspect,
|
|
454323
454388
|
focus: options.focus,
|
|
454324
454389
|
analyzeOnly: options.analyzeOnly || false
|
|
@@ -454327,7 +454392,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454327
454392
|
});
|
|
454328
454393
|
return;
|
|
454329
454394
|
}
|
|
454330
|
-
const absPath =
|
|
454395
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454331
454396
|
const spinner2 = ora("Analyzing video...").start();
|
|
454332
454397
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
454333
454398
|
"-v",
|
|
@@ -454389,7 +454454,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454389
454454
|
}
|
|
454390
454455
|
spinner2.succeed(source_default.green(`Analyzed ${cropKeyframes.length} keyframes`));
|
|
454391
454456
|
if (isJsonMode()) {
|
|
454392
|
-
const reframeOutputPath = options.output ?
|
|
454457
|
+
const reframeOutputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, `-${options.aspect.replace(":", "x")}$1`);
|
|
454393
454458
|
outputSuccess({
|
|
454394
454459
|
command: "edit reframe",
|
|
454395
454460
|
startedAt,
|
|
@@ -454424,7 +454489,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454424
454489
|
}
|
|
454425
454490
|
console.log();
|
|
454426
454491
|
if (options.keyframes) {
|
|
454427
|
-
const keyframesPath =
|
|
454492
|
+
const keyframesPath = resolve30(process.cwd(), options.keyframes);
|
|
454428
454493
|
await writeFile17(keyframesPath, JSON.stringify(cropKeyframes, null, 2));
|
|
454429
454494
|
console.log(source_default.green(`Keyframes saved to: ${keyframesPath}`));
|
|
454430
454495
|
}
|
|
@@ -454436,7 +454501,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454436
454501
|
const avgCropY = Math.round(cropKeyframes.reduce((sum, kf) => sum + kf.cropY, 0) / cropKeyframes.length);
|
|
454437
454502
|
const cropWidth = cropKeyframes[0]?.cropWidth || sourceWidth;
|
|
454438
454503
|
const cropHeight = cropKeyframes[0]?.cropHeight || sourceHeight;
|
|
454439
|
-
const outputPath = options.output ?
|
|
454504
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, `-${options.aspect.replace(":", "x")}$1`);
|
|
454440
454505
|
spinner2.start("Applying reframe...");
|
|
454441
454506
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", `crop=${cropWidth}:${cropHeight}:${avgCropX}:${avgCropY}`, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
454442
454507
|
spinner2.succeed(source_default.green("Reframe applied"));
|
|
@@ -454472,7 +454537,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454472
454537
|
dryRun: true,
|
|
454473
454538
|
data: {
|
|
454474
454539
|
params: {
|
|
454475
|
-
imagePaths: imagePaths.map((p) =>
|
|
454540
|
+
imagePaths: imagePaths.map((p) => resolve30(process.cwd(), p)),
|
|
454476
454541
|
prompt: prompt3,
|
|
454477
454542
|
provider,
|
|
454478
454543
|
model: options.model,
|
|
@@ -454493,7 +454558,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454493
454558
|
const spinner2 = ora(`Reading ${imagePaths.length} image(s)...`).start();
|
|
454494
454559
|
const imageBuffers = [];
|
|
454495
454560
|
for (const imagePath of imagePaths) {
|
|
454496
|
-
const absPath =
|
|
454561
|
+
const absPath = resolve30(process.cwd(), imagePath);
|
|
454497
454562
|
const buffer = await readFile17(absPath);
|
|
454498
454563
|
imageBuffers.push(buffer);
|
|
454499
454564
|
}
|
|
@@ -454542,7 +454607,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454542
454607
|
}
|
|
454543
454608
|
spinner2.succeed(source_default.green("Image edited"));
|
|
454544
454609
|
const img = result.images[0];
|
|
454545
|
-
const outputPath =
|
|
454610
|
+
const outputPath = resolve30(process.cwd(), options.output);
|
|
454546
454611
|
const saveImage = async () => {
|
|
454547
454612
|
await mkdir15(dirname21(outputPath), { recursive: true });
|
|
454548
454613
|
if (img.base64) {
|
|
@@ -454584,7 +454649,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454584
454649
|
if (options.output) {
|
|
454585
454650
|
validateOutputPath(options.output);
|
|
454586
454651
|
}
|
|
454587
|
-
const absPath =
|
|
454652
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454588
454653
|
const factor = parseInt(options.factor);
|
|
454589
454654
|
if (![2, 4, 8].includes(factor)) {
|
|
454590
454655
|
exitWithError(usageError("Factor must be 2, 4, or 8"));
|
|
@@ -454605,7 +454670,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454605
454670
|
});
|
|
454606
454671
|
return;
|
|
454607
454672
|
}
|
|
454608
|
-
const outputPath = options.output ?
|
|
454673
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, `-slow${factor}x$1`);
|
|
454609
454674
|
const spinner2 = ora(`Creating ${factor}x slow motion...`).start();
|
|
454610
454675
|
try {
|
|
454611
454676
|
const { stdout: fpsOut } = await execSafe("ffprobe", [
|
|
@@ -454666,7 +454731,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454666
454731
|
if (options.output) {
|
|
454667
454732
|
validateOutputPath(options.output);
|
|
454668
454733
|
}
|
|
454669
|
-
const absPath =
|
|
454734
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454670
454735
|
const scale = parseInt(options.scale);
|
|
454671
454736
|
if (scale !== 2 && scale !== 4) {
|
|
454672
454737
|
exitWithError(usageError("Scale must be 2 or 4"));
|
|
@@ -454688,7 +454753,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454688
454753
|
return;
|
|
454689
454754
|
}
|
|
454690
454755
|
if (options.ffmpeg) {
|
|
454691
|
-
const outputPath = options.output ?
|
|
454756
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, `-upscaled-${scale}x$1`);
|
|
454692
454757
|
const spinner3 = ora(`Upscaling video with FFmpeg (${scale}x)...`).start();
|
|
454693
454758
|
try {
|
|
454694
454759
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
@@ -454749,7 +454814,7 @@ __export(ai_image_exports, {
|
|
|
454749
454814
|
executeImageGenerate: () => executeImageGenerate,
|
|
454750
454815
|
executeThumbnailBestFrame: () => executeThumbnailBestFrame
|
|
454751
454816
|
});
|
|
454752
|
-
import { resolve as
|
|
454817
|
+
import { resolve as resolve33, dirname as dirname24 } from "node:path";
|
|
454753
454818
|
import { readFile as readFile18, writeFile as writeFile19, mkdir as mkdir17 } from "node:fs/promises";
|
|
454754
454819
|
import { existsSync as existsSync42 } from "node:fs";
|
|
454755
454820
|
async function executeImageGenerate(options) {
|
|
@@ -454792,7 +454857,7 @@ async function executeImageGenerate(options) {
|
|
|
454792
454857
|
} else {
|
|
454793
454858
|
return { success: false, error: "No image data available" };
|
|
454794
454859
|
}
|
|
454795
|
-
outputPath =
|
|
454860
|
+
outputPath = resolve33(process.cwd(), output3);
|
|
454796
454861
|
await mkdir17(dirname24(outputPath), { recursive: true });
|
|
454797
454862
|
await writeFile19(outputPath, buffer);
|
|
454798
454863
|
}
|
|
@@ -454827,7 +454892,7 @@ async function executeImageGenerate(options) {
|
|
|
454827
454892
|
if (output3 && result.images.length > 0) {
|
|
454828
454893
|
const img = result.images[0];
|
|
454829
454894
|
if (img.base64) {
|
|
454830
|
-
outputPath =
|
|
454895
|
+
outputPath = resolve33(process.cwd(), output3);
|
|
454831
454896
|
await mkdir17(dirname24(outputPath), { recursive: true });
|
|
454832
454897
|
await writeFile19(outputPath, Buffer.from(img.base64, "base64"));
|
|
454833
454898
|
}
|
|
@@ -454863,7 +454928,7 @@ async function executeImageGenerate(options) {
|
|
|
454863
454928
|
} else {
|
|
454864
454929
|
return { success: false, error: "No image data available" };
|
|
454865
454930
|
}
|
|
454866
|
-
outputPath =
|
|
454931
|
+
outputPath = resolve33(process.cwd(), output3);
|
|
454867
454932
|
await mkdir17(dirname24(outputPath), { recursive: true });
|
|
454868
454933
|
await writeFile19(outputPath, buffer);
|
|
454869
454934
|
}
|
|
@@ -454894,7 +454959,7 @@ async function executeGeminiEdit(options) {
|
|
|
454894
454959
|
if (!key2) return { success: false, error: "GOOGLE_API_KEY required" };
|
|
454895
454960
|
const imageBuffers = [];
|
|
454896
454961
|
for (const imagePath of imagePaths) {
|
|
454897
|
-
const absPath =
|
|
454962
|
+
const absPath = resolve33(process.cwd(), imagePath);
|
|
454898
454963
|
if (!existsSync42(absPath)) {
|
|
454899
454964
|
return { success: false, error: `Image not found: ${absPath}` };
|
|
454900
454965
|
}
|
|
@@ -454922,7 +454987,7 @@ async function executeGeminiEdit(options) {
|
|
|
454922
454987
|
const img = result.images[0];
|
|
454923
454988
|
let outputPath;
|
|
454924
454989
|
if (img.base64) {
|
|
454925
|
-
outputPath =
|
|
454990
|
+
outputPath = resolve33(process.cwd(), output3);
|
|
454926
454991
|
await mkdir17(dirname24(outputPath), { recursive: true });
|
|
454927
454992
|
await writeFile19(outputPath, Buffer.from(img.base64, "base64"));
|
|
454928
454993
|
}
|
|
@@ -455015,7 +455080,7 @@ __export(ai_analyze_exports, {
|
|
|
455015
455080
|
registerAnalyzeCommands: () => registerAnalyzeCommands
|
|
455016
455081
|
});
|
|
455017
455082
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
455018
|
-
import { extname as extname8, resolve as
|
|
455083
|
+
import { extname as extname8, resolve as resolve34 } from "node:path";
|
|
455019
455084
|
import { existsSync as existsSync43 } from "node:fs";
|
|
455020
455085
|
async function executeGeminiVideo(options) {
|
|
455021
455086
|
try {
|
|
@@ -455034,7 +455099,7 @@ async function executeGeminiVideo(options) {
|
|
|
455034
455099
|
if (isYouTube) {
|
|
455035
455100
|
videoData = options.source;
|
|
455036
455101
|
} else {
|
|
455037
|
-
const absPath =
|
|
455102
|
+
const absPath = resolve34(process.cwd(), options.source);
|
|
455038
455103
|
if (!existsSync43(absPath)) {
|
|
455039
455104
|
return { success: false, error: `File not found: ${absPath}` };
|
|
455040
455105
|
}
|
|
@@ -455107,7 +455172,7 @@ async function executeAnalyze(options) {
|
|
|
455107
455172
|
}
|
|
455108
455173
|
imageBuffer = Buffer.from(await response.arrayBuffer());
|
|
455109
455174
|
} else {
|
|
455110
|
-
const absPath =
|
|
455175
|
+
const absPath = resolve34(process.cwd(), source3);
|
|
455111
455176
|
if (!existsSync43(absPath)) {
|
|
455112
455177
|
return { success: false, error: `File not found: ${absPath}` };
|
|
455113
455178
|
}
|
|
@@ -455142,7 +455207,7 @@ async function executeAnalyze(options) {
|
|
|
455142
455207
|
}
|
|
455143
455208
|
videoData = Buffer.from(await response.arrayBuffer());
|
|
455144
455209
|
} else {
|
|
455145
|
-
const absPath =
|
|
455210
|
+
const absPath = resolve34(process.cwd(), source3);
|
|
455146
455211
|
if (!existsSync43(absPath)) {
|
|
455147
455212
|
return { success: false, error: `File not found: ${absPath}` };
|
|
455148
455213
|
}
|
|
@@ -455281,7 +455346,7 @@ __export(ai_review_exports, {
|
|
|
455281
455346
|
registerReviewCommand: () => registerReviewCommand
|
|
455282
455347
|
});
|
|
455283
455348
|
import { readFile as readFile20, rename as rename4 } from "node:fs/promises";
|
|
455284
|
-
import { resolve as
|
|
455349
|
+
import { resolve as resolve35 } from "node:path";
|
|
455285
455350
|
import { existsSync as existsSync44 } from "node:fs";
|
|
455286
455351
|
function parseReviewFeedback(response) {
|
|
455287
455352
|
let cleaned = response.trim();
|
|
@@ -455306,7 +455371,7 @@ function parseReviewFeedback(response) {
|
|
|
455306
455371
|
}
|
|
455307
455372
|
async function executeReview(options) {
|
|
455308
455373
|
const { videoPath, storyboardPath, autoApply = false, verify = false, model = "flash" } = options;
|
|
455309
|
-
const absVideoPath =
|
|
455374
|
+
const absVideoPath = resolve35(process.cwd(), videoPath);
|
|
455310
455375
|
if (!existsSync44(absVideoPath)) {
|
|
455311
455376
|
return { success: false, error: `Video not found: ${absVideoPath}` };
|
|
455312
455377
|
}
|
|
@@ -455316,7 +455381,7 @@ async function executeReview(options) {
|
|
|
455316
455381
|
}
|
|
455317
455382
|
let storyboardContext = "";
|
|
455318
455383
|
if (storyboardPath) {
|
|
455319
|
-
const absStoryboardPath =
|
|
455384
|
+
const absStoryboardPath = resolve35(process.cwd(), storyboardPath);
|
|
455320
455385
|
if (existsSync44(absStoryboardPath)) {
|
|
455321
455386
|
const content = await readFile20(absStoryboardPath, "utf-8");
|
|
455322
455387
|
storyboardContext = `
|
|
@@ -455372,7 +455437,7 @@ Score each category 1-10. For fixable issues, provide an FFmpeg filter in autoFi
|
|
|
455372
455437
|
};
|
|
455373
455438
|
if (autoApply && feedback.autoFixable.length > 0) {
|
|
455374
455439
|
let currentInput = absVideoPath;
|
|
455375
|
-
const outputBase = options.outputPath ?
|
|
455440
|
+
const outputBase = options.outputPath ? resolve35(process.cwd(), options.outputPath) : absVideoPath.replace(/(\.[^.]+)$/, "-reviewed$1");
|
|
455376
455441
|
for (const fix of feedback.autoFixable) {
|
|
455377
455442
|
if (fix.type === "color_grade" && fix.ffmpegFilter) {
|
|
455378
455443
|
try {
|
|
@@ -455526,7 +455591,7 @@ __export(ai_motion_exports, {
|
|
|
455526
455591
|
executeMotion: () => executeMotion,
|
|
455527
455592
|
registerMotionCommand: () => registerMotionCommand
|
|
455528
455593
|
});
|
|
455529
|
-
import { resolve as
|
|
455594
|
+
import { resolve as resolve37 } from "node:path";
|
|
455530
455595
|
import { existsSync as existsSync45 } from "node:fs";
|
|
455531
455596
|
import { readFile as readFile22, writeFile as writeFile21 } from "node:fs/promises";
|
|
455532
455597
|
async function executeMotion(options) {
|
|
@@ -455551,7 +455616,7 @@ async function executeMotion(options) {
|
|
|
455551
455616
|
if (!geminiApiKey) {
|
|
455552
455617
|
return { success: false, error: "GOOGLE_API_KEY required for image analysis (--image). Run 'vibe setup' or set GOOGLE_API_KEY in .env" };
|
|
455553
455618
|
}
|
|
455554
|
-
const imagePath =
|
|
455619
|
+
const imagePath = resolve37(process.cwd(), options.image);
|
|
455555
455620
|
const imageBuffer = await readFile22(imagePath);
|
|
455556
455621
|
const gemini = new GeminiProvider();
|
|
455557
455622
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
@@ -455574,7 +455639,7 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
455574
455639
|
}
|
|
455575
455640
|
let result;
|
|
455576
455641
|
if (options.fromTsx) {
|
|
455577
|
-
const tsxPath =
|
|
455642
|
+
const tsxPath = resolve37(process.cwd(), options.fromTsx);
|
|
455578
455643
|
if (!existsSync45(tsxPath)) {
|
|
455579
455644
|
return { success: false, error: `TSX file not found: ${tsxPath}` };
|
|
455580
455645
|
}
|
|
@@ -455628,7 +455693,7 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
455628
455693
|
}
|
|
455629
455694
|
const { component } = result;
|
|
455630
455695
|
const defaultOutput = options.video || options.image ? "motion-output.mp4" : options.render ? "motion.webm" : "motion.tsx";
|
|
455631
|
-
const outputPath =
|
|
455696
|
+
const outputPath = resolve37(process.cwd(), options.output || defaultOutput);
|
|
455632
455697
|
const codePath = outputPath.replace(/\.\w+$/, ".tsx");
|
|
455633
455698
|
await writeFile21(codePath, component.code, "utf-8");
|
|
455634
455699
|
const shouldRender = options.render || !!options.video || !!options.image;
|
|
@@ -455647,8 +455712,8 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
455647
455712
|
if (notInstalled) {
|
|
455648
455713
|
return { success: false, codePath, componentName: component.name, error: notInstalled };
|
|
455649
455714
|
}
|
|
455650
|
-
const baseVideo = options.video ?
|
|
455651
|
-
const baseImage = options.image ?
|
|
455715
|
+
const baseVideo = options.video ? resolve37(process.cwd(), options.video) : void 0;
|
|
455716
|
+
const baseImage = options.image ? resolve37(process.cwd(), options.image) : void 0;
|
|
455652
455717
|
if (baseVideo) {
|
|
455653
455718
|
const videoFileName = "source_video.mp4";
|
|
455654
455719
|
const wrapped = wrapComponentWithVideo2(component.code, component.name, videoFileName);
|
|
@@ -455833,7 +455898,7 @@ var init_ai_motion = __esm({
|
|
|
455833
455898
|
});
|
|
455834
455899
|
|
|
455835
455900
|
// ../cli/src/commands/generate/sound-effect.ts
|
|
455836
|
-
import { resolve as
|
|
455901
|
+
import { resolve as resolve38 } from "node:path";
|
|
455837
455902
|
import { writeFile as writeFile22 } from "node:fs/promises";
|
|
455838
455903
|
async function executeSoundEffect(options) {
|
|
455839
455904
|
try {
|
|
@@ -455855,7 +455920,7 @@ async function executeSoundEffect(options) {
|
|
|
455855
455920
|
error: result.error || "Sound effect generation failed"
|
|
455856
455921
|
};
|
|
455857
455922
|
}
|
|
455858
|
-
const outputPath =
|
|
455923
|
+
const outputPath = resolve38(
|
|
455859
455924
|
process.cwd(),
|
|
455860
455925
|
options.output || "sound-effect.mp3"
|
|
455861
455926
|
);
|
|
@@ -455910,7 +455975,7 @@ function registerSoundEffectCommand(parent) {
|
|
|
455910
455975
|
apiError(result.error || "Sound effect generation failed", true)
|
|
455911
455976
|
);
|
|
455912
455977
|
}
|
|
455913
|
-
const outputPath =
|
|
455978
|
+
const outputPath = resolve38(process.cwd(), options.output);
|
|
455914
455979
|
await writeFile22(outputPath, result.audioBuffer);
|
|
455915
455980
|
spinner2.succeed(source_default.green("Sound effect generated"));
|
|
455916
455981
|
if (isJsonMode()) {
|
|
@@ -456095,7 +456160,7 @@ var init_video_cancel = __esm({
|
|
|
456095
456160
|
});
|
|
456096
456161
|
|
|
456097
456162
|
// ../cli/src/commands/generate/background.ts
|
|
456098
|
-
import { resolve as
|
|
456163
|
+
import { resolve as resolve39, dirname as dirname25 } from "node:path";
|
|
456099
456164
|
import { writeFile as writeFile23, mkdir as mkdir18 } from "node:fs/promises";
|
|
456100
456165
|
async function executeBackground(options) {
|
|
456101
456166
|
try {
|
|
@@ -456120,7 +456185,7 @@ async function executeBackground(options) {
|
|
|
456120
456185
|
} else {
|
|
456121
456186
|
return { success: false, error: "Provider returned no image data" };
|
|
456122
456187
|
}
|
|
456123
|
-
outputPath =
|
|
456188
|
+
outputPath = resolve39(process.cwd(), options.output);
|
|
456124
456189
|
await mkdir18(dirname25(outputPath), { recursive: true });
|
|
456125
456190
|
await writeFile23(outputPath, buffer);
|
|
456126
456191
|
}
|
|
@@ -456182,7 +456247,7 @@ function registerBackgroundCommand(parent) {
|
|
|
456182
456247
|
} else {
|
|
456183
456248
|
throw new Error("No image data available");
|
|
456184
456249
|
}
|
|
456185
|
-
outputPath =
|
|
456250
|
+
outputPath = resolve39(process.cwd(), options.output);
|
|
456186
456251
|
await mkdir18(dirname25(outputPath), { recursive: true });
|
|
456187
456252
|
await writeFile23(outputPath, buffer);
|
|
456188
456253
|
}
|
|
@@ -456213,7 +456278,7 @@ function registerBackgroundCommand(parent) {
|
|
|
456213
456278
|
} else {
|
|
456214
456279
|
throw new Error("No image data available");
|
|
456215
456280
|
}
|
|
456216
|
-
const outputPath =
|
|
456281
|
+
const outputPath = resolve39(process.cwd(), options.output);
|
|
456217
456282
|
await mkdir18(dirname25(outputPath), { recursive: true });
|
|
456218
456283
|
await writeFile23(outputPath, buffer);
|
|
456219
456284
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -456255,7 +456320,7 @@ var init_sanitize = __esm({
|
|
|
456255
456320
|
});
|
|
456256
456321
|
|
|
456257
456322
|
// ../cli/src/commands/generate/storyboard.ts
|
|
456258
|
-
import { resolve as
|
|
456323
|
+
import { resolve as resolve40 } from "node:path";
|
|
456259
456324
|
import { readFile as readFile23, writeFile as writeFile24 } from "node:fs/promises";
|
|
456260
456325
|
async function executeStoryboard(options) {
|
|
456261
456326
|
const { content, duration, creativity = "low", output: output3, apiKey } = options;
|
|
@@ -456274,7 +456339,7 @@ async function executeStoryboard(options) {
|
|
|
456274
456339
|
}
|
|
456275
456340
|
let outputPath;
|
|
456276
456341
|
if (output3) {
|
|
456277
|
-
outputPath =
|
|
456342
|
+
outputPath = resolve40(process.cwd(), output3);
|
|
456278
456343
|
await writeFile24(outputPath, JSON.stringify(segments, null, 2), "utf-8");
|
|
456279
456344
|
}
|
|
456280
456345
|
return { success: true, segments, segmentCount: segments.length, outputPath };
|
|
@@ -456299,7 +456364,7 @@ function registerStoryboardCommand(parent) {
|
|
|
456299
456364
|
}
|
|
456300
456365
|
let textContent2 = content;
|
|
456301
456366
|
if (options.file) {
|
|
456302
|
-
const filePath =
|
|
456367
|
+
const filePath = resolve40(process.cwd(), content);
|
|
456303
456368
|
textContent2 = await readFile23(filePath, "utf-8");
|
|
456304
456369
|
}
|
|
456305
456370
|
if (options.dryRun) {
|
|
@@ -456341,7 +456406,7 @@ function registerStoryboardCommand(parent) {
|
|
|
456341
456406
|
if (seg.visuals) seg.visuals = sanitizeLLMResponse(seg.visuals);
|
|
456342
456407
|
}
|
|
456343
456408
|
if (options.output) {
|
|
456344
|
-
const outputPath =
|
|
456409
|
+
const outputPath = resolve40(process.cwd(), options.output);
|
|
456345
456410
|
await writeFile24(outputPath, JSON.stringify(segments, null, 2), "utf-8");
|
|
456346
456411
|
if (isJsonMode()) {
|
|
456347
456412
|
outputSuccess({
|
|
@@ -456384,7 +456449,7 @@ function registerStoryboardCommand(parent) {
|
|
|
456384
456449
|
}
|
|
456385
456450
|
console.log();
|
|
456386
456451
|
if (options.output) {
|
|
456387
|
-
console.log(source_default.green(`Saved to: ${
|
|
456452
|
+
console.log(source_default.green(`Saved to: ${resolve40(process.cwd(), options.output)}`));
|
|
456388
456453
|
}
|
|
456389
456454
|
} catch (error) {
|
|
456390
456455
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -456406,6 +456471,13 @@ var init_storyboard = __esm({
|
|
|
456406
456471
|
}
|
|
456407
456472
|
});
|
|
456408
456473
|
|
|
456474
|
+
// ../cli/src/utils/open-url.ts
|
|
456475
|
+
var init_open_url = __esm({
|
|
456476
|
+
"../cli/src/utils/open-url.ts"() {
|
|
456477
|
+
"use strict";
|
|
456478
|
+
}
|
|
456479
|
+
});
|
|
456480
|
+
|
|
456409
456481
|
// ../cli/src/utils/tty.ts
|
|
456410
456482
|
import { createInterface as createInterface4 } from "node:readline";
|
|
456411
456483
|
import { ReadStream } from "node:tty";
|
|
@@ -456457,12 +456529,13 @@ var ttyStream;
|
|
|
456457
456529
|
var init_tty = __esm({
|
|
456458
456530
|
"../cli/src/utils/tty.ts"() {
|
|
456459
456531
|
"use strict";
|
|
456532
|
+
init_open_url();
|
|
456460
456533
|
ttyStream = null;
|
|
456461
456534
|
}
|
|
456462
456535
|
});
|
|
456463
456536
|
|
|
456464
456537
|
// ../cli/src/commands/generate/speech.ts
|
|
456465
|
-
import { resolve as
|
|
456538
|
+
import { resolve as resolve41 } from "node:path";
|
|
456466
456539
|
import { writeFile as writeFile25 } from "node:fs/promises";
|
|
456467
456540
|
async function executeSpeech(options) {
|
|
456468
456541
|
try {
|
|
@@ -456480,7 +456553,7 @@ async function executeSpeech(options) {
|
|
|
456480
456553
|
if (!result.success || !result.audioBuffer) {
|
|
456481
456554
|
return { success: false, error: result.error || "TTS generation failed" };
|
|
456482
456555
|
}
|
|
456483
|
-
const outputPath =
|
|
456556
|
+
const outputPath = resolve41(process.cwd(), options.output || "output.mp3");
|
|
456484
456557
|
await writeFile25(outputPath, result.audioBuffer);
|
|
456485
456558
|
return { success: true, outputPath, characterCount: result.characterCount };
|
|
456486
456559
|
} catch (error) {
|
|
@@ -456556,7 +456629,7 @@ function registerSpeechCommand(parent) {
|
|
|
456556
456629
|
spinner2.fail(result.error || "TTS generation failed");
|
|
456557
456630
|
exitWithError(apiError(result.error || "TTS generation failed", true));
|
|
456558
456631
|
}
|
|
456559
|
-
const outputPath =
|
|
456632
|
+
const outputPath = resolve41(process.cwd(), options.output);
|
|
456560
456633
|
await writeFile25(outputPath, result.audioBuffer);
|
|
456561
456634
|
spinner2.succeed(source_default.green("Speech generated"));
|
|
456562
456635
|
if (options.fitDuration && options.fitDuration > 0) {
|
|
@@ -456642,7 +456715,7 @@ var init_speech = __esm({
|
|
|
456642
456715
|
});
|
|
456643
456716
|
|
|
456644
456717
|
// ../cli/src/commands/generate/music.ts
|
|
456645
|
-
import { resolve as
|
|
456718
|
+
import { resolve as resolve43 } from "node:path";
|
|
456646
456719
|
import { writeFile as writeFile26 } from "node:fs/promises";
|
|
456647
456720
|
import { existsSync as existsSync46 } from "node:fs";
|
|
456648
456721
|
async function executeMusic(options) {
|
|
@@ -456665,7 +456738,7 @@ async function executeMusic(options) {
|
|
|
456665
456738
|
if (!result2.success || !result2.audioBuffer) {
|
|
456666
456739
|
return { success: false, error: result2.error || "Music generation failed" };
|
|
456667
456740
|
}
|
|
456668
|
-
const outputPath2 =
|
|
456741
|
+
const outputPath2 = resolve43(process.cwd(), options.output || "music.mp3");
|
|
456669
456742
|
await writeFile26(outputPath2, result2.audioBuffer);
|
|
456670
456743
|
return { success: true, outputPath: outputPath2, provider: "elevenlabs", duration: duration2 };
|
|
456671
456744
|
}
|
|
@@ -456690,7 +456763,7 @@ async function executeMusic(options) {
|
|
|
456690
456763
|
if (!response.ok)
|
|
456691
456764
|
return { success: false, error: "Failed to download generated audio" };
|
|
456692
456765
|
const audioBuffer = Buffer.from(await response.arrayBuffer());
|
|
456693
|
-
const outputPath =
|
|
456766
|
+
const outputPath = resolve43(process.cwd(), options.output || "music.mp3");
|
|
456694
456767
|
await writeFile26(outputPath, audioBuffer);
|
|
456695
456768
|
return { success: true, outputPath, provider: "replicate", duration };
|
|
456696
456769
|
} catch (error) {
|
|
@@ -456754,7 +456827,7 @@ function registerMusicCommand(parent) {
|
|
|
456754
456827
|
spinner2.fail(result.error || "Music generation failed");
|
|
456755
456828
|
exitWithError(apiError(result.error || "Music generation failed", true));
|
|
456756
456829
|
}
|
|
456757
|
-
const outputPath =
|
|
456830
|
+
const outputPath = resolve43(process.cwd(), options.output);
|
|
456758
456831
|
await writeFile26(outputPath, result.audioBuffer);
|
|
456759
456832
|
spinner2.succeed(source_default.green("Music generated successfully"));
|
|
456760
456833
|
if (isJsonMode()) {
|
|
@@ -456787,7 +456860,7 @@ function registerMusicCommand(parent) {
|
|
|
456787
456860
|
const duration = Math.max(1, Math.min(30, parseFloat(options.duration)));
|
|
456788
456861
|
if (options.melody) {
|
|
456789
456862
|
spinner2.text = "Uploading melody reference...";
|
|
456790
|
-
const absPath =
|
|
456863
|
+
const absPath = resolve43(process.cwd(), options.melody);
|
|
456791
456864
|
if (!existsSync46(absPath)) {
|
|
456792
456865
|
spinner2.fail(`Melody file not found: ${options.melody}`);
|
|
456793
456866
|
exitWithError(notFoundError(options.melody));
|
|
@@ -456829,7 +456902,7 @@ function registerMusicCommand(parent) {
|
|
|
456829
456902
|
exitWithError(apiError("Failed to download generated audio", true));
|
|
456830
456903
|
}
|
|
456831
456904
|
const audioBuffer = Buffer.from(await response.arrayBuffer());
|
|
456832
|
-
const outputPath =
|
|
456905
|
+
const outputPath = resolve43(process.cwd(), options.output);
|
|
456833
456906
|
await writeFile26(outputPath, audioBuffer);
|
|
456834
456907
|
spinner2.succeed(source_default.green("Music generated successfully"));
|
|
456835
456908
|
if (isJsonMode()) {
|
|
@@ -456871,7 +456944,7 @@ var init_music = __esm({
|
|
|
456871
456944
|
});
|
|
456872
456945
|
|
|
456873
456946
|
// ../cli/src/commands/generate/thumbnail.ts
|
|
456874
|
-
import { resolve as
|
|
456947
|
+
import { resolve as resolve44, dirname as dirname26, basename as basename10, extname as extname9 } from "node:path";
|
|
456875
456948
|
import { existsSync as existsSync47 } from "node:fs";
|
|
456876
456949
|
import { writeFile as writeFile27, mkdir as mkdir19 } from "node:fs/promises";
|
|
456877
456950
|
function registerThumbnailCommand(parent) {
|
|
@@ -456883,7 +456956,7 @@ function registerThumbnailCommand(parent) {
|
|
|
456883
456956
|
validateOutputPath(options.output);
|
|
456884
456957
|
}
|
|
456885
456958
|
if (options.bestFrame) {
|
|
456886
|
-
const absVideoPath =
|
|
456959
|
+
const absVideoPath = resolve44(process.cwd(), options.bestFrame);
|
|
456887
456960
|
if (!existsSync47(absVideoPath)) {
|
|
456888
456961
|
exitWithError(notFoundError(absVideoPath));
|
|
456889
456962
|
}
|
|
@@ -456901,7 +456974,7 @@ function registerThumbnailCommand(parent) {
|
|
|
456901
456974
|
const spinner3 = ora("Analyzing video for best frame...").start();
|
|
456902
456975
|
const result2 = await executeThumbnailBestFrame({
|
|
456903
456976
|
videoPath: absVideoPath,
|
|
456904
|
-
outputPath:
|
|
456977
|
+
outputPath: resolve44(process.cwd(), outputPath),
|
|
456905
456978
|
prompt: options.prompt,
|
|
456906
456979
|
model: options.model,
|
|
456907
456980
|
apiKey: apiKey2
|
|
@@ -456963,7 +457036,7 @@ function registerThumbnailCommand(parent) {
|
|
|
456963
457036
|
} else {
|
|
456964
457037
|
throw new Error("No image data available");
|
|
456965
457038
|
}
|
|
456966
|
-
outputPath =
|
|
457039
|
+
outputPath = resolve44(process.cwd(), options.output);
|
|
456967
457040
|
await mkdir19(dirname26(outputPath), { recursive: true });
|
|
456968
457041
|
await writeFile27(outputPath, buffer);
|
|
456969
457042
|
}
|
|
@@ -456994,7 +457067,7 @@ function registerThumbnailCommand(parent) {
|
|
|
456994
457067
|
} else {
|
|
456995
457068
|
throw new Error("No image data available");
|
|
456996
457069
|
}
|
|
456997
|
-
const outputPath =
|
|
457070
|
+
const outputPath = resolve44(process.cwd(), options.output);
|
|
456998
457071
|
await mkdir19(dirname26(outputPath), { recursive: true });
|
|
456999
457072
|
await writeFile27(outputPath, buffer);
|
|
457000
457073
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -457023,7 +457096,7 @@ var init_thumbnail = __esm({
|
|
|
457023
457096
|
});
|
|
457024
457097
|
|
|
457025
457098
|
// ../cli/src/commands/generate/video-status.ts
|
|
457026
|
-
import { resolve as
|
|
457099
|
+
import { resolve as resolve45 } from "node:path";
|
|
457027
457100
|
import { writeFile as writeFile28 } from "node:fs/promises";
|
|
457028
457101
|
function getStatusColor(status) {
|
|
457029
457102
|
switch (status) {
|
|
@@ -457062,7 +457135,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457062
457135
|
let outputPath;
|
|
457063
457136
|
if (options.output && result.videoUrl) {
|
|
457064
457137
|
const buffer = await downloadVideo(result.videoUrl);
|
|
457065
|
-
outputPath =
|
|
457138
|
+
outputPath = resolve45(process.cwd(), options.output);
|
|
457066
457139
|
await writeFile28(outputPath, buffer);
|
|
457067
457140
|
}
|
|
457068
457141
|
outputSuccess({
|
|
@@ -457096,7 +457169,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457096
457169
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457097
457170
|
try {
|
|
457098
457171
|
const buffer = await downloadVideo(result.videoUrl);
|
|
457099
|
-
const outputPath =
|
|
457172
|
+
const outputPath = resolve45(process.cwd(), options.output);
|
|
457100
457173
|
await writeFile28(outputPath, buffer);
|
|
457101
457174
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457102
457175
|
} catch (err) {
|
|
@@ -457130,7 +457203,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457130
457203
|
let outputPath;
|
|
457131
457204
|
if (options.output && result.videoUrl) {
|
|
457132
457205
|
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
457133
|
-
outputPath =
|
|
457206
|
+
outputPath = resolve45(process.cwd(), options.output);
|
|
457134
457207
|
await writeFile28(outputPath, buffer);
|
|
457135
457208
|
}
|
|
457136
457209
|
outputSuccess({
|
|
@@ -457168,7 +457241,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457168
457241
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457169
457242
|
try {
|
|
457170
457243
|
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
457171
|
-
const outputPath =
|
|
457244
|
+
const outputPath = resolve45(process.cwd(), options.output);
|
|
457172
457245
|
await writeFile28(outputPath, buffer);
|
|
457173
457246
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457174
457247
|
} catch (err) {
|
|
@@ -457197,7 +457270,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457197
457270
|
let outputPath;
|
|
457198
457271
|
if (options.output && result.videoUrl) {
|
|
457199
457272
|
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
457200
|
-
outputPath =
|
|
457273
|
+
outputPath = resolve45(process.cwd(), options.output);
|
|
457201
457274
|
await writeFile28(outputPath, buffer);
|
|
457202
457275
|
}
|
|
457203
457276
|
outputSuccess({
|
|
@@ -457236,7 +457309,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457236
457309
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457237
457310
|
try {
|
|
457238
457311
|
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
457239
|
-
const outputPath =
|
|
457312
|
+
const outputPath = resolve45(process.cwd(), options.output);
|
|
457240
457313
|
await writeFile28(outputPath, buffer);
|
|
457241
457314
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457242
457315
|
} catch (err) {
|
|
@@ -457271,7 +457344,7 @@ var init_video_status = __esm({
|
|
|
457271
457344
|
});
|
|
457272
457345
|
|
|
457273
457346
|
// ../cli/src/commands/generate/video-extend.ts
|
|
457274
|
-
import { resolve as
|
|
457347
|
+
import { resolve as resolve46 } from "node:path";
|
|
457275
457348
|
import { writeFile as writeFile29 } from "node:fs/promises";
|
|
457276
457349
|
function registerVideoExtendCommand(parent) {
|
|
457277
457350
|
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.0, 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) => {
|
|
@@ -457348,7 +457421,7 @@ function registerVideoExtendCommand(parent) {
|
|
|
457348
457421
|
let outputPath;
|
|
457349
457422
|
if (options.output && finalResult.videoUrl) {
|
|
457350
457423
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
457351
|
-
outputPath =
|
|
457424
|
+
outputPath = resolve46(process.cwd(), options.output);
|
|
457352
457425
|
await writeFile29(outputPath, buffer);
|
|
457353
457426
|
}
|
|
457354
457427
|
outputSuccess({
|
|
@@ -457376,7 +457449,7 @@ function registerVideoExtendCommand(parent) {
|
|
|
457376
457449
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457377
457450
|
try {
|
|
457378
457451
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
457379
|
-
const outputPath =
|
|
457452
|
+
const outputPath = resolve46(process.cwd(), options.output);
|
|
457380
457453
|
await writeFile29(outputPath, buffer);
|
|
457381
457454
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457382
457455
|
} catch (err) {
|
|
@@ -457437,7 +457510,7 @@ function registerVideoExtendCommand(parent) {
|
|
|
457437
457510
|
let outputPath;
|
|
457438
457511
|
if (options.output && finalResult.videoUrl) {
|
|
457439
457512
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
457440
|
-
outputPath =
|
|
457513
|
+
outputPath = resolve46(process.cwd(), options.output);
|
|
457441
457514
|
await writeFile29(outputPath, buffer);
|
|
457442
457515
|
}
|
|
457443
457516
|
outputSuccess({
|
|
@@ -457462,7 +457535,7 @@ function registerVideoExtendCommand(parent) {
|
|
|
457462
457535
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457463
457536
|
try {
|
|
457464
457537
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
457465
|
-
const outputPath =
|
|
457538
|
+
const outputPath = resolve46(process.cwd(), options.output);
|
|
457466
457539
|
await writeFile29(outputPath, buffer);
|
|
457467
457540
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457468
457541
|
} catch (err) {
|
|
@@ -457553,7 +457626,7 @@ var init_openai_image2 = __esm({
|
|
|
457553
457626
|
});
|
|
457554
457627
|
|
|
457555
457628
|
// ../cli/src/commands/generate/image.ts
|
|
457556
|
-
import { resolve as
|
|
457629
|
+
import { resolve as resolve47, dirname as dirname27 } from "node:path";
|
|
457557
457630
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
457558
457631
|
import { writeFile as writeFile30, mkdir as mkdir20 } from "node:fs/promises";
|
|
457559
457632
|
function registerImageCommand(parent) {
|
|
@@ -457669,7 +457742,7 @@ Examples:
|
|
|
457669
457742
|
source_default.green(`Generated ${result.images.length} image(s) with OpenAI ${modelLabel}`)
|
|
457670
457743
|
);
|
|
457671
457744
|
if (isJsonMode()) {
|
|
457672
|
-
const outputPath = options.output ?
|
|
457745
|
+
const outputPath = options.output ? resolve47(process.cwd(), options.output) : void 0;
|
|
457673
457746
|
if (outputPath && result.images.length > 0) {
|
|
457674
457747
|
const img = result.images[0];
|
|
457675
457748
|
let buffer;
|
|
@@ -457727,7 +457800,7 @@ Examples:
|
|
|
457727
457800
|
} else {
|
|
457728
457801
|
throw new Error("No image data available");
|
|
457729
457802
|
}
|
|
457730
|
-
const outputPath =
|
|
457803
|
+
const outputPath = resolve47(process.cwd(), options.output);
|
|
457731
457804
|
await mkdir20(dirname27(outputPath), { recursive: true });
|
|
457732
457805
|
await writeFile30(outputPath, buffer);
|
|
457733
457806
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -457799,7 +457872,7 @@ Examples:
|
|
|
457799
457872
|
source_default.green(`Generated ${result.images.length} image(s) with Gemini (${usedLabel})`)
|
|
457800
457873
|
);
|
|
457801
457874
|
if (isJsonMode()) {
|
|
457802
|
-
const outputPath = options.output ?
|
|
457875
|
+
const outputPath = options.output ? resolve47(process.cwd(), options.output) : void 0;
|
|
457803
457876
|
if (outputPath && result.images.length > 0) {
|
|
457804
457877
|
const img = result.images[0];
|
|
457805
457878
|
const buffer = Buffer.from(img.base64, "base64");
|
|
@@ -457835,7 +457908,7 @@ Examples:
|
|
|
457835
457908
|
try {
|
|
457836
457909
|
const img = result.images[0];
|
|
457837
457910
|
const buffer = Buffer.from(img.base64, "base64");
|
|
457838
|
-
const outputPath =
|
|
457911
|
+
const outputPath = resolve47(process.cwd(), options.output);
|
|
457839
457912
|
await mkdir20(dirname27(outputPath), { recursive: true });
|
|
457840
457913
|
await writeFile30(outputPath, buffer);
|
|
457841
457914
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -457886,7 +457959,7 @@ Examples:
|
|
|
457886
457959
|
source_default.green(`Generated ${result.images.length} image(s) with xAI Grok`)
|
|
457887
457960
|
);
|
|
457888
457961
|
if (isJsonMode()) {
|
|
457889
|
-
const outputPath = options.output ?
|
|
457962
|
+
const outputPath = options.output ? resolve47(process.cwd(), options.output) : void 0;
|
|
457890
457963
|
if (outputPath && result.images.length > 0) {
|
|
457891
457964
|
const img = result.images[0];
|
|
457892
457965
|
let buffer;
|
|
@@ -457938,7 +458011,7 @@ Examples:
|
|
|
457938
458011
|
} else {
|
|
457939
458012
|
throw new Error("No image data available");
|
|
457940
458013
|
}
|
|
457941
|
-
const outputPath =
|
|
458014
|
+
const outputPath = resolve47(process.cwd(), options.output);
|
|
457942
458015
|
await mkdir20(dirname27(outputPath), { recursive: true });
|
|
457943
458016
|
await writeFile30(outputPath, buffer);
|
|
457944
458017
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -457952,7 +458025,7 @@ Examples:
|
|
|
457952
458025
|
const { spawn: spawn10 } = await import("child_process");
|
|
457953
458026
|
const __filename2 = fileURLToPath4(import.meta.url);
|
|
457954
458027
|
const __dirname3 = dirname27(__filename2);
|
|
457955
|
-
const scriptPath =
|
|
458028
|
+
const scriptPath = resolve47(
|
|
457956
458029
|
__dirname3,
|
|
457957
458030
|
"../../../../.claude/skills/runway-video/scripts/image.py"
|
|
457958
458031
|
);
|
|
@@ -457960,7 +458033,7 @@ Examples:
|
|
|
457960
458033
|
spinner2.fail("Output path required for Runway");
|
|
457961
458034
|
exitWithError(usageError("Output path required for Runway. Use -o option."));
|
|
457962
458035
|
}
|
|
457963
|
-
const outputPath =
|
|
458036
|
+
const outputPath = resolve47(process.cwd(), options.output);
|
|
457964
458037
|
const args = [scriptPath, prompt3, "-o", outputPath, "-r", options.ratio || "16:9"];
|
|
457965
458038
|
spinner2.text = "Generating image with Runway (gemini_2.5_flash)...";
|
|
457966
458039
|
await new Promise((resolvePromise, reject) => {
|
|
@@ -458970,7 +459043,7 @@ var init_dist3 = __esm({
|
|
|
458970
459043
|
|
|
458971
459044
|
// ../cli/src/commands/_shared/video-utils.ts
|
|
458972
459045
|
import { writeFile as writeFile31, unlink as unlink5, rename as rename5 } from "node:fs/promises";
|
|
458973
|
-
import { resolve as
|
|
459046
|
+
import { resolve as resolve48, basename as basename11 } from "node:path";
|
|
458974
459047
|
function sleep(ms) {
|
|
458975
459048
|
return new Promise((resolve64) => setTimeout(resolve64, ms));
|
|
458976
459049
|
}
|
|
@@ -459004,7 +459077,7 @@ async function extendVideoToTarget(videoPath, targetDuration, outputDir, sceneLa
|
|
|
459004
459077
|
const actualDuration = await getVideoDuration(videoPath);
|
|
459005
459078
|
if (actualDuration >= targetDuration - 0.1) return;
|
|
459006
459079
|
const ratio = targetDuration / actualDuration;
|
|
459007
|
-
const extendedPath =
|
|
459080
|
+
const extendedPath = resolve48(outputDir, `${basename11(videoPath, ".mp4")}-extended.mp4`);
|
|
459008
459081
|
if (ratio > 1.4 && options?.kling && options?.videoId) {
|
|
459009
459082
|
try {
|
|
459010
459083
|
options.onProgress?.(`${sceneLabel}: Extending via Kling API...`);
|
|
@@ -459020,17 +459093,17 @@ async function extendVideoToTarget(videoPath, targetDuration, outputDir, sceneLa
|
|
|
459020
459093
|
6e5
|
|
459021
459094
|
);
|
|
459022
459095
|
if (waitResult.status === "completed" && waitResult.videoUrl) {
|
|
459023
|
-
const extendedVideoPath =
|
|
459096
|
+
const extendedVideoPath = resolve48(
|
|
459024
459097
|
outputDir,
|
|
459025
459098
|
`${basename11(videoPath, ".mp4")}-kling-ext.mp4`
|
|
459026
459099
|
);
|
|
459027
459100
|
const buffer = await downloadVideo(waitResult.videoUrl);
|
|
459028
459101
|
await writeFile31(extendedVideoPath, buffer);
|
|
459029
|
-
const concatPath =
|
|
459102
|
+
const concatPath = resolve48(
|
|
459030
459103
|
outputDir,
|
|
459031
459104
|
`${basename11(videoPath, ".mp4")}-concat.mp4`
|
|
459032
459105
|
);
|
|
459033
|
-
const listPath =
|
|
459106
|
+
const listPath = resolve48(
|
|
459034
459107
|
outputDir,
|
|
459035
459108
|
`${basename11(videoPath, ".mp4")}-concat.txt`
|
|
459036
459109
|
);
|
|
@@ -459272,7 +459345,7 @@ var init_video_providers = __esm({
|
|
|
459272
459345
|
|
|
459273
459346
|
// ../cli/src/commands/ai-script-pipeline.ts
|
|
459274
459347
|
import { readFile as readFile24, writeFile as writeFile32, unlink as unlink6, rename as rename6 } from "node:fs/promises";
|
|
459275
|
-
import { resolve as
|
|
459348
|
+
import { resolve as resolve49, extname as extname10 } from "node:path";
|
|
459276
459349
|
import { existsSync as existsSync48 } from "node:fs";
|
|
459277
459350
|
async function executeRegenerateScene(options) {
|
|
459278
459351
|
const result = {
|
|
@@ -459281,12 +459354,12 @@ async function executeRegenerateScene(options) {
|
|
|
459281
459354
|
failedScenes: []
|
|
459282
459355
|
};
|
|
459283
459356
|
try {
|
|
459284
|
-
const outputDir =
|
|
459357
|
+
const outputDir = resolve49(process.cwd(), options.projectDir);
|
|
459285
459358
|
if (!existsSync48(outputDir)) {
|
|
459286
459359
|
return { ...result, error: `Project directory not found: ${outputDir}` };
|
|
459287
459360
|
}
|
|
459288
|
-
const yamlPath =
|
|
459289
|
-
const jsonPath =
|
|
459361
|
+
const yamlPath = resolve49(outputDir, "storyboard.yaml");
|
|
459362
|
+
const jsonPath = resolve49(outputDir, "storyboard.json");
|
|
459290
459363
|
const storyboardPath = existsSync48(yamlPath) ? yamlPath : existsSync48(jsonPath) ? jsonPath : null;
|
|
459291
459364
|
if (!storyboardPath) {
|
|
459292
459365
|
return { ...result, error: `Storyboard not found in: ${outputDir} (expected storyboard.yaml or storyboard.json)` };
|
|
@@ -459346,9 +459419,9 @@ async function executeRegenerateScene(options) {
|
|
|
459346
459419
|
let storyboardMutated = false;
|
|
459347
459420
|
for (const sceneNum of options.scenes) {
|
|
459348
459421
|
const segment = segments[sceneNum - 1];
|
|
459349
|
-
const narrationPath =
|
|
459350
|
-
const imagePath =
|
|
459351
|
-
const videoPath =
|
|
459422
|
+
const narrationPath = resolve49(outputDir, `narration-${sceneNum}.mp3`);
|
|
459423
|
+
const imagePath = resolve49(outputDir, `scene-${sceneNum}.png`);
|
|
459424
|
+
const videoPath = resolve49(outputDir, `scene-${sceneNum}.mp4`);
|
|
459352
459425
|
let sceneFailed = false;
|
|
459353
459426
|
if (regenerateNarration && elevenlabsApiKey) {
|
|
459354
459427
|
options.onProgress?.(`Scene ${sceneNum}: regenerating narration...`);
|
|
@@ -459379,14 +459452,14 @@ IMPORTANT - Character appearance must match exactly: ${characterDesc}`;
|
|
|
459379
459452
|
let referenceImageBuffer;
|
|
459380
459453
|
const refSceneNum = options.referenceScene;
|
|
459381
459454
|
if (refSceneNum && refSceneNum >= 1 && refSceneNum <= segments.length && refSceneNum !== sceneNum) {
|
|
459382
|
-
const refImagePath =
|
|
459455
|
+
const refImagePath = resolve49(outputDir, `scene-${refSceneNum}.png`);
|
|
459383
459456
|
if (existsSync48(refImagePath)) {
|
|
459384
459457
|
referenceImageBuffer = await readFile24(refImagePath);
|
|
459385
459458
|
}
|
|
459386
459459
|
} else if (!refSceneNum) {
|
|
459387
459460
|
for (let i = 1; i <= segments.length; i++) {
|
|
459388
459461
|
if (i !== sceneNum) {
|
|
459389
|
-
const otherImagePath =
|
|
459462
|
+
const otherImagePath = resolve49(outputDir, `scene-${i}.png`);
|
|
459390
459463
|
if (existsSync48(otherImagePath)) {
|
|
459391
459464
|
referenceImageBuffer = await readFile24(otherImagePath);
|
|
459392
459465
|
break;
|
|
@@ -459509,7 +459582,7 @@ Generate the single-person scene image now.`;
|
|
|
459509
459582
|
const targetDuration = segment.duration;
|
|
459510
459583
|
const actualVideoDuration = await getVideoDuration(videoPath);
|
|
459511
459584
|
if (actualVideoDuration < targetDuration - 0.1) {
|
|
459512
|
-
const extendedPath =
|
|
459585
|
+
const extendedPath = resolve49(outputDir, `scene-${sceneNum}-extended.mp4`);
|
|
459513
459586
|
await extendVideoNaturally(videoPath, targetDuration, extendedPath);
|
|
459514
459587
|
await unlink6(videoPath);
|
|
459515
459588
|
await rename6(extendedPath, videoPath);
|
|
@@ -459552,7 +459625,7 @@ Generate the single-person scene image now.`;
|
|
|
459552
459625
|
const targetDuration = segment.duration;
|
|
459553
459626
|
const actualVideoDuration = await getVideoDuration(videoPath);
|
|
459554
459627
|
if (actualVideoDuration < targetDuration - 0.1) {
|
|
459555
|
-
const extendedPath =
|
|
459628
|
+
const extendedPath = resolve49(outputDir, `scene-${sceneNum}-extended.mp4`);
|
|
459556
459629
|
await extendVideoNaturally(videoPath, targetDuration, extendedPath);
|
|
459557
459630
|
await unlink6(videoPath);
|
|
459558
459631
|
await rename6(extendedPath, videoPath);
|
|
@@ -459646,7 +459719,7 @@ Generate the single-person scene image now.`;
|
|
|
459646
459719
|
const targetDuration = segment.duration;
|
|
459647
459720
|
const actualVideoDuration = await getVideoDuration(videoPath);
|
|
459648
459721
|
if (actualVideoDuration < targetDuration - 0.1) {
|
|
459649
|
-
const extendedPath =
|
|
459722
|
+
const extendedPath = resolve49(outputDir, `scene-${sceneNum}-extended.mp4`);
|
|
459650
459723
|
await extendVideoNaturally(videoPath, targetDuration, extendedPath);
|
|
459651
459724
|
await unlink6(videoPath);
|
|
459652
459725
|
await rename6(extendedPath, videoPath);
|
|
@@ -459702,7 +459775,7 @@ var init_ai_script_pipeline = __esm({
|
|
|
459702
459775
|
});
|
|
459703
459776
|
|
|
459704
459777
|
// ../cli/src/commands/generate/video.ts
|
|
459705
|
-
import { resolve as
|
|
459778
|
+
import { resolve as resolve50 } from "node:path";
|
|
459706
459779
|
import { readFile as readFile25, writeFile as writeFile33 } from "node:fs/promises";
|
|
459707
459780
|
function registerVideoCommand(parent) {
|
|
459708
459781
|
parent.command("video").alias("vid").description("Generate video using AI (Seedance, Grok, Kling, Runway, or Veo)").argument("[prompt]", "Text prompt describing the video (interactive if omitted)").option("-p, --provider <provider>", "Provider: seedance (ByteDance Seedance 2.0 via fal.ai), grok, kling, runway, veo. `fal` is a backwards-compatible alias for seedance.").option("-k, --api-key <key>", "API key (or set FAL_KEY / XAI_API_KEY / RUNWAY_API_SECRET / KLING_API_KEY / GOOGLE_API_KEY env)").option("-o, --output <path>", "Output file path (downloads video)").option("-i, --image <path>", "Reference image for image-to-video").option(
|
|
@@ -459781,7 +459854,7 @@ Examples:
|
|
|
459781
459854
|
let referenceImage;
|
|
459782
459855
|
let isImageToVideo = false;
|
|
459783
459856
|
if (options.image) {
|
|
459784
|
-
const imagePath =
|
|
459857
|
+
const imagePath = resolve50(process.cwd(), options.image);
|
|
459785
459858
|
const imageBuffer = await readFile25(imagePath);
|
|
459786
459859
|
const ext = options.image.toLowerCase().split(".").pop();
|
|
459787
459860
|
const mimeTypes = {
|
|
@@ -459986,7 +460059,7 @@ Examples:
|
|
|
459986
460059
|
const veoDuration = parseInt(options.duration) <= 6 ? 6 : 8;
|
|
459987
460060
|
let lastFrame;
|
|
459988
460061
|
if (options.lastFrame) {
|
|
459989
|
-
const lastFramePath =
|
|
460062
|
+
const lastFramePath = resolve50(process.cwd(), options.lastFrame);
|
|
459990
460063
|
const lastFrameBuffer = await readFile25(lastFramePath);
|
|
459991
460064
|
const ext = options.lastFrame.toLowerCase().split(".").pop();
|
|
459992
460065
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
@@ -459996,7 +460069,7 @@ Examples:
|
|
|
459996
460069
|
if (options.refImages && options.refImages.length > 0) {
|
|
459997
460070
|
refImages = [];
|
|
459998
460071
|
for (const refPath of options.refImages.slice(0, 3)) {
|
|
459999
|
-
const absRefPath =
|
|
460072
|
+
const absRefPath = resolve50(process.cwd(), refPath);
|
|
460000
460073
|
const refBuffer = await readFile25(absRefPath);
|
|
460001
460074
|
const ext = refPath.toLowerCase().split(".").pop();
|
|
460002
460075
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
@@ -460115,7 +460188,7 @@ Examples:
|
|
|
460115
460188
|
let outputPath;
|
|
460116
460189
|
if (options.output && finalResult.videoUrl) {
|
|
460117
460190
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
460118
|
-
outputPath =
|
|
460191
|
+
outputPath = resolve50(process.cwd(), options.output);
|
|
460119
460192
|
await writeFile33(outputPath, buffer);
|
|
460120
460193
|
}
|
|
460121
460194
|
outputSuccess({
|
|
@@ -460143,7 +460216,7 @@ Examples:
|
|
|
460143
460216
|
const downloadSpinner = ora("Downloading video...").start();
|
|
460144
460217
|
try {
|
|
460145
460218
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
460146
|
-
const outputPath =
|
|
460219
|
+
const outputPath = resolve50(process.cwd(), options.output);
|
|
460147
460220
|
await writeFile33(outputPath, buffer);
|
|
460148
460221
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
460149
460222
|
} catch (err) {
|
|
@@ -460267,7 +460340,7 @@ __export(ai_video_exports, {
|
|
|
460267
460340
|
executeVideoStatus: () => executeVideoStatus
|
|
460268
460341
|
});
|
|
460269
460342
|
import { readFile as readFile26, writeFile as writeFile34 } from "node:fs/promises";
|
|
460270
|
-
import { resolve as
|
|
460343
|
+
import { resolve as resolve51 } from "node:path";
|
|
460271
460344
|
async function executeVideoGenerate(options) {
|
|
460272
460345
|
const {
|
|
460273
460346
|
prompt: prompt3,
|
|
@@ -460298,7 +460371,7 @@ async function executeVideoGenerate(options) {
|
|
|
460298
460371
|
if (!key2) return { success: false, error: `${envKeyMap[provider]} required for ${provider}` };
|
|
460299
460372
|
let referenceImage;
|
|
460300
460373
|
if (image) {
|
|
460301
|
-
const imagePath =
|
|
460374
|
+
const imagePath = resolve51(process.cwd(), image);
|
|
460302
460375
|
const imageBuffer = await readFile26(imagePath);
|
|
460303
460376
|
const ext = image.toLowerCase().split(".").pop();
|
|
460304
460377
|
const mimeTypes = { jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png", gif: "image/gif", webp: "image/webp" };
|
|
@@ -460330,7 +460403,7 @@ async function executeVideoGenerate(options) {
|
|
|
460330
460403
|
let outputPath;
|
|
460331
460404
|
if (output3 && result.videoUrl) {
|
|
460332
460405
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
460333
|
-
outputPath =
|
|
460406
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460334
460407
|
await writeFile34(outputPath, buffer);
|
|
460335
460408
|
}
|
|
460336
460409
|
return { success: true, taskId: result.id, status: "completed", videoUrl: result.videoUrl, outputPath, provider: "seedance" };
|
|
@@ -460352,7 +460425,7 @@ async function executeVideoGenerate(options) {
|
|
|
460352
460425
|
let outputPath;
|
|
460353
460426
|
if (output3 && finalResult.videoUrl) {
|
|
460354
460427
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460355
|
-
outputPath =
|
|
460428
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460356
460429
|
await writeFile34(outputPath, buffer);
|
|
460357
460430
|
}
|
|
460358
460431
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, duration: finalResult.duration, outputPath, provider: "runway" };
|
|
@@ -460386,7 +460459,7 @@ async function executeVideoGenerate(options) {
|
|
|
460386
460459
|
let outputPath;
|
|
460387
460460
|
if (output3 && finalResult.videoUrl) {
|
|
460388
460461
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460389
|
-
outputPath =
|
|
460462
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460390
460463
|
await writeFile34(outputPath, buffer);
|
|
460391
460464
|
}
|
|
460392
460465
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, duration: finalResult.duration, outputPath, provider: "kling" };
|
|
@@ -460413,7 +460486,7 @@ async function executeVideoGenerate(options) {
|
|
|
460413
460486
|
let outputPath;
|
|
460414
460487
|
if (output3 && finalResult.videoUrl) {
|
|
460415
460488
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460416
|
-
outputPath =
|
|
460489
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460417
460490
|
await writeFile34(outputPath, buffer);
|
|
460418
460491
|
}
|
|
460419
460492
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, outputPath, provider: "veo" };
|
|
@@ -460434,7 +460507,7 @@ async function executeVideoGenerate(options) {
|
|
|
460434
460507
|
let outputPath;
|
|
460435
460508
|
if (output3 && finalResult.videoUrl) {
|
|
460436
460509
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460437
|
-
outputPath =
|
|
460510
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460438
460511
|
await writeFile34(outputPath, buffer);
|
|
460439
460512
|
}
|
|
460440
460513
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, duration: finalResult.duration, outputPath, provider: "grok" };
|
|
@@ -460461,7 +460534,7 @@ async function executeVideoStatus(options) {
|
|
|
460461
460534
|
let outputPath;
|
|
460462
460535
|
if (output3 && result.videoUrl) {
|
|
460463
460536
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
460464
|
-
outputPath =
|
|
460537
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460465
460538
|
await writeFile34(outputPath, buffer);
|
|
460466
460539
|
}
|
|
460467
460540
|
return { success: true, taskId, status: result.status, progress: result.progress, videoUrl: result.videoUrl, outputPath };
|
|
@@ -460476,7 +460549,7 @@ async function executeVideoStatus(options) {
|
|
|
460476
460549
|
let outputPath;
|
|
460477
460550
|
if (output3 && result.videoUrl) {
|
|
460478
460551
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
460479
|
-
outputPath =
|
|
460552
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460480
460553
|
await writeFile34(outputPath, buffer);
|
|
460481
460554
|
}
|
|
460482
460555
|
return { success: true, taskId, status: result.status, videoUrl: result.videoUrl, duration: result.duration, outputPath };
|
|
@@ -460521,7 +460594,7 @@ async function executeVideoExtend(options) {
|
|
|
460521
460594
|
let outputPath;
|
|
460522
460595
|
if (output3 && finalResult.videoUrl) {
|
|
460523
460596
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460524
|
-
outputPath =
|
|
460597
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460525
460598
|
await writeFile34(outputPath, buffer);
|
|
460526
460599
|
}
|
|
460527
460600
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, duration: finalResult.duration, outputPath };
|
|
@@ -460544,7 +460617,7 @@ async function executeVideoExtend(options) {
|
|
|
460544
460617
|
let outputPath;
|
|
460545
460618
|
if (output3 && finalResult.videoUrl) {
|
|
460546
460619
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460547
|
-
outputPath =
|
|
460620
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460548
460621
|
await writeFile34(outputPath, buffer);
|
|
460549
460622
|
}
|
|
460550
460623
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, outputPath };
|
|
@@ -460572,13 +460645,13 @@ __export(detect_exports, {
|
|
|
460572
460645
|
executeDetectSilence: () => executeDetectSilence
|
|
460573
460646
|
});
|
|
460574
460647
|
import { readFile as readFile28, writeFile as writeFile36 } from "node:fs/promises";
|
|
460575
|
-
import { resolve as
|
|
460648
|
+
import { resolve as resolve54, basename as basename13 } from "node:path";
|
|
460576
460649
|
async function executeDetectScenes(options) {
|
|
460577
460650
|
try {
|
|
460578
460651
|
if (!commandExists("ffmpeg")) {
|
|
460579
460652
|
return { success: false, error: "FFmpeg not found. Install with: brew install ffmpeg" };
|
|
460580
460653
|
}
|
|
460581
|
-
const absPath =
|
|
460654
|
+
const absPath = resolve54(process.cwd(), options.videoPath);
|
|
460582
460655
|
const threshold = options.threshold ?? 0.3;
|
|
460583
460656
|
const { stdout: sceneStdout, stderr: sceneStderr } = await execSafe("ffmpeg", [
|
|
460584
460657
|
"-i",
|
|
@@ -460609,7 +460682,7 @@ async function executeDetectScenes(options) {
|
|
|
460609
460682
|
duration: (i < scenes.length - 1 ? scenes[i + 1].timestamp : totalDuration) - s.timestamp
|
|
460610
460683
|
}));
|
|
460611
460684
|
if (options.outputPath) {
|
|
460612
|
-
const outputPath =
|
|
460685
|
+
const outputPath = resolve54(process.cwd(), options.outputPath);
|
|
460613
460686
|
await writeFile36(outputPath, JSON.stringify({ source: absPath, totalDuration, threshold, scenes: result }, null, 2), "utf-8");
|
|
460614
460687
|
}
|
|
460615
460688
|
return { success: true, scenes: result, totalDuration };
|
|
@@ -460622,7 +460695,7 @@ async function executeDetectSilence(options) {
|
|
|
460622
460695
|
if (!commandExists("ffmpeg")) {
|
|
460623
460696
|
return { success: false, error: "FFmpeg not found. Install with: brew install ffmpeg" };
|
|
460624
460697
|
}
|
|
460625
|
-
const absPath =
|
|
460698
|
+
const absPath = resolve54(process.cwd(), options.mediaPath);
|
|
460626
460699
|
const noise = options.noise ?? "-30";
|
|
460627
460700
|
const duration = options.duration ?? "0.5";
|
|
460628
460701
|
const { stdout: silStdout, stderr: silStderr } = await execSafe("ffmpeg", [
|
|
@@ -460656,7 +460729,7 @@ async function executeDetectSilence(options) {
|
|
|
460656
460729
|
}
|
|
460657
460730
|
}
|
|
460658
460731
|
if (options.outputPath) {
|
|
460659
|
-
const outputPath =
|
|
460732
|
+
const outputPath = resolve54(process.cwd(), options.outputPath);
|
|
460660
460733
|
await writeFile36(outputPath, JSON.stringify({ source: absPath, silences }, null, 2), "utf-8");
|
|
460661
460734
|
}
|
|
460662
460735
|
return { success: true, silences };
|
|
@@ -460669,7 +460742,7 @@ async function executeDetectBeats(options) {
|
|
|
460669
460742
|
if (!commandExists("ffmpeg")) {
|
|
460670
460743
|
return { success: false, error: "FFmpeg not found. Install with: brew install ffmpeg" };
|
|
460671
460744
|
}
|
|
460672
|
-
const absPath =
|
|
460745
|
+
const absPath = resolve54(process.cwd(), options.audioPath);
|
|
460673
460746
|
const { stdout: beatStdout, stderr: beatStderr } = await execSafe("ffmpeg", [
|
|
460674
460747
|
"-i",
|
|
460675
460748
|
absPath,
|
|
@@ -460705,7 +460778,7 @@ async function executeDetectBeats(options) {
|
|
|
460705
460778
|
}
|
|
460706
460779
|
}
|
|
460707
460780
|
if (options.outputPath) {
|
|
460708
|
-
const outputPath =
|
|
460781
|
+
const outputPath = resolve54(process.cwd(), options.outputPath);
|
|
460709
460782
|
await writeFile36(outputPath, JSON.stringify({ source: absPath, beatCount: beats.length, beats }, null, 2), "utf-8");
|
|
460710
460783
|
}
|
|
460711
460784
|
return { success: true, beats, beatCount: beats.length };
|
|
@@ -460756,7 +460829,7 @@ var init_detect = __esm({
|
|
|
460756
460829
|
spinner2.fail("FFmpeg not found");
|
|
460757
460830
|
exitWithError(generalError("FFmpeg not found", "Install with: brew install ffmpeg (macOS) or apt install ffmpeg (Linux)"));
|
|
460758
460831
|
}
|
|
460759
|
-
const absPath =
|
|
460832
|
+
const absPath = resolve54(process.cwd(), videoPath);
|
|
460760
460833
|
const threshold = parseFloat(options.threshold);
|
|
460761
460834
|
spinner2.text = "Analyzing video...";
|
|
460762
460835
|
const { stdout: sceneStdout, stderr: sceneStderr } = await execSafe("ffmpeg", [
|
|
@@ -460797,7 +460870,7 @@ var init_detect = __esm({
|
|
|
460797
460870
|
}
|
|
460798
460871
|
console.log();
|
|
460799
460872
|
if (options.output) {
|
|
460800
|
-
const outputPath =
|
|
460873
|
+
const outputPath = resolve54(process.cwd(), options.output);
|
|
460801
460874
|
const result = {
|
|
460802
460875
|
source: absPath,
|
|
460803
460876
|
totalDuration,
|
|
@@ -460813,7 +460886,7 @@ var init_detect = __esm({
|
|
|
460813
460886
|
console.log(source_default.green(`Saved to: ${outputPath}`));
|
|
460814
460887
|
}
|
|
460815
460888
|
if (options.project) {
|
|
460816
|
-
const projectPath =
|
|
460889
|
+
const projectPath = resolve54(process.cwd(), options.project);
|
|
460817
460890
|
const content = await readFile28(projectPath, "utf-8");
|
|
460818
460891
|
const data = JSON.parse(content);
|
|
460819
460892
|
const project = Project.fromJSON(data);
|
|
@@ -460871,7 +460944,7 @@ var init_detect = __esm({
|
|
|
460871
460944
|
});
|
|
460872
460945
|
return;
|
|
460873
460946
|
}
|
|
460874
|
-
const absPath =
|
|
460947
|
+
const absPath = resolve54(process.cwd(), mediaPath);
|
|
460875
460948
|
const noise = options.noise;
|
|
460876
460949
|
const duration = options.duration;
|
|
460877
460950
|
const { stdout: silStdout, stderr: silStderr } = await execSafe("ffmpeg", [
|
|
@@ -460920,7 +460993,7 @@ var init_detect = __esm({
|
|
|
460920
460993
|
}
|
|
460921
460994
|
console.log();
|
|
460922
460995
|
if (options.output) {
|
|
460923
|
-
const outputPath =
|
|
460996
|
+
const outputPath = resolve54(process.cwd(), options.output);
|
|
460924
460997
|
await writeFile36(
|
|
460925
460998
|
outputPath,
|
|
460926
460999
|
JSON.stringify({ source: absPath, silences }, null, 2),
|
|
@@ -460955,7 +461028,7 @@ var init_detect = __esm({
|
|
|
460955
461028
|
});
|
|
460956
461029
|
return;
|
|
460957
461030
|
}
|
|
460958
|
-
const absPath =
|
|
461031
|
+
const absPath = resolve54(process.cwd(), audioPath);
|
|
460959
461032
|
const { stdout: beatStdout, stderr: beatStderr } = await execSafe("ffmpeg", [
|
|
460960
461033
|
"-i",
|
|
460961
461034
|
absPath,
|
|
@@ -461005,7 +461078,7 @@ var init_detect = __esm({
|
|
|
461005
461078
|
}
|
|
461006
461079
|
console.log();
|
|
461007
461080
|
if (options.output) {
|
|
461008
|
-
const outputPath =
|
|
461081
|
+
const outputPath = resolve54(process.cwd(), options.output);
|
|
461009
461082
|
await writeFile36(
|
|
461010
461083
|
outputPath,
|
|
461011
461084
|
JSON.stringify({ source: absPath, beatCount: beats.length, beats }, null, 2),
|
|
@@ -461024,8 +461097,8 @@ var init_detect = __esm({
|
|
|
461024
461097
|
|
|
461025
461098
|
// ../cli/src/pipeline/renderers/html-clips.ts
|
|
461026
461099
|
function relAsset(url) {
|
|
461027
|
-
const
|
|
461028
|
-
return `assets/${
|
|
461100
|
+
const basename18 = url.split("/").pop() ?? url;
|
|
461101
|
+
return `assets/${basename18}`;
|
|
461029
461102
|
}
|
|
461030
461103
|
function buildClipElements(state) {
|
|
461031
461104
|
return state.clips.map((clip) => {
|
|
@@ -461199,7 +461272,7 @@ __export(project_builder_exports, {
|
|
|
461199
461272
|
buildTempProject: () => buildTempProject,
|
|
461200
461273
|
resolveSourceUrl: () => resolveSourceUrl
|
|
461201
461274
|
});
|
|
461202
|
-
import { mkdtemp as mkdtemp4, mkdir as
|
|
461275
|
+
import { mkdtemp as mkdtemp4, mkdir as mkdir25, copyFile as copyFile4, writeFile as writeFile42, rm as rm5, readdir as readdir4 } from "node:fs/promises";
|
|
461203
461276
|
import { existsSync as existsSync51 } from "node:fs";
|
|
461204
461277
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
461205
461278
|
import { createRequire } from "node:module";
|
|
@@ -461207,7 +461280,7 @@ import * as path13 from "node:path";
|
|
|
461207
461280
|
async function buildTempProject(state, projectFileDir) {
|
|
461208
461281
|
const dir = await mkdtemp4(path13.join(tmpdir6(), "vibeframe-hf-"));
|
|
461209
461282
|
const assetsDir = path13.join(dir, "assets");
|
|
461210
|
-
await
|
|
461283
|
+
await mkdir25(assetsDir, { recursive: true });
|
|
461211
461284
|
const copied = /* @__PURE__ */ new Map();
|
|
461212
461285
|
for (const source3 of state.sources) {
|
|
461213
461286
|
if (copied.has(source3.id)) continue;
|
|
@@ -461223,7 +461296,7 @@ async function buildTempProject(state, projectFileDir) {
|
|
|
461223
461296
|
await copyLottieRuntime(dir);
|
|
461224
461297
|
}
|
|
461225
461298
|
const html = generateCompositionHtml(state);
|
|
461226
|
-
await
|
|
461299
|
+
await writeFile42(path13.join(dir, "index.html"), html, "utf-8");
|
|
461227
461300
|
return {
|
|
461228
461301
|
dir,
|
|
461229
461302
|
cleanup: () => rm5(dir, { recursive: true, force: true })
|
|
@@ -461237,7 +461310,7 @@ async function copyLottieRuntime(tempDir) {
|
|
|
461237
461310
|
const wasmSrc = path13.join(path13.dirname(webEntry), "dotlottie-player.wasm");
|
|
461238
461311
|
const vendorDir = path13.join(tempDir, "vendor");
|
|
461239
461312
|
const wcDest = path13.join(vendorDir, "dotlottie-wc");
|
|
461240
|
-
await
|
|
461313
|
+
await mkdir25(wcDest, { recursive: true });
|
|
461241
461314
|
for (const file of await readdir4(wcDistDir)) {
|
|
461242
461315
|
if (file.endsWith(".map") || file.endsWith(".d.ts")) continue;
|
|
461243
461316
|
await copyFile4(path13.join(wcDistDir, file), path13.join(wcDest, file));
|
|
@@ -463279,7 +463352,7 @@ init_ai_edit();
|
|
|
463279
463352
|
init_api_key();
|
|
463280
463353
|
init_exec_safe();
|
|
463281
463354
|
init_remotion();
|
|
463282
|
-
import { resolve as
|
|
463355
|
+
import { resolve as resolve31, dirname as dirname23, basename as basename9 } from "node:path";
|
|
463283
463356
|
import { writeFile as writeFile18, mkdir as mkdir16, rm as rm4 } from "node:fs/promises";
|
|
463284
463357
|
import { existsSync as existsSync41 } from "node:fs";
|
|
463285
463358
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
@@ -463431,9 +463504,9 @@ async function executeAnimatedCaption(options) {
|
|
|
463431
463504
|
} catch {
|
|
463432
463505
|
}
|
|
463433
463506
|
const effectiveFontSize = fontSize ?? Math.round(height * 0.04);
|
|
463434
|
-
const tmpAudioDir =
|
|
463507
|
+
const tmpAudioDir = resolve31(tmpdir4(), `vf-ac-${Date.now()}`);
|
|
463435
463508
|
await mkdir16(tmpAudioDir, { recursive: true });
|
|
463436
|
-
const audioPath =
|
|
463509
|
+
const audioPath = resolve31(tmpAudioDir, "audio.wav");
|
|
463437
463510
|
await execSafe("ffmpeg", [
|
|
463438
463511
|
"-y",
|
|
463439
463512
|
"-i",
|
|
@@ -463460,7 +463533,7 @@ async function executeAnimatedCaption(options) {
|
|
|
463460
463533
|
return { success: false, error: "No words detected in transcription" };
|
|
463461
463534
|
}
|
|
463462
463535
|
const groups = groupWords(transcript.words, { wordsPerGroup, maxChars });
|
|
463463
|
-
const absOutputPath =
|
|
463536
|
+
const absOutputPath = resolve31(process.cwd(), outputPath);
|
|
463464
463537
|
const outDir = dirname23(absOutputPath);
|
|
463465
463538
|
if (!existsSync41(outDir)) {
|
|
463466
463539
|
await mkdir16(outDir, { recursive: true });
|
|
@@ -463471,7 +463544,7 @@ async function executeAnimatedCaption(options) {
|
|
|
463471
463544
|
effectiveStyle,
|
|
463472
463545
|
{ highlightColor, fontSize: effectiveFontSize, position, width, height }
|
|
463473
463546
|
);
|
|
463474
|
-
const assPath =
|
|
463547
|
+
const assPath = resolve31(tmpAudioDir, "captions.ass");
|
|
463475
463548
|
await writeFile18(assPath, assContent, "utf-8");
|
|
463476
463549
|
const escapedAssPath = assPath.replace(/\\/g, "\\\\").replace(/:/g, "\\:");
|
|
463477
463550
|
await execSafe("ffmpeg", [
|
|
@@ -463876,7 +463949,7 @@ var editFillGapsTool = defineTool({
|
|
|
463876
463949
|
cost: "high",
|
|
463877
463950
|
description: "Fill timeline gaps with AI-generated video using Kling image-to-video. Detects empty regions in a project's timeline, extracts the last frame of the preceding clip, and generates a continuation video. Requires KLING_API_KEY and IMGBB_API_KEY (image hosting for Kling).",
|
|
463878
463951
|
schema: z3.object({
|
|
463879
|
-
projectPath: z3.string().describe("
|
|
463952
|
+
projectPath: z3.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
463880
463953
|
output: z3.string().optional().describe("Output project path (default: overwrite input)"),
|
|
463881
463954
|
dir: z3.string().optional().describe("Directory to save generated videos (default: <projectDir>/footage)"),
|
|
463882
463955
|
prompt: z3.string().optional().describe("Custom prompt for video generation (default: 'Continue the scene naturally with subtle motion')"),
|
|
@@ -463940,12 +464013,12 @@ init_dist();
|
|
|
463940
464013
|
init_engine();
|
|
463941
464014
|
init_ai_helpers();
|
|
463942
464015
|
import { readFile as readFile21, writeFile as writeFile20 } from "node:fs/promises";
|
|
463943
|
-
import { resolve as
|
|
464016
|
+
import { resolve as resolve36 } from "node:path";
|
|
463944
464017
|
async function executeSuggestEdit(options) {
|
|
463945
464018
|
try {
|
|
463946
464019
|
const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY;
|
|
463947
464020
|
if (!apiKey) return { success: false, error: "GOOGLE_API_KEY required for suggest" };
|
|
463948
|
-
const filePath =
|
|
464021
|
+
const filePath = resolve36(process.cwd(), options.projectPath);
|
|
463949
464022
|
const content = await readFile21(filePath, "utf-8");
|
|
463950
464023
|
const data = JSON.parse(content);
|
|
463951
464024
|
const project = Project.fromJSON(data);
|
|
@@ -464065,7 +464138,7 @@ var analyzeSuggestTool = defineTool({
|
|
|
464065
464138
|
cost: "low",
|
|
464066
464139
|
description: "Get natural-language edit suggestions for a project from Gemini. Returns suggestions array with type/confidence/clipIds. With `apply: true`, applies the first suggestion in place. Requires GOOGLE_API_KEY.",
|
|
464067
464140
|
schema: z4.object({
|
|
464068
|
-
projectPath: z4.string().describe("
|
|
464141
|
+
projectPath: z4.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
464069
464142
|
instruction: z4.string().describe("Natural-language instruction (e.g. 'trim all clips to 5 seconds', 'add transitions between every clip')"),
|
|
464070
464143
|
apply: z4.boolean().optional().describe("Apply the first suggestion in place")
|
|
464071
464144
|
}),
|
|
@@ -464427,7 +464500,7 @@ init_ai_script_pipeline();
|
|
|
464427
464500
|
|
|
464428
464501
|
// ../cli/src/commands/ai-highlights.ts
|
|
464429
464502
|
import { readFile as readFile27, writeFile as writeFile35, mkdir as mkdir21 } from "node:fs/promises";
|
|
464430
|
-
import { resolve as
|
|
464503
|
+
import { resolve as resolve53, dirname as dirname28, basename as basename12, extname as extname11 } from "node:path";
|
|
464431
464504
|
import { existsSync as existsSync49 } from "node:fs";
|
|
464432
464505
|
init_dist();
|
|
464433
464506
|
init_engine();
|
|
@@ -464458,7 +464531,7 @@ function filterHighlights(highlights, options) {
|
|
|
464458
464531
|
}
|
|
464459
464532
|
async function executeHighlights(options) {
|
|
464460
464533
|
try {
|
|
464461
|
-
const absPath =
|
|
464534
|
+
const absPath = resolve53(process.cwd(), options.media);
|
|
464462
464535
|
if (!existsSync49(absPath)) {
|
|
464463
464536
|
return { success: false, highlights: [], totalDuration: 0, totalHighlightDuration: 0, error: `File not found: ${absPath}` };
|
|
464464
464537
|
}
|
|
@@ -464606,7 +464679,7 @@ Analyze both what is SHOWN (visual cues, actions, expressions) and what is SAID
|
|
|
464606
464679
|
totalHighlightDuration
|
|
464607
464680
|
};
|
|
464608
464681
|
if (options.output) {
|
|
464609
|
-
const outputPath =
|
|
464682
|
+
const outputPath = resolve53(process.cwd(), options.output);
|
|
464610
464683
|
await writeFile35(outputPath, JSON.stringify({
|
|
464611
464684
|
sourceFile: absPath,
|
|
464612
464685
|
totalDuration: sourceDuration,
|
|
@@ -464641,7 +464714,7 @@ Analyze both what is SHOWN (visual cues, actions, expressions) and what is SAID
|
|
|
464641
464714
|
currentTime += highlight.duration;
|
|
464642
464715
|
}
|
|
464643
464716
|
}
|
|
464644
|
-
const projectPath =
|
|
464717
|
+
const projectPath = resolve53(process.cwd(), options.project);
|
|
464645
464718
|
await writeFile35(projectPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
464646
464719
|
extractResult.projectPath = projectPath;
|
|
464647
464720
|
}
|
|
@@ -464661,7 +464734,7 @@ async function executeAutoShorts(options) {
|
|
|
464661
464734
|
if (!commandExists("ffmpeg")) {
|
|
464662
464735
|
return { success: false, shorts: [], error: "FFmpeg not found" };
|
|
464663
464736
|
}
|
|
464664
|
-
const absPath =
|
|
464737
|
+
const absPath = resolve53(process.cwd(), options.video);
|
|
464665
464738
|
if (!existsSync49(absPath)) {
|
|
464666
464739
|
return { success: false, shorts: [], error: `File not found: ${absPath}` };
|
|
464667
464740
|
}
|
|
@@ -464789,7 +464862,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
464789
464862
|
}))
|
|
464790
464863
|
};
|
|
464791
464864
|
}
|
|
464792
|
-
const outputDir = options.outputDir ?
|
|
464865
|
+
const outputDir = options.outputDir ? resolve53(process.cwd(), options.outputDir) : dirname28(absPath);
|
|
464793
464866
|
if (options.outputDir && !existsSync49(outputDir)) {
|
|
464794
464867
|
await mkdir21(outputDir, { recursive: true });
|
|
464795
464868
|
}
|
|
@@ -464800,7 +464873,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
464800
464873
|
for (let i = 0; i < selectedHighlights.length; i++) {
|
|
464801
464874
|
const h = selectedHighlights[i];
|
|
464802
464875
|
const baseName = basename12(absPath, extname11(absPath));
|
|
464803
|
-
const outputPath =
|
|
464876
|
+
const outputPath = resolve53(outputDir, `${baseName}-short-${i + 1}.mp4`);
|
|
464804
464877
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
464805
464878
|
"-v",
|
|
464806
464879
|
"error",
|
|
@@ -464868,7 +464941,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
464868
464941
|
|
|
464869
464942
|
// ../cli/src/pipeline/executor.ts
|
|
464870
464943
|
var import_yaml7 = __toESM(require_dist(), 1);
|
|
464871
|
-
import { resolve as
|
|
464944
|
+
import { resolve as resolve55 } from "node:path";
|
|
464872
464945
|
import { readFile as readFile29, writeFile as writeFile37, mkdir as mkdir23 } from "node:fs/promises";
|
|
464873
464946
|
import { existsSync as existsSync50 } from "node:fs";
|
|
464874
464947
|
|
|
@@ -464976,9 +465049,9 @@ function registerAction(action, handler4) {
|
|
|
464976
465049
|
}
|
|
464977
465050
|
function getOutput(params, outputDir, defaultName) {
|
|
464978
465051
|
if (params.output && typeof params.output === "string") {
|
|
464979
|
-
return
|
|
465052
|
+
return resolve55(outputDir, params.output);
|
|
464980
465053
|
}
|
|
464981
|
-
return
|
|
465054
|
+
return resolve55(outputDir, defaultName);
|
|
464982
465055
|
}
|
|
464983
465056
|
async function ensureActionsRegistered() {
|
|
464984
465057
|
if (Object.keys(ACTION_HANDLERS).length > 0) return;
|
|
@@ -465131,7 +465204,7 @@ async function ensureActionsRegistered() {
|
|
|
465131
465204
|
const { executeSceneBuild: executeSceneBuild2 } = await Promise.resolve().then(() => (init_scene_build(), scene_build_exports));
|
|
465132
465205
|
const projectRel = params.project ?? ".";
|
|
465133
465206
|
const r = await executeSceneBuild2({
|
|
465134
|
-
projectDir:
|
|
465207
|
+
projectDir: resolve55(outputDir, projectRel),
|
|
465135
465208
|
mode: params.mode,
|
|
465136
465209
|
effort: params.effort,
|
|
465137
465210
|
composer: params.composer,
|
|
@@ -465157,7 +465230,7 @@ async function ensureActionsRegistered() {
|
|
|
465157
465230
|
const { executeSceneRender: executeSceneRender2 } = await Promise.resolve().then(() => (init_scene_render(), scene_render_exports));
|
|
465158
465231
|
const projectRel = params.project ?? ".";
|
|
465159
465232
|
const r = await executeSceneRender2({
|
|
465160
|
-
projectDir:
|
|
465233
|
+
projectDir: resolve55(outputDir, projectRel),
|
|
465161
465234
|
root: params.root,
|
|
465162
465235
|
output: params.output,
|
|
465163
465236
|
fps: params.fps,
|
|
@@ -465181,7 +465254,7 @@ async function ensureActionsRegistered() {
|
|
|
465181
465254
|
});
|
|
465182
465255
|
}
|
|
465183
465256
|
async function loadPipeline(filePath) {
|
|
465184
|
-
const absPath =
|
|
465257
|
+
const absPath = resolve55(process.cwd(), filePath);
|
|
465185
465258
|
if (!existsSync50(absPath)) {
|
|
465186
465259
|
throw new Error(`Pipeline file not found: ${absPath}`);
|
|
465187
465260
|
}
|
|
@@ -465201,13 +465274,13 @@ async function loadPipeline(filePath) {
|
|
|
465201
465274
|
var CHECKPOINT_FILE = ".pipeline-state.yaml";
|
|
465202
465275
|
async function executePipeline(manifest2, options = {}) {
|
|
465203
465276
|
await ensureActionsRegistered();
|
|
465204
|
-
const outputDir =
|
|
465277
|
+
const outputDir = resolve55(process.cwd(), options.outputDir || `${manifest2.name}-output`);
|
|
465205
465278
|
await mkdir23(outputDir, { recursive: true });
|
|
465206
465279
|
const completedSteps = /* @__PURE__ */ new Map();
|
|
465207
465280
|
const results = [];
|
|
465208
465281
|
const startTime = Date.now();
|
|
465209
465282
|
if (options.resume) {
|
|
465210
|
-
const checkpointPath =
|
|
465283
|
+
const checkpointPath = resolve55(outputDir, CHECKPOINT_FILE);
|
|
465211
465284
|
if (existsSync50(checkpointPath)) {
|
|
465212
465285
|
const checkpointContent = await readFile29(checkpointPath, "utf-8");
|
|
465213
465286
|
const checkpoint = (0, import_yaml7.parse)(checkpointContent);
|
|
@@ -465328,7 +465401,7 @@ async function executePipeline(manifest2, options = {}) {
|
|
|
465328
465401
|
}))
|
|
465329
465402
|
};
|
|
465330
465403
|
await writeFile37(
|
|
465331
|
-
|
|
465404
|
+
resolve55(outputDir, CHECKPOINT_FILE),
|
|
465332
465405
|
(0, import_yaml7.stringify)(checkpoint, { indent: 2 }),
|
|
465333
465406
|
"utf-8"
|
|
465334
465407
|
);
|
|
@@ -465385,7 +465458,7 @@ var pipelineHighlightsTool = defineTool({
|
|
|
465385
465458
|
schema: z6.object({
|
|
465386
465459
|
media: z6.string().describe("Path to the input video file"),
|
|
465387
465460
|
output: z6.string().optional().describe("Output path for the highlights compilation"),
|
|
465388
|
-
project: z6.string().optional().describe("Path to .vibe.json
|
|
465461
|
+
project: z6.string().optional().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file to add highlights to"),
|
|
465389
465462
|
duration: z6.number().optional().describe("Maximum duration per highlight in seconds (default: 30)"),
|
|
465390
465463
|
count: z6.number().optional().describe("Maximum number of highlights to extract (default: 5)"),
|
|
465391
465464
|
threshold: z6.number().optional().describe("Minimum confidence threshold 0-1 (default: 0.7)"),
|
|
@@ -465635,14 +465708,17 @@ var detectTools = [
|
|
|
465635
465708
|
|
|
465636
465709
|
// ../cli/src/tools/manifest/timeline.ts
|
|
465637
465710
|
import { z as z8 } from "zod";
|
|
465638
|
-
import {
|
|
465711
|
+
import { mkdir as mkdir24, writeFile as writeFile40 } from "node:fs/promises";
|
|
465712
|
+
import { basename as basename14, resolve as resolve56 } from "node:path";
|
|
465713
|
+
init_engine();
|
|
465714
|
+
init_project_resolver();
|
|
465639
465715
|
|
|
465640
465716
|
// ../cli/src/tools/manifest/_project-io.ts
|
|
465641
465717
|
init_engine();
|
|
465718
|
+
init_project_resolver();
|
|
465642
465719
|
import { readFile as readFile30, writeFile as writeFile39 } from "node:fs/promises";
|
|
465643
|
-
import { resolve as resolve55 } from "node:path";
|
|
465644
465720
|
async function loadProject(projectPath, cwd) {
|
|
465645
|
-
const absPath =
|
|
465721
|
+
const absPath = await resolveTimelineFile(projectPath, cwd);
|
|
465646
465722
|
const content = await readFile30(absPath, "utf-8");
|
|
465647
465723
|
const data = JSON.parse(content);
|
|
465648
465724
|
return { project: Project.fromJSON(data), absPath };
|
|
@@ -465667,13 +465743,70 @@ var MEDIA_TYPES = {
|
|
|
465667
465743
|
gif: "image",
|
|
465668
465744
|
webp: "image"
|
|
465669
465745
|
};
|
|
465746
|
+
var timelineCreateTool = defineTool({
|
|
465747
|
+
name: "timeline_create",
|
|
465748
|
+
category: "timeline",
|
|
465749
|
+
cost: "free",
|
|
465750
|
+
description: "Create a low-level timeline JSON file for FFmpeg-style editing",
|
|
465751
|
+
schema: z8.object({
|
|
465752
|
+
name: z8.string().describe("Timeline name or directory path"),
|
|
465753
|
+
outputPath: z8.string().optional().describe("Output file path. Defaults to <name>/timeline.json"),
|
|
465754
|
+
fps: z8.number().optional().describe("Frames per second (default: 30)")
|
|
465755
|
+
}),
|
|
465756
|
+
async execute(args, ctx) {
|
|
465757
|
+
const projectName = args.name === "." ? basename14(ctx.workingDirectory) : basename14(resolve56(ctx.workingDirectory, args.name));
|
|
465758
|
+
const project = new Project(projectName);
|
|
465759
|
+
if (args.fps) project.setFrameRate(args.fps);
|
|
465760
|
+
let outputPath;
|
|
465761
|
+
if (args.outputPath) {
|
|
465762
|
+
outputPath = resolve56(ctx.workingDirectory, args.outputPath);
|
|
465763
|
+
} else {
|
|
465764
|
+
const dirPath = resolve56(ctx.workingDirectory, args.name);
|
|
465765
|
+
await mkdir24(dirPath, { recursive: true });
|
|
465766
|
+
outputPath = resolve56(dirPath, TIMELINE_FILENAME);
|
|
465767
|
+
}
|
|
465768
|
+
await writeFile40(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
465769
|
+
return {
|
|
465770
|
+
success: true,
|
|
465771
|
+
data: { name: projectName, outputPath },
|
|
465772
|
+
humanLines: [`Created timeline "${projectName}" at ${outputPath}`]
|
|
465773
|
+
};
|
|
465774
|
+
}
|
|
465775
|
+
});
|
|
465776
|
+
var timelineInfoTool = defineTool({
|
|
465777
|
+
name: "timeline_info",
|
|
465778
|
+
category: "timeline",
|
|
465779
|
+
cost: "free",
|
|
465780
|
+
description: "Get information about a timeline JSON file. Legacy *.vibe.json files are supported.",
|
|
465781
|
+
schema: z8.object({
|
|
465782
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
|
|
465783
|
+
}),
|
|
465784
|
+
async execute(args, ctx) {
|
|
465785
|
+
const { project } = await loadProject(args.projectPath, ctx.workingDirectory);
|
|
465786
|
+
const meta = project.getMeta();
|
|
465787
|
+
const info = {
|
|
465788
|
+
name: meta.name,
|
|
465789
|
+
aspectRatio: meta.aspectRatio,
|
|
465790
|
+
frameRate: meta.frameRate,
|
|
465791
|
+
duration: meta.duration,
|
|
465792
|
+
sources: project.getSources().length,
|
|
465793
|
+
tracks: project.getTracks().length,
|
|
465794
|
+
clips: project.getClips().length
|
|
465795
|
+
};
|
|
465796
|
+
return {
|
|
465797
|
+
success: true,
|
|
465798
|
+
data: info,
|
|
465799
|
+
humanLines: [JSON.stringify(info, null, 2)]
|
|
465800
|
+
};
|
|
465801
|
+
}
|
|
465802
|
+
});
|
|
465670
465803
|
var timelineAddSourceTool = defineTool({
|
|
465671
465804
|
name: "timeline_add_source",
|
|
465672
465805
|
category: "timeline",
|
|
465673
465806
|
cost: "free",
|
|
465674
|
-
description: "Add a media source (video, audio, image) to the
|
|
465807
|
+
description: "Add a media source (video, audio, image) to the timeline",
|
|
465675
465808
|
schema: z8.object({
|
|
465676
|
-
projectPath: z8.string().describe("Path to
|
|
465809
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465677
465810
|
mediaPath: z8.string().describe("Path to the media file"),
|
|
465678
465811
|
name: z8.string().optional().describe("Optional name for the source"),
|
|
465679
465812
|
duration: z8.number().optional().describe("Duration of the media in seconds (default: 10)")
|
|
@@ -465698,7 +465831,7 @@ var timelineAddClipTool = defineTool({
|
|
|
465698
465831
|
cost: "free",
|
|
465699
465832
|
description: "Add a clip to the timeline from an existing source",
|
|
465700
465833
|
schema: z8.object({
|
|
465701
|
-
projectPath: z8.string().describe("Path to
|
|
465834
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465702
465835
|
sourceId: z8.string().describe("ID of the media source"),
|
|
465703
465836
|
trackId: z8.string().optional().describe("ID of the track to add clip to (optional, uses first video track)"),
|
|
465704
465837
|
startTime: z8.number().optional().describe("Start time on timeline in seconds (default: 0)"),
|
|
@@ -465729,7 +465862,7 @@ var timelineSplitClipTool = defineTool({
|
|
|
465729
465862
|
cost: "free",
|
|
465730
465863
|
description: "Split a clip at a specific time",
|
|
465731
465864
|
schema: z8.object({
|
|
465732
|
-
projectPath: z8.string().describe("Path to
|
|
465865
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465733
465866
|
clipId: z8.string().describe("ID of the clip to split"),
|
|
465734
465867
|
splitTime: z8.number().describe("Time to split at (relative to clip start) in seconds")
|
|
465735
465868
|
}),
|
|
@@ -465747,7 +465880,7 @@ var timelineTrimClipTool = defineTool({
|
|
|
465747
465880
|
cost: "free",
|
|
465748
465881
|
description: "Trim a clip by adjusting its start or end",
|
|
465749
465882
|
schema: z8.object({
|
|
465750
|
-
projectPath: z8.string().describe("Path to
|
|
465883
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465751
465884
|
clipId: z8.string().describe("ID of the clip to trim"),
|
|
465752
465885
|
trimStart: z8.number().optional().describe("New source start offset in seconds"),
|
|
465753
465886
|
trimEnd: z8.number().optional().describe("New duration in seconds")
|
|
@@ -465766,7 +465899,7 @@ var timelineMoveClipTool = defineTool({
|
|
|
465766
465899
|
cost: "free",
|
|
465767
465900
|
description: "Move a clip to a new position or track",
|
|
465768
465901
|
schema: z8.object({
|
|
465769
|
-
projectPath: z8.string().describe("Path to
|
|
465902
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465770
465903
|
clipId: z8.string().describe("ID of the clip to move"),
|
|
465771
465904
|
newStartTime: z8.number().optional().describe("New start time on timeline in seconds"),
|
|
465772
465905
|
newTrackId: z8.string().optional().describe("ID of the target track (optional)")
|
|
@@ -465788,7 +465921,7 @@ var timelineDeleteClipTool = defineTool({
|
|
|
465788
465921
|
cost: "free",
|
|
465789
465922
|
description: "Delete a clip from the timeline",
|
|
465790
465923
|
schema: z8.object({
|
|
465791
|
-
projectPath: z8.string().describe("Path to
|
|
465924
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465792
465925
|
clipId: z8.string().describe("ID of the clip to delete")
|
|
465793
465926
|
}),
|
|
465794
465927
|
async execute(args, ctx) {
|
|
@@ -465804,7 +465937,7 @@ var timelineDuplicateClipTool = defineTool({
|
|
|
465804
465937
|
cost: "free",
|
|
465805
465938
|
description: "Duplicate a clip on the timeline (optionally at a new start time)",
|
|
465806
465939
|
schema: z8.object({
|
|
465807
|
-
projectPath: z8.string().describe("Path to
|
|
465940
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465808
465941
|
clipId: z8.string().describe("ID of the clip to duplicate"),
|
|
465809
465942
|
newStartTime: z8.number().optional().describe("Start time for the duplicated clip (optional, places after original)")
|
|
465810
465943
|
}),
|
|
@@ -465822,7 +465955,7 @@ var timelineAddEffectTool = defineTool({
|
|
|
465822
465955
|
cost: "free",
|
|
465823
465956
|
description: "Add an effect to a clip",
|
|
465824
465957
|
schema: z8.object({
|
|
465825
|
-
projectPath: z8.string().describe("Path to
|
|
465958
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465826
465959
|
clipId: z8.string().describe("ID of the clip"),
|
|
465827
465960
|
effectType: z8.string().describe("Effect type: fadeIn, fadeOut, blur, brightness, contrast, saturation, grayscale, sepia, invert"),
|
|
465828
465961
|
startTime: z8.number().optional().describe("Effect start time relative to clip (default: 0)"),
|
|
@@ -465848,7 +465981,7 @@ var timelineAddTrackTool = defineTool({
|
|
|
465848
465981
|
cost: "free",
|
|
465849
465982
|
description: "Add a new track to the timeline",
|
|
465850
465983
|
schema: z8.object({
|
|
465851
|
-
projectPath: z8.string().describe("Path to
|
|
465984
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465852
465985
|
trackType: z8.string().describe("Track type: video or audio"),
|
|
465853
465986
|
name: z8.string().optional().describe("Track name (optional)")
|
|
465854
465987
|
}),
|
|
@@ -465874,7 +466007,7 @@ var timelineListTool = defineTool({
|
|
|
465874
466007
|
cost: "free",
|
|
465875
466008
|
description: "List all sources, tracks, and clips in a project",
|
|
465876
466009
|
schema: z8.object({
|
|
465877
|
-
projectPath: z8.string().describe("Path to
|
|
466010
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
|
|
465878
466011
|
}),
|
|
465879
466012
|
async execute(args, ctx) {
|
|
465880
466013
|
const { project } = await loadProject(args.projectPath, ctx.workingDirectory);
|
|
@@ -465891,6 +466024,8 @@ var timelineListTool = defineTool({
|
|
|
465891
466024
|
}
|
|
465892
466025
|
});
|
|
465893
466026
|
var timelineTools = [
|
|
466027
|
+
timelineCreateTool,
|
|
466028
|
+
timelineInfoTool,
|
|
465894
466029
|
timelineAddSourceTool,
|
|
465895
466030
|
timelineAddClipTool,
|
|
465896
466031
|
timelineSplitClipTool,
|
|
@@ -465906,16 +466041,16 @@ var timelineTools = [
|
|
|
465906
466041
|
// ../cli/src/tools/manifest/project.ts
|
|
465907
466042
|
import { z as z9 } from "zod";
|
|
465908
466043
|
import { resolve as resolve57 } from "node:path";
|
|
465909
|
-
import { writeFile as
|
|
466044
|
+
import { writeFile as writeFile41 } from "node:fs/promises";
|
|
465910
466045
|
init_engine();
|
|
465911
466046
|
var projectCreateTool = defineTool({
|
|
465912
466047
|
name: "project_create",
|
|
465913
466048
|
category: "project",
|
|
465914
466049
|
cost: "free",
|
|
465915
|
-
description: "
|
|
466050
|
+
description: "Deprecated alias for creating low-level timeline state. Prefer timeline_create.",
|
|
465916
466051
|
schema: z9.object({
|
|
465917
466052
|
name: z9.string().describe("Project name"),
|
|
465918
|
-
outputPath: z9.string().optional().describe("Output file path (defaults to {name}.vibe.json)"),
|
|
466053
|
+
outputPath: z9.string().optional().describe("Output file path (defaults to {name}.vibe.json for legacy compatibility)"),
|
|
465919
466054
|
width: z9.number().optional().describe("Video width in pixels (default: 1920)"),
|
|
465920
466055
|
height: z9.number().optional().describe("Video height in pixels (default: 1080)"),
|
|
465921
466056
|
fps: z9.number().optional().describe("Frames per second (default: 30)")
|
|
@@ -465924,11 +466059,11 @@ var projectCreateTool = defineTool({
|
|
|
465924
466059
|
const outputPath = resolve57(ctx.workingDirectory, args.outputPath ?? `${args.name}.vibe.json`);
|
|
465925
466060
|
const project = new Project(args.name);
|
|
465926
466061
|
if (args.fps) project.setFrameRate(args.fps);
|
|
465927
|
-
await
|
|
466062
|
+
await writeFile41(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
465928
466063
|
return {
|
|
465929
466064
|
success: true,
|
|
465930
466065
|
data: { name: args.name, outputPath },
|
|
465931
|
-
humanLines: [`Created project "${args.name}" at ${outputPath}`]
|
|
466066
|
+
humanLines: [`Created legacy timeline project "${args.name}" at ${outputPath}`]
|
|
465932
466067
|
};
|
|
465933
466068
|
}
|
|
465934
466069
|
});
|
|
@@ -465936,9 +466071,9 @@ var projectInfoTool = defineTool({
|
|
|
465936
466071
|
name: "project_info",
|
|
465937
466072
|
category: "project",
|
|
465938
466073
|
cost: "free",
|
|
465939
|
-
description: "
|
|
466074
|
+
description: "Deprecated alias for timeline_info. Legacy *.vibe.json files remain supported.",
|
|
465940
466075
|
schema: z9.object({
|
|
465941
|
-
projectPath: z9.string().describe("Path to
|
|
466076
|
+
projectPath: z9.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
|
|
465942
466077
|
}),
|
|
465943
466078
|
async execute(args, ctx) {
|
|
465944
466079
|
const { project } = await loadProject(args.projectPath, ctx.workingDirectory);
|
|
@@ -465976,19 +466111,15 @@ init_engine();
|
|
|
465976
466111
|
init_exec_safe();
|
|
465977
466112
|
init_output();
|
|
465978
466113
|
init_validate();
|
|
465979
|
-
|
|
465980
|
-
import {
|
|
466114
|
+
init_project_resolver();
|
|
466115
|
+
import { readFile as readFile31, access as access6 } from "node:fs/promises";
|
|
466116
|
+
import { resolve as resolve59, basename as basename16 } from "node:path";
|
|
465981
466117
|
import { spawn as spawn9 } from "node:child_process";
|
|
465982
|
-
|
|
465983
|
-
const
|
|
465984
|
-
|
|
465985
|
-
|
|
465986
|
-
|
|
465987
|
-
return resolve59(filePath, "project.vibe.json");
|
|
465988
|
-
}
|
|
465989
|
-
} catch {
|
|
465990
|
-
}
|
|
465991
|
-
return filePath;
|
|
466118
|
+
function timelineBaseName(path14) {
|
|
466119
|
+
const name = basename16(path14);
|
|
466120
|
+
if (name.endsWith(".vibe.json")) return name.slice(0, -".vibe.json".length);
|
|
466121
|
+
if (name.endsWith(".json")) return name.slice(0, -".json".length);
|
|
466122
|
+
return basename16(path14, ".vibe.json");
|
|
465992
466123
|
}
|
|
465993
466124
|
async function getMediaDuration(filePath, mediaType, defaultImageDuration = 5) {
|
|
465994
466125
|
if (mediaType === "image") {
|
|
@@ -466057,7 +466188,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
466057
466188
|
message: "FFmpeg not found. Install with: brew install ffmpeg (macOS) or apt install ffmpeg (Linux)"
|
|
466058
466189
|
};
|
|
466059
466190
|
}
|
|
466060
|
-
const filePath = await
|
|
466191
|
+
const filePath = await resolveTimelineFile(projectPath);
|
|
466061
466192
|
const content = await readFile31(filePath, "utf-8");
|
|
466062
466193
|
const data = JSON.parse(content);
|
|
466063
466194
|
const project = Project.fromJSON(data);
|
|
@@ -466079,7 +466210,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
466079
466210
|
const source3 = sources.find((s) => s.id === clip.sourceId);
|
|
466080
466211
|
if (source3) {
|
|
466081
466212
|
try {
|
|
466082
|
-
await
|
|
466213
|
+
await access6(source3.url);
|
|
466083
466214
|
if (!sourceActualDurationMap.has(source3.id)) {
|
|
466084
466215
|
try {
|
|
466085
466216
|
const dur = await getMediaDuration(source3.url, source3.type);
|
|
@@ -466114,20 +466245,20 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
466114
466245
|
};
|
|
466115
466246
|
}
|
|
466116
466247
|
}
|
|
466117
|
-
var exportCommand = new Command("export").description("Export project to video file").argument("<project>", "
|
|
466248
|
+
var exportCommand = new Command("export").description("Export project to video file").argument("<project>", "Timeline file or directory").option("-o, --output <path>", "Output file path").option("--format <format>", "Output format (mp4, webm, mov, gif)", "mp4").option(
|
|
466118
466249
|
"--preset <preset>",
|
|
466119
466250
|
"Quality preset (draft, standard, high, ultra)",
|
|
466120
466251
|
"standard"
|
|
466121
466252
|
).option("--overwrite", "Overwrite output file if exists", false).option("--gap-fill <strategy>", "Gap filling strategy (black, extend)", "extend").option("--backend <name>", "Render backend: ffmpeg (default) | hyperframes (experimental)", "ffmpeg").option("--bitrate <value>", "Video bitrate (e.g. 5000k, 8M) \u2014 overrides preset").option("--fps <number>", "Frames per second (e.g. 24, 30, 60) \u2014 overrides preset").option("--resolution <WxH>", "Output resolution (e.g. 1920x1080) \u2014 overrides preset").option("--codec <codec>", "Video codec: h264 (default) | h265 | vp9 \u2014 overrides preset").option("--dry-run", "Preview parameters without executing").addHelpText("after", `
|
|
466122
466253
|
Examples:
|
|
466123
|
-
$ vibe export
|
|
466124
|
-
$ vibe export
|
|
466125
|
-
$ vibe export
|
|
466126
|
-
$ vibe export
|
|
466127
|
-
$ vibe export
|
|
466128
|
-
$ vibe export
|
|
466129
|
-
|
|
466130
|
-
Cost: Free (no API keys needed). Requires FFmpeg.
|
|
466254
|
+
$ vibe export timeline.json -o output.mp4
|
|
466255
|
+
$ vibe export my-video -o output.mp4 --preset high --overwrite
|
|
466256
|
+
$ vibe export timeline.json -o output.webm --format webm
|
|
466257
|
+
$ vibe export timeline.json -o output.gif --format gif
|
|
466258
|
+
$ vibe export timeline.json -o out.mp4 --bitrate 5000k --fps 24 --codec h265
|
|
466259
|
+
$ vibe export timeline.json -o out.mp4 --preset high --fps 60
|
|
466260
|
+
|
|
466261
|
+
Cost: Free (no API keys needed). Requires FFmpeg. Legacy *.vibe.json files remain supported.
|
|
466131
466262
|
GIF format: 15fps, no audio, looping. Good for previews and sharing.
|
|
466132
466263
|
Custom flags (--bitrate, --fps, --resolution, --codec) override preset values.
|
|
466133
466264
|
Run 'vibe schema export' for structured parameter info.`).action(async (projectPath, options) => {
|
|
@@ -466181,7 +466312,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
466181
466312
|
exitWithError(generalError("FFmpeg not found", "Install with: brew install ffmpeg (macOS), apt install ffmpeg (Linux), or winget install ffmpeg (Windows)"));
|
|
466182
466313
|
}
|
|
466183
466314
|
spinner2.text = "Loading project...";
|
|
466184
|
-
const filePath = await
|
|
466315
|
+
const filePath = await resolveTimelineFile(projectPath);
|
|
466185
466316
|
const content = await readFile31(filePath, "utf-8");
|
|
466186
466317
|
const data = JSON.parse(content);
|
|
466187
466318
|
const project = Project.fromJSON(data);
|
|
@@ -466192,7 +466323,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
466192
466323
|
}
|
|
466193
466324
|
const outputPath = options.output ? resolve59(process.cwd(), options.output) : resolve59(
|
|
466194
466325
|
process.cwd(),
|
|
466195
|
-
`${
|
|
466326
|
+
`${timelineBaseName(projectPath)}.${options.format}`
|
|
466196
466327
|
);
|
|
466197
466328
|
const basePresetSettings = getPresetSettings(options.preset, summary.aspectRatio);
|
|
466198
466329
|
const presetSettings = applyCustomOverrides(basePresetSettings, customOverrides);
|
|
@@ -466205,7 +466336,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
466205
466336
|
const source3 = sources.find((s) => s.id === clip.sourceId);
|
|
466206
466337
|
if (source3) {
|
|
466207
466338
|
try {
|
|
466208
|
-
await
|
|
466339
|
+
await access6(source3.url);
|
|
466209
466340
|
if (!sourceActualDurationMap.has(source3.id)) {
|
|
466210
466341
|
try {
|
|
466211
466342
|
const dur = await getMediaDuration(source3.url, source3.type);
|
|
@@ -466781,16 +466912,16 @@ function getPresetSettings(preset, aspectRatio) {
|
|
|
466781
466912
|
async function runHyperframesExport(projectPath, options, spinner2, startedAt) {
|
|
466782
466913
|
spinner2.text = "Loading project...";
|
|
466783
466914
|
const { readFile: readFile34 } = await import("node:fs/promises");
|
|
466784
|
-
const { resolve: resolve64
|
|
466915
|
+
const { resolve: resolve64 } = await import("node:path");
|
|
466785
466916
|
const { Project: Project2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
|
|
466786
466917
|
const { createHyperframesBackend: createHyperframesBackend2 } = await Promise.resolve().then(() => (init_hyperframes(), hyperframes_exports));
|
|
466787
466918
|
const { exitWithError: exitWithError2, generalError: generalError2, outputSuccess: outputSuccess2 } = await Promise.resolve().then(() => (init_output(), output_exports));
|
|
466788
466919
|
const chalk2 = (await Promise.resolve().then(() => (init_source(), source_exports))).default;
|
|
466789
|
-
const filePath =
|
|
466920
|
+
const filePath = await resolveTimelineFile(projectPath);
|
|
466790
466921
|
const content = await readFile34(filePath, "utf-8");
|
|
466791
466922
|
const project = Project2.fromJSON(JSON.parse(content));
|
|
466792
466923
|
const state = project.getState();
|
|
466793
|
-
const outputPath = options.output ? resolve64(process.cwd(), options.output) : resolve64(process.cwd(), `${
|
|
466924
|
+
const outputPath = options.output ? resolve64(process.cwd(), options.output) : resolve64(process.cwd(), `${timelineBaseName(projectPath)}.${options.format ?? "mp4"}`);
|
|
466794
466925
|
const quality = ["draft", "standard", "high"].includes(options.preset ?? "") ? options.preset : "standard";
|
|
466795
466926
|
const backend = createHyperframesBackend2();
|
|
466796
466927
|
spinner2.text = "Rendering with Hyperframes...";
|
|
@@ -466827,9 +466958,9 @@ var exportVideoTool = defineTool({
|
|
|
466827
466958
|
name: "export_video",
|
|
466828
466959
|
category: "export",
|
|
466829
466960
|
cost: "free",
|
|
466830
|
-
description: "Export a VibeFrame
|
|
466961
|
+
description: "Export a VibeFrame timeline to a video file (MP4, WebM, or MOV). Requires FFmpeg.",
|
|
466831
466962
|
schema: z10.object({
|
|
466832
|
-
projectPath: z10.string().describe("Path to
|
|
466963
|
+
projectPath: z10.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
466833
466964
|
outputPath: z10.string().describe("Output video file path (e.g., output.mp4)"),
|
|
466834
466965
|
preset: z10.enum(["draft", "standard", "high", "ultra"]).optional().describe("Quality preset (default: standard)"),
|
|
466835
466966
|
format: z10.enum(["mp4", "webm", "mov"]).optional().describe("Output format (default: mp4)"),
|
|
@@ -466854,11 +466985,12 @@ var exportVideoTool = defineTool({
|
|
|
466854
466985
|
var exportTools = [exportVideoTool];
|
|
466855
466986
|
|
|
466856
466987
|
// ../cli/src/tools/manifest/agent-only.ts
|
|
466857
|
-
import { readFile as readFile32, writeFile as
|
|
466858
|
-
import { resolve as resolve61, join as join33, basename as
|
|
466988
|
+
import { readFile as readFile32, writeFile as writeFile43, readdir as readdir5, stat as stat4, access as access7, unlink as unlink7 } from "node:fs/promises";
|
|
466989
|
+
import { resolve as resolve61, join as join33, basename as basename17, extname as extname12 } from "node:path";
|
|
466859
466990
|
import { z as z11 } from "zod";
|
|
466860
466991
|
init_engine();
|
|
466861
466992
|
init_exec_safe();
|
|
466993
|
+
init_project_resolver();
|
|
466862
466994
|
function matchPattern(filename, pattern) {
|
|
466863
466995
|
const regex2 = new RegExp(
|
|
466864
466996
|
"^" + pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".") + "$",
|
|
@@ -466981,7 +467113,7 @@ var fsWriteTool = defineTool({
|
|
|
466981
467113
|
async execute(args, ctx) {
|
|
466982
467114
|
try {
|
|
466983
467115
|
const absPath = resolve61(ctx.workingDirectory, args.path);
|
|
466984
|
-
await
|
|
467116
|
+
await writeFile43(absPath, args.content, "utf-8");
|
|
466985
467117
|
return { success: true, data: { bytes: args.content.length }, humanLines: [`File written: ${args.path} (${formatSize(args.content.length)})`] };
|
|
466986
467118
|
} catch (error) {
|
|
466987
467119
|
return { success: false, error: `Failed to write file: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -467000,7 +467132,7 @@ var fsExistsTool = defineTool({
|
|
|
467000
467132
|
async execute(args, ctx) {
|
|
467001
467133
|
const absPath = resolve61(ctx.workingDirectory, args.path);
|
|
467002
467134
|
try {
|
|
467003
|
-
await
|
|
467135
|
+
await access7(absPath);
|
|
467004
467136
|
const stats = await stat4(absPath);
|
|
467005
467137
|
const type = stats.isDirectory() ? "directory" : "file";
|
|
467006
467138
|
return { success: true, data: { exists: true, type }, humanLines: [`${type} exists: ${args.path}`] };
|
|
@@ -467016,7 +467148,7 @@ var batchImportTool = defineTool({
|
|
|
467016
467148
|
surfaces: ["agent"],
|
|
467017
467149
|
description: "Import multiple media files from a directory into a project. Scans directory for video, audio, and image files.",
|
|
467018
467150
|
schema: z11.object({
|
|
467019
|
-
project: z11.string().describe("
|
|
467151
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467020
467152
|
directory: z11.string().describe("Directory containing media files to import"),
|
|
467021
467153
|
recursive: z11.boolean().optional().describe("Search subdirectories recursively (default: false)"),
|
|
467022
467154
|
filter: z11.string().optional().describe("Filter files by extension, comma-separated (e.g., '.mp4,.mov')"),
|
|
@@ -467053,7 +467185,7 @@ var batchImportTool = defineTool({
|
|
|
467053
467185
|
mediaFiles.sort();
|
|
467054
467186
|
const addedSources = [];
|
|
467055
467187
|
for (const mediaFile of mediaFiles) {
|
|
467056
|
-
const mediaName =
|
|
467188
|
+
const mediaName = basename17(mediaFile);
|
|
467057
467189
|
const mediaType = detectMediaType(mediaFile);
|
|
467058
467190
|
let duration = imageDuration;
|
|
467059
467191
|
if (mediaType !== "image") {
|
|
@@ -467063,7 +467195,7 @@ var batchImportTool = defineTool({
|
|
|
467063
467195
|
const source3 = project.addSource({ name: mediaName, type: mediaType, url: mediaFile, duration });
|
|
467064
467196
|
addedSources.push({ id: source3.id, name: mediaName, type: mediaType });
|
|
467065
467197
|
}
|
|
467066
|
-
await
|
|
467198
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467067
467199
|
return {
|
|
467068
467200
|
success: true,
|
|
467069
467201
|
data: { count: addedSources.length, sources: addedSources },
|
|
@@ -467085,7 +467217,7 @@ var batchConcatTool = defineTool({
|
|
|
467085
467217
|
surfaces: ["agent"],
|
|
467086
467218
|
description: "Concatenate multiple sources into sequential clips on the timeline",
|
|
467087
467219
|
schema: z11.object({
|
|
467088
|
-
project: z11.string().describe("
|
|
467220
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467089
467221
|
sourceIds: z11.array(z11.string()).optional().describe("Source IDs to concatenate. If empty with useAll=true, uses all sources."),
|
|
467090
467222
|
useAll: z11.boolean().optional().describe("Use all sources in the project (default: false)"),
|
|
467091
467223
|
trackId: z11.string().optional().describe("Track to place clips on (auto-selects if not specified)"),
|
|
@@ -467131,7 +467263,7 @@ var batchConcatTool = defineTool({
|
|
|
467131
467263
|
createdClips.push({ id: clip.id, sourceName: source3.name, startTime: currentTime, duration: source3.duration });
|
|
467132
467264
|
currentTime += source3.duration + gap;
|
|
467133
467265
|
}
|
|
467134
|
-
await
|
|
467266
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467135
467267
|
const totalDuration = currentTime - gap - startTime;
|
|
467136
467268
|
return {
|
|
467137
467269
|
success: true,
|
|
@@ -467154,7 +467286,7 @@ var batchApplyEffectTool = defineTool({
|
|
|
467154
467286
|
surfaces: ["agent"],
|
|
467155
467287
|
description: "Apply an effect to multiple clips at once",
|
|
467156
467288
|
schema: z11.object({
|
|
467157
|
-
project: z11.string().describe("
|
|
467289
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467158
467290
|
clipIds: z11.array(z11.string()).optional().describe("Clip IDs to apply effect to. If empty with useAll=true, applies to all clips."),
|
|
467159
467291
|
useAll: z11.boolean().optional().describe("Apply to all clips in the project (default: false)"),
|
|
467160
467292
|
effectType: z11.enum(["fadeIn", "fadeOut", "blur", "brightness", "contrast", "saturation", "speed", "volume"]).describe("Effect type to apply"),
|
|
@@ -467192,7 +467324,7 @@ var batchApplyEffectTool = defineTool({
|
|
|
467192
467324
|
});
|
|
467193
467325
|
if (effect) appliedEffects.push({ clipId: clip.id, effectId: effect.id });
|
|
467194
467326
|
}
|
|
467195
|
-
await
|
|
467327
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467196
467328
|
return {
|
|
467197
467329
|
success: true,
|
|
467198
467330
|
data: { applied: appliedEffects.length, effectType: args.effectType },
|
|
@@ -467203,17 +467335,6 @@ var batchApplyEffectTool = defineTool({
|
|
|
467203
467335
|
}
|
|
467204
467336
|
}
|
|
467205
467337
|
});
|
|
467206
|
-
async function resolveProjectPath2(inputPath, cwd) {
|
|
467207
|
-
const filePath = resolve61(cwd, inputPath);
|
|
467208
|
-
try {
|
|
467209
|
-
const stats = await stat4(filePath);
|
|
467210
|
-
if (stats.isDirectory()) {
|
|
467211
|
-
return resolve61(filePath, "project.vibe.json");
|
|
467212
|
-
}
|
|
467213
|
-
} catch {
|
|
467214
|
-
}
|
|
467215
|
-
return filePath;
|
|
467216
|
-
}
|
|
467217
467338
|
var timelineClearTool = defineTool({
|
|
467218
467339
|
name: "timeline_clear",
|
|
467219
467340
|
category: "agent-only",
|
|
@@ -467221,13 +467342,13 @@ var timelineClearTool = defineTool({
|
|
|
467221
467342
|
surfaces: ["agent"],
|
|
467222
467343
|
description: "Clear timeline contents (remove clips, tracks, or sources)",
|
|
467223
467344
|
schema: z11.object({
|
|
467224
|
-
project: z11.string().describe("
|
|
467345
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467225
467346
|
what: z11.enum(["clips", "tracks", "sources", "all"]).optional().describe("What to clear: clips (default), tracks, sources, or all"),
|
|
467226
467347
|
keepTracks: z11.boolean().optional().describe("When clearing 'all', keep default empty tracks (default: true)")
|
|
467227
467348
|
}),
|
|
467228
467349
|
async execute(args, ctx) {
|
|
467229
467350
|
try {
|
|
467230
|
-
const filePath = await
|
|
467351
|
+
const filePath = await resolveTimelineFile(args.project, ctx.workingDirectory);
|
|
467231
467352
|
const content = await readFile32(filePath, "utf-8");
|
|
467232
467353
|
const data = JSON.parse(content);
|
|
467233
467354
|
const project = Project.fromJSON(data);
|
|
@@ -467270,7 +467391,7 @@ var timelineClearTool = defineTool({
|
|
|
467270
467391
|
removed.sources++;
|
|
467271
467392
|
}
|
|
467272
467393
|
}
|
|
467273
|
-
await
|
|
467394
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467274
467395
|
const parts = [];
|
|
467275
467396
|
if (removed.clips > 0) parts.push(`${removed.clips} clips`);
|
|
467276
467397
|
if (removed.tracks > 0) parts.push(`${removed.tracks} tracks`);
|
|
@@ -467293,16 +467414,16 @@ var projectSetTool = defineTool({
|
|
|
467293
467414
|
category: "agent-only",
|
|
467294
467415
|
cost: "free",
|
|
467295
467416
|
surfaces: ["agent"],
|
|
467296
|
-
description: "Update
|
|
467417
|
+
description: "Update timeline settings (name, aspect ratio, frame rate)",
|
|
467297
467418
|
schema: z11.object({
|
|
467298
|
-
projectPath: z11.string().describe("
|
|
467419
|
+
projectPath: z11.string().describe("Timeline file or directory"),
|
|
467299
467420
|
name: z11.string().optional().describe("New project name"),
|
|
467300
467421
|
aspectRatio: z11.enum(["16:9", "9:16", "1:1", "4:5"]).optional().describe("New aspect ratio"),
|
|
467301
467422
|
fps: z11.number().optional().describe("New frame rate")
|
|
467302
467423
|
}),
|
|
467303
467424
|
async execute(args, ctx) {
|
|
467304
467425
|
try {
|
|
467305
|
-
const filePath = await
|
|
467426
|
+
const filePath = await resolveTimelineFile(args.projectPath, ctx.workingDirectory);
|
|
467306
467427
|
const content = await readFile32(filePath, "utf-8");
|
|
467307
467428
|
const data = JSON.parse(content);
|
|
467308
467429
|
const project = Project.fromJSON(data);
|
|
@@ -467319,7 +467440,7 @@ var projectSetTool = defineTool({
|
|
|
467319
467440
|
project.setFrameRate(args.fps);
|
|
467320
467441
|
updates.push(`Frame Rate: ${args.fps} fps`);
|
|
467321
467442
|
}
|
|
467322
|
-
await
|
|
467443
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467323
467444
|
return {
|
|
467324
467445
|
success: true,
|
|
467325
467446
|
data: { updates },
|
|
@@ -467340,11 +467461,11 @@ var projectOpenTool = defineTool({
|
|
|
467340
467461
|
surfaces: ["agent"],
|
|
467341
467462
|
description: "Open an existing project and set it as the current context",
|
|
467342
467463
|
schema: z11.object({
|
|
467343
|
-
projectPath: z11.string().describe("
|
|
467464
|
+
projectPath: z11.string().describe("Timeline file or directory")
|
|
467344
467465
|
}),
|
|
467345
467466
|
async execute(args, ctx) {
|
|
467346
467467
|
try {
|
|
467347
|
-
const filePath = await
|
|
467468
|
+
const filePath = await resolveTimelineFile(args.projectPath, ctx.workingDirectory);
|
|
467348
467469
|
const { project } = await loadProject(filePath, "");
|
|
467349
467470
|
ctx.agent?.setProjectPath(filePath);
|
|
467350
467471
|
const summary = project.getSummary();
|
|
@@ -467378,7 +467499,7 @@ var projectSaveTool = defineTool({
|
|
|
467378
467499
|
surfaces: ["agent"],
|
|
467379
467500
|
description: "Save the current project (uses ctx.agent.projectPath if no path given)",
|
|
467380
467501
|
schema: z11.object({
|
|
467381
|
-
projectPath: z11.string().optional().describe("
|
|
467502
|
+
projectPath: z11.string().optional().describe("Timeline file or directory (uses current agent timeline if omitted)")
|
|
467382
467503
|
}),
|
|
467383
467504
|
async execute(args, ctx) {
|
|
467384
467505
|
const path14 = args.projectPath ?? ctx.agent?.projectPath ?? null;
|
|
@@ -467389,7 +467510,7 @@ var projectSaveTool = defineTool({
|
|
|
467389
467510
|
};
|
|
467390
467511
|
}
|
|
467391
467512
|
try {
|
|
467392
|
-
const filePath = await
|
|
467513
|
+
const filePath = await resolveTimelineFile(path14, ctx.workingDirectory);
|
|
467393
467514
|
const { project, absPath } = await loadProject(filePath, "");
|
|
467394
467515
|
await saveProject(absPath, project);
|
|
467395
467516
|
return {
|
|
@@ -467412,7 +467533,7 @@ var exportAudioTool = defineTool({
|
|
|
467412
467533
|
surfaces: ["agent"],
|
|
467413
467534
|
description: "Export audio track from a project. Not implemented \u2014 use export_video then strip audio with FFmpeg.",
|
|
467414
467535
|
schema: z11.object({
|
|
467415
|
-
project: z11.string().describe("
|
|
467536
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467416
467537
|
output: z11.string().optional().describe("Output audio file path"),
|
|
467417
467538
|
format: z11.enum(["mp3", "wav", "aac"]).optional().describe("Output format (mp3, wav, aac)")
|
|
467418
467539
|
}),
|
|
@@ -467430,7 +467551,7 @@ var exportSubtitlesTool = defineTool({
|
|
|
467430
467551
|
surfaces: ["agent"],
|
|
467431
467552
|
description: "Export subtitles from transcription. Not implemented \u2014 use audio_transcribe to generate subtitles from audio.",
|
|
467432
467553
|
schema: z11.object({
|
|
467433
|
-
project: z11.string().describe("
|
|
467554
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467434
467555
|
output: z11.string().optional().describe("Output subtitle file path"),
|
|
467435
467556
|
format: z11.enum(["srt", "vtt"]).optional().describe("Subtitle format (srt, vtt)")
|
|
467436
467557
|
}),
|
|
@@ -467673,7 +467794,7 @@ var mediaConcatTool = defineTool({
|
|
|
467673
467794
|
} else {
|
|
467674
467795
|
const tempList = resolve61(ctx.workingDirectory, `concat-list-${Date.now()}.txt`);
|
|
467675
467796
|
const listContent = args.inputs.map((i) => `file '${resolve61(ctx.workingDirectory, i)}'`).join("\n");
|
|
467676
|
-
await
|
|
467797
|
+
await writeFile43(tempList, listContent, "utf-8");
|
|
467677
467798
|
try {
|
|
467678
467799
|
await execSafe(
|
|
467679
467800
|
"ffmpeg",
|
|
@@ -468310,7 +468431,7 @@ async function readResource(uri) {
|
|
|
468310
468431
|
uri,
|
|
468311
468432
|
mimeType: "application/json",
|
|
468312
468433
|
text: JSON.stringify({
|
|
468313
|
-
error: "No
|
|
468434
|
+
error: "No timeline loaded. Set VIBE_PROJECT_PATH to timeline.json or use timeline_create."
|
|
468314
468435
|
})
|
|
468315
468436
|
}
|
|
468316
468437
|
]
|
|
@@ -468406,7 +468527,7 @@ var prompts = [
|
|
|
468406
468527
|
},
|
|
468407
468528
|
{
|
|
468408
468529
|
name: "projectPath",
|
|
468409
|
-
description: "Path to
|
|
468530
|
+
description: "Path to timeline.json or a legacy *.vibe.json file",
|
|
468410
468531
|
required: false
|
|
468411
468532
|
}
|
|
468412
468533
|
]
|
|
@@ -468524,7 +468645,7 @@ function getPrompt(name, args) {
|
|
|
468524
468645
|
type: "text",
|
|
468525
468646
|
text: `Help me edit a video with the following instruction: "${args.instruction}"
|
|
468526
468647
|
|
|
468527
|
-
${args.projectPath ? `
|
|
468648
|
+
${args.projectPath ? `Timeline file: ${args.projectPath}` : "No timeline file specified."}
|
|
468528
468649
|
|
|
468529
468650
|
Please analyze the request and suggest the appropriate timeline tools to use. Consider:
|
|
468530
468651
|
1. What clips need to be affected?
|