@vibeframe/mcp-server 0.113.9 → 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 +691 -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;
|
|
@@ -470555,6 +470643,13 @@ ${finalDurationBullet}
|
|
|
470555
470643
|
- If the beat cues include \`narration\`, do not embed an \`<audio>\` tag in the
|
|
470556
470644
|
scene fragment. The root timeline wires \`assets/narration-${ctx.beat.id}.wav\`
|
|
470557
470645
|
or \`assets/narration-${ctx.beat.id}.mp3\` separately.
|
|
470646
|
+
- Do NOT invent sound effects. This scene fragment is visual-only: never add
|
|
470647
|
+
an \`<audio>\` tag, and never imply ambient/foley SFX (keyboard clicks, whoosh,
|
|
470648
|
+
applause, room tone) that the beat did not explicitly request. Audio comes
|
|
470649
|
+
only from the beat's explicit \`narration\` and \`music\` cues, wired by the
|
|
470650
|
+
root timeline. If the beat declares an explicit \`sfx\` cue, treat it as intent
|
|
470651
|
+
for the storyboard author \u2014 still do not embed it here \u2014 and only when it is
|
|
470652
|
+
clearly tied to the beat's narration/motion; ignore orphaned or generic SFX.
|
|
470558
470653
|
- **\`.clip\` elements get visibility control from the framework but NO
|
|
470559
470654
|
sizing.** Always give \`.clip\` explicit fill via CSS:
|
|
470560
470655
|
\`{ position: absolute; inset: 0; }\` (or equivalent
|
|
@@ -470620,7 +470715,7 @@ ${ctx.storyboardGlobal || "(no global direction)"}
|
|
|
470620
470715
|
|
|
470621
470716
|
## ${ctx.beat.heading}
|
|
470622
470717
|
${formatBeatCues(ctx.beat.cues)}${cueDurationNote}
|
|
470623
|
-
${ctx.beat.body}
|
|
470718
|
+
${ctx.beat.body}${formatTranscriptSection(ctx.transcript)}
|
|
470624
470719
|
|
|
470625
470720
|
=== Output format ===
|
|
470626
470721
|
|
|
@@ -470640,7 +470735,7 @@ function computeCacheKey(parts) {
|
|
|
470640
470735
|
return createHash5("sha256").update(parts.provider).update("\u241E").update(parts.model).update("\u241E").update(parts.systemPrompt).update("\u241E").update(parts.userPrompt).digest("hex");
|
|
470641
470736
|
}
|
|
470642
470737
|
function defaultCacheDir() {
|
|
470643
|
-
return
|
|
470738
|
+
return join25(USER_CACHE_DIR, "compose-scenes");
|
|
470644
470739
|
}
|
|
470645
470740
|
function extractHtml(responseText) {
|
|
470646
470741
|
const fenced = responseText.match(/```html\s*\n([\s\S]*?)\n```/);
|
|
@@ -470664,9 +470759,9 @@ async function composeBeatHtml(ctx, overrides) {
|
|
|
470664
470759
|
model: settings.model
|
|
470665
470760
|
});
|
|
470666
470761
|
const cacheDir = ctx.cacheDir ?? defaultCacheDir();
|
|
470667
|
-
const cachePath =
|
|
470668
|
-
if (
|
|
470669
|
-
const html2 = await
|
|
470762
|
+
const cachePath = join25(cacheDir, `${cacheKey2}.html`);
|
|
470763
|
+
if (existsSync25(cachePath)) {
|
|
470764
|
+
const html2 = await readFile10(cachePath, "utf-8");
|
|
470670
470765
|
return { html: html2, cached: true, cacheKey: cacheKey2, model: settings.model, provider: ctx.provider };
|
|
470671
470766
|
}
|
|
470672
470767
|
if (!ctx.apiKey) {
|
|
@@ -470802,14 +470897,14 @@ async function executeComposeScenesWithSkills(params, outputDir, overrides) {
|
|
|
470802
470897
|
const projectRoot = params.project ? resolve18(outputDir, params.project) : resolve18(outputDir);
|
|
470803
470898
|
const designPath = resolve18(projectRoot, params.design ?? "DESIGN.md");
|
|
470804
470899
|
const storyboardPath = resolve18(projectRoot, params.storyboard ?? "STORYBOARD.md");
|
|
470805
|
-
if (!
|
|
470900
|
+
if (!existsSync25(designPath)) {
|
|
470806
470901
|
return { success: false, error: `DESIGN.md not found at ${designPath}` };
|
|
470807
470902
|
}
|
|
470808
|
-
if (!
|
|
470903
|
+
if (!existsSync25(storyboardPath)) {
|
|
470809
470904
|
return { success: false, error: `STORYBOARD.md not found at ${storyboardPath}` };
|
|
470810
470905
|
}
|
|
470811
|
-
const designMd = await
|
|
470812
|
-
const storyboardMd = await
|
|
470906
|
+
const designMd = await readFile10(designPath, "utf-8");
|
|
470907
|
+
const storyboardMd = await readFile10(storyboardPath, "utf-8");
|
|
470813
470908
|
const { global: storyboardGlobal, beats } = parseStoryboard(storyboardMd);
|
|
470814
470909
|
if (beats.length === 0) {
|
|
470815
470910
|
return {
|
|
@@ -470829,7 +470924,7 @@ async function executeComposeScenesWithSkills(params, outputDir, overrides) {
|
|
|
470829
470924
|
provider = params.composer ?? "claude";
|
|
470830
470925
|
apiKey = "";
|
|
470831
470926
|
}
|
|
470832
|
-
const compositionsDir =
|
|
470927
|
+
const compositionsDir = join25(projectRoot, "compositions");
|
|
470833
470928
|
await mkdir9(compositionsDir, { recursive: true });
|
|
470834
470929
|
let finalDurations = /* @__PURE__ */ new Map();
|
|
470835
470930
|
try {
|
|
@@ -470843,6 +470938,7 @@ async function executeComposeScenesWithSkills(params, outputDir, overrides) {
|
|
|
470843
470938
|
async (beat, beatIndex) => {
|
|
470844
470939
|
onProgress({ type: "beat-start", beatId: beat.id, beatIndex, totalBeats });
|
|
470845
470940
|
try {
|
|
470941
|
+
const transcript = await readBeatTranscript(projectRoot, beat.id);
|
|
470846
470942
|
const result = await composeBeatWithRetry(
|
|
470847
470943
|
{
|
|
470848
470944
|
beat,
|
|
@@ -470853,11 +470949,12 @@ async function executeComposeScenesWithSkills(params, outputDir, overrides) {
|
|
|
470853
470949
|
apiKey,
|
|
470854
470950
|
effort: params.effort,
|
|
470855
470951
|
cacheDir: params.cacheDir,
|
|
470856
|
-
finalDurationSec: finalDurations.get(beat.id)
|
|
470952
|
+
finalDurationSec: finalDurations.get(beat.id),
|
|
470953
|
+
transcript
|
|
470857
470954
|
},
|
|
470858
470955
|
overrides
|
|
470859
470956
|
);
|
|
470860
|
-
const compositionPath =
|
|
470957
|
+
const compositionPath = join25(compositionsDir, `scene-${beat.id}.html`);
|
|
470861
470958
|
await mkdir9(dirname13(compositionPath), { recursive: true });
|
|
470862
470959
|
await writeFile14(compositionPath, result.html, "utf-8");
|
|
470863
470960
|
if (result.cached) {
|
|
@@ -470936,7 +471033,7 @@ ${failures.map((f2) => ` - ${f2.beatId}: ${f2.error}`).join("\n")}`,
|
|
|
470936
471033
|
data: aggregateData
|
|
470937
471034
|
};
|
|
470938
471035
|
}
|
|
470939
|
-
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;
|
|
470940
471037
|
var init_compose_scenes_skills = __esm({
|
|
470941
471038
|
"../cli/src/commands/_shared/compose-scenes-skills.ts"() {
|
|
470942
471039
|
"use strict";
|
|
@@ -470952,6 +471049,7 @@ var init_compose_scenes_skills = __esm({
|
|
|
470952
471049
|
init_root_sync();
|
|
470953
471050
|
init_composer_resolve();
|
|
470954
471051
|
init_config();
|
|
471052
|
+
init_transcribe_narration();
|
|
470955
471053
|
MODEL_SETTINGS_BY_PROVIDER = {
|
|
470956
471054
|
// Anthropic Claude Sonnet 4.6 — v0.69 baseline. ~9 s/beat, $3/$15 per MTok.
|
|
470957
471055
|
claude: {
|
|
@@ -470975,6 +471073,7 @@ var init_compose_scenes_skills = __esm({
|
|
|
470975
471073
|
high: { model: GEMINI_DEFAULT_TEXT_MODEL, maxTokens: 8e3, costPerMTokIn: 1.5, costPerMTokOut: 9 }
|
|
470976
471074
|
}
|
|
470977
471075
|
};
|
|
471076
|
+
TRANSCRIPT_PROMPT_MAX_WORDS = 120;
|
|
470978
471077
|
ComposeBeatError = class extends Error {
|
|
470979
471078
|
constructor(code, message, cause) {
|
|
470980
471079
|
super(message);
|
|
@@ -471060,22 +471159,22 @@ var init_compose_scenes_skills = __esm({
|
|
|
471060
471159
|
});
|
|
471061
471160
|
|
|
471062
471161
|
// ../cli/src/commands/_shared/compose-prompts.ts
|
|
471063
|
-
import { existsSync as
|
|
471064
|
-
import { readFile as
|
|
471065
|
-
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";
|
|
471066
471165
|
async function getComposePrompts(opts) {
|
|
471067
471166
|
const projectDir = resolve19(opts.projectDir);
|
|
471068
|
-
const designPath =
|
|
471069
|
-
const storyboardPath =
|
|
471070
|
-
const skillPath =
|
|
471071
|
-
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");
|
|
471072
471171
|
const warnings = [];
|
|
471073
471172
|
const baseError = (msg) => ({
|
|
471074
471173
|
success: false,
|
|
471075
471174
|
projectDir,
|
|
471076
471175
|
designReference: "DESIGN.md",
|
|
471077
471176
|
storyboardReference: "STORYBOARD.md",
|
|
471078
|
-
skillReference:
|
|
471177
|
+
skillReference: existsSync26(skillPath) ? "SKILL.md" : null,
|
|
471079
471178
|
compositionsDir: "compositions",
|
|
471080
471179
|
beats: [],
|
|
471081
471180
|
instructions: [],
|
|
@@ -471083,18 +471182,18 @@ async function getComposePrompts(opts) {
|
|
|
471083
471182
|
warnings,
|
|
471084
471183
|
error: msg
|
|
471085
471184
|
});
|
|
471086
|
-
if (!
|
|
471185
|
+
if (!existsSync26(designPath)) {
|
|
471087
471186
|
return baseError(`DESIGN.md not found at ${designPath}. Run \`vibe scene init <dir>\` first.`);
|
|
471088
471187
|
}
|
|
471089
|
-
if (!
|
|
471188
|
+
if (!existsSync26(storyboardPath)) {
|
|
471090
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.`);
|
|
471091
471190
|
}
|
|
471092
|
-
if (!
|
|
471191
|
+
if (!existsSync26(skillPath)) {
|
|
471093
471192
|
warnings.push(
|
|
471094
471193
|
"SKILL.md not installed \u2014 host agent won't have Hyperframes rules in context. Run `vibe scene install-skill` to install it."
|
|
471095
471194
|
);
|
|
471096
471195
|
}
|
|
471097
|
-
const storyboardMd = await
|
|
471196
|
+
const storyboardMd = await readFile11(storyboardPath, "utf-8");
|
|
471098
471197
|
const parsed = parseStoryboard(storyboardMd);
|
|
471099
471198
|
if (parsed.beats.length === 0) {
|
|
471100
471199
|
return baseError(`STORYBOARD.md has no \`## Beat \u2026\` headings.`);
|
|
@@ -471116,28 +471215,33 @@ async function getComposePrompts(opts) {
|
|
|
471116
471215
|
finalDurations = await resolveProjectBeatDurations(projectDir);
|
|
471117
471216
|
} catch {
|
|
471118
471217
|
}
|
|
471119
|
-
const result =
|
|
471120
|
-
|
|
471121
|
-
|
|
471122
|
-
|
|
471123
|
-
|
|
471124
|
-
beat
|
|
471125
|
-
|
|
471126
|
-
|
|
471127
|
-
|
|
471128
|
-
|
|
471129
|
-
|
|
471130
|
-
|
|
471131
|
-
|
|
471132
|
-
|
|
471133
|
-
|
|
471134
|
-
|
|
471135
|
-
|
|
471136
|
-
|
|
471137
|
-
|
|
471138
|
-
|
|
471139
|
-
|
|
471140
|
-
|
|
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;
|
|
471141
471245
|
const instructions = buildInstructions({
|
|
471142
471246
|
skillRef,
|
|
471143
471247
|
beatCount: result.length,
|
|
@@ -471185,13 +471289,14 @@ var init_compose_prompts = __esm({
|
|
|
471185
471289
|
init_compose_scenes_skills();
|
|
471186
471290
|
init_root_sync();
|
|
471187
471291
|
init_bundle();
|
|
471292
|
+
init_transcribe_narration();
|
|
471188
471293
|
}
|
|
471189
471294
|
});
|
|
471190
471295
|
|
|
471191
471296
|
// ../cli/src/commands/_shared/sub-comp-duration-sync.ts
|
|
471192
|
-
import { existsSync as
|
|
471193
|
-
import { readFile as
|
|
471194
|
-
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";
|
|
471195
471300
|
function syncSubCompositionDurationHtml(html, beatId, newDurationSec, fileRel) {
|
|
471196
471301
|
const compositionId = `scene-${beatId}`;
|
|
471197
471302
|
const file = fileRel ?? `compositions/${compositionId}.html`;
|
|
@@ -471283,15 +471388,15 @@ async function createSubCompDurationSyncPlans(opts) {
|
|
|
471283
471388
|
const results = [];
|
|
471284
471389
|
for (const beat of opts.beats) {
|
|
471285
471390
|
const fileRel = `compositions/scene-${beat.id}.html`;
|
|
471286
|
-
const filePath =
|
|
471287
|
-
if (!
|
|
471391
|
+
const filePath = join28(projectDir, fileRel);
|
|
471392
|
+
if (!existsSync28(filePath)) continue;
|
|
471288
471393
|
const newDurationSec = await resolveSyncedBeatDuration({
|
|
471289
471394
|
projectDir,
|
|
471290
471395
|
beatDuration: beat.duration,
|
|
471291
471396
|
narrationPath: beat.narrationPath,
|
|
471292
471397
|
sceneDurationSec: beat.sceneDurationSec
|
|
471293
471398
|
});
|
|
471294
|
-
const html = await
|
|
471399
|
+
const html = await readFile13(filePath, "utf-8");
|
|
471295
471400
|
const outcome = syncSubCompositionDurationHtml(html, beat.id, newDurationSec, fileRel);
|
|
471296
471401
|
results.push({ ...outcome, file: fileRel, beatId: beat.id });
|
|
471297
471402
|
}
|
|
@@ -471315,7 +471420,7 @@ var init_sub_comp_duration_sync = __esm({
|
|
|
471315
471420
|
});
|
|
471316
471421
|
|
|
471317
471422
|
// ../cli/src/commands/_shared/scene-repair.ts
|
|
471318
|
-
import { readFile as
|
|
471423
|
+
import { readFile as readFile14, writeFile as writeFile16 } from "node:fs/promises";
|
|
471319
471424
|
import { relative as relative7, resolve as resolve23 } from "node:path";
|
|
471320
471425
|
async function executeSceneRepair(opts) {
|
|
471321
471426
|
const projectDir = resolve23(opts.projectDir);
|
|
@@ -471360,7 +471465,7 @@ async function executeSceneRepair(opts) {
|
|
|
471360
471465
|
}
|
|
471361
471466
|
for (const target of targets) {
|
|
471362
471467
|
const rel = relative7(projectDir, target.abs) || target.abs;
|
|
471363
|
-
const html = await
|
|
471468
|
+
const html = await readFile14(target.abs, "utf-8");
|
|
471364
471469
|
const findings = lintHtml(html, rel, target.isSub);
|
|
471365
471470
|
const { html: nextHtml, fixedCodes } = applyMechanicalFixes(html, findings);
|
|
471366
471471
|
if (fixedCodes.length > 0) {
|
|
@@ -471733,15 +471838,15 @@ var init_storyboard_edit = __esm({
|
|
|
471733
471838
|
});
|
|
471734
471839
|
|
|
471735
471840
|
// ../cli/src/pipeline/renderers/chrome.ts
|
|
471736
|
-
import { existsSync as
|
|
471841
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
471737
471842
|
import { homedir as homedir7 } from "node:os";
|
|
471738
|
-
import { join as
|
|
471843
|
+
import { join as join29 } from "node:path";
|
|
471739
471844
|
function findChrome() {
|
|
471740
471845
|
const candidates = [
|
|
471741
471846
|
process.env.HYPERFRAMES_CHROME_PATH,
|
|
471742
471847
|
process.env.CHROME_PATH,
|
|
471743
471848
|
// puppeteer auto-downloaded headless shell
|
|
471744
|
-
|
|
471849
|
+
join29(
|
|
471745
471850
|
homedir7(),
|
|
471746
471851
|
".cache",
|
|
471747
471852
|
"puppeteer",
|
|
@@ -471759,7 +471864,7 @@ function findChrome() {
|
|
|
471759
471864
|
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
|
|
471760
471865
|
];
|
|
471761
471866
|
for (const c2 of candidates) {
|
|
471762
|
-
if (c2 &&
|
|
471867
|
+
if (c2 && existsSync30(c2)) return c2;
|
|
471763
471868
|
}
|
|
471764
471869
|
return void 0;
|
|
471765
471870
|
}
|
|
@@ -471791,7 +471896,7 @@ var init_ffmpeg_gate = __esm({
|
|
|
471791
471896
|
});
|
|
471792
471897
|
|
|
471793
471898
|
// ../cli/src/commands/_shared/scene-audio-scan.ts
|
|
471794
|
-
import { readFile as
|
|
471899
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
471795
471900
|
import { resolve as resolve25 } from "node:path";
|
|
471796
471901
|
function parseRootClips(rootHtml) {
|
|
471797
471902
|
const clips = [];
|
|
@@ -471832,7 +471937,7 @@ function makeFsCompositionReader(projectDir) {
|
|
|
471832
471937
|
return async (compositionSrcRel) => {
|
|
471833
471938
|
const abs = resolve25(projectDir, compositionSrcRel);
|
|
471834
471939
|
try {
|
|
471835
|
-
return await
|
|
471940
|
+
return await readFile16(abs, "utf-8");
|
|
471836
471941
|
} catch {
|
|
471837
471942
|
return null;
|
|
471838
471943
|
}
|
|
@@ -472032,9 +472137,9 @@ __export(scene_render_exports, {
|
|
|
472032
472137
|
qualityToCrf: () => qualityToCrf
|
|
472033
472138
|
});
|
|
472034
472139
|
import { execFile as execFile2 } from "node:child_process";
|
|
472035
|
-
import { existsSync as
|
|
472036
|
-
import { mkdir as mkdir12, readFile as
|
|
472037
|
-
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";
|
|
472038
472143
|
import { promisify as promisify2 } from "node:util";
|
|
472039
472144
|
function qualityToCrf(quality = "standard") {
|
|
472040
472145
|
return quality === "draft" ? 28 : quality === "high" ? 18 : 23;
|
|
@@ -472122,7 +472227,7 @@ async function executeSceneRender(opts = {}) {
|
|
|
472122
472227
|
}
|
|
472123
472228
|
let autoSyncApplied = false;
|
|
472124
472229
|
let autoSyncWarning;
|
|
472125
|
-
if (!opts.beatId &&
|
|
472230
|
+
if (!opts.beatId && existsSync31(join30(projectDir, "STORYBOARD.md"))) {
|
|
472126
472231
|
try {
|
|
472127
472232
|
const rootPlan = await createProjectRootSyncPlan({ projectDir });
|
|
472128
472233
|
const subPlans = await createSubCompDurationSyncPlans({
|
|
@@ -472214,7 +472319,7 @@ async function executeSceneRender(opts = {}) {
|
|
|
472214
472319
|
let audioMuxWarning;
|
|
472215
472320
|
try {
|
|
472216
472321
|
opts.onProgress?.(0.95, "Mixing audio");
|
|
472217
|
-
const rootHtml = await
|
|
472322
|
+
const rootHtml = await readFile17(resolve27(projectDir, root2), "utf-8");
|
|
472218
472323
|
const audios = await scanSceneAudio({ projectDir, rootHtml });
|
|
472219
472324
|
audioCount = audios.length;
|
|
472220
472325
|
if (audios.length > 0) {
|
|
@@ -472299,11 +472404,11 @@ async function safeStat(p2) {
|
|
|
472299
472404
|
}
|
|
472300
472405
|
async function prepareBeatRenderRoot(opts) {
|
|
472301
472406
|
const root2 = `.vibeframe/tmp/render-beat-${sanitizeFileSegment(opts.beatId)}.html`;
|
|
472302
|
-
const reportPath =
|
|
472407
|
+
const reportPath = join30(opts.projectDir, "build-report.json");
|
|
472303
472408
|
const retryWith = [
|
|
472304
472409
|
`vibe build ${opts.projectDir} --beat ${opts.beatId} --stage sync --json`
|
|
472305
472410
|
];
|
|
472306
|
-
if (!
|
|
472411
|
+
if (!existsSync31(reportPath)) {
|
|
472307
472412
|
return {
|
|
472308
472413
|
success: false,
|
|
472309
472414
|
root: root2,
|
|
@@ -472314,7 +472419,7 @@ async function prepareBeatRenderRoot(opts) {
|
|
|
472314
472419
|
}
|
|
472315
472420
|
let report;
|
|
472316
472421
|
try {
|
|
472317
|
-
report = JSON.parse(await
|
|
472422
|
+
report = JSON.parse(await readFile17(reportPath, "utf-8"));
|
|
472318
472423
|
} catch (error) {
|
|
472319
472424
|
return {
|
|
472320
472425
|
success: false,
|
|
@@ -472383,8 +472488,8 @@ async function prepareBeatRenderRoot(opts) {
|
|
|
472383
472488
|
durationSec,
|
|
472384
472489
|
narrationPath
|
|
472385
472490
|
});
|
|
472386
|
-
await mkdir12(dirname16(
|
|
472387
|
-
await writeFile18(
|
|
472491
|
+
await mkdir12(dirname16(join30(opts.projectDir, root2)), { recursive: true });
|
|
472492
|
+
await writeFile18(join30(opts.projectDir, root2), html, "utf-8");
|
|
472388
472493
|
return {
|
|
472389
472494
|
success: true,
|
|
472390
472495
|
root: root2,
|
|
@@ -472448,7 +472553,7 @@ function reportedBeatAssetPaths(beat) {
|
|
|
472448
472553
|
]);
|
|
472449
472554
|
}
|
|
472450
472555
|
async function writeRenderReport(projectDir, result) {
|
|
472451
|
-
const reportPath =
|
|
472556
|
+
const reportPath = join30(projectDir, "render-report.json");
|
|
472452
472557
|
try {
|
|
472453
472558
|
await writeFile18(
|
|
472454
472559
|
reportPath,
|
|
@@ -472490,7 +472595,7 @@ async function writeRenderReport(projectDir, result) {
|
|
|
472490
472595
|
}
|
|
472491
472596
|
function pathExists3(projectDir, value) {
|
|
472492
472597
|
const abs = isAbsolute3(value) ? value : resolve27(projectDir, value);
|
|
472493
|
-
return
|
|
472598
|
+
return existsSync31(abs);
|
|
472494
472599
|
}
|
|
472495
472600
|
function stringValue2(value) {
|
|
472496
472601
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
@@ -472564,7 +472669,7 @@ var init_concurrency = __esm({
|
|
|
472564
472669
|
});
|
|
472565
472670
|
|
|
472566
472671
|
// ../cli/src/commands/_shared/build-asset-reference.ts
|
|
472567
|
-
import { existsSync as
|
|
472672
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
472568
472673
|
import { extname as extname5, isAbsolute as isAbsolute4, relative as relative10, resolve as resolve28, sep } from "node:path";
|
|
472569
472674
|
function resolveTypedAssetReference(projectDir, kind3, value) {
|
|
472570
472675
|
const raw2 = stringOrUndefined2(value);
|
|
@@ -472595,7 +472700,7 @@ function resolveReference(projectDir, kind3, raw2, source3, forcedError) {
|
|
|
472595
472700
|
const absPath = isAbsolute4(raw2) ? resolve28(raw2) : resolve28(projectDir, raw2);
|
|
472596
472701
|
const rel = relative10(resolve28(projectDir), absPath);
|
|
472597
472702
|
const withinProject = rel.length > 0 && !rel.startsWith("..") && !isAbsolute4(rel);
|
|
472598
|
-
const exists = withinProject &&
|
|
472703
|
+
const exists = withinProject && existsSync33(absPath);
|
|
472599
472704
|
let error = forcedError;
|
|
472600
472705
|
if (!error && inferred && inferred !== kind3 && !isNarrationAudioReference(kind3, ext)) {
|
|
472601
472706
|
error = `Asset reference "${raw2}" is a ${inferred} asset, not ${kind3}.`;
|
|
@@ -472782,9 +472887,9 @@ var init_build_backdrop_prompt = __esm({
|
|
|
472782
472887
|
});
|
|
472783
472888
|
|
|
472784
472889
|
// ../cli/src/commands/_shared/build-plan.ts
|
|
472785
|
-
import { existsSync as
|
|
472786
|
-
import { readFile as
|
|
472787
|
-
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";
|
|
472788
472893
|
function backdropCostUsd(quality) {
|
|
472789
472894
|
return quality === "hd" ? 0.2 : 0.05;
|
|
472790
472895
|
}
|
|
@@ -472793,11 +472898,11 @@ async function createBuildPlan(opts) {
|
|
|
472793
472898
|
loadPlanEnv(projectDir);
|
|
472794
472899
|
const stage = opts.stage ?? "all";
|
|
472795
472900
|
const config4 = await readProjectConfig(projectDir);
|
|
472796
|
-
const storyboardPath =
|
|
472901
|
+
const storyboardPath = join31(projectDir, "STORYBOARD.md");
|
|
472797
472902
|
const warnings = [];
|
|
472798
472903
|
const retryWith = [];
|
|
472799
472904
|
const providerResolution = [];
|
|
472800
|
-
if (!
|
|
472905
|
+
if (!existsSync34(storyboardPath)) {
|
|
472801
472906
|
const validation4 = {
|
|
472802
472907
|
ok: false,
|
|
472803
472908
|
issues: [
|
|
@@ -472826,7 +472931,7 @@ async function createBuildPlan(opts) {
|
|
|
472826
472931
|
validation: validation4
|
|
472827
472932
|
});
|
|
472828
472933
|
}
|
|
472829
|
-
const storyboardMd = await
|
|
472934
|
+
const storyboardMd = await readFile18(storyboardPath, "utf-8");
|
|
472830
472935
|
const validation3 = validateStoryboardMarkdown(storyboardMd);
|
|
472831
472936
|
const validationIssues = [...validation3.issues];
|
|
472832
472937
|
const parsed = parseStoryboard(storyboardMd);
|
|
@@ -472852,7 +472957,7 @@ async function createBuildPlan(opts) {
|
|
|
472852
472957
|
const imageQuality = opts.imageQuality ?? config4.config.build.imageQuality ?? "hd";
|
|
472853
472958
|
const imageSize2 = opts.imageSize ?? config4.config.build.imageSize ?? "1536x1024";
|
|
472854
472959
|
const imageRatio = imageRatioForSize(imageSize2);
|
|
472855
|
-
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`)));
|
|
472856
472961
|
const resolved = await resolvePlanProviders({
|
|
472857
472962
|
projectDir,
|
|
472858
472963
|
config: config4,
|
|
@@ -473000,7 +473105,7 @@ async function createBuildPlan(opts) {
|
|
|
473000
473105
|
active: includeAssets
|
|
473001
473106
|
}) : null;
|
|
473002
473107
|
const compositionPath = `compositions/scene-${beat.id}.html`;
|
|
473003
|
-
const compositionExists =
|
|
473108
|
+
const compositionExists = existsSync34(join31(projectDir, compositionPath));
|
|
473004
473109
|
for (const asset of [narration, backdrop, keyframe, video, music]) {
|
|
473005
473110
|
if (!asset) continue;
|
|
473006
473111
|
if (asset.referenceError) {
|
|
@@ -473069,7 +473174,7 @@ async function createBuildPlan(opts) {
|
|
|
473069
473174
|
}
|
|
473070
473175
|
}
|
|
473071
473176
|
const validationOk = !validationIssues.some((issue) => issue.severity === "error");
|
|
473072
|
-
if (!
|
|
473177
|
+
if (!existsSync34(join31(projectDir, config4.config.composition.entry))) {
|
|
473073
473178
|
missing.add("root-composition");
|
|
473074
473179
|
if (validationOk) retryWith.push(`vibe build ${projectDir} --stage sync --json`);
|
|
473075
473180
|
}
|
|
@@ -473103,7 +473208,7 @@ async function createBuildPlan(opts) {
|
|
|
473103
473208
|
}
|
|
473104
473209
|
if (referenced.size > 0) {
|
|
473105
473210
|
const toGenerate = resolveCharacters(parsed.frontmatter).filter(
|
|
473106
|
-
(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`)))
|
|
473107
473212
|
);
|
|
473108
473213
|
if (toGenerate.length > 0) {
|
|
473109
473214
|
estimatedCostUsd += toGenerate.length * backdropCostUsd(opts.imageQuality ?? "hd");
|
|
@@ -473216,8 +473321,8 @@ function assetPlan(opts) {
|
|
|
473216
473321
|
reason: ready ? "referenced-asset" : "invalid-reference"
|
|
473217
473322
|
};
|
|
473218
473323
|
}
|
|
473219
|
-
const canonicalExists =
|
|
473220
|
-
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;
|
|
473221
473326
|
const freshness = assetFreshnessFromMetadata({
|
|
473222
473327
|
projectDir: opts.projectDir,
|
|
473223
473328
|
kind: opts.kind,
|
|
@@ -473415,7 +473520,7 @@ async function firstConfiguredComposer(projectDir) {
|
|
|
473415
473520
|
}
|
|
473416
473521
|
function firstExisting2(projectDir, paths) {
|
|
473417
473522
|
for (const path14 of paths) {
|
|
473418
|
-
if (
|
|
473523
|
+
if (existsSync34(join31(projectDir, path14))) return path14;
|
|
473419
473524
|
}
|
|
473420
473525
|
return null;
|
|
473421
473526
|
}
|
|
@@ -473456,12 +473561,12 @@ function unique3(items) {
|
|
|
473456
473561
|
return [...new Set(items.filter((item) => item.length > 0))];
|
|
473457
473562
|
}
|
|
473458
473563
|
function loadPlanEnv(projectDir) {
|
|
473459
|
-
(0, import_dotenv2.config)({ path:
|
|
473564
|
+
(0, import_dotenv2.config)({ path: join31(projectDir, ".env"), quiet: true });
|
|
473460
473565
|
(0, import_dotenv2.config)({ path: resolve29(process.cwd(), ".env"), quiet: true });
|
|
473461
473566
|
let dir = process.cwd();
|
|
473462
473567
|
while (dir !== dirname17(dir)) {
|
|
473463
|
-
if (
|
|
473464
|
-
(0, import_dotenv2.config)({ path:
|
|
473568
|
+
if (existsSync34(join31(dir, "pnpm-workspace.yaml"))) {
|
|
473569
|
+
(0, import_dotenv2.config)({ path: join31(dir, ".env"), quiet: true });
|
|
473465
473570
|
return;
|
|
473466
473571
|
}
|
|
473467
473572
|
dir = dirname17(dir);
|
|
@@ -473523,7 +473628,7 @@ var init_validate = __esm({
|
|
|
473523
473628
|
// ../cli/src/commands/generate/music.ts
|
|
473524
473629
|
import { resolve as resolve31 } from "node:path";
|
|
473525
473630
|
import { writeFile as writeFile19 } from "node:fs/promises";
|
|
473526
|
-
import { existsSync as
|
|
473631
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
473527
473632
|
async function executeMusic(options) {
|
|
473528
473633
|
try {
|
|
473529
473634
|
const provider = options.provider || "elevenlabs";
|
|
@@ -473676,7 +473781,7 @@ function registerMusicCommand(parent) {
|
|
|
473676
473781
|
if (options.melody) {
|
|
473677
473782
|
spinner2.text = "Uploading melody reference...";
|
|
473678
473783
|
const absPath = resolve31(process.cwd(), options.melody);
|
|
473679
|
-
if (!
|
|
473784
|
+
if (!existsSync35(absPath)) {
|
|
473680
473785
|
spinner2.fail(`Melody file not found: ${options.melody}`);
|
|
473681
473786
|
exitWithError(notFoundError(options.melody));
|
|
473682
473787
|
}
|
|
@@ -473809,9 +473914,9 @@ __export(scene_build_exports, {
|
|
|
473809
473914
|
executeSceneBuild: () => executeSceneBuild,
|
|
473810
473915
|
resolveSceneBuildMode: () => resolveSceneBuildMode
|
|
473811
473916
|
});
|
|
473812
|
-
import { existsSync as
|
|
473813
|
-
import { copyFile as copyFile4, mkdir as mkdir13, readFile as
|
|
473814
|
-
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";
|
|
473815
473920
|
async function executeSceneBuild(opts) {
|
|
473816
473921
|
const startedAt = Date.now();
|
|
473817
473922
|
const projectDir = resolve33(opts.projectDir);
|
|
@@ -473830,7 +473935,7 @@ async function executeSceneBuild(opts) {
|
|
|
473830
473935
|
);
|
|
473831
473936
|
}
|
|
473832
473937
|
let sceneRepair = skippedSceneRepairSummary();
|
|
473833
|
-
const storyboardPath =
|
|
473938
|
+
const storyboardPath = join33(projectDir, "STORYBOARD.md");
|
|
473834
473939
|
const buildPlan = await createBuildPlan({
|
|
473835
473940
|
projectDir,
|
|
473836
473941
|
stage: selectedStage,
|
|
@@ -473881,8 +473986,8 @@ async function executeSceneBuild(opts) {
|
|
|
473881
473986
|
}
|
|
473882
473987
|
if (!buildPlan.validation.ok) {
|
|
473883
473988
|
let invalidBeats = [];
|
|
473884
|
-
if (
|
|
473885
|
-
invalidBeats = parseStoryboard(await
|
|
473989
|
+
if (existsSync36(storyboardPath)) {
|
|
473990
|
+
invalidBeats = parseStoryboard(await readFile19(storyboardPath, "utf-8")).beats;
|
|
473886
473991
|
}
|
|
473887
473992
|
return finishBuildResult({
|
|
473888
473993
|
success: false,
|
|
@@ -473906,7 +474011,7 @@ async function executeSceneBuild(opts) {
|
|
|
473906
474011
|
totalLatencyMs: Date.now() - startedAt
|
|
473907
474012
|
});
|
|
473908
474013
|
}
|
|
473909
|
-
if (!
|
|
474014
|
+
if (!existsSync36(storyboardPath)) {
|
|
473910
474015
|
return finishBuildResult({
|
|
473911
474016
|
success: false,
|
|
473912
474017
|
phase: "failed",
|
|
@@ -473920,7 +474025,7 @@ async function executeSceneBuild(opts) {
|
|
|
473920
474025
|
totalLatencyMs: Date.now() - startedAt
|
|
473921
474026
|
});
|
|
473922
474027
|
}
|
|
473923
|
-
const storyboardMd = await
|
|
474028
|
+
const storyboardMd = await readFile19(storyboardPath, "utf-8");
|
|
473924
474029
|
const parsed = parseStoryboard(storyboardMd);
|
|
473925
474030
|
if (parsed.beats.length === 0) {
|
|
473926
474031
|
return finishBuildResult({
|
|
@@ -474027,6 +474132,7 @@ async function executeSceneBuild(opts) {
|
|
|
474027
474132
|
skipVideo: opts.skipVideo ?? false,
|
|
474028
474133
|
skipKeyframe: opts.skipKeyframe ?? false,
|
|
474029
474134
|
skipMusic: opts.skipMusic ?? false,
|
|
474135
|
+
skipTranscript: opts.skipTranscript ?? false,
|
|
474030
474136
|
force: opts.force ?? false,
|
|
474031
474137
|
onProgress,
|
|
474032
474138
|
characterPaths
|
|
@@ -474114,9 +474220,9 @@ async function executeSceneBuild(opts) {
|
|
|
474114
474220
|
let composeData;
|
|
474115
474221
|
if (shouldRunStage(selectedStage, "compose")) {
|
|
474116
474222
|
if (mode === "agent") {
|
|
474117
|
-
const compositionsDir =
|
|
474223
|
+
const compositionsDir = join33(projectDir, "compositions");
|
|
474118
474224
|
const missingBeats = activeBeats.filter(
|
|
474119
|
-
(b2) => !
|
|
474225
|
+
(b2) => !existsSync36(join33(compositionsDir, `scene-${b2.id}.html`))
|
|
474120
474226
|
);
|
|
474121
474227
|
if (missingBeats.length > 0) {
|
|
474122
474228
|
const plan = await getComposePrompts({ projectDir, beatId: opts.beatId });
|
|
@@ -474205,8 +474311,8 @@ async function executeSceneBuild(opts) {
|
|
|
474205
474311
|
if (stageReports.compose.status === "done") {
|
|
474206
474312
|
for (const beat of activeBeats) {
|
|
474207
474313
|
const videoRel = `assets/video-${beat.id}.mp4`;
|
|
474208
|
-
const compositionAbs =
|
|
474209
|
-
if (!
|
|
474314
|
+
const compositionAbs = join33(projectDir, "compositions", `scene-${beat.id}.html`);
|
|
474315
|
+
if (!existsSync36(join33(projectDir, videoRel)) || !existsSync36(compositionAbs)) continue;
|
|
474210
474316
|
const html = readFileSync12(compositionAbs, "utf-8");
|
|
474211
474317
|
if (!html.includes(videoRel)) {
|
|
474212
474318
|
warnings.push(
|
|
@@ -474264,7 +474370,7 @@ async function executeSceneBuild(opts) {
|
|
|
474264
474370
|
});
|
|
474265
474371
|
}
|
|
474266
474372
|
if (shouldRunStage(selectedStage, "sync")) {
|
|
474267
|
-
if (!
|
|
474373
|
+
if (!existsSync36(join33(projectDir, "index.html"))) {
|
|
474268
474374
|
await scaffoldSceneProject({
|
|
474269
474375
|
dir: projectDir,
|
|
474270
474376
|
name: projectDir.split(/[\\/]/).filter(Boolean).pop(),
|
|
@@ -474409,6 +474515,9 @@ async function buildBeatPrimitives(beat, ctx) {
|
|
|
474409
474515
|
ctx.skipVideo ? skipped("video", beat.id, "--skip-video", ctx) : dispatchVideo(beat, ctx, keyframe),
|
|
474410
474516
|
ctx.skipMusic ? skipped("music", beat.id, "--skip-music", ctx) : dispatchMusic(beat, ctx)
|
|
474411
474517
|
]);
|
|
474518
|
+
if (!ctx.skipTranscript) {
|
|
474519
|
+
await dispatchTranscript(beat, narration, ctx);
|
|
474520
|
+
}
|
|
474412
474521
|
return {
|
|
474413
474522
|
outcome: {
|
|
474414
474523
|
beatId: beat.id,
|
|
@@ -474526,7 +474635,7 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474526
474635
|
return {
|
|
474527
474636
|
status: "cached",
|
|
474528
474637
|
path: existingRel,
|
|
474529
|
-
durationSec: await safeAudioDuration(
|
|
474638
|
+
durationSec: await safeAudioDuration(join33(ctx.projectDir, existingRel)),
|
|
474530
474639
|
provider: metadata?.provider,
|
|
474531
474640
|
cachePath: metadata?.cachePath,
|
|
474532
474641
|
cacheKey: metadata?.cacheKey,
|
|
@@ -474550,9 +474659,9 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474550
474659
|
voice,
|
|
474551
474660
|
ext: resolution.audioExtension
|
|
474552
474661
|
});
|
|
474553
|
-
const cacheAbs =
|
|
474662
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
474554
474663
|
const rel = `assets/narration-${beat.id}.${resolution.audioExtension}`;
|
|
474555
|
-
const abs =
|
|
474664
|
+
const abs = join33(ctx.projectDir, rel);
|
|
474556
474665
|
if (existingRel && !ctx.force && isFreshCanonicalAsset({
|
|
474557
474666
|
projectDir: ctx.projectDir,
|
|
474558
474667
|
kind: "narration",
|
|
@@ -474566,7 +474675,7 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474566
474675
|
return {
|
|
474567
474676
|
status: "cached",
|
|
474568
474677
|
path: existingRel,
|
|
474569
|
-
durationSec: await safeAudioDuration(
|
|
474678
|
+
durationSec: await safeAudioDuration(join33(ctx.projectDir, existingRel)),
|
|
474570
474679
|
provider: resolution.provider,
|
|
474571
474680
|
cachePath: cache.path,
|
|
474572
474681
|
cacheKey: cache.key,
|
|
@@ -474574,7 +474683,7 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474574
474683
|
freshness: "fresh"
|
|
474575
474684
|
};
|
|
474576
474685
|
}
|
|
474577
|
-
if (
|
|
474686
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
474578
474687
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474579
474688
|
await copyFile4(cacheAbs, abs);
|
|
474580
474689
|
await writeAssetMetadata({
|
|
@@ -474609,8 +474718,8 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474609
474718
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474610
474719
|
await writeFile20(abs, result.audioBuffer);
|
|
474611
474720
|
for (const otherExt of ["mp3", "wav"]) {
|
|
474612
|
-
const sibling =
|
|
474613
|
-
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 });
|
|
474614
474723
|
}
|
|
474615
474724
|
await mkdir13(dirname18(cacheAbs), { recursive: true });
|
|
474616
474725
|
await writeFile20(cacheAbs, result.audioBuffer);
|
|
@@ -474642,6 +474751,42 @@ async function dispatchNarration(beat, ctx) {
|
|
|
474642
474751
|
freshness: "fresh"
|
|
474643
474752
|
};
|
|
474644
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
|
+
}
|
|
474645
474790
|
function characterSheetPrompt(name, description) {
|
|
474646
474791
|
return [
|
|
474647
474792
|
`Character reference sheet of an original fictional character named ${name}: ${description}.`,
|
|
@@ -474659,7 +474804,7 @@ async function buildCharacters(characters, ctx) {
|
|
|
474659
474804
|
const size = ctx.imageSize ?? "1536x1024";
|
|
474660
474805
|
for (const character of characters) {
|
|
474661
474806
|
if (character.imagePath) {
|
|
474662
|
-
if (
|
|
474807
|
+
if (existsSync36(join33(ctx.projectDir, character.imagePath))) {
|
|
474663
474808
|
paths.set(character.name, character.imagePath);
|
|
474664
474809
|
ctx.onProgress({ type: "character-cached", name: character.name, path: character.imagePath });
|
|
474665
474810
|
} else {
|
|
@@ -474672,7 +474817,7 @@ async function buildCharacters(characters, ctx) {
|
|
|
474672
474817
|
if (!character.prompt) continue;
|
|
474673
474818
|
const prompt3 = characterSheetPrompt(character.name, character.prompt);
|
|
474674
474819
|
const rel = `assets/character-${character.name}.png`;
|
|
474675
|
-
const abs =
|
|
474820
|
+
const abs = join33(ctx.projectDir, rel);
|
|
474676
474821
|
const metadataOptions = { quality: ctx.imageQuality, size };
|
|
474677
474822
|
const cache = characterCacheDescriptor({
|
|
474678
474823
|
name: character.name,
|
|
@@ -474681,7 +474826,7 @@ async function buildCharacters(characters, ctx) {
|
|
|
474681
474826
|
quality: ctx.imageQuality,
|
|
474682
474827
|
size
|
|
474683
474828
|
});
|
|
474684
|
-
if (
|
|
474829
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
474685
474830
|
const metadata = readAssetMetadata(ctx.projectDir, "character", character.name);
|
|
474686
474831
|
if (!metadata || isFreshCanonicalAsset({
|
|
474687
474832
|
projectDir: ctx.projectDir,
|
|
@@ -474697,8 +474842,8 @@ async function buildCharacters(characters, ctx) {
|
|
|
474697
474842
|
continue;
|
|
474698
474843
|
}
|
|
474699
474844
|
}
|
|
474700
|
-
const cacheAbs =
|
|
474701
|
-
if (
|
|
474845
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
474846
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
474702
474847
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474703
474848
|
await copyFile4(cacheAbs, abs);
|
|
474704
474849
|
await writeAssetMetadata({
|
|
@@ -474764,7 +474909,7 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
474764
474909
|
if (!cue) return { status: "no-cue" };
|
|
474765
474910
|
const prompt3 = augmentBackdropPrompt(cue);
|
|
474766
474911
|
const rel = `assets/backdrop-${beat.id}.png`;
|
|
474767
|
-
const abs =
|
|
474912
|
+
const abs = join33(ctx.projectDir, rel);
|
|
474768
474913
|
const size = ctx.imageSize ?? "1536x1024";
|
|
474769
474914
|
const ratio = imageRatioForSize(size);
|
|
474770
474915
|
const metadataOptions = { quality: ctx.imageQuality, size, ratio };
|
|
@@ -474777,7 +474922,7 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
474777
474922
|
ratio
|
|
474778
474923
|
});
|
|
474779
474924
|
const metadataPath = assetMetadataPath("backdrop", beat.id);
|
|
474780
|
-
if (
|
|
474925
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
474781
474926
|
const metadata = readAssetMetadata(ctx.projectDir, "backdrop", beat.id);
|
|
474782
474927
|
if (!metadata || isFreshCanonicalAsset({
|
|
474783
474928
|
projectDir: ctx.projectDir,
|
|
@@ -474800,8 +474945,8 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
474800
474945
|
};
|
|
474801
474946
|
}
|
|
474802
474947
|
}
|
|
474803
|
-
const cacheAbs =
|
|
474804
|
-
if (
|
|
474948
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
474949
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
474805
474950
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474806
474951
|
await copyFile4(cacheAbs, abs);
|
|
474807
474952
|
await writeAssetMetadata({
|
|
@@ -474933,7 +475078,7 @@ async function editKeyframeImage(prompt3, sheetBuffers, ctx, ratio) {
|
|
|
474933
475078
|
}
|
|
474934
475079
|
async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
474935
475080
|
const rel = `assets/keyframe-${beat.id}.png`;
|
|
474936
|
-
const abs =
|
|
475081
|
+
const abs = join33(ctx.projectDir, rel);
|
|
474937
475082
|
const size = ctx.imageSize ?? "1536x1024";
|
|
474938
475083
|
const ratio = imageRatioForSize(size);
|
|
474939
475084
|
const metadataOptions = { quality: ctx.imageQuality, size, ratio };
|
|
@@ -474946,7 +475091,7 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
|
474946
475091
|
ratio,
|
|
474947
475092
|
characters: characterRefsRel
|
|
474948
475093
|
});
|
|
474949
|
-
if (
|
|
475094
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
474950
475095
|
const metadata = readAssetMetadata(ctx.projectDir, "keyframe", beat.id);
|
|
474951
475096
|
if (!metadata || isFreshCanonicalAsset({
|
|
474952
475097
|
projectDir: ctx.projectDir,
|
|
@@ -474960,8 +475105,8 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
|
474960
475105
|
return { status: "cached", rel };
|
|
474961
475106
|
}
|
|
474962
475107
|
}
|
|
474963
|
-
const cacheAbs =
|
|
474964
|
-
if (
|
|
475108
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
475109
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
474965
475110
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
474966
475111
|
await copyFile4(cacheAbs, abs);
|
|
474967
475112
|
await writeAssetMetadata({
|
|
@@ -474979,8 +475124,8 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
|
|
|
474979
475124
|
}
|
|
474980
475125
|
const sheetBuffers = [];
|
|
474981
475126
|
for (const relPath of characterRefsRel) {
|
|
474982
|
-
const sheetAbs =
|
|
474983
|
-
if (
|
|
475127
|
+
const sheetAbs = join33(ctx.projectDir, relPath);
|
|
475128
|
+
if (existsSync36(sheetAbs)) sheetBuffers.push(await readFile19(sheetAbs));
|
|
474984
475129
|
}
|
|
474985
475130
|
const imgCtx = {
|
|
474986
475131
|
projectDir: ctx.projectDir,
|
|
@@ -475049,9 +475194,9 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475049
475194
|
const prompt3 = stringOrUndefined4(beat.cues?.video) ?? keyframeCue;
|
|
475050
475195
|
if (!prompt3) return { status: "no-cue" };
|
|
475051
475196
|
const characterRefsRel = beatCharacterNames(beat.cues).map((name) => ctx.characterPaths?.get(name)).filter((p2) => typeof p2 === "string");
|
|
475052
|
-
const characterRefsAbs = characterRefsRel.map((p2) =>
|
|
475197
|
+
const characterRefsAbs = characterRefsRel.map((p2) => join33(ctx.projectDir, p2));
|
|
475053
475198
|
const rel = `assets/video-${beat.id}.mp4`;
|
|
475054
|
-
const abs =
|
|
475199
|
+
const abs = join33(ctx.projectDir, rel);
|
|
475055
475200
|
const cache = videoCacheDescriptor({
|
|
475056
475201
|
beatId: beat.id,
|
|
475057
475202
|
cue: prompt3,
|
|
@@ -475063,7 +475208,7 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475063
475208
|
keyframe: keyframeCue
|
|
475064
475209
|
});
|
|
475065
475210
|
const metadataPath = assetMetadataPath("video", beat.id);
|
|
475066
|
-
if (
|
|
475211
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
475067
475212
|
const metadata = readAssetMetadata(ctx.projectDir, "video", beat.id);
|
|
475068
475213
|
if (!metadata || isFreshCanonicalAsset({
|
|
475069
475214
|
projectDir: ctx.projectDir,
|
|
@@ -475086,8 +475231,8 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475086
475231
|
};
|
|
475087
475232
|
}
|
|
475088
475233
|
}
|
|
475089
|
-
const cacheAbs =
|
|
475090
|
-
if (
|
|
475234
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
475235
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
475091
475236
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
475092
475237
|
await copyFile4(cacheAbs, abs);
|
|
475093
475238
|
await writeAssetMetadata({
|
|
@@ -475118,7 +475263,7 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475118
475263
|
ctx.onProgress({ type: "video-skipped", beatId: beat.id, reason });
|
|
475119
475264
|
return { status: "skipped" };
|
|
475120
475265
|
}
|
|
475121
|
-
const keyframeImageAbs = keyframeImageRel ?
|
|
475266
|
+
const keyframeImageAbs = keyframeImageRel ? join33(ctx.projectDir, keyframeImageRel) : void 0;
|
|
475122
475267
|
loadSceneBuildEnv(ctx.projectDir);
|
|
475123
475268
|
const result = await executeVideoGenerate({
|
|
475124
475269
|
prompt: prompt3,
|
|
@@ -475142,7 +475287,7 @@ async function dispatchVideo(beat, ctx, keyframe) {
|
|
|
475142
475287
|
ctx.onProgress({ type: "video-failed", beatId: beat.id, error });
|
|
475143
475288
|
return { status: "failed", error };
|
|
475144
475289
|
}
|
|
475145
|
-
if (result.status === "completed" &&
|
|
475290
|
+
if (result.status === "completed" && existsSync36(abs)) {
|
|
475146
475291
|
await mkdir13(dirname18(cacheAbs), { recursive: true });
|
|
475147
475292
|
await copyFile4(abs, cacheAbs);
|
|
475148
475293
|
await writeAssetMetadata({
|
|
@@ -475210,7 +475355,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475210
475355
|
const prompt3 = stringOrUndefined4(beat.cues?.music);
|
|
475211
475356
|
if (!prompt3) return { status: "no-cue" };
|
|
475212
475357
|
const rel = `assets/music-${beat.id}.mp3`;
|
|
475213
|
-
const abs =
|
|
475358
|
+
const abs = join33(ctx.projectDir, rel);
|
|
475214
475359
|
const duration = normalizeMusicDuration(beat.duration);
|
|
475215
475360
|
const cache = musicCacheDescriptor({
|
|
475216
475361
|
beatId: beat.id,
|
|
@@ -475219,7 +475364,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475219
475364
|
duration
|
|
475220
475365
|
});
|
|
475221
475366
|
const metadataPath = assetMetadataPath("music", beat.id);
|
|
475222
|
-
if (
|
|
475367
|
+
if (existsSync36(abs) && !ctx.force) {
|
|
475223
475368
|
const metadata = readAssetMetadata(ctx.projectDir, "music", beat.id);
|
|
475224
475369
|
if (!metadata || isFreshCanonicalAsset({
|
|
475225
475370
|
projectDir: ctx.projectDir,
|
|
@@ -475243,8 +475388,8 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475243
475388
|
};
|
|
475244
475389
|
}
|
|
475245
475390
|
}
|
|
475246
|
-
const cacheAbs =
|
|
475247
|
-
if (
|
|
475391
|
+
const cacheAbs = join33(ctx.projectDir, cache.path);
|
|
475392
|
+
if (existsSync36(cacheAbs) && !ctx.force) {
|
|
475248
475393
|
await mkdir13(dirname18(abs), { recursive: true });
|
|
475249
475394
|
await copyFile4(cacheAbs, abs);
|
|
475250
475395
|
await writeAssetMetadata({
|
|
@@ -475318,7 +475463,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475318
475463
|
metadataPath
|
|
475319
475464
|
};
|
|
475320
475465
|
}
|
|
475321
|
-
if (!
|
|
475466
|
+
if (!existsSync36(abs)) {
|
|
475322
475467
|
const error = result.outputPath ? `music output was not written at ${abs}` : "music generation did not return an output file";
|
|
475323
475468
|
ctx.onProgress({ type: "music-failed", beatId: beat.id, error });
|
|
475324
475469
|
return { status: "failed", error };
|
|
@@ -475354,12 +475499,12 @@ async function dispatchMusic(beat, ctx) {
|
|
|
475354
475499
|
};
|
|
475355
475500
|
}
|
|
475356
475501
|
function loadSceneBuildEnv(projectDir) {
|
|
475357
|
-
(0, import_dotenv3.config)({ path:
|
|
475502
|
+
(0, import_dotenv3.config)({ path: join33(projectDir, ".env"), quiet: true });
|
|
475358
475503
|
(0, import_dotenv3.config)({ path: resolve33(process.cwd(), ".env"), quiet: true });
|
|
475359
475504
|
let dir = process.cwd();
|
|
475360
475505
|
while (dir !== dirname18(dir)) {
|
|
475361
|
-
if (
|
|
475362
|
-
(0, import_dotenv3.config)({ path:
|
|
475506
|
+
if (existsSync36(join33(dir, "pnpm-workspace.yaml"))) {
|
|
475507
|
+
(0, import_dotenv3.config)({ path: join33(dir, ".env"), quiet: true });
|
|
475363
475508
|
return;
|
|
475364
475509
|
}
|
|
475365
475510
|
dir = dirname18(dir);
|
|
@@ -475575,7 +475720,7 @@ function mergeBeatOutcomes(base, updates) {
|
|
|
475575
475720
|
}
|
|
475576
475721
|
function firstExisting3(projectDir, relPaths) {
|
|
475577
475722
|
for (const rel of relPaths) {
|
|
475578
|
-
if (
|
|
475723
|
+
if (existsSync36(join33(projectDir, rel))) return rel;
|
|
475579
475724
|
}
|
|
475580
475725
|
return null;
|
|
475581
475726
|
}
|
|
@@ -475606,7 +475751,7 @@ async function apiKeyForVideoProvider(provider, projectDir) {
|
|
|
475606
475751
|
return getApiKeyFromConfig(providerKey, { cwd: projectDir });
|
|
475607
475752
|
}
|
|
475608
475753
|
async function finalizeBuildResult(projectDir, startedAt, result) {
|
|
475609
|
-
const reportPath =
|
|
475754
|
+
const reportPath = join33(projectDir, "build-report.json");
|
|
475610
475755
|
if (result.stageReports) {
|
|
475611
475756
|
for (const report of Object.values(result.stageReports)) {
|
|
475612
475757
|
if (report.status === "pending") report.status = "skipped";
|
|
@@ -475765,7 +475910,7 @@ function normalizeReportDuration(value) {
|
|
|
475765
475910
|
}
|
|
475766
475911
|
function buildReportComposition(projectDir, result, beatId) {
|
|
475767
475912
|
const path14 = `compositions/scene-${beatId}.html`;
|
|
475768
|
-
const exists =
|
|
475913
|
+
const exists = existsSync36(join33(projectDir, path14));
|
|
475769
475914
|
const written = composeWrittenEntry(result, beatId);
|
|
475770
475915
|
if (written) {
|
|
475771
475916
|
return {
|
|
@@ -475822,8 +475967,8 @@ function summarizeBuildBeats(projectDir, beats) {
|
|
|
475822
475967
|
let compositionsReady = 0;
|
|
475823
475968
|
for (const beat of beats) {
|
|
475824
475969
|
if (beatAssetsReady(beat)) assetsReady += 1;
|
|
475825
|
-
const compositionPath =
|
|
475826
|
-
if (
|
|
475970
|
+
const compositionPath = join33(projectDir, "compositions", `scene-${beat.beatId}.html`);
|
|
475971
|
+
if (existsSync36(compositionPath)) {
|
|
475827
475972
|
compositionsReady += 1;
|
|
475828
475973
|
} else {
|
|
475829
475974
|
needsAuthor.push(beat.beatId);
|
|
@@ -475865,6 +476010,8 @@ var init_scene_build = __esm({
|
|
|
475865
476010
|
init_compose_scenes_skills();
|
|
475866
476011
|
init_compose_prompts();
|
|
475867
476012
|
init_config();
|
|
476013
|
+
init_api_key();
|
|
476014
|
+
init_transcribe_narration();
|
|
475868
476015
|
init_scene_render();
|
|
475869
476016
|
init_storyboard_parse();
|
|
475870
476017
|
init_scene_project();
|
|
@@ -475993,18 +476140,18 @@ __export(ai_audio_exports, {
|
|
|
475993
476140
|
executeVoiceClone: () => executeVoiceClone
|
|
475994
476141
|
});
|
|
475995
476142
|
import { resolve as resolve35, dirname as dirname19, basename as basename8, extname as extname6 } from "node:path";
|
|
475996
|
-
import { readFile as
|
|
475997
|
-
import { existsSync as
|
|
476143
|
+
import { readFile as readFile20, writeFile as writeFile21 } from "node:fs/promises";
|
|
476144
|
+
import { existsSync as existsSync37 } from "node:fs";
|
|
475998
476145
|
async function executeTranscribe(options) {
|
|
475999
476146
|
const { audioPath, language, output: output3, format: format4, apiKey } = options;
|
|
476000
476147
|
try {
|
|
476001
476148
|
const key2 = apiKey || process.env.OPENAI_API_KEY;
|
|
476002
476149
|
if (!key2) return { success: false, error: "OPENAI_API_KEY required" };
|
|
476003
476150
|
const absPath = resolve35(process.cwd(), audioPath);
|
|
476004
|
-
if (!
|
|
476151
|
+
if (!existsSync37(absPath)) return { success: false, error: `File not found: ${absPath}` };
|
|
476005
476152
|
const whisper = new WhisperProvider();
|
|
476006
476153
|
await whisper.initialize({ apiKey: key2 });
|
|
476007
|
-
const audioBuffer = await
|
|
476154
|
+
const audioBuffer = await readFile20(absPath);
|
|
476008
476155
|
const audioBlob = new Blob([audioBuffer]);
|
|
476009
476156
|
const result = await whisper.transcribe(audioBlob, language);
|
|
476010
476157
|
if (result.status === "failed") {
|
|
@@ -476034,8 +476181,8 @@ async function executeIsolate(options) {
|
|
|
476034
476181
|
const key2 = apiKey || process.env.ELEVENLABS_API_KEY;
|
|
476035
476182
|
if (!key2) return { success: false, error: "ELEVENLABS_API_KEY required" };
|
|
476036
476183
|
const absPath = resolve35(process.cwd(), audioPath);
|
|
476037
|
-
if (!
|
|
476038
|
-
const audioBuffer = await
|
|
476184
|
+
if (!existsSync37(absPath)) return { success: false, error: `File not found: ${absPath}` };
|
|
476185
|
+
const audioBuffer = await readFile20(absPath);
|
|
476039
476186
|
const elevenlabs = new ElevenLabsProvider();
|
|
476040
476187
|
await elevenlabs.initialize({ apiKey: key2 });
|
|
476041
476188
|
const result = await elevenlabs.isolateVocals(audioBuffer);
|
|
@@ -476060,8 +476207,8 @@ async function executeVoiceClone(options) {
|
|
|
476060
476207
|
const audioBuffers = [];
|
|
476061
476208
|
for (const samplePath of samplePaths) {
|
|
476062
476209
|
const absPath = resolve35(process.cwd(), samplePath);
|
|
476063
|
-
if (!
|
|
476064
|
-
const buffer = await
|
|
476210
|
+
if (!existsSync37(absPath)) return { success: false, error: `File not found: ${samplePath}` };
|
|
476211
|
+
const buffer = await readFile20(absPath);
|
|
476065
476212
|
audioBuffers.push(buffer);
|
|
476066
476213
|
}
|
|
476067
476214
|
const elevenlabs = new ElevenLabsProvider();
|
|
@@ -476082,7 +476229,7 @@ async function executeDub(options) {
|
|
|
476082
476229
|
const { mediaPath, language, source: source3, voice, analyzeOnly, output: output3 } = options;
|
|
476083
476230
|
try {
|
|
476084
476231
|
const absPath = resolve35(process.cwd(), mediaPath);
|
|
476085
|
-
if (!
|
|
476232
|
+
if (!existsSync37(absPath)) return { success: false, error: `File not found: ${absPath}` };
|
|
476086
476233
|
const openaiKey = process.env.OPENAI_API_KEY;
|
|
476087
476234
|
const anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
476088
476235
|
const elevenlabsKey = process.env.ELEVENLABS_API_KEY;
|
|
@@ -476099,7 +476246,7 @@ async function executeDub(options) {
|
|
|
476099
476246
|
}
|
|
476100
476247
|
const whisper = new WhisperProvider();
|
|
476101
476248
|
await whisper.initialize({ apiKey: openaiKey });
|
|
476102
|
-
const audioBuffer = await
|
|
476249
|
+
const audioBuffer = await readFile20(audioPath);
|
|
476103
476250
|
const audioBlob = new Blob([audioBuffer]);
|
|
476104
476251
|
const transcriptResult = await whisper.transcribe(audioBlob, source3);
|
|
476105
476252
|
if (transcriptResult.status === "failed" || !transcriptResult.segments) {
|
|
@@ -476210,8 +476357,8 @@ async function executeDuck(options) {
|
|
|
476210
476357
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
476211
476358
|
const absMusicPath = resolve35(process.cwd(), musicPath);
|
|
476212
476359
|
const absVoicePath = resolve35(process.cwd(), voicePath);
|
|
476213
|
-
if (!
|
|
476214
|
-
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}` };
|
|
476215
476362
|
const defaultOutput = resolve35(dirname19(absMusicPath), `${basename8(absMusicPath, extname6(absMusicPath))}-ducked${extname6(absMusicPath)}`);
|
|
476216
476363
|
const outputPath = resolve35(process.cwd(), output3 || defaultOutput);
|
|
476217
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`;
|
|
@@ -476225,7 +476372,7 @@ async function executeDuck(options) {
|
|
|
476225
476372
|
"-y",
|
|
476226
476373
|
outputPath
|
|
476227
476374
|
], { timeout: 12e4, maxBuffer: 50 * 1024 * 1024 });
|
|
476228
|
-
if (!
|
|
476375
|
+
if (!existsSync37(outputPath)) return { success: false, error: "FFmpeg failed to create output" };
|
|
476229
476376
|
return { success: true, outputPath };
|
|
476230
476377
|
} catch (error) {
|
|
476231
476378
|
return { success: false, error: `Audio ducking failed: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -476241,8 +476388,8 @@ var init_ai_audio = __esm({
|
|
|
476241
476388
|
});
|
|
476242
476389
|
|
|
476243
476390
|
// ../cli/src/commands/_shared/edit/silence-cut.ts
|
|
476244
|
-
import { existsSync as
|
|
476245
|
-
import { readFile as
|
|
476391
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
476392
|
+
import { readFile as readFile21 } from "node:fs/promises";
|
|
476246
476393
|
async function detectSilencePeriods(videoPath, noiseThreshold, minDuration) {
|
|
476247
476394
|
const totalDuration = await getVideoDuration(videoPath);
|
|
476248
476395
|
const { stdout, stderr } = await execSafe(
|
|
@@ -476292,7 +476439,7 @@ async function detectSilencePeriodsWithGemini(videoPath, minDuration, options) {
|
|
|
476292
476439
|
}
|
|
476293
476440
|
const gemini = new GeminiProvider();
|
|
476294
476441
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
476295
|
-
const videoBuffer = await
|
|
476442
|
+
const videoBuffer = await readFile21(videoPath);
|
|
476296
476443
|
const modelId = options.model ? resolveGeminiTextModel(options.model) : void 0;
|
|
476297
476444
|
const prompt3 = `Analyze this video and identify all silent or dead segments where there is NO meaningful content.
|
|
476298
476445
|
|
|
@@ -476368,7 +476515,7 @@ async function executeSilenceCut(options) {
|
|
|
476368
476515
|
analyzeOnly = false,
|
|
476369
476516
|
useGemini = false
|
|
476370
476517
|
} = options;
|
|
476371
|
-
if (!
|
|
476518
|
+
if (!existsSync38(videoPath)) {
|
|
476372
476519
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
476373
476520
|
}
|
|
476374
476521
|
if (!commandExists("ffmpeg")) {
|
|
@@ -476476,11 +476623,11 @@ var init_silence_cut = __esm({
|
|
|
476476
476623
|
});
|
|
476477
476624
|
|
|
476478
476625
|
// ../cli/src/commands/_shared/edit/jump-cut.ts
|
|
476479
|
-
import { existsSync as
|
|
476480
|
-
import { readFile as
|
|
476481
|
-
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";
|
|
476482
476629
|
async function transcribeWithWords(audioPath, apiKey, language) {
|
|
476483
|
-
const audioBuffer = await
|
|
476630
|
+
const audioBuffer = await readFile22(audioPath);
|
|
476484
476631
|
const audioBlob = new Blob([audioBuffer]);
|
|
476485
476632
|
const formData = new FormData();
|
|
476486
476633
|
formData.append("file", audioBlob, "audio.wav");
|
|
@@ -476539,7 +476686,7 @@ async function executeJumpCut(options) {
|
|
|
476539
476686
|
analyzeOnly = false,
|
|
476540
476687
|
apiKey
|
|
476541
476688
|
} = options;
|
|
476542
|
-
if (!
|
|
476689
|
+
if (!existsSync39(videoPath)) {
|
|
476543
476690
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
476544
476691
|
}
|
|
476545
476692
|
if (!commandExists("ffmpeg")) {
|
|
@@ -476558,7 +476705,7 @@ async function executeJumpCut(options) {
|
|
|
476558
476705
|
try {
|
|
476559
476706
|
const tmpDir = `/tmp/vibe_jumpcut_${Date.now()}`;
|
|
476560
476707
|
await mkdir14(tmpDir, { recursive: true });
|
|
476561
|
-
const audioPath =
|
|
476708
|
+
const audioPath = join34(tmpDir, "audio.wav");
|
|
476562
476709
|
try {
|
|
476563
476710
|
await execSafe(
|
|
476564
476711
|
"ffmpeg",
|
|
@@ -476612,7 +476759,7 @@ async function executeJumpCut(options) {
|
|
|
476612
476759
|
const segmentPaths = [];
|
|
476613
476760
|
for (let i2 = 0; i2 < segments.length; i2++) {
|
|
476614
476761
|
const seg = segments[i2];
|
|
476615
|
-
const segPath =
|
|
476762
|
+
const segPath = join34(tmpDir, `seg-${i2.toString().padStart(4, "0")}.ts`);
|
|
476616
476763
|
const duration = seg.end - seg.start;
|
|
476617
476764
|
await execSafe(
|
|
476618
476765
|
"ffmpeg",
|
|
@@ -476635,7 +476782,7 @@ async function executeJumpCut(options) {
|
|
|
476635
476782
|
segmentPaths.push(segPath);
|
|
476636
476783
|
}
|
|
476637
476784
|
const concatList = segmentPaths.map((p2) => `file '${p2}'`).join("\n");
|
|
476638
|
-
const listPath =
|
|
476785
|
+
const listPath = join34(tmpDir, "concat.txt");
|
|
476639
476786
|
await writeFile22(listPath, concatList);
|
|
476640
476787
|
await execSafe(
|
|
476641
476788
|
"ffmpeg",
|
|
@@ -476742,8 +476889,8 @@ __export(remotion_exports, {
|
|
|
476742
476889
|
wrapComponentWithVideo: () => wrapComponentWithVideo
|
|
476743
476890
|
});
|
|
476744
476891
|
import { writeFile as writeFile23, mkdir as mkdir15, rm as rm4, copyFile as copyFile5 } from "node:fs/promises";
|
|
476745
|
-
import { existsSync as
|
|
476746
|
-
import { join as
|
|
476892
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
476893
|
+
import { join as join35 } from "node:path";
|
|
476747
476894
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
476748
476895
|
import { createHash as createHash7 } from "node:crypto";
|
|
476749
476896
|
async function ensureRemotionInstalled() {
|
|
@@ -476762,7 +476909,7 @@ async function ensureRemotionInstalled() {
|
|
|
476762
476909
|
}
|
|
476763
476910
|
}
|
|
476764
476911
|
async function scaffoldRemotionProject(componentCode, componentName, opts) {
|
|
476765
|
-
const dir =
|
|
476912
|
+
const dir = join35(tmpdir3(), `vibe_motion_${Date.now()}`);
|
|
476766
476913
|
await mkdir15(dir, { recursive: true });
|
|
476767
476914
|
const deps = {
|
|
476768
476915
|
remotion: REMOTION_VERSION,
|
|
@@ -476781,7 +476928,7 @@ async function scaffoldRemotionProject(componentCode, componentName, opts) {
|
|
|
476781
476928
|
dependencies: deps
|
|
476782
476929
|
};
|
|
476783
476930
|
const packageJsonStr = JSON.stringify(packageJson, null, 2);
|
|
476784
|
-
await writeFile23(
|
|
476931
|
+
await writeFile23(join35(dir, "package.json"), packageJsonStr);
|
|
476785
476932
|
const tsconfig = {
|
|
476786
476933
|
compilerOptions: {
|
|
476787
476934
|
target: "ES2020",
|
|
@@ -476793,8 +476940,8 @@ async function scaffoldRemotionProject(componentCode, componentName, opts) {
|
|
|
476793
476940
|
skipLibCheck: true
|
|
476794
476941
|
}
|
|
476795
476942
|
};
|
|
476796
|
-
await writeFile23(
|
|
476797
|
-
await writeFile23(
|
|
476943
|
+
await writeFile23(join35(dir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
|
|
476944
|
+
await writeFile23(join35(dir, "Component.tsx"), componentCode);
|
|
476798
476945
|
const rootCode = `import { registerRoot, Composition } from "remotion";
|
|
476799
476946
|
import { ${componentName} } from "./Component";
|
|
476800
476947
|
|
|
@@ -476813,14 +476960,14 @@ const Root = () => {
|
|
|
476813
476960
|
|
|
476814
476961
|
registerRoot(Root);
|
|
476815
476962
|
`;
|
|
476816
|
-
await writeFile23(
|
|
476963
|
+
await writeFile23(join35(dir, "Root.tsx"), rootCode);
|
|
476817
476964
|
const depsHash = createHash7("md5").update(packageJsonStr).digest("hex").slice(0, 12);
|
|
476818
|
-
const cacheMarker =
|
|
476819
|
-
const cachedModules =
|
|
476820
|
-
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)) {
|
|
476821
476968
|
const { symlink } = await import("node:fs/promises");
|
|
476822
476969
|
try {
|
|
476823
|
-
await symlink(cachedModules,
|
|
476970
|
+
await symlink(cachedModules, join35(dir, "node_modules"), "dir");
|
|
476824
476971
|
} catch {
|
|
476825
476972
|
await this_npmInstall(dir);
|
|
476826
476973
|
}
|
|
@@ -476828,12 +476975,12 @@ registerRoot(Root);
|
|
|
476828
476975
|
await this_npmInstall(dir);
|
|
476829
476976
|
try {
|
|
476830
476977
|
await mkdir15(REMOTION_CACHE_DIR, { recursive: true });
|
|
476831
|
-
await writeFile23(
|
|
476832
|
-
if (
|
|
476978
|
+
await writeFile23(join35(REMOTION_CACHE_DIR, "package.json"), packageJsonStr);
|
|
476979
|
+
if (existsSync40(join35(dir, "node_modules"))) {
|
|
476833
476980
|
const { rename: rename7, symlink } = await import("node:fs/promises");
|
|
476834
|
-
await rename7(
|
|
476981
|
+
await rename7(join35(dir, "node_modules"), cachedModules).catch(() => {
|
|
476835
476982
|
});
|
|
476836
|
-
await symlink(cachedModules,
|
|
476983
|
+
await symlink(cachedModules, join35(dir, "node_modules"), "dir").catch(() => {
|
|
476837
476984
|
});
|
|
476838
476985
|
await writeFile23(cacheMarker, depsHash);
|
|
476839
476986
|
}
|
|
@@ -476870,7 +477017,7 @@ async function renderMotion(options) {
|
|
|
476870
477017
|
}
|
|
476871
477018
|
);
|
|
476872
477019
|
try {
|
|
476873
|
-
const entryPoint =
|
|
477020
|
+
const entryPoint = join35(dir, "Root.tsx");
|
|
476874
477021
|
const { execFile: execFile3 } = await import("node:child_process");
|
|
476875
477022
|
const { promisify: promisify3 } = await import("node:util");
|
|
476876
477023
|
const execFileAsync3 = promisify3(execFile3);
|
|
@@ -477003,10 +477150,10 @@ async function renderWithEmbeddedImage(options) {
|
|
|
477003
477150
|
}
|
|
477004
477151
|
);
|
|
477005
477152
|
try {
|
|
477006
|
-
const publicDir =
|
|
477153
|
+
const publicDir = join35(dir, "public");
|
|
477007
477154
|
await mkdir15(publicDir, { recursive: true });
|
|
477008
|
-
await copyFile5(options.imagePath,
|
|
477009
|
-
const entryPoint =
|
|
477155
|
+
await copyFile5(options.imagePath, join35(publicDir, options.imageFileName));
|
|
477156
|
+
const entryPoint = join35(dir, "Root.tsx");
|
|
477010
477157
|
const mp4Out = options.outputPath.replace(/\.\w+$/, ".mp4");
|
|
477011
477158
|
const { execFile: execFileImg } = await import("node:child_process");
|
|
477012
477159
|
const { promisify: promisifyImg } = await import("node:util");
|
|
@@ -477067,10 +477214,10 @@ async function renderWithEmbeddedVideo(options) {
|
|
|
477067
477214
|
}
|
|
477068
477215
|
);
|
|
477069
477216
|
try {
|
|
477070
|
-
const publicDir =
|
|
477217
|
+
const publicDir = join35(dir, "public");
|
|
477071
477218
|
await mkdir15(publicDir, { recursive: true });
|
|
477072
|
-
await copyFile5(options.videoPath,
|
|
477073
|
-
const entryPoint =
|
|
477219
|
+
await copyFile5(options.videoPath, join35(publicDir, options.videoFileName));
|
|
477220
|
+
const entryPoint = join35(dir, "Root.tsx");
|
|
477074
477221
|
const mp4VideoOnly = options.outputPath.replace(/\.\w+$/, "_video_only.mp4");
|
|
477075
477222
|
const { execFile: execFileVid } = await import("node:child_process");
|
|
477076
477223
|
const { promisify: promisifyVid } = await import("node:util");
|
|
@@ -477486,14 +477633,14 @@ var init_remotion = __esm({
|
|
|
477486
477633
|
"use strict";
|
|
477487
477634
|
init_exec_safe();
|
|
477488
477635
|
REMOTION_VERSION = "4.0.447";
|
|
477489
|
-
REMOTION_CACHE_DIR =
|
|
477636
|
+
REMOTION_CACHE_DIR = join35(tmpdir3(), "vibe_remotion_cache");
|
|
477490
477637
|
}
|
|
477491
477638
|
});
|
|
477492
477639
|
|
|
477493
477640
|
// ../cli/src/commands/_shared/edit/caption.ts
|
|
477494
|
-
import { existsSync as
|
|
477495
|
-
import { readFile as
|
|
477496
|
-
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";
|
|
477497
477644
|
function getCaptionForceStyle(style, fontSize, fontColor, position) {
|
|
477498
477645
|
const alignment = position === "top" ? 8 : position === "center" ? 5 : 2;
|
|
477499
477646
|
const marginV = position === "center" ? 0 : 30;
|
|
@@ -477521,7 +477668,7 @@ async function executeCaption(options) {
|
|
|
477521
477668
|
position = "bottom",
|
|
477522
477669
|
apiKey
|
|
477523
477670
|
} = options;
|
|
477524
|
-
if (!
|
|
477671
|
+
if (!existsSync41(videoPath)) {
|
|
477525
477672
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
477526
477673
|
}
|
|
477527
477674
|
if (!commandExists("ffmpeg")) {
|
|
@@ -477540,8 +477687,8 @@ async function executeCaption(options) {
|
|
|
477540
477687
|
try {
|
|
477541
477688
|
const tmpDir = `/tmp/vibe_caption_${Date.now()}`;
|
|
477542
477689
|
await mkdir16(tmpDir, { recursive: true });
|
|
477543
|
-
const audioPath =
|
|
477544
|
-
const srtPath =
|
|
477690
|
+
const audioPath = join36(tmpDir, "audio.wav");
|
|
477691
|
+
const srtPath = join36(tmpDir, "captions.srt");
|
|
477545
477692
|
try {
|
|
477546
477693
|
await execSafe(
|
|
477547
477694
|
"ffmpeg",
|
|
@@ -477562,7 +477709,7 @@ async function executeCaption(options) {
|
|
|
477562
477709
|
);
|
|
477563
477710
|
const whisper = new WhisperProvider();
|
|
477564
477711
|
await whisper.initialize({ apiKey: openaiKey });
|
|
477565
|
-
const audioBuffer = await
|
|
477712
|
+
const audioBuffer = await readFile23(audioPath);
|
|
477566
477713
|
const audioBlob = new Blob([audioBuffer]);
|
|
477567
477714
|
const transcriptResult = await whisper.transcribe(audioBlob, language);
|
|
477568
477715
|
if (transcriptResult.status === "failed" || !transcriptResult.segments || transcriptResult.segments.length === 0) {
|
|
@@ -477610,7 +477757,7 @@ async function executeCaption(options) {
|
|
|
477610
477757
|
const remotionErr = await ensureRemotionInstalled2();
|
|
477611
477758
|
if (remotionErr) {
|
|
477612
477759
|
const outputDir2 = dirname20(outputPath);
|
|
477613
|
-
const outputSrtPath2 =
|
|
477760
|
+
const outputSrtPath2 = join36(
|
|
477614
477761
|
outputDir2,
|
|
477615
477762
|
basename9(outputPath, extname7(outputPath)) + ".srt"
|
|
477616
477763
|
);
|
|
@@ -477649,7 +477796,7 @@ SRT saved to: ${outputSrtPath2}` };
|
|
|
477649
477796
|
});
|
|
477650
477797
|
if (!renderResult.success) {
|
|
477651
477798
|
const outputDir2 = dirname20(outputPath);
|
|
477652
|
-
const outputSrtPath2 =
|
|
477799
|
+
const outputSrtPath2 = join36(
|
|
477653
477800
|
outputDir2,
|
|
477654
477801
|
basename9(outputPath, extname7(outputPath)) + ".srt"
|
|
477655
477802
|
);
|
|
@@ -477662,7 +477809,7 @@ SRT saved to: ${outputSrtPath2}`
|
|
|
477662
477809
|
}
|
|
477663
477810
|
}
|
|
477664
477811
|
const outputDir = dirname20(outputPath);
|
|
477665
|
-
const outputSrtPath =
|
|
477812
|
+
const outputSrtPath = join36(
|
|
477666
477813
|
outputDir,
|
|
477667
477814
|
basename9(outputPath, extname7(outputPath)) + ".srt"
|
|
477668
477815
|
);
|
|
@@ -477699,10 +477846,10 @@ var init_caption = __esm({
|
|
|
477699
477846
|
});
|
|
477700
477847
|
|
|
477701
477848
|
// ../cli/src/commands/_shared/edit/noise-reduce.ts
|
|
477702
|
-
import { existsSync as
|
|
477849
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
477703
477850
|
async function executeNoiseReduce(options) {
|
|
477704
477851
|
const { inputPath, outputPath, strength = "medium", noiseFloor } = options;
|
|
477705
|
-
if (!
|
|
477852
|
+
if (!existsSync43(inputPath)) {
|
|
477706
477853
|
return { success: false, error: `File not found: ${inputPath}` };
|
|
477707
477854
|
}
|
|
477708
477855
|
if (!commandExists("ffmpeg")) {
|
|
@@ -477759,7 +477906,7 @@ var init_noise_reduce = __esm({
|
|
|
477759
477906
|
});
|
|
477760
477907
|
|
|
477761
477908
|
// ../cli/src/commands/_shared/edit/fade.ts
|
|
477762
|
-
import { existsSync as
|
|
477909
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
477763
477910
|
async function executeFade(options) {
|
|
477764
477911
|
const {
|
|
477765
477912
|
videoPath,
|
|
@@ -477769,7 +477916,7 @@ async function executeFade(options) {
|
|
|
477769
477916
|
audioOnly = false,
|
|
477770
477917
|
videoOnly = false
|
|
477771
477918
|
} = options;
|
|
477772
|
-
if (!
|
|
477919
|
+
if (!existsSync44(videoPath)) {
|
|
477773
477920
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
477774
477921
|
}
|
|
477775
477922
|
if (!commandExists("ffmpeg")) {
|
|
@@ -477836,8 +477983,8 @@ var init_fade = __esm({
|
|
|
477836
477983
|
});
|
|
477837
477984
|
|
|
477838
477985
|
// ../cli/src/commands/_shared/edit/translate-srt.ts
|
|
477839
|
-
import { existsSync as
|
|
477840
|
-
import { readFile as
|
|
477986
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
477987
|
+
import { readFile as readFile24, writeFile as writeFile25 } from "node:fs/promises";
|
|
477841
477988
|
async function executeTranslateSrt(options) {
|
|
477842
477989
|
const {
|
|
477843
477990
|
srtPath,
|
|
@@ -477847,11 +477994,11 @@ async function executeTranslateSrt(options) {
|
|
|
477847
477994
|
sourceLanguage,
|
|
477848
477995
|
apiKey
|
|
477849
477996
|
} = options;
|
|
477850
|
-
if (!
|
|
477997
|
+
if (!existsSync45(srtPath)) {
|
|
477851
477998
|
return { success: false, error: `SRT file not found: ${srtPath}` };
|
|
477852
477999
|
}
|
|
477853
478000
|
try {
|
|
477854
|
-
const srtContent = await
|
|
478001
|
+
const srtContent = await readFile24(srtPath, "utf-8");
|
|
477855
478002
|
const segments = parseSRT(srtContent);
|
|
477856
478003
|
if (segments.length === 0) {
|
|
477857
478004
|
return { success: false, error: "No subtitle segments found in SRT file" };
|
|
@@ -477964,7 +478111,7 @@ var init_translate_srt = __esm({
|
|
|
477964
478111
|
});
|
|
477965
478112
|
|
|
477966
478113
|
// ../cli/src/commands/_shared/edit/text-overlay.ts
|
|
477967
|
-
import { existsSync as
|
|
478114
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
477968
478115
|
import { resolve as resolve36 } from "node:path";
|
|
477969
478116
|
function detectSystemFont() {
|
|
477970
478117
|
const platform = process.platform;
|
|
@@ -477975,7 +478122,7 @@ function detectSystemFont() {
|
|
|
477975
478122
|
"/Library/Fonts/Arial.ttf"
|
|
477976
478123
|
];
|
|
477977
478124
|
for (const f2 of candidates) {
|
|
477978
|
-
if (
|
|
478125
|
+
if (existsSync46(f2)) return f2;
|
|
477979
478126
|
}
|
|
477980
478127
|
} else if (platform === "linux") {
|
|
477981
478128
|
const candidates = [
|
|
@@ -477984,7 +478131,7 @@ function detectSystemFont() {
|
|
|
477984
478131
|
"/usr/share/fonts/TTF/DejaVuSans-Bold.ttf"
|
|
477985
478132
|
];
|
|
477986
478133
|
for (const f2 of candidates) {
|
|
477987
|
-
if (
|
|
478134
|
+
if (existsSync46(f2)) return f2;
|
|
477988
478135
|
}
|
|
477989
478136
|
} else if (platform === "win32") {
|
|
477990
478137
|
const candidates = [
|
|
@@ -477992,7 +478139,7 @@ function detectSystemFont() {
|
|
|
477992
478139
|
"C:\\Windows\\Fonts\\segoeui.ttf"
|
|
477993
478140
|
];
|
|
477994
478141
|
for (const f2 of candidates) {
|
|
477995
|
-
if (
|
|
478142
|
+
if (existsSync46(f2)) return f2;
|
|
477996
478143
|
}
|
|
477997
478144
|
}
|
|
477998
478145
|
return null;
|
|
@@ -478013,7 +478160,7 @@ async function applyTextOverlays(options) {
|
|
|
478013
478160
|
}
|
|
478014
478161
|
const absVideoPath = resolve36(process.cwd(), videoPath);
|
|
478015
478162
|
const absOutputPath = resolve36(process.cwd(), outputPath);
|
|
478016
|
-
if (!
|
|
478163
|
+
if (!existsSync46(absVideoPath)) {
|
|
478017
478164
|
return { success: false, error: `Video not found: ${absVideoPath}` };
|
|
478018
478165
|
}
|
|
478019
478166
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478194,7 +478341,7 @@ var init_ai_edit = __esm({
|
|
|
478194
478341
|
|
|
478195
478342
|
// ../cli/src/commands/ai-edit-cli.ts
|
|
478196
478343
|
import { resolve as resolve37, extname as extname8, basename as basename10 } from "node:path";
|
|
478197
|
-
import { existsSync as
|
|
478344
|
+
import { existsSync as existsSync47 } from "node:fs";
|
|
478198
478345
|
function registerEditCommands(aiCommand) {
|
|
478199
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", `
|
|
478200
478347
|
Examples:
|
|
@@ -478211,7 +478358,7 @@ No API key needed (FFmpeg only). Use --use-gemini for smart detection (requires
|
|
|
478211
478358
|
validateOutputPath(options.output);
|
|
478212
478359
|
}
|
|
478213
478360
|
const absVideoPath = resolve37(process.cwd(), videoPath);
|
|
478214
|
-
if (!
|
|
478361
|
+
if (!existsSync47(absVideoPath)) {
|
|
478215
478362
|
exitWithError(notFoundError(absVideoPath));
|
|
478216
478363
|
}
|
|
478217
478364
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478319,7 +478466,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478319
478466
|
validateOutputPath(options.output);
|
|
478320
478467
|
}
|
|
478321
478468
|
const absVideoPath = resolve37(process.cwd(), videoPath);
|
|
478322
|
-
if (!
|
|
478469
|
+
if (!existsSync47(absVideoPath)) {
|
|
478323
478470
|
exitWithError(notFoundError(absVideoPath));
|
|
478324
478471
|
}
|
|
478325
478472
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478400,7 +478547,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478400
478547
|
validateOutputPath(options.output);
|
|
478401
478548
|
}
|
|
478402
478549
|
const absInputPath = resolve37(process.cwd(), inputPath);
|
|
478403
|
-
if (!
|
|
478550
|
+
if (!existsSync47(absInputPath)) {
|
|
478404
478551
|
exitWithError(notFoundError(absInputPath));
|
|
478405
478552
|
}
|
|
478406
478553
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478466,7 +478613,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478466
478613
|
validateOutputPath(options.output);
|
|
478467
478614
|
}
|
|
478468
478615
|
const absVideoPath = resolve37(process.cwd(), videoPath);
|
|
478469
|
-
if (!
|
|
478616
|
+
if (!existsSync47(absVideoPath)) {
|
|
478470
478617
|
exitWithError(notFoundError(absVideoPath));
|
|
478471
478618
|
}
|
|
478472
478619
|
if (!commandExists("ffmpeg")) {
|
|
@@ -478541,7 +478688,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478541
478688
|
exitWithError(usageError("Target language required. Use -t or --target"));
|
|
478542
478689
|
}
|
|
478543
478690
|
const absSrtPath = resolve37(process.cwd(), srtPath);
|
|
478544
|
-
if (!
|
|
478691
|
+
if (!existsSync47(absSrtPath)) {
|
|
478545
478692
|
exitWithError(notFoundError(absSrtPath));
|
|
478546
478693
|
}
|
|
478547
478694
|
if (options.dryRun) {
|
|
@@ -478617,7 +478764,7 @@ Requires: OPENAI_API_KEY (Whisper transcription) + FFmpeg`).action(async (videoP
|
|
|
478617
478764
|
}
|
|
478618
478765
|
if (options.fillers) rejectControlChars(options.fillers);
|
|
478619
478766
|
const absVideoPath = resolve37(process.cwd(), videoPath);
|
|
478620
|
-
if (!
|
|
478767
|
+
if (!existsSync47(absVideoPath)) {
|
|
478621
478768
|
exitWithError(notFoundError(absVideoPath));
|
|
478622
478769
|
}
|
|
478623
478770
|
if (!commandExists("ffmpeg")) {
|
|
@@ -479109,8 +479256,8 @@ var init_project_resolver = __esm({
|
|
|
479109
479256
|
});
|
|
479110
479257
|
|
|
479111
479258
|
// ../cli/src/commands/_shared/execute-fill-gaps.ts
|
|
479112
|
-
import { existsSync as
|
|
479113
|
-
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";
|
|
479114
479261
|
import { resolve as resolve39, dirname as dirname21 } from "node:path";
|
|
479115
479262
|
function detectVideoGaps(videoClips, totalDuration) {
|
|
479116
479263
|
const gaps = [];
|
|
@@ -479167,7 +479314,7 @@ function analyzeGapFillability(gaps, videoClips, sources) {
|
|
|
479167
479314
|
}
|
|
479168
479315
|
async function uploadFrameToImgbb(framePath, imgbbApiKey) {
|
|
479169
479316
|
try {
|
|
479170
|
-
const frameBuffer = await
|
|
479317
|
+
const frameBuffer = await readFile25(framePath);
|
|
479171
479318
|
const frameBase64 = frameBuffer.toString("base64");
|
|
479172
479319
|
const formData = new FormData();
|
|
479173
479320
|
formData.append("key", imgbbApiKey);
|
|
@@ -479192,14 +479339,14 @@ async function executeFillGaps(options) {
|
|
|
479192
479339
|
try {
|
|
479193
479340
|
onProgress("Loading timeline...");
|
|
479194
479341
|
const filePath = await resolveTimelineFile(options.projectPath);
|
|
479195
|
-
if (!
|
|
479342
|
+
if (!existsSync48(filePath)) {
|
|
479196
479343
|
return {
|
|
479197
479344
|
success: false,
|
|
479198
479345
|
error: `Timeline file not found: ${filePath}`,
|
|
479199
479346
|
humanLines
|
|
479200
479347
|
};
|
|
479201
479348
|
}
|
|
479202
|
-
const content = await
|
|
479349
|
+
const content = await readFile25(filePath, "utf-8");
|
|
479203
479350
|
const data = JSON.parse(content);
|
|
479204
479351
|
const project = Project.fromJSON(data);
|
|
479205
479352
|
const clips = project.getClips().sort((a2, b2) => a2.startTime - b2.startTime);
|
|
@@ -479327,7 +479474,7 @@ async function executeFillGaps(options) {
|
|
|
479327
479474
|
}
|
|
479328
479475
|
const projectDir = dirname21(filePath);
|
|
479329
479476
|
const footageDir = options.dir ? resolve39(process.cwd(), options.dir) : resolve39(projectDir, "footage");
|
|
479330
|
-
if (!
|
|
479477
|
+
if (!existsSync48(footageDir)) {
|
|
479331
479478
|
await mkdir17(footageDir, { recursive: true });
|
|
479332
479479
|
}
|
|
479333
479480
|
humanLines.push("Generating AI Videos");
|
|
@@ -479647,8 +479794,8 @@ __export(ai_motion_exports, {
|
|
|
479647
479794
|
registerMotionCommand: () => registerMotionCommand
|
|
479648
479795
|
});
|
|
479649
479796
|
import { resolve as resolve40 } from "node:path";
|
|
479650
|
-
import { existsSync as
|
|
479651
|
-
import { readFile as
|
|
479797
|
+
import { existsSync as existsSync49 } from "node:fs";
|
|
479798
|
+
import { readFile as readFile26, writeFile as writeFile27 } from "node:fs/promises";
|
|
479652
479799
|
async function getOptionalGoogleApiKey() {
|
|
479653
479800
|
const configKey = await getApiKeyFromConfig("google");
|
|
479654
479801
|
if (configKey) return configKey;
|
|
@@ -479695,7 +479842,7 @@ async function executeMotion(options) {
|
|
|
479695
479842
|
};
|
|
479696
479843
|
}
|
|
479697
479844
|
const imagePath = resolve40(process.cwd(), options.image);
|
|
479698
|
-
const imageBuffer = await
|
|
479845
|
+
const imageBuffer = await readFile26(imagePath);
|
|
479699
479846
|
const gemini = new GeminiProvider();
|
|
479700
479847
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
479701
479848
|
const analysisResult = await gemini.analyzeImage(
|
|
@@ -479732,7 +479879,7 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
479732
479879
|
}
|
|
479733
479880
|
if (geminiApiKey) {
|
|
479734
479881
|
const videoPath = resolve40(process.cwd(), options.video);
|
|
479735
|
-
const videoBuffer = await
|
|
479882
|
+
const videoBuffer = await readFile26(videoPath);
|
|
479736
479883
|
const gemini = new GeminiProvider();
|
|
479737
479884
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
479738
479885
|
const analysisPrompt = options.understandingPrompt || `Analyze this video for motion graphics composition. Return concise production guidance:
|
|
@@ -479763,10 +479910,10 @@ Use this video understanding to place motion graphics in safe zones, match the c
|
|
|
479763
479910
|
let result;
|
|
479764
479911
|
if (options.fromTsx) {
|
|
479765
479912
|
const tsxPath = resolve40(process.cwd(), options.fromTsx);
|
|
479766
|
-
if (!
|
|
479913
|
+
if (!existsSync49(tsxPath)) {
|
|
479767
479914
|
return { success: false, error: `TSX file not found: ${tsxPath}` };
|
|
479768
479915
|
}
|
|
479769
|
-
const existingCode = await
|
|
479916
|
+
const existingCode = await readFile26(tsxPath, "utf-8");
|
|
479770
479917
|
if (useGemini) {
|
|
479771
479918
|
const gemini = new GeminiProvider();
|
|
479772
479919
|
await gemini.initialize({ apiKey });
|
|
@@ -480295,7 +480442,7 @@ __export(project_builder_exports, {
|
|
|
480295
480442
|
resolveSourceUrl: () => resolveSourceUrl
|
|
480296
480443
|
});
|
|
480297
480444
|
import { mkdtemp as mkdtemp4, mkdir as mkdir18, copyFile as copyFile6, writeFile as writeFile28, rm as rm5, readdir as readdir5 } from "node:fs/promises";
|
|
480298
|
-
import { existsSync as
|
|
480445
|
+
import { existsSync as existsSync50 } from "node:fs";
|
|
480299
480446
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
480300
480447
|
import { createRequire } from "node:module";
|
|
480301
480448
|
import * as path13 from "node:path";
|
|
@@ -480307,7 +480454,7 @@ async function buildTempProject(state, projectFileDir) {
|
|
|
480307
480454
|
for (const source3 of state.sources) {
|
|
480308
480455
|
if (copied.has(source3.id)) continue;
|
|
480309
480456
|
const resolved = resolveSourceUrl(source3.url, projectFileDir);
|
|
480310
|
-
if (!
|
|
480457
|
+
if (!existsSync50(resolved)) {
|
|
480311
480458
|
throw new Error(`Source file not found: ${resolved} (from source id=${source3.id})`);
|
|
480312
480459
|
}
|
|
480313
480460
|
const dest = path13.join(assetsDir, path13.basename(resolved));
|
|
@@ -480444,7 +480591,7 @@ __export(motion_overlay_exports, {
|
|
|
480444
480591
|
registerMotionOverlayCommand: () => registerMotionOverlayCommand
|
|
480445
480592
|
});
|
|
480446
480593
|
import { mkdir as mkdir19 } from "node:fs/promises";
|
|
480447
|
-
import { existsSync as
|
|
480594
|
+
import { existsSync as existsSync51 } from "node:fs";
|
|
480448
480595
|
import { basename as basename12, dirname as dirname24, extname as extname9, resolve as resolve43 } from "node:path";
|
|
480449
480596
|
function normalizeUnderstand2(value) {
|
|
480450
480597
|
return value === "off" || value === "required" || value === "auto" ? value : "auto";
|
|
@@ -480575,11 +480722,11 @@ async function executeMotionOverlay(options) {
|
|
|
480575
480722
|
const validationError = assertValidRequest(options);
|
|
480576
480723
|
if (validationError) return { success: false, error: validationError };
|
|
480577
480724
|
const absVideo = resolve43(process.cwd(), options.videoPath);
|
|
480578
|
-
if (!
|
|
480725
|
+
if (!existsSync51(absVideo)) return { success: false, error: `Video file not found: ${absVideo}` };
|
|
480579
480726
|
const outputPath = options.output ? resolve43(process.cwd(), options.output) : defaultOverlayOutput(options.videoPath);
|
|
480580
480727
|
if (options.asset) {
|
|
480581
480728
|
const absAsset = resolve43(process.cwd(), options.asset);
|
|
480582
|
-
if (!
|
|
480729
|
+
if (!existsSync51(absAsset)) return { success: false, error: `Lottie asset not found: ${absAsset}` };
|
|
480583
480730
|
const [videoDuration, size] = await Promise.all([
|
|
480584
480731
|
ffprobeDuration(absVideo),
|
|
480585
480732
|
ffprobeVideoSize(absVideo)
|
|
@@ -480746,7 +480893,7 @@ __export(edit_cmd_exports, {
|
|
|
480746
480893
|
executeUpscale: () => executeUpscale
|
|
480747
480894
|
});
|
|
480748
480895
|
import { resolve as resolve44, dirname as dirname25 } from "node:path";
|
|
480749
|
-
import { readFile as
|
|
480896
|
+
import { readFile as readFile27, writeFile as writeFile29, mkdir as mkdir20 } from "node:fs/promises";
|
|
480750
480897
|
async function executeGrade(options) {
|
|
480751
480898
|
const { videoPath, style, preset, output: output3, analyzeOnly, apiKey } = options;
|
|
480752
480899
|
try {
|
|
@@ -480787,7 +480934,7 @@ async function executeSpeedRamp(options) {
|
|
|
480787
480934
|
await execSafe("ffmpeg", ["-i", absPath, "-vn", "-acodec", "libmp3lame", "-q:a", "2", tempAudio, "-y"]);
|
|
480788
480935
|
const whisper = new WhisperProvider();
|
|
480789
480936
|
await whisper.initialize({ apiKey: openaiKey });
|
|
480790
|
-
const audioBuffer = await
|
|
480937
|
+
const audioBuffer = await readFile27(tempAudio);
|
|
480791
480938
|
const transcript = await whisper.transcribe(new Blob([audioBuffer]), language);
|
|
480792
480939
|
try {
|
|
480793
480940
|
const { unlink: unlink8 } = await import("node:fs/promises");
|
|
@@ -481181,7 +481328,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
481181
481328
|
spinner2.text = "Transcribing audio...";
|
|
481182
481329
|
const whisper = new WhisperProvider();
|
|
481183
481330
|
await whisper.initialize({ apiKey: openaiApiKey });
|
|
481184
|
-
const audioBuffer = await
|
|
481331
|
+
const audioBuffer = await readFile27(tempAudio);
|
|
481185
481332
|
const audioBlob = new Blob([audioBuffer]);
|
|
481186
481333
|
const transcript = await whisper.transcribe(audioBlob, options.language);
|
|
481187
481334
|
if (!transcript.segments || transcript.segments.length === 0) {
|
|
@@ -481314,7 +481461,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
481314
481461
|
for (let i2 = 1; i2 <= numKeyframes && i2 <= 30; i2++) {
|
|
481315
481462
|
const framePath = `${tempDir}/frame-${i2.toString().padStart(4, "0")}.jpg`;
|
|
481316
481463
|
try {
|
|
481317
|
-
const frameBuffer = await
|
|
481464
|
+
const frameBuffer = await readFile27(framePath);
|
|
481318
481465
|
const frameBase64 = frameBuffer.toString("base64");
|
|
481319
481466
|
const result = await claude.analyzeFrameForReframe(frameBase64, options.aspect, {
|
|
481320
481467
|
focusMode: options.focus,
|
|
@@ -481443,7 +481590,7 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
481443
481590
|
const imageBuffers = [];
|
|
481444
481591
|
for (const imagePath of imagePaths) {
|
|
481445
481592
|
const absPath = resolve44(process.cwd(), imagePath);
|
|
481446
|
-
const buffer = await
|
|
481593
|
+
const buffer = await readFile27(absPath);
|
|
481447
481594
|
imageBuffers.push(buffer);
|
|
481448
481595
|
}
|
|
481449
481596
|
let result;
|
|
@@ -481720,8 +481867,8 @@ __export(ai_image_exports, {
|
|
|
481720
481867
|
executeThumbnailBestFrame: () => executeThumbnailBestFrame
|
|
481721
481868
|
});
|
|
481722
481869
|
import { resolve as resolve46, dirname as dirname27 } from "node:path";
|
|
481723
|
-
import { readFile as
|
|
481724
|
-
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";
|
|
481725
481872
|
async function executeImageGenerate(options) {
|
|
481726
481873
|
const {
|
|
481727
481874
|
prompt: prompt3,
|
|
@@ -481865,10 +482012,10 @@ async function executeGeminiEdit(options) {
|
|
|
481865
482012
|
const imageBuffers = [];
|
|
481866
482013
|
for (const imagePath of imagePaths) {
|
|
481867
482014
|
const absPath = resolve46(process.cwd(), imagePath);
|
|
481868
|
-
if (!
|
|
482015
|
+
if (!existsSync54(absPath)) {
|
|
481869
482016
|
return { success: false, error: `Image not found: ${absPath}` };
|
|
481870
482017
|
}
|
|
481871
|
-
const buffer = await
|
|
482018
|
+
const buffer = await readFile28(absPath);
|
|
481872
482019
|
imageBuffers.push(buffer);
|
|
481873
482020
|
}
|
|
481874
482021
|
const gemini = new GeminiProvider();
|
|
@@ -481913,7 +482060,7 @@ async function executeThumbnailBestFrame(options) {
|
|
|
481913
482060
|
model = "flash",
|
|
481914
482061
|
apiKey
|
|
481915
482062
|
} = options;
|
|
481916
|
-
if (!
|
|
482063
|
+
if (!existsSync54(videoPath)) {
|
|
481917
482064
|
return { success: false, error: `Video not found: ${videoPath}` };
|
|
481918
482065
|
}
|
|
481919
482066
|
if (!commandExists("ffmpeg")) {
|
|
@@ -481926,7 +482073,7 @@ async function executeThumbnailBestFrame(options) {
|
|
|
481926
482073
|
try {
|
|
481927
482074
|
const gemini = new GeminiProvider();
|
|
481928
482075
|
await gemini.initialize({ apiKey: googleKey });
|
|
481929
|
-
const videoData = await
|
|
482076
|
+
const videoData = await readFile28(videoPath);
|
|
481930
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>"}';
|
|
481931
482078
|
const modelId = resolveGeminiTextModel(model);
|
|
481932
482079
|
const result = await gemini.analyzeVideo(videoData, analysisPrompt, {
|
|
@@ -481947,7 +482094,7 @@ async function executeThumbnailBestFrame(options) {
|
|
|
481947
482094
|
reason = reasonMatch[1];
|
|
481948
482095
|
}
|
|
481949
482096
|
await execSafe("ffmpeg", ["-ss", String(timestamp), "-i", videoPath, "-frames:v", "1", "-q:v", "2", outputPath, "-y"], { timeout: 6e4, maxBuffer: 50 * 1024 * 1024 });
|
|
481950
|
-
if (!
|
|
482097
|
+
if (!existsSync54(outputPath)) {
|
|
481951
482098
|
return { success: false, error: "FFmpeg failed to extract frame" };
|
|
481952
482099
|
}
|
|
481953
482100
|
return {
|
|
@@ -481978,9 +482125,9 @@ __export(ai_analyze_exports, {
|
|
|
481978
482125
|
executeGeminiVideo: () => executeGeminiVideo,
|
|
481979
482126
|
registerAnalyzeCommands: () => registerAnalyzeCommands
|
|
481980
482127
|
});
|
|
481981
|
-
import { readFile as
|
|
482128
|
+
import { readFile as readFile29 } from "node:fs/promises";
|
|
481982
482129
|
import { extname as extname10, resolve as resolve47 } from "node:path";
|
|
481983
|
-
import { existsSync as
|
|
482130
|
+
import { existsSync as existsSync55 } from "node:fs";
|
|
481984
482131
|
async function executeGeminiVideo(options) {
|
|
481985
482132
|
try {
|
|
481986
482133
|
const apiKey = await getApiKey("GOOGLE_API_KEY", "Google");
|
|
@@ -481994,10 +482141,10 @@ async function executeGeminiVideo(options) {
|
|
|
481994
482141
|
videoData = options.source;
|
|
481995
482142
|
} else {
|
|
481996
482143
|
const absPath = resolve47(process.cwd(), options.source);
|
|
481997
|
-
if (!
|
|
482144
|
+
if (!existsSync55(absPath)) {
|
|
481998
482145
|
return { success: false, error: `File not found: ${absPath}` };
|
|
481999
482146
|
}
|
|
482000
|
-
videoData = await
|
|
482147
|
+
videoData = await readFile29(absPath);
|
|
482001
482148
|
}
|
|
482002
482149
|
const gemini = new GeminiProvider();
|
|
482003
482150
|
await gemini.initialize({ apiKey });
|
|
@@ -482062,10 +482209,10 @@ async function executeAnalyze(options) {
|
|
|
482062
482209
|
imageBuffer = Buffer.from(await response.arrayBuffer());
|
|
482063
482210
|
} else {
|
|
482064
482211
|
const absPath = resolve47(process.cwd(), source3);
|
|
482065
|
-
if (!
|
|
482212
|
+
if (!existsSync55(absPath)) {
|
|
482066
482213
|
return { success: false, error: `File not found: ${absPath}` };
|
|
482067
482214
|
}
|
|
482068
|
-
imageBuffer = await
|
|
482215
|
+
imageBuffer = await readFile29(absPath);
|
|
482069
482216
|
}
|
|
482070
482217
|
const result2 = await gemini.analyzeImage(imageBuffer, options.prompt, {
|
|
482071
482218
|
model: modelId,
|
|
@@ -482097,10 +482244,10 @@ async function executeAnalyze(options) {
|
|
|
482097
482244
|
videoData = Buffer.from(await response.arrayBuffer());
|
|
482098
482245
|
} else {
|
|
482099
482246
|
const absPath = resolve47(process.cwd(), source3);
|
|
482100
|
-
if (!
|
|
482247
|
+
if (!existsSync55(absPath)) {
|
|
482101
482248
|
return { success: false, error: `File not found: ${absPath}` };
|
|
482102
482249
|
}
|
|
482103
|
-
videoData = await
|
|
482250
|
+
videoData = await readFile29(absPath);
|
|
482104
482251
|
}
|
|
482105
482252
|
const result = await gemini.analyzeVideo(videoData, options.prompt, {
|
|
482106
482253
|
model: modelId,
|
|
@@ -482234,9 +482381,9 @@ __export(ai_review_exports, {
|
|
|
482234
482381
|
executeReview: () => executeReview,
|
|
482235
482382
|
registerReviewCommand: () => registerReviewCommand
|
|
482236
482383
|
});
|
|
482237
|
-
import { readFile as
|
|
482384
|
+
import { readFile as readFile30, rename as rename5 } from "node:fs/promises";
|
|
482238
482385
|
import { resolve as resolve48 } from "node:path";
|
|
482239
|
-
import { existsSync as
|
|
482386
|
+
import { existsSync as existsSync56 } from "node:fs";
|
|
482240
482387
|
function parseReviewFeedback(response) {
|
|
482241
482388
|
let cleaned = response.trim();
|
|
482242
482389
|
if (cleaned.startsWith("```json")) {
|
|
@@ -482268,7 +482415,7 @@ async function executeReview(options) {
|
|
|
482268
482415
|
model = "flash"
|
|
482269
482416
|
} = options;
|
|
482270
482417
|
const absVideoPath = resolve48(process.cwd(), videoPath);
|
|
482271
|
-
if (!
|
|
482418
|
+
if (!existsSync56(absVideoPath)) {
|
|
482272
482419
|
return { success: false, error: `Video not found: ${absVideoPath}` };
|
|
482273
482420
|
}
|
|
482274
482421
|
const apiKey = process.env.GOOGLE_API_KEY || await getApiKey("GOOGLE_API_KEY", "Google");
|
|
@@ -482281,8 +482428,8 @@ async function executeReview(options) {
|
|
|
482281
482428
|
let storyboardContext = "";
|
|
482282
482429
|
if (storyboardPath) {
|
|
482283
482430
|
const absStoryboardPath = resolve48(process.cwd(), storyboardPath);
|
|
482284
|
-
if (
|
|
482285
|
-
const content = await
|
|
482431
|
+
if (existsSync56(absStoryboardPath)) {
|
|
482432
|
+
const content = await readFile30(absStoryboardPath, "utf-8");
|
|
482286
482433
|
storyboardContext = `
|
|
482287
482434
|
|
|
482288
482435
|
Original storyboard for reference:
|
|
@@ -482324,7 +482471,7 @@ ${projectContext}` : "";
|
|
|
482324
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}`;
|
|
482325
482472
|
const gemini = new GeminiProvider();
|
|
482326
482473
|
await gemini.initialize({ apiKey });
|
|
482327
|
-
const videoData = await
|
|
482474
|
+
const videoData = await readFile30(absVideoPath);
|
|
482328
482475
|
const analysisResult = await gemini.analyzeVideo(videoData, reviewPrompt, {
|
|
482329
482476
|
model: modelId
|
|
482330
482477
|
});
|
|
@@ -482379,7 +482526,7 @@ Score each category 1-10. Prefer beatIssues when you can map a problem to a stor
|
|
|
482379
482526
|
}
|
|
482380
482527
|
}
|
|
482381
482528
|
if (verify && result.outputPath) {
|
|
482382
|
-
const verifyVideoData = await
|
|
482529
|
+
const verifyVideoData = await readFile30(result.outputPath);
|
|
482383
482530
|
const verifyResult = await gemini.analyzeVideo(
|
|
482384
482531
|
verifyVideoData,
|
|
482385
482532
|
'Rate this video overall quality on a scale of 1-10. Return ONLY a JSON object: {"score": <number>}',
|
|
@@ -482843,7 +482990,7 @@ var init_sanitize = __esm({
|
|
|
482843
482990
|
|
|
482844
482991
|
// ../cli/src/commands/generate/storyboard.ts
|
|
482845
482992
|
import { resolve as resolve56 } from "node:path";
|
|
482846
|
-
import { readFile as
|
|
482993
|
+
import { readFile as readFile34, writeFile as writeFile35 } from "node:fs/promises";
|
|
482847
482994
|
async function executeStoryboard(options) {
|
|
482848
482995
|
const { content, duration, creativity = "low", output: output3, apiKey } = options;
|
|
482849
482996
|
try {
|
|
@@ -482891,7 +483038,7 @@ function registerStoryboardCommand(parent) {
|
|
|
482891
483038
|
let textContent2 = content;
|
|
482892
483039
|
if (options.file) {
|
|
482893
483040
|
const filePath = resolve56(process.cwd(), content);
|
|
482894
|
-
textContent2 = await
|
|
483041
|
+
textContent2 = await readFile34(filePath, "utf-8");
|
|
482895
483042
|
}
|
|
482896
483043
|
if (options.dryRun) {
|
|
482897
483044
|
outputSuccess({
|
|
@@ -483284,7 +483431,7 @@ var init_speech2 = __esm({
|
|
|
483284
483431
|
|
|
483285
483432
|
// ../cli/src/commands/generate/thumbnail.ts
|
|
483286
483433
|
import { resolve as resolve58, dirname as dirname29, basename as basename16, extname as extname11 } from "node:path";
|
|
483287
|
-
import { existsSync as
|
|
483434
|
+
import { existsSync as existsSync59 } from "node:fs";
|
|
483288
483435
|
import { writeFile as writeFile37, mkdir as mkdir25 } from "node:fs/promises";
|
|
483289
483436
|
function registerThumbnailCommand(parent) {
|
|
483290
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) => {
|
|
@@ -483296,7 +483443,7 @@ function registerThumbnailCommand(parent) {
|
|
|
483296
483443
|
}
|
|
483297
483444
|
if (options.bestFrame) {
|
|
483298
483445
|
const absVideoPath = resolve58(process.cwd(), options.bestFrame);
|
|
483299
|
-
if (!
|
|
483446
|
+
if (!existsSync59(absVideoPath)) {
|
|
483300
483447
|
exitWithError(notFoundError(absVideoPath));
|
|
483301
483448
|
}
|
|
483302
483449
|
if (!commandExists("ffmpeg")) {
|
|
@@ -485480,7 +485627,7 @@ var init_dist4 = __esm({
|
|
|
485480
485627
|
|
|
485481
485628
|
// ../cli/src/commands/generate/video.ts
|
|
485482
485629
|
import { resolve as resolve63 } from "node:path";
|
|
485483
|
-
import { readFile as
|
|
485630
|
+
import { readFile as readFile35, writeFile as writeFile41 } from "node:fs/promises";
|
|
485484
485631
|
function registerVideoCommand(parent) {
|
|
485485
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(
|
|
485486
485633
|
"-p, --provider <provider>",
|
|
@@ -485591,7 +485738,7 @@ Examples:
|
|
|
485591
485738
|
let isImageToVideo = false;
|
|
485592
485739
|
if (options.image) {
|
|
485593
485740
|
const imagePath = resolve63(process.cwd(), options.image);
|
|
485594
|
-
const imageBuffer = await
|
|
485741
|
+
const imageBuffer = await readFile35(imagePath);
|
|
485595
485742
|
const ext = options.image.toLowerCase().split(".").pop();
|
|
485596
485743
|
const mimeTypes = {
|
|
485597
485744
|
jpg: "image/jpeg",
|
|
@@ -485831,7 +485978,7 @@ Examples:
|
|
|
485831
485978
|
let lastFrame;
|
|
485832
485979
|
if (options.lastFrame) {
|
|
485833
485980
|
const lastFramePath = resolve63(process.cwd(), options.lastFrame);
|
|
485834
|
-
const lastFrameBuffer = await
|
|
485981
|
+
const lastFrameBuffer = await readFile35(lastFramePath);
|
|
485835
485982
|
const ext = options.lastFrame.toLowerCase().split(".").pop();
|
|
485836
485983
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
485837
485984
|
lastFrame = `data:${mimeType};base64,${lastFrameBuffer.toString("base64")}`;
|
|
@@ -485841,7 +485988,7 @@ Examples:
|
|
|
485841
485988
|
refImages = [];
|
|
485842
485989
|
for (const refPath of options.refImages.slice(0, 3)) {
|
|
485843
485990
|
const absRefPath = resolve63(process.cwd(), refPath);
|
|
485844
|
-
const refBuffer = await
|
|
485991
|
+
const refBuffer = await readFile35(absRefPath);
|
|
485845
485992
|
const ext = refPath.toLowerCase().split(".").pop();
|
|
485846
485993
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
485847
485994
|
refImages.push({ base64: refBuffer.toString("base64"), mimeType });
|
|
@@ -485973,7 +486120,7 @@ Examples:
|
|
|
485973
486120
|
if (seedanceEndImagePath && seedanceReferences.length === 0) {
|
|
485974
486121
|
try {
|
|
485975
486122
|
const absEndImagePath = resolve63(process.cwd(), seedanceEndImagePath);
|
|
485976
|
-
const endImageBuffer = await
|
|
486123
|
+
const endImageBuffer = await readFile35(absEndImagePath);
|
|
485977
486124
|
const ext = seedanceEndImagePath.toLowerCase().split(".").pop();
|
|
485978
486125
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
485979
486126
|
const uploadHost = await resolveUploadHost();
|
|
@@ -486090,7 +486237,7 @@ async function fileInputToUrlOrDataUri2(input3, fallbackMimeType) {
|
|
|
486090
486237
|
return input3;
|
|
486091
486238
|
}
|
|
486092
486239
|
const absPath = resolve63(process.cwd(), input3);
|
|
486093
|
-
const buffer = await
|
|
486240
|
+
const buffer = await readFile35(absPath);
|
|
486094
486241
|
return `data:${mimeTypeForPath2(input3, fallbackMimeType)};base64,${buffer.toString("base64")}`;
|
|
486095
486242
|
}
|
|
486096
486243
|
function mimeTypeForPath2(path14, fallback2) {
|
|
@@ -487098,7 +487245,7 @@ __export(detect_exports, {
|
|
|
487098
487245
|
executeDetectScenes: () => executeDetectScenes,
|
|
487099
487246
|
executeDetectSilence: () => executeDetectSilence
|
|
487100
487247
|
});
|
|
487101
|
-
import { readFile as
|
|
487248
|
+
import { readFile as readFile40, writeFile as writeFile46 } from "node:fs/promises";
|
|
487102
487249
|
import { resolve as resolve68, basename as basename18 } from "node:path";
|
|
487103
487250
|
async function executeDetectScenes(options) {
|
|
487104
487251
|
try {
|
|
@@ -487342,7 +487489,7 @@ var init_detect = __esm({
|
|
|
487342
487489
|
}
|
|
487343
487490
|
if (options.project) {
|
|
487344
487491
|
const projectPath = resolve68(process.cwd(), options.project);
|
|
487345
|
-
const content = await
|
|
487492
|
+
const content = await readFile40(projectPath, "utf-8");
|
|
487346
487493
|
const data = JSON.parse(content);
|
|
487347
487494
|
const project = Project.fromJSON(data);
|
|
487348
487495
|
let source3 = project.getSources().find((s2) => s2.url === absPath);
|
|
@@ -488165,8 +488312,8 @@ init_scene_project();
|
|
|
488165
488312
|
init_project_config();
|
|
488166
488313
|
init_cost_tier();
|
|
488167
488314
|
import { resolve as resolve24, relative as relative8, dirname as dirname14 } from "node:path";
|
|
488168
|
-
import { mkdir as mkdir11, readFile as
|
|
488169
|
-
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";
|
|
488170
488317
|
|
|
488171
488318
|
// ../cli/src/commands/_shared/scene-html-emit.ts
|
|
488172
488319
|
var SCENE_PRESETS = [
|
|
@@ -488735,15 +488882,16 @@ function deriveInstallHosts(detected) {
|
|
|
488735
488882
|
|
|
488736
488883
|
// ../cli/src/commands/scene.ts
|
|
488737
488884
|
init_compose_prompts();
|
|
488885
|
+
init_transcribe_narration();
|
|
488738
488886
|
|
|
488739
488887
|
// ../cli/src/commands/_shared/scene-submit.ts
|
|
488740
488888
|
init_compose_scenes_skills();
|
|
488741
488889
|
init_scene_lint();
|
|
488742
488890
|
init_storyboard_parse();
|
|
488743
488891
|
init_root_sync();
|
|
488744
|
-
import { existsSync as
|
|
488745
|
-
import { mkdir as mkdir10, readFile as
|
|
488746
|
-
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";
|
|
488747
488895
|
async function executeSceneSubmit(opts) {
|
|
488748
488896
|
const projectDir = resolve20(opts.projectDir);
|
|
488749
488897
|
const beatId = opts.beatId.trim();
|
|
@@ -488757,15 +488905,15 @@ async function executeSceneSubmit(opts) {
|
|
|
488757
488905
|
warnings: [],
|
|
488758
488906
|
retryWith: []
|
|
488759
488907
|
};
|
|
488760
|
-
const storyboardPath =
|
|
488761
|
-
if (!
|
|
488908
|
+
const storyboardPath = join27(projectDir, "STORYBOARD.md");
|
|
488909
|
+
if (!existsSync27(storyboardPath)) {
|
|
488762
488910
|
return {
|
|
488763
488911
|
...base,
|
|
488764
488912
|
success: false,
|
|
488765
488913
|
error: `STORYBOARD.md not found at ${storyboardPath}. Run \`vibe init <dir>\` first.`
|
|
488766
488914
|
};
|
|
488767
488915
|
}
|
|
488768
|
-
const parsed = parseStoryboard(await
|
|
488916
|
+
const parsed = parseStoryboard(await readFile12(storyboardPath, "utf-8"));
|
|
488769
488917
|
const beat = parsed.beats.find((b2) => b2.id === beatId);
|
|
488770
488918
|
if (!beat) {
|
|
488771
488919
|
const available = parsed.beats.map((b2) => b2.id).join(", ") || "(none)";
|
|
@@ -488835,8 +488983,8 @@ async function executeSceneSubmit(opts) {
|
|
|
488835
488983
|
if (opts.validateOnly) {
|
|
488836
488984
|
return { ...base, success: true };
|
|
488837
488985
|
}
|
|
488838
|
-
const absPath =
|
|
488839
|
-
await mkdir10(
|
|
488986
|
+
const absPath = join27(projectDir, scenePath);
|
|
488987
|
+
await mkdir10(join27(projectDir, "compositions"), { recursive: true });
|
|
488840
488988
|
await writeFile15(absPath, html.endsWith("\n") ? html : `${html}
|
|
488841
488989
|
`, "utf-8");
|
|
488842
488990
|
return {
|
|
@@ -489037,7 +489185,7 @@ sceneCommand.command("submit").description(
|
|
|
489037
489185
|
}
|
|
489038
489186
|
html = Buffer.concat(chunks).toString("utf-8");
|
|
489039
489187
|
} else if (options.file) {
|
|
489040
|
-
html = await
|
|
489188
|
+
html = await readFile15(resolve24(String(options.file)), "utf-8");
|
|
489041
489189
|
} else {
|
|
489042
489190
|
exitWithError(
|
|
489043
489191
|
usageError(
|
|
@@ -489367,8 +489515,8 @@ function readClipStart(rootHtml, beatId) {
|
|
|
489367
489515
|
async function resolveNarrationText(value) {
|
|
489368
489516
|
if (!value) return void 0;
|
|
489369
489517
|
const looksLikePath = /\.[a-z]{2,4}$/i.test(value) || value.includes("/") || value.includes("\\");
|
|
489370
|
-
if (looksLikePath &&
|
|
489371
|
-
return (await
|
|
489518
|
+
if (looksLikePath && existsSync29(value)) {
|
|
489519
|
+
return (await readFile15(value, "utf-8")).trim();
|
|
489372
489520
|
}
|
|
489373
489521
|
return value.trim();
|
|
489374
489522
|
}
|
|
@@ -489407,7 +489555,7 @@ async function executeSceneAdd(opts) {
|
|
|
489407
489555
|
if (!opts.force && await pathExists2(scenePath)) {
|
|
489408
489556
|
return errResult(`Scene already exists: ${sceneRel}. Re-run with --force to overwrite.`);
|
|
489409
489557
|
}
|
|
489410
|
-
const rootHtmlBefore = await
|
|
489558
|
+
const rootHtmlBefore = await readFile15(rootPath, "utf-8");
|
|
489411
489559
|
let dims = readRootDims(rootHtmlBefore);
|
|
489412
489560
|
if (!dims) {
|
|
489413
489561
|
const cfg2 = await loadVibeProjectConfig(projectDir);
|
|
@@ -489483,31 +489631,20 @@ async function executeSceneAdd(opts) {
|
|
|
489483
489631
|
);
|
|
489484
489632
|
} else {
|
|
489485
489633
|
opts.onProgress?.("Transcribing narration (Whisper word-level)...");
|
|
489486
|
-
|
|
489487
|
-
|
|
489488
|
-
|
|
489489
|
-
|
|
489490
|
-
|
|
489491
|
-
|
|
489492
|
-
|
|
489493
|
-
|
|
489494
|
-
|
|
489495
|
-
|
|
489496
|
-
|
|
489497
|
-
|
|
489498
|
-
|
|
489499
|
-
|
|
489500
|
-
transcriptWords = transcript.words.map((w2) => ({
|
|
489501
|
-
text: w2.text,
|
|
489502
|
-
start: w2.start,
|
|
489503
|
-
end: w2.end
|
|
489504
|
-
}));
|
|
489505
|
-
} else if (transcript.status === "failed") {
|
|
489506
|
-
opts.onProgress?.(`Transcribe failed: ${transcript.error ?? "unknown error"}`);
|
|
489507
|
-
}
|
|
489508
|
-
} catch (error) {
|
|
489509
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
489510
|
-
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
|
+
);
|
|
489511
489648
|
}
|
|
489512
489649
|
}
|
|
489513
489650
|
}
|
|
@@ -489616,7 +489753,7 @@ async function executeSceneAdd(opts) {
|
|
|
489616
489753
|
const shouldSyncStoryboard = opts.syncStoryboard !== false && await pathExists2(storyboardAbsPath);
|
|
489617
489754
|
if (shouldSyncStoryboard) {
|
|
489618
489755
|
opts.onProgress?.("Syncing STORYBOARD.md...");
|
|
489619
|
-
const before2 = await
|
|
489756
|
+
const before2 = await readFile15(storyboardAbsPath, "utf-8");
|
|
489620
489757
|
const synced = upsertStoryboardBeat(before2, {
|
|
489621
489758
|
beatId: id,
|
|
489622
489759
|
title: opts.headline,
|
|
@@ -489658,7 +489795,7 @@ async function executeSceneAdd(opts) {
|
|
|
489658
489795
|
});
|
|
489659
489796
|
const blockingIssue = syncPlan.issues.find((issue) => issue.severity === "error");
|
|
489660
489797
|
if (blockingIssue) return errResult(blockingIssue.message);
|
|
489661
|
-
const rootHtmlAfterSync = await
|
|
489798
|
+
const rootHtmlAfterSync = await readFile15(rootPath, "utf-8");
|
|
489662
489799
|
start = readClipStart(rootHtmlAfterSync, id) ?? 0;
|
|
489663
489800
|
} else {
|
|
489664
489801
|
start = nextSceneStart(rootHtmlBefore, SCENE_OVERLAP_SECONDS);
|
|
@@ -489832,7 +489969,7 @@ async function resolveSceneRepairTarget(rootArg = "index.html", projectArg = "."
|
|
|
489832
489969
|
const root2 = rootArg || "index.html";
|
|
489833
489970
|
const project = projectArg || ".";
|
|
489834
489971
|
const defaultProject = project === ".";
|
|
489835
|
-
if (defaultProject && root2 !== "index.html" && !root2.toLowerCase().endsWith(".html") &&
|
|
489972
|
+
if (defaultProject && root2 !== "index.html" && !root2.toLowerCase().endsWith(".html") && existsSync29(resolve24(root2, "index.html"))) {
|
|
489836
489973
|
return { projectDir: resolve24(root2), rootRel: "index.html" };
|
|
489837
489974
|
}
|
|
489838
489975
|
return { projectDir: resolve24(project), rootRel: root2 };
|
|
@@ -490703,7 +490840,7 @@ init_exec_safe();
|
|
|
490703
490840
|
init_remotion();
|
|
490704
490841
|
import { resolve as resolve45, dirname as dirname26, basename as basename13 } from "node:path";
|
|
490705
490842
|
import { writeFile as writeFile30, mkdir as mkdir21, rm as rm6 } from "node:fs/promises";
|
|
490706
|
-
import { existsSync as
|
|
490843
|
+
import { existsSync as existsSync53 } from "node:fs";
|
|
490707
490844
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
490708
490845
|
var ASS_STYLES = ["karaoke-sweep", "typewriter"];
|
|
490709
490846
|
var SENTENCE_BREAKS = /[.!?]/;
|
|
@@ -490884,7 +491021,7 @@ async function executeAnimatedCaption(options) {
|
|
|
490884
491021
|
const groups = groupWords(transcript.words, { wordsPerGroup, maxChars });
|
|
490885
491022
|
const absOutputPath = resolve45(process.cwd(), outputPath);
|
|
490886
491023
|
const outDir = dirname26(absOutputPath);
|
|
490887
|
-
if (!
|
|
491024
|
+
if (!existsSync53(outDir)) {
|
|
490888
491025
|
await mkdir21(outDir, { recursive: true });
|
|
490889
491026
|
}
|
|
490890
491027
|
if (tier === "ass") {
|
|
@@ -491432,14 +491569,14 @@ init_ai_review();
|
|
|
491432
491569
|
init_dist();
|
|
491433
491570
|
init_engine();
|
|
491434
491571
|
init_ai_helpers();
|
|
491435
|
-
import { readFile as
|
|
491572
|
+
import { readFile as readFile31, writeFile as writeFile32 } from "node:fs/promises";
|
|
491436
491573
|
import { resolve as resolve49 } from "node:path";
|
|
491437
491574
|
async function executeSuggestEdit(options) {
|
|
491438
491575
|
try {
|
|
491439
491576
|
const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY;
|
|
491440
491577
|
if (!apiKey) return { success: false, error: "GOOGLE_API_KEY required for suggest" };
|
|
491441
491578
|
const filePath = resolve49(process.cwd(), options.projectPath);
|
|
491442
|
-
const content = await
|
|
491579
|
+
const content = await readFile31(filePath, "utf-8");
|
|
491443
491580
|
const data = JSON.parse(content);
|
|
491444
491581
|
const project = Project.fromJSON(data);
|
|
491445
491582
|
const gemini = new GeminiProvider();
|
|
@@ -491476,9 +491613,9 @@ init_project_config();
|
|
|
491476
491613
|
init_scene_lint();
|
|
491477
491614
|
init_root_sync();
|
|
491478
491615
|
init_review_report();
|
|
491479
|
-
import { existsSync as
|
|
491480
|
-
import { readdir as readdir6, readFile as
|
|
491481
|
-
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";
|
|
491482
491619
|
async function inspectProject(opts) {
|
|
491483
491620
|
const projectDir = resolve50(opts.projectDir);
|
|
491484
491621
|
const issues = [];
|
|
@@ -491492,7 +491629,7 @@ async function inspectProject(opts) {
|
|
|
491492
491629
|
assets: { checked: 0, missing: [], stale: [], unknownFreshness: [] },
|
|
491493
491630
|
rootSync: { ok: null, issueCount: 0, issues: [] }
|
|
491494
491631
|
};
|
|
491495
|
-
if (!
|
|
491632
|
+
if (!existsSync57(projectDir) || !await isDirectory(projectDir)) {
|
|
491496
491633
|
issues.push({
|
|
491497
491634
|
severity: "error",
|
|
491498
491635
|
code: "PROJECT_NOT_FOUND",
|
|
@@ -491507,15 +491644,15 @@ async function inspectProject(opts) {
|
|
|
491507
491644
|
);
|
|
491508
491645
|
}
|
|
491509
491646
|
const coreFiles = {
|
|
491510
|
-
storyboard:
|
|
491511
|
-
design:
|
|
491512
|
-
config:
|
|
491513
|
-
legacyConfig:
|
|
491514
|
-
buildReport:
|
|
491515
|
-
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")
|
|
491516
491653
|
};
|
|
491517
491654
|
for (const [name, path14] of Object.entries(coreFiles)) {
|
|
491518
|
-
checks.files[name] =
|
|
491655
|
+
checks.files[name] = existsSync57(path14);
|
|
491519
491656
|
}
|
|
491520
491657
|
let beatIds = [];
|
|
491521
491658
|
let inspectedBeatIds = [];
|
|
@@ -491529,7 +491666,7 @@ async function inspectProject(opts) {
|
|
|
491529
491666
|
});
|
|
491530
491667
|
retryWith.push(`vibe init ${projectDir} --from "<brief>" --json`);
|
|
491531
491668
|
} else {
|
|
491532
|
-
const storyboard = await
|
|
491669
|
+
const storyboard = await readFile32(coreFiles.storyboard, "utf-8");
|
|
491533
491670
|
const validation3 = validateStoryboardMarkdown(storyboard);
|
|
491534
491671
|
storyboardBeats = validation3.beats;
|
|
491535
491672
|
beatIds = validation3.beats.map((beat) => beat.id);
|
|
@@ -491571,7 +491708,7 @@ async function inspectProject(opts) {
|
|
|
491571
491708
|
suggestedFix: "Create DESIGN.md or rerun `vibe init --from` in a new project."
|
|
491572
491709
|
});
|
|
491573
491710
|
} else {
|
|
491574
|
-
const design = await
|
|
491711
|
+
const design = await readFile32(coreFiles.design, "utf-8");
|
|
491575
491712
|
for (const issue of designPlaceholderIssues(design)) {
|
|
491576
491713
|
issues.push(issue);
|
|
491577
491714
|
}
|
|
@@ -491596,20 +491733,20 @@ async function inspectProject(opts) {
|
|
|
491596
491733
|
});
|
|
491597
491734
|
retryWith.push(`vibe build ${projectDir} --stage sync --json`);
|
|
491598
491735
|
}
|
|
491599
|
-
const compositionsDir =
|
|
491600
|
-
const existingComps =
|
|
491736
|
+
const compositionsDir = join38(projectDir, "compositions");
|
|
491737
|
+
const existingComps = existsSync57(compositionsDir) ? new Set(await listHtmlBasenames(compositionsDir)) : /* @__PURE__ */ new Set();
|
|
491601
491738
|
checks.compositions.expected = inspectedBeatIds.length;
|
|
491602
491739
|
for (const beatId of inspectedBeatIds) {
|
|
491603
491740
|
const file = `scene-${beatId}.html`;
|
|
491604
491741
|
if (existingComps.has(file)) {
|
|
491605
491742
|
checks.compositions.found++;
|
|
491606
491743
|
} else {
|
|
491607
|
-
checks.compositions.missing.push(
|
|
491744
|
+
checks.compositions.missing.push(join38("compositions", file));
|
|
491608
491745
|
issues.push({
|
|
491609
491746
|
severity: "error",
|
|
491610
491747
|
code: "MISSING_COMPOSITION",
|
|
491611
491748
|
message: `Composition for beat "${beatId}" is missing.`,
|
|
491612
|
-
file:
|
|
491749
|
+
file: join38("compositions", file),
|
|
491613
491750
|
scene: beatId,
|
|
491614
491751
|
beatId,
|
|
491615
491752
|
suggestedFix: "Run `vibe build --stage compose --json`."
|
|
@@ -491671,7 +491808,7 @@ async function inspectProject(opts) {
|
|
|
491671
491808
|
try {
|
|
491672
491809
|
const lint = await runProjectLint({ projectDir });
|
|
491673
491810
|
const lintFiles = opts.beatId ? lint.files.filter(
|
|
491674
|
-
(file) => file.file === "index.html" || file.file ===
|
|
491811
|
+
(file) => file.file === "index.html" || file.file === join38("compositions", `scene-${opts.beatId}.html`)
|
|
491675
491812
|
) : lint.files;
|
|
491676
491813
|
const lintCounts = countLintFindings(lintFiles);
|
|
491677
491814
|
checks.lint = {
|
|
@@ -491817,7 +491954,7 @@ function projectSourceReports(checks) {
|
|
|
491817
491954
|
async function inspectBuildReport(projectDir, reportPath, beatId, checks, issues, retryWith, storyboardBeats) {
|
|
491818
491955
|
checks.buildReport.exists = true;
|
|
491819
491956
|
try {
|
|
491820
|
-
const report = JSON.parse(await
|
|
491957
|
+
const report = JSON.parse(await readFile32(reportPath, "utf-8"));
|
|
491821
491958
|
if (typeof report.outputPath === "string") checks.buildReport.outputPath = report.outputPath;
|
|
491822
491959
|
const reportBeats = report.beats ?? [];
|
|
491823
491960
|
const selectedReportBeats = reportBeats.filter((item) => !beatId || item.id === beatId);
|
|
@@ -491954,7 +492091,7 @@ function inspectReportedAsset(opts) {
|
|
|
491954
492091
|
opts.checks.assets.checked++;
|
|
491955
492092
|
if (isExternalRef2(opts.value)) return;
|
|
491956
492093
|
const abs = isAbsolute7(opts.value) ? opts.value : resolve50(opts.projectDir, opts.value);
|
|
491957
|
-
if (
|
|
492094
|
+
if (existsSync57(abs)) return;
|
|
491958
492095
|
opts.checks.assets.missing.push(opts.value);
|
|
491959
492096
|
opts.issues.push({
|
|
491960
492097
|
severity: "warning",
|
|
@@ -492048,9 +492185,9 @@ init_exec_safe();
|
|
|
492048
492185
|
init_project_config();
|
|
492049
492186
|
init_storyboard_parse();
|
|
492050
492187
|
init_review_report();
|
|
492051
|
-
import { existsSync as
|
|
492052
|
-
import { readdir as readdir7, readFile as
|
|
492053
|
-
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";
|
|
492054
492191
|
var VIDEO_EXTENSIONS = /* @__PURE__ */ new Set([".mp4", ".mov", ".webm", ".m4v"]);
|
|
492055
492192
|
var DEFAULT_AI_MODEL = "flash";
|
|
492056
492193
|
var BLACK_FRAME_MIN_DURATION_SEC = 1;
|
|
@@ -492551,11 +492688,11 @@ async function inspectRender(opts) {
|
|
|
492551
492688
|
}
|
|
492552
492689
|
async function renderExpectsAudio(projectDir, beatId) {
|
|
492553
492690
|
const root2 = resolve51(projectDir);
|
|
492554
|
-
const rootHtml = await readTextIfExists(
|
|
492691
|
+
const rootHtml = await readTextIfExists(join39(root2, "index.html"));
|
|
492555
492692
|
if (rootHtml && rootHtmlExpectsAudio(rootHtml, beatId)) return true;
|
|
492556
|
-
const buildReport = await readJsonIfExists(
|
|
492693
|
+
const buildReport = await readJsonIfExists(join39(root2, "build-report.json"));
|
|
492557
492694
|
if (buildReportExpectsAudio(buildReport, beatId)) return true;
|
|
492558
|
-
const storyboard = await readTextIfExists(
|
|
492695
|
+
const storyboard = await readTextIfExists(join39(root2, "STORYBOARD.md"));
|
|
492559
492696
|
if (!storyboard) return false;
|
|
492560
492697
|
try {
|
|
492561
492698
|
const parsed = parseStoryboard(storyboard);
|
|
@@ -492566,7 +492703,7 @@ async function renderExpectsAudio(projectDir, beatId) {
|
|
|
492566
492703
|
`assets/narration-${beat.id}.wav`,
|
|
492567
492704
|
`assets/music-${beat.id}.mp3`,
|
|
492568
492705
|
`assets/music-${beat.id}.wav`
|
|
492569
|
-
].some((asset) =>
|
|
492706
|
+
].some((asset) => existsSync58(join39(root2, asset)))
|
|
492570
492707
|
);
|
|
492571
492708
|
} catch {
|
|
492572
492709
|
return false;
|
|
@@ -492674,8 +492811,8 @@ async function maybeWriteRenderReport(projectDir, opts, result) {
|
|
|
492674
492811
|
}
|
|
492675
492812
|
function renderSourceReports(projectDir, videoPath, checks) {
|
|
492676
492813
|
const reports = [];
|
|
492677
|
-
if (
|
|
492678
|
-
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");
|
|
492679
492816
|
if (videoPath) reports.push(displayPath(videoPath));
|
|
492680
492817
|
if (checks.durationSec !== void 0 || checks.width !== void 0 || checks.height !== void 0) {
|
|
492681
492818
|
reports.push("ffprobe");
|
|
@@ -492688,31 +492825,31 @@ function renderSourceReports(projectDir, videoPath, checks) {
|
|
|
492688
492825
|
async function resolveRenderVideoPath(projectDir, explicit, beatId) {
|
|
492689
492826
|
if (explicit) {
|
|
492690
492827
|
const candidate = resolve51(process.cwd(), explicit);
|
|
492691
|
-
return
|
|
492828
|
+
return existsSync58(candidate) ? candidate : null;
|
|
492692
492829
|
}
|
|
492693
|
-
const renderReportPath =
|
|
492694
|
-
if (
|
|
492830
|
+
const renderReportPath = join39(projectDir, "render-report.json");
|
|
492831
|
+
if (existsSync58(renderReportPath)) {
|
|
492695
492832
|
try {
|
|
492696
|
-
const report = JSON.parse(await
|
|
492833
|
+
const report = JSON.parse(await readFile33(renderReportPath, "utf-8"));
|
|
492697
492834
|
const reportBeat = typeof report.beat === "string" ? report.beat : null;
|
|
492698
492835
|
if (!beatId && reportBeat === null || beatId && reportBeat === beatId) {
|
|
492699
492836
|
const candidate = resolveReportedPath(projectDir, report.outputPath);
|
|
492700
|
-
if (candidate &&
|
|
492837
|
+
if (candidate && existsSync58(candidate)) return candidate;
|
|
492701
492838
|
}
|
|
492702
492839
|
} catch {
|
|
492703
492840
|
}
|
|
492704
492841
|
}
|
|
492705
|
-
const reportPath =
|
|
492706
|
-
if (!beatId &&
|
|
492842
|
+
const reportPath = join39(projectDir, "build-report.json");
|
|
492843
|
+
if (!beatId && existsSync58(reportPath)) {
|
|
492707
492844
|
try {
|
|
492708
|
-
const report = JSON.parse(await
|
|
492845
|
+
const report = JSON.parse(await readFile33(reportPath, "utf-8"));
|
|
492709
492846
|
const candidate = resolveReportedPath(projectDir, report.outputPath);
|
|
492710
|
-
if (candidate &&
|
|
492847
|
+
if (candidate && existsSync58(candidate)) return candidate;
|
|
492711
492848
|
} catch {
|
|
492712
492849
|
}
|
|
492713
492850
|
}
|
|
492714
|
-
const rendersDir =
|
|
492715
|
-
if (!
|
|
492851
|
+
const rendersDir = join39(projectDir, "renders");
|
|
492852
|
+
if (!existsSync58(rendersDir)) return null;
|
|
492716
492853
|
const entries2 = await readdir7(rendersDir, { withFileTypes: true });
|
|
492717
492854
|
const candidates = [];
|
|
492718
492855
|
for (const entry of entries2) {
|
|
@@ -492720,7 +492857,7 @@ async function resolveRenderVideoPath(projectDir, explicit, beatId) {
|
|
|
492720
492857
|
const ext = entry.name.slice(entry.name.lastIndexOf(".")).toLowerCase();
|
|
492721
492858
|
if (!VIDEO_EXTENSIONS.has(ext)) continue;
|
|
492722
492859
|
if (beatId && !entry.name.includes(sanitizeFileSegment2(beatId))) continue;
|
|
492723
|
-
const full =
|
|
492860
|
+
const full = join39(rendersDir, entry.name);
|
|
492724
492861
|
const info = await stat6(full);
|
|
492725
492862
|
candidates.push({ path: full, mtimeMs: info.mtimeMs });
|
|
492726
492863
|
}
|
|
@@ -492738,14 +492875,14 @@ async function runAiRenderReview(projectDir, videoPath, model) {
|
|
|
492738
492875
|
});
|
|
492739
492876
|
}
|
|
492740
492877
|
function resolveStoryboardPath(projectDir) {
|
|
492741
|
-
const storyboardPath =
|
|
492742
|
-
return
|
|
492878
|
+
const storyboardPath = join39(projectDir, "STORYBOARD.md");
|
|
492879
|
+
return existsSync58(storyboardPath) ? storyboardPath : null;
|
|
492743
492880
|
}
|
|
492744
492881
|
async function expectedDurationFromBuildReport(projectDir, beatId) {
|
|
492745
|
-
const reportPath =
|
|
492746
|
-
if (!
|
|
492882
|
+
const reportPath = join39(projectDir, "build-report.json");
|
|
492883
|
+
if (!existsSync58(reportPath)) return void 0;
|
|
492747
492884
|
try {
|
|
492748
|
-
const report = JSON.parse(await
|
|
492885
|
+
const report = JSON.parse(await readFile33(reportPath, "utf-8"));
|
|
492749
492886
|
const beats = beatId ? (report.beats ?? []).filter((beat) => beat.id === beatId) : report.beats ?? [];
|
|
492750
492887
|
const durations = beats.map(
|
|
492751
492888
|
(beat) => parseOptionalNumber2(beat.sceneDurationSec) ?? parseOptionalNumber2(beat.narration?.sceneDurationSec)
|
|
@@ -492757,10 +492894,10 @@ async function expectedDurationFromBuildReport(projectDir, beatId) {
|
|
|
492757
492894
|
}
|
|
492758
492895
|
}
|
|
492759
492896
|
async function beatTimingsFromBuildReport(projectDir, beatId) {
|
|
492760
|
-
const reportPath =
|
|
492761
|
-
if (!
|
|
492897
|
+
const reportPath = join39(projectDir, "build-report.json");
|
|
492898
|
+
if (!existsSync58(reportPath)) return [];
|
|
492762
492899
|
try {
|
|
492763
|
-
const report = JSON.parse(await
|
|
492900
|
+
const report = JSON.parse(await readFile33(reportPath, "utf-8"));
|
|
492764
492901
|
const source3 = report.beats ?? [];
|
|
492765
492902
|
const selected = beatId ? source3.filter((beat) => beat.id === beatId) : source3;
|
|
492766
492903
|
let cursor = 0;
|
|
@@ -492786,17 +492923,17 @@ async function beatTimingsFromBuildReport(projectDir, beatId) {
|
|
|
492786
492923
|
}
|
|
492787
492924
|
async function buildRenderReviewProjectContext(projectDir) {
|
|
492788
492925
|
const parts = [];
|
|
492789
|
-
const storyboard = await readTextIfExists(
|
|
492926
|
+
const storyboard = await readTextIfExists(join39(projectDir, "STORYBOARD.md"));
|
|
492790
492927
|
if (storyboard) {
|
|
492791
492928
|
parts.push(`STORYBOARD.md:
|
|
492792
492929
|
${truncateText(storyboard, 4e3)}`);
|
|
492793
492930
|
parts.push(`Storyboard beat cue summary:
|
|
492794
492931
|
${storyboardBeatCueSummary(storyboard)}`);
|
|
492795
492932
|
}
|
|
492796
|
-
const design = await readTextIfExists(
|
|
492933
|
+
const design = await readTextIfExists(join39(projectDir, "DESIGN.md"));
|
|
492797
492934
|
if (design) parts.push(`DESIGN.md:
|
|
492798
492935
|
${truncateText(design, 4e3)}`);
|
|
492799
|
-
const buildReport = await readTextIfExists(
|
|
492936
|
+
const buildReport = await readTextIfExists(join39(projectDir, "build-report.json"));
|
|
492800
492937
|
if (buildReport) parts.push(`build-report.json:
|
|
492801
492938
|
${truncateText(buildReport, 6e3)}`);
|
|
492802
492939
|
const timings = await beatTimingsFromBuildReport(projectDir);
|
|
@@ -492824,9 +492961,9 @@ function storyboardBeatCueSummary(storyboard) {
|
|
|
492824
492961
|
}
|
|
492825
492962
|
}
|
|
492826
492963
|
async function readTextIfExists(path14) {
|
|
492827
|
-
if (!
|
|
492964
|
+
if (!existsSync58(path14)) return null;
|
|
492828
492965
|
try {
|
|
492829
|
-
return await
|
|
492966
|
+
return await readFile33(path14, "utf-8");
|
|
492830
492967
|
} catch {
|
|
492831
492968
|
return null;
|
|
492832
492969
|
}
|
|
@@ -493645,17 +493782,17 @@ var generateTools = [
|
|
|
493645
493782
|
];
|
|
493646
493783
|
|
|
493647
493784
|
// ../cli/src/tools/manifest/storyboard.ts
|
|
493648
|
-
import { existsSync as
|
|
493649
|
-
import { readFile as
|
|
493785
|
+
import { existsSync as existsSync61 } from "node:fs";
|
|
493786
|
+
import { readFile as readFile37, writeFile as writeFile43 } from "node:fs/promises";
|
|
493650
493787
|
import { resolve as resolve65 } from "node:path";
|
|
493651
493788
|
import { z as z7 } from "zod";
|
|
493652
493789
|
init_storyboard_parse();
|
|
493653
493790
|
init_storyboard_edit();
|
|
493654
493791
|
|
|
493655
493792
|
// ../cli/src/commands/_shared/storyboard-revise.ts
|
|
493656
|
-
import { existsSync as
|
|
493657
|
-
import { readFile as
|
|
493658
|
-
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";
|
|
493659
493796
|
|
|
493660
493797
|
// ../cli/src/agent/adapters/index.ts
|
|
493661
493798
|
init_openai3();
|
|
@@ -493707,9 +493844,9 @@ init_storyboard_parse();
|
|
|
493707
493844
|
init_storyboard_edit();
|
|
493708
493845
|
async function executeStoryboardRevision(opts) {
|
|
493709
493846
|
const projectDir = resolve64(opts.projectDir);
|
|
493710
|
-
const storyboardPath =
|
|
493847
|
+
const storyboardPath = join40(projectDir, "STORYBOARD.md");
|
|
493711
493848
|
const retryWith = [`vibe storyboard revise ${projectDir} --from "<request>" --dry-run --json`];
|
|
493712
|
-
if (!
|
|
493849
|
+
if (!existsSync60(storyboardPath)) {
|
|
493713
493850
|
return failureResult({
|
|
493714
493851
|
projectDir,
|
|
493715
493852
|
storyboardPath,
|
|
@@ -493719,7 +493856,7 @@ async function executeStoryboardRevision(opts) {
|
|
|
493719
493856
|
retryWith: [`vibe init ${projectDir} --from "<brief>" --json`]
|
|
493720
493857
|
});
|
|
493721
493858
|
}
|
|
493722
|
-
const currentStoryboard = await
|
|
493859
|
+
const currentStoryboard = await readFile36(storyboardPath, "utf-8");
|
|
493723
493860
|
const projectConfig = await readProjectConfig(projectDir);
|
|
493724
493861
|
const explicitComposer = opts.composer ?? projectConfig.config.providers.composer ?? void 0;
|
|
493725
493862
|
let provider = explicitComposer ?? "claude";
|
|
@@ -493942,18 +494079,18 @@ function diffChangedBeats(before2, after2) {
|
|
|
493942
494079
|
return ids.filter((id) => JSON.stringify(beforeBeats.get(id) ?? null) !== JSON.stringify(afterBeats.get(id) ?? null));
|
|
493943
494080
|
}
|
|
493944
494081
|
async function readRevisionContext(projectDir) {
|
|
493945
|
-
const designMd = await readOptionalText(
|
|
493946
|
-
const buildReportJson = await readOptionalJsonText(
|
|
494082
|
+
const designMd = await readOptionalText(join40(projectDir, "DESIGN.md"));
|
|
494083
|
+
const buildReportJson = await readOptionalJsonText(join40(projectDir, "build-report.json"));
|
|
493947
494084
|
return { designMd, buildReportJson };
|
|
493948
494085
|
}
|
|
493949
494086
|
async function readOptionalText(path14) {
|
|
493950
|
-
if (!
|
|
493951
|
-
return
|
|
494087
|
+
if (!existsSync60(path14)) return null;
|
|
494088
|
+
return readFile36(path14, "utf-8");
|
|
493952
494089
|
}
|
|
493953
494090
|
async function readOptionalJsonText(path14) {
|
|
493954
|
-
if (!
|
|
494091
|
+
if (!existsSync60(path14)) return null;
|
|
493955
494092
|
try {
|
|
493956
|
-
const parsed = JSON.parse(await
|
|
494093
|
+
const parsed = JSON.parse(await readFile36(path14, "utf-8"));
|
|
493957
494094
|
return JSON.stringify(parsed, null, 2);
|
|
493958
494095
|
} catch {
|
|
493959
494096
|
return null;
|
|
@@ -493998,8 +494135,8 @@ var projectDirSchema = z7.object({
|
|
|
493998
494135
|
});
|
|
493999
494136
|
async function readStoryboard(projectDir) {
|
|
494000
494137
|
const path14 = resolve65(projectDir, "STORYBOARD.md");
|
|
494001
|
-
if (!
|
|
494002
|
-
return { path: path14, markdown: await
|
|
494138
|
+
if (!existsSync61(path14)) return null;
|
|
494139
|
+
return { path: path14, markdown: await readFile37(path14, "utf-8") };
|
|
494003
494140
|
}
|
|
494004
494141
|
var storyboardListTool = defineTool({
|
|
494005
494142
|
name: "storyboard_list",
|
|
@@ -494258,7 +494395,7 @@ var storyboardTools = [
|
|
|
494258
494395
|
// ../cli/src/tools/manifest/remix.ts
|
|
494259
494396
|
import { writeFile as writeFile48 } from "node:fs/promises";
|
|
494260
494397
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
494261
|
-
import { join as
|
|
494398
|
+
import { join as join41 } from "node:path";
|
|
494262
494399
|
import { z as z8 } from "zod";
|
|
494263
494400
|
|
|
494264
494401
|
// ../cli/src/commands/ai-script-pipeline.ts
|
|
@@ -494269,9 +494406,9 @@ init_config();
|
|
|
494269
494406
|
init_audio();
|
|
494270
494407
|
init_ai_helpers();
|
|
494271
494408
|
init_video_utils();
|
|
494272
|
-
import { readFile as
|
|
494409
|
+
import { readFile as readFile38, writeFile as writeFile44, unlink as unlink6, rename as rename6 } from "node:fs/promises";
|
|
494273
494410
|
import { resolve as resolve66, extname as extname12 } from "node:path";
|
|
494274
|
-
import { existsSync as
|
|
494411
|
+
import { existsSync as existsSync63 } from "node:fs";
|
|
494275
494412
|
|
|
494276
494413
|
// ../cli/src/commands/_shared/video-providers.ts
|
|
494277
494414
|
init_source();
|
|
@@ -494430,16 +494567,16 @@ async function executeRegenerateScene(options) {
|
|
|
494430
494567
|
};
|
|
494431
494568
|
try {
|
|
494432
494569
|
const outputDir = resolve66(process.cwd(), options.projectDir);
|
|
494433
|
-
if (!
|
|
494570
|
+
if (!existsSync63(outputDir)) {
|
|
494434
494571
|
return { ...result, error: `Project directory not found: ${outputDir}` };
|
|
494435
494572
|
}
|
|
494436
494573
|
const yamlPath = resolve66(outputDir, "storyboard.yaml");
|
|
494437
494574
|
const jsonPath = resolve66(outputDir, "storyboard.json");
|
|
494438
|
-
const storyboardPath =
|
|
494575
|
+
const storyboardPath = existsSync63(yamlPath) ? yamlPath : existsSync63(jsonPath) ? jsonPath : null;
|
|
494439
494576
|
if (!storyboardPath) {
|
|
494440
494577
|
return { ...result, error: `Storyboard not found in: ${outputDir} (expected storyboard.yaml or storyboard.json)` };
|
|
494441
494578
|
}
|
|
494442
|
-
const storyboardContent = await
|
|
494579
|
+
const storyboardContent = await readFile38(storyboardPath, "utf-8");
|
|
494443
494580
|
const segments = storyboardPath.endsWith(".yaml") ? (0, import_yaml6.parse)(storyboardContent).scenes : JSON.parse(storyboardContent);
|
|
494444
494581
|
for (const sceneNum of options.scenes) {
|
|
494445
494582
|
if (sceneNum < 1 || sceneNum > segments.length) {
|
|
@@ -494528,15 +494665,15 @@ IMPORTANT - Character appearance must match exactly: ${characterDesc}`;
|
|
|
494528
494665
|
const refSceneNum = options.referenceScene;
|
|
494529
494666
|
if (refSceneNum && refSceneNum >= 1 && refSceneNum <= segments.length && refSceneNum !== sceneNum) {
|
|
494530
494667
|
const refImagePath = resolve66(outputDir, `scene-${refSceneNum}.png`);
|
|
494531
|
-
if (
|
|
494532
|
-
referenceImageBuffer = await
|
|
494668
|
+
if (existsSync63(refImagePath)) {
|
|
494669
|
+
referenceImageBuffer = await readFile38(refImagePath);
|
|
494533
494670
|
}
|
|
494534
494671
|
} else if (!refSceneNum) {
|
|
494535
494672
|
for (let i2 = 1; i2 <= segments.length; i2++) {
|
|
494536
494673
|
if (i2 !== sceneNum) {
|
|
494537
494674
|
const otherImagePath = resolve66(outputDir, `scene-${i2}.png`);
|
|
494538
|
-
if (
|
|
494539
|
-
referenceImageBuffer = await
|
|
494675
|
+
if (existsSync63(otherImagePath)) {
|
|
494676
|
+
referenceImageBuffer = await readFile38(otherImagePath);
|
|
494540
494677
|
break;
|
|
494541
494678
|
}
|
|
494542
494679
|
}
|
|
@@ -494624,11 +494761,11 @@ Generate the single-person scene image now.`;
|
|
|
494624
494761
|
}
|
|
494625
494762
|
if (regenerateVideo && videoApiKey) {
|
|
494626
494763
|
options.onProgress?.(`Scene ${sceneNum}: regenerating video (${options.generator || "grok"})...`);
|
|
494627
|
-
if (!
|
|
494764
|
+
if (!existsSync63(imagePath)) {
|
|
494628
494765
|
result.failedScenes.push(sceneNum);
|
|
494629
494766
|
continue;
|
|
494630
494767
|
}
|
|
494631
|
-
const imageBuffer = await
|
|
494768
|
+
const imageBuffer = await readFile38(imagePath);
|
|
494632
494769
|
const videoDuration = segment.duration > 5 ? 10 : 5;
|
|
494633
494770
|
const maxRetries = options.retries ?? DEFAULT_VIDEO_RETRIES;
|
|
494634
494771
|
if (options.generator === "grok") {
|
|
@@ -494836,9 +494973,9 @@ Generate the single-person scene image now.`;
|
|
|
494836
494973
|
}
|
|
494837
494974
|
|
|
494838
494975
|
// ../cli/src/commands/ai-highlights.ts
|
|
494839
|
-
import { readFile as
|
|
494976
|
+
import { readFile as readFile39, writeFile as writeFile45, mkdir as mkdir27 } from "node:fs/promises";
|
|
494840
494977
|
import { resolve as resolve67, dirname as dirname31, basename as basename17, extname as extname13 } from "node:path";
|
|
494841
|
-
import { existsSync as
|
|
494978
|
+
import { existsSync as existsSync64 } from "node:fs";
|
|
494842
494979
|
init_dist();
|
|
494843
494980
|
init_engine();
|
|
494844
494981
|
init_api_key();
|
|
@@ -494869,7 +495006,7 @@ function filterHighlights(highlights, options) {
|
|
|
494869
495006
|
async function executeHighlights(options) {
|
|
494870
495007
|
try {
|
|
494871
495008
|
const absPath = resolve67(process.cwd(), options.media);
|
|
494872
|
-
if (!
|
|
495009
|
+
if (!existsSync64(absPath)) {
|
|
494873
495010
|
return { success: false, highlights: [], totalDuration: 0, totalHighlightDuration: 0, error: `File not found: ${absPath}` };
|
|
494874
495011
|
}
|
|
494875
495012
|
const ext = extname13(absPath).toLowerCase();
|
|
@@ -494888,7 +495025,7 @@ async function executeHighlights(options) {
|
|
|
494888
495025
|
sourceDuration = await ffprobeDuration(absPath);
|
|
494889
495026
|
const gemini = new GeminiProvider();
|
|
494890
495027
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
494891
|
-
const videoBuffer = await
|
|
495028
|
+
const videoBuffer = await readFile39(absPath);
|
|
494892
495029
|
const criteriaText = options.criteria === "all" || !options.criteria ? "emotional, informative, and funny moments" : `${options.criteria} moments`;
|
|
494893
495030
|
const durationText = targetDuration ? `Target a total highlight duration of ${targetDuration} seconds.` : "";
|
|
494894
495031
|
const countText = maxCount ? `Find up to ${maxCount} highlights.` : "";
|
|
@@ -494982,10 +495119,10 @@ Analyze both what is SHOWN (visual cues, actions, expressions) and what is SAID
|
|
|
494982
495119
|
}
|
|
494983
495120
|
const whisper = new WhisperProvider();
|
|
494984
495121
|
await whisper.initialize({ apiKey: openaiApiKey });
|
|
494985
|
-
const audioBuffer = await
|
|
495122
|
+
const audioBuffer = await readFile39(audioPath);
|
|
494986
495123
|
const audioBlob = new Blob([audioBuffer]);
|
|
494987
495124
|
const transcriptResult = await whisper.transcribe(audioBlob, options.language);
|
|
494988
|
-
if (tempAudioPath &&
|
|
495125
|
+
if (tempAudioPath && existsSync64(tempAudioPath)) {
|
|
494989
495126
|
const { unlink: unlinkFile } = await import("node:fs/promises");
|
|
494990
495127
|
await unlinkFile(tempAudioPath).catch(() => {
|
|
494991
495128
|
});
|
|
@@ -495072,7 +495209,7 @@ async function executeAutoShorts(options) {
|
|
|
495072
495209
|
return { success: false, shorts: [], error: "FFmpeg not found" };
|
|
495073
495210
|
}
|
|
495074
495211
|
const absPath = resolve67(process.cwd(), options.video);
|
|
495075
|
-
if (!
|
|
495212
|
+
if (!existsSync64(absPath)) {
|
|
495076
495213
|
return { success: false, shorts: [], error: `File not found: ${absPath}` };
|
|
495077
495214
|
}
|
|
495078
495215
|
const targetDuration = options.duration ?? 60;
|
|
@@ -495085,7 +495222,7 @@ async function executeAutoShorts(options) {
|
|
|
495085
495222
|
}
|
|
495086
495223
|
const gemini = new GeminiProvider();
|
|
495087
495224
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
495088
|
-
const videoBuffer = await
|
|
495225
|
+
const videoBuffer = await readFile39(absPath);
|
|
495089
495226
|
const geminiPrompt = `Analyze this video to find the BEST moments for short-form vertical video content (TikTok, YouTube Shorts, Instagram Reels).
|
|
495090
495227
|
|
|
495091
495228
|
Find ${shortCount * 3} potential clips that are ${targetDuration} seconds or shorter each.
|
|
@@ -495162,7 +495299,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
495162
495299
|
await execSafe("ffmpeg", ["-i", absPath, "-vn", "-acodec", "libmp3lame", "-q:a", "2", tempAudio, "-y"]);
|
|
495163
495300
|
const whisper = new WhisperProvider();
|
|
495164
495301
|
await whisper.initialize({ apiKey: openaiApiKey });
|
|
495165
|
-
const audioBuffer = await
|
|
495302
|
+
const audioBuffer = await readFile39(tempAudio);
|
|
495166
495303
|
const audioBlob = new Blob([audioBuffer]);
|
|
495167
495304
|
const transcript = await whisper.transcribe(audioBlob, options.language);
|
|
495168
495305
|
try {
|
|
@@ -495200,7 +495337,7 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
495200
495337
|
};
|
|
495201
495338
|
}
|
|
495202
495339
|
const outputDir = options.outputDir ? resolve67(process.cwd(), options.outputDir) : dirname31(absPath);
|
|
495203
|
-
if (options.outputDir && !
|
|
495340
|
+
if (options.outputDir && !existsSync64(outputDir)) {
|
|
495204
495341
|
await mkdir27(outputDir, { recursive: true });
|
|
495205
495342
|
}
|
|
495206
495343
|
const result = {
|
|
@@ -495279,8 +495416,8 @@ Analyze both VISUALS (expressions, actions, scene changes) and AUDIO (speech, re
|
|
|
495279
495416
|
// ../cli/src/pipeline/executor.ts
|
|
495280
495417
|
var import_yaml7 = __toESM(require_dist3(), 1);
|
|
495281
495418
|
import { resolve as resolve69 } from "node:path";
|
|
495282
|
-
import { readFile as
|
|
495283
|
-
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";
|
|
495284
495421
|
|
|
495285
495422
|
// ../cli/src/pipeline/resolver.ts
|
|
495286
495423
|
function resolveStepParams(params, completedSteps) {
|
|
@@ -495693,10 +495830,10 @@ async function ensureActionsRegistered() {
|
|
|
495693
495830
|
}
|
|
495694
495831
|
async function loadPipeline(filePath) {
|
|
495695
495832
|
const absPath = resolve69(process.cwd(), filePath);
|
|
495696
|
-
if (!
|
|
495833
|
+
if (!existsSync65(absPath)) {
|
|
495697
495834
|
throw new Error(`Pipeline file not found: ${absPath}`);
|
|
495698
495835
|
}
|
|
495699
|
-
const content = await
|
|
495836
|
+
const content = await readFile41(absPath, "utf-8");
|
|
495700
495837
|
const manifest2 = (0, import_yaml7.parse)(content);
|
|
495701
495838
|
if (!manifest2.name) throw new Error("Pipeline missing 'name' field");
|
|
495702
495839
|
if (!manifest2.steps || !Array.isArray(manifest2.steps)) throw new Error("Pipeline missing 'steps' array");
|
|
@@ -495719,8 +495856,8 @@ async function executePipeline(manifest2, options = {}) {
|
|
|
495719
495856
|
const startTime = Date.now();
|
|
495720
495857
|
if (options.resume) {
|
|
495721
495858
|
const checkpointPath = resolve69(outputDir, CHECKPOINT_FILE);
|
|
495722
|
-
if (
|
|
495723
|
-
const checkpointContent = await
|
|
495859
|
+
if (existsSync65(checkpointPath)) {
|
|
495860
|
+
const checkpointContent = await readFile41(checkpointPath, "utf-8");
|
|
495724
495861
|
const checkpoint = (0, import_yaml7.parse)(checkpointContent);
|
|
495725
495862
|
for (const cs of checkpoint.completedSteps) {
|
|
495726
495863
|
completedSteps.set(cs.id, {
|
|
@@ -495992,7 +496129,7 @@ var pipelineRunTool = defineTool({
|
|
|
495992
496129
|
let resolvedPath = args.pipelinePath;
|
|
495993
496130
|
let tempPath;
|
|
495994
496131
|
if (args.pipelineYaml) {
|
|
495995
|
-
tempPath =
|
|
496132
|
+
tempPath = join41(tmpdir6(), `vibe-mcp-pipeline-${Date.now()}.yaml`);
|
|
495996
496133
|
await writeFile48(tempPath, args.pipelineYaml, "utf-8");
|
|
495997
496134
|
resolvedPath = tempPath;
|
|
495998
496135
|
}
|
|
@@ -496168,10 +496305,10 @@ init_project_resolver();
|
|
|
496168
496305
|
// ../cli/src/tools/manifest/_project-io.ts
|
|
496169
496306
|
init_engine();
|
|
496170
496307
|
init_project_resolver();
|
|
496171
|
-
import { readFile as
|
|
496308
|
+
import { readFile as readFile42, writeFile as writeFile49 } from "node:fs/promises";
|
|
496172
496309
|
async function loadProject(projectPath, cwd) {
|
|
496173
496310
|
const absPath = await resolveTimelineFile(projectPath, cwd);
|
|
496174
|
-
const content = await
|
|
496311
|
+
const content = await readFile42(absPath, "utf-8");
|
|
496175
496312
|
const data = JSON.parse(content);
|
|
496176
496313
|
return { project: Project.fromJSON(data), absPath };
|
|
496177
496314
|
}
|
|
@@ -496522,12 +496659,12 @@ init_engine();
|
|
|
496522
496659
|
|
|
496523
496660
|
// ../cli/src/commands/_shared/project-list.ts
|
|
496524
496661
|
init_storyboard_parse();
|
|
496525
|
-
import { readdir as readdir8, readFile as
|
|
496526
|
-
import { existsSync as
|
|
496527
|
-
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";
|
|
496528
496665
|
async function executeProjectList(opts = {}) {
|
|
496529
496666
|
const workspaceDir = resolve71(opts.workspaceDir ?? ".");
|
|
496530
|
-
if (!
|
|
496667
|
+
if (!existsSync66(workspaceDir)) {
|
|
496531
496668
|
return {
|
|
496532
496669
|
success: false,
|
|
496533
496670
|
workspaceDir,
|
|
@@ -496544,11 +496681,11 @@ async function executeProjectList(opts = {}) {
|
|
|
496544
496681
|
if (entry.name === "node_modules") continue;
|
|
496545
496682
|
if (entry.name.startsWith(".")) continue;
|
|
496546
496683
|
if (entry.name.startsWith("_")) {
|
|
496547
|
-
archivedCount += await countProjects(
|
|
496684
|
+
archivedCount += await countProjects(join43(workspaceDir, entry.name));
|
|
496548
496685
|
continue;
|
|
496549
496686
|
}
|
|
496550
|
-
const projectDir =
|
|
496551
|
-
if (!
|
|
496687
|
+
const projectDir = join43(workspaceDir, entry.name);
|
|
496688
|
+
if (!existsSync66(join43(projectDir, "STORYBOARD.md"))) continue;
|
|
496552
496689
|
projects.push(await describeProject(entry.name, projectDir));
|
|
496553
496690
|
}
|
|
496554
496691
|
projects.sort((a2, b2) => b2.updatedAt.localeCompare(a2.updatedAt));
|
|
@@ -496558,7 +496695,7 @@ async function countProjects(dir) {
|
|
|
496558
496695
|
try {
|
|
496559
496696
|
const entries2 = await readdir8(dir, { withFileTypes: true });
|
|
496560
496697
|
return entries2.filter(
|
|
496561
|
-
(e2) => e2.isDirectory() &&
|
|
496698
|
+
(e2) => e2.isDirectory() && existsSync66(join43(dir, e2.name, "STORYBOARD.md"))
|
|
496562
496699
|
).length;
|
|
496563
496700
|
} catch {
|
|
496564
496701
|
return 0;
|
|
@@ -496569,8 +496706,8 @@ async function describeProject(name, projectDir) {
|
|
|
496569
496706
|
let storyboardDurationSec = 0;
|
|
496570
496707
|
const timestamps = [];
|
|
496571
496708
|
try {
|
|
496572
|
-
const storyboardPath =
|
|
496573
|
-
const parsed = parseStoryboard(await
|
|
496709
|
+
const storyboardPath = join43(projectDir, "STORYBOARD.md");
|
|
496710
|
+
const parsed = parseStoryboard(await readFile43(storyboardPath, "utf-8"));
|
|
496574
496711
|
beats = parsed.beats.length;
|
|
496575
496712
|
storyboardDurationSec = Number(
|
|
496576
496713
|
parsed.beats.reduce((sum, beat) => sum + (beat.duration ?? 0), 0).toFixed(2)
|
|
@@ -496581,8 +496718,8 @@ async function describeProject(name, projectDir) {
|
|
|
496581
496718
|
let buildStatus;
|
|
496582
496719
|
let buildUpdatedAt;
|
|
496583
496720
|
try {
|
|
496584
|
-
const reportPath =
|
|
496585
|
-
const report = JSON.parse(await
|
|
496721
|
+
const reportPath = join43(projectDir, "build-report.json");
|
|
496722
|
+
const report = JSON.parse(await readFile43(reportPath, "utf-8"));
|
|
496586
496723
|
buildStatus = report.status ?? report.phase;
|
|
496587
496724
|
buildUpdatedAt = report.updatedAt;
|
|
496588
496725
|
timestamps.push((await stat7(reportPath)).mtimeMs);
|
|
@@ -496590,12 +496727,12 @@ async function describeProject(name, projectDir) {
|
|
|
496590
496727
|
}
|
|
496591
496728
|
let latestRender;
|
|
496592
496729
|
try {
|
|
496593
|
-
const rendersDir =
|
|
496730
|
+
const rendersDir = join43(projectDir, "renders");
|
|
496594
496731
|
const files = await readdir8(rendersDir);
|
|
496595
496732
|
let newest;
|
|
496596
496733
|
for (const file of files) {
|
|
496597
496734
|
if (!/\.(mp4|webm|mov)$/i.test(file)) continue;
|
|
496598
|
-
const { mtimeMs } = await stat7(
|
|
496735
|
+
const { mtimeMs } = await stat7(join43(rendersDir, file));
|
|
496599
496736
|
if (!newest || mtimeMs > newest.mtimeMs) newest = { file, mtimeMs };
|
|
496600
496737
|
}
|
|
496601
496738
|
if (newest) {
|
|
@@ -496730,7 +496867,7 @@ init_exec_safe();
|
|
|
496730
496867
|
init_output();
|
|
496731
496868
|
init_validate();
|
|
496732
496869
|
init_project_resolver();
|
|
496733
|
-
import { readFile as
|
|
496870
|
+
import { readFile as readFile44, access as access6 } from "node:fs/promises";
|
|
496734
496871
|
import { resolve as resolve74, basename as basename20 } from "node:path";
|
|
496735
496872
|
import { spawn as spawn9 } from "node:child_process";
|
|
496736
496873
|
function timelineBaseName(path14) {
|
|
@@ -496807,7 +496944,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
496807
496944
|
};
|
|
496808
496945
|
}
|
|
496809
496946
|
const filePath = await resolveTimelineFile(projectPath);
|
|
496810
|
-
const content = await
|
|
496947
|
+
const content = await readFile44(filePath, "utf-8");
|
|
496811
496948
|
const data = JSON.parse(content);
|
|
496812
496949
|
const project = Project.fromJSON(data);
|
|
496813
496950
|
const summary = project.getSummary();
|
|
@@ -496931,7 +497068,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
496931
497068
|
}
|
|
496932
497069
|
spinner2.text = "Loading project...";
|
|
496933
497070
|
const filePath = await resolveTimelineFile(projectPath);
|
|
496934
|
-
const content = await
|
|
497071
|
+
const content = await readFile44(filePath, "utf-8");
|
|
496935
497072
|
const data = JSON.parse(content);
|
|
496936
497073
|
const project = Project.fromJSON(data);
|
|
496937
497074
|
const summary = project.getSummary();
|
|
@@ -497529,14 +497666,14 @@ function getPresetSettings(preset, aspectRatio2) {
|
|
|
497529
497666
|
}
|
|
497530
497667
|
async function runHyperframesExport(projectPath, options, spinner2, startedAt) {
|
|
497531
497668
|
spinner2.text = "Loading project...";
|
|
497532
|
-
const { readFile:
|
|
497669
|
+
const { readFile: readFile47 } = await import("node:fs/promises");
|
|
497533
497670
|
const { resolve: resolve80 } = await import("node:path");
|
|
497534
497671
|
const { Project: Project2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
|
|
497535
497672
|
const { createHyperframesBackend: createHyperframesBackend2 } = await Promise.resolve().then(() => (init_hyperframes(), hyperframes_exports));
|
|
497536
497673
|
const { exitWithError: exitWithError2, generalError: generalError2, outputSuccess: outputSuccess2 } = await Promise.resolve().then(() => (init_output(), output_exports));
|
|
497537
497674
|
const chalk2 = (await Promise.resolve().then(() => (init_source(), source_exports))).default;
|
|
497538
497675
|
const filePath = await resolveTimelineFile(projectPath);
|
|
497539
|
-
const content = await
|
|
497676
|
+
const content = await readFile47(filePath, "utf-8");
|
|
497540
497677
|
const project = Project2.fromJSON(JSON.parse(content));
|
|
497541
497678
|
const state = project.getState();
|
|
497542
497679
|
const outputPath = options.output ? resolve80(process.cwd(), options.output) : resolve80(process.cwd(), `${timelineBaseName(projectPath)}.${options.format ?? "mp4"}`);
|
|
@@ -497605,8 +497742,8 @@ var exportVideoTool = defineTool({
|
|
|
497605
497742
|
var exportTools = [exportVideoTool];
|
|
497606
497743
|
|
|
497607
497744
|
// ../cli/src/tools/manifest/agent-only.ts
|
|
497608
|
-
import { readFile as
|
|
497609
|
-
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";
|
|
497610
497747
|
import { z as z13 } from "zod";
|
|
497611
497748
|
init_engine();
|
|
497612
497749
|
init_exec_safe();
|
|
@@ -497685,7 +497822,7 @@ var fsListTool = defineTool({
|
|
|
497685
497822
|
const results = [];
|
|
497686
497823
|
for (const entry of entries2) {
|
|
497687
497824
|
if (args.pattern && !matchPattern(entry.name, args.pattern)) continue;
|
|
497688
|
-
const fullPath =
|
|
497825
|
+
const fullPath = join44(absPath, entry.name);
|
|
497689
497826
|
const stats = await stat8(fullPath);
|
|
497690
497827
|
if (entry.isDirectory()) {
|
|
497691
497828
|
results.push(`[DIR] ${entry.name}/`);
|
|
@@ -497714,7 +497851,7 @@ var fsReadTool = defineTool({
|
|
|
497714
497851
|
async execute(args, ctx) {
|
|
497715
497852
|
try {
|
|
497716
497853
|
const absPath = resolve76(ctx.workingDirectory, args.path);
|
|
497717
|
-
const content = await
|
|
497854
|
+
const content = await readFile45(absPath, "utf-8");
|
|
497718
497855
|
const maxLength = 4e3;
|
|
497719
497856
|
const truncated = content.length > maxLength;
|
|
497720
497857
|
const output3 = truncated ? content.substring(0, maxLength) + "\n... (truncated)" : content;
|
|
@@ -497787,7 +497924,7 @@ var batchImportTool = defineTool({
|
|
|
497787
497924
|
async execute(args, ctx) {
|
|
497788
497925
|
try {
|
|
497789
497926
|
const filePath = resolve76(ctx.workingDirectory, args.project);
|
|
497790
|
-
const content = await
|
|
497927
|
+
const content = await readFile45(filePath, "utf-8");
|
|
497791
497928
|
const data = JSON.parse(content);
|
|
497792
497929
|
const project = Project.fromJSON(data);
|
|
497793
497930
|
const dirPath = resolve76(ctx.workingDirectory, args.directory);
|
|
@@ -497798,7 +497935,7 @@ var batchImportTool = defineTool({
|
|
|
497798
497935
|
const scanDir = async (dir) => {
|
|
497799
497936
|
const entries2 = await readdir9(dir, { withFileTypes: true });
|
|
497800
497937
|
for (const entry of entries2) {
|
|
497801
|
-
const entryPath =
|
|
497938
|
+
const entryPath = join44(dir, entry.name);
|
|
497802
497939
|
if (entry.isDirectory() && recursive) {
|
|
497803
497940
|
await scanDir(entryPath);
|
|
497804
497941
|
} else if (entry.isFile()) {
|
|
@@ -497859,7 +497996,7 @@ var batchConcatTool = defineTool({
|
|
|
497859
497996
|
async execute(args, ctx) {
|
|
497860
497997
|
try {
|
|
497861
497998
|
const filePath = resolve76(ctx.workingDirectory, args.project);
|
|
497862
|
-
const content = await
|
|
497999
|
+
const content = await readFile45(filePath, "utf-8");
|
|
497863
498000
|
const data = JSON.parse(content);
|
|
497864
498001
|
const project = Project.fromJSON(data);
|
|
497865
498002
|
const sourceIds = args.sourceIds ?? [];
|
|
@@ -497930,7 +498067,7 @@ var batchApplyEffectTool = defineTool({
|
|
|
497930
498067
|
async execute(args, ctx) {
|
|
497931
498068
|
try {
|
|
497932
498069
|
const filePath = resolve76(ctx.workingDirectory, args.project);
|
|
497933
|
-
const content = await
|
|
498070
|
+
const content = await readFile45(filePath, "utf-8");
|
|
497934
498071
|
const data = JSON.parse(content);
|
|
497935
498072
|
const project = Project.fromJSON(data);
|
|
497936
498073
|
const clipIds = args.clipIds ?? [];
|
|
@@ -497985,7 +498122,7 @@ var timelineClearTool = defineTool({
|
|
|
497985
498122
|
async execute(args, ctx) {
|
|
497986
498123
|
try {
|
|
497987
498124
|
const filePath = await resolveTimelineFile(args.project, ctx.workingDirectory);
|
|
497988
|
-
const content = await
|
|
498125
|
+
const content = await readFile45(filePath, "utf-8");
|
|
497989
498126
|
const data = JSON.parse(content);
|
|
497990
498127
|
const project = Project.fromJSON(data);
|
|
497991
498128
|
const what = args.what ?? "clips";
|
|
@@ -498062,7 +498199,7 @@ var projectSetTool = defineTool({
|
|
|
498062
498199
|
async execute(args, ctx) {
|
|
498063
498200
|
try {
|
|
498064
498201
|
const filePath = await resolveTimelineFile(args.projectPath, ctx.workingDirectory);
|
|
498065
|
-
const content = await
|
|
498202
|
+
const content = await readFile45(filePath, "utf-8");
|
|
498066
498203
|
const data = JSON.parse(content);
|
|
498067
498204
|
const project = Project.fromJSON(data);
|
|
498068
498205
|
const updates = [];
|
|
@@ -498336,8 +498473,8 @@ var mediaCompressTool = defineTool({
|
|
|
498336
498473
|
],
|
|
498337
498474
|
{ maxBuffer: 50 * 1024 * 1024 }
|
|
498338
498475
|
);
|
|
498339
|
-
const inputBuf = await
|
|
498340
|
-
const outputBuf = await
|
|
498476
|
+
const inputBuf = await readFile45(absInput);
|
|
498477
|
+
const outputBuf = await readFile45(outputPath);
|
|
498341
498478
|
const inputSize = inputBuf.length;
|
|
498342
498479
|
const outputSize = outputBuf.length;
|
|
498343
498480
|
const reduction = (inputSize - outputSize) / inputSize * 100;
|
|
@@ -499359,7 +499496,7 @@ async function handleToolCall(name, args, extra) {
|
|
|
499359
499496
|
|
|
499360
499497
|
// src/resources/index.ts
|
|
499361
499498
|
init_engine();
|
|
499362
|
-
import { readFile as
|
|
499499
|
+
import { readFile as readFile46 } from "node:fs/promises";
|
|
499363
499500
|
import { resolve as resolve78 } from "node:path";
|
|
499364
499501
|
var resources = [
|
|
499365
499502
|
{
|
|
@@ -499396,7 +499533,7 @@ var resources = [
|
|
|
499396
499533
|
var currentProjectPath = process.env.VIBE_PROJECT_PATH || null;
|
|
499397
499534
|
async function loadProject2(projectPath) {
|
|
499398
499535
|
const absPath = resolve78(process.cwd(), projectPath);
|
|
499399
|
-
const content = await
|
|
499536
|
+
const content = await readFile46(absPath, "utf-8");
|
|
499400
499537
|
const data = JSON.parse(content);
|
|
499401
499538
|
return Project.fromJSON(data);
|
|
499402
499539
|
}
|
|
@@ -499788,14 +499925,14 @@ This creates a music video-style edit where cuts happen in rhythm with the music
|
|
|
499788
499925
|
}
|
|
499789
499926
|
|
|
499790
499927
|
// src/instructions.ts
|
|
499791
|
-
import { existsSync as
|
|
499928
|
+
import { existsSync as existsSync67, mkdirSync as mkdirSync13 } from "node:fs";
|
|
499792
499929
|
import { delimiter, isAbsolute as isAbsolute9, resolve as resolve79 } from "node:path";
|
|
499793
499930
|
var DEFAULT_EXTRA_PATH_DIRS = process.platform === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin", "/opt/local/bin"] : ["/usr/local/bin"];
|
|
499794
499931
|
function ensureSystemPath(env4 = process.env, extraDirs = DEFAULT_EXTRA_PATH_DIRS) {
|
|
499795
499932
|
const current = (env4.PATH ?? "").split(delimiter).filter(Boolean);
|
|
499796
499933
|
const added = [];
|
|
499797
499934
|
for (const dir of extraDirs) {
|
|
499798
|
-
if (!current.includes(dir) &&
|
|
499935
|
+
if (!current.includes(dir) && existsSync67(dir)) {
|
|
499799
499936
|
current.push(dir);
|
|
499800
499937
|
added.push(dir);
|
|
499801
499938
|
}
|
|
@@ -499897,7 +500034,7 @@ function handleCliFlags(argv, version) {
|
|
|
499897
500034
|
}
|
|
499898
500035
|
|
|
499899
500036
|
// src/index.ts
|
|
499900
|
-
if (handleCliFlags(process.argv.slice(2), "0.113.
|
|
500037
|
+
if (handleCliFlags(process.argv.slice(2), "0.113.11")) {
|
|
499901
500038
|
process.exit(0);
|
|
499902
500039
|
}
|
|
499903
500040
|
console.log = (...args) => console.error(...args);
|
|
@@ -499910,7 +500047,7 @@ var server2 = new Server(
|
|
|
499910
500047
|
{
|
|
499911
500048
|
name: "vibeframe",
|
|
499912
500049
|
// Stamped with the package version by build.js at bundle time.
|
|
499913
|
-
version: "0.113.
|
|
500050
|
+
version: "0.113.11"
|
|
499914
500051
|
},
|
|
499915
500052
|
{
|
|
499916
500053
|
capabilities: {
|