@vibeframe/mcp-server 0.79.3 → 0.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/index.js +479 -367
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -14031,6 +14031,9 @@ function getSetupProviders() {
|
|
|
14031
14031
|
function getAllApiKeys() {
|
|
14032
14032
|
return [...apiKeyRegistry.values()];
|
|
14033
14033
|
}
|
|
14034
|
+
function getKeyFormat(configKey) {
|
|
14035
|
+
return apiKeyRegistry.get(configKey)?.keyFormat;
|
|
14036
|
+
}
|
|
14034
14037
|
function getAllProviders() {
|
|
14035
14038
|
return [...providerRegistry2.values()];
|
|
14036
14039
|
}
|
|
@@ -14055,7 +14058,8 @@ var init_api_keys = __esm({
|
|
|
14055
14058
|
showInSetup: true,
|
|
14056
14059
|
setupDescription: "gpt-image-2 image gen ($, default since v0.56), Whisper transcribe, Agent",
|
|
14057
14060
|
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"
|
|
14061
|
+
envExampleUrl: "https://platform.openai.com/api-keys",
|
|
14062
|
+
keyFormat: { prefix: /^sk-/, example: "sk-..." }
|
|
14059
14063
|
});
|
|
14060
14064
|
defineApiKey({
|
|
14061
14065
|
configKey: "google",
|
|
@@ -14064,7 +14068,8 @@ var init_api_keys = __esm({
|
|
|
14064
14068
|
showInSetup: true,
|
|
14065
14069
|
setupDescription: "Gemini \u2014 image gen (free tier), video analysis ($), Veo ($$)",
|
|
14066
14070
|
envExampleComment: "Google API Key (Gemini auto-edit suggestions, image gen, Veo video)",
|
|
14067
|
-
envExampleUrl: "https://aistudio.google.com/apikey"
|
|
14071
|
+
envExampleUrl: "https://aistudio.google.com/apikey",
|
|
14072
|
+
keyFormat: { prefix: /^AIza/, example: "AIza..." }
|
|
14068
14073
|
});
|
|
14069
14074
|
defineApiKey({
|
|
14070
14075
|
configKey: "anthropic",
|
|
@@ -14073,7 +14078,8 @@ var init_api_keys = __esm({
|
|
|
14073
14078
|
showInSetup: true,
|
|
14074
14079
|
setupDescription: "Claude \u2014 storyboard, color grade, reframe, Agent ($)",
|
|
14075
14080
|
envExampleComment: "Anthropic API Key (Claude motion graphics & storyboarding)",
|
|
14076
|
-
envExampleUrl: "https://console.anthropic.com/"
|
|
14081
|
+
envExampleUrl: "https://console.anthropic.com/",
|
|
14082
|
+
keyFormat: { prefix: /^sk-ant-/, example: "sk-ant-..." }
|
|
14077
14083
|
});
|
|
14078
14084
|
defineApiKey({
|
|
14079
14085
|
configKey: "elevenlabs",
|
|
@@ -14082,7 +14088,8 @@ var init_api_keys = __esm({
|
|
|
14082
14088
|
showInSetup: true,
|
|
14083
14089
|
setupDescription: "TTS ($), SFX, music, voice clone, dubbing \u2014 skip to use local Kokoro",
|
|
14084
14090
|
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"
|
|
14091
|
+
envExampleUrl: "https://elevenlabs.io/api",
|
|
14092
|
+
keyFormat: { prefix: /^sk_/, example: "sk_..." }
|
|
14086
14093
|
});
|
|
14087
14094
|
defineApiKey({
|
|
14088
14095
|
configKey: "fal",
|
|
@@ -14100,7 +14107,8 @@ var init_api_keys = __esm({
|
|
|
14100
14107
|
showInSetup: true,
|
|
14101
14108
|
setupDescription: "Grok \u2014 video gen with audio ($$), image ($), Agent",
|
|
14102
14109
|
envExampleComment: "xAI API Key (Grok video generation \u2014 fallback when no FAL_KEY)",
|
|
14103
|
-
envExampleUrl: "https://console.x.ai/"
|
|
14110
|
+
envExampleUrl: "https://console.x.ai/",
|
|
14111
|
+
keyFormat: { prefix: /^xai-/, example: "xai-..." }
|
|
14104
14112
|
});
|
|
14105
14113
|
defineApiKey({
|
|
14106
14114
|
configKey: "runway",
|
|
@@ -14109,7 +14117,8 @@ var init_api_keys = __esm({
|
|
|
14109
14117
|
showInSetup: true,
|
|
14110
14118
|
setupDescription: "Gen-4.5 video generation ($$)",
|
|
14111
14119
|
envExampleComment: "Runway API Secret (Runway Gen-4.5 video generation)",
|
|
14112
|
-
envExampleUrl: "https://app.runwayml.com/settings/api-keys"
|
|
14120
|
+
envExampleUrl: "https://app.runwayml.com/settings/api-keys",
|
|
14121
|
+
keyFormat: { prefix: /^key_/, example: "key_..." }
|
|
14113
14122
|
});
|
|
14114
14123
|
defineApiKey({
|
|
14115
14124
|
configKey: "kling",
|
|
@@ -14119,7 +14128,8 @@ var init_api_keys = __esm({
|
|
|
14119
14128
|
setupDescription: "v2.5/v3 video \u2014 std ($$) and pro ($$$) modes",
|
|
14120
14129
|
envExampleComment: "Kling API Key (Kling video generation)",
|
|
14121
14130
|
envExampleUrl: "https://platform.klingai.com/",
|
|
14122
|
-
envExampleExtraLines: ["Format: ACCESS_KEY:SECRET_KEY"]
|
|
14131
|
+
envExampleExtraLines: ["Format: ACCESS_KEY:SECRET_KEY"],
|
|
14132
|
+
keyFormat: { prefix: /:/, example: "ACCESS_KEY:SECRET_KEY" }
|
|
14123
14133
|
});
|
|
14124
14134
|
defineApiKey({
|
|
14125
14135
|
configKey: "replicate",
|
|
@@ -14128,7 +14138,8 @@ var init_api_keys = __esm({
|
|
|
14128
14138
|
showInSetup: true,
|
|
14129
14139
|
setupDescription: "MusicGen background music ($, max 30s)",
|
|
14130
14140
|
envExampleComment: "Replicate API Token (music generation, video upscale, audio restoration)",
|
|
14131
|
-
envExampleUrl: "https://replicate.com/account/api-tokens"
|
|
14141
|
+
envExampleUrl: "https://replicate.com/account/api-tokens",
|
|
14142
|
+
keyFormat: { prefix: /^r8_/, example: "r8_..." }
|
|
14132
14143
|
});
|
|
14133
14144
|
defineApiKey({
|
|
14134
14145
|
configKey: "openrouter",
|
|
@@ -14137,7 +14148,8 @@ var init_api_keys = __esm({
|
|
|
14137
14148
|
showInSetup: true,
|
|
14138
14149
|
setupDescription: "300+ models via one key \u2014 Agent only (pay per model)",
|
|
14139
14150
|
envExampleComment: "OpenRouter API Key (300+ AI models via unified API, used by `vibe agent`)",
|
|
14140
|
-
envExampleUrl: "https://openrouter.ai/keys"
|
|
14151
|
+
envExampleUrl: "https://openrouter.ai/keys",
|
|
14152
|
+
keyFormat: { prefix: /^sk-or-/, example: "sk-or-..." }
|
|
14141
14153
|
});
|
|
14142
14154
|
defineApiKey({
|
|
14143
14155
|
configKey: "imgbb",
|
|
@@ -24922,6 +24934,7 @@ __export(dist_exports, {
|
|
|
24922
24934
|
getAllProviders: () => getAllProviders,
|
|
24923
24935
|
getBestProviderForCapability: () => getBestProviderForCapability,
|
|
24924
24936
|
getCommandKeyMap: () => getCommandKeyMap,
|
|
24937
|
+
getKeyFormat: () => getKeyFormat,
|
|
24925
24938
|
getProviderEnvVars: () => getProviderEnvVars,
|
|
24926
24939
|
getProvidersFor: () => getProvidersFor,
|
|
24927
24940
|
getSetupProviders: () => getSetupProviders,
|
|
@@ -127672,7 +127685,7 @@ var require_typescript2 = __commonJS({
|
|
|
127672
127685
|
walkUpParenthesizedTypesAndGetParentAndChild: () => walkUpParenthesizedTypesAndGetParentAndChild,
|
|
127673
127686
|
whitespaceOrMapCommentRegExp: () => whitespaceOrMapCommentRegExp,
|
|
127674
127687
|
writeCommentRange: () => writeCommentRange,
|
|
127675
|
-
writeFile: () =>
|
|
127688
|
+
writeFile: () => writeFile44,
|
|
127676
127689
|
writeFileEnsuringDirectories: () => writeFileEnsuringDirectories,
|
|
127677
127690
|
zipWith: () => zipWith
|
|
127678
127691
|
});
|
|
@@ -146315,7 +146328,7 @@ ${lanes.join("\n")}
|
|
|
146315
146328
|
sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath;
|
|
146316
146329
|
return combinePaths(newDirPath, sourceFilePath);
|
|
146317
146330
|
}
|
|
146318
|
-
function
|
|
146331
|
+
function writeFile44(host, diagnostics, fileName, text, writeByteOrderMark, sourceFiles, data) {
|
|
146319
146332
|
host.writeFile(
|
|
146320
146333
|
fileName,
|
|
146321
146334
|
text,
|
|
@@ -147409,15 +147422,15 @@ ${lanes.join("\n")}
|
|
|
147409
147422
|
if (isAccessExpression(name.parent) && isRightSideOfAccessExpression(name)) {
|
|
147410
147423
|
return walkAccessExpression(name.parent);
|
|
147411
147424
|
}
|
|
147412
|
-
function walkAccessExpression(
|
|
147413
|
-
if (
|
|
147414
|
-
const res = action(
|
|
147425
|
+
function walkAccessExpression(access8) {
|
|
147426
|
+
if (access8.kind === 212) {
|
|
147427
|
+
const res = action(access8.name);
|
|
147415
147428
|
if (res !== void 0) {
|
|
147416
147429
|
return res;
|
|
147417
147430
|
}
|
|
147418
|
-
} else if (
|
|
147419
|
-
if (isIdentifier(
|
|
147420
|
-
const res = action(
|
|
147431
|
+
} else if (access8.kind === 213) {
|
|
147432
|
+
if (isIdentifier(access8.argumentExpression) || isStringLiteralLike(access8.argumentExpression)) {
|
|
147433
|
+
const res = action(access8.argumentExpression);
|
|
147421
147434
|
if (res !== void 0) {
|
|
147422
147435
|
return res;
|
|
147423
147436
|
}
|
|
@@ -147425,11 +147438,11 @@ ${lanes.join("\n")}
|
|
|
147425
147438
|
return void 0;
|
|
147426
147439
|
}
|
|
147427
147440
|
}
|
|
147428
|
-
if (isAccessExpression(
|
|
147429
|
-
return walkAccessExpression(
|
|
147441
|
+
if (isAccessExpression(access8.expression)) {
|
|
147442
|
+
return walkAccessExpression(access8.expression);
|
|
147430
147443
|
}
|
|
147431
|
-
if (isIdentifier(
|
|
147432
|
-
return action(
|
|
147444
|
+
if (isIdentifier(access8.expression)) {
|
|
147445
|
+
return action(access8.expression);
|
|
147433
147446
|
}
|
|
147434
147447
|
return void 0;
|
|
147435
147448
|
}
|
|
@@ -156682,11 +156695,11 @@ ${lanes.join("\n")}
|
|
|
156682
156695
|
)
|
|
156683
156696
|
);
|
|
156684
156697
|
}
|
|
156685
|
-
function createESDecorateClassElementAccessObject(name,
|
|
156698
|
+
function createESDecorateClassElementAccessObject(name, access8) {
|
|
156686
156699
|
const properties = [];
|
|
156687
156700
|
properties.push(createESDecorateClassElementAccessHasMethod(name));
|
|
156688
|
-
if (
|
|
156689
|
-
if (
|
|
156701
|
+
if (access8.get) properties.push(createESDecorateClassElementAccessGetMethod(name));
|
|
156702
|
+
if (access8.set) properties.push(createESDecorateClassElementAccessSetMethod(name));
|
|
156690
156703
|
return factory2.createObjectLiteralExpression(properties);
|
|
156691
156704
|
}
|
|
156692
156705
|
function createESDecorateClassElementContextObject(contextIn) {
|
|
@@ -184203,7 +184216,7 @@ ${lanes.join("\n")}
|
|
|
184203
184216
|
return false;
|
|
184204
184217
|
}
|
|
184205
184218
|
function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) {
|
|
184206
|
-
const
|
|
184219
|
+
const access8 = isSymbolAccessibleWorker(
|
|
184207
184220
|
typeSymbol,
|
|
184208
184221
|
enclosingDeclaration,
|
|
184209
184222
|
788968,
|
|
@@ -184212,10 +184225,10 @@ ${lanes.join("\n")}
|
|
|
184212
184225
|
/*allowModules*/
|
|
184213
184226
|
true
|
|
184214
184227
|
);
|
|
184215
|
-
return
|
|
184228
|
+
return access8.accessibility === 0;
|
|
184216
184229
|
}
|
|
184217
184230
|
function isValueSymbolAccessible(typeSymbol, enclosingDeclaration) {
|
|
184218
|
-
const
|
|
184231
|
+
const access8 = isSymbolAccessibleWorker(
|
|
184219
184232
|
typeSymbol,
|
|
184220
184233
|
enclosingDeclaration,
|
|
184221
184234
|
111551,
|
|
@@ -184224,10 +184237,10 @@ ${lanes.join("\n")}
|
|
|
184224
184237
|
/*allowModules*/
|
|
184225
184238
|
true
|
|
184226
184239
|
);
|
|
184227
|
-
return
|
|
184240
|
+
return access8.accessibility === 0;
|
|
184228
184241
|
}
|
|
184229
184242
|
function isSymbolAccessibleByFlags(typeSymbol, enclosingDeclaration, flags) {
|
|
184230
|
-
const
|
|
184243
|
+
const access8 = isSymbolAccessibleWorker(
|
|
184231
184244
|
typeSymbol,
|
|
184232
184245
|
enclosingDeclaration,
|
|
184233
184246
|
flags,
|
|
@@ -184236,7 +184249,7 @@ ${lanes.join("\n")}
|
|
|
184236
184249
|
/*allowModules*/
|
|
184237
184250
|
false
|
|
184238
184251
|
);
|
|
184239
|
-
return
|
|
184252
|
+
return access8.accessibility === 0;
|
|
184240
184253
|
}
|
|
184241
184254
|
function isAnySymbolAccessible(symbols, enclosingDeclaration, initialSymbol, meaning, shouldComputeAliasesToMakeVisible, allowModules) {
|
|
184242
184255
|
if (!length(symbols)) return;
|
|
@@ -204546,19 +204559,19 @@ ${lanes.join("\n")}
|
|
|
204546
204559
|
}
|
|
204547
204560
|
return false;
|
|
204548
204561
|
}
|
|
204549
|
-
function getAccessedPropertyName(
|
|
204550
|
-
if (isPropertyAccessExpression(
|
|
204551
|
-
return
|
|
204562
|
+
function getAccessedPropertyName(access8) {
|
|
204563
|
+
if (isPropertyAccessExpression(access8)) {
|
|
204564
|
+
return access8.name.escapedText;
|
|
204552
204565
|
}
|
|
204553
|
-
if (isElementAccessExpression(
|
|
204554
|
-
return tryGetElementAccessExpressionName(
|
|
204566
|
+
if (isElementAccessExpression(access8)) {
|
|
204567
|
+
return tryGetElementAccessExpressionName(access8);
|
|
204555
204568
|
}
|
|
204556
|
-
if (isBindingElement(
|
|
204557
|
-
const name = getDestructuringPropertyName(
|
|
204569
|
+
if (isBindingElement(access8)) {
|
|
204570
|
+
const name = getDestructuringPropertyName(access8);
|
|
204558
204571
|
return name ? escapeLeadingUnderscores(name) : void 0;
|
|
204559
204572
|
}
|
|
204560
|
-
if (isParameter(
|
|
204561
|
-
return "" +
|
|
204573
|
+
if (isParameter(access8)) {
|
|
204574
|
+
return "" + access8.parent.parameters.indexOf(access8);
|
|
204562
204575
|
}
|
|
204563
204576
|
return void 0;
|
|
204564
204577
|
}
|
|
@@ -205773,9 +205786,9 @@ ${lanes.join("\n")}
|
|
|
205773
205786
|
type = narrowTypeBySwitchOptionalChainContainment(type, flow.node, (t) => !(t.flags & 131072 || t.flags & 128 && t.value === "undefined"));
|
|
205774
205787
|
}
|
|
205775
205788
|
}
|
|
205776
|
-
const
|
|
205777
|
-
if (
|
|
205778
|
-
type = narrowTypeBySwitchOnDiscriminantProperty(type,
|
|
205789
|
+
const access8 = getDiscriminantPropertyAccess(expr, type);
|
|
205790
|
+
if (access8) {
|
|
205791
|
+
type = narrowTypeBySwitchOnDiscriminantProperty(type, access8, flow.node);
|
|
205779
205792
|
}
|
|
205780
205793
|
}
|
|
205781
205794
|
return createFlowType(type, isIncomplete(flowType));
|
|
@@ -205937,26 +205950,26 @@ ${lanes.join("\n")}
|
|
|
205937
205950
|
}
|
|
205938
205951
|
function getDiscriminantPropertyAccess(expr, computedType) {
|
|
205939
205952
|
if (declaredType.flags & 1048576 || computedType.flags & 1048576) {
|
|
205940
|
-
const
|
|
205941
|
-
if (
|
|
205942
|
-
const name = getAccessedPropertyName(
|
|
205953
|
+
const access8 = getCandidateDiscriminantPropertyAccess(expr);
|
|
205954
|
+
if (access8) {
|
|
205955
|
+
const name = getAccessedPropertyName(access8);
|
|
205943
205956
|
if (name) {
|
|
205944
205957
|
const type = declaredType.flags & 1048576 && isTypeSubsetOf(computedType, declaredType) ? declaredType : computedType;
|
|
205945
205958
|
if (isDiscriminantProperty(type, name)) {
|
|
205946
|
-
return
|
|
205959
|
+
return access8;
|
|
205947
205960
|
}
|
|
205948
205961
|
}
|
|
205949
205962
|
}
|
|
205950
205963
|
}
|
|
205951
205964
|
return void 0;
|
|
205952
205965
|
}
|
|
205953
|
-
function narrowTypeByDiscriminant(type,
|
|
205954
|
-
const propName = getAccessedPropertyName(
|
|
205966
|
+
function narrowTypeByDiscriminant(type, access8, narrowType2) {
|
|
205967
|
+
const propName = getAccessedPropertyName(access8);
|
|
205955
205968
|
if (propName === void 0) {
|
|
205956
205969
|
return type;
|
|
205957
205970
|
}
|
|
205958
|
-
const optionalChain = isOptionalChain(
|
|
205959
|
-
const removeNullable = strictNullChecks && (optionalChain || isNonNullAccess(
|
|
205971
|
+
const optionalChain = isOptionalChain(access8);
|
|
205972
|
+
const removeNullable = strictNullChecks && (optionalChain || isNonNullAccess(access8)) && maybeTypeOfKind(
|
|
205960
205973
|
type,
|
|
205961
205974
|
98304
|
|
205962
205975
|
/* Nullable */
|
|
@@ -205976,27 +205989,27 @@ ${lanes.join("\n")}
|
|
|
205976
205989
|
return !(discriminantType.flags & 131072) && !(narrowedPropType.flags & 131072) && areTypesComparable(narrowedPropType, discriminantType);
|
|
205977
205990
|
});
|
|
205978
205991
|
}
|
|
205979
|
-
function narrowTypeByDiscriminantProperty(type,
|
|
205992
|
+
function narrowTypeByDiscriminantProperty(type, access8, operator, value, assumeTrue) {
|
|
205980
205993
|
if ((operator === 37 || operator === 38) && type.flags & 1048576) {
|
|
205981
205994
|
const keyPropertyName = getKeyPropertyName(type);
|
|
205982
|
-
if (keyPropertyName && keyPropertyName === getAccessedPropertyName(
|
|
205995
|
+
if (keyPropertyName && keyPropertyName === getAccessedPropertyName(access8)) {
|
|
205983
205996
|
const candidate = getConstituentTypeForKeyType(type, getTypeOfExpression(value));
|
|
205984
205997
|
if (candidate) {
|
|
205985
205998
|
return operator === (assumeTrue ? 37 : 38) ? candidate : isUnitType(getTypeOfPropertyOfType(candidate, keyPropertyName) || unknownType) ? removeType(type, candidate) : type;
|
|
205986
205999
|
}
|
|
205987
206000
|
}
|
|
205988
206001
|
}
|
|
205989
|
-
return narrowTypeByDiscriminant(type,
|
|
206002
|
+
return narrowTypeByDiscriminant(type, access8, (t) => narrowTypeByEquality(t, operator, value, assumeTrue));
|
|
205990
206003
|
}
|
|
205991
|
-
function narrowTypeBySwitchOnDiscriminantProperty(type,
|
|
205992
|
-
if (data.clauseStart < data.clauseEnd && type.flags & 1048576 && getKeyPropertyName(type) === getAccessedPropertyName(
|
|
206004
|
+
function narrowTypeBySwitchOnDiscriminantProperty(type, access8, data) {
|
|
206005
|
+
if (data.clauseStart < data.clauseEnd && type.flags & 1048576 && getKeyPropertyName(type) === getAccessedPropertyName(access8)) {
|
|
205993
206006
|
const clauseTypes = getSwitchClauseTypes(data.switchStatement).slice(data.clauseStart, data.clauseEnd);
|
|
205994
206007
|
const candidate = getUnionType(map3(clauseTypes, (t) => getConstituentTypeForKeyType(type, t) || unknownType));
|
|
205995
206008
|
if (candidate !== unknownType) {
|
|
205996
206009
|
return candidate;
|
|
205997
206010
|
}
|
|
205998
206011
|
}
|
|
205999
|
-
return narrowTypeByDiscriminant(type,
|
|
206012
|
+
return narrowTypeByDiscriminant(type, access8, (t) => narrowTypeBySwitchOnDiscriminant(t, data));
|
|
206000
206013
|
}
|
|
206001
206014
|
function narrowTypeByTruthiness(type, expr, assumeTrue) {
|
|
206002
206015
|
if (isMatchingReference(reference, expr)) {
|
|
@@ -206013,9 +206026,9 @@ ${lanes.join("\n")}
|
|
|
206013
206026
|
/* NEUndefinedOrNull */
|
|
206014
206027
|
);
|
|
206015
206028
|
}
|
|
206016
|
-
const
|
|
206017
|
-
if (
|
|
206018
|
-
return narrowTypeByDiscriminant(type,
|
|
206029
|
+
const access8 = getDiscriminantPropertyAccess(expr, type);
|
|
206030
|
+
if (access8) {
|
|
206031
|
+
return narrowTypeByDiscriminant(type, access8, (t) => getTypeWithFacts(
|
|
206019
206032
|
t,
|
|
206020
206033
|
assumeTrue ? 4194304 : 8388608
|
|
206021
206034
|
/* Falsy */
|
|
@@ -206643,9 +206656,9 @@ ${lanes.join("\n")}
|
|
|
206643
206656
|
/* NEUndefinedOrNull */
|
|
206644
206657
|
);
|
|
206645
206658
|
}
|
|
206646
|
-
const
|
|
206647
|
-
if (
|
|
206648
|
-
return narrowTypeByDiscriminant(type,
|
|
206659
|
+
const access8 = getDiscriminantPropertyAccess(predicateArgument, type);
|
|
206660
|
+
if (access8) {
|
|
206661
|
+
return narrowTypeByDiscriminant(type, access8, (t) => getNarrowedType(
|
|
206649
206662
|
t,
|
|
206650
206663
|
predicate.type,
|
|
206651
206664
|
assumeTrue,
|
|
@@ -206705,9 +206718,9 @@ ${lanes.join("\n")}
|
|
|
206705
206718
|
/* EQUndefinedOrNull */
|
|
206706
206719
|
);
|
|
206707
206720
|
}
|
|
206708
|
-
const
|
|
206709
|
-
if (
|
|
206710
|
-
return narrowTypeByDiscriminant(type,
|
|
206721
|
+
const access8 = getDiscriminantPropertyAccess(expr, type);
|
|
206722
|
+
if (access8) {
|
|
206723
|
+
return narrowTypeByDiscriminant(type, access8, (t) => getTypeWithFacts(
|
|
206711
206724
|
t,
|
|
206712
206725
|
assumePresent ? 2097152 : 262144
|
|
206713
206726
|
/* EQUndefinedOrNull */
|
|
@@ -255066,7 +255079,7 @@ ${lanes.join("\n")}
|
|
|
255066
255079
|
return;
|
|
255067
255080
|
}
|
|
255068
255081
|
const buildInfo = host.getBuildInfo() || { version };
|
|
255069
|
-
|
|
255082
|
+
writeFile44(
|
|
255070
255083
|
host,
|
|
255071
255084
|
emitterDiagnostics,
|
|
255072
255085
|
buildInfoPath,
|
|
@@ -255278,7 +255291,7 @@ ${lanes.join("\n")}
|
|
|
255278
255291
|
}
|
|
255279
255292
|
if (sourceMapFilePath) {
|
|
255280
255293
|
const sourceMap = sourceMapGenerator.toString();
|
|
255281
|
-
|
|
255294
|
+
writeFile44(
|
|
255282
255295
|
host,
|
|
255283
255296
|
emitterDiagnostics,
|
|
255284
255297
|
sourceMapFilePath,
|
|
@@ -255293,7 +255306,7 @@ ${lanes.join("\n")}
|
|
|
255293
255306
|
}
|
|
255294
255307
|
const text = writer.getText();
|
|
255295
255308
|
const data = { sourceMapUrlPos, diagnostics: transform2.diagnostics };
|
|
255296
|
-
|
|
255309
|
+
writeFile44(host, emitterDiagnostics, jsFilePath, text, !!compilerOptions.emitBOM, sourceFiles, data);
|
|
255297
255310
|
writer.clear();
|
|
255298
255311
|
return !data.skippedDtsWrite;
|
|
255299
255312
|
}
|
|
@@ -261956,9 +261969,9 @@ ${lanes.join("\n")}
|
|
|
261956
261969
|
/*ignoreCase*/
|
|
261957
261970
|
false
|
|
261958
261971
|
)) {
|
|
261959
|
-
const
|
|
261960
|
-
if (
|
|
261961
|
-
const name = removeSuffix(removePrefix(
|
|
261972
|
+
const basename18 = getBaseFileName(a.fileName);
|
|
261973
|
+
if (basename18 === "lib.d.ts" || basename18 === "lib.es6.d.ts") return 0;
|
|
261974
|
+
const name = removeSuffix(removePrefix(basename18, "lib."), ".d.ts");
|
|
261962
261975
|
const index = libs.indexOf(name);
|
|
261963
261976
|
if (index !== -1) return index + 1;
|
|
261964
261977
|
}
|
|
@@ -282050,13 +282063,13 @@ interface Symbol {
|
|
|
282050
282063
|
for (const element of toConvert.elements) {
|
|
282051
282064
|
const propertyName = element.propertyName || element.name;
|
|
282052
282065
|
ts_FindAllReferences_exports.Core.eachSymbolReferenceInFile(element.name, checker, sourceFile, (id) => {
|
|
282053
|
-
const
|
|
282066
|
+
const access8 = propertyName.kind === 11 ? factory.createElementAccessExpression(factory.createIdentifier(namespaceImportName), factory.cloneNode(propertyName)) : factory.createPropertyAccessExpression(factory.createIdentifier(namespaceImportName), factory.cloneNode(propertyName));
|
|
282054
282067
|
if (isShorthandPropertyAssignment(id.parent)) {
|
|
282055
|
-
changes.replaceNode(sourceFile, id.parent, factory.createPropertyAssignment(id.text,
|
|
282068
|
+
changes.replaceNode(sourceFile, id.parent, factory.createPropertyAssignment(id.text, access8));
|
|
282056
282069
|
} else if (isExportSpecifier(id.parent)) {
|
|
282057
282070
|
neededNamedImports.add(element);
|
|
282058
282071
|
} else {
|
|
282059
|
-
changes.replaceNode(sourceFile, id,
|
|
282072
|
+
changes.replaceNode(sourceFile, id, access8);
|
|
282060
282073
|
}
|
|
282061
282074
|
});
|
|
282062
282075
|
}
|
|
@@ -323175,7 +323188,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
323175
323188
|
walkUpParenthesizedTypesAndGetParentAndChild: () => walkUpParenthesizedTypesAndGetParentAndChild,
|
|
323176
323189
|
whitespaceOrMapCommentRegExp: () => whitespaceOrMapCommentRegExp,
|
|
323177
323190
|
writeCommentRange: () => writeCommentRange,
|
|
323178
|
-
writeFile: () =>
|
|
323191
|
+
writeFile: () => writeFile44,
|
|
323179
323192
|
writeFileEnsuringDirectories: () => writeFileEnsuringDirectories,
|
|
323180
323193
|
zipWith: () => zipWith
|
|
323181
323194
|
});
|
|
@@ -325704,8 +325717,8 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
325704
325717
|
}
|
|
325705
325718
|
};
|
|
325706
325719
|
for (const file of files) {
|
|
325707
|
-
const
|
|
325708
|
-
if (
|
|
325720
|
+
const basename18 = getBaseFileName(file);
|
|
325721
|
+
if (basename18 === "package.json" || basename18 === "bower.json") {
|
|
325709
325722
|
createProjectWatcher(
|
|
325710
325723
|
file,
|
|
325711
325724
|
"FileWatcher"
|
|
@@ -329377,8 +329390,8 @@ All files are: ${JSON.stringify(names)}`,
|
|
|
329377
329390
|
var _a7;
|
|
329378
329391
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
329379
329392
|
if (!fileOrDirectoryPath) return;
|
|
329380
|
-
const
|
|
329381
|
-
if (((_a7 = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a7.size) && (
|
|
329393
|
+
const basename18 = getBaseFileName(fileOrDirectoryPath);
|
|
329394
|
+
if (((_a7 = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a7.size) && (basename18 === "package.json" || basename18 === "node_modules")) {
|
|
329382
329395
|
result.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
329383
329396
|
var _a23;
|
|
329384
329397
|
(_a23 = project.getModuleSpecifierCache()) == null ? void 0 : _a23.clear();
|
|
@@ -453215,16 +453228,31 @@ var init_project = __esm({
|
|
|
453215
453228
|
}
|
|
453216
453229
|
// ============ Serialization ============
|
|
453217
453230
|
toJSON() {
|
|
453231
|
+
const state = this.getState();
|
|
453218
453232
|
return {
|
|
453219
453233
|
version: "1.0.0",
|
|
453220
|
-
state:
|
|
453234
|
+
state: {
|
|
453235
|
+
project: state.project,
|
|
453236
|
+
tracks: state.tracks,
|
|
453237
|
+
clips: state.clips,
|
|
453238
|
+
sources: state.sources,
|
|
453239
|
+
transitions: state.transitions
|
|
453240
|
+
}
|
|
453221
453241
|
};
|
|
453222
453242
|
}
|
|
453223
453243
|
static fromJSON(data) {
|
|
453224
453244
|
const project = new _Project();
|
|
453225
453245
|
data.state.project.createdAt = new Date(data.state.project.createdAt);
|
|
453226
453246
|
data.state.project.updatedAt = new Date(data.state.project.updatedAt);
|
|
453227
|
-
project.state =
|
|
453247
|
+
project.state = {
|
|
453248
|
+
...data.state,
|
|
453249
|
+
currentTime: 0,
|
|
453250
|
+
isPlaying: false,
|
|
453251
|
+
zoom: 50,
|
|
453252
|
+
scrollX: 0,
|
|
453253
|
+
selectedClipIds: [],
|
|
453254
|
+
selectedTrackId: null
|
|
453255
|
+
};
|
|
453228
453256
|
return project;
|
|
453229
453257
|
}
|
|
453230
453258
|
setFilePath(path14) {
|
|
@@ -453259,10 +453287,45 @@ var init_engine = __esm({
|
|
|
453259
453287
|
}
|
|
453260
453288
|
});
|
|
453261
453289
|
|
|
453290
|
+
// ../cli/src/utils/project-resolver.ts
|
|
453291
|
+
import { access as access5, stat as stat3 } from "node:fs/promises";
|
|
453292
|
+
import { resolve as resolve28 } from "node:path";
|
|
453293
|
+
async function resolveTimelineFile(inputPath, cwd = process.cwd()) {
|
|
453294
|
+
const filePath = resolve28(cwd, inputPath);
|
|
453295
|
+
try {
|
|
453296
|
+
const stats = await stat3(filePath);
|
|
453297
|
+
if (stats.isDirectory()) {
|
|
453298
|
+
const canonical = resolve28(filePath, TIMELINE_FILENAME);
|
|
453299
|
+
try {
|
|
453300
|
+
await access5(canonical);
|
|
453301
|
+
return canonical;
|
|
453302
|
+
} catch {
|
|
453303
|
+
}
|
|
453304
|
+
const legacy = resolve28(filePath, LEGACY_TIMELINE_FILENAME);
|
|
453305
|
+
try {
|
|
453306
|
+
await access5(legacy);
|
|
453307
|
+
return legacy;
|
|
453308
|
+
} catch {
|
|
453309
|
+
return canonical;
|
|
453310
|
+
}
|
|
453311
|
+
}
|
|
453312
|
+
} catch {
|
|
453313
|
+
}
|
|
453314
|
+
return filePath;
|
|
453315
|
+
}
|
|
453316
|
+
var TIMELINE_FILENAME, LEGACY_TIMELINE_FILENAME;
|
|
453317
|
+
var init_project_resolver = __esm({
|
|
453318
|
+
"../cli/src/utils/project-resolver.ts"() {
|
|
453319
|
+
"use strict";
|
|
453320
|
+
TIMELINE_FILENAME = "timeline.json";
|
|
453321
|
+
LEGACY_TIMELINE_FILENAME = "project.vibe.json";
|
|
453322
|
+
}
|
|
453323
|
+
});
|
|
453324
|
+
|
|
453262
453325
|
// ../cli/src/commands/_shared/execute-fill-gaps.ts
|
|
453263
453326
|
import { existsSync as existsSync40 } from "node:fs";
|
|
453264
453327
|
import { readFile as readFile16, writeFile as writeFile16, mkdir as mkdir14, rename as renameFs } from "node:fs/promises";
|
|
453265
|
-
import { resolve as
|
|
453328
|
+
import { resolve as resolve29, dirname as dirname20 } from "node:path";
|
|
453266
453329
|
function detectVideoGaps(videoClips, totalDuration) {
|
|
453267
453330
|
const gaps = [];
|
|
453268
453331
|
const sortedClips = [...videoClips].sort((a, b) => a.startTime - b.startTime);
|
|
@@ -453341,12 +453404,12 @@ async function executeFillGaps(options) {
|
|
|
453341
453404
|
});
|
|
453342
453405
|
const humanLines = [];
|
|
453343
453406
|
try {
|
|
453344
|
-
onProgress("Loading
|
|
453345
|
-
const filePath =
|
|
453407
|
+
onProgress("Loading timeline...");
|
|
453408
|
+
const filePath = await resolveTimelineFile(options.projectPath);
|
|
453346
453409
|
if (!existsSync40(filePath)) {
|
|
453347
453410
|
return {
|
|
453348
453411
|
success: false,
|
|
453349
|
-
error: `
|
|
453412
|
+
error: `Timeline file not found: ${filePath}`,
|
|
453350
453413
|
humanLines
|
|
453351
453414
|
};
|
|
453352
453415
|
}
|
|
@@ -453477,7 +453540,7 @@ async function executeFillGaps(options) {
|
|
|
453477
453540
|
};
|
|
453478
453541
|
}
|
|
453479
453542
|
const projectDir = dirname20(filePath);
|
|
453480
|
-
const footageDir = options.dir ?
|
|
453543
|
+
const footageDir = options.dir ? resolve29(process.cwd(), options.dir) : resolve29(projectDir, "footage");
|
|
453481
453544
|
if (!existsSync40(footageDir)) {
|
|
453482
453545
|
await mkdir14(footageDir, { recursive: true });
|
|
453483
453546
|
}
|
|
@@ -453509,7 +453572,7 @@ async function executeFillGaps(options) {
|
|
|
453509
453572
|
}
|
|
453510
453573
|
onProgress("Extracting frame from preceding clip...");
|
|
453511
453574
|
const frameOffset = clipBefore.sourceStartOffset + clipBefore.duration - 0.1;
|
|
453512
|
-
const framePath =
|
|
453575
|
+
const framePath = resolve29(footageDir, `frame-${gap.start.toFixed(2)}.png`);
|
|
453513
453576
|
try {
|
|
453514
453577
|
await execSafe("ffmpeg", [
|
|
453515
453578
|
"-i",
|
|
@@ -453570,7 +453633,7 @@ async function executeFillGaps(options) {
|
|
|
453570
453633
|
continue;
|
|
453571
453634
|
}
|
|
453572
453635
|
const videoFileName = `gap-fill-${gap.start.toFixed(2)}-${gap.end.toFixed(2)}.mp4`;
|
|
453573
|
-
const videoPath =
|
|
453636
|
+
const videoPath = resolve29(footageDir, videoFileName);
|
|
453574
453637
|
onProgress("Downloading generated video...");
|
|
453575
453638
|
const videoBuffer = await downloadVideo(finalResult.videoUrl);
|
|
453576
453639
|
await writeFile16(videoPath, videoBuffer);
|
|
@@ -453582,7 +453645,7 @@ async function executeFillGaps(options) {
|
|
|
453582
453645
|
const remainingNeeded = targetDuration - generatedDuration;
|
|
453583
453646
|
const segmentDuration = remainingNeeded > 5 ? "10" : "5";
|
|
453584
453647
|
onProgress(`Generating additional ${segmentDuration}s segment...`);
|
|
453585
|
-
const lastFramePath =
|
|
453648
|
+
const lastFramePath = resolve29(
|
|
453586
453649
|
footageDir,
|
|
453587
453650
|
`frame-extend-${gap.start.toFixed(2)}-${segmentIndex}.png`
|
|
453588
453651
|
);
|
|
@@ -453638,17 +453701,17 @@ async function executeFillGaps(options) {
|
|
|
453638
453701
|
);
|
|
453639
453702
|
break;
|
|
453640
453703
|
}
|
|
453641
|
-
const segVideoPath =
|
|
453704
|
+
const segVideoPath = resolve29(
|
|
453642
453705
|
footageDir,
|
|
453643
453706
|
`gap-fill-${gap.start.toFixed(2)}-${gap.end.toFixed(2)}-seg${segmentIndex}.mp4`
|
|
453644
453707
|
);
|
|
453645
453708
|
const segVideoBuffer = await downloadVideo(segFinalResult.videoUrl);
|
|
453646
453709
|
await writeFile16(segVideoPath, segVideoBuffer);
|
|
453647
|
-
const concatListPath =
|
|
453710
|
+
const concatListPath = resolve29(footageDir, `concat-${gap.start.toFixed(2)}.txt`);
|
|
453648
453711
|
const concatList = generatedVideos.map((v) => `file '${v}'`).join("\n") + `
|
|
453649
453712
|
file '${segVideoPath}'`;
|
|
453650
453713
|
await writeFile16(concatListPath, concatList);
|
|
453651
|
-
const concatOutputPath =
|
|
453714
|
+
const concatOutputPath = resolve29(
|
|
453652
453715
|
footageDir,
|
|
453653
453716
|
`gap-fill-${gap.start.toFixed(2)}-${gap.end.toFixed(2)}-merged.mp4`
|
|
453654
453717
|
);
|
|
@@ -453704,7 +453767,7 @@ file '${segVideoPath}'`;
|
|
|
453704
453767
|
humanLines.push("");
|
|
453705
453768
|
let outputPath = filePath;
|
|
453706
453769
|
if (generatedCount > 0) {
|
|
453707
|
-
outputPath = options.output ?
|
|
453770
|
+
outputPath = options.output ? resolve29(process.cwd(), options.output) : filePath;
|
|
453708
453771
|
await writeFile16(outputPath, JSON.stringify(project.toJSON(), null, 2));
|
|
453709
453772
|
humanLines.push(`\u2714 Filled ${generatedCount} gap(s) with AI-generated video`);
|
|
453710
453773
|
humanLines.push(`Project saved: ${outputPath}`);
|
|
@@ -453734,13 +453797,14 @@ var init_execute_fill_gaps = __esm({
|
|
|
453734
453797
|
init_engine();
|
|
453735
453798
|
init_api_key();
|
|
453736
453799
|
init_exec_safe();
|
|
453800
|
+
init_project_resolver();
|
|
453737
453801
|
init_ai_helpers();
|
|
453738
453802
|
}
|
|
453739
453803
|
});
|
|
453740
453804
|
|
|
453741
453805
|
// ../cli/src/commands/ai-fill-gaps.ts
|
|
453742
453806
|
function registerFillGapsCommand(aiCommand) {
|
|
453743
|
-
aiCommand.command("fill-gaps").description("Fill timeline gaps with AI-generated video (Kling image-to-video)").argument("<project>", "
|
|
453807
|
+
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
453808
|
try {
|
|
453745
453809
|
if (options.output) {
|
|
453746
453810
|
validateOutputPath(options.output);
|
|
@@ -453800,14 +453864,14 @@ __export(edit_cmd_exports, {
|
|
|
453800
453864
|
executeSpeedRamp: () => executeSpeedRamp,
|
|
453801
453865
|
executeUpscale: () => executeUpscale
|
|
453802
453866
|
});
|
|
453803
|
-
import { resolve as
|
|
453867
|
+
import { resolve as resolve30, dirname as dirname21 } from "node:path";
|
|
453804
453868
|
import { readFile as readFile17, writeFile as writeFile17, mkdir as mkdir15 } from "node:fs/promises";
|
|
453805
453869
|
async function executeGrade(options) {
|
|
453806
453870
|
const { videoPath, style, preset, output: output3, analyzeOnly, apiKey } = options;
|
|
453807
453871
|
try {
|
|
453808
453872
|
if (!style && !preset) return { success: false, error: "Either style or preset is required" };
|
|
453809
453873
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
453810
|
-
const absPath =
|
|
453874
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453811
453875
|
let gradeResult;
|
|
453812
453876
|
if (preset) {
|
|
453813
453877
|
const claude = new ClaudeProvider();
|
|
@@ -453822,7 +453886,7 @@ async function executeGrade(options) {
|
|
|
453822
453886
|
if (analyzeOnly) {
|
|
453823
453887
|
return { success: true, style: preset || style, description: gradeResult.description, ffmpegFilter: gradeResult.ffmpegFilter };
|
|
453824
453888
|
}
|
|
453825
|
-
const outputPath = output3 ?
|
|
453889
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, "-graded$1");
|
|
453826
453890
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", gradeResult.ffmpegFilter, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
453827
453891
|
return { success: true, outputPath, style: preset || style, description: gradeResult.description, ffmpegFilter: gradeResult.ffmpegFilter };
|
|
453828
453892
|
} catch (error) {
|
|
@@ -453837,7 +453901,7 @@ async function executeSpeedRamp(options) {
|
|
|
453837
453901
|
const claudeKey = apiKey || process.env.ANTHROPIC_API_KEY;
|
|
453838
453902
|
if (!openaiKey) return { success: false, error: "OPENAI_API_KEY required for Whisper transcription" };
|
|
453839
453903
|
if (!claudeKey) return { success: false, error: "ANTHROPIC_API_KEY required for Claude analysis" };
|
|
453840
|
-
const absPath =
|
|
453904
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453841
453905
|
const tempAudio = absPath.replace(/(\.[^.]+)$/, "-temp-audio.mp3");
|
|
453842
453906
|
await execSafe("ffmpeg", ["-i", absPath, "-vn", "-acodec", "libmp3lame", "-q:a", "2", tempAudio, "-y"]);
|
|
453843
453907
|
const whisper = new WhisperProvider();
|
|
@@ -453862,7 +453926,7 @@ async function executeSpeedRamp(options) {
|
|
|
453862
453926
|
if (speedResult.keyframes.length < 2) {
|
|
453863
453927
|
return { success: false, error: "Not enough keyframes for speed ramping" };
|
|
453864
453928
|
}
|
|
453865
|
-
const outputPath = output3 ?
|
|
453929
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, "-ramped$1");
|
|
453866
453930
|
const setpts = `setpts=${(1 / avgSpeed).toFixed(3)}*PTS`;
|
|
453867
453931
|
const atempo = avgSpeed >= 0.5 && avgSpeed <= 2 ? `atempo=${avgSpeed.toFixed(3)}` : "";
|
|
453868
453932
|
if (atempo) {
|
|
@@ -453879,7 +453943,7 @@ async function executeReframe(options) {
|
|
|
453879
453943
|
const { videoPath, aspect = "9:16", output: output3, analyzeOnly } = options;
|
|
453880
453944
|
try {
|
|
453881
453945
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
453882
|
-
const absPath =
|
|
453946
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453883
453947
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
453884
453948
|
"-v",
|
|
453885
453949
|
"error",
|
|
@@ -453914,7 +453978,7 @@ async function executeReframe(options) {
|
|
|
453914
453978
|
keyframeCount: 1
|
|
453915
453979
|
};
|
|
453916
453980
|
}
|
|
453917
|
-
const outputPath = output3 ?
|
|
453981
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, `-${aspect.replace(":", "x")}$1`);
|
|
453918
453982
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", `crop=${cropWidth}:${cropHeight}:${cropX}:${cropY}`, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
453919
453983
|
return { success: true, outputPath, sourceAspect: `${sourceWidth}:${sourceHeight}`, targetAspect: aspect };
|
|
453920
453984
|
} catch (error) {
|
|
@@ -453926,7 +453990,7 @@ async function executeInterpolate(options) {
|
|
|
453926
453990
|
try {
|
|
453927
453991
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
453928
453992
|
if (![2, 4, 8].includes(factor)) return { success: false, error: "Factor must be 2, 4, or 8" };
|
|
453929
|
-
const absPath =
|
|
453993
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453930
453994
|
const { stdout: fpsOut } = await execSafe("ffprobe", [
|
|
453931
453995
|
"-v",
|
|
453932
453996
|
"error",
|
|
@@ -453942,7 +454006,7 @@ async function executeInterpolate(options) {
|
|
|
453942
454006
|
const originalFps = num / (den || 1);
|
|
453943
454007
|
const targetFps = options.fps || originalFps * factor;
|
|
453944
454008
|
const mi = quality === "fast" ? "mi_mode=mci" : "mi_mode=mci:mc_mode=aobmc:me_mode=bidir:vsbmc=1";
|
|
453945
|
-
const outputPath = output3 ?
|
|
454009
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, `-slow${factor}x$1`);
|
|
453946
454010
|
await execSafe("ffmpeg", ["-i", absPath, "-filter:v", `minterpolate='${mi}:fps=${targetFps}',setpts=${factor}*PTS`, "-an", outputPath, "-y"], { timeout: 6e5 });
|
|
453947
454011
|
return { success: true, outputPath, originalFps, targetFps, factor };
|
|
453948
454012
|
} catch (error) {
|
|
@@ -453953,7 +454017,7 @@ async function executeUpscale(options) {
|
|
|
453953
454017
|
const { videoPath, output: output3, scale = 2, quality = "quality" } = options;
|
|
453954
454018
|
try {
|
|
453955
454019
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
453956
|
-
const absPath =
|
|
454020
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
453957
454021
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
453958
454022
|
"-v",
|
|
453959
454023
|
"error",
|
|
@@ -453969,7 +454033,7 @@ async function executeUpscale(options) {
|
|
|
453969
454033
|
const targetW = w * scale;
|
|
453970
454034
|
const targetH = h * scale;
|
|
453971
454035
|
const scaleFilter = quality === "quality" ? `scale=${targetW}:${targetH}:flags=lanczos` : `scale=${targetW}:${targetH}`;
|
|
453972
|
-
const outputPath = output3 ?
|
|
454036
|
+
const outputPath = output3 ? resolve30(process.cwd(), output3) : absPath.replace(/(\.[^.]+)$/, `-${scale}x$1`);
|
|
453973
454037
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", scaleFilter, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
453974
454038
|
return { success: true, outputPath, originalRes: `${w}x${h}`, targetRes: `${targetW}x${targetH}` };
|
|
453975
454039
|
} catch (error) {
|
|
@@ -454041,7 +454105,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454041
454105
|
dryRun: true,
|
|
454042
454106
|
data: {
|
|
454043
454107
|
params: {
|
|
454044
|
-
videoPath:
|
|
454108
|
+
videoPath: resolve30(process.cwd(), videoPath),
|
|
454045
454109
|
style: options.style || options.preset,
|
|
454046
454110
|
analyzeOnly: options.analyzeOnly || false
|
|
454047
454111
|
}
|
|
@@ -454068,8 +454132,8 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454068
454132
|
}
|
|
454069
454133
|
spinner2.succeed(source_default.green("Color grade analyzed"));
|
|
454070
454134
|
if (isJsonMode()) {
|
|
454071
|
-
const absPath2 =
|
|
454072
|
-
const gradeOutputPath = options.output ?
|
|
454135
|
+
const absPath2 = resolve30(process.cwd(), videoPath);
|
|
454136
|
+
const gradeOutputPath = options.output ? resolve30(process.cwd(), options.output) : absPath2.replace(/(\.[^.]+)$/, "-graded$1");
|
|
454073
454137
|
outputSuccess({
|
|
454074
454138
|
command: "edit grade",
|
|
454075
454139
|
startedAt,
|
|
@@ -454095,8 +454159,8 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454095
454159
|
console.log(source_default.dim("Use without --analyze-only to apply the grade."));
|
|
454096
454160
|
return;
|
|
454097
454161
|
}
|
|
454098
|
-
const absPath =
|
|
454099
|
-
const outputPath = options.output ?
|
|
454162
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454163
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, "-graded$1");
|
|
454100
454164
|
spinner2.start("Applying color grade...");
|
|
454101
454165
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", gradeResult.ffmpegFilter, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
454102
454166
|
spinner2.succeed(source_default.green("Color grade applied"));
|
|
@@ -454126,7 +454190,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454126
454190
|
dryRun: true,
|
|
454127
454191
|
data: {
|
|
454128
454192
|
params: {
|
|
454129
|
-
videoPath:
|
|
454193
|
+
videoPath: resolve30(process.cwd(), videoPath),
|
|
454130
454194
|
texts: options.text,
|
|
454131
454195
|
style: options.style,
|
|
454132
454196
|
fontSize: options.fontSize ? parseInt(options.fontSize) : void 0,
|
|
@@ -454139,8 +454203,8 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454139
454203
|
});
|
|
454140
454204
|
return;
|
|
454141
454205
|
}
|
|
454142
|
-
const absPath =
|
|
454143
|
-
const outputPath = options.output ?
|
|
454206
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454207
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, "-overlay$1");
|
|
454144
454208
|
const spinner2 = ora("Applying text overlays...").start();
|
|
454145
454209
|
const result = await applyTextOverlays({
|
|
454146
454210
|
videoPath: absPath,
|
|
@@ -454198,7 +454262,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454198
454262
|
dryRun: true,
|
|
454199
454263
|
data: {
|
|
454200
454264
|
params: {
|
|
454201
|
-
videoPath:
|
|
454265
|
+
videoPath: resolve30(process.cwd(), videoPath),
|
|
454202
454266
|
style: options.style,
|
|
454203
454267
|
minSpeed: parseFloat(options.minSpeed),
|
|
454204
454268
|
maxSpeed: parseFloat(options.maxSpeed),
|
|
@@ -454210,7 +454274,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454210
454274
|
}
|
|
454211
454275
|
const openaiApiKey = await requireApiKey("OPENAI_API_KEY", "OpenAI");
|
|
454212
454276
|
const claudeApiKey = await requireApiKey("ANTHROPIC_API_KEY", "Anthropic", options.apiKey);
|
|
454213
|
-
const absPath =
|
|
454277
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454214
454278
|
const spinner2 = ora("Extracting audio...").start();
|
|
454215
454279
|
const { stdout: speedRampProbe } = await execSafe("ffprobe", [
|
|
454216
454280
|
"-v",
|
|
@@ -454255,7 +454319,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454255
454319
|
spinner2.succeed(source_default.green(`Found ${speedResult.keyframes.length} speed keyframes`));
|
|
454256
454320
|
if (isJsonMode()) {
|
|
454257
454321
|
const avgSpeed2 = speedResult.keyframes.reduce((sum, kf) => sum + kf.speed, 0) / speedResult.keyframes.length;
|
|
454258
|
-
const speedRampOutputPath = options.output ?
|
|
454322
|
+
const speedRampOutputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, "-ramped$1");
|
|
454259
454323
|
outputSuccess({
|
|
454260
454324
|
command: "edit speed-ramp",
|
|
454261
454325
|
startedAt,
|
|
@@ -454284,7 +454348,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454284
454348
|
return;
|
|
454285
454349
|
}
|
|
454286
454350
|
spinner2.start("Applying speed ramps...");
|
|
454287
|
-
const outputPath = options.output ?
|
|
454351
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, "-ramped$1");
|
|
454288
454352
|
const avgSpeed = speedResult.keyframes.reduce((sum, kf) => sum + kf.speed, 0) / speedResult.keyframes.length;
|
|
454289
454353
|
const setpts = `setpts=${(1 / avgSpeed).toFixed(3)}*PTS`;
|
|
454290
454354
|
const atempo = avgSpeed >= 0.5 && avgSpeed <= 2 ? `atempo=${avgSpeed.toFixed(3)}` : "";
|
|
@@ -454318,7 +454382,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454318
454382
|
dryRun: true,
|
|
454319
454383
|
data: {
|
|
454320
454384
|
params: {
|
|
454321
|
-
videoPath:
|
|
454385
|
+
videoPath: resolve30(process.cwd(), videoPath),
|
|
454322
454386
|
aspect: options.aspect,
|
|
454323
454387
|
focus: options.focus,
|
|
454324
454388
|
analyzeOnly: options.analyzeOnly || false
|
|
@@ -454327,7 +454391,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454327
454391
|
});
|
|
454328
454392
|
return;
|
|
454329
454393
|
}
|
|
454330
|
-
const absPath =
|
|
454394
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454331
454395
|
const spinner2 = ora("Analyzing video...").start();
|
|
454332
454396
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
454333
454397
|
"-v",
|
|
@@ -454389,7 +454453,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454389
454453
|
}
|
|
454390
454454
|
spinner2.succeed(source_default.green(`Analyzed ${cropKeyframes.length} keyframes`));
|
|
454391
454455
|
if (isJsonMode()) {
|
|
454392
|
-
const reframeOutputPath = options.output ?
|
|
454456
|
+
const reframeOutputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, `-${options.aspect.replace(":", "x")}$1`);
|
|
454393
454457
|
outputSuccess({
|
|
454394
454458
|
command: "edit reframe",
|
|
454395
454459
|
startedAt,
|
|
@@ -454424,7 +454488,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454424
454488
|
}
|
|
454425
454489
|
console.log();
|
|
454426
454490
|
if (options.keyframes) {
|
|
454427
|
-
const keyframesPath =
|
|
454491
|
+
const keyframesPath = resolve30(process.cwd(), options.keyframes);
|
|
454428
454492
|
await writeFile17(keyframesPath, JSON.stringify(cropKeyframes, null, 2));
|
|
454429
454493
|
console.log(source_default.green(`Keyframes saved to: ${keyframesPath}`));
|
|
454430
454494
|
}
|
|
@@ -454436,7 +454500,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454436
454500
|
const avgCropY = Math.round(cropKeyframes.reduce((sum, kf) => sum + kf.cropY, 0) / cropKeyframes.length);
|
|
454437
454501
|
const cropWidth = cropKeyframes[0]?.cropWidth || sourceWidth;
|
|
454438
454502
|
const cropHeight = cropKeyframes[0]?.cropHeight || sourceHeight;
|
|
454439
|
-
const outputPath = options.output ?
|
|
454503
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, `-${options.aspect.replace(":", "x")}$1`);
|
|
454440
454504
|
spinner2.start("Applying reframe...");
|
|
454441
454505
|
await execSafe("ffmpeg", ["-i", absPath, "-vf", `crop=${cropWidth}:${cropHeight}:${avgCropX}:${avgCropY}`, "-c:a", "copy", outputPath, "-y"], { timeout: 6e5 });
|
|
454442
454506
|
spinner2.succeed(source_default.green("Reframe applied"));
|
|
@@ -454472,7 +454536,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454472
454536
|
dryRun: true,
|
|
454473
454537
|
data: {
|
|
454474
454538
|
params: {
|
|
454475
|
-
imagePaths: imagePaths.map((p) =>
|
|
454539
|
+
imagePaths: imagePaths.map((p) => resolve30(process.cwd(), p)),
|
|
454476
454540
|
prompt: prompt3,
|
|
454477
454541
|
provider,
|
|
454478
454542
|
model: options.model,
|
|
@@ -454493,7 +454557,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454493
454557
|
const spinner2 = ora(`Reading ${imagePaths.length} image(s)...`).start();
|
|
454494
454558
|
const imageBuffers = [];
|
|
454495
454559
|
for (const imagePath of imagePaths) {
|
|
454496
|
-
const absPath =
|
|
454560
|
+
const absPath = resolve30(process.cwd(), imagePath);
|
|
454497
454561
|
const buffer = await readFile17(absPath);
|
|
454498
454562
|
imageBuffers.push(buffer);
|
|
454499
454563
|
}
|
|
@@ -454542,7 +454606,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454542
454606
|
}
|
|
454543
454607
|
spinner2.succeed(source_default.green("Image edited"));
|
|
454544
454608
|
const img = result.images[0];
|
|
454545
|
-
const outputPath =
|
|
454609
|
+
const outputPath = resolve30(process.cwd(), options.output);
|
|
454546
454610
|
const saveImage = async () => {
|
|
454547
454611
|
await mkdir15(dirname21(outputPath), { recursive: true });
|
|
454548
454612
|
if (img.base64) {
|
|
@@ -454584,7 +454648,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454584
454648
|
if (options.output) {
|
|
454585
454649
|
validateOutputPath(options.output);
|
|
454586
454650
|
}
|
|
454587
|
-
const absPath =
|
|
454651
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454588
454652
|
const factor = parseInt(options.factor);
|
|
454589
454653
|
if (![2, 4, 8].includes(factor)) {
|
|
454590
454654
|
exitWithError(usageError("Factor must be 2, 4, or 8"));
|
|
@@ -454605,7 +454669,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454605
454669
|
});
|
|
454606
454670
|
return;
|
|
454607
454671
|
}
|
|
454608
|
-
const outputPath = options.output ?
|
|
454672
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, `-slow${factor}x$1`);
|
|
454609
454673
|
const spinner2 = ora(`Creating ${factor}x slow motion...`).start();
|
|
454610
454674
|
try {
|
|
454611
454675
|
const { stdout: fpsOut } = await execSafe("ffprobe", [
|
|
@@ -454666,7 +454730,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454666
454730
|
if (options.output) {
|
|
454667
454731
|
validateOutputPath(options.output);
|
|
454668
454732
|
}
|
|
454669
|
-
const absPath =
|
|
454733
|
+
const absPath = resolve30(process.cwd(), videoPath);
|
|
454670
454734
|
const scale = parseInt(options.scale);
|
|
454671
454735
|
if (scale !== 2 && scale !== 4) {
|
|
454672
454736
|
exitWithError(usageError("Scale must be 2 or 4"));
|
|
@@ -454688,7 +454752,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
454688
454752
|
return;
|
|
454689
454753
|
}
|
|
454690
454754
|
if (options.ffmpeg) {
|
|
454691
|
-
const outputPath = options.output ?
|
|
454755
|
+
const outputPath = options.output ? resolve30(process.cwd(), options.output) : absPath.replace(/(\.[^.]+)$/, `-upscaled-${scale}x$1`);
|
|
454692
454756
|
const spinner3 = ora(`Upscaling video with FFmpeg (${scale}x)...`).start();
|
|
454693
454757
|
try {
|
|
454694
454758
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
@@ -454749,7 +454813,7 @@ __export(ai_image_exports, {
|
|
|
454749
454813
|
executeImageGenerate: () => executeImageGenerate,
|
|
454750
454814
|
executeThumbnailBestFrame: () => executeThumbnailBestFrame
|
|
454751
454815
|
});
|
|
454752
|
-
import { resolve as
|
|
454816
|
+
import { resolve as resolve33, dirname as dirname24 } from "node:path";
|
|
454753
454817
|
import { readFile as readFile18, writeFile as writeFile19, mkdir as mkdir17 } from "node:fs/promises";
|
|
454754
454818
|
import { existsSync as existsSync42 } from "node:fs";
|
|
454755
454819
|
async function executeImageGenerate(options) {
|
|
@@ -454792,7 +454856,7 @@ async function executeImageGenerate(options) {
|
|
|
454792
454856
|
} else {
|
|
454793
454857
|
return { success: false, error: "No image data available" };
|
|
454794
454858
|
}
|
|
454795
|
-
outputPath =
|
|
454859
|
+
outputPath = resolve33(process.cwd(), output3);
|
|
454796
454860
|
await mkdir17(dirname24(outputPath), { recursive: true });
|
|
454797
454861
|
await writeFile19(outputPath, buffer);
|
|
454798
454862
|
}
|
|
@@ -454827,7 +454891,7 @@ async function executeImageGenerate(options) {
|
|
|
454827
454891
|
if (output3 && result.images.length > 0) {
|
|
454828
454892
|
const img = result.images[0];
|
|
454829
454893
|
if (img.base64) {
|
|
454830
|
-
outputPath =
|
|
454894
|
+
outputPath = resolve33(process.cwd(), output3);
|
|
454831
454895
|
await mkdir17(dirname24(outputPath), { recursive: true });
|
|
454832
454896
|
await writeFile19(outputPath, Buffer.from(img.base64, "base64"));
|
|
454833
454897
|
}
|
|
@@ -454863,7 +454927,7 @@ async function executeImageGenerate(options) {
|
|
|
454863
454927
|
} else {
|
|
454864
454928
|
return { success: false, error: "No image data available" };
|
|
454865
454929
|
}
|
|
454866
|
-
outputPath =
|
|
454930
|
+
outputPath = resolve33(process.cwd(), output3);
|
|
454867
454931
|
await mkdir17(dirname24(outputPath), { recursive: true });
|
|
454868
454932
|
await writeFile19(outputPath, buffer);
|
|
454869
454933
|
}
|
|
@@ -454894,7 +454958,7 @@ async function executeGeminiEdit(options) {
|
|
|
454894
454958
|
if (!key2) return { success: false, error: "GOOGLE_API_KEY required" };
|
|
454895
454959
|
const imageBuffers = [];
|
|
454896
454960
|
for (const imagePath of imagePaths) {
|
|
454897
|
-
const absPath =
|
|
454961
|
+
const absPath = resolve33(process.cwd(), imagePath);
|
|
454898
454962
|
if (!existsSync42(absPath)) {
|
|
454899
454963
|
return { success: false, error: `Image not found: ${absPath}` };
|
|
454900
454964
|
}
|
|
@@ -454922,7 +454986,7 @@ async function executeGeminiEdit(options) {
|
|
|
454922
454986
|
const img = result.images[0];
|
|
454923
454987
|
let outputPath;
|
|
454924
454988
|
if (img.base64) {
|
|
454925
|
-
outputPath =
|
|
454989
|
+
outputPath = resolve33(process.cwd(), output3);
|
|
454926
454990
|
await mkdir17(dirname24(outputPath), { recursive: true });
|
|
454927
454991
|
await writeFile19(outputPath, Buffer.from(img.base64, "base64"));
|
|
454928
454992
|
}
|
|
@@ -455015,7 +455079,7 @@ __export(ai_analyze_exports, {
|
|
|
455015
455079
|
registerAnalyzeCommands: () => registerAnalyzeCommands
|
|
455016
455080
|
});
|
|
455017
455081
|
import { readFile as readFile19 } from "node:fs/promises";
|
|
455018
|
-
import { extname as extname8, resolve as
|
|
455082
|
+
import { extname as extname8, resolve as resolve34 } from "node:path";
|
|
455019
455083
|
import { existsSync as existsSync43 } from "node:fs";
|
|
455020
455084
|
async function executeGeminiVideo(options) {
|
|
455021
455085
|
try {
|
|
@@ -455034,7 +455098,7 @@ async function executeGeminiVideo(options) {
|
|
|
455034
455098
|
if (isYouTube) {
|
|
455035
455099
|
videoData = options.source;
|
|
455036
455100
|
} else {
|
|
455037
|
-
const absPath =
|
|
455101
|
+
const absPath = resolve34(process.cwd(), options.source);
|
|
455038
455102
|
if (!existsSync43(absPath)) {
|
|
455039
455103
|
return { success: false, error: `File not found: ${absPath}` };
|
|
455040
455104
|
}
|
|
@@ -455107,7 +455171,7 @@ async function executeAnalyze(options) {
|
|
|
455107
455171
|
}
|
|
455108
455172
|
imageBuffer = Buffer.from(await response.arrayBuffer());
|
|
455109
455173
|
} else {
|
|
455110
|
-
const absPath =
|
|
455174
|
+
const absPath = resolve34(process.cwd(), source3);
|
|
455111
455175
|
if (!existsSync43(absPath)) {
|
|
455112
455176
|
return { success: false, error: `File not found: ${absPath}` };
|
|
455113
455177
|
}
|
|
@@ -455142,7 +455206,7 @@ async function executeAnalyze(options) {
|
|
|
455142
455206
|
}
|
|
455143
455207
|
videoData = Buffer.from(await response.arrayBuffer());
|
|
455144
455208
|
} else {
|
|
455145
|
-
const absPath =
|
|
455209
|
+
const absPath = resolve34(process.cwd(), source3);
|
|
455146
455210
|
if (!existsSync43(absPath)) {
|
|
455147
455211
|
return { success: false, error: `File not found: ${absPath}` };
|
|
455148
455212
|
}
|
|
@@ -455281,7 +455345,7 @@ __export(ai_review_exports, {
|
|
|
455281
455345
|
registerReviewCommand: () => registerReviewCommand
|
|
455282
455346
|
});
|
|
455283
455347
|
import { readFile as readFile20, rename as rename4 } from "node:fs/promises";
|
|
455284
|
-
import { resolve as
|
|
455348
|
+
import { resolve as resolve35 } from "node:path";
|
|
455285
455349
|
import { existsSync as existsSync44 } from "node:fs";
|
|
455286
455350
|
function parseReviewFeedback(response) {
|
|
455287
455351
|
let cleaned = response.trim();
|
|
@@ -455306,7 +455370,7 @@ function parseReviewFeedback(response) {
|
|
|
455306
455370
|
}
|
|
455307
455371
|
async function executeReview(options) {
|
|
455308
455372
|
const { videoPath, storyboardPath, autoApply = false, verify = false, model = "flash" } = options;
|
|
455309
|
-
const absVideoPath =
|
|
455373
|
+
const absVideoPath = resolve35(process.cwd(), videoPath);
|
|
455310
455374
|
if (!existsSync44(absVideoPath)) {
|
|
455311
455375
|
return { success: false, error: `Video not found: ${absVideoPath}` };
|
|
455312
455376
|
}
|
|
@@ -455316,7 +455380,7 @@ async function executeReview(options) {
|
|
|
455316
455380
|
}
|
|
455317
455381
|
let storyboardContext = "";
|
|
455318
455382
|
if (storyboardPath) {
|
|
455319
|
-
const absStoryboardPath =
|
|
455383
|
+
const absStoryboardPath = resolve35(process.cwd(), storyboardPath);
|
|
455320
455384
|
if (existsSync44(absStoryboardPath)) {
|
|
455321
455385
|
const content = await readFile20(absStoryboardPath, "utf-8");
|
|
455322
455386
|
storyboardContext = `
|
|
@@ -455372,7 +455436,7 @@ Score each category 1-10. For fixable issues, provide an FFmpeg filter in autoFi
|
|
|
455372
455436
|
};
|
|
455373
455437
|
if (autoApply && feedback.autoFixable.length > 0) {
|
|
455374
455438
|
let currentInput = absVideoPath;
|
|
455375
|
-
const outputBase = options.outputPath ?
|
|
455439
|
+
const outputBase = options.outputPath ? resolve35(process.cwd(), options.outputPath) : absVideoPath.replace(/(\.[^.]+)$/, "-reviewed$1");
|
|
455376
455440
|
for (const fix of feedback.autoFixable) {
|
|
455377
455441
|
if (fix.type === "color_grade" && fix.ffmpegFilter) {
|
|
455378
455442
|
try {
|
|
@@ -455526,7 +455590,7 @@ __export(ai_motion_exports, {
|
|
|
455526
455590
|
executeMotion: () => executeMotion,
|
|
455527
455591
|
registerMotionCommand: () => registerMotionCommand
|
|
455528
455592
|
});
|
|
455529
|
-
import { resolve as
|
|
455593
|
+
import { resolve as resolve37 } from "node:path";
|
|
455530
455594
|
import { existsSync as existsSync45 } from "node:fs";
|
|
455531
455595
|
import { readFile as readFile22, writeFile as writeFile21 } from "node:fs/promises";
|
|
455532
455596
|
async function executeMotion(options) {
|
|
@@ -455551,7 +455615,7 @@ async function executeMotion(options) {
|
|
|
455551
455615
|
if (!geminiApiKey) {
|
|
455552
455616
|
return { success: false, error: "GOOGLE_API_KEY required for image analysis (--image). Run 'vibe setup' or set GOOGLE_API_KEY in .env" };
|
|
455553
455617
|
}
|
|
455554
|
-
const imagePath =
|
|
455618
|
+
const imagePath = resolve37(process.cwd(), options.image);
|
|
455555
455619
|
const imageBuffer = await readFile22(imagePath);
|
|
455556
455620
|
const gemini = new GeminiProvider();
|
|
455557
455621
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
@@ -455574,7 +455638,7 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
455574
455638
|
}
|
|
455575
455639
|
let result;
|
|
455576
455640
|
if (options.fromTsx) {
|
|
455577
|
-
const tsxPath =
|
|
455641
|
+
const tsxPath = resolve37(process.cwd(), options.fromTsx);
|
|
455578
455642
|
if (!existsSync45(tsxPath)) {
|
|
455579
455643
|
return { success: false, error: `TSX file not found: ${tsxPath}` };
|
|
455580
455644
|
}
|
|
@@ -455628,7 +455692,7 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
455628
455692
|
}
|
|
455629
455693
|
const { component } = result;
|
|
455630
455694
|
const defaultOutput = options.video || options.image ? "motion-output.mp4" : options.render ? "motion.webm" : "motion.tsx";
|
|
455631
|
-
const outputPath =
|
|
455695
|
+
const outputPath = resolve37(process.cwd(), options.output || defaultOutput);
|
|
455632
455696
|
const codePath = outputPath.replace(/\.\w+$/, ".tsx");
|
|
455633
455697
|
await writeFile21(codePath, component.code, "utf-8");
|
|
455634
455698
|
const shouldRender = options.render || !!options.video || !!options.image;
|
|
@@ -455647,8 +455711,8 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
455647
455711
|
if (notInstalled) {
|
|
455648
455712
|
return { success: false, codePath, componentName: component.name, error: notInstalled };
|
|
455649
455713
|
}
|
|
455650
|
-
const baseVideo = options.video ?
|
|
455651
|
-
const baseImage = options.image ?
|
|
455714
|
+
const baseVideo = options.video ? resolve37(process.cwd(), options.video) : void 0;
|
|
455715
|
+
const baseImage = options.image ? resolve37(process.cwd(), options.image) : void 0;
|
|
455652
455716
|
if (baseVideo) {
|
|
455653
455717
|
const videoFileName = "source_video.mp4";
|
|
455654
455718
|
const wrapped = wrapComponentWithVideo2(component.code, component.name, videoFileName);
|
|
@@ -455833,7 +455897,7 @@ var init_ai_motion = __esm({
|
|
|
455833
455897
|
});
|
|
455834
455898
|
|
|
455835
455899
|
// ../cli/src/commands/generate/sound-effect.ts
|
|
455836
|
-
import { resolve as
|
|
455900
|
+
import { resolve as resolve38 } from "node:path";
|
|
455837
455901
|
import { writeFile as writeFile22 } from "node:fs/promises";
|
|
455838
455902
|
async function executeSoundEffect(options) {
|
|
455839
455903
|
try {
|
|
@@ -455855,7 +455919,7 @@ async function executeSoundEffect(options) {
|
|
|
455855
455919
|
error: result.error || "Sound effect generation failed"
|
|
455856
455920
|
};
|
|
455857
455921
|
}
|
|
455858
|
-
const outputPath =
|
|
455922
|
+
const outputPath = resolve38(
|
|
455859
455923
|
process.cwd(),
|
|
455860
455924
|
options.output || "sound-effect.mp3"
|
|
455861
455925
|
);
|
|
@@ -455910,7 +455974,7 @@ function registerSoundEffectCommand(parent) {
|
|
|
455910
455974
|
apiError(result.error || "Sound effect generation failed", true)
|
|
455911
455975
|
);
|
|
455912
455976
|
}
|
|
455913
|
-
const outputPath =
|
|
455977
|
+
const outputPath = resolve38(process.cwd(), options.output);
|
|
455914
455978
|
await writeFile22(outputPath, result.audioBuffer);
|
|
455915
455979
|
spinner2.succeed(source_default.green("Sound effect generated"));
|
|
455916
455980
|
if (isJsonMode()) {
|
|
@@ -456095,7 +456159,7 @@ var init_video_cancel = __esm({
|
|
|
456095
456159
|
});
|
|
456096
456160
|
|
|
456097
456161
|
// ../cli/src/commands/generate/background.ts
|
|
456098
|
-
import { resolve as
|
|
456162
|
+
import { resolve as resolve39, dirname as dirname25 } from "node:path";
|
|
456099
456163
|
import { writeFile as writeFile23, mkdir as mkdir18 } from "node:fs/promises";
|
|
456100
456164
|
async function executeBackground(options) {
|
|
456101
456165
|
try {
|
|
@@ -456120,7 +456184,7 @@ async function executeBackground(options) {
|
|
|
456120
456184
|
} else {
|
|
456121
456185
|
return { success: false, error: "Provider returned no image data" };
|
|
456122
456186
|
}
|
|
456123
|
-
outputPath =
|
|
456187
|
+
outputPath = resolve39(process.cwd(), options.output);
|
|
456124
456188
|
await mkdir18(dirname25(outputPath), { recursive: true });
|
|
456125
456189
|
await writeFile23(outputPath, buffer);
|
|
456126
456190
|
}
|
|
@@ -456182,7 +456246,7 @@ function registerBackgroundCommand(parent) {
|
|
|
456182
456246
|
} else {
|
|
456183
456247
|
throw new Error("No image data available");
|
|
456184
456248
|
}
|
|
456185
|
-
outputPath =
|
|
456249
|
+
outputPath = resolve39(process.cwd(), options.output);
|
|
456186
456250
|
await mkdir18(dirname25(outputPath), { recursive: true });
|
|
456187
456251
|
await writeFile23(outputPath, buffer);
|
|
456188
456252
|
}
|
|
@@ -456213,7 +456277,7 @@ function registerBackgroundCommand(parent) {
|
|
|
456213
456277
|
} else {
|
|
456214
456278
|
throw new Error("No image data available");
|
|
456215
456279
|
}
|
|
456216
|
-
const outputPath =
|
|
456280
|
+
const outputPath = resolve39(process.cwd(), options.output);
|
|
456217
456281
|
await mkdir18(dirname25(outputPath), { recursive: true });
|
|
456218
456282
|
await writeFile23(outputPath, buffer);
|
|
456219
456283
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -456255,7 +456319,7 @@ var init_sanitize = __esm({
|
|
|
456255
456319
|
});
|
|
456256
456320
|
|
|
456257
456321
|
// ../cli/src/commands/generate/storyboard.ts
|
|
456258
|
-
import { resolve as
|
|
456322
|
+
import { resolve as resolve40 } from "node:path";
|
|
456259
456323
|
import { readFile as readFile23, writeFile as writeFile24 } from "node:fs/promises";
|
|
456260
456324
|
async function executeStoryboard(options) {
|
|
456261
456325
|
const { content, duration, creativity = "low", output: output3, apiKey } = options;
|
|
@@ -456274,7 +456338,7 @@ async function executeStoryboard(options) {
|
|
|
456274
456338
|
}
|
|
456275
456339
|
let outputPath;
|
|
456276
456340
|
if (output3) {
|
|
456277
|
-
outputPath =
|
|
456341
|
+
outputPath = resolve40(process.cwd(), output3);
|
|
456278
456342
|
await writeFile24(outputPath, JSON.stringify(segments, null, 2), "utf-8");
|
|
456279
456343
|
}
|
|
456280
456344
|
return { success: true, segments, segmentCount: segments.length, outputPath };
|
|
@@ -456299,7 +456363,7 @@ function registerStoryboardCommand(parent) {
|
|
|
456299
456363
|
}
|
|
456300
456364
|
let textContent2 = content;
|
|
456301
456365
|
if (options.file) {
|
|
456302
|
-
const filePath =
|
|
456366
|
+
const filePath = resolve40(process.cwd(), content);
|
|
456303
456367
|
textContent2 = await readFile23(filePath, "utf-8");
|
|
456304
456368
|
}
|
|
456305
456369
|
if (options.dryRun) {
|
|
@@ -456341,7 +456405,7 @@ function registerStoryboardCommand(parent) {
|
|
|
456341
456405
|
if (seg.visuals) seg.visuals = sanitizeLLMResponse(seg.visuals);
|
|
456342
456406
|
}
|
|
456343
456407
|
if (options.output) {
|
|
456344
|
-
const outputPath =
|
|
456408
|
+
const outputPath = resolve40(process.cwd(), options.output);
|
|
456345
456409
|
await writeFile24(outputPath, JSON.stringify(segments, null, 2), "utf-8");
|
|
456346
456410
|
if (isJsonMode()) {
|
|
456347
456411
|
outputSuccess({
|
|
@@ -456384,7 +456448,7 @@ function registerStoryboardCommand(parent) {
|
|
|
456384
456448
|
}
|
|
456385
456449
|
console.log();
|
|
456386
456450
|
if (options.output) {
|
|
456387
|
-
console.log(source_default.green(`Saved to: ${
|
|
456451
|
+
console.log(source_default.green(`Saved to: ${resolve40(process.cwd(), options.output)}`));
|
|
456388
456452
|
}
|
|
456389
456453
|
} catch (error) {
|
|
456390
456454
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -456462,7 +456526,7 @@ var init_tty = __esm({
|
|
|
456462
456526
|
});
|
|
456463
456527
|
|
|
456464
456528
|
// ../cli/src/commands/generate/speech.ts
|
|
456465
|
-
import { resolve as
|
|
456529
|
+
import { resolve as resolve41 } from "node:path";
|
|
456466
456530
|
import { writeFile as writeFile25 } from "node:fs/promises";
|
|
456467
456531
|
async function executeSpeech(options) {
|
|
456468
456532
|
try {
|
|
@@ -456480,7 +456544,7 @@ async function executeSpeech(options) {
|
|
|
456480
456544
|
if (!result.success || !result.audioBuffer) {
|
|
456481
456545
|
return { success: false, error: result.error || "TTS generation failed" };
|
|
456482
456546
|
}
|
|
456483
|
-
const outputPath =
|
|
456547
|
+
const outputPath = resolve41(process.cwd(), options.output || "output.mp3");
|
|
456484
456548
|
await writeFile25(outputPath, result.audioBuffer);
|
|
456485
456549
|
return { success: true, outputPath, characterCount: result.characterCount };
|
|
456486
456550
|
} catch (error) {
|
|
@@ -456556,7 +456620,7 @@ function registerSpeechCommand(parent) {
|
|
|
456556
456620
|
spinner2.fail(result.error || "TTS generation failed");
|
|
456557
456621
|
exitWithError(apiError(result.error || "TTS generation failed", true));
|
|
456558
456622
|
}
|
|
456559
|
-
const outputPath =
|
|
456623
|
+
const outputPath = resolve41(process.cwd(), options.output);
|
|
456560
456624
|
await writeFile25(outputPath, result.audioBuffer);
|
|
456561
456625
|
spinner2.succeed(source_default.green("Speech generated"));
|
|
456562
456626
|
if (options.fitDuration && options.fitDuration > 0) {
|
|
@@ -456642,7 +456706,7 @@ var init_speech = __esm({
|
|
|
456642
456706
|
});
|
|
456643
456707
|
|
|
456644
456708
|
// ../cli/src/commands/generate/music.ts
|
|
456645
|
-
import { resolve as
|
|
456709
|
+
import { resolve as resolve43 } from "node:path";
|
|
456646
456710
|
import { writeFile as writeFile26 } from "node:fs/promises";
|
|
456647
456711
|
import { existsSync as existsSync46 } from "node:fs";
|
|
456648
456712
|
async function executeMusic(options) {
|
|
@@ -456665,7 +456729,7 @@ async function executeMusic(options) {
|
|
|
456665
456729
|
if (!result2.success || !result2.audioBuffer) {
|
|
456666
456730
|
return { success: false, error: result2.error || "Music generation failed" };
|
|
456667
456731
|
}
|
|
456668
|
-
const outputPath2 =
|
|
456732
|
+
const outputPath2 = resolve43(process.cwd(), options.output || "music.mp3");
|
|
456669
456733
|
await writeFile26(outputPath2, result2.audioBuffer);
|
|
456670
456734
|
return { success: true, outputPath: outputPath2, provider: "elevenlabs", duration: duration2 };
|
|
456671
456735
|
}
|
|
@@ -456690,7 +456754,7 @@ async function executeMusic(options) {
|
|
|
456690
456754
|
if (!response.ok)
|
|
456691
456755
|
return { success: false, error: "Failed to download generated audio" };
|
|
456692
456756
|
const audioBuffer = Buffer.from(await response.arrayBuffer());
|
|
456693
|
-
const outputPath =
|
|
456757
|
+
const outputPath = resolve43(process.cwd(), options.output || "music.mp3");
|
|
456694
456758
|
await writeFile26(outputPath, audioBuffer);
|
|
456695
456759
|
return { success: true, outputPath, provider: "replicate", duration };
|
|
456696
456760
|
} catch (error) {
|
|
@@ -456754,7 +456818,7 @@ function registerMusicCommand(parent) {
|
|
|
456754
456818
|
spinner2.fail(result.error || "Music generation failed");
|
|
456755
456819
|
exitWithError(apiError(result.error || "Music generation failed", true));
|
|
456756
456820
|
}
|
|
456757
|
-
const outputPath =
|
|
456821
|
+
const outputPath = resolve43(process.cwd(), options.output);
|
|
456758
456822
|
await writeFile26(outputPath, result.audioBuffer);
|
|
456759
456823
|
spinner2.succeed(source_default.green("Music generated successfully"));
|
|
456760
456824
|
if (isJsonMode()) {
|
|
@@ -456787,7 +456851,7 @@ function registerMusicCommand(parent) {
|
|
|
456787
456851
|
const duration = Math.max(1, Math.min(30, parseFloat(options.duration)));
|
|
456788
456852
|
if (options.melody) {
|
|
456789
456853
|
spinner2.text = "Uploading melody reference...";
|
|
456790
|
-
const absPath =
|
|
456854
|
+
const absPath = resolve43(process.cwd(), options.melody);
|
|
456791
456855
|
if (!existsSync46(absPath)) {
|
|
456792
456856
|
spinner2.fail(`Melody file not found: ${options.melody}`);
|
|
456793
456857
|
exitWithError(notFoundError(options.melody));
|
|
@@ -456829,7 +456893,7 @@ function registerMusicCommand(parent) {
|
|
|
456829
456893
|
exitWithError(apiError("Failed to download generated audio", true));
|
|
456830
456894
|
}
|
|
456831
456895
|
const audioBuffer = Buffer.from(await response.arrayBuffer());
|
|
456832
|
-
const outputPath =
|
|
456896
|
+
const outputPath = resolve43(process.cwd(), options.output);
|
|
456833
456897
|
await writeFile26(outputPath, audioBuffer);
|
|
456834
456898
|
spinner2.succeed(source_default.green("Music generated successfully"));
|
|
456835
456899
|
if (isJsonMode()) {
|
|
@@ -456871,7 +456935,7 @@ var init_music = __esm({
|
|
|
456871
456935
|
});
|
|
456872
456936
|
|
|
456873
456937
|
// ../cli/src/commands/generate/thumbnail.ts
|
|
456874
|
-
import { resolve as
|
|
456938
|
+
import { resolve as resolve44, dirname as dirname26, basename as basename10, extname as extname9 } from "node:path";
|
|
456875
456939
|
import { existsSync as existsSync47 } from "node:fs";
|
|
456876
456940
|
import { writeFile as writeFile27, mkdir as mkdir19 } from "node:fs/promises";
|
|
456877
456941
|
function registerThumbnailCommand(parent) {
|
|
@@ -456883,7 +456947,7 @@ function registerThumbnailCommand(parent) {
|
|
|
456883
456947
|
validateOutputPath(options.output);
|
|
456884
456948
|
}
|
|
456885
456949
|
if (options.bestFrame) {
|
|
456886
|
-
const absVideoPath =
|
|
456950
|
+
const absVideoPath = resolve44(process.cwd(), options.bestFrame);
|
|
456887
456951
|
if (!existsSync47(absVideoPath)) {
|
|
456888
456952
|
exitWithError(notFoundError(absVideoPath));
|
|
456889
456953
|
}
|
|
@@ -456901,7 +456965,7 @@ function registerThumbnailCommand(parent) {
|
|
|
456901
456965
|
const spinner3 = ora("Analyzing video for best frame...").start();
|
|
456902
456966
|
const result2 = await executeThumbnailBestFrame({
|
|
456903
456967
|
videoPath: absVideoPath,
|
|
456904
|
-
outputPath:
|
|
456968
|
+
outputPath: resolve44(process.cwd(), outputPath),
|
|
456905
456969
|
prompt: options.prompt,
|
|
456906
456970
|
model: options.model,
|
|
456907
456971
|
apiKey: apiKey2
|
|
@@ -456963,7 +457027,7 @@ function registerThumbnailCommand(parent) {
|
|
|
456963
457027
|
} else {
|
|
456964
457028
|
throw new Error("No image data available");
|
|
456965
457029
|
}
|
|
456966
|
-
outputPath =
|
|
457030
|
+
outputPath = resolve44(process.cwd(), options.output);
|
|
456967
457031
|
await mkdir19(dirname26(outputPath), { recursive: true });
|
|
456968
457032
|
await writeFile27(outputPath, buffer);
|
|
456969
457033
|
}
|
|
@@ -456994,7 +457058,7 @@ function registerThumbnailCommand(parent) {
|
|
|
456994
457058
|
} else {
|
|
456995
457059
|
throw new Error("No image data available");
|
|
456996
457060
|
}
|
|
456997
|
-
const outputPath =
|
|
457061
|
+
const outputPath = resolve44(process.cwd(), options.output);
|
|
456998
457062
|
await mkdir19(dirname26(outputPath), { recursive: true });
|
|
456999
457063
|
await writeFile27(outputPath, buffer);
|
|
457000
457064
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -457023,7 +457087,7 @@ var init_thumbnail = __esm({
|
|
|
457023
457087
|
});
|
|
457024
457088
|
|
|
457025
457089
|
// ../cli/src/commands/generate/video-status.ts
|
|
457026
|
-
import { resolve as
|
|
457090
|
+
import { resolve as resolve45 } from "node:path";
|
|
457027
457091
|
import { writeFile as writeFile28 } from "node:fs/promises";
|
|
457028
457092
|
function getStatusColor(status) {
|
|
457029
457093
|
switch (status) {
|
|
@@ -457062,7 +457126,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457062
457126
|
let outputPath;
|
|
457063
457127
|
if (options.output && result.videoUrl) {
|
|
457064
457128
|
const buffer = await downloadVideo(result.videoUrl);
|
|
457065
|
-
outputPath =
|
|
457129
|
+
outputPath = resolve45(process.cwd(), options.output);
|
|
457066
457130
|
await writeFile28(outputPath, buffer);
|
|
457067
457131
|
}
|
|
457068
457132
|
outputSuccess({
|
|
@@ -457096,7 +457160,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457096
457160
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457097
457161
|
try {
|
|
457098
457162
|
const buffer = await downloadVideo(result.videoUrl);
|
|
457099
|
-
const outputPath =
|
|
457163
|
+
const outputPath = resolve45(process.cwd(), options.output);
|
|
457100
457164
|
await writeFile28(outputPath, buffer);
|
|
457101
457165
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457102
457166
|
} catch (err) {
|
|
@@ -457130,7 +457194,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457130
457194
|
let outputPath;
|
|
457131
457195
|
if (options.output && result.videoUrl) {
|
|
457132
457196
|
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
457133
|
-
outputPath =
|
|
457197
|
+
outputPath = resolve45(process.cwd(), options.output);
|
|
457134
457198
|
await writeFile28(outputPath, buffer);
|
|
457135
457199
|
}
|
|
457136
457200
|
outputSuccess({
|
|
@@ -457168,7 +457232,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457168
457232
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457169
457233
|
try {
|
|
457170
457234
|
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
457171
|
-
const outputPath =
|
|
457235
|
+
const outputPath = resolve45(process.cwd(), options.output);
|
|
457172
457236
|
await writeFile28(outputPath, buffer);
|
|
457173
457237
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457174
457238
|
} catch (err) {
|
|
@@ -457197,7 +457261,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457197
457261
|
let outputPath;
|
|
457198
457262
|
if (options.output && result.videoUrl) {
|
|
457199
457263
|
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
457200
|
-
outputPath =
|
|
457264
|
+
outputPath = resolve45(process.cwd(), options.output);
|
|
457201
457265
|
await writeFile28(outputPath, buffer);
|
|
457202
457266
|
}
|
|
457203
457267
|
outputSuccess({
|
|
@@ -457236,7 +457300,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
457236
457300
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457237
457301
|
try {
|
|
457238
457302
|
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
457239
|
-
const outputPath =
|
|
457303
|
+
const outputPath = resolve45(process.cwd(), options.output);
|
|
457240
457304
|
await writeFile28(outputPath, buffer);
|
|
457241
457305
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457242
457306
|
} catch (err) {
|
|
@@ -457271,7 +457335,7 @@ var init_video_status = __esm({
|
|
|
457271
457335
|
});
|
|
457272
457336
|
|
|
457273
457337
|
// ../cli/src/commands/generate/video-extend.ts
|
|
457274
|
-
import { resolve as
|
|
457338
|
+
import { resolve as resolve46 } from "node:path";
|
|
457275
457339
|
import { writeFile as writeFile29 } from "node:fs/promises";
|
|
457276
457340
|
function registerVideoExtendCommand(parent) {
|
|
457277
457341
|
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 +457412,7 @@ function registerVideoExtendCommand(parent) {
|
|
|
457348
457412
|
let outputPath;
|
|
457349
457413
|
if (options.output && finalResult.videoUrl) {
|
|
457350
457414
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
457351
|
-
outputPath =
|
|
457415
|
+
outputPath = resolve46(process.cwd(), options.output);
|
|
457352
457416
|
await writeFile29(outputPath, buffer);
|
|
457353
457417
|
}
|
|
457354
457418
|
outputSuccess({
|
|
@@ -457376,7 +457440,7 @@ function registerVideoExtendCommand(parent) {
|
|
|
457376
457440
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457377
457441
|
try {
|
|
457378
457442
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
457379
|
-
const outputPath =
|
|
457443
|
+
const outputPath = resolve46(process.cwd(), options.output);
|
|
457380
457444
|
await writeFile29(outputPath, buffer);
|
|
457381
457445
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457382
457446
|
} catch (err) {
|
|
@@ -457437,7 +457501,7 @@ function registerVideoExtendCommand(parent) {
|
|
|
457437
457501
|
let outputPath;
|
|
457438
457502
|
if (options.output && finalResult.videoUrl) {
|
|
457439
457503
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
457440
|
-
outputPath =
|
|
457504
|
+
outputPath = resolve46(process.cwd(), options.output);
|
|
457441
457505
|
await writeFile29(outputPath, buffer);
|
|
457442
457506
|
}
|
|
457443
457507
|
outputSuccess({
|
|
@@ -457462,7 +457526,7 @@ function registerVideoExtendCommand(parent) {
|
|
|
457462
457526
|
const downloadSpinner = ora("Downloading video...").start();
|
|
457463
457527
|
try {
|
|
457464
457528
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
457465
|
-
const outputPath =
|
|
457529
|
+
const outputPath = resolve46(process.cwd(), options.output);
|
|
457466
457530
|
await writeFile29(outputPath, buffer);
|
|
457467
457531
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
457468
457532
|
} catch (err) {
|
|
@@ -457553,7 +457617,7 @@ var init_openai_image2 = __esm({
|
|
|
457553
457617
|
});
|
|
457554
457618
|
|
|
457555
457619
|
// ../cli/src/commands/generate/image.ts
|
|
457556
|
-
import { resolve as
|
|
457620
|
+
import { resolve as resolve47, dirname as dirname27 } from "node:path";
|
|
457557
457621
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
457558
457622
|
import { writeFile as writeFile30, mkdir as mkdir20 } from "node:fs/promises";
|
|
457559
457623
|
function registerImageCommand(parent) {
|
|
@@ -457669,7 +457733,7 @@ Examples:
|
|
|
457669
457733
|
source_default.green(`Generated ${result.images.length} image(s) with OpenAI ${modelLabel}`)
|
|
457670
457734
|
);
|
|
457671
457735
|
if (isJsonMode()) {
|
|
457672
|
-
const outputPath = options.output ?
|
|
457736
|
+
const outputPath = options.output ? resolve47(process.cwd(), options.output) : void 0;
|
|
457673
457737
|
if (outputPath && result.images.length > 0) {
|
|
457674
457738
|
const img = result.images[0];
|
|
457675
457739
|
let buffer;
|
|
@@ -457727,7 +457791,7 @@ Examples:
|
|
|
457727
457791
|
} else {
|
|
457728
457792
|
throw new Error("No image data available");
|
|
457729
457793
|
}
|
|
457730
|
-
const outputPath =
|
|
457794
|
+
const outputPath = resolve47(process.cwd(), options.output);
|
|
457731
457795
|
await mkdir20(dirname27(outputPath), { recursive: true });
|
|
457732
457796
|
await writeFile30(outputPath, buffer);
|
|
457733
457797
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -457799,7 +457863,7 @@ Examples:
|
|
|
457799
457863
|
source_default.green(`Generated ${result.images.length} image(s) with Gemini (${usedLabel})`)
|
|
457800
457864
|
);
|
|
457801
457865
|
if (isJsonMode()) {
|
|
457802
|
-
const outputPath = options.output ?
|
|
457866
|
+
const outputPath = options.output ? resolve47(process.cwd(), options.output) : void 0;
|
|
457803
457867
|
if (outputPath && result.images.length > 0) {
|
|
457804
457868
|
const img = result.images[0];
|
|
457805
457869
|
const buffer = Buffer.from(img.base64, "base64");
|
|
@@ -457835,7 +457899,7 @@ Examples:
|
|
|
457835
457899
|
try {
|
|
457836
457900
|
const img = result.images[0];
|
|
457837
457901
|
const buffer = Buffer.from(img.base64, "base64");
|
|
457838
|
-
const outputPath =
|
|
457902
|
+
const outputPath = resolve47(process.cwd(), options.output);
|
|
457839
457903
|
await mkdir20(dirname27(outputPath), { recursive: true });
|
|
457840
457904
|
await writeFile30(outputPath, buffer);
|
|
457841
457905
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -457886,7 +457950,7 @@ Examples:
|
|
|
457886
457950
|
source_default.green(`Generated ${result.images.length} image(s) with xAI Grok`)
|
|
457887
457951
|
);
|
|
457888
457952
|
if (isJsonMode()) {
|
|
457889
|
-
const outputPath = options.output ?
|
|
457953
|
+
const outputPath = options.output ? resolve47(process.cwd(), options.output) : void 0;
|
|
457890
457954
|
if (outputPath && result.images.length > 0) {
|
|
457891
457955
|
const img = result.images[0];
|
|
457892
457956
|
let buffer;
|
|
@@ -457938,7 +458002,7 @@ Examples:
|
|
|
457938
458002
|
} else {
|
|
457939
458003
|
throw new Error("No image data available");
|
|
457940
458004
|
}
|
|
457941
|
-
const outputPath =
|
|
458005
|
+
const outputPath = resolve47(process.cwd(), options.output);
|
|
457942
458006
|
await mkdir20(dirname27(outputPath), { recursive: true });
|
|
457943
458007
|
await writeFile30(outputPath, buffer);
|
|
457944
458008
|
saveSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
@@ -457952,7 +458016,7 @@ Examples:
|
|
|
457952
458016
|
const { spawn: spawn10 } = await import("child_process");
|
|
457953
458017
|
const __filename2 = fileURLToPath4(import.meta.url);
|
|
457954
458018
|
const __dirname3 = dirname27(__filename2);
|
|
457955
|
-
const scriptPath =
|
|
458019
|
+
const scriptPath = resolve47(
|
|
457956
458020
|
__dirname3,
|
|
457957
458021
|
"../../../../.claude/skills/runway-video/scripts/image.py"
|
|
457958
458022
|
);
|
|
@@ -457960,7 +458024,7 @@ Examples:
|
|
|
457960
458024
|
spinner2.fail("Output path required for Runway");
|
|
457961
458025
|
exitWithError(usageError("Output path required for Runway. Use -o option."));
|
|
457962
458026
|
}
|
|
457963
|
-
const outputPath =
|
|
458027
|
+
const outputPath = resolve47(process.cwd(), options.output);
|
|
457964
458028
|
const args = [scriptPath, prompt3, "-o", outputPath, "-r", options.ratio || "16:9"];
|
|
457965
458029
|
spinner2.text = "Generating image with Runway (gemini_2.5_flash)...";
|
|
457966
458030
|
await new Promise((resolvePromise, reject) => {
|
|
@@ -458970,7 +459034,7 @@ var init_dist3 = __esm({
|
|
|
458970
459034
|
|
|
458971
459035
|
// ../cli/src/commands/_shared/video-utils.ts
|
|
458972
459036
|
import { writeFile as writeFile31, unlink as unlink5, rename as rename5 } from "node:fs/promises";
|
|
458973
|
-
import { resolve as
|
|
459037
|
+
import { resolve as resolve48, basename as basename11 } from "node:path";
|
|
458974
459038
|
function sleep(ms) {
|
|
458975
459039
|
return new Promise((resolve64) => setTimeout(resolve64, ms));
|
|
458976
459040
|
}
|
|
@@ -459004,7 +459068,7 @@ async function extendVideoToTarget(videoPath, targetDuration, outputDir, sceneLa
|
|
|
459004
459068
|
const actualDuration = await getVideoDuration(videoPath);
|
|
459005
459069
|
if (actualDuration >= targetDuration - 0.1) return;
|
|
459006
459070
|
const ratio = targetDuration / actualDuration;
|
|
459007
|
-
const extendedPath =
|
|
459071
|
+
const extendedPath = resolve48(outputDir, `${basename11(videoPath, ".mp4")}-extended.mp4`);
|
|
459008
459072
|
if (ratio > 1.4 && options?.kling && options?.videoId) {
|
|
459009
459073
|
try {
|
|
459010
459074
|
options.onProgress?.(`${sceneLabel}: Extending via Kling API...`);
|
|
@@ -459020,17 +459084,17 @@ async function extendVideoToTarget(videoPath, targetDuration, outputDir, sceneLa
|
|
|
459020
459084
|
6e5
|
|
459021
459085
|
);
|
|
459022
459086
|
if (waitResult.status === "completed" && waitResult.videoUrl) {
|
|
459023
|
-
const extendedVideoPath =
|
|
459087
|
+
const extendedVideoPath = resolve48(
|
|
459024
459088
|
outputDir,
|
|
459025
459089
|
`${basename11(videoPath, ".mp4")}-kling-ext.mp4`
|
|
459026
459090
|
);
|
|
459027
459091
|
const buffer = await downloadVideo(waitResult.videoUrl);
|
|
459028
459092
|
await writeFile31(extendedVideoPath, buffer);
|
|
459029
|
-
const concatPath =
|
|
459093
|
+
const concatPath = resolve48(
|
|
459030
459094
|
outputDir,
|
|
459031
459095
|
`${basename11(videoPath, ".mp4")}-concat.mp4`
|
|
459032
459096
|
);
|
|
459033
|
-
const listPath =
|
|
459097
|
+
const listPath = resolve48(
|
|
459034
459098
|
outputDir,
|
|
459035
459099
|
`${basename11(videoPath, ".mp4")}-concat.txt`
|
|
459036
459100
|
);
|
|
@@ -459272,7 +459336,7 @@ var init_video_providers = __esm({
|
|
|
459272
459336
|
|
|
459273
459337
|
// ../cli/src/commands/ai-script-pipeline.ts
|
|
459274
459338
|
import { readFile as readFile24, writeFile as writeFile32, unlink as unlink6, rename as rename6 } from "node:fs/promises";
|
|
459275
|
-
import { resolve as
|
|
459339
|
+
import { resolve as resolve49, extname as extname10 } from "node:path";
|
|
459276
459340
|
import { existsSync as existsSync48 } from "node:fs";
|
|
459277
459341
|
async function executeRegenerateScene(options) {
|
|
459278
459342
|
const result = {
|
|
@@ -459281,12 +459345,12 @@ async function executeRegenerateScene(options) {
|
|
|
459281
459345
|
failedScenes: []
|
|
459282
459346
|
};
|
|
459283
459347
|
try {
|
|
459284
|
-
const outputDir =
|
|
459348
|
+
const outputDir = resolve49(process.cwd(), options.projectDir);
|
|
459285
459349
|
if (!existsSync48(outputDir)) {
|
|
459286
459350
|
return { ...result, error: `Project directory not found: ${outputDir}` };
|
|
459287
459351
|
}
|
|
459288
|
-
const yamlPath =
|
|
459289
|
-
const jsonPath =
|
|
459352
|
+
const yamlPath = resolve49(outputDir, "storyboard.yaml");
|
|
459353
|
+
const jsonPath = resolve49(outputDir, "storyboard.json");
|
|
459290
459354
|
const storyboardPath = existsSync48(yamlPath) ? yamlPath : existsSync48(jsonPath) ? jsonPath : null;
|
|
459291
459355
|
if (!storyboardPath) {
|
|
459292
459356
|
return { ...result, error: `Storyboard not found in: ${outputDir} (expected storyboard.yaml or storyboard.json)` };
|
|
@@ -459346,9 +459410,9 @@ async function executeRegenerateScene(options) {
|
|
|
459346
459410
|
let storyboardMutated = false;
|
|
459347
459411
|
for (const sceneNum of options.scenes) {
|
|
459348
459412
|
const segment = segments[sceneNum - 1];
|
|
459349
|
-
const narrationPath =
|
|
459350
|
-
const imagePath =
|
|
459351
|
-
const videoPath =
|
|
459413
|
+
const narrationPath = resolve49(outputDir, `narration-${sceneNum}.mp3`);
|
|
459414
|
+
const imagePath = resolve49(outputDir, `scene-${sceneNum}.png`);
|
|
459415
|
+
const videoPath = resolve49(outputDir, `scene-${sceneNum}.mp4`);
|
|
459352
459416
|
let sceneFailed = false;
|
|
459353
459417
|
if (regenerateNarration && elevenlabsApiKey) {
|
|
459354
459418
|
options.onProgress?.(`Scene ${sceneNum}: regenerating narration...`);
|
|
@@ -459379,14 +459443,14 @@ IMPORTANT - Character appearance must match exactly: ${characterDesc}`;
|
|
|
459379
459443
|
let referenceImageBuffer;
|
|
459380
459444
|
const refSceneNum = options.referenceScene;
|
|
459381
459445
|
if (refSceneNum && refSceneNum >= 1 && refSceneNum <= segments.length && refSceneNum !== sceneNum) {
|
|
459382
|
-
const refImagePath =
|
|
459446
|
+
const refImagePath = resolve49(outputDir, `scene-${refSceneNum}.png`);
|
|
459383
459447
|
if (existsSync48(refImagePath)) {
|
|
459384
459448
|
referenceImageBuffer = await readFile24(refImagePath);
|
|
459385
459449
|
}
|
|
459386
459450
|
} else if (!refSceneNum) {
|
|
459387
459451
|
for (let i = 1; i <= segments.length; i++) {
|
|
459388
459452
|
if (i !== sceneNum) {
|
|
459389
|
-
const otherImagePath =
|
|
459453
|
+
const otherImagePath = resolve49(outputDir, `scene-${i}.png`);
|
|
459390
459454
|
if (existsSync48(otherImagePath)) {
|
|
459391
459455
|
referenceImageBuffer = await readFile24(otherImagePath);
|
|
459392
459456
|
break;
|
|
@@ -459509,7 +459573,7 @@ Generate the single-person scene image now.`;
|
|
|
459509
459573
|
const targetDuration = segment.duration;
|
|
459510
459574
|
const actualVideoDuration = await getVideoDuration(videoPath);
|
|
459511
459575
|
if (actualVideoDuration < targetDuration - 0.1) {
|
|
459512
|
-
const extendedPath =
|
|
459576
|
+
const extendedPath = resolve49(outputDir, `scene-${sceneNum}-extended.mp4`);
|
|
459513
459577
|
await extendVideoNaturally(videoPath, targetDuration, extendedPath);
|
|
459514
459578
|
await unlink6(videoPath);
|
|
459515
459579
|
await rename6(extendedPath, videoPath);
|
|
@@ -459552,7 +459616,7 @@ Generate the single-person scene image now.`;
|
|
|
459552
459616
|
const targetDuration = segment.duration;
|
|
459553
459617
|
const actualVideoDuration = await getVideoDuration(videoPath);
|
|
459554
459618
|
if (actualVideoDuration < targetDuration - 0.1) {
|
|
459555
|
-
const extendedPath =
|
|
459619
|
+
const extendedPath = resolve49(outputDir, `scene-${sceneNum}-extended.mp4`);
|
|
459556
459620
|
await extendVideoNaturally(videoPath, targetDuration, extendedPath);
|
|
459557
459621
|
await unlink6(videoPath);
|
|
459558
459622
|
await rename6(extendedPath, videoPath);
|
|
@@ -459646,7 +459710,7 @@ Generate the single-person scene image now.`;
|
|
|
459646
459710
|
const targetDuration = segment.duration;
|
|
459647
459711
|
const actualVideoDuration = await getVideoDuration(videoPath);
|
|
459648
459712
|
if (actualVideoDuration < targetDuration - 0.1) {
|
|
459649
|
-
const extendedPath =
|
|
459713
|
+
const extendedPath = resolve49(outputDir, `scene-${sceneNum}-extended.mp4`);
|
|
459650
459714
|
await extendVideoNaturally(videoPath, targetDuration, extendedPath);
|
|
459651
459715
|
await unlink6(videoPath);
|
|
459652
459716
|
await rename6(extendedPath, videoPath);
|
|
@@ -459702,7 +459766,7 @@ var init_ai_script_pipeline = __esm({
|
|
|
459702
459766
|
});
|
|
459703
459767
|
|
|
459704
459768
|
// ../cli/src/commands/generate/video.ts
|
|
459705
|
-
import { resolve as
|
|
459769
|
+
import { resolve as resolve50 } from "node:path";
|
|
459706
459770
|
import { readFile as readFile25, writeFile as writeFile33 } from "node:fs/promises";
|
|
459707
459771
|
function registerVideoCommand(parent) {
|
|
459708
459772
|
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 +459845,7 @@ Examples:
|
|
|
459781
459845
|
let referenceImage;
|
|
459782
459846
|
let isImageToVideo = false;
|
|
459783
459847
|
if (options.image) {
|
|
459784
|
-
const imagePath =
|
|
459848
|
+
const imagePath = resolve50(process.cwd(), options.image);
|
|
459785
459849
|
const imageBuffer = await readFile25(imagePath);
|
|
459786
459850
|
const ext = options.image.toLowerCase().split(".").pop();
|
|
459787
459851
|
const mimeTypes = {
|
|
@@ -459986,7 +460050,7 @@ Examples:
|
|
|
459986
460050
|
const veoDuration = parseInt(options.duration) <= 6 ? 6 : 8;
|
|
459987
460051
|
let lastFrame;
|
|
459988
460052
|
if (options.lastFrame) {
|
|
459989
|
-
const lastFramePath =
|
|
460053
|
+
const lastFramePath = resolve50(process.cwd(), options.lastFrame);
|
|
459990
460054
|
const lastFrameBuffer = await readFile25(lastFramePath);
|
|
459991
460055
|
const ext = options.lastFrame.toLowerCase().split(".").pop();
|
|
459992
460056
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
@@ -459996,7 +460060,7 @@ Examples:
|
|
|
459996
460060
|
if (options.refImages && options.refImages.length > 0) {
|
|
459997
460061
|
refImages = [];
|
|
459998
460062
|
for (const refPath of options.refImages.slice(0, 3)) {
|
|
459999
|
-
const absRefPath =
|
|
460063
|
+
const absRefPath = resolve50(process.cwd(), refPath);
|
|
460000
460064
|
const refBuffer = await readFile25(absRefPath);
|
|
460001
460065
|
const ext = refPath.toLowerCase().split(".").pop();
|
|
460002
460066
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
@@ -460115,7 +460179,7 @@ Examples:
|
|
|
460115
460179
|
let outputPath;
|
|
460116
460180
|
if (options.output && finalResult.videoUrl) {
|
|
460117
460181
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
460118
|
-
outputPath =
|
|
460182
|
+
outputPath = resolve50(process.cwd(), options.output);
|
|
460119
460183
|
await writeFile33(outputPath, buffer);
|
|
460120
460184
|
}
|
|
460121
460185
|
outputSuccess({
|
|
@@ -460143,7 +460207,7 @@ Examples:
|
|
|
460143
460207
|
const downloadSpinner = ora("Downloading video...").start();
|
|
460144
460208
|
try {
|
|
460145
460209
|
const buffer = await downloadVideo(finalResult.videoUrl, apiKey);
|
|
460146
|
-
const outputPath =
|
|
460210
|
+
const outputPath = resolve50(process.cwd(), options.output);
|
|
460147
460211
|
await writeFile33(outputPath, buffer);
|
|
460148
460212
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
460149
460213
|
} catch (err) {
|
|
@@ -460267,7 +460331,7 @@ __export(ai_video_exports, {
|
|
|
460267
460331
|
executeVideoStatus: () => executeVideoStatus
|
|
460268
460332
|
});
|
|
460269
460333
|
import { readFile as readFile26, writeFile as writeFile34 } from "node:fs/promises";
|
|
460270
|
-
import { resolve as
|
|
460334
|
+
import { resolve as resolve51 } from "node:path";
|
|
460271
460335
|
async function executeVideoGenerate(options) {
|
|
460272
460336
|
const {
|
|
460273
460337
|
prompt: prompt3,
|
|
@@ -460298,7 +460362,7 @@ async function executeVideoGenerate(options) {
|
|
|
460298
460362
|
if (!key2) return { success: false, error: `${envKeyMap[provider]} required for ${provider}` };
|
|
460299
460363
|
let referenceImage;
|
|
460300
460364
|
if (image) {
|
|
460301
|
-
const imagePath =
|
|
460365
|
+
const imagePath = resolve51(process.cwd(), image);
|
|
460302
460366
|
const imageBuffer = await readFile26(imagePath);
|
|
460303
460367
|
const ext = image.toLowerCase().split(".").pop();
|
|
460304
460368
|
const mimeTypes = { jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png", gif: "image/gif", webp: "image/webp" };
|
|
@@ -460330,7 +460394,7 @@ async function executeVideoGenerate(options) {
|
|
|
460330
460394
|
let outputPath;
|
|
460331
460395
|
if (output3 && result.videoUrl) {
|
|
460332
460396
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
460333
|
-
outputPath =
|
|
460397
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460334
460398
|
await writeFile34(outputPath, buffer);
|
|
460335
460399
|
}
|
|
460336
460400
|
return { success: true, taskId: result.id, status: "completed", videoUrl: result.videoUrl, outputPath, provider: "seedance" };
|
|
@@ -460352,7 +460416,7 @@ async function executeVideoGenerate(options) {
|
|
|
460352
460416
|
let outputPath;
|
|
460353
460417
|
if (output3 && finalResult.videoUrl) {
|
|
460354
460418
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460355
|
-
outputPath =
|
|
460419
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460356
460420
|
await writeFile34(outputPath, buffer);
|
|
460357
460421
|
}
|
|
460358
460422
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, duration: finalResult.duration, outputPath, provider: "runway" };
|
|
@@ -460386,7 +460450,7 @@ async function executeVideoGenerate(options) {
|
|
|
460386
460450
|
let outputPath;
|
|
460387
460451
|
if (output3 && finalResult.videoUrl) {
|
|
460388
460452
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460389
|
-
outputPath =
|
|
460453
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460390
460454
|
await writeFile34(outputPath, buffer);
|
|
460391
460455
|
}
|
|
460392
460456
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, duration: finalResult.duration, outputPath, provider: "kling" };
|
|
@@ -460413,7 +460477,7 @@ async function executeVideoGenerate(options) {
|
|
|
460413
460477
|
let outputPath;
|
|
460414
460478
|
if (output3 && finalResult.videoUrl) {
|
|
460415
460479
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460416
|
-
outputPath =
|
|
460480
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460417
460481
|
await writeFile34(outputPath, buffer);
|
|
460418
460482
|
}
|
|
460419
460483
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, outputPath, provider: "veo" };
|
|
@@ -460434,7 +460498,7 @@ async function executeVideoGenerate(options) {
|
|
|
460434
460498
|
let outputPath;
|
|
460435
460499
|
if (output3 && finalResult.videoUrl) {
|
|
460436
460500
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460437
|
-
outputPath =
|
|
460501
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460438
460502
|
await writeFile34(outputPath, buffer);
|
|
460439
460503
|
}
|
|
460440
460504
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, duration: finalResult.duration, outputPath, provider: "grok" };
|
|
@@ -460461,7 +460525,7 @@ async function executeVideoStatus(options) {
|
|
|
460461
460525
|
let outputPath;
|
|
460462
460526
|
if (output3 && result.videoUrl) {
|
|
460463
460527
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
460464
|
-
outputPath =
|
|
460528
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460465
460529
|
await writeFile34(outputPath, buffer);
|
|
460466
460530
|
}
|
|
460467
460531
|
return { success: true, taskId, status: result.status, progress: result.progress, videoUrl: result.videoUrl, outputPath };
|
|
@@ -460476,7 +460540,7 @@ async function executeVideoStatus(options) {
|
|
|
460476
460540
|
let outputPath;
|
|
460477
460541
|
if (output3 && result.videoUrl) {
|
|
460478
460542
|
const buffer = await downloadVideo(result.videoUrl, key2);
|
|
460479
|
-
outputPath =
|
|
460543
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460480
460544
|
await writeFile34(outputPath, buffer);
|
|
460481
460545
|
}
|
|
460482
460546
|
return { success: true, taskId, status: result.status, videoUrl: result.videoUrl, duration: result.duration, outputPath };
|
|
@@ -460521,7 +460585,7 @@ async function executeVideoExtend(options) {
|
|
|
460521
460585
|
let outputPath;
|
|
460522
460586
|
if (output3 && finalResult.videoUrl) {
|
|
460523
460587
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460524
|
-
outputPath =
|
|
460588
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460525
460589
|
await writeFile34(outputPath, buffer);
|
|
460526
460590
|
}
|
|
460527
460591
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, duration: finalResult.duration, outputPath };
|
|
@@ -460544,7 +460608,7 @@ async function executeVideoExtend(options) {
|
|
|
460544
460608
|
let outputPath;
|
|
460545
460609
|
if (output3 && finalResult.videoUrl) {
|
|
460546
460610
|
const buffer = await downloadVideo(finalResult.videoUrl, key2);
|
|
460547
|
-
outputPath =
|
|
460611
|
+
outputPath = resolve51(process.cwd(), output3);
|
|
460548
460612
|
await writeFile34(outputPath, buffer);
|
|
460549
460613
|
}
|
|
460550
460614
|
return { success: true, taskId: result.id, status: "completed", videoUrl: finalResult.videoUrl, outputPath };
|
|
@@ -460572,13 +460636,13 @@ __export(detect_exports, {
|
|
|
460572
460636
|
executeDetectSilence: () => executeDetectSilence
|
|
460573
460637
|
});
|
|
460574
460638
|
import { readFile as readFile28, writeFile as writeFile36 } from "node:fs/promises";
|
|
460575
|
-
import { resolve as
|
|
460639
|
+
import { resolve as resolve54, basename as basename13 } from "node:path";
|
|
460576
460640
|
async function executeDetectScenes(options) {
|
|
460577
460641
|
try {
|
|
460578
460642
|
if (!commandExists("ffmpeg")) {
|
|
460579
460643
|
return { success: false, error: "FFmpeg not found. Install with: brew install ffmpeg" };
|
|
460580
460644
|
}
|
|
460581
|
-
const absPath =
|
|
460645
|
+
const absPath = resolve54(process.cwd(), options.videoPath);
|
|
460582
460646
|
const threshold = options.threshold ?? 0.3;
|
|
460583
460647
|
const { stdout: sceneStdout, stderr: sceneStderr } = await execSafe("ffmpeg", [
|
|
460584
460648
|
"-i",
|
|
@@ -460609,7 +460673,7 @@ async function executeDetectScenes(options) {
|
|
|
460609
460673
|
duration: (i < scenes.length - 1 ? scenes[i + 1].timestamp : totalDuration) - s.timestamp
|
|
460610
460674
|
}));
|
|
460611
460675
|
if (options.outputPath) {
|
|
460612
|
-
const outputPath =
|
|
460676
|
+
const outputPath = resolve54(process.cwd(), options.outputPath);
|
|
460613
460677
|
await writeFile36(outputPath, JSON.stringify({ source: absPath, totalDuration, threshold, scenes: result }, null, 2), "utf-8");
|
|
460614
460678
|
}
|
|
460615
460679
|
return { success: true, scenes: result, totalDuration };
|
|
@@ -460622,7 +460686,7 @@ async function executeDetectSilence(options) {
|
|
|
460622
460686
|
if (!commandExists("ffmpeg")) {
|
|
460623
460687
|
return { success: false, error: "FFmpeg not found. Install with: brew install ffmpeg" };
|
|
460624
460688
|
}
|
|
460625
|
-
const absPath =
|
|
460689
|
+
const absPath = resolve54(process.cwd(), options.mediaPath);
|
|
460626
460690
|
const noise = options.noise ?? "-30";
|
|
460627
460691
|
const duration = options.duration ?? "0.5";
|
|
460628
460692
|
const { stdout: silStdout, stderr: silStderr } = await execSafe("ffmpeg", [
|
|
@@ -460656,7 +460720,7 @@ async function executeDetectSilence(options) {
|
|
|
460656
460720
|
}
|
|
460657
460721
|
}
|
|
460658
460722
|
if (options.outputPath) {
|
|
460659
|
-
const outputPath =
|
|
460723
|
+
const outputPath = resolve54(process.cwd(), options.outputPath);
|
|
460660
460724
|
await writeFile36(outputPath, JSON.stringify({ source: absPath, silences }, null, 2), "utf-8");
|
|
460661
460725
|
}
|
|
460662
460726
|
return { success: true, silences };
|
|
@@ -460669,7 +460733,7 @@ async function executeDetectBeats(options) {
|
|
|
460669
460733
|
if (!commandExists("ffmpeg")) {
|
|
460670
460734
|
return { success: false, error: "FFmpeg not found. Install with: brew install ffmpeg" };
|
|
460671
460735
|
}
|
|
460672
|
-
const absPath =
|
|
460736
|
+
const absPath = resolve54(process.cwd(), options.audioPath);
|
|
460673
460737
|
const { stdout: beatStdout, stderr: beatStderr } = await execSafe("ffmpeg", [
|
|
460674
460738
|
"-i",
|
|
460675
460739
|
absPath,
|
|
@@ -460705,7 +460769,7 @@ async function executeDetectBeats(options) {
|
|
|
460705
460769
|
}
|
|
460706
460770
|
}
|
|
460707
460771
|
if (options.outputPath) {
|
|
460708
|
-
const outputPath =
|
|
460772
|
+
const outputPath = resolve54(process.cwd(), options.outputPath);
|
|
460709
460773
|
await writeFile36(outputPath, JSON.stringify({ source: absPath, beatCount: beats.length, beats }, null, 2), "utf-8");
|
|
460710
460774
|
}
|
|
460711
460775
|
return { success: true, beats, beatCount: beats.length };
|
|
@@ -460756,7 +460820,7 @@ var init_detect = __esm({
|
|
|
460756
460820
|
spinner2.fail("FFmpeg not found");
|
|
460757
460821
|
exitWithError(generalError("FFmpeg not found", "Install with: brew install ffmpeg (macOS) or apt install ffmpeg (Linux)"));
|
|
460758
460822
|
}
|
|
460759
|
-
const absPath =
|
|
460823
|
+
const absPath = resolve54(process.cwd(), videoPath);
|
|
460760
460824
|
const threshold = parseFloat(options.threshold);
|
|
460761
460825
|
spinner2.text = "Analyzing video...";
|
|
460762
460826
|
const { stdout: sceneStdout, stderr: sceneStderr } = await execSafe("ffmpeg", [
|
|
@@ -460797,7 +460861,7 @@ var init_detect = __esm({
|
|
|
460797
460861
|
}
|
|
460798
460862
|
console.log();
|
|
460799
460863
|
if (options.output) {
|
|
460800
|
-
const outputPath =
|
|
460864
|
+
const outputPath = resolve54(process.cwd(), options.output);
|
|
460801
460865
|
const result = {
|
|
460802
460866
|
source: absPath,
|
|
460803
460867
|
totalDuration,
|
|
@@ -460813,7 +460877,7 @@ var init_detect = __esm({
|
|
|
460813
460877
|
console.log(source_default.green(`Saved to: ${outputPath}`));
|
|
460814
460878
|
}
|
|
460815
460879
|
if (options.project) {
|
|
460816
|
-
const projectPath =
|
|
460880
|
+
const projectPath = resolve54(process.cwd(), options.project);
|
|
460817
460881
|
const content = await readFile28(projectPath, "utf-8");
|
|
460818
460882
|
const data = JSON.parse(content);
|
|
460819
460883
|
const project = Project.fromJSON(data);
|
|
@@ -460871,7 +460935,7 @@ var init_detect = __esm({
|
|
|
460871
460935
|
});
|
|
460872
460936
|
return;
|
|
460873
460937
|
}
|
|
460874
|
-
const absPath =
|
|
460938
|
+
const absPath = resolve54(process.cwd(), mediaPath);
|
|
460875
460939
|
const noise = options.noise;
|
|
460876
460940
|
const duration = options.duration;
|
|
460877
460941
|
const { stdout: silStdout, stderr: silStderr } = await execSafe("ffmpeg", [
|
|
@@ -460920,7 +460984,7 @@ var init_detect = __esm({
|
|
|
460920
460984
|
}
|
|
460921
460985
|
console.log();
|
|
460922
460986
|
if (options.output) {
|
|
460923
|
-
const outputPath =
|
|
460987
|
+
const outputPath = resolve54(process.cwd(), options.output);
|
|
460924
460988
|
await writeFile36(
|
|
460925
460989
|
outputPath,
|
|
460926
460990
|
JSON.stringify({ source: absPath, silences }, null, 2),
|
|
@@ -460955,7 +461019,7 @@ var init_detect = __esm({
|
|
|
460955
461019
|
});
|
|
460956
461020
|
return;
|
|
460957
461021
|
}
|
|
460958
|
-
const absPath =
|
|
461022
|
+
const absPath = resolve54(process.cwd(), audioPath);
|
|
460959
461023
|
const { stdout: beatStdout, stderr: beatStderr } = await execSafe("ffmpeg", [
|
|
460960
461024
|
"-i",
|
|
460961
461025
|
absPath,
|
|
@@ -461005,7 +461069,7 @@ var init_detect = __esm({
|
|
|
461005
461069
|
}
|
|
461006
461070
|
console.log();
|
|
461007
461071
|
if (options.output) {
|
|
461008
|
-
const outputPath =
|
|
461072
|
+
const outputPath = resolve54(process.cwd(), options.output);
|
|
461009
461073
|
await writeFile36(
|
|
461010
461074
|
outputPath,
|
|
461011
461075
|
JSON.stringify({ source: absPath, beatCount: beats.length, beats }, null, 2),
|
|
@@ -461024,8 +461088,8 @@ var init_detect = __esm({
|
|
|
461024
461088
|
|
|
461025
461089
|
// ../cli/src/pipeline/renderers/html-clips.ts
|
|
461026
461090
|
function relAsset(url) {
|
|
461027
|
-
const
|
|
461028
|
-
return `assets/${
|
|
461091
|
+
const basename18 = url.split("/").pop() ?? url;
|
|
461092
|
+
return `assets/${basename18}`;
|
|
461029
461093
|
}
|
|
461030
461094
|
function buildClipElements(state) {
|
|
461031
461095
|
return state.clips.map((clip) => {
|
|
@@ -461199,7 +461263,7 @@ __export(project_builder_exports, {
|
|
|
461199
461263
|
buildTempProject: () => buildTempProject,
|
|
461200
461264
|
resolveSourceUrl: () => resolveSourceUrl
|
|
461201
461265
|
});
|
|
461202
|
-
import { mkdtemp as mkdtemp4, mkdir as
|
|
461266
|
+
import { mkdtemp as mkdtemp4, mkdir as mkdir25, copyFile as copyFile4, writeFile as writeFile42, rm as rm5, readdir as readdir4 } from "node:fs/promises";
|
|
461203
461267
|
import { existsSync as existsSync51 } from "node:fs";
|
|
461204
461268
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
461205
461269
|
import { createRequire } from "node:module";
|
|
@@ -461207,7 +461271,7 @@ import * as path13 from "node:path";
|
|
|
461207
461271
|
async function buildTempProject(state, projectFileDir) {
|
|
461208
461272
|
const dir = await mkdtemp4(path13.join(tmpdir6(), "vibeframe-hf-"));
|
|
461209
461273
|
const assetsDir = path13.join(dir, "assets");
|
|
461210
|
-
await
|
|
461274
|
+
await mkdir25(assetsDir, { recursive: true });
|
|
461211
461275
|
const copied = /* @__PURE__ */ new Map();
|
|
461212
461276
|
for (const source3 of state.sources) {
|
|
461213
461277
|
if (copied.has(source3.id)) continue;
|
|
@@ -461223,7 +461287,7 @@ async function buildTempProject(state, projectFileDir) {
|
|
|
461223
461287
|
await copyLottieRuntime(dir);
|
|
461224
461288
|
}
|
|
461225
461289
|
const html = generateCompositionHtml(state);
|
|
461226
|
-
await
|
|
461290
|
+
await writeFile42(path13.join(dir, "index.html"), html, "utf-8");
|
|
461227
461291
|
return {
|
|
461228
461292
|
dir,
|
|
461229
461293
|
cleanup: () => rm5(dir, { recursive: true, force: true })
|
|
@@ -461237,7 +461301,7 @@ async function copyLottieRuntime(tempDir) {
|
|
|
461237
461301
|
const wasmSrc = path13.join(path13.dirname(webEntry), "dotlottie-player.wasm");
|
|
461238
461302
|
const vendorDir = path13.join(tempDir, "vendor");
|
|
461239
461303
|
const wcDest = path13.join(vendorDir, "dotlottie-wc");
|
|
461240
|
-
await
|
|
461304
|
+
await mkdir25(wcDest, { recursive: true });
|
|
461241
461305
|
for (const file of await readdir4(wcDistDir)) {
|
|
461242
461306
|
if (file.endsWith(".map") || file.endsWith(".d.ts")) continue;
|
|
461243
461307
|
await copyFile4(path13.join(wcDistDir, file), path13.join(wcDest, file));
|
|
@@ -463279,7 +463343,7 @@ init_ai_edit();
|
|
|
463279
463343
|
init_api_key();
|
|
463280
463344
|
init_exec_safe();
|
|
463281
463345
|
init_remotion();
|
|
463282
|
-
import { resolve as
|
|
463346
|
+
import { resolve as resolve31, dirname as dirname23, basename as basename9 } from "node:path";
|
|
463283
463347
|
import { writeFile as writeFile18, mkdir as mkdir16, rm as rm4 } from "node:fs/promises";
|
|
463284
463348
|
import { existsSync as existsSync41 } from "node:fs";
|
|
463285
463349
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
@@ -463431,9 +463495,9 @@ async function executeAnimatedCaption(options) {
|
|
|
463431
463495
|
} catch {
|
|
463432
463496
|
}
|
|
463433
463497
|
const effectiveFontSize = fontSize ?? Math.round(height * 0.04);
|
|
463434
|
-
const tmpAudioDir =
|
|
463498
|
+
const tmpAudioDir = resolve31(tmpdir4(), `vf-ac-${Date.now()}`);
|
|
463435
463499
|
await mkdir16(tmpAudioDir, { recursive: true });
|
|
463436
|
-
const audioPath =
|
|
463500
|
+
const audioPath = resolve31(tmpAudioDir, "audio.wav");
|
|
463437
463501
|
await execSafe("ffmpeg", [
|
|
463438
463502
|
"-y",
|
|
463439
463503
|
"-i",
|
|
@@ -463460,7 +463524,7 @@ async function executeAnimatedCaption(options) {
|
|
|
463460
463524
|
return { success: false, error: "No words detected in transcription" };
|
|
463461
463525
|
}
|
|
463462
463526
|
const groups = groupWords(transcript.words, { wordsPerGroup, maxChars });
|
|
463463
|
-
const absOutputPath =
|
|
463527
|
+
const absOutputPath = resolve31(process.cwd(), outputPath);
|
|
463464
463528
|
const outDir = dirname23(absOutputPath);
|
|
463465
463529
|
if (!existsSync41(outDir)) {
|
|
463466
463530
|
await mkdir16(outDir, { recursive: true });
|
|
@@ -463471,7 +463535,7 @@ async function executeAnimatedCaption(options) {
|
|
|
463471
463535
|
effectiveStyle,
|
|
463472
463536
|
{ highlightColor, fontSize: effectiveFontSize, position, width, height }
|
|
463473
463537
|
);
|
|
463474
|
-
const assPath =
|
|
463538
|
+
const assPath = resolve31(tmpAudioDir, "captions.ass");
|
|
463475
463539
|
await writeFile18(assPath, assContent, "utf-8");
|
|
463476
463540
|
const escapedAssPath = assPath.replace(/\\/g, "\\\\").replace(/:/g, "\\:");
|
|
463477
463541
|
await execSafe("ffmpeg", [
|
|
@@ -463876,7 +463940,7 @@ var editFillGapsTool = defineTool({
|
|
|
463876
463940
|
cost: "high",
|
|
463877
463941
|
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
463942
|
schema: z3.object({
|
|
463879
|
-
projectPath: z3.string().describe("
|
|
463943
|
+
projectPath: z3.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
463880
463944
|
output: z3.string().optional().describe("Output project path (default: overwrite input)"),
|
|
463881
463945
|
dir: z3.string().optional().describe("Directory to save generated videos (default: <projectDir>/footage)"),
|
|
463882
463946
|
prompt: z3.string().optional().describe("Custom prompt for video generation (default: 'Continue the scene naturally with subtle motion')"),
|
|
@@ -463940,12 +464004,12 @@ init_dist();
|
|
|
463940
464004
|
init_engine();
|
|
463941
464005
|
init_ai_helpers();
|
|
463942
464006
|
import { readFile as readFile21, writeFile as writeFile20 } from "node:fs/promises";
|
|
463943
|
-
import { resolve as
|
|
464007
|
+
import { resolve as resolve36 } from "node:path";
|
|
463944
464008
|
async function executeSuggestEdit(options) {
|
|
463945
464009
|
try {
|
|
463946
464010
|
const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY;
|
|
463947
464011
|
if (!apiKey) return { success: false, error: "GOOGLE_API_KEY required for suggest" };
|
|
463948
|
-
const filePath =
|
|
464012
|
+
const filePath = resolve36(process.cwd(), options.projectPath);
|
|
463949
464013
|
const content = await readFile21(filePath, "utf-8");
|
|
463950
464014
|
const data = JSON.parse(content);
|
|
463951
464015
|
const project = Project.fromJSON(data);
|
|
@@ -464065,7 +464129,7 @@ var analyzeSuggestTool = defineTool({
|
|
|
464065
464129
|
cost: "low",
|
|
464066
464130
|
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
464131
|
schema: z4.object({
|
|
464068
|
-
projectPath: z4.string().describe("
|
|
464132
|
+
projectPath: z4.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
464069
464133
|
instruction: z4.string().describe("Natural-language instruction (e.g. 'trim all clips to 5 seconds', 'add transitions between every clip')"),
|
|
464070
464134
|
apply: z4.boolean().optional().describe("Apply the first suggestion in place")
|
|
464071
464135
|
}),
|
|
@@ -464427,7 +464491,7 @@ init_ai_script_pipeline();
|
|
|
464427
464491
|
|
|
464428
464492
|
// ../cli/src/commands/ai-highlights.ts
|
|
464429
464493
|
import { readFile as readFile27, writeFile as writeFile35, mkdir as mkdir21 } from "node:fs/promises";
|
|
464430
|
-
import { resolve as
|
|
464494
|
+
import { resolve as resolve53, dirname as dirname28, basename as basename12, extname as extname11 } from "node:path";
|
|
464431
464495
|
import { existsSync as existsSync49 } from "node:fs";
|
|
464432
464496
|
init_dist();
|
|
464433
464497
|
init_engine();
|
|
@@ -464458,7 +464522,7 @@ function filterHighlights(highlights, options) {
|
|
|
464458
464522
|
}
|
|
464459
464523
|
async function executeHighlights(options) {
|
|
464460
464524
|
try {
|
|
464461
|
-
const absPath =
|
|
464525
|
+
const absPath = resolve53(process.cwd(), options.media);
|
|
464462
464526
|
if (!existsSync49(absPath)) {
|
|
464463
464527
|
return { success: false, highlights: [], totalDuration: 0, totalHighlightDuration: 0, error: `File not found: ${absPath}` };
|
|
464464
464528
|
}
|
|
@@ -464606,7 +464670,7 @@ Analyze both what is SHOWN (visual cues, actions, expressions) and what is SAID
|
|
|
464606
464670
|
totalHighlightDuration
|
|
464607
464671
|
};
|
|
464608
464672
|
if (options.output) {
|
|
464609
|
-
const outputPath =
|
|
464673
|
+
const outputPath = resolve53(process.cwd(), options.output);
|
|
464610
464674
|
await writeFile35(outputPath, JSON.stringify({
|
|
464611
464675
|
sourceFile: absPath,
|
|
464612
464676
|
totalDuration: sourceDuration,
|
|
@@ -464641,7 +464705,7 @@ Analyze both what is SHOWN (visual cues, actions, expressions) and what is SAID
|
|
|
464641
464705
|
currentTime += highlight.duration;
|
|
464642
464706
|
}
|
|
464643
464707
|
}
|
|
464644
|
-
const projectPath =
|
|
464708
|
+
const projectPath = resolve53(process.cwd(), options.project);
|
|
464645
464709
|
await writeFile35(projectPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
464646
464710
|
extractResult.projectPath = projectPath;
|
|
464647
464711
|
}
|
|
@@ -464661,7 +464725,7 @@ async function executeAutoShorts(options) {
|
|
|
464661
464725
|
if (!commandExists("ffmpeg")) {
|
|
464662
464726
|
return { success: false, shorts: [], error: "FFmpeg not found" };
|
|
464663
464727
|
}
|
|
464664
|
-
const absPath =
|
|
464728
|
+
const absPath = resolve53(process.cwd(), options.video);
|
|
464665
464729
|
if (!existsSync49(absPath)) {
|
|
464666
464730
|
return { success: false, shorts: [], error: `File not found: ${absPath}` };
|
|
464667
464731
|
}
|
|
@@ -464789,7 +464853,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
464789
464853
|
}))
|
|
464790
464854
|
};
|
|
464791
464855
|
}
|
|
464792
|
-
const outputDir = options.outputDir ?
|
|
464856
|
+
const outputDir = options.outputDir ? resolve53(process.cwd(), options.outputDir) : dirname28(absPath);
|
|
464793
464857
|
if (options.outputDir && !existsSync49(outputDir)) {
|
|
464794
464858
|
await mkdir21(outputDir, { recursive: true });
|
|
464795
464859
|
}
|
|
@@ -464800,7 +464864,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
464800
464864
|
for (let i = 0; i < selectedHighlights.length; i++) {
|
|
464801
464865
|
const h = selectedHighlights[i];
|
|
464802
464866
|
const baseName = basename12(absPath, extname11(absPath));
|
|
464803
|
-
const outputPath =
|
|
464867
|
+
const outputPath = resolve53(outputDir, `${baseName}-short-${i + 1}.mp4`);
|
|
464804
464868
|
const { stdout: probeOut } = await execSafe("ffprobe", [
|
|
464805
464869
|
"-v",
|
|
464806
464870
|
"error",
|
|
@@ -464868,7 +464932,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
464868
464932
|
|
|
464869
464933
|
// ../cli/src/pipeline/executor.ts
|
|
464870
464934
|
var import_yaml7 = __toESM(require_dist(), 1);
|
|
464871
|
-
import { resolve as
|
|
464935
|
+
import { resolve as resolve55 } from "node:path";
|
|
464872
464936
|
import { readFile as readFile29, writeFile as writeFile37, mkdir as mkdir23 } from "node:fs/promises";
|
|
464873
464937
|
import { existsSync as existsSync50 } from "node:fs";
|
|
464874
464938
|
|
|
@@ -464976,9 +465040,9 @@ function registerAction(action, handler4) {
|
|
|
464976
465040
|
}
|
|
464977
465041
|
function getOutput(params, outputDir, defaultName) {
|
|
464978
465042
|
if (params.output && typeof params.output === "string") {
|
|
464979
|
-
return
|
|
465043
|
+
return resolve55(outputDir, params.output);
|
|
464980
465044
|
}
|
|
464981
|
-
return
|
|
465045
|
+
return resolve55(outputDir, defaultName);
|
|
464982
465046
|
}
|
|
464983
465047
|
async function ensureActionsRegistered() {
|
|
464984
465048
|
if (Object.keys(ACTION_HANDLERS).length > 0) return;
|
|
@@ -465131,7 +465195,7 @@ async function ensureActionsRegistered() {
|
|
|
465131
465195
|
const { executeSceneBuild: executeSceneBuild2 } = await Promise.resolve().then(() => (init_scene_build(), scene_build_exports));
|
|
465132
465196
|
const projectRel = params.project ?? ".";
|
|
465133
465197
|
const r = await executeSceneBuild2({
|
|
465134
|
-
projectDir:
|
|
465198
|
+
projectDir: resolve55(outputDir, projectRel),
|
|
465135
465199
|
mode: params.mode,
|
|
465136
465200
|
effort: params.effort,
|
|
465137
465201
|
composer: params.composer,
|
|
@@ -465157,7 +465221,7 @@ async function ensureActionsRegistered() {
|
|
|
465157
465221
|
const { executeSceneRender: executeSceneRender2 } = await Promise.resolve().then(() => (init_scene_render(), scene_render_exports));
|
|
465158
465222
|
const projectRel = params.project ?? ".";
|
|
465159
465223
|
const r = await executeSceneRender2({
|
|
465160
|
-
projectDir:
|
|
465224
|
+
projectDir: resolve55(outputDir, projectRel),
|
|
465161
465225
|
root: params.root,
|
|
465162
465226
|
output: params.output,
|
|
465163
465227
|
fps: params.fps,
|
|
@@ -465181,7 +465245,7 @@ async function ensureActionsRegistered() {
|
|
|
465181
465245
|
});
|
|
465182
465246
|
}
|
|
465183
465247
|
async function loadPipeline(filePath) {
|
|
465184
|
-
const absPath =
|
|
465248
|
+
const absPath = resolve55(process.cwd(), filePath);
|
|
465185
465249
|
if (!existsSync50(absPath)) {
|
|
465186
465250
|
throw new Error(`Pipeline file not found: ${absPath}`);
|
|
465187
465251
|
}
|
|
@@ -465201,13 +465265,13 @@ async function loadPipeline(filePath) {
|
|
|
465201
465265
|
var CHECKPOINT_FILE = ".pipeline-state.yaml";
|
|
465202
465266
|
async function executePipeline(manifest2, options = {}) {
|
|
465203
465267
|
await ensureActionsRegistered();
|
|
465204
|
-
const outputDir =
|
|
465268
|
+
const outputDir = resolve55(process.cwd(), options.outputDir || `${manifest2.name}-output`);
|
|
465205
465269
|
await mkdir23(outputDir, { recursive: true });
|
|
465206
465270
|
const completedSteps = /* @__PURE__ */ new Map();
|
|
465207
465271
|
const results = [];
|
|
465208
465272
|
const startTime = Date.now();
|
|
465209
465273
|
if (options.resume) {
|
|
465210
|
-
const checkpointPath =
|
|
465274
|
+
const checkpointPath = resolve55(outputDir, CHECKPOINT_FILE);
|
|
465211
465275
|
if (existsSync50(checkpointPath)) {
|
|
465212
465276
|
const checkpointContent = await readFile29(checkpointPath, "utf-8");
|
|
465213
465277
|
const checkpoint = (0, import_yaml7.parse)(checkpointContent);
|
|
@@ -465328,7 +465392,7 @@ async function executePipeline(manifest2, options = {}) {
|
|
|
465328
465392
|
}))
|
|
465329
465393
|
};
|
|
465330
465394
|
await writeFile37(
|
|
465331
|
-
|
|
465395
|
+
resolve55(outputDir, CHECKPOINT_FILE),
|
|
465332
465396
|
(0, import_yaml7.stringify)(checkpoint, { indent: 2 }),
|
|
465333
465397
|
"utf-8"
|
|
465334
465398
|
);
|
|
@@ -465385,7 +465449,7 @@ var pipelineHighlightsTool = defineTool({
|
|
|
465385
465449
|
schema: z6.object({
|
|
465386
465450
|
media: z6.string().describe("Path to the input video file"),
|
|
465387
465451
|
output: z6.string().optional().describe("Output path for the highlights compilation"),
|
|
465388
|
-
project: z6.string().optional().describe("Path to .vibe.json
|
|
465452
|
+
project: z6.string().optional().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file to add highlights to"),
|
|
465389
465453
|
duration: z6.number().optional().describe("Maximum duration per highlight in seconds (default: 30)"),
|
|
465390
465454
|
count: z6.number().optional().describe("Maximum number of highlights to extract (default: 5)"),
|
|
465391
465455
|
threshold: z6.number().optional().describe("Minimum confidence threshold 0-1 (default: 0.7)"),
|
|
@@ -465635,14 +465699,17 @@ var detectTools = [
|
|
|
465635
465699
|
|
|
465636
465700
|
// ../cli/src/tools/manifest/timeline.ts
|
|
465637
465701
|
import { z as z8 } from "zod";
|
|
465638
|
-
import {
|
|
465702
|
+
import { mkdir as mkdir24, writeFile as writeFile40 } from "node:fs/promises";
|
|
465703
|
+
import { basename as basename14, resolve as resolve56 } from "node:path";
|
|
465704
|
+
init_engine();
|
|
465705
|
+
init_project_resolver();
|
|
465639
465706
|
|
|
465640
465707
|
// ../cli/src/tools/manifest/_project-io.ts
|
|
465641
465708
|
init_engine();
|
|
465709
|
+
init_project_resolver();
|
|
465642
465710
|
import { readFile as readFile30, writeFile as writeFile39 } from "node:fs/promises";
|
|
465643
|
-
import { resolve as resolve55 } from "node:path";
|
|
465644
465711
|
async function loadProject(projectPath, cwd) {
|
|
465645
|
-
const absPath =
|
|
465712
|
+
const absPath = await resolveTimelineFile(projectPath, cwd);
|
|
465646
465713
|
const content = await readFile30(absPath, "utf-8");
|
|
465647
465714
|
const data = JSON.parse(content);
|
|
465648
465715
|
return { project: Project.fromJSON(data), absPath };
|
|
@@ -465667,13 +465734,70 @@ var MEDIA_TYPES = {
|
|
|
465667
465734
|
gif: "image",
|
|
465668
465735
|
webp: "image"
|
|
465669
465736
|
};
|
|
465737
|
+
var timelineCreateTool = defineTool({
|
|
465738
|
+
name: "timeline_create",
|
|
465739
|
+
category: "timeline",
|
|
465740
|
+
cost: "free",
|
|
465741
|
+
description: "Create a low-level timeline JSON file for FFmpeg-style editing",
|
|
465742
|
+
schema: z8.object({
|
|
465743
|
+
name: z8.string().describe("Timeline name or directory path"),
|
|
465744
|
+
outputPath: z8.string().optional().describe("Output file path. Defaults to <name>/timeline.json"),
|
|
465745
|
+
fps: z8.number().optional().describe("Frames per second (default: 30)")
|
|
465746
|
+
}),
|
|
465747
|
+
async execute(args, ctx) {
|
|
465748
|
+
const projectName = args.name === "." ? basename14(ctx.workingDirectory) : basename14(resolve56(ctx.workingDirectory, args.name));
|
|
465749
|
+
const project = new Project(projectName);
|
|
465750
|
+
if (args.fps) project.setFrameRate(args.fps);
|
|
465751
|
+
let outputPath;
|
|
465752
|
+
if (args.outputPath) {
|
|
465753
|
+
outputPath = resolve56(ctx.workingDirectory, args.outputPath);
|
|
465754
|
+
} else {
|
|
465755
|
+
const dirPath = resolve56(ctx.workingDirectory, args.name);
|
|
465756
|
+
await mkdir24(dirPath, { recursive: true });
|
|
465757
|
+
outputPath = resolve56(dirPath, TIMELINE_FILENAME);
|
|
465758
|
+
}
|
|
465759
|
+
await writeFile40(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
465760
|
+
return {
|
|
465761
|
+
success: true,
|
|
465762
|
+
data: { name: projectName, outputPath },
|
|
465763
|
+
humanLines: [`Created timeline "${projectName}" at ${outputPath}`]
|
|
465764
|
+
};
|
|
465765
|
+
}
|
|
465766
|
+
});
|
|
465767
|
+
var timelineInfoTool = defineTool({
|
|
465768
|
+
name: "timeline_info",
|
|
465769
|
+
category: "timeline",
|
|
465770
|
+
cost: "free",
|
|
465771
|
+
description: "Get information about a timeline JSON file. Legacy *.vibe.json files are supported.",
|
|
465772
|
+
schema: z8.object({
|
|
465773
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
|
|
465774
|
+
}),
|
|
465775
|
+
async execute(args, ctx) {
|
|
465776
|
+
const { project } = await loadProject(args.projectPath, ctx.workingDirectory);
|
|
465777
|
+
const meta = project.getMeta();
|
|
465778
|
+
const info = {
|
|
465779
|
+
name: meta.name,
|
|
465780
|
+
aspectRatio: meta.aspectRatio,
|
|
465781
|
+
frameRate: meta.frameRate,
|
|
465782
|
+
duration: meta.duration,
|
|
465783
|
+
sources: project.getSources().length,
|
|
465784
|
+
tracks: project.getTracks().length,
|
|
465785
|
+
clips: project.getClips().length
|
|
465786
|
+
};
|
|
465787
|
+
return {
|
|
465788
|
+
success: true,
|
|
465789
|
+
data: info,
|
|
465790
|
+
humanLines: [JSON.stringify(info, null, 2)]
|
|
465791
|
+
};
|
|
465792
|
+
}
|
|
465793
|
+
});
|
|
465670
465794
|
var timelineAddSourceTool = defineTool({
|
|
465671
465795
|
name: "timeline_add_source",
|
|
465672
465796
|
category: "timeline",
|
|
465673
465797
|
cost: "free",
|
|
465674
|
-
description: "Add a media source (video, audio, image) to the
|
|
465798
|
+
description: "Add a media source (video, audio, image) to the timeline",
|
|
465675
465799
|
schema: z8.object({
|
|
465676
|
-
projectPath: z8.string().describe("Path to
|
|
465800
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465677
465801
|
mediaPath: z8.string().describe("Path to the media file"),
|
|
465678
465802
|
name: z8.string().optional().describe("Optional name for the source"),
|
|
465679
465803
|
duration: z8.number().optional().describe("Duration of the media in seconds (default: 10)")
|
|
@@ -465698,7 +465822,7 @@ var timelineAddClipTool = defineTool({
|
|
|
465698
465822
|
cost: "free",
|
|
465699
465823
|
description: "Add a clip to the timeline from an existing source",
|
|
465700
465824
|
schema: z8.object({
|
|
465701
|
-
projectPath: z8.string().describe("Path to
|
|
465825
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465702
465826
|
sourceId: z8.string().describe("ID of the media source"),
|
|
465703
465827
|
trackId: z8.string().optional().describe("ID of the track to add clip to (optional, uses first video track)"),
|
|
465704
465828
|
startTime: z8.number().optional().describe("Start time on timeline in seconds (default: 0)"),
|
|
@@ -465729,7 +465853,7 @@ var timelineSplitClipTool = defineTool({
|
|
|
465729
465853
|
cost: "free",
|
|
465730
465854
|
description: "Split a clip at a specific time",
|
|
465731
465855
|
schema: z8.object({
|
|
465732
|
-
projectPath: z8.string().describe("Path to
|
|
465856
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465733
465857
|
clipId: z8.string().describe("ID of the clip to split"),
|
|
465734
465858
|
splitTime: z8.number().describe("Time to split at (relative to clip start) in seconds")
|
|
465735
465859
|
}),
|
|
@@ -465747,7 +465871,7 @@ var timelineTrimClipTool = defineTool({
|
|
|
465747
465871
|
cost: "free",
|
|
465748
465872
|
description: "Trim a clip by adjusting its start or end",
|
|
465749
465873
|
schema: z8.object({
|
|
465750
|
-
projectPath: z8.string().describe("Path to
|
|
465874
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465751
465875
|
clipId: z8.string().describe("ID of the clip to trim"),
|
|
465752
465876
|
trimStart: z8.number().optional().describe("New source start offset in seconds"),
|
|
465753
465877
|
trimEnd: z8.number().optional().describe("New duration in seconds")
|
|
@@ -465766,7 +465890,7 @@ var timelineMoveClipTool = defineTool({
|
|
|
465766
465890
|
cost: "free",
|
|
465767
465891
|
description: "Move a clip to a new position or track",
|
|
465768
465892
|
schema: z8.object({
|
|
465769
|
-
projectPath: z8.string().describe("Path to
|
|
465893
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465770
465894
|
clipId: z8.string().describe("ID of the clip to move"),
|
|
465771
465895
|
newStartTime: z8.number().optional().describe("New start time on timeline in seconds"),
|
|
465772
465896
|
newTrackId: z8.string().optional().describe("ID of the target track (optional)")
|
|
@@ -465788,7 +465912,7 @@ var timelineDeleteClipTool = defineTool({
|
|
|
465788
465912
|
cost: "free",
|
|
465789
465913
|
description: "Delete a clip from the timeline",
|
|
465790
465914
|
schema: z8.object({
|
|
465791
|
-
projectPath: z8.string().describe("Path to
|
|
465915
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465792
465916
|
clipId: z8.string().describe("ID of the clip to delete")
|
|
465793
465917
|
}),
|
|
465794
465918
|
async execute(args, ctx) {
|
|
@@ -465804,7 +465928,7 @@ var timelineDuplicateClipTool = defineTool({
|
|
|
465804
465928
|
cost: "free",
|
|
465805
465929
|
description: "Duplicate a clip on the timeline (optionally at a new start time)",
|
|
465806
465930
|
schema: z8.object({
|
|
465807
|
-
projectPath: z8.string().describe("Path to
|
|
465931
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465808
465932
|
clipId: z8.string().describe("ID of the clip to duplicate"),
|
|
465809
465933
|
newStartTime: z8.number().optional().describe("Start time for the duplicated clip (optional, places after original)")
|
|
465810
465934
|
}),
|
|
@@ -465822,7 +465946,7 @@ var timelineAddEffectTool = defineTool({
|
|
|
465822
465946
|
cost: "free",
|
|
465823
465947
|
description: "Add an effect to a clip",
|
|
465824
465948
|
schema: z8.object({
|
|
465825
|
-
projectPath: z8.string().describe("Path to
|
|
465949
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465826
465950
|
clipId: z8.string().describe("ID of the clip"),
|
|
465827
465951
|
effectType: z8.string().describe("Effect type: fadeIn, fadeOut, blur, brightness, contrast, saturation, grayscale, sepia, invert"),
|
|
465828
465952
|
startTime: z8.number().optional().describe("Effect start time relative to clip (default: 0)"),
|
|
@@ -465848,7 +465972,7 @@ var timelineAddTrackTool = defineTool({
|
|
|
465848
465972
|
cost: "free",
|
|
465849
465973
|
description: "Add a new track to the timeline",
|
|
465850
465974
|
schema: z8.object({
|
|
465851
|
-
projectPath: z8.string().describe("Path to
|
|
465975
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
465852
465976
|
trackType: z8.string().describe("Track type: video or audio"),
|
|
465853
465977
|
name: z8.string().optional().describe("Track name (optional)")
|
|
465854
465978
|
}),
|
|
@@ -465874,7 +465998,7 @@ var timelineListTool = defineTool({
|
|
|
465874
465998
|
cost: "free",
|
|
465875
465999
|
description: "List all sources, tracks, and clips in a project",
|
|
465876
466000
|
schema: z8.object({
|
|
465877
|
-
projectPath: z8.string().describe("Path to
|
|
466001
|
+
projectPath: z8.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
|
|
465878
466002
|
}),
|
|
465879
466003
|
async execute(args, ctx) {
|
|
465880
466004
|
const { project } = await loadProject(args.projectPath, ctx.workingDirectory);
|
|
@@ -465891,6 +466015,8 @@ var timelineListTool = defineTool({
|
|
|
465891
466015
|
}
|
|
465892
466016
|
});
|
|
465893
466017
|
var timelineTools = [
|
|
466018
|
+
timelineCreateTool,
|
|
466019
|
+
timelineInfoTool,
|
|
465894
466020
|
timelineAddSourceTool,
|
|
465895
466021
|
timelineAddClipTool,
|
|
465896
466022
|
timelineSplitClipTool,
|
|
@@ -465906,16 +466032,16 @@ var timelineTools = [
|
|
|
465906
466032
|
// ../cli/src/tools/manifest/project.ts
|
|
465907
466033
|
import { z as z9 } from "zod";
|
|
465908
466034
|
import { resolve as resolve57 } from "node:path";
|
|
465909
|
-
import { writeFile as
|
|
466035
|
+
import { writeFile as writeFile41 } from "node:fs/promises";
|
|
465910
466036
|
init_engine();
|
|
465911
466037
|
var projectCreateTool = defineTool({
|
|
465912
466038
|
name: "project_create",
|
|
465913
466039
|
category: "project",
|
|
465914
466040
|
cost: "free",
|
|
465915
|
-
description: "
|
|
466041
|
+
description: "Deprecated alias for creating low-level timeline state. Prefer timeline_create.",
|
|
465916
466042
|
schema: z9.object({
|
|
465917
466043
|
name: z9.string().describe("Project name"),
|
|
465918
|
-
outputPath: z9.string().optional().describe("Output file path (defaults to {name}.vibe.json)"),
|
|
466044
|
+
outputPath: z9.string().optional().describe("Output file path (defaults to {name}.vibe.json for legacy compatibility)"),
|
|
465919
466045
|
width: z9.number().optional().describe("Video width in pixels (default: 1920)"),
|
|
465920
466046
|
height: z9.number().optional().describe("Video height in pixels (default: 1080)"),
|
|
465921
466047
|
fps: z9.number().optional().describe("Frames per second (default: 30)")
|
|
@@ -465924,11 +466050,11 @@ var projectCreateTool = defineTool({
|
|
|
465924
466050
|
const outputPath = resolve57(ctx.workingDirectory, args.outputPath ?? `${args.name}.vibe.json`);
|
|
465925
466051
|
const project = new Project(args.name);
|
|
465926
466052
|
if (args.fps) project.setFrameRate(args.fps);
|
|
465927
|
-
await
|
|
466053
|
+
await writeFile41(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
465928
466054
|
return {
|
|
465929
466055
|
success: true,
|
|
465930
466056
|
data: { name: args.name, outputPath },
|
|
465931
|
-
humanLines: [`Created project "${args.name}" at ${outputPath}`]
|
|
466057
|
+
humanLines: [`Created legacy timeline project "${args.name}" at ${outputPath}`]
|
|
465932
466058
|
};
|
|
465933
466059
|
}
|
|
465934
466060
|
});
|
|
@@ -465936,9 +466062,9 @@ var projectInfoTool = defineTool({
|
|
|
465936
466062
|
name: "project_info",
|
|
465937
466063
|
category: "project",
|
|
465938
466064
|
cost: "free",
|
|
465939
|
-
description: "
|
|
466065
|
+
description: "Deprecated alias for timeline_info. Legacy *.vibe.json files remain supported.",
|
|
465940
466066
|
schema: z9.object({
|
|
465941
|
-
projectPath: z9.string().describe("Path to
|
|
466067
|
+
projectPath: z9.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
|
|
465942
466068
|
}),
|
|
465943
466069
|
async execute(args, ctx) {
|
|
465944
466070
|
const { project } = await loadProject(args.projectPath, ctx.workingDirectory);
|
|
@@ -465976,19 +466102,15 @@ init_engine();
|
|
|
465976
466102
|
init_exec_safe();
|
|
465977
466103
|
init_output();
|
|
465978
466104
|
init_validate();
|
|
465979
|
-
|
|
465980
|
-
import {
|
|
466105
|
+
init_project_resolver();
|
|
466106
|
+
import { readFile as readFile31, access as access6 } from "node:fs/promises";
|
|
466107
|
+
import { resolve as resolve59, basename as basename16 } from "node:path";
|
|
465981
466108
|
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;
|
|
466109
|
+
function timelineBaseName(path14) {
|
|
466110
|
+
const name = basename16(path14);
|
|
466111
|
+
if (name.endsWith(".vibe.json")) return name.slice(0, -".vibe.json".length);
|
|
466112
|
+
if (name.endsWith(".json")) return name.slice(0, -".json".length);
|
|
466113
|
+
return basename16(path14, ".vibe.json");
|
|
465992
466114
|
}
|
|
465993
466115
|
async function getMediaDuration(filePath, mediaType, defaultImageDuration = 5) {
|
|
465994
466116
|
if (mediaType === "image") {
|
|
@@ -466057,7 +466179,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
466057
466179
|
message: "FFmpeg not found. Install with: brew install ffmpeg (macOS) or apt install ffmpeg (Linux)"
|
|
466058
466180
|
};
|
|
466059
466181
|
}
|
|
466060
|
-
const filePath = await
|
|
466182
|
+
const filePath = await resolveTimelineFile(projectPath);
|
|
466061
466183
|
const content = await readFile31(filePath, "utf-8");
|
|
466062
466184
|
const data = JSON.parse(content);
|
|
466063
466185
|
const project = Project.fromJSON(data);
|
|
@@ -466079,7 +466201,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
466079
466201
|
const source3 = sources.find((s) => s.id === clip.sourceId);
|
|
466080
466202
|
if (source3) {
|
|
466081
466203
|
try {
|
|
466082
|
-
await
|
|
466204
|
+
await access6(source3.url);
|
|
466083
466205
|
if (!sourceActualDurationMap.has(source3.id)) {
|
|
466084
466206
|
try {
|
|
466085
466207
|
const dur = await getMediaDuration(source3.url, source3.type);
|
|
@@ -466114,20 +466236,20 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
466114
466236
|
};
|
|
466115
466237
|
}
|
|
466116
466238
|
}
|
|
466117
|
-
var exportCommand = new Command("export").description("Export project to video file").argument("<project>", "
|
|
466239
|
+
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
466240
|
"--preset <preset>",
|
|
466119
466241
|
"Quality preset (draft, standard, high, ultra)",
|
|
466120
466242
|
"standard"
|
|
466121
466243
|
).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
466244
|
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.
|
|
466245
|
+
$ vibe export timeline.json -o output.mp4
|
|
466246
|
+
$ vibe export my-video -o output.mp4 --preset high --overwrite
|
|
466247
|
+
$ vibe export timeline.json -o output.webm --format webm
|
|
466248
|
+
$ vibe export timeline.json -o output.gif --format gif
|
|
466249
|
+
$ vibe export timeline.json -o out.mp4 --bitrate 5000k --fps 24 --codec h265
|
|
466250
|
+
$ vibe export timeline.json -o out.mp4 --preset high --fps 60
|
|
466251
|
+
|
|
466252
|
+
Cost: Free (no API keys needed). Requires FFmpeg. Legacy *.vibe.json files remain supported.
|
|
466131
466253
|
GIF format: 15fps, no audio, looping. Good for previews and sharing.
|
|
466132
466254
|
Custom flags (--bitrate, --fps, --resolution, --codec) override preset values.
|
|
466133
466255
|
Run 'vibe schema export' for structured parameter info.`).action(async (projectPath, options) => {
|
|
@@ -466181,7 +466303,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
466181
466303
|
exitWithError(generalError("FFmpeg not found", "Install with: brew install ffmpeg (macOS), apt install ffmpeg (Linux), or winget install ffmpeg (Windows)"));
|
|
466182
466304
|
}
|
|
466183
466305
|
spinner2.text = "Loading project...";
|
|
466184
|
-
const filePath = await
|
|
466306
|
+
const filePath = await resolveTimelineFile(projectPath);
|
|
466185
466307
|
const content = await readFile31(filePath, "utf-8");
|
|
466186
466308
|
const data = JSON.parse(content);
|
|
466187
466309
|
const project = Project.fromJSON(data);
|
|
@@ -466192,7 +466314,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
466192
466314
|
}
|
|
466193
466315
|
const outputPath = options.output ? resolve59(process.cwd(), options.output) : resolve59(
|
|
466194
466316
|
process.cwd(),
|
|
466195
|
-
`${
|
|
466317
|
+
`${timelineBaseName(projectPath)}.${options.format}`
|
|
466196
466318
|
);
|
|
466197
466319
|
const basePresetSettings = getPresetSettings(options.preset, summary.aspectRatio);
|
|
466198
466320
|
const presetSettings = applyCustomOverrides(basePresetSettings, customOverrides);
|
|
@@ -466205,7 +466327,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
466205
466327
|
const source3 = sources.find((s) => s.id === clip.sourceId);
|
|
466206
466328
|
if (source3) {
|
|
466207
466329
|
try {
|
|
466208
|
-
await
|
|
466330
|
+
await access6(source3.url);
|
|
466209
466331
|
if (!sourceActualDurationMap.has(source3.id)) {
|
|
466210
466332
|
try {
|
|
466211
466333
|
const dur = await getMediaDuration(source3.url, source3.type);
|
|
@@ -466781,16 +466903,16 @@ function getPresetSettings(preset, aspectRatio) {
|
|
|
466781
466903
|
async function runHyperframesExport(projectPath, options, spinner2, startedAt) {
|
|
466782
466904
|
spinner2.text = "Loading project...";
|
|
466783
466905
|
const { readFile: readFile34 } = await import("node:fs/promises");
|
|
466784
|
-
const { resolve: resolve64
|
|
466906
|
+
const { resolve: resolve64 } = await import("node:path");
|
|
466785
466907
|
const { Project: Project2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
|
|
466786
466908
|
const { createHyperframesBackend: createHyperframesBackend2 } = await Promise.resolve().then(() => (init_hyperframes(), hyperframes_exports));
|
|
466787
466909
|
const { exitWithError: exitWithError2, generalError: generalError2, outputSuccess: outputSuccess2 } = await Promise.resolve().then(() => (init_output(), output_exports));
|
|
466788
466910
|
const chalk2 = (await Promise.resolve().then(() => (init_source(), source_exports))).default;
|
|
466789
|
-
const filePath =
|
|
466911
|
+
const filePath = await resolveTimelineFile(projectPath);
|
|
466790
466912
|
const content = await readFile34(filePath, "utf-8");
|
|
466791
466913
|
const project = Project2.fromJSON(JSON.parse(content));
|
|
466792
466914
|
const state = project.getState();
|
|
466793
|
-
const outputPath = options.output ? resolve64(process.cwd(), options.output) : resolve64(process.cwd(), `${
|
|
466915
|
+
const outputPath = options.output ? resolve64(process.cwd(), options.output) : resolve64(process.cwd(), `${timelineBaseName(projectPath)}.${options.format ?? "mp4"}`);
|
|
466794
466916
|
const quality = ["draft", "standard", "high"].includes(options.preset ?? "") ? options.preset : "standard";
|
|
466795
466917
|
const backend = createHyperframesBackend2();
|
|
466796
466918
|
spinner2.text = "Rendering with Hyperframes...";
|
|
@@ -466827,9 +466949,9 @@ var exportVideoTool = defineTool({
|
|
|
466827
466949
|
name: "export_video",
|
|
466828
466950
|
category: "export",
|
|
466829
466951
|
cost: "free",
|
|
466830
|
-
description: "Export a VibeFrame
|
|
466952
|
+
description: "Export a VibeFrame timeline to a video file (MP4, WebM, or MOV). Requires FFmpeg.",
|
|
466831
466953
|
schema: z10.object({
|
|
466832
|
-
projectPath: z10.string().describe("Path to
|
|
466954
|
+
projectPath: z10.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
|
|
466833
466955
|
outputPath: z10.string().describe("Output video file path (e.g., output.mp4)"),
|
|
466834
466956
|
preset: z10.enum(["draft", "standard", "high", "ultra"]).optional().describe("Quality preset (default: standard)"),
|
|
466835
466957
|
format: z10.enum(["mp4", "webm", "mov"]).optional().describe("Output format (default: mp4)"),
|
|
@@ -466854,11 +466976,12 @@ var exportVideoTool = defineTool({
|
|
|
466854
466976
|
var exportTools = [exportVideoTool];
|
|
466855
466977
|
|
|
466856
466978
|
// ../cli/src/tools/manifest/agent-only.ts
|
|
466857
|
-
import { readFile as readFile32, writeFile as
|
|
466858
|
-
import { resolve as resolve61, join as join33, basename as
|
|
466979
|
+
import { readFile as readFile32, writeFile as writeFile43, readdir as readdir5, stat as stat4, access as access7, unlink as unlink7 } from "node:fs/promises";
|
|
466980
|
+
import { resolve as resolve61, join as join33, basename as basename17, extname as extname12 } from "node:path";
|
|
466859
466981
|
import { z as z11 } from "zod";
|
|
466860
466982
|
init_engine();
|
|
466861
466983
|
init_exec_safe();
|
|
466984
|
+
init_project_resolver();
|
|
466862
466985
|
function matchPattern(filename, pattern) {
|
|
466863
466986
|
const regex2 = new RegExp(
|
|
466864
466987
|
"^" + pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".") + "$",
|
|
@@ -466981,7 +467104,7 @@ var fsWriteTool = defineTool({
|
|
|
466981
467104
|
async execute(args, ctx) {
|
|
466982
467105
|
try {
|
|
466983
467106
|
const absPath = resolve61(ctx.workingDirectory, args.path);
|
|
466984
|
-
await
|
|
467107
|
+
await writeFile43(absPath, args.content, "utf-8");
|
|
466985
467108
|
return { success: true, data: { bytes: args.content.length }, humanLines: [`File written: ${args.path} (${formatSize(args.content.length)})`] };
|
|
466986
467109
|
} catch (error) {
|
|
466987
467110
|
return { success: false, error: `Failed to write file: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -467000,7 +467123,7 @@ var fsExistsTool = defineTool({
|
|
|
467000
467123
|
async execute(args, ctx) {
|
|
467001
467124
|
const absPath = resolve61(ctx.workingDirectory, args.path);
|
|
467002
467125
|
try {
|
|
467003
|
-
await
|
|
467126
|
+
await access7(absPath);
|
|
467004
467127
|
const stats = await stat4(absPath);
|
|
467005
467128
|
const type = stats.isDirectory() ? "directory" : "file";
|
|
467006
467129
|
return { success: true, data: { exists: true, type }, humanLines: [`${type} exists: ${args.path}`] };
|
|
@@ -467016,7 +467139,7 @@ var batchImportTool = defineTool({
|
|
|
467016
467139
|
surfaces: ["agent"],
|
|
467017
467140
|
description: "Import multiple media files from a directory into a project. Scans directory for video, audio, and image files.",
|
|
467018
467141
|
schema: z11.object({
|
|
467019
|
-
project: z11.string().describe("
|
|
467142
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467020
467143
|
directory: z11.string().describe("Directory containing media files to import"),
|
|
467021
467144
|
recursive: z11.boolean().optional().describe("Search subdirectories recursively (default: false)"),
|
|
467022
467145
|
filter: z11.string().optional().describe("Filter files by extension, comma-separated (e.g., '.mp4,.mov')"),
|
|
@@ -467053,7 +467176,7 @@ var batchImportTool = defineTool({
|
|
|
467053
467176
|
mediaFiles.sort();
|
|
467054
467177
|
const addedSources = [];
|
|
467055
467178
|
for (const mediaFile of mediaFiles) {
|
|
467056
|
-
const mediaName =
|
|
467179
|
+
const mediaName = basename17(mediaFile);
|
|
467057
467180
|
const mediaType = detectMediaType(mediaFile);
|
|
467058
467181
|
let duration = imageDuration;
|
|
467059
467182
|
if (mediaType !== "image") {
|
|
@@ -467063,7 +467186,7 @@ var batchImportTool = defineTool({
|
|
|
467063
467186
|
const source3 = project.addSource({ name: mediaName, type: mediaType, url: mediaFile, duration });
|
|
467064
467187
|
addedSources.push({ id: source3.id, name: mediaName, type: mediaType });
|
|
467065
467188
|
}
|
|
467066
|
-
await
|
|
467189
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467067
467190
|
return {
|
|
467068
467191
|
success: true,
|
|
467069
467192
|
data: { count: addedSources.length, sources: addedSources },
|
|
@@ -467085,7 +467208,7 @@ var batchConcatTool = defineTool({
|
|
|
467085
467208
|
surfaces: ["agent"],
|
|
467086
467209
|
description: "Concatenate multiple sources into sequential clips on the timeline",
|
|
467087
467210
|
schema: z11.object({
|
|
467088
|
-
project: z11.string().describe("
|
|
467211
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467089
467212
|
sourceIds: z11.array(z11.string()).optional().describe("Source IDs to concatenate. If empty with useAll=true, uses all sources."),
|
|
467090
467213
|
useAll: z11.boolean().optional().describe("Use all sources in the project (default: false)"),
|
|
467091
467214
|
trackId: z11.string().optional().describe("Track to place clips on (auto-selects if not specified)"),
|
|
@@ -467131,7 +467254,7 @@ var batchConcatTool = defineTool({
|
|
|
467131
467254
|
createdClips.push({ id: clip.id, sourceName: source3.name, startTime: currentTime, duration: source3.duration });
|
|
467132
467255
|
currentTime += source3.duration + gap;
|
|
467133
467256
|
}
|
|
467134
|
-
await
|
|
467257
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467135
467258
|
const totalDuration = currentTime - gap - startTime;
|
|
467136
467259
|
return {
|
|
467137
467260
|
success: true,
|
|
@@ -467154,7 +467277,7 @@ var batchApplyEffectTool = defineTool({
|
|
|
467154
467277
|
surfaces: ["agent"],
|
|
467155
467278
|
description: "Apply an effect to multiple clips at once",
|
|
467156
467279
|
schema: z11.object({
|
|
467157
|
-
project: z11.string().describe("
|
|
467280
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467158
467281
|
clipIds: z11.array(z11.string()).optional().describe("Clip IDs to apply effect to. If empty with useAll=true, applies to all clips."),
|
|
467159
467282
|
useAll: z11.boolean().optional().describe("Apply to all clips in the project (default: false)"),
|
|
467160
467283
|
effectType: z11.enum(["fadeIn", "fadeOut", "blur", "brightness", "contrast", "saturation", "speed", "volume"]).describe("Effect type to apply"),
|
|
@@ -467192,7 +467315,7 @@ var batchApplyEffectTool = defineTool({
|
|
|
467192
467315
|
});
|
|
467193
467316
|
if (effect) appliedEffects.push({ clipId: clip.id, effectId: effect.id });
|
|
467194
467317
|
}
|
|
467195
|
-
await
|
|
467318
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467196
467319
|
return {
|
|
467197
467320
|
success: true,
|
|
467198
467321
|
data: { applied: appliedEffects.length, effectType: args.effectType },
|
|
@@ -467203,17 +467326,6 @@ var batchApplyEffectTool = defineTool({
|
|
|
467203
467326
|
}
|
|
467204
467327
|
}
|
|
467205
467328
|
});
|
|
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
467329
|
var timelineClearTool = defineTool({
|
|
467218
467330
|
name: "timeline_clear",
|
|
467219
467331
|
category: "agent-only",
|
|
@@ -467221,13 +467333,13 @@ var timelineClearTool = defineTool({
|
|
|
467221
467333
|
surfaces: ["agent"],
|
|
467222
467334
|
description: "Clear timeline contents (remove clips, tracks, or sources)",
|
|
467223
467335
|
schema: z11.object({
|
|
467224
|
-
project: z11.string().describe("
|
|
467336
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467225
467337
|
what: z11.enum(["clips", "tracks", "sources", "all"]).optional().describe("What to clear: clips (default), tracks, sources, or all"),
|
|
467226
467338
|
keepTracks: z11.boolean().optional().describe("When clearing 'all', keep default empty tracks (default: true)")
|
|
467227
467339
|
}),
|
|
467228
467340
|
async execute(args, ctx) {
|
|
467229
467341
|
try {
|
|
467230
|
-
const filePath = await
|
|
467342
|
+
const filePath = await resolveTimelineFile(args.project, ctx.workingDirectory);
|
|
467231
467343
|
const content = await readFile32(filePath, "utf-8");
|
|
467232
467344
|
const data = JSON.parse(content);
|
|
467233
467345
|
const project = Project.fromJSON(data);
|
|
@@ -467270,7 +467382,7 @@ var timelineClearTool = defineTool({
|
|
|
467270
467382
|
removed.sources++;
|
|
467271
467383
|
}
|
|
467272
467384
|
}
|
|
467273
|
-
await
|
|
467385
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467274
467386
|
const parts = [];
|
|
467275
467387
|
if (removed.clips > 0) parts.push(`${removed.clips} clips`);
|
|
467276
467388
|
if (removed.tracks > 0) parts.push(`${removed.tracks} tracks`);
|
|
@@ -467293,16 +467405,16 @@ var projectSetTool = defineTool({
|
|
|
467293
467405
|
category: "agent-only",
|
|
467294
467406
|
cost: "free",
|
|
467295
467407
|
surfaces: ["agent"],
|
|
467296
|
-
description: "Update
|
|
467408
|
+
description: "Update timeline settings (name, aspect ratio, frame rate)",
|
|
467297
467409
|
schema: z11.object({
|
|
467298
|
-
projectPath: z11.string().describe("
|
|
467410
|
+
projectPath: z11.string().describe("Timeline file or directory"),
|
|
467299
467411
|
name: z11.string().optional().describe("New project name"),
|
|
467300
467412
|
aspectRatio: z11.enum(["16:9", "9:16", "1:1", "4:5"]).optional().describe("New aspect ratio"),
|
|
467301
467413
|
fps: z11.number().optional().describe("New frame rate")
|
|
467302
467414
|
}),
|
|
467303
467415
|
async execute(args, ctx) {
|
|
467304
467416
|
try {
|
|
467305
|
-
const filePath = await
|
|
467417
|
+
const filePath = await resolveTimelineFile(args.projectPath, ctx.workingDirectory);
|
|
467306
467418
|
const content = await readFile32(filePath, "utf-8");
|
|
467307
467419
|
const data = JSON.parse(content);
|
|
467308
467420
|
const project = Project.fromJSON(data);
|
|
@@ -467319,7 +467431,7 @@ var projectSetTool = defineTool({
|
|
|
467319
467431
|
project.setFrameRate(args.fps);
|
|
467320
467432
|
updates.push(`Frame Rate: ${args.fps} fps`);
|
|
467321
467433
|
}
|
|
467322
|
-
await
|
|
467434
|
+
await writeFile43(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
467323
467435
|
return {
|
|
467324
467436
|
success: true,
|
|
467325
467437
|
data: { updates },
|
|
@@ -467340,11 +467452,11 @@ var projectOpenTool = defineTool({
|
|
|
467340
467452
|
surfaces: ["agent"],
|
|
467341
467453
|
description: "Open an existing project and set it as the current context",
|
|
467342
467454
|
schema: z11.object({
|
|
467343
|
-
projectPath: z11.string().describe("
|
|
467455
|
+
projectPath: z11.string().describe("Timeline file or directory")
|
|
467344
467456
|
}),
|
|
467345
467457
|
async execute(args, ctx) {
|
|
467346
467458
|
try {
|
|
467347
|
-
const filePath = await
|
|
467459
|
+
const filePath = await resolveTimelineFile(args.projectPath, ctx.workingDirectory);
|
|
467348
467460
|
const { project } = await loadProject(filePath, "");
|
|
467349
467461
|
ctx.agent?.setProjectPath(filePath);
|
|
467350
467462
|
const summary = project.getSummary();
|
|
@@ -467378,7 +467490,7 @@ var projectSaveTool = defineTool({
|
|
|
467378
467490
|
surfaces: ["agent"],
|
|
467379
467491
|
description: "Save the current project (uses ctx.agent.projectPath if no path given)",
|
|
467380
467492
|
schema: z11.object({
|
|
467381
|
-
projectPath: z11.string().optional().describe("
|
|
467493
|
+
projectPath: z11.string().optional().describe("Timeline file or directory (uses current agent timeline if omitted)")
|
|
467382
467494
|
}),
|
|
467383
467495
|
async execute(args, ctx) {
|
|
467384
467496
|
const path14 = args.projectPath ?? ctx.agent?.projectPath ?? null;
|
|
@@ -467389,7 +467501,7 @@ var projectSaveTool = defineTool({
|
|
|
467389
467501
|
};
|
|
467390
467502
|
}
|
|
467391
467503
|
try {
|
|
467392
|
-
const filePath = await
|
|
467504
|
+
const filePath = await resolveTimelineFile(path14, ctx.workingDirectory);
|
|
467393
467505
|
const { project, absPath } = await loadProject(filePath, "");
|
|
467394
467506
|
await saveProject(absPath, project);
|
|
467395
467507
|
return {
|
|
@@ -467412,7 +467524,7 @@ var exportAudioTool = defineTool({
|
|
|
467412
467524
|
surfaces: ["agent"],
|
|
467413
467525
|
description: "Export audio track from a project. Not implemented \u2014 use export_video then strip audio with FFmpeg.",
|
|
467414
467526
|
schema: z11.object({
|
|
467415
|
-
project: z11.string().describe("
|
|
467527
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467416
467528
|
output: z11.string().optional().describe("Output audio file path"),
|
|
467417
467529
|
format: z11.enum(["mp3", "wav", "aac"]).optional().describe("Output format (mp3, wav, aac)")
|
|
467418
467530
|
}),
|
|
@@ -467430,7 +467542,7 @@ var exportSubtitlesTool = defineTool({
|
|
|
467430
467542
|
surfaces: ["agent"],
|
|
467431
467543
|
description: "Export subtitles from transcription. Not implemented \u2014 use audio_transcribe to generate subtitles from audio.",
|
|
467432
467544
|
schema: z11.object({
|
|
467433
|
-
project: z11.string().describe("
|
|
467545
|
+
project: z11.string().describe("Timeline file or directory"),
|
|
467434
467546
|
output: z11.string().optional().describe("Output subtitle file path"),
|
|
467435
467547
|
format: z11.enum(["srt", "vtt"]).optional().describe("Subtitle format (srt, vtt)")
|
|
467436
467548
|
}),
|
|
@@ -467673,7 +467785,7 @@ var mediaConcatTool = defineTool({
|
|
|
467673
467785
|
} else {
|
|
467674
467786
|
const tempList = resolve61(ctx.workingDirectory, `concat-list-${Date.now()}.txt`);
|
|
467675
467787
|
const listContent = args.inputs.map((i) => `file '${resolve61(ctx.workingDirectory, i)}'`).join("\n");
|
|
467676
|
-
await
|
|
467788
|
+
await writeFile43(tempList, listContent, "utf-8");
|
|
467677
467789
|
try {
|
|
467678
467790
|
await execSafe(
|
|
467679
467791
|
"ffmpeg",
|
|
@@ -468310,7 +468422,7 @@ async function readResource(uri) {
|
|
|
468310
468422
|
uri,
|
|
468311
468423
|
mimeType: "application/json",
|
|
468312
468424
|
text: JSON.stringify({
|
|
468313
|
-
error: "No
|
|
468425
|
+
error: "No timeline loaded. Set VIBE_PROJECT_PATH to timeline.json or use timeline_create."
|
|
468314
468426
|
})
|
|
468315
468427
|
}
|
|
468316
468428
|
]
|
|
@@ -468406,7 +468518,7 @@ var prompts = [
|
|
|
468406
468518
|
},
|
|
468407
468519
|
{
|
|
468408
468520
|
name: "projectPath",
|
|
468409
|
-
description: "Path to
|
|
468521
|
+
description: "Path to timeline.json or a legacy *.vibe.json file",
|
|
468410
468522
|
required: false
|
|
468411
468523
|
}
|
|
468412
468524
|
]
|
|
@@ -468524,7 +468636,7 @@ function getPrompt(name, args) {
|
|
|
468524
468636
|
type: "text",
|
|
468525
468637
|
text: `Help me edit a video with the following instruction: "${args.instruction}"
|
|
468526
468638
|
|
|
468527
|
-
${args.projectPath ? `
|
|
468639
|
+
${args.projectPath ? `Timeline file: ${args.projectPath}` : "No timeline file specified."}
|
|
468528
468640
|
|
|
468529
468641
|
Please analyze the request and suggest the appropriate timeline tools to use. Consider:
|
|
468530
468642
|
1. What clips need to be affected?
|