@vibeframe/mcp-server 0.113.10 → 0.113.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +684 -554
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -4757,15 +4757,15 @@ async function loadKokoroRuntime() {
|
|
|
4757
4757
|
}
|
|
4758
4758
|
async function loadKokoroFromWorkspace(baseDir = process.cwd()) {
|
|
4759
4759
|
try {
|
|
4760
|
-
const { readFile:
|
|
4761
|
-
const { join:
|
|
4760
|
+
const { readFile: readFile47 } = await import("node:fs/promises");
|
|
4761
|
+
const { join: join45, resolve: resolve80 } = await import("node:path");
|
|
4762
4762
|
const { pathToFileURL } = await import("node:url");
|
|
4763
4763
|
const pkgDir = resolve80(baseDir, "node_modules", "kokoro-js");
|
|
4764
|
-
const pkg = JSON.parse(await
|
|
4764
|
+
const pkg = JSON.parse(await readFile47(join45(pkgDir, "package.json"), "utf-8"));
|
|
4765
4765
|
const entry = pkg.exports?.node?.import ?? pkg.exports?.default ?? pkg.module ?? pkg.main;
|
|
4766
4766
|
if (!entry)
|
|
4767
4767
|
return null;
|
|
4768
|
-
const mod = await import(pathToFileURL(
|
|
4768
|
+
const mod = await import(pathToFileURL(join45(pkgDir, entry)).href);
|
|
4769
4769
|
return mod.KokoroTTS ?? null;
|
|
4770
4770
|
} catch {
|
|
4771
4771
|
return null;
|
|
@@ -4776,20 +4776,20 @@ async function loadBundledKokoroRuntime(runtimeDir = process.env.VIBE_KOKORO_RUN
|
|
|
4776
4776
|
if (!base)
|
|
4777
4777
|
return null;
|
|
4778
4778
|
try {
|
|
4779
|
-
const { readFile:
|
|
4780
|
-
const { join:
|
|
4779
|
+
const { readFile: readFile47, writeFile: writeFile53, mkdir: mkdir30 } = await import("node:fs/promises");
|
|
4780
|
+
const { join: join45, resolve: resolve80 } = await import("node:path");
|
|
4781
4781
|
const { pathToFileURL } = await import("node:url");
|
|
4782
4782
|
const { homedir: homedir8 } = await import("node:os");
|
|
4783
4783
|
const transformersDir = resolve80(base, "node_modules", "@huggingface", "transformers");
|
|
4784
4784
|
const ortDistDir = resolve80(base, "node_modules", "onnxruntime-web", "dist");
|
|
4785
|
-
const transformers = await import(pathToFileURL(
|
|
4786
|
-
const cacheRoot =
|
|
4785
|
+
const transformers = await import(pathToFileURL(join45(transformersDir, "dist", "transformers.web.js")).href);
|
|
4786
|
+
const cacheRoot = join45(homedir8(), ".cache", "vibeframe", "models");
|
|
4787
4787
|
transformers.env.allowLocalModels = false;
|
|
4788
4788
|
transformers.env.useCustomCache = true;
|
|
4789
4789
|
transformers.env.customCache = {
|
|
4790
4790
|
async match(key2) {
|
|
4791
4791
|
try {
|
|
4792
|
-
return new Response(await
|
|
4792
|
+
return new Response(await readFile47(join45(cacheRoot, encodeURIComponent(String(key2)))));
|
|
4793
4793
|
} catch {
|
|
4794
4794
|
return void 0;
|
|
4795
4795
|
}
|
|
@@ -4798,7 +4798,7 @@ async function loadBundledKokoroRuntime(runtimeDir = process.env.VIBE_KOKORO_RUN
|
|
|
4798
4798
|
try {
|
|
4799
4799
|
const buf = Buffer.from(await response.arrayBuffer());
|
|
4800
4800
|
await mkdir30(cacheRoot, { recursive: true });
|
|
4801
|
-
await writeFile53(
|
|
4801
|
+
await writeFile53(join45(cacheRoot, encodeURIComponent(String(key2))), buf);
|
|
4802
4802
|
} catch {
|
|
4803
4803
|
}
|
|
4804
4804
|
}
|
|
@@ -33729,7 +33729,7 @@ var require_util = __commonJS({
|
|
|
33729
33729
|
return path14;
|
|
33730
33730
|
});
|
|
33731
33731
|
exports.normalize = normalize3;
|
|
33732
|
-
function
|
|
33732
|
+
function join45(aRoot, aPath) {
|
|
33733
33733
|
if (aRoot === "") {
|
|
33734
33734
|
aRoot = ".";
|
|
33735
33735
|
}
|
|
@@ -33761,7 +33761,7 @@ var require_util = __commonJS({
|
|
|
33761
33761
|
}
|
|
33762
33762
|
return joined;
|
|
33763
33763
|
}
|
|
33764
|
-
exports.join =
|
|
33764
|
+
exports.join = join45;
|
|
33765
33765
|
exports.isAbsolute = function(aPath) {
|
|
33766
33766
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
33767
33767
|
};
|
|
@@ -33975,7 +33975,7 @@ var require_util = __commonJS({
|
|
|
33975
33975
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
33976
33976
|
}
|
|
33977
33977
|
}
|
|
33978
|
-
sourceURL =
|
|
33978
|
+
sourceURL = join45(urlGenerate(parsed), sourceURL);
|
|
33979
33979
|
}
|
|
33980
33980
|
return normalize3(sourceURL);
|
|
33981
33981
|
}
|
|
@@ -35415,8 +35415,8 @@ var require_source_map = __commonJS({
|
|
|
35415
35415
|
var require_previous_map = __commonJS({
|
|
35416
35416
|
"../../node_modules/.pnpm/postcss@8.5.6/node_modules/postcss/lib/previous-map.js"(exports, module) {
|
|
35417
35417
|
"use strict";
|
|
35418
|
-
var { existsSync:
|
|
35419
|
-
var { dirname: dirname33, join:
|
|
35418
|
+
var { existsSync: existsSync68, readFileSync: readFileSync13 } = __require("fs");
|
|
35419
|
+
var { dirname: dirname33, join: join45 } = __require("path");
|
|
35420
35420
|
var { SourceMapConsumer, SourceMapGenerator } = require_source_map();
|
|
35421
35421
|
function fromBase64(str2) {
|
|
35422
35422
|
if (Buffer) {
|
|
@@ -35478,7 +35478,7 @@ var require_previous_map = __commonJS({
|
|
|
35478
35478
|
}
|
|
35479
35479
|
loadFile(path14) {
|
|
35480
35480
|
this.root = dirname33(path14);
|
|
35481
|
-
if (
|
|
35481
|
+
if (existsSync68(path14)) {
|
|
35482
35482
|
this.mapFile = path14;
|
|
35483
35483
|
return readFileSync13(path14, "utf-8").toString().trim();
|
|
35484
35484
|
}
|
|
@@ -35514,7 +35514,7 @@ var require_previous_map = __commonJS({
|
|
|
35514
35514
|
return this.decodeInline(this.annotation);
|
|
35515
35515
|
} else if (this.annotation) {
|
|
35516
35516
|
let map3 = this.annotation;
|
|
35517
|
-
if (file) map3 =
|
|
35517
|
+
if (file) map3 = join45(dirname33(file), map3);
|
|
35518
35518
|
return this.loadFile(map3);
|
|
35519
35519
|
}
|
|
35520
35520
|
}
|
|
@@ -94143,7 +94143,7 @@ var require_util3 = __commonJS({
|
|
|
94143
94143
|
return path14;
|
|
94144
94144
|
}
|
|
94145
94145
|
exports.normalize = normalize3;
|
|
94146
|
-
function
|
|
94146
|
+
function join45(aRoot, aPath) {
|
|
94147
94147
|
if (aRoot === "") {
|
|
94148
94148
|
aRoot = ".";
|
|
94149
94149
|
}
|
|
@@ -94175,7 +94175,7 @@ var require_util3 = __commonJS({
|
|
|
94175
94175
|
}
|
|
94176
94176
|
return joined;
|
|
94177
94177
|
}
|
|
94178
|
-
exports.join =
|
|
94178
|
+
exports.join = join45;
|
|
94179
94179
|
exports.isAbsolute = function(aPath) {
|
|
94180
94180
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
94181
94181
|
};
|
|
@@ -94348,7 +94348,7 @@ var require_util3 = __commonJS({
|
|
|
94348
94348
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
94349
94349
|
}
|
|
94350
94350
|
}
|
|
94351
|
-
sourceURL =
|
|
94351
|
+
sourceURL = join45(urlGenerate(parsed), sourceURL);
|
|
94352
94352
|
}
|
|
94353
94353
|
return normalize3(sourceURL);
|
|
94354
94354
|
}
|
|
@@ -96150,7 +96150,7 @@ var require_escodegen = __commonJS({
|
|
|
96150
96150
|
function noEmptySpace() {
|
|
96151
96151
|
return space ? space : " ";
|
|
96152
96152
|
}
|
|
96153
|
-
function
|
|
96153
|
+
function join45(left3, right3) {
|
|
96154
96154
|
var leftSource, rightSource, leftCharCode, rightCharCode;
|
|
96155
96155
|
leftSource = toSourceNodeWhenNeeded(left3).toString();
|
|
96156
96156
|
if (leftSource.length === 0) {
|
|
@@ -96481,8 +96481,8 @@ var require_escodegen = __commonJS({
|
|
|
96481
96481
|
} else {
|
|
96482
96482
|
result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT));
|
|
96483
96483
|
}
|
|
96484
|
-
result =
|
|
96485
|
-
result = [
|
|
96484
|
+
result = join45(result, operator);
|
|
96485
|
+
result = [join45(
|
|
96486
96486
|
result,
|
|
96487
96487
|
that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)
|
|
96488
96488
|
), ")"];
|
|
@@ -96625,11 +96625,11 @@ var require_escodegen = __commonJS({
|
|
|
96625
96625
|
var result, fragment;
|
|
96626
96626
|
result = ["class"];
|
|
96627
96627
|
if (stmt.id) {
|
|
96628
|
-
result =
|
|
96628
|
+
result = join45(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
|
|
96629
96629
|
}
|
|
96630
96630
|
if (stmt.superClass) {
|
|
96631
|
-
fragment =
|
|
96632
|
-
result =
|
|
96631
|
+
fragment = join45("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
|
|
96632
|
+
result = join45(result, fragment);
|
|
96633
96633
|
}
|
|
96634
96634
|
result.push(space);
|
|
96635
96635
|
result.push(this.generateStatement(stmt.body, S_TFFT));
|
|
@@ -96642,9 +96642,9 @@ var require_escodegen = __commonJS({
|
|
|
96642
96642
|
return escapeDirective(stmt.directive) + this.semicolon(flags);
|
|
96643
96643
|
},
|
|
96644
96644
|
DoWhileStatement: function(stmt, flags) {
|
|
96645
|
-
var result =
|
|
96645
|
+
var result = join45("do", this.maybeBlock(stmt.body, S_TFFF));
|
|
96646
96646
|
result = this.maybeBlockSuffix(stmt.body, result);
|
|
96647
|
-
return
|
|
96647
|
+
return join45(result, [
|
|
96648
96648
|
"while" + space + "(",
|
|
96649
96649
|
this.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
|
|
96650
96650
|
")" + this.semicolon(flags)
|
|
@@ -96680,11 +96680,11 @@ var require_escodegen = __commonJS({
|
|
|
96680
96680
|
ExportDefaultDeclaration: function(stmt, flags) {
|
|
96681
96681
|
var result = ["export"], bodyFlags;
|
|
96682
96682
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
96683
|
-
result =
|
|
96683
|
+
result = join45(result, "default");
|
|
96684
96684
|
if (isStatement(stmt.declaration)) {
|
|
96685
|
-
result =
|
|
96685
|
+
result = join45(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
96686
96686
|
} else {
|
|
96687
|
-
result =
|
|
96687
|
+
result = join45(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
|
|
96688
96688
|
}
|
|
96689
96689
|
return result;
|
|
96690
96690
|
},
|
|
@@ -96692,15 +96692,15 @@ var require_escodegen = __commonJS({
|
|
|
96692
96692
|
var result = ["export"], bodyFlags, that = this;
|
|
96693
96693
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
96694
96694
|
if (stmt.declaration) {
|
|
96695
|
-
return
|
|
96695
|
+
return join45(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
96696
96696
|
}
|
|
96697
96697
|
if (stmt.specifiers) {
|
|
96698
96698
|
if (stmt.specifiers.length === 0) {
|
|
96699
|
-
result =
|
|
96699
|
+
result = join45(result, "{" + space + "}");
|
|
96700
96700
|
} else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) {
|
|
96701
|
-
result =
|
|
96701
|
+
result = join45(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
|
|
96702
96702
|
} else {
|
|
96703
|
-
result =
|
|
96703
|
+
result = join45(result, "{");
|
|
96704
96704
|
withIndent(function(indent2) {
|
|
96705
96705
|
var i2, iz;
|
|
96706
96706
|
result.push(newline);
|
|
@@ -96718,7 +96718,7 @@ var require_escodegen = __commonJS({
|
|
|
96718
96718
|
result.push(base + "}");
|
|
96719
96719
|
}
|
|
96720
96720
|
if (stmt.source) {
|
|
96721
|
-
result =
|
|
96721
|
+
result = join45(result, [
|
|
96722
96722
|
"from" + space,
|
|
96723
96723
|
// ModuleSpecifier
|
|
96724
96724
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
@@ -96806,7 +96806,7 @@ var require_escodegen = __commonJS({
|
|
|
96806
96806
|
];
|
|
96807
96807
|
cursor = 0;
|
|
96808
96808
|
if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) {
|
|
96809
|
-
result =
|
|
96809
|
+
result = join45(result, [
|
|
96810
96810
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
96811
96811
|
]);
|
|
96812
96812
|
++cursor;
|
|
@@ -96816,7 +96816,7 @@ var require_escodegen = __commonJS({
|
|
|
96816
96816
|
result.push(",");
|
|
96817
96817
|
}
|
|
96818
96818
|
if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) {
|
|
96819
|
-
result =
|
|
96819
|
+
result = join45(result, [
|
|
96820
96820
|
space,
|
|
96821
96821
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
96822
96822
|
]);
|
|
@@ -96845,7 +96845,7 @@ var require_escodegen = __commonJS({
|
|
|
96845
96845
|
}
|
|
96846
96846
|
}
|
|
96847
96847
|
}
|
|
96848
|
-
result =
|
|
96848
|
+
result = join45(result, [
|
|
96849
96849
|
"from" + space,
|
|
96850
96850
|
// ModuleSpecifier
|
|
96851
96851
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
@@ -96899,7 +96899,7 @@ var require_escodegen = __commonJS({
|
|
|
96899
96899
|
return result;
|
|
96900
96900
|
},
|
|
96901
96901
|
ThrowStatement: function(stmt, flags) {
|
|
96902
|
-
return [
|
|
96902
|
+
return [join45(
|
|
96903
96903
|
"throw",
|
|
96904
96904
|
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
|
|
96905
96905
|
), this.semicolon(flags)];
|
|
@@ -96910,7 +96910,7 @@ var require_escodegen = __commonJS({
|
|
|
96910
96910
|
result = this.maybeBlockSuffix(stmt.block, result);
|
|
96911
96911
|
if (stmt.handlers) {
|
|
96912
96912
|
for (i2 = 0, iz = stmt.handlers.length; i2 < iz; ++i2) {
|
|
96913
|
-
result =
|
|
96913
|
+
result = join45(result, this.generateStatement(stmt.handlers[i2], S_TFFF));
|
|
96914
96914
|
if (stmt.finalizer || i2 + 1 !== iz) {
|
|
96915
96915
|
result = this.maybeBlockSuffix(stmt.handlers[i2].body, result);
|
|
96916
96916
|
}
|
|
@@ -96918,7 +96918,7 @@ var require_escodegen = __commonJS({
|
|
|
96918
96918
|
} else {
|
|
96919
96919
|
guardedHandlers = stmt.guardedHandlers || [];
|
|
96920
96920
|
for (i2 = 0, iz = guardedHandlers.length; i2 < iz; ++i2) {
|
|
96921
|
-
result =
|
|
96921
|
+
result = join45(result, this.generateStatement(guardedHandlers[i2], S_TFFF));
|
|
96922
96922
|
if (stmt.finalizer || i2 + 1 !== iz) {
|
|
96923
96923
|
result = this.maybeBlockSuffix(guardedHandlers[i2].body, result);
|
|
96924
96924
|
}
|
|
@@ -96926,13 +96926,13 @@ var require_escodegen = __commonJS({
|
|
|
96926
96926
|
if (stmt.handler) {
|
|
96927
96927
|
if (Array.isArray(stmt.handler)) {
|
|
96928
96928
|
for (i2 = 0, iz = stmt.handler.length; i2 < iz; ++i2) {
|
|
96929
|
-
result =
|
|
96929
|
+
result = join45(result, this.generateStatement(stmt.handler[i2], S_TFFF));
|
|
96930
96930
|
if (stmt.finalizer || i2 + 1 !== iz) {
|
|
96931
96931
|
result = this.maybeBlockSuffix(stmt.handler[i2].body, result);
|
|
96932
96932
|
}
|
|
96933
96933
|
}
|
|
96934
96934
|
} else {
|
|
96935
|
-
result =
|
|
96935
|
+
result = join45(result, this.generateStatement(stmt.handler, S_TFFF));
|
|
96936
96936
|
if (stmt.finalizer) {
|
|
96937
96937
|
result = this.maybeBlockSuffix(stmt.handler.body, result);
|
|
96938
96938
|
}
|
|
@@ -96940,7 +96940,7 @@ var require_escodegen = __commonJS({
|
|
|
96940
96940
|
}
|
|
96941
96941
|
}
|
|
96942
96942
|
if (stmt.finalizer) {
|
|
96943
|
-
result =
|
|
96943
|
+
result = join45(result, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
|
|
96944
96944
|
}
|
|
96945
96945
|
return result;
|
|
96946
96946
|
},
|
|
@@ -96974,7 +96974,7 @@ var require_escodegen = __commonJS({
|
|
|
96974
96974
|
withIndent(function() {
|
|
96975
96975
|
if (stmt.test) {
|
|
96976
96976
|
result = [
|
|
96977
|
-
|
|
96977
|
+
join45("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
|
|
96978
96978
|
":"
|
|
96979
96979
|
];
|
|
96980
96980
|
} else {
|
|
@@ -97022,9 +97022,9 @@ var require_escodegen = __commonJS({
|
|
|
97022
97022
|
result.push(this.maybeBlock(stmt.consequent, S_TFFF));
|
|
97023
97023
|
result = this.maybeBlockSuffix(stmt.consequent, result);
|
|
97024
97024
|
if (stmt.alternate.type === Syntax.IfStatement) {
|
|
97025
|
-
result =
|
|
97025
|
+
result = join45(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
|
|
97026
97026
|
} else {
|
|
97027
|
-
result =
|
|
97027
|
+
result = join45(result, join45("else", this.maybeBlock(stmt.alternate, bodyFlags)));
|
|
97028
97028
|
}
|
|
97029
97029
|
} else {
|
|
97030
97030
|
result.push(this.maybeBlock(stmt.consequent, bodyFlags));
|
|
@@ -97125,7 +97125,7 @@ var require_escodegen = __commonJS({
|
|
|
97125
97125
|
},
|
|
97126
97126
|
ReturnStatement: function(stmt, flags) {
|
|
97127
97127
|
if (stmt.argument) {
|
|
97128
|
-
return [
|
|
97128
|
+
return [join45(
|
|
97129
97129
|
"return",
|
|
97130
97130
|
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
|
|
97131
97131
|
), this.semicolon(flags)];
|
|
@@ -97214,14 +97214,14 @@ var require_escodegen = __commonJS({
|
|
|
97214
97214
|
if (leftSource.charCodeAt(leftSource.length - 1) === 47 && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) {
|
|
97215
97215
|
result = [fragment, noEmptySpace(), expr.operator];
|
|
97216
97216
|
} else {
|
|
97217
|
-
result =
|
|
97217
|
+
result = join45(fragment, expr.operator);
|
|
97218
97218
|
}
|
|
97219
97219
|
fragment = this.generateExpression(expr.right, rightPrecedence, flags);
|
|
97220
97220
|
if (expr.operator === "/" && fragment.toString().charAt(0) === "/" || expr.operator.slice(-1) === "<" && fragment.toString().slice(0, 3) === "!--") {
|
|
97221
97221
|
result.push(noEmptySpace());
|
|
97222
97222
|
result.push(fragment);
|
|
97223
97223
|
} else {
|
|
97224
|
-
result =
|
|
97224
|
+
result = join45(result, fragment);
|
|
97225
97225
|
}
|
|
97226
97226
|
if (expr.operator === "in" && !(flags & F_ALLOW_IN)) {
|
|
97227
97227
|
return ["(", result, ")"];
|
|
@@ -97261,7 +97261,7 @@ var require_escodegen = __commonJS({
|
|
|
97261
97261
|
var result, length, i2, iz, itemFlags;
|
|
97262
97262
|
length = expr["arguments"].length;
|
|
97263
97263
|
itemFlags = flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0 ? E_TFT : E_TFF;
|
|
97264
|
-
result =
|
|
97264
|
+
result = join45(
|
|
97265
97265
|
"new",
|
|
97266
97266
|
this.generateExpression(expr.callee, Precedence.New, itemFlags)
|
|
97267
97267
|
);
|
|
@@ -97311,11 +97311,11 @@ var require_escodegen = __commonJS({
|
|
|
97311
97311
|
var result, fragment, rightCharCode, leftSource, leftCharCode;
|
|
97312
97312
|
fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT);
|
|
97313
97313
|
if (space === "") {
|
|
97314
|
-
result =
|
|
97314
|
+
result = join45(expr.operator, fragment);
|
|
97315
97315
|
} else {
|
|
97316
97316
|
result = [expr.operator];
|
|
97317
97317
|
if (expr.operator.length > 2) {
|
|
97318
|
-
result =
|
|
97318
|
+
result = join45(result, fragment);
|
|
97319
97319
|
} else {
|
|
97320
97320
|
leftSource = toSourceNodeWhenNeeded(result).toString();
|
|
97321
97321
|
leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
|
|
@@ -97338,7 +97338,7 @@ var require_escodegen = __commonJS({
|
|
|
97338
97338
|
result = "yield";
|
|
97339
97339
|
}
|
|
97340
97340
|
if (expr.argument) {
|
|
97341
|
-
result =
|
|
97341
|
+
result = join45(
|
|
97342
97342
|
result,
|
|
97343
97343
|
this.generateExpression(expr.argument, Precedence.Yield, E_TTT)
|
|
97344
97344
|
);
|
|
@@ -97346,7 +97346,7 @@ var require_escodegen = __commonJS({
|
|
|
97346
97346
|
return parenthesize(result, Precedence.Yield, precedence);
|
|
97347
97347
|
},
|
|
97348
97348
|
AwaitExpression: function(expr, precedence, flags) {
|
|
97349
|
-
var result =
|
|
97349
|
+
var result = join45(
|
|
97350
97350
|
expr.all ? "await*" : "await",
|
|
97351
97351
|
this.generateExpression(expr.argument, Precedence.Await, E_TTT)
|
|
97352
97352
|
);
|
|
@@ -97429,11 +97429,11 @@ var require_escodegen = __commonJS({
|
|
|
97429
97429
|
var result, fragment;
|
|
97430
97430
|
result = ["class"];
|
|
97431
97431
|
if (expr.id) {
|
|
97432
|
-
result =
|
|
97432
|
+
result = join45(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
|
|
97433
97433
|
}
|
|
97434
97434
|
if (expr.superClass) {
|
|
97435
|
-
fragment =
|
|
97436
|
-
result =
|
|
97435
|
+
fragment = join45("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
|
|
97436
|
+
result = join45(result, fragment);
|
|
97437
97437
|
}
|
|
97438
97438
|
result.push(space);
|
|
97439
97439
|
result.push(this.generateStatement(expr.body, S_TFFT));
|
|
@@ -97448,7 +97448,7 @@ var require_escodegen = __commonJS({
|
|
|
97448
97448
|
}
|
|
97449
97449
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
97450
97450
|
fragment = [
|
|
97451
|
-
|
|
97451
|
+
join45(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
|
|
97452
97452
|
this.generateFunctionBody(expr.value)
|
|
97453
97453
|
];
|
|
97454
97454
|
} else {
|
|
@@ -97458,7 +97458,7 @@ var require_escodegen = __commonJS({
|
|
|
97458
97458
|
this.generateFunctionBody(expr.value)
|
|
97459
97459
|
];
|
|
97460
97460
|
}
|
|
97461
|
-
return
|
|
97461
|
+
return join45(result, fragment);
|
|
97462
97462
|
},
|
|
97463
97463
|
Property: function(expr, precedence, flags) {
|
|
97464
97464
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
@@ -97653,7 +97653,7 @@ var require_escodegen = __commonJS({
|
|
|
97653
97653
|
for (i2 = 0, iz = expr.blocks.length; i2 < iz; ++i2) {
|
|
97654
97654
|
fragment = that.generateExpression(expr.blocks[i2], Precedence.Sequence, E_TTT);
|
|
97655
97655
|
if (i2 > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
97656
|
-
result =
|
|
97656
|
+
result = join45(result, fragment);
|
|
97657
97657
|
} else {
|
|
97658
97658
|
result.push(fragment);
|
|
97659
97659
|
}
|
|
@@ -97661,13 +97661,13 @@ var require_escodegen = __commonJS({
|
|
|
97661
97661
|
});
|
|
97662
97662
|
}
|
|
97663
97663
|
if (expr.filter) {
|
|
97664
|
-
result =
|
|
97664
|
+
result = join45(result, "if" + space);
|
|
97665
97665
|
fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
|
|
97666
|
-
result =
|
|
97666
|
+
result = join45(result, ["(", fragment, ")"]);
|
|
97667
97667
|
}
|
|
97668
97668
|
if (!extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
97669
97669
|
fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
|
|
97670
|
-
result =
|
|
97670
|
+
result = join45(result, fragment);
|
|
97671
97671
|
}
|
|
97672
97672
|
result.push(expr.type === Syntax.GeneratorExpression ? ")" : "]");
|
|
97673
97673
|
return result;
|
|
@@ -97683,8 +97683,8 @@ var require_escodegen = __commonJS({
|
|
|
97683
97683
|
} else {
|
|
97684
97684
|
fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT);
|
|
97685
97685
|
}
|
|
97686
|
-
fragment =
|
|
97687
|
-
fragment =
|
|
97686
|
+
fragment = join45(fragment, expr.of ? "of" : "in");
|
|
97687
|
+
fragment = join45(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
|
|
97688
97688
|
return ["for" + space + "(", fragment, ")"];
|
|
97689
97689
|
},
|
|
97690
97690
|
SpreadElement: function(expr, precedence, flags) {
|
|
@@ -124086,9 +124086,9 @@ async function getConnectionTransport(options) {
|
|
|
124086
124086
|
throw new Error("Could not detect required browser platform");
|
|
124087
124087
|
}
|
|
124088
124088
|
const { convertPuppeteerChannelToBrowsersChannel: convertPuppeteerChannelToBrowsersChannel3 } = await Promise.resolve().then(() => (init_LaunchOptions(), LaunchOptions_exports));
|
|
124089
|
-
const { join:
|
|
124089
|
+
const { join: join45 } = await import("node:path");
|
|
124090
124090
|
const userDataDir = resolveDefaultUserDataDir4(Browser5.CHROME, platform, convertPuppeteerChannelToBrowsersChannel3(options.channel));
|
|
124091
|
-
const portPath =
|
|
124091
|
+
const portPath = join45(userDataDir, "DevToolsActivePort");
|
|
124092
124092
|
try {
|
|
124093
124093
|
const fileContent = await environment.value.fs.promises.readFile(portPath, "ascii");
|
|
124094
124094
|
const [rawPort, rawPath] = fileContent.split("\n").map((line) => {
|
|
@@ -137965,7 +137965,7 @@ ${lanes.join("\n")}
|
|
|
137965
137965
|
writeOutputIsTTY() {
|
|
137966
137966
|
return process.stdout.isTTY;
|
|
137967
137967
|
},
|
|
137968
|
-
readFile:
|
|
137968
|
+
readFile: readFile47,
|
|
137969
137969
|
writeFile: writeFile210,
|
|
137970
137970
|
watchFile: watchFile2,
|
|
137971
137971
|
watchDirectory,
|
|
@@ -138171,7 +138171,7 @@ ${lanes.join("\n")}
|
|
|
138171
138171
|
callback
|
|
138172
138172
|
);
|
|
138173
138173
|
}
|
|
138174
|
-
function
|
|
138174
|
+
function readFile47(fileName, _encoding) {
|
|
138175
138175
|
let buffer;
|
|
138176
138176
|
try {
|
|
138177
138177
|
buffer = _fs.readFileSync(fileName);
|
|
@@ -174727,7 +174727,7 @@ ${lanes.join("\n")}
|
|
|
174727
174727
|
const possibleOption = getSpellingSuggestion(unknownOption, diagnostics.optionDeclarations, getOptionName);
|
|
174728
174728
|
return possibleOption ? createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics.unknownDidYouMeanDiagnostic, unknownOptionErrorText || unknownOption, possibleOption.name) : createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics.unknownOptionDiagnostic, unknownOptionErrorText || unknownOption);
|
|
174729
174729
|
}
|
|
174730
|
-
function parseCommandLineWorker(diagnostics, commandLine,
|
|
174730
|
+
function parseCommandLineWorker(diagnostics, commandLine, readFile47) {
|
|
174731
174731
|
const options = {};
|
|
174732
174732
|
let watchOptions;
|
|
174733
174733
|
const fileNames = [];
|
|
@@ -174775,7 +174775,7 @@ ${lanes.join("\n")}
|
|
|
174775
174775
|
}
|
|
174776
174776
|
}
|
|
174777
174777
|
function parseResponseFile(fileName) {
|
|
174778
|
-
const text = tryReadFile(fileName,
|
|
174778
|
+
const text = tryReadFile(fileName, readFile47 || ((fileName2) => sys.readFile(fileName2)));
|
|
174779
174779
|
if (!isString3(text)) {
|
|
174780
174780
|
errors.push(text);
|
|
174781
174781
|
return;
|
|
@@ -174878,8 +174878,8 @@ ${lanes.join("\n")}
|
|
|
174878
174878
|
unknownDidYouMeanDiagnostic: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1,
|
|
174879
174879
|
optionTypeMismatchDiagnostic: Diagnostics.Compiler_option_0_expects_an_argument
|
|
174880
174880
|
};
|
|
174881
|
-
function parseCommandLine(commandLine,
|
|
174882
|
-
return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine,
|
|
174881
|
+
function parseCommandLine(commandLine, readFile47) {
|
|
174882
|
+
return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine, readFile47);
|
|
174883
174883
|
}
|
|
174884
174884
|
function getOptionFromName(optionName, allowShort) {
|
|
174885
174885
|
return getOptionDeclarationFromName(getOptionsNameMap, optionName, allowShort);
|
|
@@ -174961,8 +174961,8 @@ ${lanes.join("\n")}
|
|
|
174961
174961
|
watchOptionsToExtend
|
|
174962
174962
|
);
|
|
174963
174963
|
}
|
|
174964
|
-
function readConfigFile2(fileName,
|
|
174965
|
-
const textOrDiagnostic = tryReadFile(fileName,
|
|
174964
|
+
function readConfigFile2(fileName, readFile47) {
|
|
174965
|
+
const textOrDiagnostic = tryReadFile(fileName, readFile47);
|
|
174966
174966
|
return isString3(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
|
|
174967
174967
|
}
|
|
174968
174968
|
function parseConfigFileTextToJson(fileName, jsonText) {
|
|
@@ -174977,14 +174977,14 @@ ${lanes.join("\n")}
|
|
|
174977
174977
|
error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : void 0
|
|
174978
174978
|
};
|
|
174979
174979
|
}
|
|
174980
|
-
function readJsonConfigFile(fileName,
|
|
174981
|
-
const textOrDiagnostic = tryReadFile(fileName,
|
|
174980
|
+
function readJsonConfigFile(fileName, readFile47) {
|
|
174981
|
+
const textOrDiagnostic = tryReadFile(fileName, readFile47);
|
|
174982
174982
|
return isString3(textOrDiagnostic) ? parseJsonText(fileName, textOrDiagnostic) : { fileName, parseDiagnostics: [textOrDiagnostic] };
|
|
174983
174983
|
}
|
|
174984
|
-
function tryReadFile(fileName,
|
|
174984
|
+
function tryReadFile(fileName, readFile47) {
|
|
174985
174985
|
let text;
|
|
174986
174986
|
try {
|
|
174987
|
-
text =
|
|
174987
|
+
text = readFile47(fileName);
|
|
174988
174988
|
} catch (e2) {
|
|
174989
174989
|
return createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e2.message);
|
|
174990
174990
|
}
|
|
@@ -264642,12 +264642,12 @@ ${lanes.join("\n")}
|
|
|
264642
264642
|
function createCompilerHost(options, setParentNodes) {
|
|
264643
264643
|
return createCompilerHostWorker(options, setParentNodes);
|
|
264644
264644
|
}
|
|
264645
|
-
function createGetSourceFile(
|
|
264645
|
+
function createGetSourceFile(readFile47, setParentNodes) {
|
|
264646
264646
|
return (fileName, languageVersionOrOptions, onError) => {
|
|
264647
264647
|
let text;
|
|
264648
264648
|
try {
|
|
264649
264649
|
mark("beforeIORead");
|
|
264650
|
-
text =
|
|
264650
|
+
text = readFile47(fileName);
|
|
264651
264651
|
mark("afterIORead");
|
|
264652
264652
|
measure("I/O Read", "beforeIORead", "afterIORead");
|
|
264653
264653
|
} catch (e2) {
|
|
@@ -265551,7 +265551,7 @@ ${lanes.join("\n")}
|
|
|
265551
265551
|
getRedirectFromOutput,
|
|
265552
265552
|
forEachResolvedProjectReference: forEachResolvedProjectReference2
|
|
265553
265553
|
});
|
|
265554
|
-
const
|
|
265554
|
+
const readFile47 = host.readFile.bind(host);
|
|
265555
265555
|
(_e2 = tracing) == null ? void 0 : _e2.push(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram });
|
|
265556
265556
|
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
|
|
265557
265557
|
(_f = tracing) == null ? void 0 : _f.pop();
|
|
@@ -265777,7 +265777,7 @@ ${lanes.join("\n")}
|
|
|
265777
265777
|
shouldTransformImportCall,
|
|
265778
265778
|
emitBuildInfo,
|
|
265779
265779
|
fileExists: fileExists2,
|
|
265780
|
-
readFile:
|
|
265780
|
+
readFile: readFile47,
|
|
265781
265781
|
directoryExists,
|
|
265782
265782
|
getSymlinkCache,
|
|
265783
265783
|
realpath: (_o = host.realpath) == null ? void 0 : _o.bind(host),
|
|
@@ -470414,10 +470414,57 @@ var init_composer_resolve = __esm({
|
|
|
470414
470414
|
}
|
|
470415
470415
|
});
|
|
470416
470416
|
|
|
470417
|
+
// ../cli/src/commands/_shared/transcribe-narration.ts
|
|
470418
|
+
import { existsSync as existsSync24 } from "node:fs";
|
|
470419
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
470420
|
+
import { join as join24 } from "node:path";
|
|
470421
|
+
async function transcribeNarrationWords(audioAbsPath, opts) {
|
|
470422
|
+
try {
|
|
470423
|
+
const whisper = new WhisperProvider();
|
|
470424
|
+
await whisper.initialize({ apiKey: opts.apiKey });
|
|
470425
|
+
const audioBytes = await readFile9(audioAbsPath);
|
|
470426
|
+
const audioBlob = new Blob([new Uint8Array(audioBytes)]);
|
|
470427
|
+
const transcript = await whisper.transcribe(audioBlob, void 0, {
|
|
470428
|
+
granularity: "word",
|
|
470429
|
+
language: opts.language
|
|
470430
|
+
});
|
|
470431
|
+
if (transcript.status === "completed" && transcript.words?.length) {
|
|
470432
|
+
return transcript.words.map((w2) => ({ text: w2.text, start: w2.start, end: w2.end }));
|
|
470433
|
+
}
|
|
470434
|
+
return [];
|
|
470435
|
+
} catch {
|
|
470436
|
+
return [];
|
|
470437
|
+
}
|
|
470438
|
+
}
|
|
470439
|
+
function beatTranscriptRelPath(beatId) {
|
|
470440
|
+
return `assets/transcript-${beatId}.json`;
|
|
470441
|
+
}
|
|
470442
|
+
async function readBeatTranscript(projectDir, beatId) {
|
|
470443
|
+
const abs = join24(projectDir, beatTranscriptRelPath(beatId));
|
|
470444
|
+
if (!existsSync24(abs)) return void 0;
|
|
470445
|
+
try {
|
|
470446
|
+
const parsed = JSON.parse(await readFile9(abs, "utf-8"));
|
|
470447
|
+
if (!Array.isArray(parsed)) return void 0;
|
|
470448
|
+
const words = parsed.filter(
|
|
470449
|
+
(w2) => typeof w2 === "object" && w2 !== null && typeof w2.text === "string" && Number.isFinite(w2.start) && Number.isFinite(w2.end)
|
|
470450
|
+
).map((w2) => ({ text: w2.text, start: w2.start, end: w2.end }));
|
|
470451
|
+
return words.length > 0 ? words : void 0;
|
|
470452
|
+
} catch {
|
|
470453
|
+
return void 0;
|
|
470454
|
+
}
|
|
470455
|
+
}
|
|
470456
|
+
var init_transcribe_narration = __esm({
|
|
470457
|
+
"../cli/src/commands/_shared/transcribe-narration.ts"() {
|
|
470458
|
+
"use strict";
|
|
470459
|
+
init_dist();
|
|
470460
|
+
}
|
|
470461
|
+
});
|
|
470462
|
+
|
|
470417
470463
|
// ../cli/src/commands/_shared/compose-scenes-skills.ts
|
|
470418
470464
|
var compose_scenes_skills_exports = {};
|
|
470419
470465
|
__export(compose_scenes_skills_exports, {
|
|
470420
470466
|
ComposeBeatError: () => ComposeBeatError,
|
|
470467
|
+
TRANSCRIPT_PROMPT_MAX_WORDS: () => TRANSCRIPT_PROMPT_MAX_WORDS,
|
|
470421
470468
|
buildSystemPrompt: () => buildSystemPrompt,
|
|
470422
470469
|
buildUserPrompt: () => buildUserPrompt,
|
|
470423
470470
|
composeBeatHtml: () => composeBeatHtml,
|
|
@@ -470427,12 +470474,13 @@ __export(compose_scenes_skills_exports, {
|
|
|
470427
470474
|
executeComposeScenesWithSkills: () => executeComposeScenesWithSkills,
|
|
470428
470475
|
extractHtml: () => extractHtml,
|
|
470429
470476
|
formatLintFeedback: () => formatLintFeedback,
|
|
470477
|
+
formatTranscriptSection: () => formatTranscriptSection,
|
|
470430
470478
|
lintBeatHtml: () => lintBeatHtml
|
|
470431
470479
|
});
|
|
470432
470480
|
import { createHash as createHash5 } from "node:crypto";
|
|
470433
|
-
import { existsSync as
|
|
470434
|
-
import { mkdir as mkdir9, readFile as
|
|
470435
|
-
import { dirname as dirname13, join as
|
|
470481
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync12 } from "node:fs";
|
|
470482
|
+
import { mkdir as mkdir9, readFile as readFile10, writeFile as writeFile14 } from "node:fs/promises";
|
|
470483
|
+
import { dirname as dirname13, join as join25, resolve as resolve18 } from "node:path";
|
|
470436
470484
|
function buildSystemPrompt(ctx) {
|
|
470437
470485
|
return `You are a Hyperframes composition author. The skill content below
|
|
470438
470486
|
defines the framework rules, motion principles, and quality standards.
|
|
@@ -470465,6 +470513,46 @@ function formatBeatCues(cues) {
|
|
|
470465
470513
|
}
|
|
470466
470514
|
return lines.join("\n") + "\n";
|
|
470467
470515
|
}
|
|
470516
|
+
function formatTranscriptSection(transcript, maxWords = TRANSCRIPT_PROMPT_MAX_WORDS) {
|
|
470517
|
+
if (!transcript || transcript.length === 0) return "";
|
|
470518
|
+
const round = (n2) => Number(Math.max(0, n2).toFixed(2));
|
|
470519
|
+
const noAudioRule = "This is for VISUAL sync only \u2014 do NOT add an `<audio>` tag or invent SFX; the narration audio is wired separately by the root timeline. If this beat is visual-only (no on-screen text), you may ignore these timings.";
|
|
470520
|
+
if (transcript.length <= maxWords) {
|
|
470521
|
+
const pairs = transcript.map((w2) => `[${round(w2.start)}, ${JSON.stringify(w2.text)}]`).join(", ");
|
|
470522
|
+
return `
|
|
470523
|
+
|
|
470524
|
+
=== Narration word timings (seconds) ===
|
|
470525
|
+
|
|
470526
|
+
Whisper word-level start times for this beat's narration. If you author captions
|
|
470527
|
+
or kinetic typography, reveal each word at its start time with absolute-time
|
|
470528
|
+
GSAP tweens, e.g.
|
|
470529
|
+
\`tl.fromTo('.caption .word[data-i="0"]', { opacity: 0, y: 10 }, { opacity: 1, y: 0, duration: 0.18 }, ${round(
|
|
470530
|
+
transcript[0].start
|
|
470531
|
+
)});\`
|
|
470532
|
+
${noAudioRule}
|
|
470533
|
+
|
|
470534
|
+
word starts (word-level): ${pairs}`;
|
|
470535
|
+
}
|
|
470536
|
+
const phraseCount = Math.max(1, Math.floor(maxWords / 2));
|
|
470537
|
+
const chunkSize = Math.ceil(transcript.length / phraseCount);
|
|
470538
|
+
const anchors = [];
|
|
470539
|
+
for (let i2 = 0; i2 < transcript.length; i2 += chunkSize) {
|
|
470540
|
+
const chunk = transcript.slice(i2, i2 + chunkSize);
|
|
470541
|
+
const text = chunk.map((w2) => w2.text).join(" ");
|
|
470542
|
+
anchors.push(`[${round(chunk[0].start)}, ${JSON.stringify(text)}]`);
|
|
470543
|
+
}
|
|
470544
|
+
return `
|
|
470545
|
+
|
|
470546
|
+
=== Narration timings (approximate, phrase-level) ===
|
|
470547
|
+
|
|
470548
|
+
This beat's narration is long (${transcript.length} words), so timings are
|
|
470549
|
+
grouped into phrase-level anchors (start time of each phrase). Use them to PACE
|
|
470550
|
+
caption / kinetic-type reveals across the beat \u2014 they are approximate, not
|
|
470551
|
+
per-word truth.
|
|
470552
|
+
${noAudioRule}
|
|
470553
|
+
|
|
470554
|
+
phrase starts (approximate): ${anchors.join(", ")}`;
|
|
470555
|
+
}
|
|
470468
470556
|
function buildUserPrompt(ctx) {
|
|
470469
470557
|
const compositionId = `scene-${ctx.beat.id}`;
|
|
470470
470558
|
const durLiteral = ctx.finalDurationSec !== void 0 ? String(ctx.finalDurationSec) : void 0;
|
|
@@ -470627,7 +470715,7 @@ ${ctx.storyboardGlobal || "(no global direction)"}
|
|
|
470627
470715
|
|
|
470628
470716
|
## ${ctx.beat.heading}
|
|
470629
470717
|
${formatBeatCues(ctx.beat.cues)}${cueDurationNote}
|
|
470630
|
-
${ctx.beat.body}
|
|
470718
|
+
${ctx.beat.body}${formatTranscriptSection(ctx.transcript)}
|
|
470631
470719
|
|
|
470632
470720
|
=== Output format ===
|
|
470633
470721
|
|
|
@@ -470647,7 +470735,7 @@ function computeCacheKey(parts) {
|
|
|
470647
470735
|
return createHash5("sha256").update(parts.provider).update("\u241E").update(parts.model).update("\u241E").update(parts.systemPrompt).update("\u241E").update(parts.userPrompt).digest("hex");
|
|
470648
470736
|
}
|
|
470649
470737
|
function defaultCacheDir() {
|
|
470650
|
-
return
|
|
470738
|
+
return join25(USER_CACHE_DIR, "compose-scenes");
|
|
470651
470739
|
}
|
|
470652
470740
|
function extractHtml(responseText) {
|
|
470653
470741
|
const fenced = responseText.match(/```html\s*\n([\s\S]*?)\n```/);
|
|
@@ -470671,9 +470759,9 @@ async function composeBeatHtml(ctx, overrides) {
|
|
|
470671
470759
|
model: settings.model
|
|
470672
470760
|
});
|
|
470673
470761
|
const cacheDir = ctx.cacheDir ?? defaultCacheDir();
|
|
470674
|
-
const cachePath =
|
|
470675
|
-
if (
|
|
470676
|
-
const html2 = await
|
|
470762
|
+
const cachePath = join25(cacheDir, `${cacheKey2}.html`);
|
|
470763
|
+
if (existsSync25(cachePath)) {
|
|
470764
|
+
const html2 = await readFile10(cachePath, "utf-8");
|
|
470677
470765
|
return { html: html2, cached: true, cacheKey: cacheKey2, model: settings.model, provider: ctx.provider };
|
|
470678
470766
|
}
|
|
470679
470767
|
if (!ctx.apiKey) {
|
|
@@ -470809,14 +470897,14 @@ async function executeComposeScenesWithSkills(params, outputDir, overrides) {
|
|
|
470809
470897
|
const projectRoot = params.project ? resolve18(outputDir, params.project) : resolve18(outputDir);
|
|
470810
470898
|
const designPath = resolve18(projectRoot, params.design ?? "DESIGN.md");
|
|
470811
470899
|
const storyboardPath = resolve18(projectRoot, params.storyboard ?? "STORYBOARD.md");
|
|
470812
|
-
if (!
|
|
470900
|
+
if (!existsSync25(designPath)) {
|
|
470813
470901
|
return { success: false, error: `DESIGN.md not found at ${designPath}` };
|
|
470814
470902
|
}
|
|
470815
|
-
if (!
|
|
470903
|
+
if (!existsSync25(storyboardPath)) {
|
|
470816
470904
|
return { success: false, error: `STORYBOARD.md not found at ${storyboardPath}` };
|
|
470817
470905
|
}
|
|
470818
|
-
const designMd = await
|
|
470819
|
-
const storyboardMd = await
|
|
470906
|
+
const designMd = await readFile10(designPath, "utf-8");
|
|
470907
|
+
const storyboardMd = await readFile10(storyboardPath, "utf-8");
|
|
470820
470908
|
const { global: storyboardGlobal, beats } = parseStoryboard(storyboardMd);
|
|
470821
470909
|
if (beats.length === 0) {
|
|
470822
470910
|
return {
|
|
@@ -470836,7 +470924,7 @@ async function executeComposeScenesWithSkills(params, outputDir, overrides) {
|
|
|
470836
470924
|
provider = params.composer ?? "claude";
|
|
470837
470925
|
apiKey = "";
|
|
470838
470926
|
}
|
|
470839
|
-
const compositionsDir =
|
|
470927
|
+
const compositionsDir = join25(projectRoot, "compositions");
|
|
470840
470928
|
await mkdir9(compositionsDir, { recursive: true });
|
|
470841
470929
|
let finalDurations = /* @__PURE__ */ new Map();
|
|
470842
470930
|
try {
|
|
@@ -470850,6 +470938,7 @@ async function executeComposeScenesWithSkills(params, outputDir, overrides) {
|
|
|
470850
470938
|
async (beat, beatIndex) => {
|
|
470851
470939
|
onProgress({ type: "beat-start", beatId: beat.id, beatIndex, totalBeats });
|
|
470852
470940
|
try {
|
|
470941
|
+
const transcript = await readBeatTranscript(projectRoot, beat.id);
|
|
470853
470942
|
const result = await composeBeatWithRetry(
|
|
470854
470943
|
{
|
|
470855
470944
|
beat,
|
|
@@ -470860,11 +470949,12 @@ async function executeComposeScenesWithSkills(params, outputDir, overrides) {
|
|
|
470860
470949
|
apiKey,
|
|
470861
470950
|
effort: params.effort,
|
|
470862
470951
|
cacheDir: params.cacheDir,
|
|
470863
|
-
finalDurationSec: finalDurations.get(beat.id)
|
|
470952
|
+
finalDurationSec: finalDurations.get(beat.id),
|
|
470953
|
+
transcript
|
|
470864
470954
|
},
|
|
470865
470955
|
overrides
|
|
470866
470956
|
);
|
|
470867
|
-
const compositionPath =
|
|
470957
|
+
const compositionPath = join25(compositionsDir, `scene-${beat.id}.html`);
|
|
470868
470958
|
await mkdir9(dirname13(compositionPath), { recursive: true });
|
|
470869
470959
|
await writeFile14(compositionPath, result.html, "utf-8");
|
|
470870
470960
|
if (result.cached) {
|
|
@@ -470943,7 +471033,7 @@ ${failures.map((f2) => ` - ${f2.beatId}: ${f2.error}`).join("\n")}`,
|
|
|
470943
471033
|
data: aggregateData
|
|
470944
471034
|
};
|
|
470945
471035
|
}
|
|
470946
|
-
var MODEL_SETTINGS_BY_PROVIDER, ComposeBeatError, defaultCallLLM, CONFIG_PROVIDER_BY_COMPOSER;
|
|
471036
|
+
var MODEL_SETTINGS_BY_PROVIDER, TRANSCRIPT_PROMPT_MAX_WORDS, ComposeBeatError, defaultCallLLM, CONFIG_PROVIDER_BY_COMPOSER;
|
|
470947
471037
|
var init_compose_scenes_skills = __esm({
|
|
470948
471038
|
"../cli/src/commands/_shared/compose-scenes-skills.ts"() {
|
|
470949
471039
|
"use strict";
|
|
@@ -470959,6 +471049,7 @@ var init_compose_scenes_skills = __esm({
|
|
|
470959
471049
|
init_root_sync();
|
|
470960
471050
|
init_composer_resolve();
|
|
470961
471051
|
init_config();
|
|
471052
|
+
init_transcribe_narration();
|
|
470962
471053
|
MODEL_SETTINGS_BY_PROVIDER = {
|
|
470963
471054
|
// Anthropic Claude Sonnet 4.6 — v0.69 baseline. ~9 s/beat, $3/$15 per MTok.
|
|
470964
471055
|
claude: {
|
|
@@ -470982,6 +471073,7 @@ var init_compose_scenes_skills = __esm({
|
|
|
470982
471073
|
high: { model: GEMINI_DEFAULT_TEXT_MODEL, maxTokens: 8e3, costPerMTokIn: 1.5, costPerMTokOut: 9 }
|
|
470983
471074
|
}
|
|
470984
471075
|
};
|
|
471076
|
+
TRANSCRIPT_PROMPT_MAX_WORDS = 120;
|
|
470985
471077
|
ComposeBeatError = class extends Error {
|
|
470986
471078
|
constructor(code, message, cause) {
|
|
470987
471079
|
super(message);
|
|
@@ -471067,22 +471159,22 @@ var init_compose_scenes_skills = __esm({
|
|
|
471067
471159
|
});
|
|
471068
471160
|
|
|
471069
471161
|
// ../cli/src/commands/_shared/compose-prompts.ts
|
|
471070
|
-
import { existsSync as
|
|
471071
|
-
import { readFile as
|
|
471072
|
-
import { join as
|
|
471162
|
+
import { existsSync as existsSync26 } from "node:fs";
|
|
471163
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
471164
|
+
import { join as join26, relative as relative6, resolve as resolve19 } from "node:path";
|
|
471073
471165
|
async function getComposePrompts(opts) {
|
|
471074
471166
|
const projectDir = resolve19(opts.projectDir);
|
|
471075
|
-
const designPath =
|
|
471076
|
-
const storyboardPath =
|
|
471077
|
-
const skillPath =
|
|
471078
|
-
const compositionsDir =
|
|
471167
|
+
const designPath = join26(projectDir, "DESIGN.md");
|
|
471168
|
+
const storyboardPath = join26(projectDir, "STORYBOARD.md");
|
|
471169
|
+
const skillPath = join26(projectDir, "SKILL.md");
|
|
471170
|
+
const compositionsDir = join26(projectDir, "compositions");
|
|
471079
471171
|
const warnings = [];
|
|
471080
471172
|
const baseError = (msg) => ({
|
|
471081
471173
|
success: false,
|
|
471082
471174
|
projectDir,
|
|
471083
471175
|
designReference: "DESIGN.md",
|
|
471084
471176
|
storyboardReference: "STORYBOARD.md",
|
|
471085
|
-
skillReference:
|
|
471177
|
+
skillReference: existsSync26(skillPath) ? "SKILL.md" : null,
|
|
471086
471178
|
compositionsDir: "compositions",
|
|
471087
471179
|
beats: [],
|
|
471088
471180
|
instructions: [],
|
|
@@ -471090,18 +471182,18 @@ async function getComposePrompts(opts) {
|
|
|
471090
471182
|
warnings,
|
|
471091
471183
|
error: msg
|
|
471092
471184
|
});
|
|
471093
|
-
if (!
|
|
471185
|
+
if (!existsSync26(designPath)) {
|
|
471094
471186
|
return baseError(`DESIGN.md not found at ${designPath}. Run \`vibe scene init <dir>\` first.`);
|
|
471095
471187
|
}
|
|
471096
|
-
if (!
|
|
471188
|
+
if (!existsSync26(storyboardPath)) {
|
|
471097
471189
|
return baseError(`STORYBOARD.md not found at ${storyboardPath}. Run \`vibe scene init <dir>\` to create a starter, or add STORYBOARD.md with per-beat cues.`);
|
|
471098
471190
|
}
|
|
471099
|
-
if (!
|
|
471191
|
+
if (!existsSync26(skillPath)) {
|
|
471100
471192
|
warnings.push(
|
|
471101
471193
|
"SKILL.md not installed \u2014 host agent won't have Hyperframes rules in context. Run `vibe scene install-skill` to install it."
|
|
471102
471194
|
);
|
|
471103
471195
|
}
|
|
471104
|
-
const storyboardMd = await
|
|
471196
|
+
const storyboardMd = await readFile11(storyboardPath, "utf-8");
|
|
471105
471197
|
const parsed = parseStoryboard(storyboardMd);
|
|
471106
471198
|
if (parsed.beats.length === 0) {
|
|
471107
471199
|
return baseError(`STORYBOARD.md has no \`## Beat \u2026\` headings.`);
|
|
@@ -471123,28 +471215,33 @@ async function getComposePrompts(opts) {
|
|
|
471123
471215
|
finalDurations = await resolveProjectBeatDurations(projectDir);
|
|
471124
471216
|
} catch {
|
|
471125
471217
|
}
|
|
471126
|
-
const result =
|
|
471127
|
-
|
|
471128
|
-
|
|
471129
|
-
|
|
471130
|
-
|
|
471131
|
-
beat
|
|
471132
|
-
|
|
471133
|
-
|
|
471134
|
-
|
|
471135
|
-
|
|
471136
|
-
|
|
471137
|
-
|
|
471138
|
-
|
|
471139
|
-
|
|
471140
|
-
|
|
471141
|
-
|
|
471142
|
-
|
|
471143
|
-
|
|
471144
|
-
|
|
471145
|
-
|
|
471146
|
-
|
|
471147
|
-
|
|
471218
|
+
const result = await Promise.all(
|
|
471219
|
+
beats.map(async (beat) => {
|
|
471220
|
+
const outputPathAbs = join26(compositionsDir, `scene-${beat.id}.html`);
|
|
471221
|
+
const outputPathRel = relative6(projectDir, outputPathAbs);
|
|
471222
|
+
const finalDurationSec = finalDurations.get(beat.id);
|
|
471223
|
+
const transcript = await readBeatTranscript(projectDir, beat.id);
|
|
471224
|
+
const userPrompt = buildUserPrompt({
|
|
471225
|
+
beat,
|
|
471226
|
+
storyboardGlobal: parsed.global,
|
|
471227
|
+
finalDurationSec,
|
|
471228
|
+
transcript
|
|
471229
|
+
});
|
|
471230
|
+
return {
|
|
471231
|
+
id: beat.id,
|
|
471232
|
+
heading: beat.heading,
|
|
471233
|
+
outputPath: outputPathRel,
|
|
471234
|
+
duration: beat.duration,
|
|
471235
|
+
finalDurationSec,
|
|
471236
|
+
cues: beat.cues,
|
|
471237
|
+
body: beat.body,
|
|
471238
|
+
userPrompt,
|
|
471239
|
+
transcriptPath: transcript ? beatTranscriptRelPath(beat.id) : void 0,
|
|
471240
|
+
exists: existsSync26(outputPathAbs)
|
|
471241
|
+
};
|
|
471242
|
+
})
|
|
471243
|
+
);
|
|
471244
|
+
const skillRef = existsSync26(skillPath) ? "SKILL.md" : null;
|
|
471148
471245
|
const instructions = buildInstructions({
|
|
471149
471246
|
skillRef,
|
|
471150
471247
|
beatCount: result.length,
|
|
@@ -471192,13 +471289,14 @@ var init_compose_prompts = __esm({
|
|
|
471192
471289
|
init_compose_scenes_skills();
|
|
471193
471290
|
init_root_sync();
|
|
471194
471291
|
init_bundle();
|
|
471292
|
+
init_transcribe_narration();
|
|
471195
471293
|
}
|
|
471196
471294
|
});
|
|
471197
471295
|
|
|
471198
471296
|
// ../cli/src/commands/_shared/sub-comp-duration-sync.ts
|
|
471199
|
-
import { existsSync as
|
|
471200
|
-
import { readFile as
|
|
471201
|
-
import { join as
|
|
471297
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
471298
|
+
import { readFile as readFile13 } from "node:fs/promises";
|
|
471299
|
+
import { join as join28, resolve as resolve21 } from "node:path";
|
|
471202
471300
|
function syncSubCompositionDurationHtml(html, beatId, newDurationSec, fileRel) {
|
|
471203
471301
|
const compositionId = `scene-${beatId}`;
|
|
471204
471302
|
const file = fileRel ?? `compositions/${compositionId}.html`;
|
|
@@ -471290,15 +471388,15 @@ async function createSubCompDurationSyncPlans(opts) {
|
|
|
471290
471388
|
const results = [];
|
|
471291
471389
|
for (const beat of opts.beats) {
|
|
471292
471390
|
const fileRel = `compositions/scene-${beat.id}.html`;
|
|
471293
|
-
const filePath =
|
|
471294
|
-
if (!
|
|
471391
|
+
const filePath = join28(projectDir, fileRel);
|
|
471392
|
+
if (!existsSync28(filePath)) continue;
|
|
471295
471393
|
const newDurationSec = await resolveSyncedBeatDuration({
|
|
471296
471394
|
projectDir,
|
|
471297
471395
|
beatDuration: beat.duration,
|
|
471298
471396
|
narrationPath: beat.narrationPath,
|
|
471299
471397
|
sceneDurationSec: beat.sceneDurationSec
|
|
471300
471398
|
});
|
|
471301
|
-
const html = await
|
|
471399
|
+
const html = await readFile13(filePath, "utf-8");
|
|
471302
471400
|
const outcome = syncSubCompositionDurationHtml(html, beat.id, newDurationSec, fileRel);
|
|
471303
471401
|
results.push({ ...outcome, file: fileRel, beatId: beat.id });
|
|
471304
471402
|
}
|
|
@@ -471322,7 +471420,7 @@ var init_sub_comp_duration_sync = __esm({
|
|
|
471322
471420
|
});
|
|
471323
471421
|
|
|
471324
471422
|
// ../cli/src/commands/_shared/scene-repair.ts
|
|
471325
|
-
import { readFile as
|
|
471423
|
+
import { readFile as readFile14, writeFile as writeFile16 } from "node:fs/promises";
|
|
471326
471424
|
import { relative as relative7, resolve as resolve23 } from "node:path";
|
|
471327
471425
|
async function executeSceneRepair(opts) {
|
|
471328
471426
|
const projectDir = resolve23(opts.projectDir);
|
|
@@ -471367,7 +471465,7 @@ async function executeSceneRepair(opts) {
|
|
|
471367
471465
|
}
|
|
471368
471466
|
for (const target of targets) {
|
|
471369
471467
|
const rel = relative7(projectDir, target.abs) || target.abs;
|
|
471370
|
-
const html = await
|
|
471468
|
+
const html = await readFile14(target.abs, "utf-8");
|
|
471371
471469
|
const findings = lintHtml(html, rel, target.isSub);
|
|
471372
471470
|
const { html: nextHtml, fixedCodes } = applyMechanicalFixes(html, findings);
|
|
471373
471471
|
if (fixedCodes.length > 0) {
|
|
@@ -471740,15 +471838,15 @@ var init_storyboard_edit = __esm({
|
|
|
471740
471838
|
});
|
|
471741
471839
|
|
|
471742
471840
|
// ../cli/src/pipeline/renderers/chrome.ts
|
|
471743
|
-
import { existsSync as
|
|
471841
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
471744
471842
|
import { homedir as homedir7 } from "node:os";
|
|
471745
|
-
import { join as
|
|
471843
|
+
import { join as join29 } from "node:path";
|
|
471746
471844
|
function findChrome() {
|
|
471747
471845
|
const candidates = [
|
|
471748
471846
|
process.env.HYPERFRAMES_CHROME_PATH,
|
|
471749
471847
|
process.env.CHROME_PATH,
|
|
471750
471848
|
// puppeteer auto-downloaded headless shell
|
|
471751
|
-
|
|
471849
|
+
join29(
|
|
471752
471850
|
homedir7(),
|
|
471753
471851
|
".cache",
|
|
471754
471852
|
"puppeteer",
|
|
@@ -471766,7 +471864,7 @@ function findChrome() {
|
|
|
471766
471864
|
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
|
|
471767
471865
|
];
|
|
471768
471866
|
for (const c2 of candidates) {
|
|
471769
|
-
if (c2 &&
|
|
471867
|
+
if (c2 && existsSync30(c2)) return c2;
|
|
471770
471868
|
}
|
|
471771
471869
|
return void 0;
|
|
471772
471870
|
}
|
|
@@ -471798,7 +471896,7 @@ var init_ffmpeg_gate = __esm({
|
|
|
471798
471896
|
});
|
|
471799
471897
|
|
|
471800
471898
|
// ../cli/src/commands/_shared/scene-audio-scan.ts
|
|
471801
|
-
import { readFile as
|
|
471899
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
471802
471900
|
import { resolve as resolve25 } from "node:path";
|
|
471803
471901
|
function parseRootClips(rootHtml) {
|
|
471804
471902
|
const clips = [];
|
|
@@ -471839,7 +471937,7 @@ function makeFsCompositionReader(projectDir) {
|
|
|
471839
471937
|
return async (compositionSrcRel) => {
|
|
471840
471938
|
const abs = resolve25(projectDir, compositionSrcRel);
|
|
471841
471939
|
try {
|
|
471842
|
-
return await
|
|
471940
|
+
return await readFile16(abs, "utf-8");
|
|
471843
471941
|
} catch {
|
|
471844
471942
|
return null;
|
|
471845
471943
|
}
|
|
@@ -472039,9 +472137,9 @@ __export(scene_render_exports, {
|
|
|
472039
472137
|
qualityToCrf: () => qualityToCrf
|
|
472040
472138
|
});
|
|
472041
472139
|
import { execFile as execFile2 } from "node:child_process";
|
|
472042
|
-
import { existsSync as
|
|
472043
|
-
import { mkdir as mkdir12, readFile as
|
|
472044
|
-
import { resolve as resolve27, relative as relative9, dirname as dirname16, basename as basename7, join as
|
|
472140
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
472141
|
+
import { mkdir as mkdir12, readFile as readFile17, stat as stat3, writeFile as writeFile18 } from "node:fs/promises";
|
|
472142
|
+
import { resolve as resolve27, relative as relative9, dirname as dirname16, basename as basename7, join as join30, isAbsolute as isAbsolute3 } from "node:path";
|
|
472045
472143
|
import { promisify as promisify2 } from "node:util";
|
|
472046
472144
|
function qualityToCrf(quality = "standard") {
|
|
472047
472145
|
return quality === "draft" ? 28 : quality === "high" ? 18 : 23;
|
|
@@ -472129,7 +472227,7 @@ async function executeSceneRender(opts = {}) {
|
|
|
472129
472227
|
}
|
|
472130
472228
|
let autoSyncApplied = false;
|
|
472131
472229
|
let autoSyncWarning;
|
|
472132
|
-
if (!opts.beatId &&
|
|
472230
|
+
if (!opts.beatId && existsSync31(join30(projectDir, "STORYBOARD.md"))) {
|
|
472133
472231
|
try {
|
|
472134
472232
|
const rootPlan = await createProjectRootSyncPlan({ projectDir });
|
|
472135
472233
|
const subPlans = await createSubCompDurationSyncPlans({
|
|
@@ -472221,7 +472319,7 @@ async function executeSceneRender(opts = {}) {
|
|
|
472221
472319
|
let audioMuxWarning;
|
|
472222
472320
|
try {
|
|
472223
472321
|
opts.onProgress?.(0.95, "Mixing audio");
|
|
472224
|
-
const rootHtml = await
|
|
472322
|
+
const rootHtml = await readFile17(resolve27(projectDir, root2), "utf-8");
|
|
472225
472323
|
const audios = await scanSceneAudio({ projectDir, rootHtml });
|
|
472226
472324
|
audioCount = audios.length;
|
|
472227
472325
|
if (audios.length > 0) {
|
|
@@ -472306,11 +472404,11 @@ async function safeStat(p2) {
|
|
|
472306
472404
|
}
|
|
472307
472405
|
async function prepareBeatRenderRoot(opts) {
|
|
472308
472406
|
const root2 = `.vibeframe/tmp/render-beat-${sanitizeFileSegment(opts.beatId)}.html`;
|
|
472309
|
-
const reportPath =
|
|
472407
|
+
const reportPath = join30(opts.projectDir, "build-report.json");
|
|
472310
472408
|
const retryWith = [
|
|
472311
472409
|
`vibe build ${opts.projectDir} --beat ${opts.beatId} --stage sync --json`
|
|
472312
472410
|
];
|
|
472313
|
-
if (!
|
|
472411
|
+
if (!existsSync31(reportPath)) {
|
|
472314
472412
|
return {
|
|
472315
472413
|
success: false,
|
|
472316
472414
|
root: root2,
|
|
@@ -472321,7 +472419,7 @@ async function prepareBeatRenderRoot(opts) {
|
|
|
472321
472419
|
}
|
|
472322
472420
|
let report;
|
|
472323
472421
|
try {
|
|
472324
|
-
report = JSON.parse(await
|
|
472422
|
+
report = JSON.parse(await readFile17(reportPath, "utf-8"));
|
|
472325
472423
|
} catch (error) {
|
|
472326
472424
|
return {
|
|
472327
472425
|
success: false,
|
|
@@ -472390,8 +472488,8 @@ async function prepareBeatRenderRoot(opts) {
|
|
|
472390
472488
|
durationSec,
|
|
472391
472489
|
narrationPath
|
|
472392
472490
|
});
|
|
472393
|
-
await mkdir12(dirname16(
|
|
472394
|
-
await writeFile18(
|
|
472491
|
+
await mkdir12(dirname16(join30(opts.projectDir, root2)), { recursive: true });
|
|
472492
|
+
await writeFile18(join30(opts.projectDir, root2), html, "utf-8");
|
|
472395
472493
|
return {
|
|
472396
472494
|
success: true,
|
|
472397
472495
|
root: root2,
|
|
@@ -472455,7 +472553,7 @@ function reportedBeatAssetPaths(beat) {
|
|
|
472455
472553
|
]);
|
|
472456
472554
|
}
|
|
472457
472555
|
async function writeRenderReport(projectDir, result) {
|
|
472458
|
-
const reportPath =
|
|
472556
|
+
const reportPath = join30(projectDir, "render-report.json");
|
|
472459
472557
|
try {
|
|
472460
472558
|
await writeFile18(
|
|
472461
472559
|
reportPath,
|
|
@@ -472497,7 +472595,7 @@ async function writeRenderReport(projectDir, result) {
|
|
|
472497
472595
|
}
|
|
472498
472596
|
function pathExists3(projectDir, value) {
|
|
472499
472597
|
const abs = isAbsolute3(value) ? value : resolve27(projectDir, value);
|
|
472500
|
-
return
|
|
472598
|
+
return existsSync31(abs);
|
|
472501
472599
|
}
|
|
472502
472600
|
function stringValue2(value) {
|
|
472503
472601
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
@@ -472571,7 +472669,7 @@ var init_concurrency = __esm({
|
|
|
472571
472669
|
});
|
|
472572
472670
|
|
|
472573
472671
|
// ../cli/src/commands/_shared/build-asset-reference.ts
|
|
472574
|
-
import { existsSync as
|
|
472672
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
472575
472673
|
import { extname as extname5, isAbsolute as isAbsolute4, relative as relative10, resolve as resolve28, sep } from "node:path";
|
|
472576
472674
|
function resolveTypedAssetReference(projectDir, kind3, value) {
|
|
472577
472675
|
const raw2 = stringOrUndefined2(value);
|
|
@@ -472602,7 +472700,7 @@ function resolveReference(projectDir, kind3, raw2, source3, forcedError) {
|
|
|
472602
472700
|
const absPath = isAbsolute4(raw2) ? resolve28(raw2) : resolve28(projectDir, raw2);
|
|
472603
472701
|
const rel = relative10(resolve28(projectDir), absPath);
|
|
472604
472702
|
const withinProject = rel.length > 0 && !rel.startsWith("..") && !isAbsolute4(rel);
|
|
472605
|
-
const exists = withinProject &&
|
|
472703
|
+
const exists = withinProject && existsSync33(absPath);
|
|
472606
472704
|
let error = forcedError;
|
|
472607
472705
|
if (!error && inferred && inferred !== kind3 && !isNarrationAudioReference(kind3, ext)) {
|
|
472608
472706
|
error = `Asset reference "${raw2}" is a ${inferred} asset, not ${kind3}.`;
|
|
@@ -472789,9 +472887,9 @@ var init_build_backdrop_prompt = __esm({
|
|
|
472789
472887
|
});
|
|
472790
472888
|
|
|
472791
472889
|
// ../cli/src/commands/_shared/build-plan.ts
|
|
472792
|
-
import { existsSync as
|
|
472793
|
-
import { readFile as
|
|
472794
|
-
import { dirname as dirname17, join as
|
|
472890
|
+
import { existsSync as existsSync34 } from "node:fs";
|
|
472891
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
472892
|
+
import { dirname as dirname17, join as join31, resolve as resolve29 } from "node:path";
|
|
472795
472893
|
function backdropCostUsd(quality) {
|
|
472796
472894
|
return quality === "hd" ? 0.2 : 0.05;
|
|
472797
472895
|
}
|
|
@@ -472800,11 +472898,11 @@ async function createBuildPlan(opts) {
|
|
|
472800
472898
|
loadPlanEnv(projectDir);
|
|
472801
472899
|
const stage = opts.stage ?? "all";
|
|
472802
472900
|
const config4 = await readProjectConfig(projectDir);
|
|
472803
|
-
const storyboardPath =
|
|
472901
|
+
const storyboardPath = join31(projectDir, "STORYBOARD.md");
|
|
472804
472902
|
const warnings = [];
|
|
472805
472903
|
const retryWith = [];
|
|
472806
472904
|
const providerResolution = [];
|
|
472807
|
-
if (!
|
|
472905
|
+
if (!existsSync34(storyboardPath)) {
|
|
472808
472906
|
const validation4 = {
|
|
472809
472907
|
ok: false,
|
|
472810
472908
|
issues: [
|
|
@@ -472833,7 +472931,7 @@ async function createBuildPlan(opts) {
|
|
|
472833
472931
|
validation: validation4
|
|
472834
472932
|
});
|
|
472835
472933
|
}
|
|
472836
|
-
const storyboardMd = await
|
|
472934
|
+
const storyboardMd = await readFile18(storyboardPath, "utf-8");
|
|
472837
472935
|
const validation3 = validateStoryboardMarkdown(storyboardMd);
|
|
472838
472936
|
const validationIssues = [...validation3.issues];
|
|
472839
472937
|
const parsed = parseStoryboard(storyboardMd);
|
|
@@ -472859,7 +472957,7 @@ async function createBuildPlan(opts) {
|
|
|
472859
472957
|
const imageQuality = opts.imageQuality ?? config4.config.build.imageQuality ?? "hd";
|
|
472860
472958
|
const imageSize2 = opts.imageSize ?? config4.config.build.imageSize ?? "1536x1024";
|
|
472861
472959
|
const imageRatio = imageRatioForSize(imageSize2);
|
|
472862
|
-
const needsComposer = includeCompose && mode !== "agent" && sourceBeats.some((beat) => !
|
|
472960
|
+
const needsComposer = includeCompose && mode !== "agent" && sourceBeats.some((beat) => !existsSync34(join31(projectDir, `compositions/scene-${beat.id}.html`)));
|
|
472863
472961
|
const resolved = await resolvePlanProviders({
|
|
472864
472962
|
projectDir,
|
|
472865
472963
|
config: config4,
|
|
@@ -473007,7 +473105,7 @@ async function createBuildPlan(opts) {
|
|
|
473007
473105
|
active: includeAssets
|
|
473008
473106
|
}) : null;
|
|
473009
473107
|
const compositionPath = `compositions/scene-${beat.id}.html`;
|
|
473010
|
-
const compositionExists =
|
|
473108
|
+
const compositionExists = existsSync34(join31(projectDir, compositionPath));
|
|
473011
473109
|
for (const asset of [narration, backdrop, keyframe, video, music]) {
|
|
473012
473110
|
if (!asset) continue;
|
|
473013
473111
|
if (asset.referenceError) {
|
|
@@ -473076,7 +473174,7 @@ async function createBuildPlan(opts) {
|
|
|
473076
473174
|
}
|
|
473077
473175
|
}
|
|
473078
473176
|
const validationOk = !validationIssues.some((issue) => issue.severity === "error");
|
|
473079
|
-
if (!
|
|
473177
|
+
if (!existsSync34(join31(projectDir, config4.config.composition.entry))) {
|
|
473080
473178
|
missing.add("root-composition");
|
|
473081
473179
|
if (validationOk) retryWith.push(`vibe build ${projectDir} --stage sync --json`);
|
|
473082
473180
|
}
|
|
@@ -473110,7 +473208,7 @@ async function createBuildPlan(opts) {
|
|
|
473110
473208
|
}
|
|
473111
473209
|
if (referenced.size > 0) {
|
|
473112
473210
|
const toGenerate = resolveCharacters(parsed.frontmatter).filter(
|
|
473113
|
-
(c2) => referenced.has(c2.name) && c2.prompt && (opts.force || !
|
|
473211
|
+
(c2) => referenced.has(c2.name) && c2.prompt && (opts.force || !existsSync34(join31(projectDir, `assets/character-${c2.name}.png`)))
|
|
473114
473212
|
);
|
|
473115
473213
|
if (toGenerate.length > 0) {
|
|
473116
473214
|
estimatedCostUsd += toGenerate.length * backdropCostUsd(opts.imageQuality ?? "hd");
|
|
@@ -473223,8 +473321,8 @@ function assetPlan(opts) {
|
|
|
473223
473321
|
reason: ready ? "referenced-asset" : "invalid-reference"
|
|
473224
473322
|
};
|
|
473225
473323
|
}
|
|
473226
|
-
const canonicalExists =
|
|
473227
|
-
const cacheHit = opts.cache ?
|
|
473324
|
+
const canonicalExists = existsSync34(join31(opts.projectDir, opts.path));
|
|
473325
|
+
const cacheHit = opts.cache ? existsSync34(join31(opts.projectDir, opts.cache.path)) : false;
|
|
473228
473326
|
const freshness = assetFreshnessFromMetadata({
|
|
473229
473327
|
projectDir: opts.projectDir,
|
|
473230
473328
|
kind: opts.kind,
|
|
@@ -473422,7 +473520,7 @@ async function firstConfiguredComposer(projectDir) {
|
|
|
473422
473520
|
}
|
|
473423
473521
|
function firstExisting2(projectDir, paths) {
|
|
473424
473522
|
for (const path14 of paths) {
|
|
473425
|
-
if (
|
|
473523
|
+
if (existsSync34(join31(projectDir, path14))) return path14;
|
|
473426
473524
|
}
|
|
473427
473525
|
return null;
|
|
473428
473526
|
}
|
|
@@ -473463,12 +473561,12 @@ function unique3(items) {
|
|
|
473463
473561
|
return [...new Set(items.filter((item) => item.length > 0))];
|
|
473464
473562
|
}
|
|
473465
473563
|
function loadPlanEnv(projectDir) {
|
|
473466
|
-
(0, import_dotenv2.config)({ path:
|
|
473564
|
+
(0, import_dotenv2.config)({ path: join31(projectDir, ".env"), quiet: true });
|
|
473467
473565
|
(0, import_dotenv2.config)({ path: resolve29(process.cwd(), ".env"), quiet: true });
|
|
473468
473566
|
let dir = process.cwd();
|
|
473469
473567
|
while (dir !== dirname17(dir)) {
|
|
473470
|
-
if (
|
|
473471
|
-
(0, import_dotenv2.config)({ path:
|
|
473568
|
+
if (existsSync34(join31(dir, "pnpm-workspace.yaml"))) {
|
|
473569
|
+
(0, import_dotenv2.config)({ path: join31(dir, ".env"), quiet: true });
|
|
473472
473570
|
return;
|
|
473473
473571
|
}
|
|
473474
473572
|
dir = dirname17(dir);
|
|
@@ -473530,7 +473628,7 @@ var init_validate = __esm({
|
|
|
473530
473628
|
// ../cli/src/commands/generate/music.ts
|
|
473531
473629
|
import { resolve as resolve31 } from "node:path";
|
|
473532
473630
|
import { writeFile as writeFile19 } from "node:fs/promises";
|
|
473533
|
-
import { existsSync as
|
|
473631
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
473534
473632
|
async function executeMusic(options) {
|
|
473535
473633
|
try {
|
|
473536
473634
|
const provider = options.provider || "elevenlabs";
|
|
@@ -473683,7 +473781,7 @@ function registerMusicCommand(parent) {
|
|
|
473683
473781
|
if (options.melody) {
|
|
473684
473782
|
spinner2.text = "Uploading melody reference...";
|
|
473685
473783
|
const absPath = resolve31(process.cwd(), options.melody);
|
|
473686
|
-
if (!
|
|
473784
|
+
if (!existsSync35(absPath)) {
|
|
473687
473785
|
spinner2.fail(`Melody file not found: ${options.melody}`);
|
|
473688
473786
|
exitWithError(notFoundError(options.melody));
|
|
473689
473787
|
}
|
|
@@ -473816,9 +473914,9 @@ __export(scene_build_exports, {
|
|
|
473816
473914
|
executeSceneBuild: () => executeSceneBuild,
|
|
473817
473915
|
resolveSceneBuildMode: () => resolveSceneBuildMode
|
|
473818
473916
|
});
|
|
473819
|
-
import { existsSync as
|
|
473820
|
-
import { copyFile as copyFile4, mkdir as mkdir13, readFile as
|
|
473821
|
-
import { dirname as dirname18, join as
|
|
473917
|
+
import { existsSync as existsSync36, readFileSync as readFileSync12 } from "node:fs";
|
|
473918
|
+
import { copyFile as copyFile4, mkdir as mkdir13, readFile as readFile19, rm as rm3, writeFile as writeFile20 } from "node:fs/promises";
|
|
473919
|
+
import { dirname as dirname18, join as join33, resolve as resolve33 } from "node:path";
|
|
473822
473920
|
async function executeSceneBuild(opts) {
|
|
473823
473921
|
const startedAt = Date.now();
|
|
473824
473922
|
const projectDir = resolve33(opts.projectDir);
|
|
@@ -473837,7 +473935,7 @@ async function executeSceneBuild(opts) {
|
|
|
473837
473935
|
);
|
|
473838
473936
|
}
|
|
473839
473937
|
let sceneRepair = skippedSceneRepairSummary();
|
|
473840
|
-
const storyboardPath =
|
|
473938
|
+
const storyboardPath = join33(projectDir, "STORYBOARD.md");
|
|
473841
473939
|
const buildPlan = await createBuildPlan({
|
|
473842
473940
|
projectDir,
|
|
473843
473941
|
stage: selectedStage,
|
|
@@ -473888,8 +473986,8 @@ async function executeSceneBuild(opts) {
|
|
|
473888
473986
|
}
|
|
473889
473987
|
if (!buildPlan.validation.ok) {
|
|
473890
473988
|
let invalidBeats = [];
|
|
473891
|
-
if (
|
|
473892
|
-
invalidBeats = parseStoryboard(await
|
|
473989
|
+
if (existsSync36(storyboardPath)) {
|
|
473990
|
+
invalidBeats = parseStoryboard(await readFile19(storyboardPath, "utf-8")).beats;
|
|
473893
473991
|
}
|
|
473894
473992
|
return finishBuildResult({
|
|
473895
473993
|
success: false,
|
|
@@ -473913,7 +474011,7 @@ async function executeSceneBuild(opts) {
|
|
|
473913
474011
|
totalLatencyMs: Date.now() - startedAt
|
|
473914
474012
|
});
|
|
473915
474013
|
}
|
|
473916
|
-
if (!
|
|
474014
|
+
if (!existsSync36(storyboardPath)) {
|
|
473917
474015
|
return finishBuildResult({
|
|
473918
474016
|
success: false,
|
|
473919
474017
|
phase: "failed",
|
|
@@ -473927,7 +474025,7 @@ async function executeSceneBuild(opts) {
|
|
|
473927
474025
|
totalLatencyMs: Date.now() - startedAt
|
|
473928
474026
|
});
|
|
473929
474027
|
}
|
|
473930
|
-
const storyboardMd = await
|
|
474028
|
+
const storyboardMd = await readFile19(storyboardPath, "utf-8");
|
|
473931
474029
|
const parsed = parseStoryboard(storyboardMd);
|
|
473932
474030
|
if (parsed.beats.length === 0) {
|
|
473933
474031
|
return finishBuildResult({
|
|
@@ -474034,6 +474132,7 @@ async function executeSceneBuild(opts) {
|
|
|
474034
474132
|
skipVideo: opts.skipVideo ?? false,
|
|
474035
474133
|
skipKeyframe: opts.skipKeyframe ?? false,
|
|
474036
474134
|
skipMusic: opts.skipMusic ?? false,
|
|
474135
|
+
skipTranscript: opts.skipTranscript ?? false,
|
|
474037
474136
|
force: opts.force ?? false,
|
|
474038
474137
|
onProgress,
|
|
474039
474138
|
characterPaths
|
|
@@ -474121,9 +474220,9 @@ async function executeSceneBuild(opts) {
|
|
|
474121
474220
|
let composeData;
|
|
474122
474221
|
if (shouldRunStage(selectedStage, "compose")) {
|
|
474123
474222
|
if (mode === "agent") {
|
|
474124
|
-
const compositionsDir =
|
|
474223
|
+
const compositionsDir = join33(projectDir, "compositions");
|
|
474125
474224
|
const missingBeats = activeBeats.filter(
|
|
474126
|
-
(b2) => !
|
|
474225
|
+
(b2) => !existsSync36(join33(compositionsDir, `scene-${b2.id}.html`))
|
|
474127
474226
|
);
|
|
474128
474227
|
if (missingBeats.length > 0) {
|
|
474129
474228
|
const plan = await getComposePrompts({ projectDir, beatId: opts.beatId });
|
|
@@ -474212,8 +474311,8 @@ async function executeSceneBuild(opts) {
|
|
|
474212
474311
|
if (stageReports.compose.status === "done") {
|
|
474213
474312
|
for (const beat of activeBeats) {
|
|
474214
474313
|
const videoRel = `assets/video-${beat.id}.mp4`;
|
|
474215
|
-
const compositionAbs =
|
|
474216
|
-
if (!
|
|
474314
|
+
const compositionAbs = join33(projectDir, "compositions", `scene-${beat.id}.html`);
|
|
474315
|
+
if (!existsSync36(join33(projectDir, videoRel)) || !existsSync36(compositionAbs)) continue;
|
|
474217
474316
|
const html = readFileSync12(compositionAbs, "utf-8");
|
|
474218
474317
|
if (!html.includes(videoRel)) {
|
|
474219
474318
|
warnings.push(
|
|
@@ -474271,7 +474370,7 @@ async function executeSceneBuild(opts) {
|
|
|
474271
474370
|
});
|
|
474272
474371
|
}
|
|
474273
474372
|
if (shouldRunStage(selectedStage, "sync")) {
|
|
474274
|
-
if (!
|
|
474373
|
+
if (!existsSync36(join33(projectDir, "index.html"))) {
|
|
474275
474374
|
await scaffoldSceneProject({
|
|
474276
474375
|
dir: projectDir,
|
|
474277
474376
|
name: projectDir.split(/[\\/]/).filter(Boolean).pop(),
|
|
@@ -474416,6 +474515,9 @@ async function buildBeatPrimitives(beat, ctx) {
|
|
|
474416
474515
|
ctx.skipVideo ? skipped("video", beat.id, "--skip-video", ctx) : dispatchVideo(beat, ctx, keyframe),
|
|
474417
474516
|
ctx.skipMusic ? skipped("music", beat.id, "--skip-music", ctx) : dispatchMusic(beat, ctx)
|
|
474418
474517
|
]);
|
|
474518
|
+
if (!ctx.skipTranscript) {
|
|
474519
|
+
await dispatchTranscript(beat, narration, ctx);
|
|
474520
|
+
}
|
|
474419
474521
|
return {
|
|
474420
474522
|
outcome: {
|
|
474421
474523
|
beatId: beat.id,
|
|
@@ -474533,7 +474635,7 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474533
474635
|
return {
|
|
474534
474636
|
status: "cached",
|
|
474535
474637
|
path: existingRel,
|
|
474536
|
-
durationSec: await safeAudioDuration(
|
|
474638
|
+
durationSec: await safeAudioDuration(join33(ctx.projectDir, existingRel)),
|
|
474537
474639
|
provider: metadata?.provider,
|
|
474538
474640
|
cachePath: metadata?.cachePath,
|
|
474539
474641
|
cacheKey: metadata?.cacheKey,
|
|
@@ -474557,9 +474659,9 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474557
474659
|
voice,
|
|
474558
474660
|
ext: resolution.audioExtension
|
|
474559
474661
|
});
|
|
474560
|
-
const cacheAbs =
|
|
474662
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
474561
474663
|
const rel = `assets/narration-${beat.id}.${resolution.audioExtension}`;
|
|
474562
|
-
const abs =
|
|
474664
|
+
const abs = join33(ctx.projectDir, rel);
|
|
474563
474665
|
if (existingRel && !ctx.force && isFreshCanonicalAsset({
|
|
474564
474666
|
projectDir: ctx.projectDir,
|
|
474565
474667
|
kind: "narration",
|
|
@@ -474573,7 +474675,7 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474573
474675
|
return {
|
|
474574
474676
|
status: "cached",
|
|
474575
474677
|
path: existingRel,
|
|
474576
|
-
durationSec: await safeAudioDuration(
|
|
474678
|
+
durationSec: await safeAudioDuration(join33(ctx.projectDir, existingRel)),
|
|
474577
474679
|
provider: resolution.provider,
|
|
474578
474680
|
cachePath: cache.path,
|
|
474579
474681
|
cacheKey: cache.key,
|
|
@@ -474581,7 +474683,7 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474581
474683
|
freshness: "fresh"
|
|
474582
474684
|
};
|
|
474583
474685
|
}
|
|
474584
|
-
if (
|
|
474686
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
474585
474687
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474586
474688
|
await copyFile4(cacheAbs, abs);
|
|
474587
474689
|
await writeAssetMetadata({
|
|
@@ -474616,8 +474718,8 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474616
474718
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474617
474719
|
await writeFile20(abs, result.audioBuffer);
|
|
474618
474720
|
for (const otherExt of ["mp3", "wav"]) {
|
|
474619
|
-
const sibling =
|
|
474620
|
-
if (sibling !== abs &&
|
|
474721
|
+
const sibling = join33(ctx.projectDir, `assets/narration-${beat.id}.${otherExt}`);
|
|
474722
|
+
if (sibling !== abs && existsSync36(sibling)) await rm3(sibling, { force: true });
|
|
474621
474723
|
}
|
|
474622
474724
|
await mkdir13(dirname18(cacheAbs), { recursive: true });
|
|
474623
474725
|
await writeFile20(cacheAbs, result.audioBuffer);
|
|
@@ -474649,6 +474751,42 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474649
474751
|
freshness: "fresh"
|
|
474650
474752
|
};
|
|
474651
474753
|
}
|
|
474754
|
+
async function dispatchTranscript(beat, narration, ctx) {
|
|
474755
|
+
if (!narration.path) return;
|
|
474756
|
+
const relPath = beatTranscriptRelPath(beat.id);
|
|
474757
|
+
const abs = join33(ctx.projectDir, relPath);
|
|
474758
|
+
const narrationFresh = narration.status === "generated";
|
|
474759
|
+
if (existsSync36(abs) && !ctx.force && !narrationFresh) {
|
|
474760
|
+
ctx.onProgress({ type: "transcript-cached", beatId: beat.id, path: relPath });
|
|
474761
|
+
return;
|
|
474762
|
+
}
|
|
474763
|
+
const apiKey = await getConfiguredApiKey("OPENAI_API_KEY", void 0, { cwd: ctx.projectDir });
|
|
474764
|
+
if (!apiKey) {
|
|
474765
|
+
ctx.onProgress({
|
|
474766
|
+
type: "transcript-skipped",
|
|
474767
|
+
beatId: beat.id,
|
|
474768
|
+
reason: "OPENAI_API_KEY not set \u2014 narration plays but word-sync timings unavailable"
|
|
474769
|
+
});
|
|
474770
|
+
return;
|
|
474771
|
+
}
|
|
474772
|
+
const words = await transcribeNarrationWords(join33(ctx.projectDir, narration.path), { apiKey });
|
|
474773
|
+
if (words.length === 0) {
|
|
474774
|
+
ctx.onProgress({
|
|
474775
|
+
type: "transcript-skipped",
|
|
474776
|
+
beatId: beat.id,
|
|
474777
|
+
reason: "transcription returned no word timings"
|
|
474778
|
+
});
|
|
474779
|
+
return;
|
|
474780
|
+
}
|
|
474781
|
+
await mkdir13(dirname18(abs), { recursive: true });
|
|
474782
|
+
await writeFile20(abs, JSON.stringify(words, null, 2), "utf-8");
|
|
474783
|
+
ctx.onProgress({
|
|
474784
|
+
type: "transcript-generated",
|
|
474785
|
+
beatId: beat.id,
|
|
474786
|
+
path: relPath,
|
|
474787
|
+
wordCount: words.length
|
|
474788
|
+
});
|
|
474789
|
+
}
|
|
474652
474790
|
function characterSheetPrompt(name, description) {
|
|
474653
474791
|
return [
|
|
474654
474792
|
`Character reference sheet of an original fictional character named ${name}: ${description}.`,
|
|
@@ -474666,7 +474804,7 @@ async function buildCharacters(characters, ctx) {
|
|
|
474666
474804
|
const size = ctx.imageSize ?? "1536x1024";
|
|
474667
474805
|
for (const character of characters) {
|
|
474668
474806
|
if (character.imagePath) {
|
|
474669
|
-
if (
|
|
474807
|
+
if (existsSync36(join33(ctx.projectDir, character.imagePath))) {
|
|
474670
474808
|
paths.set(character.name, character.imagePath);
|
|
474671
474809
|
ctx.onProgress({ type: "character-cached", name: character.name, path: character.imagePath });
|
|
474672
474810
|
} else {
|
|
@@ -474679,7 +474817,7 @@ async function buildCharacters(characters, ctx) {
|
|
|
474679
474817
|
if (!character.prompt) continue;
|
|
474680
474818
|
const prompt3 = characterSheetPrompt(character.name, character.prompt);
|
|
474681
474819
|
const rel = `assets/character-${character.name}.png`;
|
|
474682
|
-
const abs =
|
|
474820
|
+
const abs = join33(ctx.projectDir, rel);
|
|
474683
474821
|
const metadataOptions = { quality: ctx.imageQuality, size };
|
|
474684
474822
|
const cache = characterCacheDescriptor({
|
|
474685
474823
|
name: character.name,
|
|
@@ -474688,7 +474826,7 @@ async function buildCharacters(characters, ctx) {
|
|
|
474688
474826
|
quality: ctx.imageQuality,
|
|
474689
474827
|
size
|
|
474690
474828
|
});
|
|
474691
|
-
if (
|
|
474829
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
474692
474830
|
const metadata = readAssetMetadata(ctx.projectDir, "character", character.name);
|
|
474693
474831
|
if (!metadata || isFreshCanonicalAsset({
|
|
474694
474832
|
projectDir: ctx.projectDir,
|
|
@@ -474704,8 +474842,8 @@ async function buildCharacters(characters, ctx) {
|
|
|
474704
474842
|
continue;
|
|
474705
474843
|
}
|
|
474706
474844
|
}
|
|
474707
|
-
const cacheAbs =
|
|
474708
|
-
if (
|
|
474845
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
474846
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
474709
474847
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474710
474848
|
await copyFile4(cacheAbs, abs);
|
|
474711
474849
|
await writeAssetMetadata({
|
|
@@ -474771,7 +474909,7 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
474771
474909
|
if (!cue) return { status: "no-cue" };
|
|
474772
474910
|
const prompt3 = augmentBackdropPrompt(cue);
|
|
474773
474911
|
const rel = `assets/backdrop-${beat.id}.png`;
|
|
474774
|
-
const abs =
|
|
474912
|
+
const abs = join33(ctx.projectDir, rel);
|
|
474775
474913
|
const size = ctx.imageSize ?? "1536x1024";
|
|
474776
474914
|
const ratio = imageRatioForSize(size);
|
|
474777
474915
|
const metadataOptions = { quality: ctx.imageQuality, size, ratio };
|
|
@@ -474784,7 +474922,7 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
474784
474922
|
ratio
|
|
474785
474923
|
});
|
|
474786
474924
|
const metadataPath = assetMetadataPath("backdrop", beat.id);
|
|
474787
|
-
if (
|
|
474925
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
474788
474926
|
const metadata = readAssetMetadata(ctx.projectDir, "backdrop", beat.id);
|
|
474789
474927
|
if (!metadata || isFreshCanonicalAsset({
|
|
474790
474928
|
projectDir: ctx.projectDir,
|
|
@@ -474807,8 +474945,8 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
474807
474945
|
};
|
|
474808
474946
|
}
|
|
474809
474947
|
}
|
|
474810
|
-
const cacheAbs =
|
|
474811
|
-
if (
|
|
474948
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
474949
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
474812
474950
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474813
474951
|
await copyFile4(cacheAbs, abs);
|
|
474814
474952
|
await writeAssetMetadata({
|
|
@@ -474940,7 +475078,7 @@ async function editKeyframeImage(prompt3, sheetBuffers, ctx, ratio) {
|
|
|
474940
475078
|
}
|
|
474941
475079
|
async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
474942
475080
|
const rel = `assets/keyframe-${beat.id}.png`;
|
|
474943
|
-
const abs =
|
|
475081
|
+
const abs = join33(ctx.projectDir, rel);
|
|
474944
475082
|
const size = ctx.imageSize ?? "1536x1024";
|
|
474945
475083
|
const ratio = imageRatioForSize(size);
|
|
474946
475084
|
const metadataOptions = { quality: ctx.imageQuality, size, ratio };
|
|
@@ -474953,7 +475091,7 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
|
474953
475091
|
ratio,
|
|
474954
475092
|
characters: characterRefsRel
|
|
474955
475093
|
});
|
|
474956
|
-
if (
|
|
475094
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
474957
475095
|
const metadata = readAssetMetadata(ctx.projectDir, "keyframe", beat.id);
|
|
474958
475096
|
if (!metadata || isFreshCanonicalAsset({
|
|
474959
475097
|
projectDir: ctx.projectDir,
|
|
@@ -474967,8 +475105,8 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
|
474967
475105
|
return { status: "cached", rel };
|
|
474968
475106
|
}
|
|
474969
475107
|
}
|
|
474970
|
-
const cacheAbs =
|
|
474971
|
-
if (
|
|
475108
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
475109
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
474972
475110
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474973
475111
|
await copyFile4(cacheAbs, abs);
|
|
474974
475112
|
await writeAssetMetadata({
|
|
@@ -474986,8 +475124,8 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
|
474986
475124
|
}
|
|
474987
475125
|
const sheetBuffers = [];
|
|
474988
475126
|
for (const relPath of characterRefsRel) {
|
|
474989
|
-
const sheetAbs =
|
|
474990
|
-
if (
|
|
475127
|
+
const sheetAbs = join33(ctx.projectDir, relPath);
|
|
475128
|
+
if (existsSync36(sheetAbs)) sheetBuffers.push(await readFile19(sheetAbs));
|
|
474991
475129
|
}
|
|
474992
475130
|
const imgCtx = {
|
|
474993
475131
|
projectDir: ctx.projectDir,
|
|
@@ -475056,9 +475194,9 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475056
475194
|
const prompt3 = stringOrUndefined4(beat.cues?.video) ?? keyframeCue;
|
|
475057
475195
|
if (!prompt3) return { status: "no-cue" };
|
|
475058
475196
|
const characterRefsRel = beatCharacterNames(beat.cues).map((name) => ctx.characterPaths?.get(name)).filter((p2) => typeof p2 === "string");
|
|
475059
|
-
const characterRefsAbs = characterRefsRel.map((p2) =>
|
|
475197
|
+
const characterRefsAbs = characterRefsRel.map((p2) => join33(ctx.projectDir, p2));
|
|
475060
475198
|
const rel = `assets/video-${beat.id}.mp4`;
|
|
475061
|
-
const abs =
|
|
475199
|
+
const abs = join33(ctx.projectDir, rel);
|
|
475062
475200
|
const cache = videoCacheDescriptor({
|
|
475063
475201
|
beatId: beat.id,
|
|
475064
475202
|
cue: prompt3,
|
|
@@ -475070,7 +475208,7 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475070
475208
|
keyframe: keyframeCue
|
|
475071
475209
|
});
|
|
475072
475210
|
const metadataPath = assetMetadataPath("video", beat.id);
|
|
475073
|
-
if (
|
|
475211
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
475074
475212
|
const metadata = readAssetMetadata(ctx.projectDir, "video", beat.id);
|
|
475075
475213
|
if (!metadata || isFreshCanonicalAsset({
|
|
475076
475214
|
projectDir: ctx.projectDir,
|
|
@@ -475093,8 +475231,8 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475093
475231
|
};
|
|
475094
475232
|
}
|
|
475095
475233
|
}
|
|
475096
|
-
const cacheAbs =
|
|
475097
|
-
if (
|
|
475234
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
475235
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
475098
475236
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
475099
475237
|
await copyFile4(cacheAbs, abs);
|
|
475100
475238
|
await writeAssetMetadata({
|
|
@@ -475125,7 +475263,7 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475125
475263
|
ctx.onProgress({ type: "video-skipped", beatId: beat.id, reason });
|
|
475126
475264
|
return { status: "skipped" };
|
|
475127
475265
|
}
|
|
475128
|
-
const keyframeImageAbs = keyframeImageRel ?
|
|
475266
|
+
const keyframeImageAbs = keyframeImageRel ? join33(ctx.projectDir, keyframeImageRel) : void 0;
|
|
475129
475267
|
loadSceneBuildEnv(ctx.projectDir);
|
|
475130
475268
|
const result = await executeVideoGenerate({
|
|
475131
475269
|
prompt: prompt3,
|
|
@@ -475149,7 +475287,7 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475149
475287
|
ctx.onProgress({ type: "video-failed", beatId: beat.id, error });
|
|
475150
475288
|
return { status: "failed", error };
|
|
475151
475289
|
}
|
|
475152
|
-
if (result.status === "completed" &&
|
|
475290
|
+
if (result.status === "completed" && existsSync36(abs)) {
|
|
475153
475291
|
await mkdir13(dirname18(cacheAbs), { recursive: true });
|
|
475154
475292
|
await copyFile4(abs, cacheAbs);
|
|
475155
475293
|
await writeAssetMetadata({
|
|
@@ -475217,7 +475355,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475217
475355
|
const prompt3 = stringOrUndefined4(beat.cues?.music);
|
|
475218
475356
|
if (!prompt3) return { status: "no-cue" };
|
|
475219
475357
|
const rel = `assets/music-${beat.id}.mp3`;
|
|
475220
|
-
const abs =
|
|
475358
|
+
const abs = join33(ctx.projectDir, rel);
|
|
475221
475359
|
const duration = normalizeMusicDuration(beat.duration);
|
|
475222
475360
|
const cache = musicCacheDescriptor({
|
|
475223
475361
|
beatId: beat.id,
|
|
@@ -475226,7 +475364,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475226
475364
|
duration
|
|
475227
475365
|
});
|
|
475228
475366
|
const metadataPath = assetMetadataPath("music", beat.id);
|
|
475229
|
-
if (
|
|
475367
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
475230
475368
|
const metadata = readAssetMetadata(ctx.projectDir, "music", beat.id);
|
|
475231
475369
|
if (!metadata || isFreshCanonicalAsset({
|
|
475232
475370
|
projectDir: ctx.projectDir,
|
|
@@ -475250,8 +475388,8 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475250
475388
|
};
|
|
475251
475389
|
}
|
|
475252
475390
|
}
|
|
475253
|
-
const cacheAbs =
|
|
475254
|
-
if (
|
|
475391
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
475392
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
475255
475393
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
475256
475394
|
await copyFile4(cacheAbs, abs);
|
|
475257
475395
|
await writeAssetMetadata({
|
|
@@ -475325,7 +475463,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475325
475463
|
metadataPath
|
|
475326
475464
|
};
|
|
475327
475465
|
}
|
|
475328
|
-
if (!
|
|
475466
|
+
if (!existsSync36(abs)) {
|
|
475329
475467
|
const error = result.outputPath ? `music output was not written at ${abs}` : "music generation did not return an output file";
|
|
475330
475468
|
ctx.onProgress({ type: "music-failed", beatId: beat.id, error });
|
|
475331
475469
|
return { status: "failed", error };
|
|
@@ -475361,12 +475499,12 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475361
475499
|
};
|
|
475362
475500
|
}
|
|
475363
475501
|
function loadSceneBuildEnv(projectDir) {
|
|
475364
|
-
(0, import_dotenv3.config)({ path:
|
|
475502
|
+
(0, import_dotenv3.config)({ path: join33(projectDir, ".env"), quiet: true });
|
|
475365
475503
|
(0, import_dotenv3.config)({ path: resolve33(process.cwd(), ".env"), quiet: true });
|
|
475366
475504
|
let dir = process.cwd();
|
|
475367
475505
|
while (dir !== dirname18(dir)) {
|
|
475368
|
-
if (
|
|
475369
|
-
(0, import_dotenv3.config)({ path:
|
|
475506
|
+
if (existsSync36(join33(dir, "pnpm-workspace.yaml"))) {
|
|
475507
|
+
(0, import_dotenv3.config)({ path: join33(dir, ".env"), quiet: true });
|
|
475370
475508
|
return;
|
|
475371
475509
|
}
|
|
475372
475510
|
dir = dirname18(dir);
|
|
@@ -475582,7 +475720,7 @@ function mergeBeatOutcomes(base, updates) {
|
|
|
475582
475720
|
}
|
|
475583
475721
|
function firstExisting3(projectDir, relPaths) {
|
|
475584
475722
|
for (const rel of relPaths) {
|
|
475585
|
-
if (
|
|
475723
|
+
if (existsSync36(join33(projectDir, rel))) return rel;
|
|
475586
475724
|
}
|
|
475587
475725
|
return null;
|
|
475588
475726
|
}
|
|
@@ -475613,7 +475751,7 @@ async function apiKeyForVideoProvider(provider, projectDir) {
|
|
|
475613
475751
|
return getApiKeyFromConfig(providerKey, { cwd: projectDir });
|
|
475614
475752
|
}
|
|
475615
475753
|
async function finalizeBuildResult(projectDir, startedAt, result) {
|
|
475616
|
-
const reportPath =
|
|
475754
|
+
const reportPath = join33(projectDir, "build-report.json");
|
|
475617
475755
|
if (result.stageReports) {
|
|
475618
475756
|
for (const report of Object.values(result.stageReports)) {
|
|
475619
475757
|
if (report.status === "pending") report.status = "skipped";
|
|
@@ -475772,7 +475910,7 @@ function normalizeReportDuration(value) {
|
|
|
475772
475910
|
}
|
|
475773
475911
|
function buildReportComposition(projectDir, result, beatId) {
|
|
475774
475912
|
const path14 = `compositions/scene-${beatId}.html`;
|
|
475775
|
-
const exists =
|
|
475913
|
+
const exists = existsSync36(join33(projectDir, path14));
|
|
475776
475914
|
const written = composeWrittenEntry(result, beatId);
|
|
475777
475915
|
if (written) {
|
|
475778
475916
|
return {
|
|
@@ -475829,8 +475967,8 @@ function summarizeBuildBeats(projectDir, beats) {
|
|
|
475829
475967
|
let compositionsReady = 0;
|
|
475830
475968
|
for (const beat of beats) {
|
|
475831
475969
|
if (beatAssetsReady(beat)) assetsReady += 1;
|
|
475832
|
-
const compositionPath =
|
|
475833
|
-
if (
|
|
475970
|
+
const compositionPath = join33(projectDir, "compositions", `scene-${beat.beatId}.html`);
|
|
475971
|
+
if (existsSync36(compositionPath)) {
|
|
475834
475972
|
compositionsReady += 1;
|
|
475835
475973
|
} else {
|
|
475836
475974
|
needsAuthor.push(beat.beatId);
|
|
@@ -475872,6 +476010,8 @@ var init_scene_build = __esm({
|
|
|
475872
476010
|
init_compose_scenes_skills();
|
|
475873
476011
|
init_compose_prompts();
|
|
475874
476012
|
init_config();
|
|
476013
|
+
init_api_key();
|
|
476014
|
+
init_transcribe_narration();
|
|
475875
476015
|
init_scene_render();
|
|
475876
476016
|
init_storyboard_parse();
|
|
475877
476017
|
init_scene_project();
|
|
@@ -476000,18 +476140,18 @@ __export(ai_audio_exports, {
|
|
|
476000
476140
|
executeVoiceClone: () => executeVoiceClone
|
|
476001
476141
|
});
|
|
476002
476142
|
import { resolve as resolve35, dirname as dirname19, basename as basename8, extname as extname6 } from "node:path";
|
|
476003
|
-
import { readFile as
|
|
476004
|
-
import { existsSync as
|
|
476143
|
+
import { readFile as readFile20, writeFile as writeFile21 } from "node:fs/promises";
|
|
476144
|
+
import { existsSync as existsSync37 } from "node:fs";
|
|
476005
476145
|
async function executeTranscribe(options) {
|
|
476006
476146
|
const { audioPath, language, output: output3, format: format4, apiKey } = options;
|
|
476007
476147
|
try {
|
|
476008
476148
|
const key2 = apiKey || process.env.OPENAI_API_KEY;
|
|
476009
476149
|
if (!key2) return { success: false, error: "OPENAI_API_KEY required" };
|
|
476010
476150
|
const absPath = resolve35(process.cwd(), audioPath);
|
|
476011
|
-
if (!
|
|
476151
|
+
if (!existsSync37(absPath)) return { success: false, error: `File not found: ${absPath}` };
|
|
476012
476152
|
const whisper = new WhisperProvider();
|
|
476013
476153
|
await whisper.initialize({ apiKey: key2 });
|
|
476014
|
-
const audioBuffer = await
|
|
476154
|
+
const audioBuffer = await readFile20(absPath);
|
|
476015
476155
|
const audioBlob = new Blob([audioBuffer]);
|
|
476016
476156
|
const result = await whisper.transcribe(audioBlob, language);
|
|
476017
476157
|
if (result.status === "failed") {
|
|
@@ -476041,8 +476181,8 @@ async function executeIsolate(options) {
|
|
|
476041
476181
|
const key2 = apiKey || process.env.ELEVENLABS_API_KEY;
|
|
476042
476182
|
if (!key2) return { success: false, error: "ELEVENLABS_API_KEY required" };
|
|
476043
476183
|
const absPath = resolve35(process.cwd(), audioPath);
|
|
476044
|
-
if (!
|
|
476045
|
-
const audioBuffer = await
|
|
476184
|
+
if (!existsSync37(absPath)) return { success: false, error: `File not found: ${absPath}` };
|
|
476185
|
+
const audioBuffer = await readFile20(absPath);
|
|
476046
476186
|
const elevenlabs = new ElevenLabsProvider();
|
|
476047
476187
|
await elevenlabs.initialize({ apiKey: key2 });
|
|
476048
476188
|
const result = await elevenlabs.isolateVocals(audioBuffer);
|
|
@@ -476067,8 +476207,8 @@ async function executeVoiceClone(options) {
|
|
|
476067
476207
|
const audioBuffers = [];
|
|
476068
476208
|
for (const samplePath of samplePaths) {
|
|
476069
476209
|
const absPath = resolve35(process.cwd(), samplePath);
|
|
476070
|
-
if (!
|
|
476071
|
-
const buffer = await
|
|
476210
|
+
if (!existsSync37(absPath)) return { success: false, error: `File not found: ${samplePath}` };
|
|
476211
|
+
const buffer = await readFile20(absPath);
|
|
476072
476212
|
audioBuffers.push(buffer);
|
|
476073
476213
|
}
|
|
476074
476214
|
const elevenlabs = new ElevenLabsProvider();
|
|
@@ -476089,7 +476229,7 @@ async function executeDub(options) {
|
|
|
476089
476229
|
const { mediaPath, language, source: source3, voice, analyzeOnly, output: output3 } = options;
|
|
476090
476230
|
try {
|
|
476091
476231
|
const absPath = resolve35(process.cwd(), mediaPath);
|
|
476092
|
-
if (!
|
|
476232
|
+
if (!existsSync37(absPath)) return { success: false, error: `File not found: ${absPath}` };
|
|
476093
476233
|
const openaiKey = process.env.OPENAI_API_KEY;
|
|
476094
476234
|
const anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
476095
476235
|
const elevenlabsKey = process.env.ELEVENLABS_API_KEY;
|
|
@@ -476106,7 +476246,7 @@ async function executeDub(options) {
|
|
|
476106
476246
|
}
|
|
476107
476247
|
const whisper = new WhisperProvider();
|
|
476108
476248
|
await whisper.initialize({ apiKey: openaiKey });
|
|
476109
|
-
const audioBuffer = await
|
|
476249
|
+
const audioBuffer = await readFile20(audioPath);
|
|
476110
476250
|
const audioBlob = new Blob([audioBuffer]);
|
|
476111
476251
|
const transcriptResult = await whisper.transcribe(audioBlob, source3);
|
|
476112
476252
|
if (transcriptResult.status === "failed" || !transcriptResult.segments) {
|
|
@@ -476217,8 +476357,8 @@ async function executeDuck(options) {
|
|
|
476217
476357
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
476218
476358
|
const absMusicPath = resolve35(process.cwd(), musicPath);
|
|
476219
476359
|
const absVoicePath = resolve35(process.cwd(), voicePath);
|
|
476220
|
-
if (!
|
|
476221
|
-
if (!
|
|
476360
|
+
if (!existsSync37(absMusicPath)) return { success: false, error: `Music file not found: ${absMusicPath}` };
|
|
476361
|
+
if (!existsSync37(absVoicePath)) return { success: false, error: `Voice file not found: ${absVoicePath}` };
|
|
476222
476362
|
const defaultOutput = resolve35(dirname19(absMusicPath), `${basename8(absMusicPath, extname6(absMusicPath))}-ducked${extname6(absMusicPath)}`);
|
|
476223
476363
|
const outputPath = resolve35(process.cwd(), output3 || defaultOutput);
|
|
476224
476364
|
const filter4 = `[1:a]asplit=2[sc][mix];[0:a][sc]sidechaincompress=threshold=${threshold}dB:ratio=${ratio}:attack=${attack}:release=${release}[ducked];[ducked][mix]amix=inputs=2:duration=longest`;
|
|
@@ -476232,7 +476372,7 @@ async function executeDuck(options) {
|
|
|
476232
476372
|
"-y",
|
|
476233
476373
|
outputPath
|
|
476234
476374
|
], { timeout: 12e4, maxBuffer: 50 * 1024 * 1024 });
|
|
476235
|
-
if (!
|
|
476375
|
+
if (!existsSync37(outputPath)) return { success: false, error: "FFmpeg failed to create output" };
|
|
476236
476376
|
return { success: true, outputPath };
|
|
476237
476377
|
} catch (error) {
|
|
476238
476378
|
return { success: false, error: `Audio ducking failed: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -476248,8 +476388,8 @@ var init_ai_audio = __esm({
|
|
|
476248
476388
|
});
|
|
476249
476389
|
|
|
476250
476390
|
// ../cli/src/commands/_shared/edit/silence-cut.ts
|
|
476251
|
-
import { existsSync as
|
|
476252
|
-
import { readFile as
|
|
476391
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
476392
|
+
import { readFile as readFile21 } from "node:fs/promises";
|
|
476253
476393
|
async function detectSilencePeriods(videoPath, noiseThreshold, minDuration) {
|
|
476254
476394
|
const totalDuration = await getVideoDuration(videoPath);
|
|
476255
476395
|
const { stdout, stderr } = await execSafe(
|
|
@@ -476299,7 +476439,7 @@ async function detectSilencePeriodsWithGemini(videoPath, minDuration, options) {
|
|
|
476299
476439
|
}
|
|
476300
476440
|
const gemini = new GeminiProvider();
|
|
476301
476441
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
476302
|
-
const videoBuffer = await
|
|
476442
|
+
const videoBuffer = await readFile21(videoPath);
|
|
476303
476443
|
const modelId = options.model ? resolveGeminiTextModel(options.model) : void 0;
|
|
476304
476444
|
const prompt3 = `Analyze this video and identify all silent or dead segments where there is NO meaningful content.
|
|
476305
476445
|
|
|
@@ -476375,7 +476515,7 @@ async function executeSilenceCut(options) {
|
|
|
476375
476515
|
analyzeOnly = false,
|
|
476376
476516
|
useGemini = false
|
|
476377
476517
|
} = options;
|
|
476378
|
-
if (!
|
|
476518
|
+
if (!existsSync38(videoPath)) {
|
|
476379
476519
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
476380
476520
|
}
|
|
476381
476521
|
if (!commandExists("ffmpeg")) {
|
|
@@ -476483,11 +476623,11 @@ var init_silence_cut = __esm({
|
|
|
476483
476623
|
});
|
|
476484
476624
|
|
|
476485
476625
|
// ../cli/src/commands/_shared/edit/jump-cut.ts
|
|
476486
|
-
import { existsSync as
|
|
476487
|
-
import { readFile as
|
|
476488
|
-
import { join as
|
|
476626
|
+
import { existsSync as existsSync39 } from "node:fs";
|
|
476627
|
+
import { readFile as readFile22, writeFile as writeFile22, mkdir as mkdir14 } from "node:fs/promises";
|
|
476628
|
+
import { join as join34 } from "node:path";
|
|
476489
476629
|
async function transcribeWithWords(audioPath, apiKey, language) {
|
|
476490
|
-
const audioBuffer = await
|
|
476630
|
+
const audioBuffer = await readFile22(audioPath);
|
|
476491
476631
|
const audioBlob = new Blob([audioBuffer]);
|
|
476492
476632
|
const formData = new FormData();
|
|
476493
476633
|
formData.append("file", audioBlob, "audio.wav");
|
|
@@ -476546,7 +476686,7 @@ async function executeJumpCut(options) {
|
|
|
476546
476686
|
analyzeOnly = false,
|
|
476547
476687
|
apiKey
|
|
476548
476688
|
} = options;
|
|
476549
|
-
if (!
|
|
476689
|
+
if (!existsSync39(videoPath)) {
|
|
476550
476690
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
476551
476691
|
}
|
|
476552
476692
|
if (!commandExists("ffmpeg")) {
|
|
@@ -476565,7 +476705,7 @@ async function executeJumpCut(options) {
|
|
|
476565
476705
|
try {
|
|
476566
476706
|
const tmpDir = `/tmp/vibe_jumpcut_${Date.now()}`;
|
|
476567
476707
|
await mkdir14(tmpDir, { recursive: true });
|
|
476568
|
-
const audioPath =
|
|
476708
|
+
const audioPath = join34(tmpDir, "audio.wav");
|
|
476569
476709
|
try {
|
|
476570
476710
|
await execSafe(
|
|
476571
476711
|
"ffmpeg",
|
|
@@ -476619,7 +476759,7 @@ async function executeJumpCut(options) {
|
|
|
476619
476759
|
const segmentPaths = [];
|
|
476620
476760
|
for (let i2 = 0; i2 < segments.length; i2++) {
|
|
476621
476761
|
const seg = segments[i2];
|
|
476622
|
-
const segPath =
|
|
476762
|
+
const segPath = join34(tmpDir, `seg-${i2.toString().padStart(4, "0")}.ts`);
|
|
476623
476763
|
const duration = seg.end - seg.start;
|
|
476624
476764
|
await execSafe(
|
|
476625
476765
|
"ffmpeg",
|
|
@@ -476642,7 +476782,7 @@ async function executeJumpCut(options) {
|
|
|
476642
476782
|
segmentPaths.push(segPath);
|
|
476643
476783
|
}
|
|
476644
476784
|
const concatList = segmentPaths.map((p2) => `file '${p2}'`).join("\n");
|
|
476645
|
-
const listPath =
|
|
476785
|
+
const listPath = join34(tmpDir, "concat.txt");
|
|
476646
476786
|
await writeFile22(listPath, concatList);
|
|
476647
476787
|
await execSafe(
|
|
476648
476788
|
"ffmpeg",
|
|
@@ -476749,8 +476889,8 @@ __export(remotion_exports, {
|
|
|
476749
476889
|
wrapComponentWithVideo: () => wrapComponentWithVideo
|
|
476750
476890
|
});
|
|
476751
476891
|
import { writeFile as writeFile23, mkdir as mkdir15, rm as rm4, copyFile as copyFile5 } from "node:fs/promises";
|
|
476752
|
-
import { existsSync as
|
|
476753
|
-
import { join as
|
|
476892
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
476893
|
+
import { join as join35 } from "node:path";
|
|
476754
476894
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
476755
476895
|
import { createHash as createHash7 } from "node:crypto";
|
|
476756
476896
|
async function ensureRemotionInstalled() {
|
|
@@ -476769,7 +476909,7 @@ async function ensureRemotionInstalled() {
|
|
|
476769
476909
|
}
|
|
476770
476910
|
}
|
|
476771
476911
|
async function scaffoldRemotionProject(componentCode, componentName, opts) {
|
|
476772
|
-
const dir =
|
|
476912
|
+
const dir = join35(tmpdir3(), `vibe_motion_${Date.now()}`);
|
|
476773
476913
|
await mkdir15(dir, { recursive: true });
|
|
476774
476914
|
const deps = {
|
|
476775
476915
|
remotion: REMOTION_VERSION,
|
|
@@ -476788,7 +476928,7 @@ async function scaffoldRemotionProject(componentCode, componentName, opts) {
|
|
|
476788
476928
|
dependencies: deps
|
|
476789
476929
|
};
|
|
476790
476930
|
const packageJsonStr = JSON.stringify(packageJson, null, 2);
|
|
476791
|
-
await writeFile23(
|
|
476931
|
+
await writeFile23(join35(dir, "package.json"), packageJsonStr);
|
|
476792
476932
|
const tsconfig = {
|
|
476793
476933
|
compilerOptions: {
|
|
476794
476934
|
target: "ES2020",
|
|
@@ -476800,8 +476940,8 @@ async function scaffoldRemotionProject(componentCode, componentName, opts) {
|
|
|
476800
476940
|
skipLibCheck: true
|
|
476801
476941
|
}
|
|
476802
476942
|
};
|
|
476803
|
-
await writeFile23(
|
|
476804
|
-
await writeFile23(
|
|
476943
|
+
await writeFile23(join35(dir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
|
|
476944
|
+
await writeFile23(join35(dir, "Component.tsx"), componentCode);
|
|
476805
476945
|
const rootCode = `import { registerRoot, Composition } from "remotion";
|
|
476806
476946
|
import { ${componentName} } from "./Component";
|
|
476807
476947
|
|
|
@@ -476820,14 +476960,14 @@ const Root = () => {
|
|
|
476820
476960
|
|
|
476821
476961
|
registerRoot(Root);
|
|
476822
476962
|
`;
|
|
476823
|
-
await writeFile23(
|
|
476963
|
+
await writeFile23(join35(dir, "Root.tsx"), rootCode);
|
|
476824
476964
|
const depsHash = createHash7("md5").update(packageJsonStr).digest("hex").slice(0, 12);
|
|
476825
|
-
const cacheMarker =
|
|
476826
|
-
const cachedModules =
|
|
476827
|
-
if (
|
|
476965
|
+
const cacheMarker = join35(REMOTION_CACHE_DIR, `.deps-${depsHash}`);
|
|
476966
|
+
const cachedModules = join35(REMOTION_CACHE_DIR, "node_modules");
|
|
476967
|
+
if (existsSync40(cacheMarker) && existsSync40(cachedModules)) {
|
|
476828
476968
|
const { symlink } = await import("node:fs/promises");
|
|
476829
476969
|
try {
|
|
476830
|
-
await symlink(cachedModules,
|
|
476970
|
+
await symlink(cachedModules, join35(dir, "node_modules"), "dir");
|
|
476831
476971
|
} catch {
|
|
476832
476972
|
await this_npmInstall(dir);
|
|
476833
476973
|
}
|
|
@@ -476835,12 +476975,12 @@ registerRoot(Root);
|
|
|
476835
476975
|
await this_npmInstall(dir);
|
|
476836
476976
|
try {
|
|
476837
476977
|
await mkdir15(REMOTION_CACHE_DIR, { recursive: true });
|
|
476838
|
-
await writeFile23(
|
|
476839
|
-
if (
|
|
476978
|
+
await writeFile23(join35(REMOTION_CACHE_DIR, "package.json"), packageJsonStr);
|
|
476979
|
+
if (existsSync40(join35(dir, "node_modules"))) {
|
|
476840
476980
|
const { rename: rename7, symlink } = await import("node:fs/promises");
|
|
476841
|
-
await rename7(
|
|
476981
|
+
await rename7(join35(dir, "node_modules"), cachedModules).catch(() => {
|
|
476842
476982
|
});
|
|
476843
|
-
await symlink(cachedModules,
|
|
476983
|
+
await symlink(cachedModules, join35(dir, "node_modules"), "dir").catch(() => {
|
|
476844
476984
|
});
|
|
476845
476985
|
await writeFile23(cacheMarker, depsHash);
|
|
476846
476986
|
}
|
|
@@ -476877,7 +477017,7 @@ async function renderMotion(options) {
|
|
|
476877
477017
|
}
|
|
476878
477018
|
);
|
|
476879
477019
|
try {
|
|
476880
|
-
const entryPoint =
|
|
477020
|
+
const entryPoint = join35(dir, "Root.tsx");
|
|
476881
477021
|
const { execFile: execFile3 } = await import("node:child_process");
|
|
476882
477022
|
const { promisify: promisify3 } = await import("node:util");
|
|
476883
477023
|
const execFileAsync3 = promisify3(execFile3);
|
|
@@ -477010,10 +477150,10 @@ async function renderWithEmbeddedImage(options) {
|
|
|
477010
477150
|
}
|
|
477011
477151
|
);
|
|
477012
477152
|
try {
|
|
477013
|
-
const publicDir =
|
|
477153
|
+
const publicDir = join35(dir, "public");
|
|
477014
477154
|
await mkdir15(publicDir, { recursive: true });
|
|
477015
|
-
await copyFile5(options.imagePath,
|
|
477016
|
-
const entryPoint =
|
|
477155
|
+
await copyFile5(options.imagePath, join35(publicDir, options.imageFileName));
|
|
477156
|
+
const entryPoint = join35(dir, "Root.tsx");
|
|
477017
477157
|
const mp4Out = options.outputPath.replace(/\.\w+$/, ".mp4");
|
|
477018
477158
|
const { execFile: execFileImg } = await import("node:child_process");
|
|
477019
477159
|
const { promisify: promisifyImg } = await import("node:util");
|
|
@@ -477074,10 +477214,10 @@ async function renderWithEmbeddedVideo(options) {
|
|
|
477074
477214
|
}
|
|
477075
477215
|
);
|
|
477076
477216
|
try {
|
|
477077
|
-
const publicDir =
|
|
477217
|
+
const publicDir = join35(dir, "public");
|
|
477078
477218
|
await mkdir15(publicDir, { recursive: true });
|
|
477079
|
-
await copyFile5(options.videoPath,
|
|
477080
|
-
const entryPoint =
|
|
477219
|
+
await copyFile5(options.videoPath, join35(publicDir, options.videoFileName));
|
|
477220
|
+
const entryPoint = join35(dir, "Root.tsx");
|
|
477081
477221
|
const mp4VideoOnly = options.outputPath.replace(/\.\w+$/, "_video_only.mp4");
|
|
477082
477222
|
const { execFile: execFileVid } = await import("node:child_process");
|
|
477083
477223
|
const { promisify: promisifyVid } = await import("node:util");
|
|
@@ -477493,14 +477633,14 @@ var init_remotion = __esm({
|
|
|
477493
477633
|
"use strict";
|
|
477494
477634
|
init_exec_safe();
|
|
477495
477635
|
REMOTION_VERSION = "4.0.447";
|
|
477496
|
-
REMOTION_CACHE_DIR =
|
|
477636
|
+
REMOTION_CACHE_DIR = join35(tmpdir3(), "vibe_remotion_cache");
|
|
477497
477637
|
}
|
|
477498
477638
|
});
|
|
477499
477639
|
|
|
477500
477640
|
// ../cli/src/commands/_shared/edit/caption.ts
|
|
477501
|
-
import { existsSync as
|
|
477502
|
-
import { readFile as
|
|
477503
|
-
import { dirname as dirname20, basename as basename9, extname as extname7, join as
|
|
477641
|
+
import { existsSync as existsSync41 } from "node:fs";
|
|
477642
|
+
import { readFile as readFile23, writeFile as writeFile24, mkdir as mkdir16 } from "node:fs/promises";
|
|
477643
|
+
import { dirname as dirname20, basename as basename9, extname as extname7, join as join36 } from "node:path";
|
|
477504
477644
|
function getCaptionForceStyle(style, fontSize, fontColor, position) {
|
|
477505
477645
|
const alignment = position === "top" ? 8 : position === "center" ? 5 : 2;
|
|
477506
477646
|
const marginV = position === "center" ? 0 : 30;
|
|
@@ -477528,7 +477668,7 @@ async function executeCaption(options) {
|
|
|
477528
477668
|
position = "bottom",
|
|
477529
477669
|
apiKey
|
|
477530
477670
|
} = options;
|
|
477531
|
-
if (!
|
|
477671
|
+
if (!existsSync41(videoPath)) {
|
|
477532
477672
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
477533
477673
|
}
|
|
477534
477674
|
if (!commandExists("ffmpeg")) {
|
|
@@ -477547,8 +477687,8 @@ async function executeCaption(options) {
|
|
|
477547
477687
|
try {
|
|
477548
477688
|
const tmpDir = `/tmp/vibe_caption_${Date.now()}`;
|
|
477549
477689
|
await mkdir16(tmpDir, { recursive: true });
|
|
477550
|
-
const audioPath =
|
|
477551
|
-
const srtPath =
|
|
477690
|
+
const audioPath = join36(tmpDir, "audio.wav");
|
|
477691
|
+
const srtPath = join36(tmpDir, "captions.srt");
|
|
477552
477692
|
try {
|
|
477553
477693
|
await execSafe(
|
|
477554
477694
|
"ffmpeg",
|
|
@@ -477569,7 +477709,7 @@ async function executeCaption(options) {
|
|
|
477569
477709
|
);
|
|
477570
477710
|
const whisper = new WhisperProvider();
|
|
477571
477711
|
await whisper.initialize({ apiKey: openaiKey });
|
|
477572
|
-
const audioBuffer = await
|
|
477712
|
+
const audioBuffer = await readFile23(audioPath);
|
|
477573
477713
|
const audioBlob = new Blob([audioBuffer]);
|
|
477574
477714
|
const transcriptResult = await whisper.transcribe(audioBlob, language);
|
|
477575
477715
|
if (transcriptResult.status === "failed" || !transcriptResult.segments || transcriptResult.segments.length === 0) {
|
|
@@ -477617,7 +477757,7 @@ async function executeCaption(options) {
|
|
|
477617
477757
|
const remotionErr = await ensureRemotionInstalled2();
|
|
477618
477758
|
if (remotionErr) {
|
|
477619
477759
|
const outputDir2 = dirname20(outputPath);
|
|
477620
|
-
const outputSrtPath2 =
|
|
477760
|
+
const outputSrtPath2 = join36(
|
|
477621
477761
|
outputDir2,
|
|
477622
477762
|
basename9(outputPath, extname7(outputPath)) + ".srt"
|
|
477623
477763
|
);
|
|
@@ -477656,7 +477796,7 @@ SRT saved to: ${outputSrtPath2}` };
|
|
|
477656
477796
|
});
|
|
477657
477797
|
if (!renderResult.success) {
|
|
477658
477798
|
const outputDir2 = dirname20(outputPath);
|
|
477659
|
-
const outputSrtPath2 =
|
|
477799
|
+
const outputSrtPath2 = join36(
|
|
477660
477800
|
outputDir2,
|
|
477661
477801
|
basename9(outputPath, extname7(outputPath)) + ".srt"
|
|
477662
477802
|
);
|
|
@@ -477669,7 +477809,7 @@ SRT saved to: ${outputSrtPath2}`
|
|
|
477669
477809
|
}
|
|
477670
477810
|
}
|
|
477671
477811
|
const outputDir = dirname20(outputPath);
|
|
477672
|
-
const outputSrtPath =
|
|
477812
|
+
const outputSrtPath = join36(
|
|
477673
477813
|
outputDir,
|
|
477674
477814
|
basename9(outputPath, extname7(outputPath)) + ".srt"
|
|
477675
477815
|
);
|
|
@@ -477706,10 +477846,10 @@ var init_caption = __esm({
|
|
|
477706
477846
|
});
|
|
477707
477847
|
|
|
477708
477848
|
// ../cli/src/commands/_shared/edit/noise-reduce.ts
|
|
477709
|
-
import { existsSync as
|
|
477849
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
477710
477850
|
async function executeNoiseReduce(options) {
|
|
477711
477851
|
const { inputPath, outputPath, strength = "medium", noiseFloor } = options;
|
|
477712
|
-
if (!
|
|
477852
|
+
if (!existsSync43(inputPath)) {
|
|
477713
477853
|
return { success: false, error: `File not found: ${inputPath}` };
|
|
477714
477854
|
}
|
|
477715
477855
|
if (!commandExists("ffmpeg")) {
|
|
@@ -477766,7 +477906,7 @@ var init_noise_reduce = __esm({
|
|
|
477766
477906
|
});
|
|
477767
477907
|
|
|
477768
477908
|
// ../cli/src/commands/_shared/edit/fade.ts
|
|
477769
|
-
import { existsSync as
|
|
477909
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
477770
477910
|
async function executeFade(options) {
|
|
477771
477911
|
const {
|
|
477772
477912
|
videoPath,
|
|
@@ -477776,7 +477916,7 @@ async function executeFade(options) {
|
|
|
477776
477916
|
audioOnly = false,
|
|
477777
477917
|
videoOnly = false
|
|
477778
477918
|
} = options;
|
|
477779
|
-
if (!
|
|
477919
|
+
if (!existsSync44(videoPath)) {
|
|
477780
477920
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
477781
477921
|
}
|
|
477782
477922
|
if (!commandExists("ffmpeg")) {
|
|
@@ -477843,8 +477983,8 @@ var init_fade = __esm({
|
|
|
477843
477983
|
});
|
|
477844
477984
|
|
|
477845
477985
|
// ../cli/src/commands/_shared/edit/translate-srt.ts
|
|
477846
|
-
import { existsSync as
|
|
477847
|
-
import { readFile as
|
|
477986
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
477987
|
+
import { readFile as readFile24, writeFile as writeFile25 } from "node:fs/promises";
|
|
477848
477988
|
async function executeTranslateSrt(options) {
|
|
477849
477989
|
const {
|
|
477850
477990
|
srtPath,
|
|
@@ -477854,11 +477994,11 @@ async function executeTranslateSrt(options) {
|
|
|
477854
477994
|
sourceLanguage,
|
|
477855
477995
|
apiKey
|
|
477856
477996
|
} = options;
|
|
477857
|
-
if (!
|
|
477997
|
+
if (!existsSync45(srtPath)) {
|
|
477858
477998
|
return { success: false, error: `SRT file not found: ${srtPath}` };
|
|
477859
477999
|
}
|
|
477860
478000
|
try {
|
|
477861
|
-
const srtContent = await
|
|
478001
|
+
const srtContent = await readFile24(srtPath, "utf-8");
|
|
477862
478002
|
const segments = parseSRT(srtContent);
|
|
477863
478003
|
if (segments.length === 0) {
|
|
477864
478004
|
return { success: false, error: "No subtitle segments found in SRT file" };
|
|
@@ -477971,7 +478111,7 @@ var init_translate_srt = __esm({
|
|
|
477971
478111
|
});
|
|
477972
478112
|
|
|
477973
478113
|
// ../cli/src/commands/_shared/edit/text-overlay.ts
|
|
477974
|
-
import { existsSync as
|
|
478114
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
477975
478115
|
import { resolve as resolve36 } from "node:path";
|
|
477976
478116
|
function detectSystemFont() {
|
|
477977
478117
|
const platform = process.platform;
|
|
@@ -477982,7 +478122,7 @@ function detectSystemFont() {
|
|
|
477982
478122
|
"/Library/Fonts/Arial.ttf"
|
|
477983
478123
|
];
|
|
477984
478124
|
for (const f2 of candidates) {
|
|
477985
|
-
if (
|
|
478125
|
+
if (existsSync46(f2)) return f2;
|
|
477986
478126
|
}
|
|
477987
478127
|
} else if (platform === "linux") {
|
|
477988
478128
|
const candidates = [
|
|
@@ -477991,7 +478131,7 @@ function detectSystemFont() {
|
|
|
477991
478131
|
"/usr/share/fonts/TTF/DejaVuSans-Bold.ttf"
|
|
477992
478132
|
];
|
|
477993
478133
|
for (const f2 of candidates) {
|
|
477994
|
-
if (
|
|
478134
|
+
if (existsSync46(f2)) return f2;
|
|
477995
478135
|
}
|
|
477996
478136
|
} else if (platform === "win32") {
|
|
477997
478137
|
const candidates = [
|
|
@@ -477999,7 +478139,7 @@ function detectSystemFont() {
|
|
|
477999
478139
|
"C:\\Windows\\Fonts\\segoeui.ttf"
|
|
478000
478140
|
];
|
|
478001
478141
|
for (const f2 of candidates) {
|
|
478002
|
-
if (
|
|
478142
|
+
if (existsSync46(f2)) return f2;
|
|
478003
478143
|
}
|
|
478004
478144
|
}
|
|
478005
478145
|
return null;
|
|
@@ -478020,7 +478160,7 @@ async function applyTextOverlays(options) {
|
|
|
478020
478160
|
}
|
|
478021
478161
|
const absVideoPath = resolve36(process.cwd(), videoPath);
|
|
478022
478162
|
const absOutputPath = resolve36(process.cwd(), outputPath);
|
|
478023
|
-
if (!
|
|
478163
|
+
if (!existsSync46(absVideoPath)) {
|
|
478024
478164
|
return { success: false, error: `Video not found: ${absVideoPath}` };
|
|
478025
478165
|
}
|
|
478026
478166
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478201,7 +478341,7 @@ var init_ai_edit = __esm({
|
|
|
478201
478341
|
|
|
478202
478342
|
// ../cli/src/commands/ai-edit-cli.ts
|
|
478203
478343
|
import { resolve as resolve37, extname as extname8, basename as basename10 } from "node:path";
|
|
478204
|
-
import { existsSync as
|
|
478344
|
+
import { existsSync as existsSync47 } from "node:fs";
|
|
478205
478345
|
function registerEditCommands(aiCommand) {
|
|
478206
478346
|
aiCommand.command("silence-cut").alias("sc").description("Remove silent segments from video (FFmpeg default, or Gemini for smart detection)").argument("<video>", "Video file path").option("-o, --output <path>", "Output file path (default: <name>-cut.<ext>)").option("--noise <dB>", "Silence threshold in dB (default: -30)", "-30").option("-d, --min-duration <seconds>", "Minimum silence duration to cut (default: 0.5)", "0.5").option("--padding <seconds>", "Padding around non-silent segments (default: 0.1)", "0.1").option("--analyze-only", "(deprecated \u2014 use `vibe detect silence`) Only detect silence, don't cut").option("--use-gemini", "Use Gemini Video Understanding for context-aware silence detection").option("-m, --model <model>", "Gemini model (default: flash)").option("--low-res", "Low resolution mode for longer videos (Gemini only)").option("-k, --api-key <key>", "Google API key override (or set GOOGLE_API_KEY env)").option("--dry-run", "Preview parameters without executing").addHelpText("after", `
|
|
478207
478347
|
Examples:
|
|
@@ -478218,7 +478358,7 @@ No API key needed (FFmpeg only). Use --use-gemini for smart detection (requires
|
|
|
478218
478358
|
validateOutputPath(options.output);
|
|
478219
478359
|
}
|
|
478220
478360
|
const absVideoPath = resolve37(process.cwd(), videoPath);
|
|
478221
|
-
if (!
|
|
478361
|
+
if (!existsSync47(absVideoPath)) {
|
|
478222
478362
|
exitWithError(notFoundError(absVideoPath));
|
|
478223
478363
|
}
|
|
478224
478364
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478326,7 +478466,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478326
478466
|
validateOutputPath(options.output);
|
|
478327
478467
|
}
|
|
478328
478468
|
const absVideoPath = resolve37(process.cwd(), videoPath);
|
|
478329
|
-
if (!
|
|
478469
|
+
if (!existsSync47(absVideoPath)) {
|
|
478330
478470
|
exitWithError(notFoundError(absVideoPath));
|
|
478331
478471
|
}
|
|
478332
478472
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478407,7 +478547,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478407
478547
|
validateOutputPath(options.output);
|
|
478408
478548
|
}
|
|
478409
478549
|
const absInputPath = resolve37(process.cwd(), inputPath);
|
|
478410
|
-
if (!
|
|
478550
|
+
if (!existsSync47(absInputPath)) {
|
|
478411
478551
|
exitWithError(notFoundError(absInputPath));
|
|
478412
478552
|
}
|
|
478413
478553
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478473,7 +478613,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478473
478613
|
validateOutputPath(options.output);
|
|
478474
478614
|
}
|
|
478475
478615
|
const absVideoPath = resolve37(process.cwd(), videoPath);
|
|
478476
|
-
if (!
|
|
478616
|
+
if (!existsSync47(absVideoPath)) {
|
|
478477
478617
|
exitWithError(notFoundError(absVideoPath));
|
|
478478
478618
|
}
|
|
478479
478619
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478548,7 +478688,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478548
478688
|
exitWithError(usageError("Target language required. Use -t or --target"));
|
|
478549
478689
|
}
|
|
478550
478690
|
const absSrtPath = resolve37(process.cwd(), srtPath);
|
|
478551
|
-
if (!
|
|
478691
|
+
if (!existsSync47(absSrtPath)) {
|
|
478552
478692
|
exitWithError(notFoundError(absSrtPath));
|
|
478553
478693
|
}
|
|
478554
478694
|
if (options.dryRun) {
|
|
@@ -478624,7 +478764,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478624
478764
|
}
|
|
478625
478765
|
if (options.fillers) rejectControlChars(options.fillers);
|
|
478626
478766
|
const absVideoPath = resolve37(process.cwd(), videoPath);
|
|
478627
|
-
if (!
|
|
478767
|
+
if (!existsSync47(absVideoPath)) {
|
|
478628
478768
|
exitWithError(notFoundError(absVideoPath));
|
|
478629
478769
|
}
|
|
478630
478770
|
if (!commandExists("ffmpeg")) {
|
|
@@ -479116,8 +479256,8 @@ var init_project_resolver = __esm({
|
|
|
479116
479256
|
});
|
|
479117
479257
|
|
|
479118
479258
|
// ../cli/src/commands/_shared/execute-fill-gaps.ts
|
|
479119
|
-
import { existsSync as
|
|
479120
|
-
import { readFile as
|
|
479259
|
+
import { existsSync as existsSync48 } from "node:fs";
|
|
479260
|
+
import { readFile as readFile25, writeFile as writeFile26, mkdir as mkdir17, rename as renameFs } from "node:fs/promises";
|
|
479121
479261
|
import { resolve as resolve39, dirname as dirname21 } from "node:path";
|
|
479122
479262
|
function detectVideoGaps(videoClips, totalDuration) {
|
|
479123
479263
|
const gaps = [];
|
|
@@ -479174,7 +479314,7 @@ function analyzeGapFillability(gaps, videoClips, sources) {
|
|
|
479174
479314
|
}
|
|
479175
479315
|
async function uploadFrameToImgbb(framePath, imgbbApiKey) {
|
|
479176
479316
|
try {
|
|
479177
|
-
const frameBuffer = await
|
|
479317
|
+
const frameBuffer = await readFile25(framePath);
|
|
479178
479318
|
const frameBase64 = frameBuffer.toString("base64");
|
|
479179
479319
|
const formData = new FormData();
|
|
479180
479320
|
formData.append("key", imgbbApiKey);
|
|
@@ -479199,14 +479339,14 @@ async function executeFillGaps(options) {
|
|
|
479199
479339
|
try {
|
|
479200
479340
|
onProgress("Loading timeline...");
|
|
479201
479341
|
const filePath = await resolveTimelineFile(options.projectPath);
|
|
479202
|
-
if (!
|
|
479342
|
+
if (!existsSync48(filePath)) {
|
|
479203
479343
|
return {
|
|
479204
479344
|
success: false,
|
|
479205
479345
|
error: `Timeline file not found: ${filePath}`,
|
|
479206
479346
|
humanLines
|
|
479207
479347
|
};
|
|
479208
479348
|
}
|
|
479209
|
-
const content = await
|
|
479349
|
+
const content = await readFile25(filePath, "utf-8");
|
|
479210
479350
|
const data = JSON.parse(content);
|
|
479211
479351
|
const project = Project.fromJSON(data);
|
|
479212
479352
|
const clips = project.getClips().sort((a2, b2) => a2.startTime - b2.startTime);
|
|
@@ -479334,7 +479474,7 @@ async function executeFillGaps(options) {
|
|
|
479334
479474
|
}
|
|
479335
479475
|
const projectDir = dirname21(filePath);
|
|
479336
479476
|
const footageDir = options.dir ? resolve39(process.cwd(), options.dir) : resolve39(projectDir, "footage");
|
|
479337
|
-
if (!
|
|
479477
|
+
if (!existsSync48(footageDir)) {
|
|
479338
479478
|
await mkdir17(footageDir, { recursive: true });
|
|
479339
479479
|
}
|
|
479340
479480
|
humanLines.push("Generating AI Videos");
|
|
@@ -479654,8 +479794,8 @@ __export(ai_motion_exports, {
|
|
|
479654
479794
|
registerMotionCommand: () => registerMotionCommand
|
|
479655
479795
|
});
|
|
479656
479796
|
import { resolve as resolve40 } from "node:path";
|
|
479657
|
-
import { existsSync as
|
|
479658
|
-
import { readFile as
|
|
479797
|
+
import { existsSync as existsSync49 } from "node:fs";
|
|
479798
|
+
import { readFile as readFile26, writeFile as writeFile27 } from "node:fs/promises";
|
|
479659
479799
|
async function getOptionalGoogleApiKey() {
|
|
479660
479800
|
const configKey = await getApiKeyFromConfig("google");
|
|
479661
479801
|
if (configKey) return configKey;
|
|
@@ -479702,7 +479842,7 @@ async function executeMotion(options) {
|
|
|
479702
479842
|
};
|
|
479703
479843
|
}
|
|
479704
479844
|
const imagePath = resolve40(process.cwd(), options.image);
|
|
479705
|
-
const imageBuffer = await
|
|
479845
|
+
const imageBuffer = await readFile26(imagePath);
|
|
479706
479846
|
const gemini = new GeminiProvider();
|
|
479707
479847
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
479708
479848
|
const analysisResult = await gemini.analyzeImage(
|
|
@@ -479739,7 +479879,7 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
479739
479879
|
}
|
|
479740
479880
|
if (geminiApiKey) {
|
|
479741
479881
|
const videoPath = resolve40(process.cwd(), options.video);
|
|
479742
|
-
const videoBuffer = await
|
|
479882
|
+
const videoBuffer = await readFile26(videoPath);
|
|
479743
479883
|
const gemini = new GeminiProvider();
|
|
479744
479884
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
479745
479885
|
const analysisPrompt = options.understandingPrompt || `Analyze this video for motion graphics composition. Return concise production guidance:
|
|
@@ -479770,10 +479910,10 @@ Use this video understanding to place motion graphics in safe zones, match the c
|
|
|
479770
479910
|
let result;
|
|
479771
479911
|
if (options.fromTsx) {
|
|
479772
479912
|
const tsxPath = resolve40(process.cwd(), options.fromTsx);
|
|
479773
|
-
if (!
|
|
479913
|
+
if (!existsSync49(tsxPath)) {
|
|
479774
479914
|
return { success: false, error: `TSX file not found: ${tsxPath}` };
|
|
479775
479915
|
}
|
|
479776
|
-
const existingCode = await
|
|
479916
|
+
const existingCode = await readFile26(tsxPath, "utf-8");
|
|
479777
479917
|
if (useGemini) {
|
|
479778
479918
|
const gemini = new GeminiProvider();
|
|
479779
479919
|
await gemini.initialize({ apiKey });
|
|
@@ -480302,7 +480442,7 @@ __export(project_builder_exports, {
|
|
|
480302
480442
|
resolveSourceUrl: () => resolveSourceUrl
|
|
480303
480443
|
});
|
|
480304
480444
|
import { mkdtemp as mkdtemp4, mkdir as mkdir18, copyFile as copyFile6, writeFile as writeFile28, rm as rm5, readdir as readdir5 } from "node:fs/promises";
|
|
480305
|
-
import { existsSync as
|
|
480445
|
+
import { existsSync as existsSync50 } from "node:fs";
|
|
480306
480446
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
480307
480447
|
import { createRequire } from "node:module";
|
|
480308
480448
|
import * as path13 from "node:path";
|
|
@@ -480314,7 +480454,7 @@ async function buildTempProject(state, projectFileDir) {
|
|
|
480314
480454
|
for (const source3 of state.sources) {
|
|
480315
480455
|
if (copied.has(source3.id)) continue;
|
|
480316
480456
|
const resolved = resolveSourceUrl(source3.url, projectFileDir);
|
|
480317
|
-
if (!
|
|
480457
|
+
if (!existsSync50(resolved)) {
|
|
480318
480458
|
throw new Error(`Source file not found: ${resolved} (from source id=${source3.id})`);
|
|
480319
480459
|
}
|
|
480320
480460
|
const dest = path13.join(assetsDir, path13.basename(resolved));
|
|
@@ -480451,7 +480591,7 @@ __export(motion_overlay_exports, {
|
|
|
480451
480591
|
registerMotionOverlayCommand: () => registerMotionOverlayCommand
|
|
480452
480592
|
});
|
|
480453
480593
|
import { mkdir as mkdir19 } from "node:fs/promises";
|
|
480454
|
-
import { existsSync as
|
|
480594
|
+
import { existsSync as existsSync51 } from "node:fs";
|
|
480455
480595
|
import { basename as basename12, dirname as dirname24, extname as extname9, resolve as resolve43 } from "node:path";
|
|
480456
480596
|
function normalizeUnderstand2(value) {
|
|
480457
480597
|
return value === "off" || value === "required" || value === "auto" ? value : "auto";
|
|
@@ -480582,11 +480722,11 @@ async function executeMotionOverlay(options) {
|
|
|
480582
480722
|
const validationError = assertValidRequest(options);
|
|
480583
480723
|
if (validationError) return { success: false, error: validationError };
|
|
480584
480724
|
const absVideo = resolve43(process.cwd(), options.videoPath);
|
|
480585
|
-
if (!
|
|
480725
|
+
if (!existsSync51(absVideo)) return { success: false, error: `Video file not found: ${absVideo}` };
|
|
480586
480726
|
const outputPath = options.output ? resolve43(process.cwd(), options.output) : defaultOverlayOutput(options.videoPath);
|
|
480587
480727
|
if (options.asset) {
|
|
480588
480728
|
const absAsset = resolve43(process.cwd(), options.asset);
|
|
480589
|
-
if (!
|
|
480729
|
+
if (!existsSync51(absAsset)) return { success: false, error: `Lottie asset not found: ${absAsset}` };
|
|
480590
480730
|
const [videoDuration, size] = await Promise.all([
|
|
480591
480731
|
ffprobeDuration(absVideo),
|
|
480592
480732
|
ffprobeVideoSize(absVideo)
|
|
@@ -480753,7 +480893,7 @@ __export(edit_cmd_exports, {
|
|
|
480753
480893
|
executeUpscale: () => executeUpscale
|
|
480754
480894
|
});
|
|
480755
480895
|
import { resolve as resolve44, dirname as dirname25 } from "node:path";
|
|
480756
|
-
import { readFile as
|
|
480896
|
+
import { readFile as readFile27, writeFile as writeFile29, mkdir as mkdir20 } from "node:fs/promises";
|
|
480757
480897
|
async function executeGrade(options) {
|
|
480758
480898
|
const { videoPath, style, preset, output: output3, analyzeOnly, apiKey } = options;
|
|
480759
480899
|
try {
|
|
@@ -480794,7 +480934,7 @@ async function executeSpeedRamp(options) {
|
|
|
480794
480934
|
await execSafe("ffmpeg", ["-i", absPath, "-vn", "-acodec", "libmp3lame", "-q:a", "2", tempAudio, "-y"]);
|
|
480795
480935
|
const whisper = new WhisperProvider();
|
|
480796
480936
|
await whisper.initialize({ apiKey: openaiKey });
|
|
480797
|
-
const audioBuffer = await
|
|
480937
|
+
const audioBuffer = await readFile27(tempAudio);
|
|
480798
480938
|
const transcript = await whisper.transcribe(new Blob([audioBuffer]), language);
|
|
480799
480939
|
try {
|
|
480800
480940
|
const { unlink: unlink8 } = await import("node:fs/promises");
|
|
@@ -481188,7 +481328,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
481188
481328
|
spinner2.text = "Transcribing audio...";
|
|
481189
481329
|
const whisper = new WhisperProvider();
|
|
481190
481330
|
await whisper.initialize({ apiKey: openaiApiKey });
|
|
481191
|
-
const audioBuffer = await
|
|
481331
|
+
const audioBuffer = await readFile27(tempAudio);
|
|
481192
481332
|
const audioBlob = new Blob([audioBuffer]);
|
|
481193
481333
|
const transcript = await whisper.transcribe(audioBlob, options.language);
|
|
481194
481334
|
if (!transcript.segments || transcript.segments.length === 0) {
|
|
@@ -481321,7 +481461,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
481321
481461
|
for (let i2 = 1; i2 <= numKeyframes && i2 <= 30; i2++) {
|
|
481322
481462
|
const framePath = `${tempDir}/frame-${i2.toString().padStart(4, "0")}.jpg`;
|
|
481323
481463
|
try {
|
|
481324
|
-
const frameBuffer = await
|
|
481464
|
+
const frameBuffer = await readFile27(framePath);
|
|
481325
481465
|
const frameBase64 = frameBuffer.toString("base64");
|
|
481326
481466
|
const result = await claude.analyzeFrameForReframe(frameBase64, options.aspect, {
|
|
481327
481467
|
focusMode: options.focus,
|
|
@@ -481450,7 +481590,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
481450
481590
|
const imageBuffers = [];
|
|
481451
481591
|
for (const imagePath of imagePaths) {
|
|
481452
481592
|
const absPath = resolve44(process.cwd(), imagePath);
|
|
481453
|
-
const buffer = await
|
|
481593
|
+
const buffer = await readFile27(absPath);
|
|
481454
481594
|
imageBuffers.push(buffer);
|
|
481455
481595
|
}
|
|
481456
481596
|
let result;
|
|
@@ -481727,8 +481867,8 @@ __export(ai_image_exports, {
|
|
|
481727
481867
|
executeThumbnailBestFrame: () => executeThumbnailBestFrame
|
|
481728
481868
|
});
|
|
481729
481869
|
import { resolve as resolve46, dirname as dirname27 } from "node:path";
|
|
481730
|
-
import { readFile as
|
|
481731
|
-
import { existsSync as
|
|
481870
|
+
import { readFile as readFile28, writeFile as writeFile31, mkdir as mkdir23 } from "node:fs/promises";
|
|
481871
|
+
import { existsSync as existsSync54 } from "node:fs";
|
|
481732
481872
|
async function executeImageGenerate(options) {
|
|
481733
481873
|
const {
|
|
481734
481874
|
prompt: prompt3,
|
|
@@ -481872,10 +482012,10 @@ async function executeGeminiEdit(options) {
|
|
|
481872
482012
|
const imageBuffers = [];
|
|
481873
482013
|
for (const imagePath of imagePaths) {
|
|
481874
482014
|
const absPath = resolve46(process.cwd(), imagePath);
|
|
481875
|
-
if (!
|
|
482015
|
+
if (!existsSync54(absPath)) {
|
|
481876
482016
|
return { success: false, error: `Image not found: ${absPath}` };
|
|
481877
482017
|
}
|
|
481878
|
-
const buffer = await
|
|
482018
|
+
const buffer = await readFile28(absPath);
|
|
481879
482019
|
imageBuffers.push(buffer);
|
|
481880
482020
|
}
|
|
481881
482021
|
const gemini = new GeminiProvider();
|
|
@@ -481920,7 +482060,7 @@ async function executeThumbnailBestFrame(options) {
|
|
|
481920
482060
|
model = "flash",
|
|
481921
482061
|
apiKey
|
|
481922
482062
|
} = options;
|
|
481923
|
-
if (!
|
|
482063
|
+
if (!existsSync54(videoPath)) {
|
|
481924
482064
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
481925
482065
|
}
|
|
481926
482066
|
if (!commandExists("ffmpeg")) {
|
|
@@ -481933,7 +482073,7 @@ async function executeThumbnailBestFrame(options) {
|
|
|
481933
482073
|
try {
|
|
481934
482074
|
const gemini = new GeminiProvider();
|
|
481935
482075
|
await gemini.initialize({ apiKey: googleKey });
|
|
481936
|
-
const videoData = await
|
|
482076
|
+
const videoData = await readFile28(videoPath);
|
|
481937
482077
|
const analysisPrompt = prompt3 || 'Analyze this video and find the single best frame for a thumbnail. Look for frames that are visually striking, well-composed, emotionally engaging, and representative of the video content. Avoid blurry frames, transitions, or dark scenes. Return ONLY a JSON object: {"timestamp": <seconds as number>, "reason": "<brief explanation>"}';
|
|
481938
482078
|
const modelId = resolveGeminiTextModel(model);
|
|
481939
482079
|
const result = await gemini.analyzeVideo(videoData, analysisPrompt, {
|
|
@@ -481954,7 +482094,7 @@ async function executeThumbnailBestFrame(options) {
|
|
|
481954
482094
|
reason = reasonMatch[1];
|
|
481955
482095
|
}
|
|
481956
482096
|
await execSafe("ffmpeg", ["-ss", String(timestamp), "-i", videoPath, "-frames:v", "1", "-q:v", "2", outputPath, "-y"], { timeout: 6e4, maxBuffer: 50 * 1024 * 1024 });
|
|
481957
|
-
if (!
|
|
482097
|
+
if (!existsSync54(outputPath)) {
|
|
481958
482098
|
return { success: false, error: "FFmpeg failed to extract frame" };
|
|
481959
482099
|
}
|
|
481960
482100
|
return {
|
|
@@ -481985,9 +482125,9 @@ __export(ai_analyze_exports, {
|
|
|
481985
482125
|
executeGeminiVideo: () => executeGeminiVideo,
|
|
481986
482126
|
registerAnalyzeCommands: () => registerAnalyzeCommands
|
|
481987
482127
|
});
|
|
481988
|
-
import { readFile as
|
|
482128
|
+
import { readFile as readFile29 } from "node:fs/promises";
|
|
481989
482129
|
import { extname as extname10, resolve as resolve47 } from "node:path";
|
|
481990
|
-
import { existsSync as
|
|
482130
|
+
import { existsSync as existsSync55 } from "node:fs";
|
|
481991
482131
|
async function executeGeminiVideo(options) {
|
|
481992
482132
|
try {
|
|
481993
482133
|
const apiKey = await getApiKey("GOOGLE_API_KEY", "Google");
|
|
@@ -482001,10 +482141,10 @@ async function executeGeminiVideo(options) {
|
|
|
482001
482141
|
videoData = options.source;
|
|
482002
482142
|
} else {
|
|
482003
482143
|
const absPath = resolve47(process.cwd(), options.source);
|
|
482004
|
-
if (!
|
|
482144
|
+
if (!existsSync55(absPath)) {
|
|
482005
482145
|
return { success: false, error: `File not found: ${absPath}` };
|
|
482006
482146
|
}
|
|
482007
|
-
videoData = await
|
|
482147
|
+
videoData = await readFile29(absPath);
|
|
482008
482148
|
}
|
|
482009
482149
|
const gemini = new GeminiProvider();
|
|
482010
482150
|
await gemini.initialize({ apiKey });
|
|
@@ -482069,10 +482209,10 @@ async function executeAnalyze(options) {
|
|
|
482069
482209
|
imageBuffer = Buffer.from(await response.arrayBuffer());
|
|
482070
482210
|
} else {
|
|
482071
482211
|
const absPath = resolve47(process.cwd(), source3);
|
|
482072
|
-
if (!
|
|
482212
|
+
if (!existsSync55(absPath)) {
|
|
482073
482213
|
return { success: false, error: `File not found: ${absPath}` };
|
|
482074
482214
|
}
|
|
482075
|
-
imageBuffer = await
|
|
482215
|
+
imageBuffer = await readFile29(absPath);
|
|
482076
482216
|
}
|
|
482077
482217
|
const result2 = await gemini.analyzeImage(imageBuffer, options.prompt, {
|
|
482078
482218
|
model: modelId,
|
|
@@ -482104,10 +482244,10 @@ async function executeAnalyze(options) {
|
|
|
482104
482244
|
videoData = Buffer.from(await response.arrayBuffer());
|
|
482105
482245
|
} else {
|
|
482106
482246
|
const absPath = resolve47(process.cwd(), source3);
|
|
482107
|
-
if (!
|
|
482247
|
+
if (!existsSync55(absPath)) {
|
|
482108
482248
|
return { success: false, error: `File not found: ${absPath}` };
|
|
482109
482249
|
}
|
|
482110
|
-
videoData = await
|
|
482250
|
+
videoData = await readFile29(absPath);
|
|
482111
482251
|
}
|
|
482112
482252
|
const result = await gemini.analyzeVideo(videoData, options.prompt, {
|
|
482113
482253
|
model: modelId,
|
|
@@ -482241,9 +482381,9 @@ __export(ai_review_exports, {
|
|
|
482241
482381
|
executeReview: () => executeReview,
|
|
482242
482382
|
registerReviewCommand: () => registerReviewCommand
|
|
482243
482383
|
});
|
|
482244
|
-
import { readFile as
|
|
482384
|
+
import { readFile as readFile30, rename as rename5 } from "node:fs/promises";
|
|
482245
482385
|
import { resolve as resolve48 } from "node:path";
|
|
482246
|
-
import { existsSync as
|
|
482386
|
+
import { existsSync as existsSync56 } from "node:fs";
|
|
482247
482387
|
function parseReviewFeedback(response) {
|
|
482248
482388
|
let cleaned = response.trim();
|
|
482249
482389
|
if (cleaned.startsWith("```json")) {
|
|
@@ -482275,7 +482415,7 @@ async function executeReview(options) {
|
|
|
482275
482415
|
model = "flash"
|
|
482276
482416
|
} = options;
|
|
482277
482417
|
const absVideoPath = resolve48(process.cwd(), videoPath);
|
|
482278
|
-
if (!
|
|
482418
|
+
if (!existsSync56(absVideoPath)) {
|
|
482279
482419
|
return { success: false, error: `Video not found: ${absVideoPath}` };
|
|
482280
482420
|
}
|
|
482281
482421
|
const apiKey = process.env.GOOGLE_API_KEY || await getApiKey("GOOGLE_API_KEY", "Google");
|
|
@@ -482288,8 +482428,8 @@ async function executeReview(options) {
|
|
|
482288
482428
|
let storyboardContext = "";
|
|
482289
482429
|
if (storyboardPath) {
|
|
482290
482430
|
const absStoryboardPath = resolve48(process.cwd(), storyboardPath);
|
|
482291
|
-
if (
|
|
482292
|
-
const content = await
|
|
482431
|
+
if (existsSync56(absStoryboardPath)) {
|
|
482432
|
+
const content = await readFile30(absStoryboardPath, "utf-8");
|
|
482293
482433
|
storyboardContext = `
|
|
482294
482434
|
|
|
482295
482435
|
Original storyboard for reference:
|
|
@@ -482331,7 +482471,7 @@ ${projectContext}` : "";
|
|
|
482331
482471
|
Score each category 1-10. Prefer beatIssues when you can map a problem to a storyboard beat or timestamp. Use the exact beatId values from the storyboard or beat timing summary, and include timeRange in seconds for every localized finding. In particular, flag narration/visual mismatches, overly static holds, and audio-visual sync problems as beatIssues. Use category issue arrays only for problems that cannot be localized to a beat. For fixable issues, provide an FFmpeg filter in autoFixable. Be specific and practical.${storyboardContext}${extraProjectContext}`;
|
|
482332
482472
|
const gemini = new GeminiProvider();
|
|
482333
482473
|
await gemini.initialize({ apiKey });
|
|
482334
|
-
const videoData = await
|
|
482474
|
+
const videoData = await readFile30(absVideoPath);
|
|
482335
482475
|
const analysisResult = await gemini.analyzeVideo(videoData, reviewPrompt, {
|
|
482336
482476
|
model: modelId
|
|
482337
482477
|
});
|
|
@@ -482386,7 +482526,7 @@ Score each category 1-10. Prefer beatIssues when you can map a problem to a stor
|
|
|
482386
482526
|
}
|
|
482387
482527
|
}
|
|
482388
482528
|
if (verify && result.outputPath) {
|
|
482389
|
-
const verifyVideoData = await
|
|
482529
|
+
const verifyVideoData = await readFile30(result.outputPath);
|
|
482390
482530
|
const verifyResult = await gemini.analyzeVideo(
|
|
482391
482531
|
verifyVideoData,
|
|
482392
482532
|
'Rate this video overall quality on a scale of 1-10. Return ONLY a JSON object: {"score": <number>}',
|
|
@@ -482850,7 +482990,7 @@ var init_sanitize = __esm({
|
|
|
482850
482990
|
|
|
482851
482991
|
// ../cli/src/commands/generate/storyboard.ts
|
|
482852
482992
|
import { resolve as resolve56 } from "node:path";
|
|
482853
|
-
import { readFile as
|
|
482993
|
+
import { readFile as readFile34, writeFile as writeFile35 } from "node:fs/promises";
|
|
482854
482994
|
async function executeStoryboard(options) {
|
|
482855
482995
|
const { content, duration, creativity = "low", output: output3, apiKey } = options;
|
|
482856
482996
|
try {
|
|
@@ -482898,7 +483038,7 @@ function registerStoryboardCommand(parent) {
|
|
|
482898
483038
|
let textContent2 = content;
|
|
482899
483039
|
if (options.file) {
|
|
482900
483040
|
const filePath = resolve56(process.cwd(), content);
|
|
482901
|
-
textContent2 = await
|
|
483041
|
+
textContent2 = await readFile34(filePath, "utf-8");
|
|
482902
483042
|
}
|
|
482903
483043
|
if (options.dryRun) {
|
|
482904
483044
|
outputSuccess({
|
|
@@ -483291,7 +483431,7 @@ var init_speech2 = __esm({
|
|
|
483291
483431
|
|
|
483292
483432
|
// ../cli/src/commands/generate/thumbnail.ts
|
|
483293
483433
|
import { resolve as resolve58, dirname as dirname29, basename as basename16, extname as extname11 } from "node:path";
|
|
483294
|
-
import { existsSync as
|
|
483434
|
+
import { existsSync as existsSync59 } from "node:fs";
|
|
483295
483435
|
import { writeFile as writeFile37, mkdir as mkdir25 } from "node:fs/promises";
|
|
483296
483436
|
function registerThumbnailCommand(parent) {
|
|
483297
483437
|
parent.command("thumbnail").description("Generate video thumbnail (DALL-E) or extract best frame from video (Gemini)").argument("[description]", "Thumbnail description (for DALL-E generation)").option("-k, --api-key <key>", "API key (OpenAI for generation, Google for best-frame)").option("-o, --output <path>", "Output file path").option("--style <style>", "Platform style: youtube, instagram, tiktok, twitter").option("--best-frame <video>", "Extract best thumbnail frame from video using Gemini AI").option("--prompt <prompt>", "Custom prompt for best-frame analysis").option("--model <model>", `Gemini model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").action(async (description, options) => {
|
|
@@ -483303,7 +483443,7 @@ function registerThumbnailCommand(parent) {
|
|
|
483303
483443
|
}
|
|
483304
483444
|
if (options.bestFrame) {
|
|
483305
483445
|
const absVideoPath = resolve58(process.cwd(), options.bestFrame);
|
|
483306
|
-
if (!
|
|
483446
|
+
if (!existsSync59(absVideoPath)) {
|
|
483307
483447
|
exitWithError(notFoundError(absVideoPath));
|
|
483308
483448
|
}
|
|
483309
483449
|
if (!commandExists("ffmpeg")) {
|
|
@@ -485487,7 +485627,7 @@ var init_dist4 = __esm({
|
|
|
485487
485627
|
|
|
485488
485628
|
// ../cli/src/commands/generate/video.ts
|
|
485489
485629
|
import { resolve as resolve63 } from "node:path";
|
|
485490
|
-
import { readFile as
|
|
485630
|
+
import { readFile as readFile35, writeFile as writeFile41 } from "node:fs/promises";
|
|
485491
485631
|
function registerVideoCommand(parent) {
|
|
485492
485632
|
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(
|
|
485493
485633
|
"-p, --provider <provider>",
|
|
@@ -485598,7 +485738,7 @@ Examples:
|
|
|
485598
485738
|
let isImageToVideo = false;
|
|
485599
485739
|
if (options.image) {
|
|
485600
485740
|
const imagePath = resolve63(process.cwd(), options.image);
|
|
485601
|
-
const imageBuffer = await
|
|
485741
|
+
const imageBuffer = await readFile35(imagePath);
|
|
485602
485742
|
const ext = options.image.toLowerCase().split(".").pop();
|
|
485603
485743
|
const mimeTypes = {
|
|
485604
485744
|
jpg: "image/jpeg",
|
|
@@ -485838,7 +485978,7 @@ Examples:
|
|
|
485838
485978
|
let lastFrame;
|
|
485839
485979
|
if (options.lastFrame) {
|
|
485840
485980
|
const lastFramePath = resolve63(process.cwd(), options.lastFrame);
|
|
485841
|
-
const lastFrameBuffer = await
|
|
485981
|
+
const lastFrameBuffer = await readFile35(lastFramePath);
|
|
485842
485982
|
const ext = options.lastFrame.toLowerCase().split(".").pop();
|
|
485843
485983
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
485844
485984
|
lastFrame = `data:${mimeType};base64,${lastFrameBuffer.toString("base64")}`;
|
|
@@ -485848,7 +485988,7 @@ Examples:
|
|
|
485848
485988
|
refImages = [];
|
|
485849
485989
|
for (const refPath of options.refImages.slice(0, 3)) {
|
|
485850
485990
|
const absRefPath = resolve63(process.cwd(), refPath);
|
|
485851
|
-
const refBuffer = await
|
|
485991
|
+
const refBuffer = await readFile35(absRefPath);
|
|
485852
485992
|
const ext = refPath.toLowerCase().split(".").pop();
|
|
485853
485993
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
485854
485994
|
refImages.push({ base64: refBuffer.toString("base64"), mimeType });
|
|
@@ -485980,7 +486120,7 @@ Examples:
|
|
|
485980
486120
|
if (seedanceEndImagePath && seedanceReferences.length === 0) {
|
|
485981
486121
|
try {
|
|
485982
486122
|
const absEndImagePath = resolve63(process.cwd(), seedanceEndImagePath);
|
|
485983
|
-
const endImageBuffer = await
|
|
486123
|
+
const endImageBuffer = await readFile35(absEndImagePath);
|
|
485984
486124
|
const ext = seedanceEndImagePath.toLowerCase().split(".").pop();
|
|
485985
486125
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
485986
486126
|
const uploadHost = await resolveUploadHost();
|
|
@@ -486097,7 +486237,7 @@ async function fileInputToUrlOrDataUri2(input3, fallbackMimeType) {
|
|
|
486097
486237
|
return input3;
|
|
486098
486238
|
}
|
|
486099
486239
|
const absPath = resolve63(process.cwd(), input3);
|
|
486100
|
-
const buffer = await
|
|
486240
|
+
const buffer = await readFile35(absPath);
|
|
486101
486241
|
return `data:${mimeTypeForPath2(input3, fallbackMimeType)};base64,${buffer.toString("base64")}`;
|
|
486102
486242
|
}
|
|
486103
486243
|
function mimeTypeForPath2(path14, fallback2) {
|
|
@@ -487105,7 +487245,7 @@ __export(detect_exports, {
|
|
|
487105
487245
|
executeDetectScenes: () => executeDetectScenes,
|
|
487106
487246
|
executeDetectSilence: () => executeDetectSilence
|
|
487107
487247
|
});
|
|
487108
|
-
import { readFile as
|
|
487248
|
+
import { readFile as readFile40, writeFile as writeFile46 } from "node:fs/promises";
|
|
487109
487249
|
import { resolve as resolve68, basename as basename18 } from "node:path";
|
|
487110
487250
|
async function executeDetectScenes(options) {
|
|
487111
487251
|
try {
|
|
@@ -487349,7 +487489,7 @@ var init_detect = __esm({
|
|
|
487349
487489
|
}
|
|
487350
487490
|
if (options.project) {
|
|
487351
487491
|
const projectPath = resolve68(process.cwd(), options.project);
|
|
487352
|
-
const content = await
|
|
487492
|
+
const content = await readFile40(projectPath, "utf-8");
|
|
487353
487493
|
const data = JSON.parse(content);
|
|
487354
487494
|
const project = Project.fromJSON(data);
|
|
487355
487495
|
let source3 = project.getSources().find((s2) => s2.url === absPath);
|
|
@@ -488172,8 +488312,8 @@ init_scene_project();
|
|
|
488172
488312
|
init_project_config();
|
|
488173
488313
|
init_cost_tier();
|
|
488174
488314
|
import { resolve as resolve24, relative as relative8, dirname as dirname14 } from "node:path";
|
|
488175
|
-
import { mkdir as mkdir11, readFile as
|
|
488176
|
-
import { existsSync as
|
|
488315
|
+
import { mkdir as mkdir11, readFile as readFile15, writeFile as writeFile17, access as access4, copyFile as copyFile3 } from "node:fs/promises";
|
|
488316
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
488177
488317
|
|
|
488178
488318
|
// ../cli/src/commands/_shared/scene-html-emit.ts
|
|
488179
488319
|
var SCENE_PRESETS = [
|
|
@@ -488742,15 +488882,16 @@ function deriveInstallHosts(detected) {
|
|
|
488742
488882
|
|
|
488743
488883
|
// ../cli/src/commands/scene.ts
|
|
488744
488884
|
init_compose_prompts();
|
|
488885
|
+
init_transcribe_narration();
|
|
488745
488886
|
|
|
488746
488887
|
// ../cli/src/commands/_shared/scene-submit.ts
|
|
488747
488888
|
init_compose_scenes_skills();
|
|
488748
488889
|
init_scene_lint();
|
|
488749
488890
|
init_storyboard_parse();
|
|
488750
488891
|
init_root_sync();
|
|
488751
|
-
import { existsSync as
|
|
488752
|
-
import { mkdir as mkdir10, readFile as
|
|
488753
|
-
import { join as
|
|
488892
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
488893
|
+
import { mkdir as mkdir10, readFile as readFile12, writeFile as writeFile15 } from "node:fs/promises";
|
|
488894
|
+
import { join as join27, resolve as resolve20 } from "node:path";
|
|
488754
488895
|
async function executeSceneSubmit(opts) {
|
|
488755
488896
|
const projectDir = resolve20(opts.projectDir);
|
|
488756
488897
|
const beatId = opts.beatId.trim();
|
|
@@ -488764,15 +488905,15 @@ async function executeSceneSubmit(opts) {
|
|
|
488764
488905
|
warnings: [],
|
|
488765
488906
|
retryWith: []
|
|
488766
488907
|
};
|
|
488767
|
-
const storyboardPath =
|
|
488768
|
-
if (!
|
|
488908
|
+
const storyboardPath = join27(projectDir, "STORYBOARD.md");
|
|
488909
|
+
if (!existsSync27(storyboardPath)) {
|
|
488769
488910
|
return {
|
|
488770
488911
|
...base,
|
|
488771
488912
|
success: false,
|
|
488772
488913
|
error: `STORYBOARD.md not found at ${storyboardPath}. Run \`vibe init <dir>\` first.`
|
|
488773
488914
|
};
|
|
488774
488915
|
}
|
|
488775
|
-
const parsed = parseStoryboard(await
|
|
488916
|
+
const parsed = parseStoryboard(await readFile12(storyboardPath, "utf-8"));
|
|
488776
488917
|
const beat = parsed.beats.find((b2) => b2.id === beatId);
|
|
488777
488918
|
if (!beat) {
|
|
488778
488919
|
const available = parsed.beats.map((b2) => b2.id).join(", ") || "(none)";
|
|
@@ -488842,8 +488983,8 @@ async function executeSceneSubmit(opts) {
|
|
|
488842
488983
|
if (opts.validateOnly) {
|
|
488843
488984
|
return { ...base, success: true };
|
|
488844
488985
|
}
|
|
488845
|
-
const absPath =
|
|
488846
|
-
await mkdir10(
|
|
488986
|
+
const absPath = join27(projectDir, scenePath);
|
|
488987
|
+
await mkdir10(join27(projectDir, "compositions"), { recursive: true });
|
|
488847
488988
|
await writeFile15(absPath, html.endsWith("\n") ? html : `${html}
|
|
488848
488989
|
`, "utf-8");
|
|
488849
488990
|
return {
|
|
@@ -489044,7 +489185,7 @@ sceneCommand.command("submit").description(
|
|
|
489044
489185
|
}
|
|
489045
489186
|
html = Buffer.concat(chunks).toString("utf-8");
|
|
489046
489187
|
} else if (options.file) {
|
|
489047
|
-
html = await
|
|
489188
|
+
html = await readFile15(resolve24(String(options.file)), "utf-8");
|
|
489048
489189
|
} else {
|
|
489049
489190
|
exitWithError(
|
|
489050
489191
|
usageError(
|
|
@@ -489374,8 +489515,8 @@ function readClipStart(rootHtml, beatId) {
|
|
|
489374
489515
|
async function resolveNarrationText(value) {
|
|
489375
489516
|
if (!value) return void 0;
|
|
489376
489517
|
const looksLikePath = /\.[a-z]{2,4}$/i.test(value) || value.includes("/") || value.includes("\\");
|
|
489377
|
-
if (looksLikePath &&
|
|
489378
|
-
return (await
|
|
489518
|
+
if (looksLikePath && existsSync29(value)) {
|
|
489519
|
+
return (await readFile15(value, "utf-8")).trim();
|
|
489379
489520
|
}
|
|
489380
489521
|
return value.trim();
|
|
489381
489522
|
}
|
|
@@ -489414,7 +489555,7 @@ async function executeSceneAdd(opts) {
|
|
|
489414
489555
|
if (!opts.force && await pathExists2(scenePath)) {
|
|
489415
489556
|
return errResult(`Scene already exists: ${sceneRel}. Re-run with --force to overwrite.`);
|
|
489416
489557
|
}
|
|
489417
|
-
const rootHtmlBefore = await
|
|
489558
|
+
const rootHtmlBefore = await readFile15(rootPath, "utf-8");
|
|
489418
489559
|
let dims = readRootDims(rootHtmlBefore);
|
|
489419
489560
|
if (!dims) {
|
|
489420
489561
|
const cfg2 = await loadVibeProjectConfig(projectDir);
|
|
@@ -489490,31 +489631,20 @@ async function executeSceneAdd(opts) {
|
|
|
489490
489631
|
);
|
|
489491
489632
|
} else {
|
|
489492
489633
|
opts.onProgress?.("Transcribing narration (Whisper word-level)...");
|
|
489493
|
-
|
|
489494
|
-
|
|
489495
|
-
|
|
489496
|
-
|
|
489497
|
-
|
|
489498
|
-
|
|
489499
|
-
|
|
489500
|
-
|
|
489501
|
-
|
|
489502
|
-
|
|
489503
|
-
|
|
489504
|
-
|
|
489505
|
-
|
|
489506
|
-
|
|
489507
|
-
transcriptWords = transcript.words.map((w2) => ({
|
|
489508
|
-
text: w2.text,
|
|
489509
|
-
start: w2.start,
|
|
489510
|
-
end: w2.end
|
|
489511
|
-
}));
|
|
489512
|
-
} else if (transcript.status === "failed") {
|
|
489513
|
-
opts.onProgress?.(`Transcribe failed: ${transcript.error ?? "unknown error"}`);
|
|
489514
|
-
}
|
|
489515
|
-
} catch (error) {
|
|
489516
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
489517
|
-
opts.onProgress?.(`Transcribe failed: ${msg}`);
|
|
489634
|
+
const words = await transcribeNarrationWords(audioAbsPath, {
|
|
489635
|
+
apiKey: whisperKey,
|
|
489636
|
+
language: opts.transcribeLanguage
|
|
489637
|
+
});
|
|
489638
|
+
if (words.length > 0) {
|
|
489639
|
+
transcriptRelPath = beatTranscriptRelPath(id);
|
|
489640
|
+
const transcriptAbs = resolve24(projectDir, transcriptRelPath);
|
|
489641
|
+
await writeFile17(transcriptAbs, JSON.stringify(words, null, 2), "utf-8");
|
|
489642
|
+
transcriptWordCount = words.length;
|
|
489643
|
+
transcriptWords = words;
|
|
489644
|
+
} else {
|
|
489645
|
+
opts.onProgress?.(
|
|
489646
|
+
"Transcribe produced no word timings \u2014 narration plays without word-sync"
|
|
489647
|
+
);
|
|
489518
489648
|
}
|
|
489519
489649
|
}
|
|
489520
489650
|
}
|
|
@@ -489623,7 +489753,7 @@ async function executeSceneAdd(opts) {
|
|
|
489623
489753
|
const shouldSyncStoryboard = opts.syncStoryboard !== false && await pathExists2(storyboardAbsPath);
|
|
489624
489754
|
if (shouldSyncStoryboard) {
|
|
489625
489755
|
opts.onProgress?.("Syncing STORYBOARD.md...");
|
|
489626
|
-
const before2 = await
|
|
489756
|
+
const before2 = await readFile15(storyboardAbsPath, "utf-8");
|
|
489627
489757
|
const synced = upsertStoryboardBeat(before2, {
|
|
489628
489758
|
beatId: id,
|
|
489629
489759
|
title: opts.headline,
|
|
@@ -489665,7 +489795,7 @@ async function executeSceneAdd(opts) {
|
|
|
489665
489795
|
});
|
|
489666
489796
|
const blockingIssue = syncPlan.issues.find((issue) => issue.severity === "error");
|
|
489667
489797
|
if (blockingIssue) return errResult(blockingIssue.message);
|
|
489668
|
-
const rootHtmlAfterSync = await
|
|
489798
|
+
const rootHtmlAfterSync = await readFile15(rootPath, "utf-8");
|
|
489669
489799
|
start = readClipStart(rootHtmlAfterSync, id) ?? 0;
|
|
489670
489800
|
} else {
|
|
489671
489801
|
start = nextSceneStart(rootHtmlBefore, SCENE_OVERLAP_SECONDS);
|
|
@@ -489839,7 +489969,7 @@ async function resolveSceneRepairTarget(rootArg = "index.html", projectArg = "."
|
|
|
489839
489969
|
const root2 = rootArg || "index.html";
|
|
489840
489970
|
const project = projectArg || ".";
|
|
489841
489971
|
const defaultProject = project === ".";
|
|
489842
|
-
if (defaultProject && root2 !== "index.html" && !root2.toLowerCase().endsWith(".html") &&
|
|
489972
|
+
if (defaultProject && root2 !== "index.html" && !root2.toLowerCase().endsWith(".html") && existsSync29(resolve24(root2, "index.html"))) {
|
|
489843
489973
|
return { projectDir: resolve24(root2), rootRel: "index.html" };
|
|
489844
489974
|
}
|
|
489845
489975
|
return { projectDir: resolve24(project), rootRel: root2 };
|
|
@@ -490710,7 +490840,7 @@ init_exec_safe();
|
|
|
490710
490840
|
init_remotion();
|
|
490711
490841
|
import { resolve as resolve45, dirname as dirname26, basename as basename13 } from "node:path";
|
|
490712
490842
|
import { writeFile as writeFile30, mkdir as mkdir21, rm as rm6 } from "node:fs/promises";
|
|
490713
|
-
import { existsSync as
|
|
490843
|
+
import { existsSync as existsSync53 } from "node:fs";
|
|
490714
490844
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
490715
490845
|
var ASS_STYLES = ["karaoke-sweep", "typewriter"];
|
|
490716
490846
|
var SENTENCE_BREAKS = /[.!?]/;
|
|
@@ -490891,7 +491021,7 @@ async function executeAnimatedCaption(options) {
|
|
|
490891
491021
|
const groups = groupWords(transcript.words, { wordsPerGroup, maxChars });
|
|
490892
491022
|
const absOutputPath = resolve45(process.cwd(), outputPath);
|
|
490893
491023
|
const outDir = dirname26(absOutputPath);
|
|
490894
|
-
if (!
|
|
491024
|
+
if (!existsSync53(outDir)) {
|
|
490895
491025
|
await mkdir21(outDir, { recursive: true });
|
|
490896
491026
|
}
|
|
490897
491027
|
if (tier === "ass") {
|
|
@@ -491439,14 +491569,14 @@ init_ai_review();
|
|
|
491439
491569
|
init_dist();
|
|
491440
491570
|
init_engine();
|
|
491441
491571
|
init_ai_helpers();
|
|
491442
|
-
import { readFile as
|
|
491572
|
+
import { readFile as readFile31, writeFile as writeFile32 } from "node:fs/promises";
|
|
491443
491573
|
import { resolve as resolve49 } from "node:path";
|
|
491444
491574
|
async function executeSuggestEdit(options) {
|
|
491445
491575
|
try {
|
|
491446
491576
|
const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY;
|
|
491447
491577
|
if (!apiKey) return { success: false, error: "GOOGLE_API_KEY required for suggest" };
|
|
491448
491578
|
const filePath = resolve49(process.cwd(), options.projectPath);
|
|
491449
|
-
const content = await
|
|
491579
|
+
const content = await readFile31(filePath, "utf-8");
|
|
491450
491580
|
const data = JSON.parse(content);
|
|
491451
491581
|
const project = Project.fromJSON(data);
|
|
491452
491582
|
const gemini = new GeminiProvider();
|
|
@@ -491483,9 +491613,9 @@ init_project_config();
|
|
|
491483
491613
|
init_scene_lint();
|
|
491484
491614
|
init_root_sync();
|
|
491485
491615
|
init_review_report();
|
|
491486
|
-
import { existsSync as
|
|
491487
|
-
import { readdir as readdir6, readFile as
|
|
491488
|
-
import { basename as basename14, isAbsolute as isAbsolute7, join as
|
|
491616
|
+
import { existsSync as existsSync57 } from "node:fs";
|
|
491617
|
+
import { readdir as readdir6, readFile as readFile32, stat as stat5 } from "node:fs/promises";
|
|
491618
|
+
import { basename as basename14, isAbsolute as isAbsolute7, join as join38, relative as relative13, resolve as resolve50 } from "node:path";
|
|
491489
491619
|
async function inspectProject(opts) {
|
|
491490
491620
|
const projectDir = resolve50(opts.projectDir);
|
|
491491
491621
|
const issues = [];
|
|
@@ -491499,7 +491629,7 @@ async function inspectProject(opts) {
|
|
|
491499
491629
|
assets: { checked: 0, missing: [], stale: [], unknownFreshness: [] },
|
|
491500
491630
|
rootSync: { ok: null, issueCount: 0, issues: [] }
|
|
491501
491631
|
};
|
|
491502
|
-
if (!
|
|
491632
|
+
if (!existsSync57(projectDir) || !await isDirectory(projectDir)) {
|
|
491503
491633
|
issues.push({
|
|
491504
491634
|
severity: "error",
|
|
491505
491635
|
code: "PROJECT_NOT_FOUND",
|
|
@@ -491514,15 +491644,15 @@ async function inspectProject(opts) {
|
|
|
491514
491644
|
);
|
|
491515
491645
|
}
|
|
491516
491646
|
const coreFiles = {
|
|
491517
|
-
storyboard:
|
|
491518
|
-
design:
|
|
491519
|
-
config:
|
|
491520
|
-
legacyConfig:
|
|
491521
|
-
buildReport:
|
|
491522
|
-
root:
|
|
491647
|
+
storyboard: join38(projectDir, "STORYBOARD.md"),
|
|
491648
|
+
design: join38(projectDir, "DESIGN.md"),
|
|
491649
|
+
config: join38(projectDir, "vibe.config.json"),
|
|
491650
|
+
legacyConfig: join38(projectDir, "vibe.project.yaml"),
|
|
491651
|
+
buildReport: join38(projectDir, "build-report.json"),
|
|
491652
|
+
root: join38(projectDir, "index.html")
|
|
491523
491653
|
};
|
|
491524
491654
|
for (const [name, path14] of Object.entries(coreFiles)) {
|
|
491525
|
-
checks.files[name] =
|
|
491655
|
+
checks.files[name] = existsSync57(path14);
|
|
491526
491656
|
}
|
|
491527
491657
|
let beatIds = [];
|
|
491528
491658
|
let inspectedBeatIds = [];
|
|
@@ -491536,7 +491666,7 @@ async function inspectProject(opts) {
|
|
|
491536
491666
|
});
|
|
491537
491667
|
retryWith.push(`vibe init ${projectDir} --from "<brief>" --json`);
|
|
491538
491668
|
} else {
|
|
491539
|
-
const storyboard = await
|
|
491669
|
+
const storyboard = await readFile32(coreFiles.storyboard, "utf-8");
|
|
491540
491670
|
const validation3 = validateStoryboardMarkdown(storyboard);
|
|
491541
491671
|
storyboardBeats = validation3.beats;
|
|
491542
491672
|
beatIds = validation3.beats.map((beat) => beat.id);
|
|
@@ -491578,7 +491708,7 @@ async function inspectProject(opts) {
|
|
|
491578
491708
|
suggestedFix: "Create DESIGN.md or rerun `vibe init --from` in a new project."
|
|
491579
491709
|
});
|
|
491580
491710
|
} else {
|
|
491581
|
-
const design = await
|
|
491711
|
+
const design = await readFile32(coreFiles.design, "utf-8");
|
|
491582
491712
|
for (const issue of designPlaceholderIssues(design)) {
|
|
491583
491713
|
issues.push(issue);
|
|
491584
491714
|
}
|
|
@@ -491603,20 +491733,20 @@ async function inspectProject(opts) {
|
|
|
491603
491733
|
});
|
|
491604
491734
|
retryWith.push(`vibe build ${projectDir} --stage sync --json`);
|
|
491605
491735
|
}
|
|
491606
|
-
const compositionsDir =
|
|
491607
|
-
const existingComps =
|
|
491736
|
+
const compositionsDir = join38(projectDir, "compositions");
|
|
491737
|
+
const existingComps = existsSync57(compositionsDir) ? new Set(await listHtmlBasenames(compositionsDir)) : /* @__PURE__ */ new Set();
|
|
491608
491738
|
checks.compositions.expected = inspectedBeatIds.length;
|
|
491609
491739
|
for (const beatId of inspectedBeatIds) {
|
|
491610
491740
|
const file = `scene-${beatId}.html`;
|
|
491611
491741
|
if (existingComps.has(file)) {
|
|
491612
491742
|
checks.compositions.found++;
|
|
491613
491743
|
} else {
|
|
491614
|
-
checks.compositions.missing.push(
|
|
491744
|
+
checks.compositions.missing.push(join38("compositions", file));
|
|
491615
491745
|
issues.push({
|
|
491616
491746
|
severity: "error",
|
|
491617
491747
|
code: "MISSING_COMPOSITION",
|
|
491618
491748
|
message: `Composition for beat "${beatId}" is missing.`,
|
|
491619
|
-
file:
|
|
491749
|
+
file: join38("compositions", file),
|
|
491620
491750
|
scene: beatId,
|
|
491621
491751
|
beatId,
|
|
491622
491752
|
suggestedFix: "Run `vibe build --stage compose --json`."
|
|
@@ -491678,7 +491808,7 @@ async function inspectProject(opts) {
|
|
|
491678
491808
|
try {
|
|
491679
491809
|
const lint = await runProjectLint({ projectDir });
|
|
491680
491810
|
const lintFiles = opts.beatId ? lint.files.filter(
|
|
491681
|
-
(file) => file.file === "index.html" || file.file ===
|
|
491811
|
+
(file) => file.file === "index.html" || file.file === join38("compositions", `scene-${opts.beatId}.html`)
|
|
491682
491812
|
) : lint.files;
|
|
491683
491813
|
const lintCounts = countLintFindings(lintFiles);
|
|
491684
491814
|
checks.lint = {
|
|
@@ -491824,7 +491954,7 @@ function projectSourceReports(checks) {
|
|
|
491824
491954
|
async function inspectBuildReport(projectDir, reportPath, beatId, checks, issues, retryWith, storyboardBeats) {
|
|
491825
491955
|
checks.buildReport.exists = true;
|
|
491826
491956
|
try {
|
|
491827
|
-
const report = JSON.parse(await
|
|
491957
|
+
const report = JSON.parse(await readFile32(reportPath, "utf-8"));
|
|
491828
491958
|
if (typeof report.outputPath === "string") checks.buildReport.outputPath = report.outputPath;
|
|
491829
491959
|
const reportBeats = report.beats ?? [];
|
|
491830
491960
|
const selectedReportBeats = reportBeats.filter((item) => !beatId || item.id === beatId);
|
|
@@ -491961,7 +492091,7 @@ function inspectReportedAsset(opts) {
|
|
|
491961
492091
|
opts.checks.assets.checked++;
|
|
491962
492092
|
if (isExternalRef2(opts.value)) return;
|
|
491963
492093
|
const abs = isAbsolute7(opts.value) ? opts.value : resolve50(opts.projectDir, opts.value);
|
|
491964
|
-
if (
|
|
492094
|
+
if (existsSync57(abs)) return;
|
|
491965
492095
|
opts.checks.assets.missing.push(opts.value);
|
|
491966
492096
|
opts.issues.push({
|
|
491967
492097
|
severity: "warning",
|
|
@@ -492055,9 +492185,9 @@ init_exec_safe();
|
|
|
492055
492185
|
init_project_config();
|
|
492056
492186
|
init_storyboard_parse();
|
|
492057
492187
|
init_review_report();
|
|
492058
|
-
import { existsSync as
|
|
492059
|
-
import { readdir as readdir7, readFile as
|
|
492060
|
-
import { basename as basename15, isAbsolute as isAbsolute8, join as
|
|
492188
|
+
import { existsSync as existsSync58 } from "node:fs";
|
|
492189
|
+
import { readdir as readdir7, readFile as readFile33, stat as stat6 } from "node:fs/promises";
|
|
492190
|
+
import { basename as basename15, isAbsolute as isAbsolute8, join as join39, relative as relative14, resolve as resolve51 } from "node:path";
|
|
492061
492191
|
var VIDEO_EXTENSIONS = /* @__PURE__ */ new Set([".mp4", ".mov", ".webm", ".m4v"]);
|
|
492062
492192
|
var DEFAULT_AI_MODEL = "flash";
|
|
492063
492193
|
var BLACK_FRAME_MIN_DURATION_SEC = 1;
|
|
@@ -492558,11 +492688,11 @@ async function inspectRender(opts) {
|
|
|
492558
492688
|
}
|
|
492559
492689
|
async function renderExpectsAudio(projectDir, beatId) {
|
|
492560
492690
|
const root2 = resolve51(projectDir);
|
|
492561
|
-
const rootHtml = await readTextIfExists(
|
|
492691
|
+
const rootHtml = await readTextIfExists(join39(root2, "index.html"));
|
|
492562
492692
|
if (rootHtml && rootHtmlExpectsAudio(rootHtml, beatId)) return true;
|
|
492563
|
-
const buildReport = await readJsonIfExists(
|
|
492693
|
+
const buildReport = await readJsonIfExists(join39(root2, "build-report.json"));
|
|
492564
492694
|
if (buildReportExpectsAudio(buildReport, beatId)) return true;
|
|
492565
|
-
const storyboard = await readTextIfExists(
|
|
492695
|
+
const storyboard = await readTextIfExists(join39(root2, "STORYBOARD.md"));
|
|
492566
492696
|
if (!storyboard) return false;
|
|
492567
492697
|
try {
|
|
492568
492698
|
const parsed = parseStoryboard(storyboard);
|
|
@@ -492573,7 +492703,7 @@ async function renderExpectsAudio(projectDir, beatId) {
|
|
|
492573
492703
|
`assets/narration-${beat.id}.wav`,
|
|
492574
492704
|
`assets/music-${beat.id}.mp3`,
|
|
492575
492705
|
`assets/music-${beat.id}.wav`
|
|
492576
|
-
].some((asset) =>
|
|
492706
|
+
].some((asset) => existsSync58(join39(root2, asset)))
|
|
492577
492707
|
);
|
|
492578
492708
|
} catch {
|
|
492579
492709
|
return false;
|
|
@@ -492681,8 +492811,8 @@ async function maybeWriteRenderReport(projectDir, opts, result) {
|
|
|
492681
492811
|
}
|
|
492682
492812
|
function renderSourceReports(projectDir, videoPath, checks) {
|
|
492683
492813
|
const reports = [];
|
|
492684
|
-
if (
|
|
492685
|
-
if (
|
|
492814
|
+
if (existsSync58(join39(projectDir, "build-report.json"))) reports.push("build-report.json");
|
|
492815
|
+
if (existsSync58(join39(projectDir, "render-report.json"))) reports.push("render-report.json");
|
|
492686
492816
|
if (videoPath) reports.push(displayPath(videoPath));
|
|
492687
492817
|
if (checks.durationSec !== void 0 || checks.width !== void 0 || checks.height !== void 0) {
|
|
492688
492818
|
reports.push("ffprobe");
|
|
@@ -492695,31 +492825,31 @@ function renderSourceReports(projectDir, videoPath, checks) {
|
|
|
492695
492825
|
async function resolveRenderVideoPath(projectDir, explicit, beatId) {
|
|
492696
492826
|
if (explicit) {
|
|
492697
492827
|
const candidate = resolve51(process.cwd(), explicit);
|
|
492698
|
-
return
|
|
492828
|
+
return existsSync58(candidate) ? candidate : null;
|
|
492699
492829
|
}
|
|
492700
|
-
const renderReportPath =
|
|
492701
|
-
if (
|
|
492830
|
+
const renderReportPath = join39(projectDir, "render-report.json");
|
|
492831
|
+
if (existsSync58(renderReportPath)) {
|
|
492702
492832
|
try {
|
|
492703
|
-
const report = JSON.parse(await
|
|
492833
|
+
const report = JSON.parse(await readFile33(renderReportPath, "utf-8"));
|
|
492704
492834
|
const reportBeat = typeof report.beat === "string" ? report.beat : null;
|
|
492705
492835
|
if (!beatId && reportBeat === null || beatId && reportBeat === beatId) {
|
|
492706
492836
|
const candidate = resolveReportedPath(projectDir, report.outputPath);
|
|
492707
|
-
if (candidate &&
|
|
492837
|
+
if (candidate && existsSync58(candidate)) return candidate;
|
|
492708
492838
|
}
|
|
492709
492839
|
} catch {
|
|
492710
492840
|
}
|
|
492711
492841
|
}
|
|
492712
|
-
const reportPath =
|
|
492713
|
-
if (!beatId &&
|
|
492842
|
+
const reportPath = join39(projectDir, "build-report.json");
|
|
492843
|
+
if (!beatId && existsSync58(reportPath)) {
|
|
492714
492844
|
try {
|
|
492715
|
-
const report = JSON.parse(await
|
|
492845
|
+
const report = JSON.parse(await readFile33(reportPath, "utf-8"));
|
|
492716
492846
|
const candidate = resolveReportedPath(projectDir, report.outputPath);
|
|
492717
|
-
if (candidate &&
|
|
492847
|
+
if (candidate && existsSync58(candidate)) return candidate;
|
|
492718
492848
|
} catch {
|
|
492719
492849
|
}
|
|
492720
492850
|
}
|
|
492721
|
-
const rendersDir =
|
|
492722
|
-
if (!
|
|
492851
|
+
const rendersDir = join39(projectDir, "renders");
|
|
492852
|
+
if (!existsSync58(rendersDir)) return null;
|
|
492723
492853
|
const entries2 = await readdir7(rendersDir, { withFileTypes: true });
|
|
492724
492854
|
const candidates = [];
|
|
492725
492855
|
for (const entry of entries2) {
|
|
@@ -492727,7 +492857,7 @@ async function resolveRenderVideoPath(projectDir, explicit, beatId) {
|
|
|
492727
492857
|
const ext = entry.name.slice(entry.name.lastIndexOf(".")).toLowerCase();
|
|
492728
492858
|
if (!VIDEO_EXTENSIONS.has(ext)) continue;
|
|
492729
492859
|
if (beatId && !entry.name.includes(sanitizeFileSegment2(beatId))) continue;
|
|
492730
|
-
const full =
|
|
492860
|
+
const full = join39(rendersDir, entry.name);
|
|
492731
492861
|
const info = await stat6(full);
|
|
492732
492862
|
candidates.push({ path: full, mtimeMs: info.mtimeMs });
|
|
492733
492863
|
}
|
|
@@ -492745,14 +492875,14 @@ async function runAiRenderReview(projectDir, videoPath, model) {
|
|
|
492745
492875
|
});
|
|
492746
492876
|
}
|
|
492747
492877
|
function resolveStoryboardPath(projectDir) {
|
|
492748
|
-
const storyboardPath =
|
|
492749
|
-
return
|
|
492878
|
+
const storyboardPath = join39(projectDir, "STORYBOARD.md");
|
|
492879
|
+
return existsSync58(storyboardPath) ? storyboardPath : null;
|
|
492750
492880
|
}
|
|
492751
492881
|
async function expectedDurationFromBuildReport(projectDir, beatId) {
|
|
492752
|
-
const reportPath =
|
|
492753
|
-
if (!
|
|
492882
|
+
const reportPath = join39(projectDir, "build-report.json");
|
|
492883
|
+
if (!existsSync58(reportPath)) return void 0;
|
|
492754
492884
|
try {
|
|
492755
|
-
const report = JSON.parse(await
|
|
492885
|
+
const report = JSON.parse(await readFile33(reportPath, "utf-8"));
|
|
492756
492886
|
const beats = beatId ? (report.beats ?? []).filter((beat) => beat.id === beatId) : report.beats ?? [];
|
|
492757
492887
|
const durations = beats.map(
|
|
492758
492888
|
(beat) => parseOptionalNumber2(beat.sceneDurationSec) ?? parseOptionalNumber2(beat.narration?.sceneDurationSec)
|
|
@@ -492764,10 +492894,10 @@ async function expectedDurationFromBuildReport(projectDir, beatId) {
|
|
|
492764
492894
|
}
|
|
492765
492895
|
}
|
|
492766
492896
|
async function beatTimingsFromBuildReport(projectDir, beatId) {
|
|
492767
|
-
const reportPath =
|
|
492768
|
-
if (!
|
|
492897
|
+
const reportPath = join39(projectDir, "build-report.json");
|
|
492898
|
+
if (!existsSync58(reportPath)) return [];
|
|
492769
492899
|
try {
|
|
492770
|
-
const report = JSON.parse(await
|
|
492900
|
+
const report = JSON.parse(await readFile33(reportPath, "utf-8"));
|
|
492771
492901
|
const source3 = report.beats ?? [];
|
|
492772
492902
|
const selected = beatId ? source3.filter((beat) => beat.id === beatId) : source3;
|
|
492773
492903
|
let cursor = 0;
|
|
@@ -492793,17 +492923,17 @@ async function beatTimingsFromBuildReport(projectDir, beatId) {
|
|
|
492793
492923
|
}
|
|
492794
492924
|
async function buildRenderReviewProjectContext(projectDir) {
|
|
492795
492925
|
const parts = [];
|
|
492796
|
-
const storyboard = await readTextIfExists(
|
|
492926
|
+
const storyboard = await readTextIfExists(join39(projectDir, "STORYBOARD.md"));
|
|
492797
492927
|
if (storyboard) {
|
|
492798
492928
|
parts.push(`STORYBOARD.md:
|
|
492799
492929
|
${truncateText(storyboard, 4e3)}`);
|
|
492800
492930
|
parts.push(`Storyboard beat cue summary:
|
|
492801
492931
|
${storyboardBeatCueSummary(storyboard)}`);
|
|
492802
492932
|
}
|
|
492803
|
-
const design = await readTextIfExists(
|
|
492933
|
+
const design = await readTextIfExists(join39(projectDir, "DESIGN.md"));
|
|
492804
492934
|
if (design) parts.push(`DESIGN.md:
|
|
492805
492935
|
${truncateText(design, 4e3)}`);
|
|
492806
|
-
const buildReport = await readTextIfExists(
|
|
492936
|
+
const buildReport = await readTextIfExists(join39(projectDir, "build-report.json"));
|
|
492807
492937
|
if (buildReport) parts.push(`build-report.json:
|
|
492808
492938
|
${truncateText(buildReport, 6e3)}`);
|
|
492809
492939
|
const timings = await beatTimingsFromBuildReport(projectDir);
|
|
@@ -492831,9 +492961,9 @@ function storyboardBeatCueSummary(storyboard) {
|
|
|
492831
492961
|
}
|
|
492832
492962
|
}
|
|
492833
492963
|
async function readTextIfExists(path14) {
|
|
492834
|
-
if (!
|
|
492964
|
+
if (!existsSync58(path14)) return null;
|
|
492835
492965
|
try {
|
|
492836
|
-
return await
|
|
492966
|
+
return await readFile33(path14, "utf-8");
|
|
492837
492967
|
} catch {
|
|
492838
492968
|
return null;
|
|
492839
492969
|
}
|
|
@@ -493652,17 +493782,17 @@ var generateTools = [
|
|
|
493652
493782
|
];
|
|
493653
493783
|
|
|
493654
493784
|
// ../cli/src/tools/manifest/storyboard.ts
|
|
493655
|
-
import { existsSync as
|
|
493656
|
-
import { readFile as
|
|
493785
|
+
import { existsSync as existsSync61 } from "node:fs";
|
|
493786
|
+
import { readFile as readFile37, writeFile as writeFile43 } from "node:fs/promises";
|
|
493657
493787
|
import { resolve as resolve65 } from "node:path";
|
|
493658
493788
|
import { z as z7 } from "zod";
|
|
493659
493789
|
init_storyboard_parse();
|
|
493660
493790
|
init_storyboard_edit();
|
|
493661
493791
|
|
|
493662
493792
|
// ../cli/src/commands/_shared/storyboard-revise.ts
|
|
493663
|
-
import { existsSync as
|
|
493664
|
-
import { readFile as
|
|
493665
|
-
import { join as
|
|
493793
|
+
import { existsSync as existsSync60 } from "node:fs";
|
|
493794
|
+
import { readFile as readFile36, writeFile as writeFile42 } from "node:fs/promises";
|
|
493795
|
+
import { join as join40, resolve as resolve64 } from "node:path";
|
|
493666
493796
|
|
|
493667
493797
|
// ../cli/src/agent/adapters/index.ts
|
|
493668
493798
|
init_openai3();
|
|
@@ -493714,9 +493844,9 @@ init_storyboard_parse();
|
|
|
493714
493844
|
init_storyboard_edit();
|
|
493715
493845
|
async function executeStoryboardRevision(opts) {
|
|
493716
493846
|
const projectDir = resolve64(opts.projectDir);
|
|
493717
|
-
const storyboardPath =
|
|
493847
|
+
const storyboardPath = join40(projectDir, "STORYBOARD.md");
|
|
493718
493848
|
const retryWith = [`vibe storyboard revise ${projectDir} --from "<request>" --dry-run --json`];
|
|
493719
|
-
if (!
|
|
493849
|
+
if (!existsSync60(storyboardPath)) {
|
|
493720
493850
|
return failureResult({
|
|
493721
493851
|
projectDir,
|
|
493722
493852
|
storyboardPath,
|
|
@@ -493726,7 +493856,7 @@ async function executeStoryboardRevision(opts) {
|
|
|
493726
493856
|
retryWith: [`vibe init ${projectDir} --from "<brief>" --json`]
|
|
493727
493857
|
});
|
|
493728
493858
|
}
|
|
493729
|
-
const currentStoryboard = await
|
|
493859
|
+
const currentStoryboard = await readFile36(storyboardPath, "utf-8");
|
|
493730
493860
|
const projectConfig = await readProjectConfig(projectDir);
|
|
493731
493861
|
const explicitComposer = opts.composer ?? projectConfig.config.providers.composer ?? void 0;
|
|
493732
493862
|
let provider = explicitComposer ?? "claude";
|
|
@@ -493949,18 +494079,18 @@ function diffChangedBeats(before2, after2) {
|
|
|
493949
494079
|
return ids.filter((id) => JSON.stringify(beforeBeats.get(id) ?? null) !== JSON.stringify(afterBeats.get(id) ?? null));
|
|
493950
494080
|
}
|
|
493951
494081
|
async function readRevisionContext(projectDir) {
|
|
493952
|
-
const designMd = await readOptionalText(
|
|
493953
|
-
const buildReportJson = await readOptionalJsonText(
|
|
494082
|
+
const designMd = await readOptionalText(join40(projectDir, "DESIGN.md"));
|
|
494083
|
+
const buildReportJson = await readOptionalJsonText(join40(projectDir, "build-report.json"));
|
|
493954
494084
|
return { designMd, buildReportJson };
|
|
493955
494085
|
}
|
|
493956
494086
|
async function readOptionalText(path14) {
|
|
493957
|
-
if (!
|
|
493958
|
-
return
|
|
494087
|
+
if (!existsSync60(path14)) return null;
|
|
494088
|
+
return readFile36(path14, "utf-8");
|
|
493959
494089
|
}
|
|
493960
494090
|
async function readOptionalJsonText(path14) {
|
|
493961
|
-
if (!
|
|
494091
|
+
if (!existsSync60(path14)) return null;
|
|
493962
494092
|
try {
|
|
493963
|
-
const parsed = JSON.parse(await
|
|
494093
|
+
const parsed = JSON.parse(await readFile36(path14, "utf-8"));
|
|
493964
494094
|
return JSON.stringify(parsed, null, 2);
|
|
493965
494095
|
} catch {
|
|
493966
494096
|
return null;
|
|
@@ -494005,8 +494135,8 @@ var projectDirSchema = z7.object({
|
|
|
494005
494135
|
});
|
|
494006
494136
|
async function readStoryboard(projectDir) {
|
|
494007
494137
|
const path14 = resolve65(projectDir, "STORYBOARD.md");
|
|
494008
|
-
if (!
|
|
494009
|
-
return { path: path14, markdown: await
|
|
494138
|
+
if (!existsSync61(path14)) return null;
|
|
494139
|
+
return { path: path14, markdown: await readFile37(path14, "utf-8") };
|
|
494010
494140
|
}
|
|
494011
494141
|
var storyboardListTool = defineTool({
|
|
494012
494142
|
name: "storyboard_list",
|
|
@@ -494265,7 +494395,7 @@ var storyboardTools = [
|
|
|
494265
494395
|
// ../cli/src/tools/manifest/remix.ts
|
|
494266
494396
|
import { writeFile as writeFile48 } from "node:fs/promises";
|
|
494267
494397
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
494268
|
-
import { join as
|
|
494398
|
+
import { join as join41 } from "node:path";
|
|
494269
494399
|
import { z as z8 } from "zod";
|
|
494270
494400
|
|
|
494271
494401
|
// ../cli/src/commands/ai-script-pipeline.ts
|
|
@@ -494276,9 +494406,9 @@ init_config();
|
|
|
494276
494406
|
init_audio();
|
|
494277
494407
|
init_ai_helpers();
|
|
494278
494408
|
init_video_utils();
|
|
494279
|
-
import { readFile as
|
|
494409
|
+
import { readFile as readFile38, writeFile as writeFile44, unlink as unlink6, rename as rename6 } from "node:fs/promises";
|
|
494280
494410
|
import { resolve as resolve66, extname as extname12 } from "node:path";
|
|
494281
|
-
import { existsSync as
|
|
494411
|
+
import { existsSync as existsSync63 } from "node:fs";
|
|
494282
494412
|
|
|
494283
494413
|
// ../cli/src/commands/_shared/video-providers.ts
|
|
494284
494414
|
init_source();
|
|
@@ -494437,16 +494567,16 @@ async function executeRegenerateScene(options) {
|
|
|
494437
494567
|
};
|
|
494438
494568
|
try {
|
|
494439
494569
|
const outputDir = resolve66(process.cwd(), options.projectDir);
|
|
494440
|
-
if (!
|
|
494570
|
+
if (!existsSync63(outputDir)) {
|
|
494441
494571
|
return { ...result, error: `Project directory not found: ${outputDir}` };
|
|
494442
494572
|
}
|
|
494443
494573
|
const yamlPath = resolve66(outputDir, "storyboard.yaml");
|
|
494444
494574
|
const jsonPath = resolve66(outputDir, "storyboard.json");
|
|
494445
|
-
const storyboardPath =
|
|
494575
|
+
const storyboardPath = existsSync63(yamlPath) ? yamlPath : existsSync63(jsonPath) ? jsonPath : null;
|
|
494446
494576
|
if (!storyboardPath) {
|
|
494447
494577
|
return { ...result, error: `Storyboard not found in: ${outputDir} (expected storyboard.yaml or storyboard.json)` };
|
|
494448
494578
|
}
|
|
494449
|
-
const storyboardContent = await
|
|
494579
|
+
const storyboardContent = await readFile38(storyboardPath, "utf-8");
|
|
494450
494580
|
const segments = storyboardPath.endsWith(".yaml") ? (0, import_yaml6.parse)(storyboardContent).scenes : JSON.parse(storyboardContent);
|
|
494451
494581
|
for (const sceneNum of options.scenes) {
|
|
494452
494582
|
if (sceneNum < 1 || sceneNum > segments.length) {
|
|
@@ -494535,15 +494665,15 @@ IMPORTANT - Character appearance must match exactly: ${characterDesc}`;
|
|
|
494535
494665
|
const refSceneNum = options.referenceScene;
|
|
494536
494666
|
if (refSceneNum && refSceneNum >= 1 && refSceneNum <= segments.length && refSceneNum !== sceneNum) {
|
|
494537
494667
|
const refImagePath = resolve66(outputDir, `scene-${refSceneNum}.png`);
|
|
494538
|
-
if (
|
|
494539
|
-
referenceImageBuffer = await
|
|
494668
|
+
if (existsSync63(refImagePath)) {
|
|
494669
|
+
referenceImageBuffer = await readFile38(refImagePath);
|
|
494540
494670
|
}
|
|
494541
494671
|
} else if (!refSceneNum) {
|
|
494542
494672
|
for (let i2 = 1; i2 <= segments.length; i2++) {
|
|
494543
494673
|
if (i2 !== sceneNum) {
|
|
494544
494674
|
const otherImagePath = resolve66(outputDir, `scene-${i2}.png`);
|
|
494545
|
-
if (
|
|
494546
|
-
referenceImageBuffer = await
|
|
494675
|
+
if (existsSync63(otherImagePath)) {
|
|
494676
|
+
referenceImageBuffer = await readFile38(otherImagePath);
|
|
494547
494677
|
break;
|
|
494548
494678
|
}
|
|
494549
494679
|
}
|
|
@@ -494631,11 +494761,11 @@ Generate the single-person scene image now.`;
|
|
|
494631
494761
|
}
|
|
494632
494762
|
if (regenerateVideo && videoApiKey) {
|
|
494633
494763
|
options.onProgress?.(`Scene ${sceneNum}: regenerating video (${options.generator || "grok"})...`);
|
|
494634
|
-
if (!
|
|
494764
|
+
if (!existsSync63(imagePath)) {
|
|
494635
494765
|
result.failedScenes.push(sceneNum);
|
|
494636
494766
|
continue;
|
|
494637
494767
|
}
|
|
494638
|
-
const imageBuffer = await
|
|
494768
|
+
const imageBuffer = await readFile38(imagePath);
|
|
494639
494769
|
const videoDuration = segment.duration > 5 ? 10 : 5;
|
|
494640
494770
|
const maxRetries = options.retries ?? DEFAULT_VIDEO_RETRIES;
|
|
494641
494771
|
if (options.generator === "grok") {
|
|
@@ -494843,9 +494973,9 @@ Generate the single-person scene image now.`;
|
|
|
494843
494973
|
}
|
|
494844
494974
|
|
|
494845
494975
|
// ../cli/src/commands/ai-highlights.ts
|
|
494846
|
-
import { readFile as
|
|
494976
|
+
import { readFile as readFile39, writeFile as writeFile45, mkdir as mkdir27 } from "node:fs/promises";
|
|
494847
494977
|
import { resolve as resolve67, dirname as dirname31, basename as basename17, extname as extname13 } from "node:path";
|
|
494848
|
-
import { existsSync as
|
|
494978
|
+
import { existsSync as existsSync64 } from "node:fs";
|
|
494849
494979
|
init_dist();
|
|
494850
494980
|
init_engine();
|
|
494851
494981
|
init_api_key();
|
|
@@ -494876,7 +495006,7 @@ function filterHighlights(highlights, options) {
|
|
|
494876
495006
|
async function executeHighlights(options) {
|
|
494877
495007
|
try {
|
|
494878
495008
|
const absPath = resolve67(process.cwd(), options.media);
|
|
494879
|
-
if (!
|
|
495009
|
+
if (!existsSync64(absPath)) {
|
|
494880
495010
|
return { success: false, highlights: [], totalDuration: 0, totalHighlightDuration: 0, error: `File not found: ${absPath}` };
|
|
494881
495011
|
}
|
|
494882
495012
|
const ext = extname13(absPath).toLowerCase();
|
|
@@ -494895,7 +495025,7 @@ async function executeHighlights(options) {
|
|
|
494895
495025
|
sourceDuration = await ffprobeDuration(absPath);
|
|
494896
495026
|
const gemini = new GeminiProvider();
|
|
494897
495027
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
494898
|
-
const videoBuffer = await
|
|
495028
|
+
const videoBuffer = await readFile39(absPath);
|
|
494899
495029
|
const criteriaText = options.criteria === "all" || !options.criteria ? "emotional, informative, and funny moments" : `${options.criteria} moments`;
|
|
494900
495030
|
const durationText = targetDuration ? `Target a total highlight duration of ${targetDuration} seconds.` : "";
|
|
494901
495031
|
const countText = maxCount ? `Find up to ${maxCount} highlights.` : "";
|
|
@@ -494989,10 +495119,10 @@ Analyze both what is SHOWN (visual cues, actions, expressions) and what is SAID
|
|
|
494989
495119
|
}
|
|
494990
495120
|
const whisper = new WhisperProvider();
|
|
494991
495121
|
await whisper.initialize({ apiKey: openaiApiKey });
|
|
494992
|
-
const audioBuffer = await
|
|
495122
|
+
const audioBuffer = await readFile39(audioPath);
|
|
494993
495123
|
const audioBlob = new Blob([audioBuffer]);
|
|
494994
495124
|
const transcriptResult = await whisper.transcribe(audioBlob, options.language);
|
|
494995
|
-
if (tempAudioPath &&
|
|
495125
|
+
if (tempAudioPath && existsSync64(tempAudioPath)) {
|
|
494996
495126
|
const { unlink: unlinkFile } = await import("node:fs/promises");
|
|
494997
495127
|
await unlinkFile(tempAudioPath).catch(() => {
|
|
494998
495128
|
});
|
|
@@ -495079,7 +495209,7 @@ async function executeAutoShorts(options) {
|
|
|
495079
495209
|
return { success: false, shorts: [], error: "FFmpeg not found" };
|
|
495080
495210
|
}
|
|
495081
495211
|
const absPath = resolve67(process.cwd(), options.video);
|
|
495082
|
-
if (!
|
|
495212
|
+
if (!existsSync64(absPath)) {
|
|
495083
495213
|
return { success: false, shorts: [], error: `File not found: ${absPath}` };
|
|
495084
495214
|
}
|
|
495085
495215
|
const targetDuration = options.duration ?? 60;
|
|
@@ -495092,7 +495222,7 @@ async function executeAutoShorts(options) {
|
|
|
495092
495222
|
}
|
|
495093
495223
|
const gemini = new GeminiProvider();
|
|
495094
495224
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
495095
|
-
const videoBuffer = await
|
|
495225
|
+
const videoBuffer = await readFile39(absPath);
|
|
495096
495226
|
const geminiPrompt = `Analyze this video to find the BEST moments for short-form vertical video content (TikTok, YouTube Shorts, Instagram Reels).
|
|
495097
495227
|
|
|
495098
495228
|
Find ${shortCount * 3} potential clips that are ${targetDuration} seconds or shorter each.
|
|
@@ -495169,7 +495299,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
495169
495299
|
await execSafe("ffmpeg", ["-i", absPath, "-vn", "-acodec", "libmp3lame", "-q:a", "2", tempAudio, "-y"]);
|
|
495170
495300
|
const whisper = new WhisperProvider();
|
|
495171
495301
|
await whisper.initialize({ apiKey: openaiApiKey });
|
|
495172
|
-
const audioBuffer = await
|
|
495302
|
+
const audioBuffer = await readFile39(tempAudio);
|
|
495173
495303
|
const audioBlob = new Blob([audioBuffer]);
|
|
495174
495304
|
const transcript = await whisper.transcribe(audioBlob, options.language);
|
|
495175
495305
|
try {
|
|
@@ -495207,7 +495337,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
495207
495337
|
};
|
|
495208
495338
|
}
|
|
495209
495339
|
const outputDir = options.outputDir ? resolve67(process.cwd(), options.outputDir) : dirname31(absPath);
|
|
495210
|
-
if (options.outputDir && !
|
|
495340
|
+
if (options.outputDir && !existsSync64(outputDir)) {
|
|
495211
495341
|
await mkdir27(outputDir, { recursive: true });
|
|
495212
495342
|
}
|
|
495213
495343
|
const result = {
|
|
@@ -495286,8 +495416,8 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
495286
495416
|
// ../cli/src/pipeline/executor.ts
|
|
495287
495417
|
var import_yaml7 = __toESM(require_dist3(), 1);
|
|
495288
495418
|
import { resolve as resolve69 } from "node:path";
|
|
495289
|
-
import { readFile as
|
|
495290
|
-
import { existsSync as
|
|
495419
|
+
import { readFile as readFile41, writeFile as writeFile47, mkdir as mkdir28 } from "node:fs/promises";
|
|
495420
|
+
import { existsSync as existsSync65 } from "node:fs";
|
|
495291
495421
|
|
|
495292
495422
|
// ../cli/src/pipeline/resolver.ts
|
|
495293
495423
|
function resolveStepParams(params, completedSteps) {
|
|
@@ -495700,10 +495830,10 @@ async function ensureActionsRegistered() {
|
|
|
495700
495830
|
}
|
|
495701
495831
|
async function loadPipeline(filePath) {
|
|
495702
495832
|
const absPath = resolve69(process.cwd(), filePath);
|
|
495703
|
-
if (!
|
|
495833
|
+
if (!existsSync65(absPath)) {
|
|
495704
495834
|
throw new Error(`Pipeline file not found: ${absPath}`);
|
|
495705
495835
|
}
|
|
495706
|
-
const content = await
|
|
495836
|
+
const content = await readFile41(absPath, "utf-8");
|
|
495707
495837
|
const manifest2 = (0, import_yaml7.parse)(content);
|
|
495708
495838
|
if (!manifest2.name) throw new Error("Pipeline missing 'name' field");
|
|
495709
495839
|
if (!manifest2.steps || !Array.isArray(manifest2.steps)) throw new Error("Pipeline missing 'steps' array");
|
|
@@ -495726,8 +495856,8 @@ async function executePipeline(manifest2, options = {}) {
|
|
|
495726
495856
|
const startTime = Date.now();
|
|
495727
495857
|
if (options.resume) {
|
|
495728
495858
|
const checkpointPath = resolve69(outputDir, CHECKPOINT_FILE);
|
|
495729
|
-
if (
|
|
495730
|
-
const checkpointContent = await
|
|
495859
|
+
if (existsSync65(checkpointPath)) {
|
|
495860
|
+
const checkpointContent = await readFile41(checkpointPath, "utf-8");
|
|
495731
495861
|
const checkpoint = (0, import_yaml7.parse)(checkpointContent);
|
|
495732
495862
|
for (const cs of checkpoint.completedSteps) {
|
|
495733
495863
|
completedSteps.set(cs.id, {
|
|
@@ -495999,7 +496129,7 @@ var pipelineRunTool = defineTool({
|
|
|
495999
496129
|
let resolvedPath = args.pipelinePath;
|
|
496000
496130
|
let tempPath;
|
|
496001
496131
|
if (args.pipelineYaml) {
|
|
496002
|
-
tempPath =
|
|
496132
|
+
tempPath = join41(tmpdir6(), `vibe-mcp-pipeline-${Date.now()}.yaml`);
|
|
496003
496133
|
await writeFile48(tempPath, args.pipelineYaml, "utf-8");
|
|
496004
496134
|
resolvedPath = tempPath;
|
|
496005
496135
|
}
|
|
@@ -496175,10 +496305,10 @@ init_project_resolver();
|
|
|
496175
496305
|
// ../cli/src/tools/manifest/_project-io.ts
|
|
496176
496306
|
init_engine();
|
|
496177
496307
|
init_project_resolver();
|
|
496178
|
-
import { readFile as
|
|
496308
|
+
import { readFile as readFile42, writeFile as writeFile49 } from "node:fs/promises";
|
|
496179
496309
|
async function loadProject(projectPath, cwd) {
|
|
496180
496310
|
const absPath = await resolveTimelineFile(projectPath, cwd);
|
|
496181
|
-
const content = await
|
|
496311
|
+
const content = await readFile42(absPath, "utf-8");
|
|
496182
496312
|
const data = JSON.parse(content);
|
|
496183
496313
|
return { project: Project.fromJSON(data), absPath };
|
|
496184
496314
|
}
|
|
@@ -496529,12 +496659,12 @@ init_engine();
|
|
|
496529
496659
|
|
|
496530
496660
|
// ../cli/src/commands/_shared/project-list.ts
|
|
496531
496661
|
init_storyboard_parse();
|
|
496532
|
-
import { readdir as readdir8, readFile as
|
|
496533
|
-
import { existsSync as
|
|
496534
|
-
import { join as
|
|
496662
|
+
import { readdir as readdir8, readFile as readFile43, stat as stat7 } from "node:fs/promises";
|
|
496663
|
+
import { existsSync as existsSync66 } from "node:fs";
|
|
496664
|
+
import { join as join43, resolve as resolve71 } from "node:path";
|
|
496535
496665
|
async function executeProjectList(opts = {}) {
|
|
496536
496666
|
const workspaceDir = resolve71(opts.workspaceDir ?? ".");
|
|
496537
|
-
if (!
|
|
496667
|
+
if (!existsSync66(workspaceDir)) {
|
|
496538
496668
|
return {
|
|
496539
496669
|
success: false,
|
|
496540
496670
|
workspaceDir,
|
|
@@ -496551,11 +496681,11 @@ async function executeProjectList(opts = {}) {
|
|
|
496551
496681
|
if (entry.name === "node_modules") continue;
|
|
496552
496682
|
if (entry.name.startsWith(".")) continue;
|
|
496553
496683
|
if (entry.name.startsWith("_")) {
|
|
496554
|
-
archivedCount += await countProjects(
|
|
496684
|
+
archivedCount += await countProjects(join43(workspaceDir, entry.name));
|
|
496555
496685
|
continue;
|
|
496556
496686
|
}
|
|
496557
|
-
const projectDir =
|
|
496558
|
-
if (!
|
|
496687
|
+
const projectDir = join43(workspaceDir, entry.name);
|
|
496688
|
+
if (!existsSync66(join43(projectDir, "STORYBOARD.md"))) continue;
|
|
496559
496689
|
projects.push(await describeProject(entry.name, projectDir));
|
|
496560
496690
|
}
|
|
496561
496691
|
projects.sort((a2, b2) => b2.updatedAt.localeCompare(a2.updatedAt));
|
|
@@ -496565,7 +496695,7 @@ async function countProjects(dir) {
|
|
|
496565
496695
|
try {
|
|
496566
496696
|
const entries2 = await readdir8(dir, { withFileTypes: true });
|
|
496567
496697
|
return entries2.filter(
|
|
496568
|
-
(e2) => e2.isDirectory() &&
|
|
496698
|
+
(e2) => e2.isDirectory() && existsSync66(join43(dir, e2.name, "STORYBOARD.md"))
|
|
496569
496699
|
).length;
|
|
496570
496700
|
} catch {
|
|
496571
496701
|
return 0;
|
|
@@ -496576,8 +496706,8 @@ async function describeProject(name, projectDir) {
|
|
|
496576
496706
|
let storyboardDurationSec = 0;
|
|
496577
496707
|
const timestamps = [];
|
|
496578
496708
|
try {
|
|
496579
|
-
const storyboardPath =
|
|
496580
|
-
const parsed = parseStoryboard(await
|
|
496709
|
+
const storyboardPath = join43(projectDir, "STORYBOARD.md");
|
|
496710
|
+
const parsed = parseStoryboard(await readFile43(storyboardPath, "utf-8"));
|
|
496581
496711
|
beats = parsed.beats.length;
|
|
496582
496712
|
storyboardDurationSec = Number(
|
|
496583
496713
|
parsed.beats.reduce((sum, beat) => sum + (beat.duration ?? 0), 0).toFixed(2)
|
|
@@ -496588,8 +496718,8 @@ async function describeProject(name, projectDir) {
|
|
|
496588
496718
|
let buildStatus;
|
|
496589
496719
|
let buildUpdatedAt;
|
|
496590
496720
|
try {
|
|
496591
|
-
const reportPath =
|
|
496592
|
-
const report = JSON.parse(await
|
|
496721
|
+
const reportPath = join43(projectDir, "build-report.json");
|
|
496722
|
+
const report = JSON.parse(await readFile43(reportPath, "utf-8"));
|
|
496593
496723
|
buildStatus = report.status ?? report.phase;
|
|
496594
496724
|
buildUpdatedAt = report.updatedAt;
|
|
496595
496725
|
timestamps.push((await stat7(reportPath)).mtimeMs);
|
|
@@ -496597,12 +496727,12 @@ async function describeProject(name, projectDir) {
|
|
|
496597
496727
|
}
|
|
496598
496728
|
let latestRender;
|
|
496599
496729
|
try {
|
|
496600
|
-
const rendersDir =
|
|
496730
|
+
const rendersDir = join43(projectDir, "renders");
|
|
496601
496731
|
const files = await readdir8(rendersDir);
|
|
496602
496732
|
let newest;
|
|
496603
496733
|
for (const file of files) {
|
|
496604
496734
|
if (!/\.(mp4|webm|mov)$/i.test(file)) continue;
|
|
496605
|
-
const { mtimeMs } = await stat7(
|
|
496735
|
+
const { mtimeMs } = await stat7(join43(rendersDir, file));
|
|
496606
496736
|
if (!newest || mtimeMs > newest.mtimeMs) newest = { file, mtimeMs };
|
|
496607
496737
|
}
|
|
496608
496738
|
if (newest) {
|
|
@@ -496737,7 +496867,7 @@ init_exec_safe();
|
|
|
496737
496867
|
init_output();
|
|
496738
496868
|
init_validate();
|
|
496739
496869
|
init_project_resolver();
|
|
496740
|
-
import { readFile as
|
|
496870
|
+
import { readFile as readFile44, access as access6 } from "node:fs/promises";
|
|
496741
496871
|
import { resolve as resolve74, basename as basename20 } from "node:path";
|
|
496742
496872
|
import { spawn as spawn9 } from "node:child_process";
|
|
496743
496873
|
function timelineBaseName(path14) {
|
|
@@ -496814,7 +496944,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
496814
496944
|
};
|
|
496815
496945
|
}
|
|
496816
496946
|
const filePath = await resolveTimelineFile(projectPath);
|
|
496817
|
-
const content = await
|
|
496947
|
+
const content = await readFile44(filePath, "utf-8");
|
|
496818
496948
|
const data = JSON.parse(content);
|
|
496819
496949
|
const project = Project.fromJSON(data);
|
|
496820
496950
|
const summary = project.getSummary();
|
|
@@ -496938,7 +497068,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
496938
497068
|
}
|
|
496939
497069
|
spinner2.text = "Loading project...";
|
|
496940
497070
|
const filePath = await resolveTimelineFile(projectPath);
|
|
496941
|
-
const content = await
|
|
497071
|
+
const content = await readFile44(filePath, "utf-8");
|
|
496942
497072
|
const data = JSON.parse(content);
|
|
496943
497073
|
const project = Project.fromJSON(data);
|
|
496944
497074
|
const summary = project.getSummary();
|
|
@@ -497536,14 +497666,14 @@ function getPresetSettings(preset, aspectRatio2) {
|
|
|
497536
497666
|
}
|
|
497537
497667
|
async function runHyperframesExport(projectPath, options, spinner2, startedAt) {
|
|
497538
497668
|
spinner2.text = "Loading project...";
|
|
497539
|
-
const { readFile:
|
|
497669
|
+
const { readFile: readFile47 } = await import("node:fs/promises");
|
|
497540
497670
|
const { resolve: resolve80 } = await import("node:path");
|
|
497541
497671
|
const { Project: Project2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
|
|
497542
497672
|
const { createHyperframesBackend: createHyperframesBackend2 } = await Promise.resolve().then(() => (init_hyperframes(), hyperframes_exports));
|
|
497543
497673
|
const { exitWithError: exitWithError2, generalError: generalError2, outputSuccess: outputSuccess2 } = await Promise.resolve().then(() => (init_output(), output_exports));
|
|
497544
497674
|
const chalk2 = (await Promise.resolve().then(() => (init_source(), source_exports))).default;
|
|
497545
497675
|
const filePath = await resolveTimelineFile(projectPath);
|
|
497546
|
-
const content = await
|
|
497676
|
+
const content = await readFile47(filePath, "utf-8");
|
|
497547
497677
|
const project = Project2.fromJSON(JSON.parse(content));
|
|
497548
497678
|
const state = project.getState();
|
|
497549
497679
|
const outputPath = options.output ? resolve80(process.cwd(), options.output) : resolve80(process.cwd(), `${timelineBaseName(projectPath)}.${options.format ?? "mp4"}`);
|
|
@@ -497612,8 +497742,8 @@ var exportVideoTool = defineTool({
|
|
|
497612
497742
|
var exportTools = [exportVideoTool];
|
|
497613
497743
|
|
|
497614
497744
|
// ../cli/src/tools/manifest/agent-only.ts
|
|
497615
|
-
import { readFile as
|
|
497616
|
-
import { resolve as resolve76, join as
|
|
497745
|
+
import { readFile as readFile45, writeFile as writeFile52, readdir as readdir9, stat as stat8, access as access7, unlink as unlink7 } from "node:fs/promises";
|
|
497746
|
+
import { resolve as resolve76, join as join44, basename as basename21, extname as extname14 } from "node:path";
|
|
497617
497747
|
import { z as z13 } from "zod";
|
|
497618
497748
|
init_engine();
|
|
497619
497749
|
init_exec_safe();
|
|
@@ -497692,7 +497822,7 @@ var fsListTool = defineTool({
|
|
|
497692
497822
|
const results = [];
|
|
497693
497823
|
for (const entry of entries2) {
|
|
497694
497824
|
if (args.pattern && !matchPattern(entry.name, args.pattern)) continue;
|
|
497695
|
-
const fullPath =
|
|
497825
|
+
const fullPath = join44(absPath, entry.name);
|
|
497696
497826
|
const stats = await stat8(fullPath);
|
|
497697
497827
|
if (entry.isDirectory()) {
|
|
497698
497828
|
results.push(`[DIR] ${entry.name}/`);
|
|
@@ -497721,7 +497851,7 @@ var fsReadTool = defineTool({
|
|
|
497721
497851
|
async execute(args, ctx) {
|
|
497722
497852
|
try {
|
|
497723
497853
|
const absPath = resolve76(ctx.workingDirectory, args.path);
|
|
497724
|
-
const content = await
|
|
497854
|
+
const content = await readFile45(absPath, "utf-8");
|
|
497725
497855
|
const maxLength = 4e3;
|
|
497726
497856
|
const truncated = content.length > maxLength;
|
|
497727
497857
|
const output3 = truncated ? content.substring(0, maxLength) + "\n... (truncated)" : content;
|
|
@@ -497794,7 +497924,7 @@ var batchImportTool = defineTool({
|
|
|
497794
497924
|
async execute(args, ctx) {
|
|
497795
497925
|
try {
|
|
497796
497926
|
const filePath = resolve76(ctx.workingDirectory, args.project);
|
|
497797
|
-
const content = await
|
|
497927
|
+
const content = await readFile45(filePath, "utf-8");
|
|
497798
497928
|
const data = JSON.parse(content);
|
|
497799
497929
|
const project = Project.fromJSON(data);
|
|
497800
497930
|
const dirPath = resolve76(ctx.workingDirectory, args.directory);
|
|
@@ -497805,7 +497935,7 @@ var batchImportTool = defineTool({
|
|
|
497805
497935
|
const scanDir = async (dir) => {
|
|
497806
497936
|
const entries2 = await readdir9(dir, { withFileTypes: true });
|
|
497807
497937
|
for (const entry of entries2) {
|
|
497808
|
-
const entryPath =
|
|
497938
|
+
const entryPath = join44(dir, entry.name);
|
|
497809
497939
|
if (entry.isDirectory() && recursive) {
|
|
497810
497940
|
await scanDir(entryPath);
|
|
497811
497941
|
} else if (entry.isFile()) {
|
|
@@ -497866,7 +497996,7 @@ var batchConcatTool = defineTool({
|
|
|
497866
497996
|
async execute(args, ctx) {
|
|
497867
497997
|
try {
|
|
497868
497998
|
const filePath = resolve76(ctx.workingDirectory, args.project);
|
|
497869
|
-
const content = await
|
|
497999
|
+
const content = await readFile45(filePath, "utf-8");
|
|
497870
498000
|
const data = JSON.parse(content);
|
|
497871
498001
|
const project = Project.fromJSON(data);
|
|
497872
498002
|
const sourceIds = args.sourceIds ?? [];
|
|
@@ -497937,7 +498067,7 @@ var batchApplyEffectTool = defineTool({
|
|
|
497937
498067
|
async execute(args, ctx) {
|
|
497938
498068
|
try {
|
|
497939
498069
|
const filePath = resolve76(ctx.workingDirectory, args.project);
|
|
497940
|
-
const content = await
|
|
498070
|
+
const content = await readFile45(filePath, "utf-8");
|
|
497941
498071
|
const data = JSON.parse(content);
|
|
497942
498072
|
const project = Project.fromJSON(data);
|
|
497943
498073
|
const clipIds = args.clipIds ?? [];
|
|
@@ -497992,7 +498122,7 @@ var timelineClearTool = defineTool({
|
|
|
497992
498122
|
async execute(args, ctx) {
|
|
497993
498123
|
try {
|
|
497994
498124
|
const filePath = await resolveTimelineFile(args.project, ctx.workingDirectory);
|
|
497995
|
-
const content = await
|
|
498125
|
+
const content = await readFile45(filePath, "utf-8");
|
|
497996
498126
|
const data = JSON.parse(content);
|
|
497997
498127
|
const project = Project.fromJSON(data);
|
|
497998
498128
|
const what = args.what ?? "clips";
|
|
@@ -498069,7 +498199,7 @@ var projectSetTool = defineTool({
|
|
|
498069
498199
|
async execute(args, ctx) {
|
|
498070
498200
|
try {
|
|
498071
498201
|
const filePath = await resolveTimelineFile(args.projectPath, ctx.workingDirectory);
|
|
498072
|
-
const content = await
|
|
498202
|
+
const content = await readFile45(filePath, "utf-8");
|
|
498073
498203
|
const data = JSON.parse(content);
|
|
498074
498204
|
const project = Project.fromJSON(data);
|
|
498075
498205
|
const updates = [];
|
|
@@ -498343,8 +498473,8 @@ var mediaCompressTool = defineTool({
|
|
|
498343
498473
|
],
|
|
498344
498474
|
{ maxBuffer: 50 * 1024 * 1024 }
|
|
498345
498475
|
);
|
|
498346
|
-
const inputBuf = await
|
|
498347
|
-
const outputBuf = await
|
|
498476
|
+
const inputBuf = await readFile45(absInput);
|
|
498477
|
+
const outputBuf = await readFile45(outputPath);
|
|
498348
498478
|
const inputSize = inputBuf.length;
|
|
498349
498479
|
const outputSize = outputBuf.length;
|
|
498350
498480
|
const reduction = (inputSize - outputSize) / inputSize * 100;
|
|
@@ -499366,7 +499496,7 @@ async function handleToolCall(name, args, extra) {
|
|
|
499366
499496
|
|
|
499367
499497
|
// src/resources/index.ts
|
|
499368
499498
|
init_engine();
|
|
499369
|
-
import { readFile as
|
|
499499
|
+
import { readFile as readFile46 } from "node:fs/promises";
|
|
499370
499500
|
import { resolve as resolve78 } from "node:path";
|
|
499371
499501
|
var resources = [
|
|
499372
499502
|
{
|
|
@@ -499403,7 +499533,7 @@ var resources = [
|
|
|
499403
499533
|
var currentProjectPath = process.env.VIBE_PROJECT_PATH || null;
|
|
499404
499534
|
async function loadProject2(projectPath) {
|
|
499405
499535
|
const absPath = resolve78(process.cwd(), projectPath);
|
|
499406
|
-
const content = await
|
|
499536
|
+
const content = await readFile46(absPath, "utf-8");
|
|
499407
499537
|
const data = JSON.parse(content);
|
|
499408
499538
|
return Project.fromJSON(data);
|
|
499409
499539
|
}
|
|
@@ -499795,14 +499925,14 @@ This creates a music video-style edit where cuts happen in rhythm with the music
|
|
|
499795
499925
|
}
|
|
499796
499926
|
|
|
499797
499927
|
// src/instructions.ts
|
|
499798
|
-
import { existsSync as
|
|
499928
|
+
import { existsSync as existsSync67, mkdirSync as mkdirSync13 } from "node:fs";
|
|
499799
499929
|
import { delimiter, isAbsolute as isAbsolute9, resolve as resolve79 } from "node:path";
|
|
499800
499930
|
var DEFAULT_EXTRA_PATH_DIRS = process.platform === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin", "/opt/local/bin"] : ["/usr/local/bin"];
|
|
499801
499931
|
function ensureSystemPath(env4 = process.env, extraDirs = DEFAULT_EXTRA_PATH_DIRS) {
|
|
499802
499932
|
const current = (env4.PATH ?? "").split(delimiter).filter(Boolean);
|
|
499803
499933
|
const added = [];
|
|
499804
499934
|
for (const dir of extraDirs) {
|
|
499805
|
-
if (!current.includes(dir) &&
|
|
499935
|
+
if (!current.includes(dir) && existsSync67(dir)) {
|
|
499806
499936
|
current.push(dir);
|
|
499807
499937
|
added.push(dir);
|
|
499808
499938
|
}
|
|
@@ -499904,7 +500034,7 @@ function handleCliFlags(argv, version) {
|
|
|
499904
500034
|
}
|
|
499905
500035
|
|
|
499906
500036
|
// src/index.ts
|
|
499907
|
-
if (handleCliFlags(process.argv.slice(2), "0.113.
|
|
500037
|
+
if (handleCliFlags(process.argv.slice(2), "0.113.11")) {
|
|
499908
500038
|
process.exit(0);
|
|
499909
500039
|
}
|
|
499910
500040
|
console.log = (...args) => console.error(...args);
|
|
@@ -499917,7 +500047,7 @@ var server2 = new Server(
|
|
|
499917
500047
|
{
|
|
499918
500048
|
name: "vibeframe",
|
|
499919
500049
|
// Stamped with the package version by build.js at bundle time.
|
|
499920
|
-
version: "0.113.
|
|
500050
|
+
version: "0.113.11"
|
|
499921
500051
|
},
|
|
499922
500052
|
{
|
|
499923
500053
|
capabilities: {
|