@vibeframe/cli 0.106.3 → 0.106.5
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/commands/_shared/host-integration.d.ts +51 -0
- package/dist/commands/_shared/host-integration.test.d.ts +1 -0
- package/dist/commands/_shared/init-templates.d.ts +1 -1
- package/dist/commands/host.d.ts +8 -0
- package/dist/commands/host.test.d.ts +1 -0
- package/dist/index.js +1015 -485
- package/dist/tools/define-tool.js +1 -0
- package/dist/tools/manifest/index.js +13 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -7844,7 +7844,7 @@ function errorMessage(error) {
|
|
|
7844
7844
|
return error instanceof Error ? error.message : "Unknown error";
|
|
7845
7845
|
}
|
|
7846
7846
|
function sleep(ms) {
|
|
7847
|
-
return new Promise((
|
|
7847
|
+
return new Promise((resolve83) => setTimeout(resolve83, ms));
|
|
7848
7848
|
}
|
|
7849
7849
|
var ProviderHttpError;
|
|
7850
7850
|
var init_http = __esm({
|
|
@@ -12238,7 +12238,7 @@ var init_RunwayProvider = __esm({
|
|
|
12238
12238
|
* Sleep helper
|
|
12239
12239
|
*/
|
|
12240
12240
|
sleep(ms) {
|
|
12241
|
-
return new Promise((
|
|
12241
|
+
return new Promise((resolve83) => setTimeout(resolve83, ms));
|
|
12242
12242
|
}
|
|
12243
12243
|
};
|
|
12244
12244
|
RunwayProvider.API_VERSION = "2024-11-06";
|
|
@@ -12679,7 +12679,7 @@ var init_KlingProvider = __esm({
|
|
|
12679
12679
|
* Sleep helper
|
|
12680
12680
|
*/
|
|
12681
12681
|
sleep(ms) {
|
|
12682
|
-
return new Promise((
|
|
12682
|
+
return new Promise((resolve83) => setTimeout(resolve83, ms));
|
|
12683
12683
|
}
|
|
12684
12684
|
};
|
|
12685
12685
|
klingProvider = new KlingProvider();
|
|
@@ -12997,7 +12997,7 @@ var init_GrokProvider = __esm({
|
|
|
12997
12997
|
}
|
|
12998
12998
|
}
|
|
12999
12999
|
sleep(ms) {
|
|
13000
|
-
return new Promise((
|
|
13000
|
+
return new Promise((resolve83) => setTimeout(resolve83, ms));
|
|
13001
13001
|
}
|
|
13002
13002
|
};
|
|
13003
13003
|
grokProvider = new GrokProvider();
|
|
@@ -13032,11 +13032,11 @@ var require_middleware = __commonJS({
|
|
|
13032
13032
|
"use strict";
|
|
13033
13033
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
13034
13034
|
function adopt(value) {
|
|
13035
|
-
return value instanceof P ? value : new P(function(
|
|
13036
|
-
|
|
13035
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
13036
|
+
resolve83(value);
|
|
13037
13037
|
});
|
|
13038
13038
|
}
|
|
13039
|
-
return new (P || (P = Promise))(function(
|
|
13039
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
13040
13040
|
function fulfilled(value) {
|
|
13041
13041
|
try {
|
|
13042
13042
|
step(generator.next(value));
|
|
@@ -13052,7 +13052,7 @@ var require_middleware = __commonJS({
|
|
|
13052
13052
|
}
|
|
13053
13053
|
}
|
|
13054
13054
|
function step(result) {
|
|
13055
|
-
result.done ?
|
|
13055
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
13056
13056
|
}
|
|
13057
13057
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13058
13058
|
});
|
|
@@ -13137,11 +13137,11 @@ var require_response = __commonJS({
|
|
|
13137
13137
|
"use strict";
|
|
13138
13138
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
13139
13139
|
function adopt(value) {
|
|
13140
|
-
return value instanceof P ? value : new P(function(
|
|
13141
|
-
|
|
13140
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
13141
|
+
resolve83(value);
|
|
13142
13142
|
});
|
|
13143
13143
|
}
|
|
13144
|
-
return new (P || (P = Promise))(function(
|
|
13144
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
13145
13145
|
function fulfilled(value) {
|
|
13146
13146
|
try {
|
|
13147
13147
|
step(generator.next(value));
|
|
@@ -13157,7 +13157,7 @@ var require_response = __commonJS({
|
|
|
13157
13157
|
}
|
|
13158
13158
|
}
|
|
13159
13159
|
function step(result) {
|
|
13160
|
-
result.done ?
|
|
13160
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
13161
13161
|
}
|
|
13162
13162
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13163
13163
|
});
|
|
@@ -13264,11 +13264,11 @@ var require_utils = __commonJS({
|
|
|
13264
13264
|
"use strict";
|
|
13265
13265
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
13266
13266
|
function adopt(value) {
|
|
13267
|
-
return value instanceof P ? value : new P(function(
|
|
13268
|
-
|
|
13267
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
13268
|
+
resolve83(value);
|
|
13269
13269
|
});
|
|
13270
13270
|
}
|
|
13271
|
-
return new (P || (P = Promise))(function(
|
|
13271
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
13272
13272
|
function fulfilled(value) {
|
|
13273
13273
|
try {
|
|
13274
13274
|
step(generator.next(value));
|
|
@@ -13284,7 +13284,7 @@ var require_utils = __commonJS({
|
|
|
13284
13284
|
}
|
|
13285
13285
|
}
|
|
13286
13286
|
function step(result) {
|
|
13287
|
-
result.done ?
|
|
13287
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
13288
13288
|
}
|
|
13289
13289
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13290
13290
|
});
|
|
@@ -13377,7 +13377,7 @@ var require_utils = __commonJS({
|
|
|
13377
13377
|
}
|
|
13378
13378
|
function sleep4(ms) {
|
|
13379
13379
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13380
|
-
return new Promise((
|
|
13380
|
+
return new Promise((resolve83) => setTimeout(resolve83, ms));
|
|
13381
13381
|
});
|
|
13382
13382
|
}
|
|
13383
13383
|
}
|
|
@@ -13389,11 +13389,11 @@ var require_retry = __commonJS({
|
|
|
13389
13389
|
"use strict";
|
|
13390
13390
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
13391
13391
|
function adopt(value) {
|
|
13392
|
-
return value instanceof P ? value : new P(function(
|
|
13393
|
-
|
|
13392
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
13393
|
+
resolve83(value);
|
|
13394
13394
|
});
|
|
13395
13395
|
}
|
|
13396
|
-
return new (P || (P = Promise))(function(
|
|
13396
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
13397
13397
|
function fulfilled(value) {
|
|
13398
13398
|
try {
|
|
13399
13399
|
step(generator.next(value));
|
|
@@ -13409,7 +13409,7 @@ var require_retry = __commonJS({
|
|
|
13409
13409
|
}
|
|
13410
13410
|
}
|
|
13411
13411
|
function step(result) {
|
|
13412
|
-
result.done ?
|
|
13412
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
13413
13413
|
}
|
|
13414
13414
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13415
13415
|
});
|
|
@@ -13616,11 +13616,11 @@ var require_request = __commonJS({
|
|
|
13616
13616
|
"use strict";
|
|
13617
13617
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
13618
13618
|
function adopt(value) {
|
|
13619
|
-
return value instanceof P ? value : new P(function(
|
|
13620
|
-
|
|
13619
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
13620
|
+
resolve83(value);
|
|
13621
13621
|
});
|
|
13622
13622
|
}
|
|
13623
|
-
return new (P || (P = Promise))(function(
|
|
13623
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
13624
13624
|
function fulfilled(value) {
|
|
13625
13625
|
try {
|
|
13626
13626
|
step(generator.next(value));
|
|
@@ -13636,7 +13636,7 @@ var require_request = __commonJS({
|
|
|
13636
13636
|
}
|
|
13637
13637
|
}
|
|
13638
13638
|
function step(result) {
|
|
13639
|
-
result.done ?
|
|
13639
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
13640
13640
|
}
|
|
13641
13641
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13642
13642
|
});
|
|
@@ -13723,11 +13723,11 @@ var require_storage = __commonJS({
|
|
|
13723
13723
|
"use strict";
|
|
13724
13724
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
13725
13725
|
function adopt(value) {
|
|
13726
|
-
return value instanceof P ? value : new P(function(
|
|
13727
|
-
|
|
13726
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
13727
|
+
resolve83(value);
|
|
13728
13728
|
});
|
|
13729
13729
|
}
|
|
13730
|
-
return new (P || (P = Promise))(function(
|
|
13730
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
13731
13731
|
function fulfilled(value) {
|
|
13732
13732
|
try {
|
|
13733
13733
|
step(generator.next(value));
|
|
@@ -13743,7 +13743,7 @@ var require_storage = __commonJS({
|
|
|
13743
13743
|
}
|
|
13744
13744
|
}
|
|
13745
13745
|
function step(result) {
|
|
13746
|
-
result.done ?
|
|
13746
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
13747
13747
|
}
|
|
13748
13748
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13749
13749
|
});
|
|
@@ -14071,11 +14071,11 @@ var require_auth = __commonJS({
|
|
|
14071
14071
|
"use strict";
|
|
14072
14072
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
14073
14073
|
function adopt(value) {
|
|
14074
|
-
return value instanceof P ? value : new P(function(
|
|
14075
|
-
|
|
14074
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
14075
|
+
resolve83(value);
|
|
14076
14076
|
});
|
|
14077
14077
|
}
|
|
14078
|
-
return new (P || (P = Promise))(function(
|
|
14078
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
14079
14079
|
function fulfilled(value) {
|
|
14080
14080
|
try {
|
|
14081
14081
|
step(generator.next(value));
|
|
@@ -14091,7 +14091,7 @@ var require_auth = __commonJS({
|
|
|
14091
14091
|
}
|
|
14092
14092
|
}
|
|
14093
14093
|
function step(result) {
|
|
14094
|
-
result.done ?
|
|
14094
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
14095
14095
|
}
|
|
14096
14096
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14097
14097
|
});
|
|
@@ -14130,11 +14130,11 @@ var require_streaming = __commonJS({
|
|
|
14130
14130
|
"use strict";
|
|
14131
14131
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
14132
14132
|
function adopt(value) {
|
|
14133
|
-
return value instanceof P ? value : new P(function(
|
|
14134
|
-
|
|
14133
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
14134
|
+
resolve83(value);
|
|
14135
14135
|
});
|
|
14136
14136
|
}
|
|
14137
|
-
return new (P || (P = Promise))(function(
|
|
14137
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
14138
14138
|
function fulfilled(value) {
|
|
14139
14139
|
try {
|
|
14140
14140
|
step(generator.next(value));
|
|
@@ -14150,7 +14150,7 @@ var require_streaming = __commonJS({
|
|
|
14150
14150
|
}
|
|
14151
14151
|
}
|
|
14152
14152
|
function step(result) {
|
|
14153
|
-
result.done ?
|
|
14153
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
14154
14154
|
}
|
|
14155
14155
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14156
14156
|
});
|
|
@@ -14383,7 +14383,7 @@ var require_streaming = __commonJS({
|
|
|
14383
14383
|
query: options.queryParams
|
|
14384
14384
|
});
|
|
14385
14385
|
this.options = options;
|
|
14386
|
-
this.donePromise = new Promise((
|
|
14386
|
+
this.donePromise = new Promise((resolve83, reject) => {
|
|
14387
14387
|
if (this.streamClosed) {
|
|
14388
14388
|
reject(new response_1.ApiError({
|
|
14389
14389
|
message: "Streaming connection is already closed.",
|
|
@@ -14394,11 +14394,11 @@ var require_streaming = __commonJS({
|
|
|
14394
14394
|
}
|
|
14395
14395
|
this.signal.addEventListener("abort", () => {
|
|
14396
14396
|
var _a2;
|
|
14397
|
-
|
|
14397
|
+
resolve83((_a2 = this.currentData) !== null && _a2 !== void 0 ? _a2 : {});
|
|
14398
14398
|
});
|
|
14399
14399
|
this.on("done", (data) => {
|
|
14400
14400
|
this.streamClosed = true;
|
|
14401
|
-
|
|
14401
|
+
resolve83(data);
|
|
14402
14402
|
});
|
|
14403
14403
|
this.on("error", (error) => {
|
|
14404
14404
|
this.streamClosed = true;
|
|
@@ -14423,7 +14423,7 @@ var require_streaming = __commonJS({
|
|
|
14423
14423
|
if (data) {
|
|
14424
14424
|
yield yield __await(data);
|
|
14425
14425
|
}
|
|
14426
|
-
yield __await(new Promise((
|
|
14426
|
+
yield __await(new Promise((resolve83) => setTimeout(resolve83, 16)));
|
|
14427
14427
|
}
|
|
14428
14428
|
});
|
|
14429
14429
|
}
|
|
@@ -14468,11 +14468,11 @@ var require_queue = __commonJS({
|
|
|
14468
14468
|
"use strict";
|
|
14469
14469
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
14470
14470
|
function adopt(value) {
|
|
14471
|
-
return value instanceof P ? value : new P(function(
|
|
14472
|
-
|
|
14471
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
14472
|
+
resolve83(value);
|
|
14473
14473
|
});
|
|
14474
14474
|
}
|
|
14475
|
-
return new (P || (P = Promise))(function(
|
|
14475
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
14476
14476
|
function fulfilled(value) {
|
|
14477
14477
|
try {
|
|
14478
14478
|
step(generator.next(value));
|
|
@@ -14488,7 +14488,7 @@ var require_queue = __commonJS({
|
|
|
14488
14488
|
}
|
|
14489
14489
|
}
|
|
14490
14490
|
function step(result) {
|
|
14491
|
-
result.done ?
|
|
14491
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
14492
14492
|
}
|
|
14493
14493
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14494
14494
|
});
|
|
@@ -14623,7 +14623,7 @@ var require_queue = __commonJS({
|
|
|
14623
14623
|
}
|
|
14624
14624
|
return doneStatus;
|
|
14625
14625
|
}
|
|
14626
|
-
return new Promise((
|
|
14626
|
+
return new Promise((resolve83, reject) => {
|
|
14627
14627
|
var _a;
|
|
14628
14628
|
let pollingTimeoutId;
|
|
14629
14629
|
const pollInterval = "pollInterval" in options && typeof options.pollInterval === "number" ? (_a = options.pollInterval) !== null && _a !== void 0 ? _a : DEFAULT_POLL_INTERVAL : DEFAULT_POLL_INTERVAL;
|
|
@@ -14655,7 +14655,7 @@ var require_queue = __commonJS({
|
|
|
14655
14655
|
}
|
|
14656
14656
|
if (requestStatus.status === "COMPLETED") {
|
|
14657
14657
|
clearScheduledTasks();
|
|
14658
|
-
|
|
14658
|
+
resolve83(requestStatus);
|
|
14659
14659
|
return;
|
|
14660
14660
|
}
|
|
14661
14661
|
pollingTimeoutId = setTimeout(poll, pollInterval);
|
|
@@ -16616,11 +16616,11 @@ var require_realtime = __commonJS({
|
|
|
16616
16616
|
"use strict";
|
|
16617
16617
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
16618
16618
|
function adopt(value) {
|
|
16619
|
-
return value instanceof P ? value : new P(function(
|
|
16620
|
-
|
|
16619
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
16620
|
+
resolve83(value);
|
|
16621
16621
|
});
|
|
16622
16622
|
}
|
|
16623
|
-
return new (P || (P = Promise))(function(
|
|
16623
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
16624
16624
|
function fulfilled(value) {
|
|
16625
16625
|
try {
|
|
16626
16626
|
step(generator.next(value));
|
|
@@ -16636,7 +16636,7 @@ var require_realtime = __commonJS({
|
|
|
16636
16636
|
}
|
|
16637
16637
|
}
|
|
16638
16638
|
function step(result) {
|
|
16639
|
-
result.done ?
|
|
16639
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
16640
16640
|
}
|
|
16641
16641
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
16642
16642
|
});
|
|
@@ -16961,11 +16961,11 @@ var require_client = __commonJS({
|
|
|
16961
16961
|
"use strict";
|
|
16962
16962
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
16963
16963
|
function adopt(value) {
|
|
16964
|
-
return value instanceof P ? value : new P(function(
|
|
16965
|
-
|
|
16964
|
+
return value instanceof P ? value : new P(function(resolve83) {
|
|
16965
|
+
resolve83(value);
|
|
16966
16966
|
});
|
|
16967
16967
|
}
|
|
16968
|
-
return new (P || (P = Promise))(function(
|
|
16968
|
+
return new (P || (P = Promise))(function(resolve83, reject) {
|
|
16969
16969
|
function fulfilled(value) {
|
|
16970
16970
|
try {
|
|
16971
16971
|
step(generator.next(value));
|
|
@@ -16981,7 +16981,7 @@ var require_client = __commonJS({
|
|
|
16981
16981
|
}
|
|
16982
16982
|
}
|
|
16983
16983
|
function step(result) {
|
|
16984
|
-
result.done ?
|
|
16984
|
+
result.done ? resolve83(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
16985
16985
|
}
|
|
16986
16986
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
16987
16987
|
});
|
|
@@ -17666,7 +17666,7 @@ var init_ReplicateProvider = __esm({
|
|
|
17666
17666
|
* Sleep helper
|
|
17667
17667
|
*/
|
|
17668
17668
|
sleep(ms) {
|
|
17669
|
-
return new Promise((
|
|
17669
|
+
return new Promise((resolve83) => setTimeout(resolve83, ms));
|
|
17670
17670
|
}
|
|
17671
17671
|
/**
|
|
17672
17672
|
* Generate music from text prompt using MusicGen
|
|
@@ -21601,7 +21601,7 @@ var require_timestamp2 = __commonJS({
|
|
|
21601
21601
|
resolve: (str) => parseSexagesimal(str, false),
|
|
21602
21602
|
stringify: stringifySexagesimal
|
|
21603
21603
|
};
|
|
21604
|
-
var
|
|
21604
|
+
var timestamp2 = {
|
|
21605
21605
|
identify: (value) => value instanceof Date,
|
|
21606
21606
|
default: true,
|
|
21607
21607
|
tag: "tag:yaml.org,2002:timestamp",
|
|
@@ -21610,7 +21610,7 @@ var require_timestamp2 = __commonJS({
|
|
|
21610
21610
|
// assumed to be 00:00:00Z (start of day, UTC).
|
|
21611
21611
|
test: RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"),
|
|
21612
21612
|
resolve(str) {
|
|
21613
|
-
const match = str.match(
|
|
21613
|
+
const match = str.match(timestamp2.test);
|
|
21614
21614
|
if (!match)
|
|
21615
21615
|
throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");
|
|
21616
21616
|
const [, year, month, day, hour, minute, second] = match.map(Number);
|
|
@@ -21629,7 +21629,7 @@ var require_timestamp2 = __commonJS({
|
|
|
21629
21629
|
};
|
|
21630
21630
|
exports.floatTime = floatTime;
|
|
21631
21631
|
exports.intTime = intTime;
|
|
21632
|
-
exports.timestamp =
|
|
21632
|
+
exports.timestamp = timestamp2;
|
|
21633
21633
|
}
|
|
21634
21634
|
});
|
|
21635
21635
|
|
|
@@ -21649,7 +21649,7 @@ var require_schema3 = __commonJS({
|
|
|
21649
21649
|
var omap = require_omap();
|
|
21650
21650
|
var pairs = require_pairs();
|
|
21651
21651
|
var set = require_set();
|
|
21652
|
-
var
|
|
21652
|
+
var timestamp2 = require_timestamp2();
|
|
21653
21653
|
var schema = [
|
|
21654
21654
|
map.map,
|
|
21655
21655
|
seq.seq,
|
|
@@ -21669,9 +21669,9 @@ var require_schema3 = __commonJS({
|
|
|
21669
21669
|
omap.omap,
|
|
21670
21670
|
pairs.pairs,
|
|
21671
21671
|
set.set,
|
|
21672
|
-
|
|
21673
|
-
|
|
21674
|
-
|
|
21672
|
+
timestamp2.intTime,
|
|
21673
|
+
timestamp2.floatTime,
|
|
21674
|
+
timestamp2.timestamp
|
|
21675
21675
|
];
|
|
21676
21676
|
exports.schema = schema;
|
|
21677
21677
|
}
|
|
@@ -21696,7 +21696,7 @@ var require_tags = __commonJS({
|
|
|
21696
21696
|
var pairs = require_pairs();
|
|
21697
21697
|
var schema$2 = require_schema3();
|
|
21698
21698
|
var set = require_set();
|
|
21699
|
-
var
|
|
21699
|
+
var timestamp2 = require_timestamp2();
|
|
21700
21700
|
var schemas = /* @__PURE__ */ new Map([
|
|
21701
21701
|
["core", schema.schema],
|
|
21702
21702
|
["failsafe", [map.map, seq.seq, string.string]],
|
|
@@ -21710,11 +21710,11 @@ var require_tags = __commonJS({
|
|
|
21710
21710
|
float: float.float,
|
|
21711
21711
|
floatExp: float.floatExp,
|
|
21712
21712
|
floatNaN: float.floatNaN,
|
|
21713
|
-
floatTime:
|
|
21713
|
+
floatTime: timestamp2.floatTime,
|
|
21714
21714
|
int: int.int,
|
|
21715
21715
|
intHex: int.intHex,
|
|
21716
21716
|
intOct: int.intOct,
|
|
21717
|
-
intTime:
|
|
21717
|
+
intTime: timestamp2.intTime,
|
|
21718
21718
|
map: map.map,
|
|
21719
21719
|
merge: merge.merge,
|
|
21720
21720
|
null: _null.nullTag,
|
|
@@ -21722,7 +21722,7 @@ var require_tags = __commonJS({
|
|
|
21722
21722
|
pairs: pairs.pairs,
|
|
21723
21723
|
seq: seq.seq,
|
|
21724
21724
|
set: set.set,
|
|
21725
|
-
timestamp:
|
|
21725
|
+
timestamp: timestamp2.timestamp
|
|
21726
21726
|
};
|
|
21727
21727
|
var coreKnownTags = {
|
|
21728
21728
|
"tag:yaml.org,2002:binary": binary.binary,
|
|
@@ -21730,7 +21730,7 @@ var require_tags = __commonJS({
|
|
|
21730
21730
|
"tag:yaml.org,2002:omap": omap.omap,
|
|
21731
21731
|
"tag:yaml.org,2002:pairs": pairs.pairs,
|
|
21732
21732
|
"tag:yaml.org,2002:set": set.set,
|
|
21733
|
-
"tag:yaml.org,2002:timestamp":
|
|
21733
|
+
"tag:yaml.org,2002:timestamp": timestamp2.timestamp
|
|
21734
21734
|
};
|
|
21735
21735
|
function getTags(customTags, schemaName, addMergeTag) {
|
|
21736
21736
|
const schemaTags = schemas.get(schemaName);
|
|
@@ -26132,7 +26132,7 @@ async function prompt(question, hidden = false) {
|
|
|
26132
26132
|
input: process.stdin,
|
|
26133
26133
|
output: process.stdout
|
|
26134
26134
|
});
|
|
26135
|
-
return new Promise((
|
|
26135
|
+
return new Promise((resolve83) => {
|
|
26136
26136
|
if (hidden && process.stdin.isTTY) {
|
|
26137
26137
|
process.stdout.write(question);
|
|
26138
26138
|
let input = "";
|
|
@@ -26146,7 +26146,7 @@ async function prompt(question, hidden = false) {
|
|
|
26146
26146
|
process.stdin.removeListener("data", onData);
|
|
26147
26147
|
process.stdout.write("\n");
|
|
26148
26148
|
rl.close();
|
|
26149
|
-
|
|
26149
|
+
resolve83(input);
|
|
26150
26150
|
} else if (char === "") {
|
|
26151
26151
|
process.exit(1);
|
|
26152
26152
|
} else if (char === "\x7F" || char === "\b") {
|
|
@@ -26161,7 +26161,7 @@ async function prompt(question, hidden = false) {
|
|
|
26161
26161
|
} else {
|
|
26162
26162
|
rl.question(question, (answer) => {
|
|
26163
26163
|
rl.close();
|
|
26164
|
-
|
|
26164
|
+
resolve83(answer);
|
|
26165
26165
|
});
|
|
26166
26166
|
}
|
|
26167
26167
|
});
|
|
@@ -26758,6 +26758,18 @@ a host agent's built-in image/audio generation tool for VibeFrame project
|
|
|
26758
26758
|
assets unless the user explicitly requests an external, non-VibeFrame
|
|
26759
26759
|
asset.
|
|
26760
26760
|
|
|
26761
|
+
## App host setup
|
|
26762
|
+
|
|
26763
|
+
VibeFrame is CLI-first, not terminal-only. Codex, Claude Code, and Cursor can
|
|
26764
|
+
drive this project through shell commands, and app hosts can use the MCP server
|
|
26765
|
+
as a typed tool surface.
|
|
26766
|
+
|
|
26767
|
+
\`\`\`bash
|
|
26768
|
+
vibe host setup all # print Codex/Claude/Cursor snippets
|
|
26769
|
+
vibe host setup all --write # write project/app config
|
|
26770
|
+
vibe host doctor all --json # verify readiness
|
|
26771
|
+
\`\`\`
|
|
26772
|
+
|
|
26761
26773
|
## Skills \u2014 USE THESE FIRST
|
|
26762
26774
|
|
|
26763
26775
|
@SKILL.md
|
|
@@ -33269,16 +33281,16 @@ async function prompt2(question) {
|
|
|
33269
33281
|
input,
|
|
33270
33282
|
output: process.stdout
|
|
33271
33283
|
});
|
|
33272
|
-
return new Promise((
|
|
33284
|
+
return new Promise((resolve83) => {
|
|
33273
33285
|
rl.question(question, (answer) => {
|
|
33274
33286
|
rl.close();
|
|
33275
|
-
|
|
33287
|
+
resolve83(answer);
|
|
33276
33288
|
});
|
|
33277
33289
|
});
|
|
33278
33290
|
}
|
|
33279
33291
|
async function promptHidden(question, opts = {}) {
|
|
33280
33292
|
const input = getTTYInputStream();
|
|
33281
|
-
return new Promise((
|
|
33293
|
+
return new Promise((resolve83) => {
|
|
33282
33294
|
let value = "";
|
|
33283
33295
|
if (typeof input.setRawMode === "function") {
|
|
33284
33296
|
input.setRawMode(true);
|
|
@@ -33292,7 +33304,7 @@ async function promptHidden(question, opts = {}) {
|
|
|
33292
33304
|
input.setRawMode(false);
|
|
33293
33305
|
input.removeListener("data", onData);
|
|
33294
33306
|
process.stdout.write("\n");
|
|
33295
|
-
|
|
33307
|
+
resolve83(value);
|
|
33296
33308
|
} else if (char === "") {
|
|
33297
33309
|
input.setRawMode(false);
|
|
33298
33310
|
process.stdout.write("\n");
|
|
@@ -33318,7 +33330,7 @@ async function promptHidden(question, opts = {}) {
|
|
|
33318
33330
|
const rl = createInterface2({ input, output: process.stdout });
|
|
33319
33331
|
rl.question(question, (answer) => {
|
|
33320
33332
|
rl.close();
|
|
33321
|
-
|
|
33333
|
+
resolve83(answer);
|
|
33322
33334
|
});
|
|
33323
33335
|
}
|
|
33324
33336
|
});
|
|
@@ -33326,7 +33338,7 @@ async function promptHidden(question, opts = {}) {
|
|
|
33326
33338
|
async function promptSelect(_question, options, defaultIndex = 0, opts = {}) {
|
|
33327
33339
|
const input = getTTYInputStream();
|
|
33328
33340
|
if (typeof input.setRawMode === "function") {
|
|
33329
|
-
return new Promise((
|
|
33341
|
+
return new Promise((resolve83) => {
|
|
33330
33342
|
let selected = defaultIndex;
|
|
33331
33343
|
const render = () => {
|
|
33332
33344
|
if (renderCount > 0) {
|
|
@@ -33354,7 +33366,7 @@ async function promptSelect(_question, options, defaultIndex = 0, opts = {}) {
|
|
|
33354
33366
|
input.setRawMode(false);
|
|
33355
33367
|
input.removeListener("data", onData);
|
|
33356
33368
|
process.stdout.write("\n");
|
|
33357
|
-
|
|
33369
|
+
resolve83(selected);
|
|
33358
33370
|
} else if (char === "") {
|
|
33359
33371
|
input.setRawMode(false);
|
|
33360
33372
|
process.stdout.write("\n");
|
|
@@ -33364,7 +33376,7 @@ async function promptSelect(_question, options, defaultIndex = 0, opts = {}) {
|
|
|
33364
33376
|
input.setRawMode(false);
|
|
33365
33377
|
input.removeListener("data", onData);
|
|
33366
33378
|
process.stdout.write("\n");
|
|
33367
|
-
|
|
33379
|
+
resolve83(opts.backIndex);
|
|
33368
33380
|
} else if (char === "\x1B[A" || char === "k") {
|
|
33369
33381
|
selected = (selected - 1 + options.length) % options.length;
|
|
33370
33382
|
render();
|
|
@@ -33378,7 +33390,7 @@ async function promptSelect(_question, options, defaultIndex = 0, opts = {}) {
|
|
|
33378
33390
|
input.removeListener("data", onData);
|
|
33379
33391
|
render();
|
|
33380
33392
|
process.stdout.write("\n");
|
|
33381
|
-
|
|
33393
|
+
resolve83(selected);
|
|
33382
33394
|
}
|
|
33383
33395
|
};
|
|
33384
33396
|
const onData = (chunk) => {
|
|
@@ -33402,7 +33414,7 @@ async function promptSelect(_question, options, defaultIndex = 0, opts = {}) {
|
|
|
33402
33414
|
async function promptConfirm(question, defaultYes = true) {
|
|
33403
33415
|
const input = getTTYInputStream();
|
|
33404
33416
|
if (typeof input.setRawMode === "function") {
|
|
33405
|
-
return new Promise((
|
|
33417
|
+
return new Promise((resolve83) => {
|
|
33406
33418
|
const options = ["Yes", "No"];
|
|
33407
33419
|
let selected = defaultYes ? 0 : 1;
|
|
33408
33420
|
let renderCount = 0;
|
|
@@ -33432,7 +33444,7 @@ async function promptConfirm(question, defaultYes = true) {
|
|
|
33432
33444
|
finished = true;
|
|
33433
33445
|
input.setRawMode(false);
|
|
33434
33446
|
input.removeListener("data", onData);
|
|
33435
|
-
|
|
33447
|
+
resolve83(selected === 0);
|
|
33436
33448
|
} else if (char === "") {
|
|
33437
33449
|
input.setRawMode(false);
|
|
33438
33450
|
process.stdout.write("\n");
|
|
@@ -33446,14 +33458,14 @@ async function promptConfirm(question, defaultYes = true) {
|
|
|
33446
33458
|
input.setRawMode(false);
|
|
33447
33459
|
input.removeListener("data", onData);
|
|
33448
33460
|
render();
|
|
33449
|
-
|
|
33461
|
+
resolve83(true);
|
|
33450
33462
|
} else if (char === "n" || char === "N") {
|
|
33451
33463
|
selected = 1;
|
|
33452
33464
|
finished = true;
|
|
33453
33465
|
input.setRawMode(false);
|
|
33454
33466
|
input.removeListener("data", onData);
|
|
33455
33467
|
render();
|
|
33456
|
-
|
|
33468
|
+
resolve83(false);
|
|
33457
33469
|
}
|
|
33458
33470
|
};
|
|
33459
33471
|
const onData = (chunk) => {
|
|
@@ -33472,7 +33484,7 @@ async function promptMultiSelect(_question, options, defaultSelected = [], opts
|
|
|
33472
33484
|
const input = getTTYInputStream();
|
|
33473
33485
|
const selected = options.map((_, i) => Boolean(defaultSelected[i]));
|
|
33474
33486
|
if (typeof input.setRawMode === "function") {
|
|
33475
|
-
return new Promise((
|
|
33487
|
+
return new Promise((resolve83) => {
|
|
33476
33488
|
let cursor = 0;
|
|
33477
33489
|
let renderCount = 0;
|
|
33478
33490
|
let userToggled = false;
|
|
@@ -33502,7 +33514,7 @@ async function promptMultiSelect(_question, options, defaultSelected = [], opts
|
|
|
33502
33514
|
for (let i = 0; i < selected.length; i++) {
|
|
33503
33515
|
if (selected[i]) result.push(i);
|
|
33504
33516
|
}
|
|
33505
|
-
|
|
33517
|
+
resolve83(result);
|
|
33506
33518
|
};
|
|
33507
33519
|
let finished = false;
|
|
33508
33520
|
const handleChar = (char) => {
|
|
@@ -33816,7 +33828,7 @@ var init_speech = __esm({
|
|
|
33816
33828
|
import { writeFile as writeFile19, unlink, rename } from "node:fs/promises";
|
|
33817
33829
|
import { resolve as resolve22, basename as basename4 } from "node:path";
|
|
33818
33830
|
function sleep2(ms) {
|
|
33819
|
-
return new Promise((
|
|
33831
|
+
return new Promise((resolve83) => setTimeout(resolve83, ms));
|
|
33820
33832
|
}
|
|
33821
33833
|
async function uploadToImgbb(imageBuffer, apiKey) {
|
|
33822
33834
|
try {
|
|
@@ -35506,7 +35518,7 @@ function unique(items) {
|
|
|
35506
35518
|
];
|
|
35507
35519
|
}
|
|
35508
35520
|
function sleep3(ms) {
|
|
35509
|
-
return new Promise((
|
|
35521
|
+
return new Promise((resolve83) => setTimeout(resolve83, ms));
|
|
35510
35522
|
}
|
|
35511
35523
|
var init_status_jobs = __esm({
|
|
35512
35524
|
"src/commands/_shared/status-jobs.ts"() {
|
|
@@ -36015,20 +36027,20 @@ async function executeThumbnailBestFrame(options) {
|
|
|
36015
36027
|
if (!jsonMatch) {
|
|
36016
36028
|
return { success: false, error: `Could not parse timestamp from Gemini response: ${result.response.slice(0, 200)}` };
|
|
36017
36029
|
}
|
|
36018
|
-
const
|
|
36030
|
+
const timestamp2 = parseFloat(jsonMatch[1]);
|
|
36019
36031
|
let reason;
|
|
36020
36032
|
const reasonMatch = result.response.match(/"reason"\s*:\s*"([^"]+)"/);
|
|
36021
36033
|
if (reasonMatch) {
|
|
36022
36034
|
reason = reasonMatch[1];
|
|
36023
36035
|
}
|
|
36024
|
-
await execSafe("ffmpeg", ["-ss", String(
|
|
36036
|
+
await execSafe("ffmpeg", ["-ss", String(timestamp2), "-i", videoPath, "-frames:v", "1", "-q:v", "2", outputPath, "-y"], { timeout: 6e4, maxBuffer: 50 * 1024 * 1024 });
|
|
36025
36037
|
if (!existsSync16(outputPath)) {
|
|
36026
36038
|
return { success: false, error: "FFmpeg failed to extract frame" };
|
|
36027
36039
|
}
|
|
36028
36040
|
return {
|
|
36029
36041
|
success: true,
|
|
36030
36042
|
outputPath,
|
|
36031
|
-
timestamp,
|
|
36043
|
+
timestamp: timestamp2,
|
|
36032
36044
|
reason
|
|
36033
36045
|
};
|
|
36034
36046
|
} catch (error) {
|
|
@@ -39557,8 +39569,8 @@ function parseSRT(content) {
|
|
|
39557
39569
|
}
|
|
39558
39570
|
return segments;
|
|
39559
39571
|
}
|
|
39560
|
-
function parseSRTTimestamp(
|
|
39561
|
-
const normalized =
|
|
39572
|
+
function parseSRTTimestamp(timestamp2) {
|
|
39573
|
+
const normalized = timestamp2.replace(",", ".");
|
|
39562
39574
|
const parts = normalized.split(":");
|
|
39563
39575
|
const hours = parseInt(parts[0], 10);
|
|
39564
39576
|
const mins = parseInt(parts[1], 10);
|
|
@@ -47096,6 +47108,7 @@ var init_product_surface = __esm({
|
|
|
47096
47108
|
build: { surface: "public", note: "Primary storyboard-to-video build engine." },
|
|
47097
47109
|
render: { surface: "public", note: "Project render entrypoint." },
|
|
47098
47110
|
doctor: { surface: "public", note: "System and provider health check." },
|
|
47111
|
+
host: { surface: "public", note: "Codex, Claude, and Cursor app integration setup." },
|
|
47099
47112
|
guide: { surface: "public", note: "Workflow chooser and first-run guidance." },
|
|
47100
47113
|
demo: { surface: "advanced", note: "Smoke-test/demo helper, not a core workflow." },
|
|
47101
47114
|
run: { surface: "agent", note: "Automation surface for YAML pipelines." },
|
|
@@ -50855,11 +50868,11 @@ var init_FrameParser = __esm({
|
|
|
50855
50868
|
const nullStr = _FrameParser.readNullTerminatedString(uint8Array, syltHeader.encoding);
|
|
50856
50869
|
uint8Array = uint8Array.subarray(nullStr.len);
|
|
50857
50870
|
if (readSyllables) {
|
|
50858
|
-
const
|
|
50871
|
+
const timestamp2 = UINT32_BE.get(uint8Array, 0);
|
|
50859
50872
|
uint8Array = uint8Array.subarray(UINT32_BE.len);
|
|
50860
50873
|
result.syncText.push({
|
|
50861
50874
|
text: nullStr.text,
|
|
50862
|
-
timestamp
|
|
50875
|
+
timestamp: timestamp2
|
|
50863
50876
|
});
|
|
50864
50877
|
} else {
|
|
50865
50878
|
result.descriptor = nullStr.text;
|
|
@@ -56854,8 +56867,8 @@ var init_detect = __esm({
|
|
|
56854
56867
|
let match;
|
|
56855
56868
|
scenes.push({ timestamp: 0, score: 1 });
|
|
56856
56869
|
while ((match = regex2.exec(output)) !== null) {
|
|
56857
|
-
const
|
|
56858
|
-
scenes.push({ timestamp, score: threshold });
|
|
56870
|
+
const timestamp2 = parseFloat(match[1]);
|
|
56871
|
+
scenes.push({ timestamp: timestamp2, score: threshold });
|
|
56859
56872
|
}
|
|
56860
56873
|
const totalDuration = await ffprobeDuration(absPath);
|
|
56861
56874
|
spinner2.succeed(source_default.green(`Detected ${scenes.length} scenes`));
|
|
@@ -58464,14 +58477,14 @@ var init_adapters = __esm({
|
|
|
58464
58477
|
});
|
|
58465
58478
|
|
|
58466
58479
|
// src/commands/_shared/storyboard-revise.ts
|
|
58467
|
-
import { existsSync as
|
|
58468
|
-
import { readFile as
|
|
58469
|
-
import { join as
|
|
58480
|
+
import { existsSync as existsSync42 } from "node:fs";
|
|
58481
|
+
import { readFile as readFile39, writeFile as writeFile46 } from "node:fs/promises";
|
|
58482
|
+
import { join as join20, resolve as resolve55 } from "node:path";
|
|
58470
58483
|
async function executeStoryboardRevision(opts) {
|
|
58471
|
-
const projectDir =
|
|
58472
|
-
const storyboardPath2 =
|
|
58484
|
+
const projectDir = resolve55(opts.projectDir);
|
|
58485
|
+
const storyboardPath2 = join20(projectDir, "STORYBOARD.md");
|
|
58473
58486
|
const retryWith = [`vibe storyboard revise ${projectDir} --from "<request>" --dry-run --json`];
|
|
58474
|
-
if (!
|
|
58487
|
+
if (!existsSync42(storyboardPath2)) {
|
|
58475
58488
|
return failureResult({
|
|
58476
58489
|
projectDir,
|
|
58477
58490
|
storyboardPath: storyboardPath2,
|
|
@@ -58481,7 +58494,7 @@ async function executeStoryboardRevision(opts) {
|
|
|
58481
58494
|
retryWith: [`vibe init ${projectDir} --from "<brief>" --json`]
|
|
58482
58495
|
});
|
|
58483
58496
|
}
|
|
58484
|
-
const currentStoryboard = await
|
|
58497
|
+
const currentStoryboard = await readFile39(storyboardPath2, "utf-8");
|
|
58485
58498
|
const projectConfig = await readProjectConfig(projectDir);
|
|
58486
58499
|
const explicitComposer = opts.composer ?? projectConfig.config.providers.composer ?? void 0;
|
|
58487
58500
|
let provider = explicitComposer ?? "claude";
|
|
@@ -58580,7 +58593,7 @@ async function executeStoryboardRevision(opts) {
|
|
|
58580
58593
|
}
|
|
58581
58594
|
const storyboardMd = normalizeMarkdown(payload.storyboardMd);
|
|
58582
58595
|
if (!opts.dryRun) {
|
|
58583
|
-
await
|
|
58596
|
+
await writeFile46(storyboardPath2, storyboardMd, "utf-8");
|
|
58584
58597
|
}
|
|
58585
58598
|
const changedBeats = unique2([...diffChangedBeats(currentStoryboard, storyboardMd), ...payload.changedBeats]);
|
|
58586
58599
|
return stripUndefined3({
|
|
@@ -58703,18 +58716,18 @@ function diffChangedBeats(before, after) {
|
|
|
58703
58716
|
return ids.filter((id) => JSON.stringify(beforeBeats.get(id) ?? null) !== JSON.stringify(afterBeats.get(id) ?? null));
|
|
58704
58717
|
}
|
|
58705
58718
|
async function readRevisionContext(projectDir) {
|
|
58706
|
-
const designMd = await readOptionalText(
|
|
58707
|
-
const buildReportJson = await readOptionalJsonText(
|
|
58719
|
+
const designMd = await readOptionalText(join20(projectDir, "DESIGN.md"));
|
|
58720
|
+
const buildReportJson = await readOptionalJsonText(join20(projectDir, "build-report.json"));
|
|
58708
58721
|
return { designMd, buildReportJson };
|
|
58709
58722
|
}
|
|
58710
58723
|
async function readOptionalText(path2) {
|
|
58711
|
-
if (!
|
|
58712
|
-
return
|
|
58724
|
+
if (!existsSync42(path2)) return null;
|
|
58725
|
+
return readFile39(path2, "utf-8");
|
|
58713
58726
|
}
|
|
58714
58727
|
async function readOptionalJsonText(path2) {
|
|
58715
|
-
if (!
|
|
58728
|
+
if (!existsSync42(path2)) return null;
|
|
58716
58729
|
try {
|
|
58717
|
-
const parsed = JSON.parse(await
|
|
58730
|
+
const parsed = JSON.parse(await readFile39(path2, "utf-8"));
|
|
58718
58731
|
return JSON.stringify(parsed, null, 2);
|
|
58719
58732
|
} catch {
|
|
58720
58733
|
return null;
|
|
@@ -58762,8 +58775,8 @@ var init_storyboard_revise = __esm({
|
|
|
58762
58775
|
});
|
|
58763
58776
|
|
|
58764
58777
|
// src/commands/_shared/build-asset-reference.ts
|
|
58765
|
-
import { existsSync as
|
|
58766
|
-
import { extname as extname13, isAbsolute as isAbsolute5, relative as relative10, resolve as
|
|
58778
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
58779
|
+
import { extname as extname13, isAbsolute as isAbsolute5, relative as relative10, resolve as resolve57, sep } from "node:path";
|
|
58767
58780
|
function resolveTypedAssetReference(projectDir, kind, value) {
|
|
58768
58781
|
const raw = stringOrUndefined2(value);
|
|
58769
58782
|
if (!raw || !looksLikeAssetPath(raw)) return null;
|
|
@@ -58790,10 +58803,10 @@ function isReadyAssetReference(reference) {
|
|
|
58790
58803
|
function resolveReference(projectDir, kind, raw, source, forcedError) {
|
|
58791
58804
|
const ext = extname13(raw).toLowerCase();
|
|
58792
58805
|
const inferred = inferAssetKind(raw);
|
|
58793
|
-
const absPath = isAbsolute5(raw) ?
|
|
58794
|
-
const rel = relative10(
|
|
58806
|
+
const absPath = isAbsolute5(raw) ? resolve57(raw) : resolve57(projectDir, raw);
|
|
58807
|
+
const rel = relative10(resolve57(projectDir), absPath);
|
|
58795
58808
|
const withinProject = rel.length > 0 && !rel.startsWith("..") && !isAbsolute5(rel);
|
|
58796
|
-
const exists = withinProject &&
|
|
58809
|
+
const exists = withinProject && existsSync44(absPath);
|
|
58797
58810
|
let error = forcedError;
|
|
58798
58811
|
if (!error && inferred && inferred !== kind && !isNarrationAudioReference(kind, ext)) {
|
|
58799
58812
|
error = `Asset reference "${raw}" is a ${inferred} asset, not ${kind}.`;
|
|
@@ -58952,19 +58965,19 @@ var init_build_backdrop_prompt = __esm({
|
|
|
58952
58965
|
});
|
|
58953
58966
|
|
|
58954
58967
|
// src/commands/_shared/build-plan.ts
|
|
58955
|
-
import { existsSync as
|
|
58956
|
-
import { readFile as
|
|
58957
|
-
import { dirname as
|
|
58968
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
58969
|
+
import { readFile as readFile41 } from "node:fs/promises";
|
|
58970
|
+
import { dirname as dirname20, join as join21, resolve as resolve58 } from "node:path";
|
|
58958
58971
|
async function createBuildPlan(opts) {
|
|
58959
|
-
const projectDir =
|
|
58972
|
+
const projectDir = resolve58(opts.projectDir);
|
|
58960
58973
|
loadPlanEnv(projectDir);
|
|
58961
58974
|
const stage = opts.stage ?? "all";
|
|
58962
58975
|
const config2 = await readProjectConfig(projectDir);
|
|
58963
|
-
const storyboardPath2 =
|
|
58976
|
+
const storyboardPath2 = join21(projectDir, "STORYBOARD.md");
|
|
58964
58977
|
const warnings = [];
|
|
58965
58978
|
const retryWith = [];
|
|
58966
58979
|
const providerResolution = [];
|
|
58967
|
-
if (!
|
|
58980
|
+
if (!existsSync45(storyboardPath2)) {
|
|
58968
58981
|
const validation2 = {
|
|
58969
58982
|
ok: false,
|
|
58970
58983
|
issues: [
|
|
@@ -58993,7 +59006,7 @@ async function createBuildPlan(opts) {
|
|
|
58993
59006
|
validation: validation2
|
|
58994
59007
|
});
|
|
58995
59008
|
}
|
|
58996
|
-
const storyboardMd = await
|
|
59009
|
+
const storyboardMd = await readFile41(storyboardPath2, "utf-8");
|
|
58997
59010
|
const validation = validateStoryboardMarkdown(storyboardMd);
|
|
58998
59011
|
const validationIssues = [...validation.issues];
|
|
58999
59012
|
const parsed = parseStoryboard(storyboardMd);
|
|
@@ -59019,7 +59032,7 @@ async function createBuildPlan(opts) {
|
|
|
59019
59032
|
const imageQuality = opts.imageQuality ?? config2.config.build.imageQuality ?? "hd";
|
|
59020
59033
|
const imageSize2 = opts.imageSize ?? config2.config.build.imageSize ?? "1536x1024";
|
|
59021
59034
|
const imageRatio = imageRatioForSize(imageSize2);
|
|
59022
|
-
const needsComposer = includeCompose && mode !== "agent" && sourceBeats.some((beat) => !
|
|
59035
|
+
const needsComposer = includeCompose && mode !== "agent" && sourceBeats.some((beat) => !existsSync45(join21(projectDir, `compositions/scene-${beat.id}.html`)));
|
|
59023
59036
|
const resolved = await resolvePlanProviders({
|
|
59024
59037
|
projectDir,
|
|
59025
59038
|
config: config2,
|
|
@@ -59140,7 +59153,7 @@ async function createBuildPlan(opts) {
|
|
|
59140
59153
|
active: includeAssets
|
|
59141
59154
|
}) : null;
|
|
59142
59155
|
const compositionPath = `compositions/scene-${beat.id}.html`;
|
|
59143
|
-
const compositionExists =
|
|
59156
|
+
const compositionExists = existsSync45(join21(projectDir, compositionPath));
|
|
59144
59157
|
for (const asset of [narration, backdrop, video, music]) {
|
|
59145
59158
|
if (!asset) continue;
|
|
59146
59159
|
if (asset.referenceError) {
|
|
@@ -59207,7 +59220,7 @@ async function createBuildPlan(opts) {
|
|
|
59207
59220
|
}
|
|
59208
59221
|
}
|
|
59209
59222
|
const validationOk = !validationIssues.some((issue) => issue.severity === "error");
|
|
59210
|
-
if (!
|
|
59223
|
+
if (!existsSync45(join21(projectDir, config2.config.composition.entry))) {
|
|
59211
59224
|
missing.add("root-composition");
|
|
59212
59225
|
if (validationOk) retryWith.push(`vibe build ${projectDir} --stage sync --json`);
|
|
59213
59226
|
}
|
|
@@ -59339,8 +59352,8 @@ function assetPlan(opts) {
|
|
|
59339
59352
|
reason: ready ? "referenced-asset" : "invalid-reference"
|
|
59340
59353
|
};
|
|
59341
59354
|
}
|
|
59342
|
-
const canonicalExists =
|
|
59343
|
-
const cacheHit = opts.cache ?
|
|
59355
|
+
const canonicalExists = existsSync45(join21(opts.projectDir, opts.path));
|
|
59356
|
+
const cacheHit = opts.cache ? existsSync45(join21(opts.projectDir, opts.cache.path)) : false;
|
|
59344
59357
|
const freshness = assetFreshnessFromMetadata({
|
|
59345
59358
|
projectDir: opts.projectDir,
|
|
59346
59359
|
kind: opts.kind,
|
|
@@ -59534,7 +59547,7 @@ async function firstConfiguredComposer(projectDir) {
|
|
|
59534
59547
|
}
|
|
59535
59548
|
function firstExisting2(projectDir, paths) {
|
|
59536
59549
|
for (const path2 of paths) {
|
|
59537
|
-
if (
|
|
59550
|
+
if (existsSync45(join21(projectDir, path2))) return path2;
|
|
59538
59551
|
}
|
|
59539
59552
|
return null;
|
|
59540
59553
|
}
|
|
@@ -59575,15 +59588,15 @@ function unique3(items) {
|
|
|
59575
59588
|
return [...new Set(items.filter((item) => item.length > 0))];
|
|
59576
59589
|
}
|
|
59577
59590
|
function loadPlanEnv(projectDir) {
|
|
59578
|
-
(0, import_dotenv3.config)({ path:
|
|
59579
|
-
(0, import_dotenv3.config)({ path:
|
|
59591
|
+
(0, import_dotenv3.config)({ path: join21(projectDir, ".env"), quiet: true });
|
|
59592
|
+
(0, import_dotenv3.config)({ path: resolve58(process.cwd(), ".env"), quiet: true });
|
|
59580
59593
|
let dir = process.cwd();
|
|
59581
|
-
while (dir !==
|
|
59582
|
-
if (
|
|
59583
|
-
(0, import_dotenv3.config)({ path:
|
|
59594
|
+
while (dir !== dirname20(dir)) {
|
|
59595
|
+
if (existsSync45(join21(dir, "pnpm-workspace.yaml"))) {
|
|
59596
|
+
(0, import_dotenv3.config)({ path: join21(dir, ".env"), quiet: true });
|
|
59584
59597
|
return;
|
|
59585
59598
|
}
|
|
59586
|
-
dir =
|
|
59599
|
+
dir = dirname20(dir);
|
|
59587
59600
|
}
|
|
59588
59601
|
}
|
|
59589
59602
|
var import_dotenv3, BACKDROP_COST_USD, VIDEO_COST_USD, MUSIC_COST_USD, ELEVENLABS_NARRATION_COST_USD, COMPOSE_COST_USD, SUPPORTED_BUILD_IMAGE_PROVIDERS;
|
|
@@ -59611,8 +59624,8 @@ var init_build_plan = __esm({
|
|
|
59611
59624
|
});
|
|
59612
59625
|
|
|
59613
59626
|
// src/commands/_shared/scene-audio-scan.ts
|
|
59614
|
-
import { readFile as
|
|
59615
|
-
import { resolve as
|
|
59627
|
+
import { readFile as readFile42 } from "node:fs/promises";
|
|
59628
|
+
import { resolve as resolve60 } from "node:path";
|
|
59616
59629
|
function parseRootClips(rootHtml) {
|
|
59617
59630
|
const clips = [];
|
|
59618
59631
|
const clipRegex = /<div\b[^>]*class="clip"[^>]*>/gi;
|
|
@@ -59650,9 +59663,9 @@ function parseSceneAudios(compositionHtml) {
|
|
|
59650
59663
|
}
|
|
59651
59664
|
function makeFsCompositionReader(projectDir) {
|
|
59652
59665
|
return async (compositionSrcRel) => {
|
|
59653
|
-
const abs =
|
|
59666
|
+
const abs = resolve60(projectDir, compositionSrcRel);
|
|
59654
59667
|
try {
|
|
59655
|
-
return await
|
|
59668
|
+
return await readFile42(abs, "utf-8");
|
|
59656
59669
|
} catch {
|
|
59657
59670
|
return null;
|
|
59658
59671
|
}
|
|
@@ -59669,7 +59682,7 @@ async function scanSceneAudio(opts) {
|
|
|
59669
59682
|
for (const audio of audios) {
|
|
59670
59683
|
out.push({
|
|
59671
59684
|
srcRel: audio.srcRel,
|
|
59672
|
-
srcAbs:
|
|
59685
|
+
srcAbs: resolve60(opts.projectDir, audio.srcRel),
|
|
59673
59686
|
absoluteStart: clip.start + audio.localStart,
|
|
59674
59687
|
durationHint: audio.durationHint,
|
|
59675
59688
|
clipDurationCap: clip.duration - audio.localStart,
|
|
@@ -59684,7 +59697,7 @@ async function scanSceneAudio(opts) {
|
|
|
59684
59697
|
for (const audio of rootAudios) {
|
|
59685
59698
|
out.push({
|
|
59686
59699
|
srcRel: audio.srcRel,
|
|
59687
|
-
srcAbs:
|
|
59700
|
+
srcAbs: resolve60(opts.projectDir, audio.srcRel),
|
|
59688
59701
|
absoluteStart: audio.localStart,
|
|
59689
59702
|
durationHint: audio.durationHint,
|
|
59690
59703
|
clipDurationCap: Math.max(0, maxClipEnd - audio.localStart),
|
|
@@ -59719,7 +59732,7 @@ var init_scene_audio_scan = __esm({
|
|
|
59719
59732
|
|
|
59720
59733
|
// src/commands/_shared/scene-audio-mux.ts
|
|
59721
59734
|
import { rename as rename4, unlink as unlink3 } from "node:fs/promises";
|
|
59722
|
-
import { resolve as
|
|
59735
|
+
import { resolve as resolve61, dirname as dirname21, extname as extname14, basename as basename20 } from "node:path";
|
|
59723
59736
|
function buildAudioMuxFilter(audios) {
|
|
59724
59737
|
if (audios.length === 0) return null;
|
|
59725
59738
|
const labels = [];
|
|
@@ -59779,8 +59792,8 @@ async function muxAudioIntoVideo(opts) {
|
|
|
59779
59792
|
return { success: true, outputPath: opts.videoPath, audioCount: 0 };
|
|
59780
59793
|
}
|
|
59781
59794
|
const ext = extname14(opts.videoPath) || `.${opts.format}`;
|
|
59782
|
-
const tmpPath =
|
|
59783
|
-
|
|
59795
|
+
const tmpPath = resolve61(
|
|
59796
|
+
dirname21(opts.videoPath),
|
|
59784
59797
|
`.${basename20(opts.videoPath, ext)}.muxing${ext}`
|
|
59785
59798
|
);
|
|
59786
59799
|
const args = ["-y", "-loglevel", "error", "-i", opts.videoPath];
|
|
@@ -59850,9 +59863,9 @@ __export(scene_render_exports, {
|
|
|
59850
59863
|
prepareBeatRenderRoot: () => prepareBeatRenderRoot,
|
|
59851
59864
|
qualityToCrf: () => qualityToCrf2
|
|
59852
59865
|
});
|
|
59853
|
-
import { existsSync as
|
|
59854
|
-
import { mkdir as
|
|
59855
|
-
import { resolve as
|
|
59866
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
59867
|
+
import { mkdir as mkdir24, readFile as readFile43, stat as stat8, writeFile as writeFile48 } from "node:fs/promises";
|
|
59868
|
+
import { resolve as resolve62, relative as relative11, dirname as dirname22, basename as basename21, join as join22, isAbsolute as isAbsolute6 } from "node:path";
|
|
59856
59869
|
import {
|
|
59857
59870
|
createRenderJob,
|
|
59858
59871
|
executeRenderJob
|
|
@@ -59864,9 +59877,9 @@ function defaultOutputPath(opts) {
|
|
|
59864
59877
|
const fmt = opts.format ?? "mp4";
|
|
59865
59878
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
59866
59879
|
const stamp = now.toISOString().replace(/[:T]/g, "-").replace(/\..+$/, "");
|
|
59867
|
-
const name = (opts.projectName ?? basename21(
|
|
59880
|
+
const name = (opts.projectName ?? basename21(resolve62(opts.projectDir))) || "scene";
|
|
59868
59881
|
const beat = opts.beatId ? `-${sanitizeFileSegment2(opts.beatId)}` : "";
|
|
59869
|
-
return
|
|
59882
|
+
return resolve62(opts.projectDir, "renders", `${name}${beat}-${stamp}.${fmt}`);
|
|
59870
59883
|
}
|
|
59871
59884
|
function buildRenderConfig(opts) {
|
|
59872
59885
|
const quality = opts.quality ?? "standard";
|
|
@@ -59880,7 +59893,7 @@ function buildRenderConfig(opts) {
|
|
|
59880
59893
|
};
|
|
59881
59894
|
}
|
|
59882
59895
|
async function executeSceneRender(opts = {}) {
|
|
59883
|
-
const projectDir =
|
|
59896
|
+
const projectDir = resolve62(opts.projectDir ?? ".");
|
|
59884
59897
|
const projectConfig = await readProjectConfig(projectDir);
|
|
59885
59898
|
const engine = projectConfig.config.composition.engine;
|
|
59886
59899
|
if (engine !== "hyperframes") {
|
|
@@ -59926,7 +59939,7 @@ async function executeSceneRender(opts = {}) {
|
|
|
59926
59939
|
kind: "render",
|
|
59927
59940
|
beat: opts.beatId ?? null,
|
|
59928
59941
|
root,
|
|
59929
|
-
error: `Root composition not found: ${
|
|
59942
|
+
error: `Root composition not found: ${resolve62(projectDir, root)}. Run \`vibe scene init\` first.`
|
|
59930
59943
|
};
|
|
59931
59944
|
}
|
|
59932
59945
|
const chrome = await preflightChrome();
|
|
@@ -59940,8 +59953,8 @@ async function executeSceneRender(opts = {}) {
|
|
|
59940
59953
|
};
|
|
59941
59954
|
}
|
|
59942
59955
|
const projectName = projectConfig.config.name;
|
|
59943
|
-
const outputPath = opts.output ?
|
|
59944
|
-
await
|
|
59956
|
+
const outputPath = opts.output ? resolve62(projectDir, opts.output) : defaultOutputPath({ projectDir, projectName, format: opts.format, beatId: opts.beatId });
|
|
59957
|
+
await mkdir24(dirname22(outputPath), { recursive: true });
|
|
59945
59958
|
const config2 = buildRenderConfig({
|
|
59946
59959
|
fps: opts.fps,
|
|
59947
59960
|
quality: opts.quality,
|
|
@@ -59973,7 +59986,7 @@ async function executeSceneRender(opts = {}) {
|
|
|
59973
59986
|
let audioMuxWarning;
|
|
59974
59987
|
try {
|
|
59975
59988
|
opts.onProgress?.(0.95, "Mixing audio");
|
|
59976
|
-
const rootHtml = await
|
|
59989
|
+
const rootHtml = await readFile43(resolve62(projectDir, root), "utf-8");
|
|
59977
59990
|
const audios = await scanSceneAudio({ projectDir, rootHtml });
|
|
59978
59991
|
audioCount = audios.length;
|
|
59979
59992
|
if (audios.length > 0) {
|
|
@@ -60027,11 +60040,11 @@ async function safeStat(p) {
|
|
|
60027
60040
|
}
|
|
60028
60041
|
async function prepareBeatRenderRoot(opts) {
|
|
60029
60042
|
const root = `.vibeframe/tmp/render-beat-${sanitizeFileSegment2(opts.beatId)}.html`;
|
|
60030
|
-
const reportPath =
|
|
60043
|
+
const reportPath = join22(opts.projectDir, "build-report.json");
|
|
60031
60044
|
const retryWith = [
|
|
60032
60045
|
`vibe build ${opts.projectDir} --beat ${opts.beatId} --stage sync --json`
|
|
60033
60046
|
];
|
|
60034
|
-
if (!
|
|
60047
|
+
if (!existsSync46(reportPath)) {
|
|
60035
60048
|
return {
|
|
60036
60049
|
success: false,
|
|
60037
60050
|
root,
|
|
@@ -60042,7 +60055,7 @@ async function prepareBeatRenderRoot(opts) {
|
|
|
60042
60055
|
}
|
|
60043
60056
|
let report;
|
|
60044
60057
|
try {
|
|
60045
|
-
report = JSON.parse(await
|
|
60058
|
+
report = JSON.parse(await readFile43(reportPath, "utf-8"));
|
|
60046
60059
|
} catch (error) {
|
|
60047
60060
|
return {
|
|
60048
60061
|
success: false,
|
|
@@ -60111,8 +60124,8 @@ async function prepareBeatRenderRoot(opts) {
|
|
|
60111
60124
|
durationSec,
|
|
60112
60125
|
narrationPath
|
|
60113
60126
|
});
|
|
60114
|
-
await
|
|
60115
|
-
await
|
|
60127
|
+
await mkdir24(dirname22(join22(opts.projectDir, root)), { recursive: true });
|
|
60128
|
+
await writeFile48(join22(opts.projectDir, root), html, "utf-8");
|
|
60116
60129
|
return {
|
|
60117
60130
|
success: true,
|
|
60118
60131
|
root,
|
|
@@ -60176,9 +60189,9 @@ function reportedBeatAssetPaths(beat) {
|
|
|
60176
60189
|
]);
|
|
60177
60190
|
}
|
|
60178
60191
|
async function writeRenderReport(projectDir, result) {
|
|
60179
|
-
const reportPath =
|
|
60192
|
+
const reportPath = join22(projectDir, "render-report.json");
|
|
60180
60193
|
try {
|
|
60181
|
-
await
|
|
60194
|
+
await writeFile48(
|
|
60182
60195
|
reportPath,
|
|
60183
60196
|
JSON.stringify(
|
|
60184
60197
|
{
|
|
@@ -60210,8 +60223,8 @@ async function writeRenderReport(projectDir, result) {
|
|
|
60210
60223
|
}
|
|
60211
60224
|
}
|
|
60212
60225
|
function pathExists3(projectDir, value) {
|
|
60213
|
-
const abs = isAbsolute6(value) ? value :
|
|
60214
|
-
return
|
|
60226
|
+
const abs = isAbsolute6(value) ? value : resolve62(projectDir, value);
|
|
60227
|
+
return existsSync46(abs);
|
|
60215
60228
|
}
|
|
60216
60229
|
function stringValue(value) {
|
|
60217
60230
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
@@ -60264,12 +60277,12 @@ __export(scene_build_exports, {
|
|
|
60264
60277
|
executeSceneBuild: () => executeSceneBuild,
|
|
60265
60278
|
resolveSceneBuildMode: () => resolveSceneBuildMode
|
|
60266
60279
|
});
|
|
60267
|
-
import { existsSync as
|
|
60268
|
-
import { copyFile as copyFile5, mkdir as
|
|
60269
|
-
import { dirname as
|
|
60280
|
+
import { existsSync as existsSync47 } from "node:fs";
|
|
60281
|
+
import { copyFile as copyFile5, mkdir as mkdir25, readFile as readFile44, writeFile as writeFile49 } from "node:fs/promises";
|
|
60282
|
+
import { dirname as dirname23, join as join23, resolve as resolve63 } from "node:path";
|
|
60270
60283
|
async function executeSceneBuild(opts) {
|
|
60271
60284
|
const startedAt = Date.now();
|
|
60272
|
-
const projectDir =
|
|
60285
|
+
const projectDir = resolve63(opts.projectDir);
|
|
60273
60286
|
const onProgress = opts.onProgress ?? (() => {
|
|
60274
60287
|
});
|
|
60275
60288
|
const mode = resolveSceneBuildMode(opts);
|
|
@@ -60278,7 +60291,7 @@ async function executeSceneBuild(opts) {
|
|
|
60278
60291
|
const warnings = [];
|
|
60279
60292
|
const retryWith = [];
|
|
60280
60293
|
let sceneRepair = skippedSceneRepairSummary();
|
|
60281
|
-
const storyboardPath2 =
|
|
60294
|
+
const storyboardPath2 = join23(projectDir, "STORYBOARD.md");
|
|
60282
60295
|
const buildPlan = await createBuildPlan({
|
|
60283
60296
|
projectDir,
|
|
60284
60297
|
stage: selectedStage,
|
|
@@ -60306,8 +60319,8 @@ async function executeSceneBuild(opts) {
|
|
|
60306
60319
|
});
|
|
60307
60320
|
if (!buildPlan.validation.ok) {
|
|
60308
60321
|
let invalidBeats = [];
|
|
60309
|
-
if (
|
|
60310
|
-
invalidBeats = parseStoryboard(await
|
|
60322
|
+
if (existsSync47(storyboardPath2)) {
|
|
60323
|
+
invalidBeats = parseStoryboard(await readFile44(storyboardPath2, "utf-8")).beats;
|
|
60311
60324
|
}
|
|
60312
60325
|
return finishBuildResult({
|
|
60313
60326
|
success: false,
|
|
@@ -60331,7 +60344,7 @@ async function executeSceneBuild(opts) {
|
|
|
60331
60344
|
totalLatencyMs: Date.now() - startedAt
|
|
60332
60345
|
});
|
|
60333
60346
|
}
|
|
60334
|
-
if (!
|
|
60347
|
+
if (!existsSync47(storyboardPath2)) {
|
|
60335
60348
|
return finishBuildResult({
|
|
60336
60349
|
success: false,
|
|
60337
60350
|
phase: "failed",
|
|
@@ -60345,7 +60358,7 @@ async function executeSceneBuild(opts) {
|
|
|
60345
60358
|
totalLatencyMs: Date.now() - startedAt
|
|
60346
60359
|
});
|
|
60347
60360
|
}
|
|
60348
|
-
const storyboardMd = await
|
|
60361
|
+
const storyboardMd = await readFile44(storyboardPath2, "utf-8");
|
|
60349
60362
|
const parsed = parseStoryboard(storyboardMd);
|
|
60350
60363
|
if (parsed.beats.length === 0) {
|
|
60351
60364
|
return finishBuildResult({
|
|
@@ -60513,9 +60526,9 @@ async function executeSceneBuild(opts) {
|
|
|
60513
60526
|
let composeData;
|
|
60514
60527
|
if (shouldRunStage(selectedStage, "compose")) {
|
|
60515
60528
|
if (mode === "agent") {
|
|
60516
|
-
const compositionsDir =
|
|
60529
|
+
const compositionsDir = join23(projectDir, "compositions");
|
|
60517
60530
|
const missingBeats = activeBeats.filter(
|
|
60518
|
-
(b) => !
|
|
60531
|
+
(b) => !existsSync47(join23(compositionsDir, `scene-${b.id}.html`))
|
|
60519
60532
|
);
|
|
60520
60533
|
if (missingBeats.length > 0) {
|
|
60521
60534
|
const plan = await getComposePrompts({ projectDir, beatId: opts.beatId });
|
|
@@ -60651,7 +60664,7 @@ async function executeSceneBuild(opts) {
|
|
|
60651
60664
|
});
|
|
60652
60665
|
}
|
|
60653
60666
|
if (shouldRunStage(selectedStage, "sync")) {
|
|
60654
|
-
if (!
|
|
60667
|
+
if (!existsSync47(join23(projectDir, "index.html"))) {
|
|
60655
60668
|
await scaffoldSceneProject({
|
|
60656
60669
|
dir: projectDir,
|
|
60657
60670
|
name: projectDir.split(/[\\/]/).filter(Boolean).pop(),
|
|
@@ -60910,7 +60923,7 @@ async function dispatchNarration(beat, ctx) {
|
|
|
60910
60923
|
return {
|
|
60911
60924
|
status: "cached",
|
|
60912
60925
|
path: existingRel,
|
|
60913
|
-
durationSec: await safeAudioDuration(
|
|
60926
|
+
durationSec: await safeAudioDuration(join23(ctx.projectDir, existingRel)),
|
|
60914
60927
|
provider: metadata?.provider,
|
|
60915
60928
|
cachePath: metadata?.cachePath,
|
|
60916
60929
|
cacheKey: metadata?.cacheKey,
|
|
@@ -60934,9 +60947,9 @@ async function dispatchNarration(beat, ctx) {
|
|
|
60934
60947
|
voice,
|
|
60935
60948
|
ext: resolution.audioExtension
|
|
60936
60949
|
});
|
|
60937
|
-
const cacheAbs =
|
|
60950
|
+
const cacheAbs = join23(ctx.projectDir, cache.path);
|
|
60938
60951
|
const rel = `assets/narration-${beat.id}.${resolution.audioExtension}`;
|
|
60939
|
-
const abs =
|
|
60952
|
+
const abs = join23(ctx.projectDir, rel);
|
|
60940
60953
|
if (existingRel && !ctx.force && isFreshCanonicalAsset({
|
|
60941
60954
|
projectDir: ctx.projectDir,
|
|
60942
60955
|
kind: "narration",
|
|
@@ -60950,7 +60963,7 @@ async function dispatchNarration(beat, ctx) {
|
|
|
60950
60963
|
return {
|
|
60951
60964
|
status: "cached",
|
|
60952
60965
|
path: existingRel,
|
|
60953
|
-
durationSec: await safeAudioDuration(
|
|
60966
|
+
durationSec: await safeAudioDuration(join23(ctx.projectDir, existingRel)),
|
|
60954
60967
|
provider: resolution.provider,
|
|
60955
60968
|
cachePath: cache.path,
|
|
60956
60969
|
cacheKey: cache.key,
|
|
@@ -60958,8 +60971,8 @@ async function dispatchNarration(beat, ctx) {
|
|
|
60958
60971
|
freshness: "fresh"
|
|
60959
60972
|
};
|
|
60960
60973
|
}
|
|
60961
|
-
if (
|
|
60962
|
-
await
|
|
60974
|
+
if (existsSync47(cacheAbs) && !ctx.force) {
|
|
60975
|
+
await mkdir25(dirname23(abs), { recursive: true });
|
|
60963
60976
|
await copyFile5(cacheAbs, abs);
|
|
60964
60977
|
await writeAssetMetadata({
|
|
60965
60978
|
projectDir: ctx.projectDir,
|
|
@@ -60990,10 +61003,10 @@ async function dispatchNarration(beat, ctx) {
|
|
|
60990
61003
|
ctx.onProgress({ type: "narration-failed", beatId: beat.id, error });
|
|
60991
61004
|
return { status: "failed", error };
|
|
60992
61005
|
}
|
|
60993
|
-
await
|
|
60994
|
-
await
|
|
60995
|
-
await
|
|
60996
|
-
await
|
|
61006
|
+
await mkdir25(dirname23(abs), { recursive: true });
|
|
61007
|
+
await writeFile49(abs, result.audioBuffer);
|
|
61008
|
+
await mkdir25(dirname23(cacheAbs), { recursive: true });
|
|
61009
|
+
await writeFile49(cacheAbs, result.audioBuffer);
|
|
60997
61010
|
await writeAssetMetadata({
|
|
60998
61011
|
projectDir: ctx.projectDir,
|
|
60999
61012
|
kind: "narration",
|
|
@@ -61029,7 +61042,7 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
61029
61042
|
if (!cue) return { status: "no-cue" };
|
|
61030
61043
|
const prompt3 = augmentBackdropPrompt(cue);
|
|
61031
61044
|
const rel = `assets/backdrop-${beat.id}.png`;
|
|
61032
|
-
const abs =
|
|
61045
|
+
const abs = join23(ctx.projectDir, rel);
|
|
61033
61046
|
const size = ctx.imageSize ?? "1536x1024";
|
|
61034
61047
|
const ratio = imageRatioForSize(size);
|
|
61035
61048
|
const metadataOptions = { quality: ctx.imageQuality, size, ratio };
|
|
@@ -61042,7 +61055,7 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
61042
61055
|
ratio
|
|
61043
61056
|
});
|
|
61044
61057
|
const metadataPath = assetMetadataPath("backdrop", beat.id);
|
|
61045
|
-
if (
|
|
61058
|
+
if (existsSync47(abs) && !ctx.force) {
|
|
61046
61059
|
const metadata = readAssetMetadata(ctx.projectDir, "backdrop", beat.id);
|
|
61047
61060
|
if (!metadata || isFreshCanonicalAsset({
|
|
61048
61061
|
projectDir: ctx.projectDir,
|
|
@@ -61065,9 +61078,9 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
61065
61078
|
};
|
|
61066
61079
|
}
|
|
61067
61080
|
}
|
|
61068
|
-
const cacheAbs =
|
|
61069
|
-
if (
|
|
61070
|
-
await
|
|
61081
|
+
const cacheAbs = join23(ctx.projectDir, cache.path);
|
|
61082
|
+
if (existsSync47(cacheAbs) && !ctx.force) {
|
|
61083
|
+
await mkdir25(dirname23(abs), { recursive: true });
|
|
61071
61084
|
await copyFile5(cacheAbs, abs);
|
|
61072
61085
|
await writeAssetMetadata({
|
|
61073
61086
|
projectDir: ctx.projectDir,
|
|
@@ -61097,11 +61110,11 @@ async function dispatchBackdrop(beat, ctx) {
|
|
|
61097
61110
|
ctx.onProgress({ type: "backdrop-failed", beatId: beat.id, error });
|
|
61098
61111
|
return { status: "failed", error };
|
|
61099
61112
|
}
|
|
61100
|
-
await
|
|
61113
|
+
await mkdir25(dirname23(abs), { recursive: true });
|
|
61101
61114
|
const buffer = generated.buffer;
|
|
61102
|
-
await
|
|
61103
|
-
await
|
|
61104
|
-
await
|
|
61115
|
+
await writeFile49(abs, buffer);
|
|
61116
|
+
await mkdir25(dirname23(cacheAbs), { recursive: true });
|
|
61117
|
+
await writeFile49(cacheAbs, buffer);
|
|
61105
61118
|
await writeAssetMetadata({
|
|
61106
61119
|
projectDir: ctx.projectDir,
|
|
61107
61120
|
kind: "backdrop",
|
|
@@ -61192,7 +61205,7 @@ async function dispatchVideo(beat, ctx) {
|
|
|
61192
61205
|
const prompt3 = stringOrUndefined4(beat.cues?.video);
|
|
61193
61206
|
if (!prompt3) return { status: "no-cue" };
|
|
61194
61207
|
const rel = `assets/video-${beat.id}.mp4`;
|
|
61195
|
-
const abs =
|
|
61208
|
+
const abs = join23(ctx.projectDir, rel);
|
|
61196
61209
|
const cache = videoCacheDescriptor({
|
|
61197
61210
|
beatId: beat.id,
|
|
61198
61211
|
cue: prompt3,
|
|
@@ -61200,7 +61213,7 @@ async function dispatchVideo(beat, ctx) {
|
|
|
61200
61213
|
duration: normalizeVideoDuration(beat.duration)
|
|
61201
61214
|
});
|
|
61202
61215
|
const metadataPath = assetMetadataPath("video", beat.id);
|
|
61203
|
-
if (
|
|
61216
|
+
if (existsSync47(abs) && !ctx.force) {
|
|
61204
61217
|
const metadata = readAssetMetadata(ctx.projectDir, "video", beat.id);
|
|
61205
61218
|
if (!metadata || isFreshCanonicalAsset({
|
|
61206
61219
|
projectDir: ctx.projectDir,
|
|
@@ -61223,9 +61236,9 @@ async function dispatchVideo(beat, ctx) {
|
|
|
61223
61236
|
};
|
|
61224
61237
|
}
|
|
61225
61238
|
}
|
|
61226
|
-
const cacheAbs =
|
|
61227
|
-
if (
|
|
61228
|
-
await
|
|
61239
|
+
const cacheAbs = join23(ctx.projectDir, cache.path);
|
|
61240
|
+
if (existsSync47(cacheAbs) && !ctx.force) {
|
|
61241
|
+
await mkdir25(dirname23(abs), { recursive: true });
|
|
61229
61242
|
await copyFile5(cacheAbs, abs);
|
|
61230
61243
|
await writeAssetMetadata({
|
|
61231
61244
|
projectDir: ctx.projectDir,
|
|
@@ -61264,8 +61277,8 @@ async function dispatchVideo(beat, ctx) {
|
|
|
61264
61277
|
ctx.onProgress({ type: "video-failed", beatId: beat.id, error });
|
|
61265
61278
|
return { status: "failed", error };
|
|
61266
61279
|
}
|
|
61267
|
-
if (result.status === "completed" &&
|
|
61268
|
-
await
|
|
61280
|
+
if (result.status === "completed" && existsSync47(abs)) {
|
|
61281
|
+
await mkdir25(dirname23(cacheAbs), { recursive: true });
|
|
61269
61282
|
await copyFile5(abs, cacheAbs);
|
|
61270
61283
|
await writeAssetMetadata({
|
|
61271
61284
|
projectDir: ctx.projectDir,
|
|
@@ -61332,7 +61345,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
61332
61345
|
const prompt3 = stringOrUndefined4(beat.cues?.music);
|
|
61333
61346
|
if (!prompt3) return { status: "no-cue" };
|
|
61334
61347
|
const rel = `assets/music-${beat.id}.mp3`;
|
|
61335
|
-
const abs =
|
|
61348
|
+
const abs = join23(ctx.projectDir, rel);
|
|
61336
61349
|
const duration = normalizeMusicDuration(beat.duration);
|
|
61337
61350
|
const cache = musicCacheDescriptor({
|
|
61338
61351
|
beatId: beat.id,
|
|
@@ -61341,7 +61354,7 @@ async function dispatchMusic(beat, ctx) {
|
|
|
61341
61354
|
duration
|
|
61342
61355
|
});
|
|
61343
61356
|
const metadataPath = assetMetadataPath("music", beat.id);
|
|
61344
|
-
if (
|
|
61357
|
+
if (existsSync47(abs) && !ctx.force) {
|
|
61345
61358
|
const metadata = readAssetMetadata(ctx.projectDir, "music", beat.id);
|
|
61346
61359
|
if (!metadata || isFreshCanonicalAsset({
|
|
61347
61360
|
projectDir: ctx.projectDir,
|
|
@@ -61365,9 +61378,9 @@ async function dispatchMusic(beat, ctx) {
|
|
|
61365
61378
|
};
|
|
61366
61379
|
}
|
|
61367
61380
|
}
|
|
61368
|
-
const cacheAbs =
|
|
61369
|
-
if (
|
|
61370
|
-
await
|
|
61381
|
+
const cacheAbs = join23(ctx.projectDir, cache.path);
|
|
61382
|
+
if (existsSync47(cacheAbs) && !ctx.force) {
|
|
61383
|
+
await mkdir25(dirname23(abs), { recursive: true });
|
|
61371
61384
|
await copyFile5(cacheAbs, abs);
|
|
61372
61385
|
await writeAssetMetadata({
|
|
61373
61386
|
projectDir: ctx.projectDir,
|
|
@@ -61440,12 +61453,12 @@ async function dispatchMusic(beat, ctx) {
|
|
|
61440
61453
|
metadataPath
|
|
61441
61454
|
};
|
|
61442
61455
|
}
|
|
61443
|
-
if (!
|
|
61456
|
+
if (!existsSync47(abs)) {
|
|
61444
61457
|
const error = result.outputPath ? `music output was not written at ${abs}` : "music generation did not return an output file";
|
|
61445
61458
|
ctx.onProgress({ type: "music-failed", beatId: beat.id, error });
|
|
61446
61459
|
return { status: "failed", error };
|
|
61447
61460
|
}
|
|
61448
|
-
await
|
|
61461
|
+
await mkdir25(dirname23(cacheAbs), { recursive: true });
|
|
61449
61462
|
await copyFile5(abs, cacheAbs);
|
|
61450
61463
|
await writeAssetMetadata({
|
|
61451
61464
|
projectDir: ctx.projectDir,
|
|
@@ -61476,15 +61489,15 @@ async function dispatchMusic(beat, ctx) {
|
|
|
61476
61489
|
};
|
|
61477
61490
|
}
|
|
61478
61491
|
function loadSceneBuildEnv(projectDir) {
|
|
61479
|
-
(0, import_dotenv4.config)({ path:
|
|
61480
|
-
(0, import_dotenv4.config)({ path:
|
|
61492
|
+
(0, import_dotenv4.config)({ path: join23(projectDir, ".env"), quiet: true });
|
|
61493
|
+
(0, import_dotenv4.config)({ path: resolve63(process.cwd(), ".env"), quiet: true });
|
|
61481
61494
|
let dir = process.cwd();
|
|
61482
|
-
while (dir !==
|
|
61483
|
-
if (
|
|
61484
|
-
(0, import_dotenv4.config)({ path:
|
|
61495
|
+
while (dir !== dirname23(dir)) {
|
|
61496
|
+
if (existsSync47(join23(dir, "pnpm-workspace.yaml"))) {
|
|
61497
|
+
(0, import_dotenv4.config)({ path: join23(dir, ".env"), quiet: true });
|
|
61485
61498
|
return;
|
|
61486
61499
|
}
|
|
61487
|
-
dir =
|
|
61500
|
+
dir = dirname23(dir);
|
|
61488
61501
|
}
|
|
61489
61502
|
}
|
|
61490
61503
|
async function skipped(kind, beatId, reason, ctx) {
|
|
@@ -61690,7 +61703,7 @@ function mergeBeatOutcomes(base, updates) {
|
|
|
61690
61703
|
}
|
|
61691
61704
|
function firstExisting3(projectDir, relPaths) {
|
|
61692
61705
|
for (const rel of relPaths) {
|
|
61693
|
-
if (
|
|
61706
|
+
if (existsSync47(join23(projectDir, rel))) return rel;
|
|
61694
61707
|
}
|
|
61695
61708
|
return null;
|
|
61696
61709
|
}
|
|
@@ -61721,7 +61734,7 @@ async function apiKeyForVideoProvider(provider, projectDir) {
|
|
|
61721
61734
|
return getApiKeyFromConfig(providerKey, { cwd: projectDir });
|
|
61722
61735
|
}
|
|
61723
61736
|
async function finalizeBuildResult(projectDir, startedAt, result) {
|
|
61724
|
-
const reportPath =
|
|
61737
|
+
const reportPath = join23(projectDir, "build-report.json");
|
|
61725
61738
|
if (result.stageReports) {
|
|
61726
61739
|
for (const report of Object.values(result.stageReports)) {
|
|
61727
61740
|
if (report.status === "pending") report.status = "skipped";
|
|
@@ -61737,7 +61750,7 @@ async function finalizeBuildResult(projectDir, startedAt, result) {
|
|
|
61737
61750
|
totalLatencyMs: Date.now() - startedAt
|
|
61738
61751
|
};
|
|
61739
61752
|
try {
|
|
61740
|
-
await
|
|
61753
|
+
await writeFile49(
|
|
61741
61754
|
reportPath,
|
|
61742
61755
|
JSON.stringify(toBuildReport(projectDir, withMeta), null, 2) + "\n",
|
|
61743
61756
|
"utf-8"
|
|
@@ -61880,7 +61893,7 @@ function normalizeReportDuration(value) {
|
|
|
61880
61893
|
}
|
|
61881
61894
|
function buildReportComposition(projectDir, result, beatId) {
|
|
61882
61895
|
const path2 = `compositions/scene-${beatId}.html`;
|
|
61883
|
-
const exists =
|
|
61896
|
+
const exists = existsSync47(join23(projectDir, path2));
|
|
61884
61897
|
const written = composeWrittenEntry(result, beatId);
|
|
61885
61898
|
if (written) {
|
|
61886
61899
|
return {
|
|
@@ -61937,8 +61950,8 @@ function summarizeBuildBeats(projectDir, beats) {
|
|
|
61937
61950
|
let compositionsReady = 0;
|
|
61938
61951
|
for (const beat of beats) {
|
|
61939
61952
|
if (beatAssetsReady(beat)) assetsReady += 1;
|
|
61940
|
-
const compositionPath =
|
|
61941
|
-
if (
|
|
61953
|
+
const compositionPath = join23(projectDir, "compositions", `scene-${beat.beatId}.html`);
|
|
61954
|
+
if (existsSync47(compositionPath)) {
|
|
61942
61955
|
compositionsReady += 1;
|
|
61943
61956
|
} else {
|
|
61944
61957
|
needsAuthor.push(beat.beatId);
|
|
@@ -61972,7 +61985,7 @@ async function resolveBeatDuration(opts) {
|
|
|
61972
61985
|
const storyboardMin = opts.beatDuration ?? 3;
|
|
61973
61986
|
if (!opts.narrationPath) return Number(storyboardMin.toFixed(2));
|
|
61974
61987
|
try {
|
|
61975
|
-
const audioDuration = await getAudioDuration(
|
|
61988
|
+
const audioDuration = await getAudioDuration(join23(opts.projectDir, opts.narrationPath));
|
|
61976
61989
|
return Number(Math.max(storyboardMin, audioDuration + 0.5).toFixed(2));
|
|
61977
61990
|
} catch {
|
|
61978
61991
|
return Number(storyboardMin.toFixed(2));
|
|
@@ -62076,19 +62089,19 @@ __export(ai_audio_exports, {
|
|
|
62076
62089
|
executeTranscribe: () => executeTranscribe,
|
|
62077
62090
|
executeVoiceClone: () => executeVoiceClone
|
|
62078
62091
|
});
|
|
62079
|
-
import { resolve as
|
|
62080
|
-
import { readFile as
|
|
62081
|
-
import { existsSync as
|
|
62092
|
+
import { resolve as resolve71, dirname as dirname25, basename as basename22, extname as extname15 } from "node:path";
|
|
62093
|
+
import { readFile as readFile46, writeFile as writeFile50 } from "node:fs/promises";
|
|
62094
|
+
import { existsSync as existsSync52 } from "node:fs";
|
|
62082
62095
|
async function executeTranscribe(options) {
|
|
62083
62096
|
const { audioPath, language, output, format, apiKey } = options;
|
|
62084
62097
|
try {
|
|
62085
62098
|
const key = apiKey || process.env.OPENAI_API_KEY;
|
|
62086
62099
|
if (!key) return { success: false, error: "OPENAI_API_KEY required" };
|
|
62087
|
-
const absPath =
|
|
62088
|
-
if (!
|
|
62100
|
+
const absPath = resolve71(process.cwd(), audioPath);
|
|
62101
|
+
if (!existsSync52(absPath)) return { success: false, error: `File not found: ${absPath}` };
|
|
62089
62102
|
const whisper = new WhisperProvider();
|
|
62090
62103
|
await whisper.initialize({ apiKey: key });
|
|
62091
|
-
const audioBuffer = await
|
|
62104
|
+
const audioBuffer = await readFile46(absPath);
|
|
62092
62105
|
const audioBlob = new Blob([audioBuffer]);
|
|
62093
62106
|
const result = await whisper.transcribe(audioBlob, language);
|
|
62094
62107
|
if (result.status === "failed") {
|
|
@@ -62096,10 +62109,10 @@ async function executeTranscribe(options) {
|
|
|
62096
62109
|
}
|
|
62097
62110
|
let outputPath;
|
|
62098
62111
|
if (output) {
|
|
62099
|
-
outputPath =
|
|
62112
|
+
outputPath = resolve71(process.cwd(), output);
|
|
62100
62113
|
const fmt = detectFormat(output, format);
|
|
62101
62114
|
const content = formatTranscript(result, fmt);
|
|
62102
|
-
await
|
|
62115
|
+
await writeFile50(outputPath, content, "utf-8");
|
|
62103
62116
|
}
|
|
62104
62117
|
return {
|
|
62105
62118
|
success: true,
|
|
@@ -62117,17 +62130,17 @@ async function executeIsolate(options) {
|
|
|
62117
62130
|
try {
|
|
62118
62131
|
const key = apiKey || process.env.ELEVENLABS_API_KEY;
|
|
62119
62132
|
if (!key) return { success: false, error: "ELEVENLABS_API_KEY required" };
|
|
62120
|
-
const absPath =
|
|
62121
|
-
if (!
|
|
62122
|
-
const audioBuffer = await
|
|
62133
|
+
const absPath = resolve71(process.cwd(), audioPath);
|
|
62134
|
+
if (!existsSync52(absPath)) return { success: false, error: `File not found: ${absPath}` };
|
|
62135
|
+
const audioBuffer = await readFile46(absPath);
|
|
62123
62136
|
const elevenlabs = new ElevenLabsProvider();
|
|
62124
62137
|
await elevenlabs.initialize({ apiKey: key });
|
|
62125
62138
|
const result = await elevenlabs.isolateVocals(audioBuffer);
|
|
62126
62139
|
if (!result.success || !result.audioBuffer) {
|
|
62127
62140
|
return { success: false, error: result.error || "Audio isolation failed" };
|
|
62128
62141
|
}
|
|
62129
|
-
const outputPath =
|
|
62130
|
-
await
|
|
62142
|
+
const outputPath = resolve71(process.cwd(), output);
|
|
62143
|
+
await writeFile50(outputPath, result.audioBuffer);
|
|
62131
62144
|
return { success: true, outputPath };
|
|
62132
62145
|
} catch (error) {
|
|
62133
62146
|
return { success: false, error: `Audio isolation failed: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -62143,9 +62156,9 @@ async function executeVoiceClone(options) {
|
|
|
62143
62156
|
}
|
|
62144
62157
|
const audioBuffers = [];
|
|
62145
62158
|
for (const samplePath of samplePaths) {
|
|
62146
|
-
const absPath =
|
|
62147
|
-
if (!
|
|
62148
|
-
const buffer = await
|
|
62159
|
+
const absPath = resolve71(process.cwd(), samplePath);
|
|
62160
|
+
if (!existsSync52(absPath)) return { success: false, error: `File not found: ${samplePath}` };
|
|
62161
|
+
const buffer = await readFile46(absPath);
|
|
62149
62162
|
audioBuffers.push(buffer);
|
|
62150
62163
|
}
|
|
62151
62164
|
const elevenlabs = new ElevenLabsProvider();
|
|
@@ -62165,8 +62178,8 @@ async function executeVoiceClone(options) {
|
|
|
62165
62178
|
async function executeDub(options) {
|
|
62166
62179
|
const { mediaPath, language, source, voice, analyzeOnly, output } = options;
|
|
62167
62180
|
try {
|
|
62168
|
-
const absPath =
|
|
62169
|
-
if (!
|
|
62181
|
+
const absPath = resolve71(process.cwd(), mediaPath);
|
|
62182
|
+
if (!existsSync52(absPath)) return { success: false, error: `File not found: ${absPath}` };
|
|
62170
62183
|
const openaiKey = process.env.OPENAI_API_KEY;
|
|
62171
62184
|
const anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
62172
62185
|
const elevenlabsKey = process.env.ELEVENLABS_API_KEY;
|
|
@@ -62177,13 +62190,13 @@ async function executeDub(options) {
|
|
|
62177
62190
|
const isVideo = [".mp4", ".mov", ".avi", ".mkv", ".webm"].includes(ext);
|
|
62178
62191
|
let audioPath = absPath;
|
|
62179
62192
|
if (isVideo) {
|
|
62180
|
-
const tempAudioPath =
|
|
62193
|
+
const tempAudioPath = resolve71(dirname25(absPath), `temp-audio-${Date.now()}.mp3`);
|
|
62181
62194
|
execSafeSync("ffmpeg", ["-i", absPath, "-vn", "-acodec", "mp3", "-y", tempAudioPath]);
|
|
62182
62195
|
audioPath = tempAudioPath;
|
|
62183
62196
|
}
|
|
62184
62197
|
const whisper = new WhisperProvider();
|
|
62185
62198
|
await whisper.initialize({ apiKey: openaiKey });
|
|
62186
|
-
const audioBuffer = await
|
|
62199
|
+
const audioBuffer = await readFile46(audioPath);
|
|
62187
62200
|
const audioBlob = new Blob([audioBuffer]);
|
|
62188
62201
|
const transcriptResult = await whisper.transcribe(audioBlob, source);
|
|
62189
62202
|
if (transcriptResult.status === "failed" || !transcriptResult.segments) {
|
|
@@ -62226,7 +62239,7 @@ ${segmentTexts}`,
|
|
|
62226
62239
|
}
|
|
62227
62240
|
if (analyzeOnly) {
|
|
62228
62241
|
if (output) {
|
|
62229
|
-
const timingPath =
|
|
62242
|
+
const timingPath = resolve71(process.cwd(), output);
|
|
62230
62243
|
const timingData = {
|
|
62231
62244
|
sourcePath: absPath,
|
|
62232
62245
|
sourceLanguage: transcriptResult.detectedLanguage || source || "auto",
|
|
@@ -62238,14 +62251,14 @@ ${segmentTexts}`,
|
|
|
62238
62251
|
translated: translatedSegments[i]?.text || s.text
|
|
62239
62252
|
}))
|
|
62240
62253
|
};
|
|
62241
|
-
await
|
|
62254
|
+
await writeFile50(timingPath, JSON.stringify(timingData, null, 2));
|
|
62242
62255
|
}
|
|
62243
62256
|
return {
|
|
62244
62257
|
success: true,
|
|
62245
62258
|
sourceLanguage: transcriptResult.detectedLanguage || source || "auto",
|
|
62246
62259
|
targetLanguage: language,
|
|
62247
62260
|
segmentCount: segments.length,
|
|
62248
|
-
outputPath: output ?
|
|
62261
|
+
outputPath: output ? resolve71(process.cwd(), output) : void 0
|
|
62249
62262
|
};
|
|
62250
62263
|
}
|
|
62251
62264
|
const elevenlabs = new ElevenLabsProvider();
|
|
@@ -62259,9 +62272,9 @@ ${segmentTexts}`,
|
|
|
62259
62272
|
}
|
|
62260
62273
|
const combinedBuffer = Buffer.concat(dubbedBuffers);
|
|
62261
62274
|
const outputExt = isVideo ? ".mp3" : extname15(absPath);
|
|
62262
|
-
const defaultOutputPath2 =
|
|
62263
|
-
const finalOutputPath =
|
|
62264
|
-
await
|
|
62275
|
+
const defaultOutputPath2 = resolve71(dirname25(absPath), `${basename22(absPath, extname15(absPath))}-${language}${outputExt}`);
|
|
62276
|
+
const finalOutputPath = resolve71(process.cwd(), output || defaultOutputPath2);
|
|
62277
|
+
await writeFile50(finalOutputPath, combinedBuffer);
|
|
62265
62278
|
if (isVideo && audioPath !== absPath) {
|
|
62266
62279
|
try {
|
|
62267
62280
|
const { unlink: unlink5 } = await import("node:fs/promises");
|
|
@@ -62292,12 +62305,12 @@ async function executeDuck(options) {
|
|
|
62292
62305
|
} = options;
|
|
62293
62306
|
try {
|
|
62294
62307
|
if (!commandExists("ffmpeg")) return { success: false, error: "FFmpeg not found" };
|
|
62295
|
-
const absMusicPath =
|
|
62296
|
-
const absVoicePath =
|
|
62297
|
-
if (!
|
|
62298
|
-
if (!
|
|
62299
|
-
const defaultOutput =
|
|
62300
|
-
const outputPath =
|
|
62308
|
+
const absMusicPath = resolve71(process.cwd(), musicPath);
|
|
62309
|
+
const absVoicePath = resolve71(process.cwd(), voicePath);
|
|
62310
|
+
if (!existsSync52(absMusicPath)) return { success: false, error: `Music file not found: ${absMusicPath}` };
|
|
62311
|
+
if (!existsSync52(absVoicePath)) return { success: false, error: `Voice file not found: ${absVoicePath}` };
|
|
62312
|
+
const defaultOutput = resolve71(dirname25(absMusicPath), `${basename22(absMusicPath, extname15(absMusicPath))}-ducked${extname15(absMusicPath)}`);
|
|
62313
|
+
const outputPath = resolve71(process.cwd(), output || defaultOutput);
|
|
62301
62314
|
const filter = `[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`;
|
|
62302
62315
|
await execSafe("ffmpeg", [
|
|
62303
62316
|
"-i",
|
|
@@ -62309,7 +62322,7 @@ async function executeDuck(options) {
|
|
|
62309
62322
|
"-y",
|
|
62310
62323
|
outputPath
|
|
62311
62324
|
], { timeout: 12e4, maxBuffer: 50 * 1024 * 1024 });
|
|
62312
|
-
if (!
|
|
62325
|
+
if (!existsSync52(outputPath)) return { success: false, error: "FFmpeg failed to create output" };
|
|
62313
62326
|
return { success: true, outputPath };
|
|
62314
62327
|
} catch (error) {
|
|
62315
62328
|
return { success: false, error: `Audio ducking failed: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -62325,9 +62338,9 @@ var init_ai_audio = __esm({
|
|
|
62325
62338
|
});
|
|
62326
62339
|
|
|
62327
62340
|
// src/pipeline/executor.ts
|
|
62328
|
-
import { resolve as
|
|
62329
|
-
import { readFile as
|
|
62330
|
-
import { existsSync as
|
|
62341
|
+
import { resolve as resolve72 } from "node:path";
|
|
62342
|
+
import { readFile as readFile47, writeFile as writeFile51, mkdir as mkdir27 } from "node:fs/promises";
|
|
62343
|
+
import { existsSync as existsSync53 } from "node:fs";
|
|
62331
62344
|
function maxCostFor(action) {
|
|
62332
62345
|
const cmd = ACTION_METADATA[action]?.command;
|
|
62333
62346
|
if (!cmd) return 0;
|
|
@@ -62338,9 +62351,9 @@ function registerAction(action, handler) {
|
|
|
62338
62351
|
}
|
|
62339
62352
|
function getOutput(params, outputDir, defaultName) {
|
|
62340
62353
|
if (params.output && typeof params.output === "string") {
|
|
62341
|
-
return
|
|
62354
|
+
return resolve72(outputDir, params.output);
|
|
62342
62355
|
}
|
|
62343
|
-
return
|
|
62356
|
+
return resolve72(outputDir, defaultName);
|
|
62344
62357
|
}
|
|
62345
62358
|
function stringParam(value) {
|
|
62346
62359
|
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
@@ -62591,7 +62604,7 @@ async function ensureActionsRegistered() {
|
|
|
62591
62604
|
const { executeSceneBuild: executeSceneBuild2 } = await Promise.resolve().then(() => (init_scene_build(), scene_build_exports));
|
|
62592
62605
|
const projectRel = params.project ?? ".";
|
|
62593
62606
|
const r = await executeSceneBuild2({
|
|
62594
|
-
projectDir:
|
|
62607
|
+
projectDir: resolve72(outputDir, projectRel),
|
|
62595
62608
|
mode: params.mode,
|
|
62596
62609
|
effort: params.effort,
|
|
62597
62610
|
composer: params.composer,
|
|
@@ -62617,7 +62630,7 @@ async function ensureActionsRegistered() {
|
|
|
62617
62630
|
const { executeSceneRender: executeSceneRender2 } = await Promise.resolve().then(() => (init_scene_render(), scene_render_exports));
|
|
62618
62631
|
const projectRel = params.project ?? ".";
|
|
62619
62632
|
const r = await executeSceneRender2({
|
|
62620
|
-
projectDir:
|
|
62633
|
+
projectDir: resolve72(outputDir, projectRel),
|
|
62621
62634
|
root: params.root,
|
|
62622
62635
|
output: params.output,
|
|
62623
62636
|
fps: params.fps,
|
|
@@ -62641,11 +62654,11 @@ async function ensureActionsRegistered() {
|
|
|
62641
62654
|
});
|
|
62642
62655
|
}
|
|
62643
62656
|
async function loadPipeline(filePath) {
|
|
62644
|
-
const absPath =
|
|
62645
|
-
if (!
|
|
62657
|
+
const absPath = resolve72(process.cwd(), filePath);
|
|
62658
|
+
if (!existsSync53(absPath)) {
|
|
62646
62659
|
throw new Error(`Pipeline file not found: ${absPath}`);
|
|
62647
62660
|
}
|
|
62648
|
-
const content = await
|
|
62661
|
+
const content = await readFile47(absPath, "utf-8");
|
|
62649
62662
|
const manifest2 = (0, import_yaml8.parse)(content);
|
|
62650
62663
|
if (!manifest2.name) throw new Error("Pipeline missing 'name' field");
|
|
62651
62664
|
if (!manifest2.steps || !Array.isArray(manifest2.steps)) throw new Error("Pipeline missing 'steps' array");
|
|
@@ -62660,15 +62673,15 @@ async function loadPipeline(filePath) {
|
|
|
62660
62673
|
}
|
|
62661
62674
|
async function executePipeline(manifest2, options = {}) {
|
|
62662
62675
|
await ensureActionsRegistered();
|
|
62663
|
-
const outputDir =
|
|
62664
|
-
await
|
|
62676
|
+
const outputDir = resolve72(process.cwd(), options.outputDir || `${manifest2.name}-output`);
|
|
62677
|
+
await mkdir27(outputDir, { recursive: true });
|
|
62665
62678
|
const completedSteps = /* @__PURE__ */ new Map();
|
|
62666
62679
|
const results = [];
|
|
62667
62680
|
const startTime = Date.now();
|
|
62668
62681
|
if (options.resume) {
|
|
62669
|
-
const checkpointPath =
|
|
62670
|
-
if (
|
|
62671
|
-
const checkpointContent = await
|
|
62682
|
+
const checkpointPath = resolve72(outputDir, CHECKPOINT_FILE);
|
|
62683
|
+
if (existsSync53(checkpointPath)) {
|
|
62684
|
+
const checkpointContent = await readFile47(checkpointPath, "utf-8");
|
|
62672
62685
|
const checkpoint = (0, import_yaml8.parse)(checkpointContent);
|
|
62673
62686
|
for (const cs of checkpoint.completedSteps) {
|
|
62674
62687
|
completedSteps.set(cs.id, {
|
|
@@ -62786,8 +62799,8 @@ async function executePipeline(manifest2, options = {}) {
|
|
|
62786
62799
|
data: s.data
|
|
62787
62800
|
}))
|
|
62788
62801
|
};
|
|
62789
|
-
await
|
|
62790
|
-
|
|
62802
|
+
await writeFile51(
|
|
62803
|
+
resolve72(outputDir, CHECKPOINT_FILE),
|
|
62791
62804
|
(0, import_yaml8.stringify)(checkpoint, { indent: 2 }),
|
|
62792
62805
|
"utf-8"
|
|
62793
62806
|
);
|
|
@@ -67041,7 +67054,7 @@ var init_define_tool = __esm({
|
|
|
67041
67054
|
});
|
|
67042
67055
|
|
|
67043
67056
|
// src/tools/manifest/scene.ts
|
|
67044
|
-
import { resolve as
|
|
67057
|
+
import { resolve as resolve73, relative as relative12 } from "node:path";
|
|
67045
67058
|
function summariseLint(result) {
|
|
67046
67059
|
return {
|
|
67047
67060
|
ok: result.ok,
|
|
@@ -67157,7 +67170,7 @@ var init_scene2 = __esm({
|
|
|
67157
67170
|
description: "Scaffold a new VibeFrame video scene project. Supports minimal, agent, and full profiles; full includes the current HTML render backend metadata. Idempotent: re-running keeps user-authored files and merges backend config instead of overwriting. No API keys required.",
|
|
67158
67171
|
schema: sceneInitSchema,
|
|
67159
67172
|
async execute(args, ctx) {
|
|
67160
|
-
const dir =
|
|
67173
|
+
const dir = resolve73(ctx.workingDirectory, args.dir);
|
|
67161
67174
|
const result = await scaffoldSceneProject({
|
|
67162
67175
|
dir,
|
|
67163
67176
|
name: args.name,
|
|
@@ -67207,7 +67220,7 @@ var init_scene2 = __esm({
|
|
|
67207
67220
|
description: "Add a single scene to an existing scene project. Optionally generates narration audio (ElevenLabs) and/or a backdrop image (Gemini/OpenAI), then emits compositions/scene-<id>.html with a paused GSAP timeline and splices a clip reference into the root index.html. Use skipAudio:true and skipImage:true for text-only scenes that need no API calls.",
|
|
67208
67221
|
schema: sceneAddSchema,
|
|
67209
67222
|
async execute(args, ctx) {
|
|
67210
|
-
const projectDir = args.projectDir ?
|
|
67223
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67211
67224
|
const result = await executeSceneAdd({
|
|
67212
67225
|
name: args.name,
|
|
67213
67226
|
preset: args.preset ?? "simple",
|
|
@@ -67264,7 +67277,7 @@ var init_scene2 = __esm({
|
|
|
67264
67277
|
description: "Validate every scene file in a project against the public Hyperframes lint rules (in-process, no Chrome required). Returns errors, warnings, and info findings per file. Optional fix:true mechanically repairs `timed_element_missing_clip_class` only \u2014 other issues surface with fixHints.",
|
|
67265
67278
|
schema: sceneLintSchema,
|
|
67266
67279
|
async execute(args, ctx) {
|
|
67267
|
-
const projectDir = args.projectDir ?
|
|
67280
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67268
67281
|
const result = await runProjectLint({
|
|
67269
67282
|
projectDir,
|
|
67270
67283
|
rootRel: args.root,
|
|
@@ -67301,7 +67314,7 @@ var init_scene2 = __esm({
|
|
|
67301
67314
|
description: "Apply deterministic mechanical scene repairs. Currently uses the safe lint auto-fix allow-list and never performs semantic creative rewrites.",
|
|
67302
67315
|
schema: sceneRepairSchema,
|
|
67303
67316
|
async execute(args, ctx) {
|
|
67304
|
-
const projectDir = args.projectDir ?
|
|
67317
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67305
67318
|
const result = await executeSceneRepair({
|
|
67306
67319
|
projectDir,
|
|
67307
67320
|
rootRel: args.root,
|
|
@@ -67335,7 +67348,7 @@ var init_scene2 = __esm({
|
|
|
67335
67348
|
description: "Render a scene project to MP4/WebM/MOV via the Hyperframes producer. Requires Chrome installed locally. Output defaults to renders/<projectName>-<isoStamp>.<format>.",
|
|
67336
67349
|
schema: sceneRenderSchema,
|
|
67337
67350
|
async execute(args, ctx) {
|
|
67338
|
-
const projectDir = args.projectDir ?
|
|
67351
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67339
67352
|
const result = await executeSceneRender({
|
|
67340
67353
|
projectDir,
|
|
67341
67354
|
root: args.root,
|
|
@@ -67409,7 +67422,7 @@ var init_scene2 = __esm({
|
|
|
67409
67422
|
description: "v0.60 one-shot orchestrator: read STORYBOARD.md per-beat YAML cues (narration / backdrop / duration), dispatch TTS + image generation per beat, compose scene HTML via the compose-scenes-with-skills pipeline, then render to MP4. Use this instead of chaining init + scene_add + render manually. Caches by SHA256 of (DESIGN.md + cue body) so re-runs are idempotent and cheap.",
|
|
67410
67423
|
schema: sceneBuildSchema,
|
|
67411
67424
|
async execute(args, ctx) {
|
|
67412
|
-
const projectDir = args.projectDir ?
|
|
67425
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67413
67426
|
const result = await executeSceneBuild({
|
|
67414
67427
|
projectDir,
|
|
67415
67428
|
stage: args.stage,
|
|
@@ -67506,7 +67519,7 @@ var init_scene2 = __esm({
|
|
|
67506
67519
|
description: "Install the vendored Hyperframes skill bundle into a scene project so the host agent (Claude Code, Cursor, Codex, Aider) can read framework rules + house style directly. Writes a universal SKILL.md + references/ at the project root, plus per-host layouts (.claude/skills/hyperframes/ for Claude Code, .cursor/rules/hyperframes.mdc for Cursor) when those hosts are detected. Phase H1 of the agentic-native composer plan \u2014 once installed, the host agent itself can author scene HTML using the rules instead of relying on vibe's internal LLM call.",
|
|
67507
67520
|
schema: sceneInstallSkillSchema,
|
|
67508
67521
|
async execute(args, ctx) {
|
|
67509
|
-
const projectDir =
|
|
67522
|
+
const projectDir = resolve73(ctx.workingDirectory, args.projectDir);
|
|
67510
67523
|
const hostFlag = args.host ?? "auto";
|
|
67511
67524
|
const hosts = (() => {
|
|
67512
67525
|
if (hostFlag === "all") return ["all"];
|
|
@@ -67552,7 +67565,7 @@ var init_scene2 = __esm({
|
|
|
67552
67565
|
description: "Emit the per-beat compose plan for the host agent to author scene HTML itself. Reads STORYBOARD.md + DESIGN.md and returns each beat's outputPath + userPrompt + cues + body, plus references to the project's SKILL.md (Hyperframes rules) and DESIGN.md (visual identity). The host agent writes each compositions/scene-<id>.html file directly \u2014 VibeFrame makes NO LLM call here. Pairs with scene_install_skill (Phase H1). Phase H2 of the agentic-native composer plan; the internal-LLM batch path (build) remains as a fallback for non-agent contexts.",
|
|
67553
67566
|
schema: sceneComposePromptsSchema,
|
|
67554
67567
|
async execute(args, ctx) {
|
|
67555
|
-
const projectDir =
|
|
67568
|
+
const projectDir = resolve73(ctx.workingDirectory, args.projectDir);
|
|
67556
67569
|
const result = await getComposePrompts({
|
|
67557
67570
|
projectDir,
|
|
67558
67571
|
beatId: args.beat
|
|
@@ -68180,14 +68193,14 @@ var init_edit = __esm({
|
|
|
68180
68193
|
});
|
|
68181
68194
|
|
|
68182
68195
|
// src/commands/ai-suggest-edit.ts
|
|
68183
|
-
import { readFile as
|
|
68184
|
-
import { resolve as
|
|
68196
|
+
import { readFile as readFile48, writeFile as writeFile52 } from "node:fs/promises";
|
|
68197
|
+
import { resolve as resolve74 } from "node:path";
|
|
68185
68198
|
async function executeSuggestEdit(options) {
|
|
68186
68199
|
try {
|
|
68187
68200
|
const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY;
|
|
68188
68201
|
if (!apiKey) return { success: false, error: "GOOGLE_API_KEY required for suggest" };
|
|
68189
|
-
const filePath =
|
|
68190
|
-
const content = await
|
|
68202
|
+
const filePath = resolve74(process.cwd(), options.projectPath);
|
|
68203
|
+
const content = await readFile48(filePath, "utf-8");
|
|
68191
68204
|
const data = JSON.parse(content);
|
|
68192
68205
|
const project = Project.fromJSON(data);
|
|
68193
68206
|
const gemini = new GeminiProvider();
|
|
@@ -68198,7 +68211,7 @@ async function executeSuggestEdit(options) {
|
|
|
68198
68211
|
const first = suggestions[0];
|
|
68199
68212
|
const applied = applySuggestion(project, first);
|
|
68200
68213
|
if (applied) {
|
|
68201
|
-
await
|
|
68214
|
+
await writeFile52(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
68202
68215
|
return {
|
|
68203
68216
|
success: true,
|
|
68204
68217
|
suggestions,
|
|
@@ -68227,7 +68240,7 @@ var init_ai_suggest_edit = __esm({
|
|
|
68227
68240
|
});
|
|
68228
68241
|
|
|
68229
68242
|
// src/tools/manifest/inspect.ts
|
|
68230
|
-
import { resolve as
|
|
68243
|
+
import { resolve as resolve75 } from "node:path";
|
|
68231
68244
|
var inspectProjectTool, inspectRenderTool, analyzeMediaTool, analyzeVideoTool, analyzeReviewTool, analyzeSuggestTool, inspectTools;
|
|
68232
68245
|
var init_inspect = __esm({
|
|
68233
68246
|
"src/tools/manifest/inspect.ts"() {
|
|
@@ -68251,11 +68264,11 @@ var init_inspect = __esm({
|
|
|
68251
68264
|
report: external_exports.boolean().optional().describe("Write review-report.json. Default true.")
|
|
68252
68265
|
}),
|
|
68253
68266
|
async execute(args, ctx) {
|
|
68254
|
-
const projectDir = args.projectDir ?
|
|
68267
|
+
const projectDir = args.projectDir ? resolve75(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68255
68268
|
const result = await inspectProject({
|
|
68256
68269
|
projectDir,
|
|
68257
68270
|
beatId: args.beat,
|
|
68258
|
-
outputPath: args.outputPath ?
|
|
68271
|
+
outputPath: args.outputPath ? resolve75(ctx.workingDirectory, args.outputPath) : void 0,
|
|
68259
68272
|
writeReport: args.report !== false
|
|
68260
68273
|
});
|
|
68261
68274
|
return {
|
|
@@ -68285,13 +68298,13 @@ var init_inspect = __esm({
|
|
|
68285
68298
|
dryRun: external_exports.boolean().optional().describe("Preview resolved inputs without probing video or calling Gemini.")
|
|
68286
68299
|
}),
|
|
68287
68300
|
async execute(args, ctx) {
|
|
68288
|
-
const projectDir = args.projectDir ?
|
|
68301
|
+
const projectDir = args.projectDir ? resolve75(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68289
68302
|
if (args.dryRun) {
|
|
68290
68303
|
const result2 = await previewInspectRender({
|
|
68291
68304
|
projectDir,
|
|
68292
68305
|
beatId: args.beat,
|
|
68293
|
-
videoPath: args.videoPath ?
|
|
68294
|
-
outputPath: args.outputPath ?
|
|
68306
|
+
videoPath: args.videoPath ? resolve75(ctx.workingDirectory, args.videoPath) : void 0,
|
|
68307
|
+
outputPath: args.outputPath ? resolve75(ctx.workingDirectory, args.outputPath) : void 0,
|
|
68295
68308
|
writeReport: args.report !== false,
|
|
68296
68309
|
ai: args.ai === true,
|
|
68297
68310
|
model: args.model
|
|
@@ -68308,8 +68321,8 @@ var init_inspect = __esm({
|
|
|
68308
68321
|
const result = await inspectRender({
|
|
68309
68322
|
projectDir,
|
|
68310
68323
|
beatId: args.beat,
|
|
68311
|
-
videoPath: args.videoPath ?
|
|
68312
|
-
outputPath: args.outputPath ?
|
|
68324
|
+
videoPath: args.videoPath ? resolve75(ctx.workingDirectory, args.videoPath) : void 0,
|
|
68325
|
+
outputPath: args.outputPath ? resolve75(ctx.workingDirectory, args.outputPath) : void 0,
|
|
68313
68326
|
writeReport: args.report !== false,
|
|
68314
68327
|
ai: args.ai === true,
|
|
68315
68328
|
model: args.model
|
|
@@ -68899,13 +68912,13 @@ var init_generate2 = __esm({
|
|
|
68899
68912
|
});
|
|
68900
68913
|
|
|
68901
68914
|
// src/tools/manifest/storyboard.ts
|
|
68902
|
-
import { existsSync as
|
|
68903
|
-
import { readFile as
|
|
68904
|
-
import { resolve as
|
|
68915
|
+
import { existsSync as existsSync54 } from "node:fs";
|
|
68916
|
+
import { readFile as readFile49, writeFile as writeFile53 } from "node:fs/promises";
|
|
68917
|
+
import { resolve as resolve76 } from "node:path";
|
|
68905
68918
|
async function readStoryboard2(projectDir) {
|
|
68906
|
-
const path2 =
|
|
68907
|
-
if (!
|
|
68908
|
-
return { path: path2, markdown: await
|
|
68919
|
+
const path2 = resolve76(projectDir, "STORYBOARD.md");
|
|
68920
|
+
if (!existsSync54(path2)) return null;
|
|
68921
|
+
return { path: path2, markdown: await readFile49(path2, "utf-8") };
|
|
68909
68922
|
}
|
|
68910
68923
|
var projectDirSchema, storyboardListTool, storyboardValidateTool, storyboardGetTool, storyboardSetTool, storyboardMoveTool, storyboardReviseTool, planTool, storyboardTools;
|
|
68911
68924
|
var init_storyboard2 = __esm({
|
|
@@ -68927,7 +68940,7 @@ var init_storyboard2 = __esm({
|
|
|
68927
68940
|
description: "List beats, ids, durations, and cue blocks from a project's STORYBOARD.md.",
|
|
68928
68941
|
schema: projectDirSchema,
|
|
68929
68942
|
async execute(args, ctx) {
|
|
68930
|
-
const projectDir = args.projectDir ?
|
|
68943
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68931
68944
|
const file = await readStoryboard2(projectDir);
|
|
68932
68945
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
68933
68946
|
const parsed = parseStoryboard(file.markdown);
|
|
@@ -68953,7 +68966,7 @@ var init_storyboard2 = __esm({
|
|
|
68953
68966
|
description: "Validate STORYBOARD.md beat ids and cue blocks.",
|
|
68954
68967
|
schema: projectDirSchema,
|
|
68955
68968
|
async execute(args, ctx) {
|
|
68956
|
-
const projectDir = args.projectDir ?
|
|
68969
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68957
68970
|
const file = await readStoryboard2(projectDir);
|
|
68958
68971
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
68959
68972
|
const result = validateStoryboardMarkdown(file.markdown);
|
|
@@ -68986,7 +68999,7 @@ var init_storyboard2 = __esm({
|
|
|
68986
68999
|
beat: external_exports.string().describe("Beat id to return.")
|
|
68987
69000
|
}),
|
|
68988
69001
|
async execute(args, ctx) {
|
|
68989
|
-
const projectDir = args.projectDir ?
|
|
69002
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68990
69003
|
const file = await readStoryboard2(projectDir);
|
|
68991
69004
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
68992
69005
|
const beat = getStoryboardBeat(file.markdown, args.beat);
|
|
@@ -69012,7 +69025,7 @@ var init_storyboard2 = __esm({
|
|
|
69012
69025
|
unset: external_exports.boolean().optional().describe("Remove the cue key.")
|
|
69013
69026
|
}),
|
|
69014
69027
|
async execute(args, ctx) {
|
|
69015
|
-
const projectDir = args.projectDir ?
|
|
69028
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
69016
69029
|
const file = await readStoryboard2(projectDir);
|
|
69017
69030
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
69018
69031
|
try {
|
|
@@ -69023,7 +69036,7 @@ var init_storyboard2 = __esm({
|
|
|
69023
69036
|
value,
|
|
69024
69037
|
unset: args.unset
|
|
69025
69038
|
});
|
|
69026
|
-
await
|
|
69039
|
+
await writeFile53(file.path, next, "utf-8");
|
|
69027
69040
|
return {
|
|
69028
69041
|
success: true,
|
|
69029
69042
|
data: { beat: args.beat, key: args.key },
|
|
@@ -69045,7 +69058,7 @@ var init_storyboard2 = __esm({
|
|
|
69045
69058
|
after: external_exports.string().describe("Beat id that should precede the moved beat.")
|
|
69046
69059
|
}),
|
|
69047
69060
|
async execute(args, ctx) {
|
|
69048
|
-
const projectDir = args.projectDir ?
|
|
69061
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
69049
69062
|
const file = await readStoryboard2(projectDir);
|
|
69050
69063
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
69051
69064
|
try {
|
|
@@ -69053,7 +69066,7 @@ var init_storyboard2 = __esm({
|
|
|
69053
69066
|
beatId: args.beat,
|
|
69054
69067
|
afterBeatId: args.after
|
|
69055
69068
|
});
|
|
69056
|
-
await
|
|
69069
|
+
await writeFile53(file.path, next, "utf-8");
|
|
69057
69070
|
return {
|
|
69058
69071
|
success: true,
|
|
69059
69072
|
data: { beat: args.beat, after: args.after },
|
|
@@ -69077,7 +69090,7 @@ var init_storyboard2 = __esm({
|
|
|
69077
69090
|
dryRun: external_exports.boolean().optional().describe("Preview the revised storyboard without writing.")
|
|
69078
69091
|
}),
|
|
69079
69092
|
async execute(args, ctx) {
|
|
69080
|
-
const projectDir = args.projectDir ?
|
|
69093
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
69081
69094
|
const result = await executeStoryboardRevision({
|
|
69082
69095
|
projectDir,
|
|
69083
69096
|
request: args.request,
|
|
@@ -69120,7 +69133,7 @@ var init_storyboard2 = __esm({
|
|
|
69120
69133
|
force: external_exports.boolean().optional().describe("Plan regeneration even when outputs exist.")
|
|
69121
69134
|
}),
|
|
69122
69135
|
async execute(args, ctx) {
|
|
69123
|
-
const projectDir = args.projectDir ?
|
|
69136
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
69124
69137
|
const plan = await createBuildPlan({
|
|
69125
69138
|
projectDir,
|
|
69126
69139
|
stage: args.stage,
|
|
@@ -69163,9 +69176,9 @@ var init_storyboard2 = __esm({
|
|
|
69163
69176
|
});
|
|
69164
69177
|
|
|
69165
69178
|
// src/tools/manifest/remix.ts
|
|
69166
|
-
import { writeFile as
|
|
69179
|
+
import { writeFile as writeFile54 } from "node:fs/promises";
|
|
69167
69180
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
69168
|
-
import { join as
|
|
69181
|
+
import { join as join25 } from "node:path";
|
|
69169
69182
|
var pipelineHighlightsTool, pipelineAutoShortsTool, pipelineRunTool, pipelineRegenerateSceneTool, remixTools;
|
|
69170
69183
|
var init_remix = __esm({
|
|
69171
69184
|
"src/tools/manifest/remix.ts"() {
|
|
@@ -69273,8 +69286,8 @@ var init_remix = __esm({
|
|
|
69273
69286
|
let resolvedPath = args.pipelinePath;
|
|
69274
69287
|
let tempPath;
|
|
69275
69288
|
if (args.pipelineYaml) {
|
|
69276
|
-
tempPath =
|
|
69277
|
-
await
|
|
69289
|
+
tempPath = join25(tmpdir4(), `vibe-mcp-pipeline-${Date.now()}.yaml`);
|
|
69290
|
+
await writeFile54(tempPath, args.pipelineYaml, "utf-8");
|
|
69278
69291
|
resolvedPath = tempPath;
|
|
69279
69292
|
}
|
|
69280
69293
|
try {
|
|
@@ -69441,15 +69454,15 @@ var init_detect2 = __esm({
|
|
|
69441
69454
|
});
|
|
69442
69455
|
|
|
69443
69456
|
// src/tools/manifest/_project-io.ts
|
|
69444
|
-
import { readFile as
|
|
69457
|
+
import { readFile as readFile50, writeFile as writeFile55 } from "node:fs/promises";
|
|
69445
69458
|
async function loadProject2(projectPath, cwd) {
|
|
69446
69459
|
const absPath = await resolveTimelineFile(projectPath, cwd);
|
|
69447
|
-
const content = await
|
|
69460
|
+
const content = await readFile50(absPath, "utf-8");
|
|
69448
69461
|
const data = JSON.parse(content);
|
|
69449
69462
|
return { project: Project.fromJSON(data), absPath };
|
|
69450
69463
|
}
|
|
69451
69464
|
async function saveProject(absPath, project) {
|
|
69452
|
-
await
|
|
69465
|
+
await writeFile55(absPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
69453
69466
|
}
|
|
69454
69467
|
var init_project_io = __esm({
|
|
69455
69468
|
"src/tools/manifest/_project-io.ts"() {
|
|
@@ -69460,8 +69473,8 @@ var init_project_io = __esm({
|
|
|
69460
69473
|
});
|
|
69461
69474
|
|
|
69462
69475
|
// src/tools/manifest/timeline.ts
|
|
69463
|
-
import { mkdir as
|
|
69464
|
-
import { basename as basename23, resolve as
|
|
69476
|
+
import { mkdir as mkdir28, writeFile as writeFile56 } from "node:fs/promises";
|
|
69477
|
+
import { basename as basename23, resolve as resolve77 } from "node:path";
|
|
69465
69478
|
var MEDIA_TYPES, timelineCreateTool, timelineInfoTool, timelineAddSourceTool, timelineAddClipTool, timelineSplitClipTool, timelineTrimClipTool, timelineMoveClipTool, timelineDeleteClipTool, timelineDuplicateClipTool, timelineAddEffectTool, timelineAddTrackTool, timelineListTool, timelineTools;
|
|
69466
69479
|
var init_timeline = __esm({
|
|
69467
69480
|
"src/tools/manifest/timeline.ts"() {
|
|
@@ -69497,18 +69510,18 @@ var init_timeline = __esm({
|
|
|
69497
69510
|
fps: external_exports.number().optional().describe("Frames per second (default: 30)")
|
|
69498
69511
|
}),
|
|
69499
69512
|
async execute(args, ctx) {
|
|
69500
|
-
const projectName = args.name === "." ? basename23(ctx.workingDirectory) : basename23(
|
|
69513
|
+
const projectName = args.name === "." ? basename23(ctx.workingDirectory) : basename23(resolve77(ctx.workingDirectory, args.name));
|
|
69501
69514
|
const project = new Project(projectName);
|
|
69502
69515
|
if (args.fps) project.setFrameRate(args.fps);
|
|
69503
69516
|
let outputPath;
|
|
69504
69517
|
if (args.outputPath) {
|
|
69505
|
-
outputPath =
|
|
69518
|
+
outputPath = resolve77(ctx.workingDirectory, args.outputPath);
|
|
69506
69519
|
} else {
|
|
69507
|
-
const dirPath =
|
|
69508
|
-
await
|
|
69509
|
-
outputPath =
|
|
69520
|
+
const dirPath = resolve77(ctx.workingDirectory, args.name);
|
|
69521
|
+
await mkdir28(dirPath, { recursive: true });
|
|
69522
|
+
outputPath = resolve77(dirPath, TIMELINE_FILENAME);
|
|
69510
69523
|
}
|
|
69511
|
-
await
|
|
69524
|
+
await writeFile56(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
69512
69525
|
return {
|
|
69513
69526
|
success: true,
|
|
69514
69527
|
data: { name: projectName, outputPath },
|
|
@@ -69556,7 +69569,7 @@ var init_timeline = __esm({
|
|
|
69556
69569
|
}),
|
|
69557
69570
|
async execute(args, ctx) {
|
|
69558
69571
|
const { project, absPath } = await loadProject2(args.projectPath, ctx.workingDirectory);
|
|
69559
|
-
const mediaPath =
|
|
69572
|
+
const mediaPath = resolve77(ctx.workingDirectory, args.mediaPath);
|
|
69560
69573
|
const ext = mediaPath.split(".").pop()?.toLowerCase() ?? "";
|
|
69561
69574
|
const source = project.addSource({
|
|
69562
69575
|
name: args.name ?? mediaPath.split("/").pop() ?? "media",
|
|
@@ -69784,8 +69797,8 @@ var init_timeline = __esm({
|
|
|
69784
69797
|
});
|
|
69785
69798
|
|
|
69786
69799
|
// src/tools/manifest/project.ts
|
|
69787
|
-
import { resolve as
|
|
69788
|
-
import { writeFile as
|
|
69800
|
+
import { resolve as resolve78 } from "node:path";
|
|
69801
|
+
import { writeFile as writeFile57 } from "node:fs/promises";
|
|
69789
69802
|
var projectCreateTool, projectInfoTool, projectTools;
|
|
69790
69803
|
var init_project2 = __esm({
|
|
69791
69804
|
"src/tools/manifest/project.ts"() {
|
|
@@ -69807,10 +69820,10 @@ var init_project2 = __esm({
|
|
|
69807
69820
|
fps: external_exports.number().optional().describe("Frames per second (default: 30)")
|
|
69808
69821
|
}),
|
|
69809
69822
|
async execute(args, ctx) {
|
|
69810
|
-
const outputPath =
|
|
69823
|
+
const outputPath = resolve78(ctx.workingDirectory, args.outputPath ?? `${args.name}.vibe.json`);
|
|
69811
69824
|
const project = new Project(args.name);
|
|
69812
69825
|
if (args.fps) project.setFrameRate(args.fps);
|
|
69813
|
-
await
|
|
69826
|
+
await writeFile57(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
69814
69827
|
return {
|
|
69815
69828
|
success: true,
|
|
69816
69829
|
data: { name: args.name, outputPath },
|
|
@@ -69853,8 +69866,8 @@ var init_project2 = __esm({
|
|
|
69853
69866
|
});
|
|
69854
69867
|
|
|
69855
69868
|
// src/commands/export.ts
|
|
69856
|
-
import { readFile as
|
|
69857
|
-
import { resolve as
|
|
69869
|
+
import { readFile as readFile51, access as access7 } from "node:fs/promises";
|
|
69870
|
+
import { resolve as resolve79, basename as basename24 } from "node:path";
|
|
69858
69871
|
import { spawn as spawn3 } from "node:child_process";
|
|
69859
69872
|
function timelineBaseName(path2) {
|
|
69860
69873
|
const name = basename24(path2);
|
|
@@ -69922,7 +69935,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
69922
69935
|
};
|
|
69923
69936
|
}
|
|
69924
69937
|
const filePath = await resolveTimelineFile(projectPath);
|
|
69925
|
-
const content = await
|
|
69938
|
+
const content = await readFile51(filePath, "utf-8");
|
|
69926
69939
|
const data = JSON.parse(content);
|
|
69927
69940
|
const project = Project.fromJSON(data);
|
|
69928
69941
|
const summary = project.getSummary();
|
|
@@ -69932,7 +69945,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
69932
69945
|
message: "Project has no clips to export"
|
|
69933
69946
|
};
|
|
69934
69947
|
}
|
|
69935
|
-
const finalOutputPath =
|
|
69948
|
+
const finalOutputPath = resolve79(process.cwd(), outputPath);
|
|
69936
69949
|
const basePresetSettings = getPresetSettings(preset, summary.aspectRatio);
|
|
69937
69950
|
const presetSettings = applyCustomOverrides(basePresetSettings, { bitrate, fps, resolution, codec });
|
|
69938
69951
|
const clips = project.getClips().sort((a, b) => a.startTime - b.startTime);
|
|
@@ -70328,7 +70341,7 @@ function buildFFmpegArgs(clips, sources, presetSettings, outputPath, options, so
|
|
|
70328
70341
|
return args;
|
|
70329
70342
|
}
|
|
70330
70343
|
function runFFmpegProcess(ffmpegPath, args, onProgress) {
|
|
70331
|
-
return new Promise((
|
|
70344
|
+
return new Promise((resolve83, reject) => {
|
|
70332
70345
|
const ffmpeg = spawn3(ffmpegPath, args, {
|
|
70333
70346
|
stdio: ["pipe", "pipe", "pipe"]
|
|
70334
70347
|
});
|
|
@@ -70352,7 +70365,7 @@ function runFFmpegProcess(ffmpegPath, args, onProgress) {
|
|
|
70352
70365
|
});
|
|
70353
70366
|
ffmpeg.on("close", (code) => {
|
|
70354
70367
|
if (code === 0) {
|
|
70355
|
-
|
|
70368
|
+
resolve83();
|
|
70356
70369
|
} else {
|
|
70357
70370
|
const errorMatch = stderr.match(/Error.*$/m);
|
|
70358
70371
|
const errorMsg = errorMatch ? errorMatch[0] : `FFmpeg exited with code ${code}`;
|
|
@@ -70488,17 +70501,17 @@ function getPresetSettings(preset, aspectRatio2) {
|
|
|
70488
70501
|
}
|
|
70489
70502
|
async function runHyperframesExport(projectPath, options, spinner2, startedAt) {
|
|
70490
70503
|
spinner2.text = "Loading project...";
|
|
70491
|
-
const { readFile:
|
|
70492
|
-
const { resolve:
|
|
70504
|
+
const { readFile: readFile53 } = await import("node:fs/promises");
|
|
70505
|
+
const { resolve: resolve83 } = await import("node:path");
|
|
70493
70506
|
const { Project: Project2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
|
|
70494
70507
|
const { createHyperframesBackend: createHyperframesBackend2 } = await Promise.resolve().then(() => (init_hyperframes(), hyperframes_exports));
|
|
70495
70508
|
const { exitWithError: exitWithError2, generalError: generalError2, outputSuccess: outputSuccess2 } = await Promise.resolve().then(() => (init_output(), output_exports));
|
|
70496
70509
|
const chalk2 = (await Promise.resolve().then(() => (init_source(), source_exports))).default;
|
|
70497
70510
|
const filePath = await resolveTimelineFile(projectPath);
|
|
70498
|
-
const content = await
|
|
70511
|
+
const content = await readFile53(filePath, "utf-8");
|
|
70499
70512
|
const project = Project2.fromJSON(JSON.parse(content));
|
|
70500
70513
|
const state = project.getState();
|
|
70501
|
-
const outputPath = options.output ?
|
|
70514
|
+
const outputPath = options.output ? resolve83(process.cwd(), options.output) : resolve83(process.cwd(), `${timelineBaseName(projectPath)}.${options.format ?? "mp4"}`);
|
|
70502
70515
|
const quality = ["draft", "standard", "high"].includes(options.preset ?? "") ? options.preset : "standard";
|
|
70503
70516
|
const backend = createHyperframesBackend2();
|
|
70504
70517
|
spinner2.text = "Rendering with Hyperframes...";
|
|
@@ -70617,7 +70630,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
70617
70630
|
}
|
|
70618
70631
|
spinner2.text = "Loading project...";
|
|
70619
70632
|
const filePath = await resolveTimelineFile(projectPath);
|
|
70620
|
-
const content = await
|
|
70633
|
+
const content = await readFile51(filePath, "utf-8");
|
|
70621
70634
|
const data = JSON.parse(content);
|
|
70622
70635
|
const project = Project.fromJSON(data);
|
|
70623
70636
|
const summary = project.getSummary();
|
|
@@ -70625,7 +70638,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
70625
70638
|
spinner2.fail("Project has no clips to export");
|
|
70626
70639
|
exitWithError(usageError("Project has no clips to export"));
|
|
70627
70640
|
}
|
|
70628
|
-
const outputPath = options.output ?
|
|
70641
|
+
const outputPath = options.output ? resolve79(process.cwd(), options.output) : resolve79(
|
|
70629
70642
|
process.cwd(),
|
|
70630
70643
|
`${timelineBaseName(projectPath)}.${options.format}`
|
|
70631
70644
|
);
|
|
@@ -70709,7 +70722,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
70709
70722
|
});
|
|
70710
70723
|
|
|
70711
70724
|
// src/tools/manifest/export.ts
|
|
70712
|
-
import { resolve as
|
|
70725
|
+
import { resolve as resolve80 } from "node:path";
|
|
70713
70726
|
var exportVideoTool, exportTools;
|
|
70714
70727
|
var init_export2 = __esm({
|
|
70715
70728
|
"src/tools/manifest/export.ts"() {
|
|
@@ -70730,8 +70743,8 @@ var init_export2 = __esm({
|
|
|
70730
70743
|
overwrite: external_exports.boolean().optional().describe("Overwrite existing output file (default: false)")
|
|
70731
70744
|
}),
|
|
70732
70745
|
async execute(args, ctx) {
|
|
70733
|
-
const projectPath =
|
|
70734
|
-
const outputPath =
|
|
70746
|
+
const projectPath = resolve80(ctx.workingDirectory, args.projectPath);
|
|
70747
|
+
const outputPath = resolve80(ctx.workingDirectory, args.outputPath);
|
|
70735
70748
|
const result = await runExport(projectPath, outputPath, {
|
|
70736
70749
|
preset: args.preset,
|
|
70737
70750
|
format: args.format,
|
|
@@ -70750,8 +70763,8 @@ var init_export2 = __esm({
|
|
|
70750
70763
|
});
|
|
70751
70764
|
|
|
70752
70765
|
// src/tools/manifest/agent-only.ts
|
|
70753
|
-
import { readFile as
|
|
70754
|
-
import { resolve as
|
|
70766
|
+
import { readFile as readFile52, writeFile as writeFile58, readdir as readdir7, stat as stat9, access as access8, unlink as unlink4 } from "node:fs/promises";
|
|
70767
|
+
import { resolve as resolve81, join as join26, basename as basename25, extname as extname16 } from "node:path";
|
|
70755
70768
|
function matchPattern(filename, pattern) {
|
|
70756
70769
|
const regex2 = new RegExp(
|
|
70757
70770
|
"^" + pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".") + "$",
|
|
@@ -70829,12 +70842,12 @@ var init_agent_only = __esm({
|
|
|
70829
70842
|
async execute(args, ctx) {
|
|
70830
70843
|
const dirPath = args.path ?? ".";
|
|
70831
70844
|
try {
|
|
70832
|
-
const absPath =
|
|
70845
|
+
const absPath = resolve81(ctx.workingDirectory, dirPath);
|
|
70833
70846
|
const entries = await readdir7(absPath, { withFileTypes: true });
|
|
70834
70847
|
const results = [];
|
|
70835
70848
|
for (const entry of entries) {
|
|
70836
70849
|
if (args.pattern && !matchPattern(entry.name, args.pattern)) continue;
|
|
70837
|
-
const fullPath =
|
|
70850
|
+
const fullPath = join26(absPath, entry.name);
|
|
70838
70851
|
const stats = await stat9(fullPath);
|
|
70839
70852
|
if (entry.isDirectory()) {
|
|
70840
70853
|
results.push(`[DIR] ${entry.name}/`);
|
|
@@ -70860,8 +70873,8 @@ var init_agent_only = __esm({
|
|
|
70860
70873
|
}),
|
|
70861
70874
|
async execute(args, ctx) {
|
|
70862
70875
|
try {
|
|
70863
|
-
const absPath =
|
|
70864
|
-
const content = await
|
|
70876
|
+
const absPath = resolve81(ctx.workingDirectory, args.path);
|
|
70877
|
+
const content = await readFile52(absPath, "utf-8");
|
|
70865
70878
|
const maxLength = 4e3;
|
|
70866
70879
|
const truncated = content.length > maxLength;
|
|
70867
70880
|
const output = truncated ? content.substring(0, maxLength) + "\n... (truncated)" : content;
|
|
@@ -70883,8 +70896,8 @@ var init_agent_only = __esm({
|
|
|
70883
70896
|
}),
|
|
70884
70897
|
async execute(args, ctx) {
|
|
70885
70898
|
try {
|
|
70886
|
-
const absPath =
|
|
70887
|
-
await
|
|
70899
|
+
const absPath = resolve81(ctx.workingDirectory, args.path);
|
|
70900
|
+
await writeFile58(absPath, args.content, "utf-8");
|
|
70888
70901
|
return { success: true, data: { bytes: args.content.length }, humanLines: [`File written: ${args.path} (${formatSize(args.content.length)})`] };
|
|
70889
70902
|
} catch (error) {
|
|
70890
70903
|
return { success: false, error: `Failed to write file: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -70901,7 +70914,7 @@ var init_agent_only = __esm({
|
|
|
70901
70914
|
path: external_exports.string().describe("Path to check")
|
|
70902
70915
|
}),
|
|
70903
70916
|
async execute(args, ctx) {
|
|
70904
|
-
const absPath =
|
|
70917
|
+
const absPath = resolve81(ctx.workingDirectory, args.path);
|
|
70905
70918
|
try {
|
|
70906
70919
|
await access8(absPath);
|
|
70907
70920
|
const stats = await stat9(absPath);
|
|
@@ -70927,11 +70940,11 @@ var init_agent_only = __esm({
|
|
|
70927
70940
|
}),
|
|
70928
70941
|
async execute(args, ctx) {
|
|
70929
70942
|
try {
|
|
70930
|
-
const filePath =
|
|
70931
|
-
const content = await
|
|
70943
|
+
const filePath = resolve81(ctx.workingDirectory, args.project);
|
|
70944
|
+
const content = await readFile52(filePath, "utf-8");
|
|
70932
70945
|
const data = JSON.parse(content);
|
|
70933
70946
|
const project = Project.fromJSON(data);
|
|
70934
|
-
const dirPath =
|
|
70947
|
+
const dirPath = resolve81(ctx.workingDirectory, args.directory);
|
|
70935
70948
|
const filterExts = args.filter ? args.filter.split(",").map((e) => e.trim().toLowerCase()) : null;
|
|
70936
70949
|
const imageDuration = args.imageDuration ?? 5;
|
|
70937
70950
|
const recursive = args.recursive ?? false;
|
|
@@ -70939,7 +70952,7 @@ var init_agent_only = __esm({
|
|
|
70939
70952
|
const scanDir = async (dir) => {
|
|
70940
70953
|
const entries = await readdir7(dir, { withFileTypes: true });
|
|
70941
70954
|
for (const entry of entries) {
|
|
70942
|
-
const entryPath =
|
|
70955
|
+
const entryPath = join26(dir, entry.name);
|
|
70943
70956
|
if (entry.isDirectory() && recursive) {
|
|
70944
70957
|
await scanDir(entryPath);
|
|
70945
70958
|
} else if (entry.isFile()) {
|
|
@@ -70966,7 +70979,7 @@ var init_agent_only = __esm({
|
|
|
70966
70979
|
const source = project.addSource({ name: mediaName, type: mediaType, url: mediaFile, duration });
|
|
70967
70980
|
addedSources.push({ id: source.id, name: mediaName, type: mediaType });
|
|
70968
70981
|
}
|
|
70969
|
-
await
|
|
70982
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
70970
70983
|
return {
|
|
70971
70984
|
success: true,
|
|
70972
70985
|
data: { count: addedSources.length, sources: addedSources },
|
|
@@ -70997,8 +71010,8 @@ var init_agent_only = __esm({
|
|
|
70997
71010
|
}),
|
|
70998
71011
|
async execute(args, ctx) {
|
|
70999
71012
|
try {
|
|
71000
|
-
const filePath =
|
|
71001
|
-
const content = await
|
|
71013
|
+
const filePath = resolve81(ctx.workingDirectory, args.project);
|
|
71014
|
+
const content = await readFile52(filePath, "utf-8");
|
|
71002
71015
|
const data = JSON.parse(content);
|
|
71003
71016
|
const project = Project.fromJSON(data);
|
|
71004
71017
|
const sourceIds = args.sourceIds ?? [];
|
|
@@ -71034,7 +71047,7 @@ var init_agent_only = __esm({
|
|
|
71034
71047
|
createdClips.push({ id: clip.id, sourceName: source.name, startTime: currentTime, duration: source.duration });
|
|
71035
71048
|
currentTime += source.duration + gap;
|
|
71036
71049
|
}
|
|
71037
|
-
await
|
|
71050
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
71038
71051
|
const totalDuration = currentTime - gap - startTime;
|
|
71039
71052
|
return {
|
|
71040
71053
|
success: true,
|
|
@@ -71066,8 +71079,8 @@ var init_agent_only = __esm({
|
|
|
71066
71079
|
}),
|
|
71067
71080
|
async execute(args, ctx) {
|
|
71068
71081
|
try {
|
|
71069
|
-
const filePath =
|
|
71070
|
-
const content = await
|
|
71082
|
+
const filePath = resolve81(ctx.workingDirectory, args.project);
|
|
71083
|
+
const content = await readFile52(filePath, "utf-8");
|
|
71071
71084
|
const data = JSON.parse(content);
|
|
71072
71085
|
const project = Project.fromJSON(data);
|
|
71073
71086
|
const clipIds = args.clipIds ?? [];
|
|
@@ -71095,7 +71108,7 @@ var init_agent_only = __esm({
|
|
|
71095
71108
|
});
|
|
71096
71109
|
if (effect) appliedEffects.push({ clipId: clip.id, effectId: effect.id });
|
|
71097
71110
|
}
|
|
71098
|
-
await
|
|
71111
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
71099
71112
|
return {
|
|
71100
71113
|
success: true,
|
|
71101
71114
|
data: { applied: appliedEffects.length, effectType: args.effectType },
|
|
@@ -71120,7 +71133,7 @@ var init_agent_only = __esm({
|
|
|
71120
71133
|
async execute(args, ctx) {
|
|
71121
71134
|
try {
|
|
71122
71135
|
const filePath = await resolveTimelineFile(args.project, ctx.workingDirectory);
|
|
71123
|
-
const content = await
|
|
71136
|
+
const content = await readFile52(filePath, "utf-8");
|
|
71124
71137
|
const data = JSON.parse(content);
|
|
71125
71138
|
const project = Project.fromJSON(data);
|
|
71126
71139
|
const what = args.what ?? "clips";
|
|
@@ -71162,7 +71175,7 @@ var init_agent_only = __esm({
|
|
|
71162
71175
|
removed.sources++;
|
|
71163
71176
|
}
|
|
71164
71177
|
}
|
|
71165
|
-
await
|
|
71178
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
71166
71179
|
const parts = [];
|
|
71167
71180
|
if (removed.clips > 0) parts.push(`${removed.clips} clips`);
|
|
71168
71181
|
if (removed.tracks > 0) parts.push(`${removed.tracks} tracks`);
|
|
@@ -71195,7 +71208,7 @@ var init_agent_only = __esm({
|
|
|
71195
71208
|
async execute(args, ctx) {
|
|
71196
71209
|
try {
|
|
71197
71210
|
const filePath = await resolveTimelineFile(args.projectPath, ctx.workingDirectory);
|
|
71198
|
-
const content = await
|
|
71211
|
+
const content = await readFile52(filePath, "utf-8");
|
|
71199
71212
|
const data = JSON.parse(content);
|
|
71200
71213
|
const project = Project.fromJSON(data);
|
|
71201
71214
|
const updates = [];
|
|
@@ -71211,7 +71224,7 @@ var init_agent_only = __esm({
|
|
|
71211
71224
|
project.setFrameRate(args.fps);
|
|
71212
71225
|
updates.push(`Frame Rate: ${args.fps} fps`);
|
|
71213
71226
|
}
|
|
71214
|
-
await
|
|
71227
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
71215
71228
|
return {
|
|
71216
71229
|
success: true,
|
|
71217
71230
|
data: { updates },
|
|
@@ -71344,7 +71357,7 @@ var init_agent_only = __esm({
|
|
|
71344
71357
|
}),
|
|
71345
71358
|
async execute(args, ctx) {
|
|
71346
71359
|
try {
|
|
71347
|
-
const absPath =
|
|
71360
|
+
const absPath = resolve81(ctx.workingDirectory, args.path);
|
|
71348
71361
|
const { stdout } = await execSafe(
|
|
71349
71362
|
"ffprobe",
|
|
71350
71363
|
["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", absPath],
|
|
@@ -71431,10 +71444,10 @@ Audio:`);
|
|
|
71431
71444
|
}),
|
|
71432
71445
|
async execute(args, ctx) {
|
|
71433
71446
|
try {
|
|
71434
|
-
const absInput =
|
|
71447
|
+
const absInput = resolve81(ctx.workingDirectory, args.input);
|
|
71435
71448
|
const ext = args.input.split(".").pop() || "mp4";
|
|
71436
71449
|
const baseName = args.input.replace(/\.[^/.]+$/, "");
|
|
71437
|
-
const outputPath = args.output ?
|
|
71450
|
+
const outputPath = args.output ? resolve81(ctx.workingDirectory, args.output) : resolve81(ctx.workingDirectory, `${baseName}-compressed.${ext}`);
|
|
71438
71451
|
const crfValues = { low: 28, medium: 23, high: 18 };
|
|
71439
71452
|
const crf = crfValues[args.quality ?? "medium"];
|
|
71440
71453
|
await execSafe(
|
|
@@ -71457,8 +71470,8 @@ Audio:`);
|
|
|
71457
71470
|
],
|
|
71458
71471
|
{ maxBuffer: 50 * 1024 * 1024 }
|
|
71459
71472
|
);
|
|
71460
|
-
const inputBuf = await
|
|
71461
|
-
const outputBuf = await
|
|
71473
|
+
const inputBuf = await readFile52(absInput);
|
|
71474
|
+
const outputBuf = await readFile52(outputPath);
|
|
71462
71475
|
const inputSize = inputBuf.length;
|
|
71463
71476
|
const outputSize = outputBuf.length;
|
|
71464
71477
|
const reduction = (inputSize - outputSize) / inputSize * 100;
|
|
@@ -71492,8 +71505,8 @@ Audio:`);
|
|
|
71492
71505
|
}),
|
|
71493
71506
|
async execute(args, ctx) {
|
|
71494
71507
|
try {
|
|
71495
|
-
const absInput =
|
|
71496
|
-
const absOutput =
|
|
71508
|
+
const absInput = resolve81(ctx.workingDirectory, args.input);
|
|
71509
|
+
const absOutput = resolve81(ctx.workingDirectory, args.output);
|
|
71497
71510
|
const codecMap = {
|
|
71498
71511
|
h264: "libx264",
|
|
71499
71512
|
h265: "libx265",
|
|
@@ -71544,11 +71557,11 @@ Audio:`);
|
|
|
71544
71557
|
};
|
|
71545
71558
|
}
|
|
71546
71559
|
try {
|
|
71547
|
-
const absOutput =
|
|
71560
|
+
const absOutput = resolve81(ctx.workingDirectory, args.output);
|
|
71548
71561
|
if (args.reencode) {
|
|
71549
71562
|
const ffmpegArgs = [];
|
|
71550
71563
|
for (const i of args.inputs) {
|
|
71551
|
-
ffmpegArgs.push("-i",
|
|
71564
|
+
ffmpegArgs.push("-i", resolve81(ctx.workingDirectory, i));
|
|
71552
71565
|
}
|
|
71553
71566
|
const filterComplex = args.inputs.map((_, i) => `[${i}:v][${i}:a]`).join("");
|
|
71554
71567
|
ffmpegArgs.push(
|
|
@@ -71563,9 +71576,9 @@ Audio:`);
|
|
|
71563
71576
|
);
|
|
71564
71577
|
await execSafe("ffmpeg", ffmpegArgs, { maxBuffer: 100 * 1024 * 1024 });
|
|
71565
71578
|
} else {
|
|
71566
|
-
const tempList =
|
|
71567
|
-
const listContent = args.inputs.map((i) => `file '${
|
|
71568
|
-
await
|
|
71579
|
+
const tempList = resolve81(ctx.workingDirectory, `concat-list-${Date.now()}.txt`);
|
|
71580
|
+
const listContent = args.inputs.map((i) => `file '${resolve81(ctx.workingDirectory, i)}'`).join("\n");
|
|
71581
|
+
await writeFile58(tempList, listContent, "utf-8");
|
|
71569
71582
|
try {
|
|
71570
71583
|
await execSafe(
|
|
71571
71584
|
"ffmpeg",
|
|
@@ -71659,7 +71672,7 @@ var init_walkthrough = __esm({
|
|
|
71659
71672
|
});
|
|
71660
71673
|
|
|
71661
71674
|
// src/tools/manifest/status.ts
|
|
71662
|
-
import { resolve as
|
|
71675
|
+
import { resolve as resolve82 } from "node:path";
|
|
71663
71676
|
var statusJobTool, statusProjectTool, statusTools;
|
|
71664
71677
|
var init_status = __esm({
|
|
71665
71678
|
"src/tools/manifest/status.ts"() {
|
|
@@ -71680,7 +71693,7 @@ var init_status = __esm({
|
|
|
71680
71693
|
output: external_exports.string().optional().describe("Download result media to this path when complete.")
|
|
71681
71694
|
}),
|
|
71682
71695
|
async execute(args, ctx) {
|
|
71683
|
-
const projectDir = args.projectDir ?
|
|
71696
|
+
const projectDir = args.projectDir ? resolve82(ctx.workingDirectory, args.projectDir) : findProjectRoot(ctx.workingDirectory);
|
|
71684
71697
|
const record = await readJobRecord(args.jobId, projectDir);
|
|
71685
71698
|
if (!record) return { success: false, error: `Job not found: ${args.jobId}` };
|
|
71686
71699
|
const result = args.refresh === false ? makeJobStatusResult(record, {
|
|
@@ -71689,7 +71702,7 @@ var init_status = __esm({
|
|
|
71689
71702
|
warnings: []
|
|
71690
71703
|
}) : await refreshJobRecord(record, {
|
|
71691
71704
|
wait: args.wait,
|
|
71692
|
-
output: args.output ?
|
|
71705
|
+
output: args.output ? resolve82(ctx.workingDirectory, args.output) : void 0,
|
|
71693
71706
|
workingDirectory: ctx.workingDirectory
|
|
71694
71707
|
});
|
|
71695
71708
|
return {
|
|
@@ -71712,7 +71725,7 @@ var init_status = __esm({
|
|
|
71712
71725
|
refresh: external_exports.boolean().optional().describe("Refresh active supported jobs before summarizing. Default false.")
|
|
71713
71726
|
}),
|
|
71714
71727
|
async execute(args, ctx) {
|
|
71715
|
-
const projectDir = args.projectDir ?
|
|
71728
|
+
const projectDir = args.projectDir ? resolve82(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
71716
71729
|
const result = await inspectProjectStatus(projectDir, { refresh: args.refresh === true });
|
|
71717
71730
|
return {
|
|
71718
71731
|
success: true,
|
|
@@ -71994,8 +72007,8 @@ init_source();
|
|
|
71994
72007
|
// package.json
|
|
71995
72008
|
var package_default = {
|
|
71996
72009
|
name: "@vibeframe/cli",
|
|
71997
|
-
version: "0.106.
|
|
71998
|
-
description: "VibeFrame CLI -
|
|
72010
|
+
version: "0.106.5",
|
|
72011
|
+
description: "VibeFrame CLI - agentic video workflow runtime",
|
|
71999
72012
|
private: false,
|
|
72000
72013
|
license: "MIT",
|
|
72001
72014
|
repository: {
|
|
@@ -78013,9 +78026,9 @@ function parseLrc(lrcString) {
|
|
|
78013
78026
|
const minutes = Number.parseInt(match[1], 10);
|
|
78014
78027
|
const seconds = Number.parseInt(match[2], 10);
|
|
78015
78028
|
const ms = match[3].length === 3 ? Number.parseInt(match[3], 10) : Number.parseInt(match[3], 10) * 10;
|
|
78016
|
-
const
|
|
78029
|
+
const timestamp2 = (minutes * 60 + seconds) * 1e3 + ms;
|
|
78017
78030
|
const text = line.replace(TIMESTAMP_REGEX, "").trim();
|
|
78018
|
-
syncText.push({ timestamp, text });
|
|
78031
|
+
syncText.push({ timestamp: timestamp2, text });
|
|
78019
78032
|
}
|
|
78020
78033
|
}
|
|
78021
78034
|
return {
|
|
@@ -79170,12 +79183,12 @@ function resolveCopier() {
|
|
|
79170
79183
|
async function copyToClipboard(text) {
|
|
79171
79184
|
const opener = resolveCopier();
|
|
79172
79185
|
if (!opener) return false;
|
|
79173
|
-
return new Promise((
|
|
79186
|
+
return new Promise((resolve83) => {
|
|
79174
79187
|
let settled = false;
|
|
79175
79188
|
const finish = (ok) => {
|
|
79176
79189
|
if (settled) return;
|
|
79177
79190
|
settled = true;
|
|
79178
|
-
|
|
79191
|
+
resolve83(ok);
|
|
79179
79192
|
};
|
|
79180
79193
|
try {
|
|
79181
79194
|
const child = spawn2(opener.command, opener.args, {
|
|
@@ -80428,9 +80441,9 @@ init_source();
|
|
|
80428
80441
|
init_agent_host_detect();
|
|
80429
80442
|
init_scene_project();
|
|
80430
80443
|
init_visual_styles();
|
|
80431
|
-
import { existsSync as
|
|
80432
|
-
import { mkdir as
|
|
80433
|
-
import { basename as basename19, dirname as
|
|
80444
|
+
import { existsSync as existsSync41 } from "node:fs";
|
|
80445
|
+
import { mkdir as mkdir23, readFile as readFile38, writeFile as writeFile45 } from "node:fs/promises";
|
|
80446
|
+
import { basename as basename19, dirname as dirname19, resolve as resolve54 } from "node:path";
|
|
80434
80447
|
|
|
80435
80448
|
// src/commands/_shared/storyboard-draft.ts
|
|
80436
80449
|
init_scene_project();
|
|
@@ -80588,6 +80601,261 @@ function escapeRegExp2(value) {
|
|
|
80588
80601
|
init_project_config();
|
|
80589
80602
|
init_install_skill();
|
|
80590
80603
|
|
|
80604
|
+
// src/commands/_shared/host-integration.ts
|
|
80605
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
80606
|
+
import { mkdir as mkdir22, readFile as readFile37, writeFile as writeFile44 } from "node:fs/promises";
|
|
80607
|
+
import { homedir as homedir6 } from "node:os";
|
|
80608
|
+
import { dirname as dirname18, join as join19, resolve as resolve53 } from "node:path";
|
|
80609
|
+
var HOST_SELECTIONS = [
|
|
80610
|
+
"codex",
|
|
80611
|
+
"claude",
|
|
80612
|
+
"claude-code",
|
|
80613
|
+
"claude-desktop",
|
|
80614
|
+
"cursor",
|
|
80615
|
+
"all"
|
|
80616
|
+
];
|
|
80617
|
+
var VIBEFRAME_MCP_JSON = {
|
|
80618
|
+
command: "npx",
|
|
80619
|
+
args: ["-y", "@vibeframe/mcp-server"]
|
|
80620
|
+
};
|
|
80621
|
+
var CODEX_MCP_BLOCK = `[mcp_servers.vibeframe]
|
|
80622
|
+
command = "npx"
|
|
80623
|
+
args = ["-y", "@vibeframe/mcp-server"]
|
|
80624
|
+
enabled = true
|
|
80625
|
+
`;
|
|
80626
|
+
var CODEX_MANAGED_START = "# >>> VibeFrame MCP server >>>";
|
|
80627
|
+
var CODEX_MANAGED_END = "# <<< VibeFrame MCP server <<<";
|
|
80628
|
+
function hostDefinitions(_projectDir = process.cwd()) {
|
|
80629
|
+
return [
|
|
80630
|
+
{
|
|
80631
|
+
id: "codex",
|
|
80632
|
+
label: "OpenAI Codex",
|
|
80633
|
+
surfaces: ["shell", "project-guidance", "mcp"],
|
|
80634
|
+
guidanceFiles: ["AGENTS.md"],
|
|
80635
|
+
configPath: (dir) => join19(resolve53(dir), ".codex", "config.toml"),
|
|
80636
|
+
configKind: "codex-toml",
|
|
80637
|
+
notes: [
|
|
80638
|
+
"Codex reads AGENTS.md and can also load project-scoped .codex/config.toml after the project is trusted.",
|
|
80639
|
+
"Keep provider/auth keys in VibeFrame config or environment, not in project-local Codex config."
|
|
80640
|
+
]
|
|
80641
|
+
},
|
|
80642
|
+
{
|
|
80643
|
+
id: "claude-code",
|
|
80644
|
+
label: "Claude Code",
|
|
80645
|
+
surfaces: ["shell", "project-guidance", "mcp"],
|
|
80646
|
+
guidanceFiles: ["AGENTS.md", "CLAUDE.md", ".claude/skills/hyperframes/"],
|
|
80647
|
+
configPath: (dir) => join19(resolve53(dir), ".mcp.json"),
|
|
80648
|
+
configKind: "mcp-json",
|
|
80649
|
+
notes: [
|
|
80650
|
+
"Claude Code can drive vibe directly through shell plus AGENTS.md/CLAUDE.md.",
|
|
80651
|
+
"The MCP entry is optional and gives Claude Code a typed tool surface."
|
|
80652
|
+
]
|
|
80653
|
+
},
|
|
80654
|
+
{
|
|
80655
|
+
id: "claude-desktop",
|
|
80656
|
+
label: "Claude Desktop",
|
|
80657
|
+
surfaces: ["mcp"],
|
|
80658
|
+
guidanceFiles: [],
|
|
80659
|
+
configPath: (_dir) => claudeDesktopConfigPath(),
|
|
80660
|
+
configKind: "mcp-json",
|
|
80661
|
+
notes: [
|
|
80662
|
+
"Claude Desktop uses MCP config rather than project shell commands.",
|
|
80663
|
+
"With --write, VibeFrame backs up the existing config before merging."
|
|
80664
|
+
]
|
|
80665
|
+
},
|
|
80666
|
+
{
|
|
80667
|
+
id: "cursor",
|
|
80668
|
+
label: "Cursor",
|
|
80669
|
+
surfaces: ["shell", "project-guidance", "mcp"],
|
|
80670
|
+
guidanceFiles: ["AGENTS.md", ".cursor/rules/hyperframes.mdc"],
|
|
80671
|
+
configPath: (dir) => join19(resolve53(dir), ".cursor", "mcp.json"),
|
|
80672
|
+
configKind: "mcp-json",
|
|
80673
|
+
notes: [
|
|
80674
|
+
"Cursor can use AGENTS.md/rules for shell-driven work and .cursor/mcp.json for typed MCP tools."
|
|
80675
|
+
]
|
|
80676
|
+
}
|
|
80677
|
+
];
|
|
80678
|
+
}
|
|
80679
|
+
function resolveHostSelection(selection) {
|
|
80680
|
+
if (selection === "all") return ["codex", "claude-code", "claude-desktop", "cursor"];
|
|
80681
|
+
if (selection === "claude") return ["claude-code", "claude-desktop"];
|
|
80682
|
+
return [selection];
|
|
80683
|
+
}
|
|
80684
|
+
function renderHostSnippet(host, _projectDir) {
|
|
80685
|
+
if (host.configKind === "codex-toml") return CODEX_MCP_BLOCK.trimEnd();
|
|
80686
|
+
return JSON.stringify({ mcpServers: { vibeframe: VIBEFRAME_MCP_JSON } }, null, 2);
|
|
80687
|
+
}
|
|
80688
|
+
function claudeCodeAddCommand() {
|
|
80689
|
+
return "claude mcp add vibeframe --scope project -- npx -y @vibeframe/mcp-server";
|
|
80690
|
+
}
|
|
80691
|
+
async function planHostSetup(host, projectDir, opts) {
|
|
80692
|
+
const configPath = host.configPath(projectDir);
|
|
80693
|
+
const snippet = renderHostSnippet(host, projectDir);
|
|
80694
|
+
const files = [];
|
|
80695
|
+
const warnings = [];
|
|
80696
|
+
const nextSteps = hostNextSteps(host);
|
|
80697
|
+
for (const relPath of host.guidanceFiles.filter((p) => !p.endsWith("/"))) {
|
|
80698
|
+
const absPath = join19(resolve53(projectDir), relPath);
|
|
80699
|
+
files.push({
|
|
80700
|
+
path: absPath,
|
|
80701
|
+
status: existsSync40(absPath) ? "skipped-exists" : "missing",
|
|
80702
|
+
reason: existsSync40(absPath) ? "already present" : "run vibe init --agent all first"
|
|
80703
|
+
});
|
|
80704
|
+
}
|
|
80705
|
+
if (!opts.write || opts.dryRun) {
|
|
80706
|
+
files.push({
|
|
80707
|
+
path: configPath,
|
|
80708
|
+
status: opts.write ? "would-merge" : "would-write",
|
|
80709
|
+
reason: opts.write ? "dry run" : "snippet only; pass --write to modify"
|
|
80710
|
+
});
|
|
80711
|
+
return { host, snippet, command: host.id === "claude-code" ? claudeCodeAddCommand() : void 0, configPath, files, warnings, nextSteps };
|
|
80712
|
+
}
|
|
80713
|
+
try {
|
|
80714
|
+
const action = host.configKind === "codex-toml" ? await mergeCodexToml(configPath, { force: opts.force === true }) : await mergeMcpJson(configPath, {
|
|
80715
|
+
force: opts.force === true,
|
|
80716
|
+
backup: host.id === "claude-desktop"
|
|
80717
|
+
});
|
|
80718
|
+
files.push(action);
|
|
80719
|
+
} catch (error) {
|
|
80720
|
+
warnings.push(error instanceof Error ? error.message : String(error));
|
|
80721
|
+
}
|
|
80722
|
+
return { host, snippet, command: host.id === "claude-code" ? claudeCodeAddCommand() : void 0, configPath, files, warnings, nextSteps };
|
|
80723
|
+
}
|
|
80724
|
+
async function inspectHost(host, projectDir) {
|
|
80725
|
+
const configPath = host.configPath(projectDir);
|
|
80726
|
+
const warnings = [];
|
|
80727
|
+
const nextSteps = hostNextSteps(host);
|
|
80728
|
+
const guidanceFiles = host.guidanceFiles.map((relPath) => {
|
|
80729
|
+
const absPath = relPath.endsWith("/") ? join19(resolve53(projectDir), relPath) : join19(resolve53(projectDir), relPath);
|
|
80730
|
+
return {
|
|
80731
|
+
path: absPath,
|
|
80732
|
+
status: existsSync40(absPath) ? "skipped-exists" : "missing",
|
|
80733
|
+
reason: existsSync40(absPath) ? "present" : "missing"
|
|
80734
|
+
};
|
|
80735
|
+
});
|
|
80736
|
+
let configured = false;
|
|
80737
|
+
if (existsSync40(configPath)) {
|
|
80738
|
+
try {
|
|
80739
|
+
const content = await readFile37(configPath, "utf-8");
|
|
80740
|
+
configured = host.configKind === "codex-toml" ? /\[mcp_servers\.vibeframe\]/.test(content) : hasVibeframeMcpServer(JSON.parse(content));
|
|
80741
|
+
} catch (error) {
|
|
80742
|
+
warnings.push(error instanceof Error ? error.message : String(error));
|
|
80743
|
+
}
|
|
80744
|
+
}
|
|
80745
|
+
return { host, configPath, configured, guidanceFiles, warnings, nextSteps };
|
|
80746
|
+
}
|
|
80747
|
+
async function mergeMcpJson(configPath, opts) {
|
|
80748
|
+
let root = {};
|
|
80749
|
+
const exists = existsSync40(configPath);
|
|
80750
|
+
if (exists) {
|
|
80751
|
+
const raw = await readFile37(configPath, "utf-8");
|
|
80752
|
+
try {
|
|
80753
|
+
root = raw.trim() ? JSON.parse(raw) : {};
|
|
80754
|
+
} catch (error) {
|
|
80755
|
+
throw new Error(`Invalid JSON in ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
80756
|
+
}
|
|
80757
|
+
}
|
|
80758
|
+
const mcpServers = typeof root.mcpServers === "object" && root.mcpServers !== null && !Array.isArray(root.mcpServers) ? root.mcpServers : {};
|
|
80759
|
+
if (mcpServers.vibeframe && !opts.force) {
|
|
80760
|
+
return {
|
|
80761
|
+
path: configPath,
|
|
80762
|
+
status: "skipped-exists",
|
|
80763
|
+
reason: "vibeframe MCP server already exists; pass --force to replace"
|
|
80764
|
+
};
|
|
80765
|
+
}
|
|
80766
|
+
root.mcpServers = { ...mcpServers, vibeframe: VIBEFRAME_MCP_JSON };
|
|
80767
|
+
await mkdir22(dirname18(configPath), { recursive: true });
|
|
80768
|
+
if (exists && opts.backup) {
|
|
80769
|
+
await writeFile44(`${configPath}.bak-${timestamp()}`, await readFile37(configPath, "utf-8"), "utf-8");
|
|
80770
|
+
}
|
|
80771
|
+
await writeFile44(configPath, JSON.stringify(root, null, 2) + "\n", "utf-8");
|
|
80772
|
+
return { path: configPath, status: exists ? "merged" : "wrote" };
|
|
80773
|
+
}
|
|
80774
|
+
async function mergeCodexToml(configPath, opts) {
|
|
80775
|
+
const exists = existsSync40(configPath);
|
|
80776
|
+
const block = `${CODEX_MANAGED_START}
|
|
80777
|
+
${CODEX_MCP_BLOCK}${CODEX_MANAGED_END}`;
|
|
80778
|
+
if (!exists) {
|
|
80779
|
+
await mkdir22(dirname18(configPath), { recursive: true });
|
|
80780
|
+
await writeFile44(configPath, `#:schema https://developers.openai.com/codex/config-schema.json
|
|
80781
|
+
|
|
80782
|
+
${block}
|
|
80783
|
+
`, "utf-8");
|
|
80784
|
+
return { path: configPath, status: "wrote" };
|
|
80785
|
+
}
|
|
80786
|
+
const raw = await readFile37(configPath, "utf-8");
|
|
80787
|
+
if (raw.includes(CODEX_MANAGED_START)) {
|
|
80788
|
+
const updated = raw.replace(
|
|
80789
|
+
new RegExp(`${escapeRegExp3(CODEX_MANAGED_START)}[\\s\\S]*?${escapeRegExp3(CODEX_MANAGED_END)}`),
|
|
80790
|
+
block
|
|
80791
|
+
);
|
|
80792
|
+
await writeFile44(configPath, ensureTrailingNewline(updated), "utf-8");
|
|
80793
|
+
return { path: configPath, status: "merged", reason: "updated managed VibeFrame block" };
|
|
80794
|
+
}
|
|
80795
|
+
if (/\[mcp_servers\.vibeframe\]/.test(raw)) {
|
|
80796
|
+
if (!opts.force) {
|
|
80797
|
+
return {
|
|
80798
|
+
path: configPath,
|
|
80799
|
+
status: "skipped-exists",
|
|
80800
|
+
reason: "vibeframe MCP table already exists; pass --force to replace"
|
|
80801
|
+
};
|
|
80802
|
+
}
|
|
80803
|
+
const updated = raw.replace(/\n?\[mcp_servers\.vibeframe\][\s\S]*?(?=\n\[|$)/, `
|
|
80804
|
+
${block}
|
|
80805
|
+
`);
|
|
80806
|
+
await writeFile44(configPath, ensureTrailingNewline(updated), "utf-8");
|
|
80807
|
+
return { path: configPath, status: "merged", reason: "replaced existing VibeFrame MCP table" };
|
|
80808
|
+
}
|
|
80809
|
+
await writeFile44(configPath, `${ensureTrailingNewline(raw)}
|
|
80810
|
+
${block}
|
|
80811
|
+
`, "utf-8");
|
|
80812
|
+
return { path: configPath, status: "merged" };
|
|
80813
|
+
}
|
|
80814
|
+
function hasVibeframeMcpServer(value) {
|
|
80815
|
+
if (!value || typeof value !== "object") return false;
|
|
80816
|
+
const root = value;
|
|
80817
|
+
if (!root.mcpServers || typeof root.mcpServers !== "object") return false;
|
|
80818
|
+
return Object.prototype.hasOwnProperty.call(root.mcpServers, "vibeframe");
|
|
80819
|
+
}
|
|
80820
|
+
function hostNextSteps(host) {
|
|
80821
|
+
if (host.id === "codex") {
|
|
80822
|
+
return [
|
|
80823
|
+
"Trust the project in Codex so .codex/config.toml is loaded.",
|
|
80824
|
+
"Run /mcp in Codex to confirm the vibeframe server is connected."
|
|
80825
|
+
];
|
|
80826
|
+
}
|
|
80827
|
+
if (host.id === "claude-code") {
|
|
80828
|
+
return [
|
|
80829
|
+
"Restart Claude Code or run /mcp to approve the project-scoped server.",
|
|
80830
|
+
"Use AGENTS.md/CLAUDE.md for shell-driven vibe workflows."
|
|
80831
|
+
];
|
|
80832
|
+
}
|
|
80833
|
+
if (host.id === "claude-desktop") {
|
|
80834
|
+
return ["Restart Claude Desktop after updating its MCP config."];
|
|
80835
|
+
}
|
|
80836
|
+
return ["Restart Cursor or reload MCP servers, then ask Cursor to use the vibeframe MCP tools."];
|
|
80837
|
+
}
|
|
80838
|
+
function claudeDesktopConfigPath() {
|
|
80839
|
+
const home = homedir6();
|
|
80840
|
+
if (process.platform === "darwin") {
|
|
80841
|
+
return join19(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
80842
|
+
}
|
|
80843
|
+
if (process.platform === "win32") {
|
|
80844
|
+
return join19(process.env.APPDATA ?? join19(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
|
|
80845
|
+
}
|
|
80846
|
+
return join19(home, ".config", "Claude", "claude_desktop_config.json");
|
|
80847
|
+
}
|
|
80848
|
+
function timestamp() {
|
|
80849
|
+
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
80850
|
+
}
|
|
80851
|
+
function ensureTrailingNewline(value) {
|
|
80852
|
+
return value.endsWith("\n") ? value : `${value}
|
|
80853
|
+
`;
|
|
80854
|
+
}
|
|
80855
|
+
function escapeRegExp3(value) {
|
|
80856
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
80857
|
+
}
|
|
80858
|
+
|
|
80591
80859
|
// src/commands/_shared/init-templates.ts
|
|
80592
80860
|
var AGENTS_MD = `# AGENTS.md
|
|
80593
80861
|
|
|
@@ -80628,6 +80896,8 @@ vibe schema --list # full machine-readable catalog (80+)
|
|
|
80628
80896
|
vibe schema --list --surface public # small first-run/product command surface
|
|
80629
80897
|
vibe schema generate.video # JSON Schema for any single command
|
|
80630
80898
|
vibe doctor # available providers + system health
|
|
80899
|
+
vibe host setup all # print Codex/Claude/Cursor app integration snippets
|
|
80900
|
+
vibe host doctor all --json # verify project guidance + MCP config
|
|
80631
80901
|
vibe guide motion # choose text-overlay vs motion-overlay vs generate motion
|
|
80632
80902
|
vibe guide scene # step-by-step authoring guide (scene)
|
|
80633
80903
|
vibe guide pipeline # step-by-step authoring guide (pipeline)
|
|
@@ -80752,6 +81022,22 @@ unless the user explicitly asks for a non-VibeFrame asset.
|
|
|
80752
81022
|
\`.env\` is still supported as a gitignored fallback. Copy \`.env.example\`
|
|
80753
81023
|
to start if you prefer environment variables.
|
|
80754
81024
|
|
|
81025
|
+
## App host setup
|
|
81026
|
+
|
|
81027
|
+
VibeFrame is CLI-first, not terminal-only. Codex, Claude Code, and Cursor can
|
|
81028
|
+
drive the same project through shell commands, and app hosts can also use
|
|
81029
|
+
VibeFrame's MCP server as a typed tool surface.
|
|
81030
|
+
|
|
81031
|
+
\`\`\`bash
|
|
81032
|
+
vibe host setup all # print snippets only
|
|
81033
|
+
vibe host setup all --write # write project/app config
|
|
81034
|
+
vibe host doctor all --json # verify readiness
|
|
81035
|
+
\`\`\`
|
|
81036
|
+
|
|
81037
|
+
Default setup is snippet-only; use \`--write\` when you want VibeFrame to merge
|
|
81038
|
+
the generated config. Keep provider keys in \`.vibeframe/config.yaml\`, user
|
|
81039
|
+
config, or env files \u2014 not in app host config.
|
|
81040
|
+
|
|
80755
81041
|
### Composition rules (scene HTML)
|
|
80756
81042
|
|
|
80757
81043
|
\`vibe init\` installs local composition rules into your project. The
|
|
@@ -80942,7 +81228,7 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80942
81228
|
).option(
|
|
80943
81229
|
"--from <brief>",
|
|
80944
81230
|
"Draft STORYBOARD.md and DESIGN.md from a brief string or text/markdown file"
|
|
80945
|
-
).option("-r, --ratio <ratio>", "Scene aspect ratio: 16:9, 9:16, 1:1, 4:5", "16:9").option("-d, --duration <sec>", "Default scene/root duration in seconds", "10").option("--visual-style <name>", "Seed scene DESIGN.md from a named style").option("--agent <id>", `Agent target: ${VALID_AGENTS.join(" | ")}`, "auto").option("--force", "Overwrite existing files instead of skipping").option("--dry-run", "Print the file list without writing anything").action(async (projectDirArg, options) => {
|
|
81231
|
+
).option("-r, --ratio <ratio>", "Scene aspect ratio: 16:9, 9:16, 1:1, 4:5", "16:9").option("-d, --duration <sec>", "Default scene/root duration in seconds", "10").option("--visual-style <name>", "Seed scene DESIGN.md from a named style").option("--agent <id>", `Agent target: ${VALID_AGENTS.join(" | ")}`, "auto").option("--mcp", "Also write project-scoped MCP config for Codex/Claude Code/Cursor").option("--force", "Overwrite existing files instead of skipping").option("--dry-run", "Print the file list without writing anything").action(async (projectDirArg, options) => {
|
|
80946
81232
|
const startedAt = Date.now();
|
|
80947
81233
|
const initType = String(options.type ?? "scene");
|
|
80948
81234
|
if (initType !== "scene" && initType !== "agent") {
|
|
@@ -80958,14 +81244,14 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80958
81244
|
usageError(`Invalid --agent: ${agent}`, `Must be one of: ${VALID_AGENTS.join(", ")}`)
|
|
80959
81245
|
);
|
|
80960
81246
|
}
|
|
80961
|
-
const projectDir =
|
|
81247
|
+
const projectDir = resolve54(projectDirArg);
|
|
80962
81248
|
const projectName = basename19(projectDir);
|
|
80963
81249
|
const targetHosts = resolveTargets(agent);
|
|
80964
81250
|
const wantsClaude = targetHosts.includes("claude-code");
|
|
80965
81251
|
const wantsGemini = targetHosts.includes("gemini-cli");
|
|
80966
81252
|
const wantsCrossTool = targetHosts.some((h) => h !== "claude-code");
|
|
80967
81253
|
const actions = [];
|
|
80968
|
-
if (!
|
|
81254
|
+
if (!existsSync41(projectDir)) {
|
|
80969
81255
|
if (options.dryRun) {
|
|
80970
81256
|
actions.push({
|
|
80971
81257
|
path: projectDir,
|
|
@@ -80973,13 +81259,13 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80973
81259
|
reason: "(would create directory)"
|
|
80974
81260
|
});
|
|
80975
81261
|
} else {
|
|
80976
|
-
await
|
|
81262
|
+
await mkdir23(projectDir, { recursive: true });
|
|
80977
81263
|
}
|
|
80978
81264
|
}
|
|
80979
81265
|
if (wantsCrossTool || !wantsClaude) {
|
|
80980
81266
|
actions.push(
|
|
80981
81267
|
await writeIfMissing(
|
|
80982
|
-
|
|
81268
|
+
resolve54(projectDir, "AGENTS.md"),
|
|
80983
81269
|
AGENTS_MD,
|
|
80984
81270
|
options.force,
|
|
80985
81271
|
options.dryRun
|
|
@@ -80989,7 +81275,7 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80989
81275
|
if (wantsClaude) {
|
|
80990
81276
|
actions.push(
|
|
80991
81277
|
await writeIfMissing(
|
|
80992
|
-
|
|
81278
|
+
resolve54(projectDir, "CLAUDE.md"),
|
|
80993
81279
|
CLAUDE_MD,
|
|
80994
81280
|
options.force,
|
|
80995
81281
|
options.dryRun
|
|
@@ -80999,7 +81285,7 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80999
81285
|
if (wantsGemini) {
|
|
81000
81286
|
actions.push(
|
|
81001
81287
|
await writeIfMissing(
|
|
81002
|
-
|
|
81288
|
+
resolve54(projectDir, "GEMINI.md"),
|
|
81003
81289
|
GEMINI_MD,
|
|
81004
81290
|
options.force,
|
|
81005
81291
|
options.dryRun
|
|
@@ -81008,18 +81294,18 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
81008
81294
|
}
|
|
81009
81295
|
actions.push(
|
|
81010
81296
|
await writeIfMissing(
|
|
81011
|
-
|
|
81297
|
+
resolve54(projectDir, ".env.example"),
|
|
81012
81298
|
renderEnvExample(),
|
|
81013
81299
|
options.force,
|
|
81014
81300
|
options.dryRun
|
|
81015
81301
|
)
|
|
81016
81302
|
);
|
|
81017
81303
|
actions.push(
|
|
81018
|
-
await mergeGitignore(
|
|
81304
|
+
await mergeGitignore(resolve54(projectDir, ".gitignore"), GITIGNORE_ADDITIONS, options.dryRun)
|
|
81019
81305
|
);
|
|
81020
81306
|
actions.push(
|
|
81021
81307
|
await writeIfMissing(
|
|
81022
|
-
|
|
81308
|
+
resolve54(projectDir, VIBE_CONFIG_FILENAME),
|
|
81023
81309
|
projectConfigJson({ name: projectName }),
|
|
81024
81310
|
options.force,
|
|
81025
81311
|
options.dryRun
|
|
@@ -81027,12 +81313,20 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
81027
81313
|
);
|
|
81028
81314
|
actions.push(
|
|
81029
81315
|
await writeIfMissing(
|
|
81030
|
-
|
|
81316
|
+
resolve54(projectDir, "vibe.project.yaml"),
|
|
81031
81317
|
renderProjectYaml({ name: projectName }),
|
|
81032
81318
|
options.force,
|
|
81033
81319
|
options.dryRun
|
|
81034
81320
|
)
|
|
81035
81321
|
);
|
|
81322
|
+
if (options.mcp === true) {
|
|
81323
|
+
actions.push(
|
|
81324
|
+
...await setupProjectMcpTargets(projectDir, targetHosts, {
|
|
81325
|
+
force: options.force === true,
|
|
81326
|
+
dryRun: options.dryRun === true
|
|
81327
|
+
})
|
|
81328
|
+
);
|
|
81329
|
+
}
|
|
81036
81330
|
if (isJsonMode()) {
|
|
81037
81331
|
outputSuccess({
|
|
81038
81332
|
command: "init",
|
|
@@ -81117,7 +81411,7 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81117
81411
|
)
|
|
81118
81412
|
);
|
|
81119
81413
|
}
|
|
81120
|
-
const projectDir =
|
|
81414
|
+
const projectDir = resolve54(projectDirArg);
|
|
81121
81415
|
const projectName = basename19(projectDir);
|
|
81122
81416
|
const groups = describeSceneScaffold({ dir: projectDir, profile });
|
|
81123
81417
|
const fromBrief = typeof options.from === "string" && options.from.trim() ? await readBriefOrLiteral(String(options.from), process.cwd()) : null;
|
|
@@ -81170,14 +81464,14 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81170
81464
|
aspect,
|
|
81171
81465
|
visualStyle
|
|
81172
81466
|
});
|
|
81173
|
-
const storyboardPath2 =
|
|
81174
|
-
const designPath =
|
|
81175
|
-
if (options.force || result.created.includes(storyboardPath2) || !
|
|
81176
|
-
await
|
|
81467
|
+
const storyboardPath2 = resolve54(projectDir, "STORYBOARD.md");
|
|
81468
|
+
const designPath = resolve54(projectDir, "DESIGN.md");
|
|
81469
|
+
if (options.force || result.created.includes(storyboardPath2) || !existsSync41(storyboardPath2)) {
|
|
81470
|
+
await writeFile45(storyboardPath2, draft.storyboardMd, "utf-8");
|
|
81177
81471
|
if (!result.created.includes(storyboardPath2)) result.created.push(storyboardPath2);
|
|
81178
81472
|
}
|
|
81179
|
-
if (options.force || result.created.includes(designPath) || !
|
|
81180
|
-
await
|
|
81473
|
+
if (options.force || result.created.includes(designPath) || !existsSync41(designPath)) {
|
|
81474
|
+
await writeFile45(designPath, draft.designMd, "utf-8");
|
|
81181
81475
|
if (!result.created.includes(designPath)) result.created.push(designPath);
|
|
81182
81476
|
}
|
|
81183
81477
|
draftWarnings.push(...draft.warnings);
|
|
@@ -81187,6 +81481,10 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81187
81481
|
projectDir,
|
|
81188
81482
|
hosts: deriveInstallHosts(detectedIds)
|
|
81189
81483
|
}) : { success: true, files: [], bundleVersion: "not-installed" };
|
|
81484
|
+
const mcpActions = options.mcp === true ? await setupProjectMcpTargets(projectDir, detectedIds, {
|
|
81485
|
+
force: options.force === true,
|
|
81486
|
+
dryRun: false
|
|
81487
|
+
}) : [];
|
|
81190
81488
|
if (isJsonMode()) {
|
|
81191
81489
|
outputSuccess({
|
|
81192
81490
|
command: "init",
|
|
@@ -81206,6 +81504,7 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81206
81504
|
groups: result.groups,
|
|
81207
81505
|
skillFiles: skillResult.files,
|
|
81208
81506
|
skillBundleVersion: skillResult.bundleVersion,
|
|
81507
|
+
mcpFiles: mcpActions,
|
|
81209
81508
|
warnings: draftWarnings
|
|
81210
81509
|
}
|
|
81211
81510
|
});
|
|
@@ -81243,6 +81542,10 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81243
81542
|
for (const f of skillResult.files.filter((f2) => f2.status === "wrote")) {
|
|
81244
81543
|
console.log(source_default.green(` + ${f.path.replace(projectDir + "/", "")}`));
|
|
81245
81544
|
}
|
|
81545
|
+
for (const f of mcpActions) {
|
|
81546
|
+
const icon = f.status === "wrote" || f.status === "merged" ? source_default.green("+") : source_default.dim("\xB7");
|
|
81547
|
+
console.log(`${icon} ${f.path.replace(projectDir + "/", "")} ${source_default.dim(`(${f.status})`)}`);
|
|
81548
|
+
}
|
|
81246
81549
|
console.log();
|
|
81247
81550
|
console.log(source_default.dim(`Tip: cd ${projectDirArg} before running the next commands.`));
|
|
81248
81551
|
console.log();
|
|
@@ -81290,9 +81593,9 @@ function printGroup(label, files, projectDir) {
|
|
|
81290
81593
|
}
|
|
81291
81594
|
}
|
|
81292
81595
|
async function readBriefOrLiteral(value, cwd) {
|
|
81293
|
-
const candidate =
|
|
81294
|
-
if (
|
|
81295
|
-
return
|
|
81596
|
+
const candidate = resolve54(cwd, value);
|
|
81597
|
+
if (existsSync41(candidate)) {
|
|
81598
|
+
return readFile38(candidate, "utf-8");
|
|
81296
81599
|
}
|
|
81297
81600
|
return value;
|
|
81298
81601
|
}
|
|
@@ -81311,32 +81614,65 @@ function resolveTargets(agent) {
|
|
|
81311
81614
|
}
|
|
81312
81615
|
return [agent];
|
|
81313
81616
|
}
|
|
81617
|
+
async function setupProjectMcpTargets(projectDir, targetHosts, opts) {
|
|
81618
|
+
const ids = /* @__PURE__ */ new Set();
|
|
81619
|
+
if (targetHosts.includes("codex")) ids.add("codex");
|
|
81620
|
+
if (targetHosts.includes("claude-code")) ids.add("claude-code");
|
|
81621
|
+
if (targetHosts.includes("cursor")) ids.add("cursor");
|
|
81622
|
+
if (targetHosts.length === 0) {
|
|
81623
|
+
ids.add("codex");
|
|
81624
|
+
ids.add("claude-code");
|
|
81625
|
+
ids.add("cursor");
|
|
81626
|
+
}
|
|
81627
|
+
const actions = [];
|
|
81628
|
+
for (const host of hostDefinitions(projectDir).filter((h) => ids.has(h.id))) {
|
|
81629
|
+
const plan = await planHostSetup(host, projectDir, {
|
|
81630
|
+
write: true,
|
|
81631
|
+
dryRun: opts.dryRun,
|
|
81632
|
+
force: opts.force
|
|
81633
|
+
});
|
|
81634
|
+
const configAction = plan.files.find((file) => file.path === plan.configPath);
|
|
81635
|
+
if (!configAction) continue;
|
|
81636
|
+
actions.push({
|
|
81637
|
+
path: configAction.path,
|
|
81638
|
+
status: normalizeHostAction(configAction.status),
|
|
81639
|
+
reason: configAction.reason
|
|
81640
|
+
});
|
|
81641
|
+
}
|
|
81642
|
+
return actions;
|
|
81643
|
+
}
|
|
81644
|
+
function normalizeHostAction(status) {
|
|
81645
|
+
if (status === "merged") return "merged";
|
|
81646
|
+
if (status === "wrote") return "wrote";
|
|
81647
|
+
if (status === "skipped-exists") return "skipped-exists";
|
|
81648
|
+
return "would-write";
|
|
81649
|
+
}
|
|
81314
81650
|
async function writeIfMissing(absPath, content, force, dryRun) {
|
|
81315
|
-
const exists =
|
|
81651
|
+
const exists = existsSync41(absPath);
|
|
81316
81652
|
if (exists && !force) {
|
|
81317
81653
|
return { path: absPath, status: "skipped-exists", reason: "(use --force to overwrite)" };
|
|
81318
81654
|
}
|
|
81319
81655
|
if (dryRun) {
|
|
81320
81656
|
return { path: absPath, status: "would-write" };
|
|
81321
81657
|
}
|
|
81322
|
-
await
|
|
81323
|
-
await
|
|
81658
|
+
await mkdir23(dirname19(absPath), { recursive: true });
|
|
81659
|
+
await writeFile45(absPath, content, "utf-8");
|
|
81324
81660
|
return { path: absPath, status: "wrote" };
|
|
81325
81661
|
}
|
|
81326
81662
|
async function mergeGitignore(absPath, additions, dryRun) {
|
|
81327
81663
|
const marker = "# VibeFrame";
|
|
81328
|
-
if (!
|
|
81664
|
+
if (!existsSync41(absPath)) {
|
|
81329
81665
|
if (dryRun) return { path: absPath, status: "would-write" };
|
|
81330
|
-
await
|
|
81666
|
+
await writeFile45(absPath, additions.trimStart(), "utf-8");
|
|
81331
81667
|
return { path: absPath, status: "wrote" };
|
|
81332
81668
|
}
|
|
81333
|
-
const existing = await
|
|
81669
|
+
const existing = await readFile38(absPath, "utf-8");
|
|
81334
81670
|
if (existing.includes(marker)) {
|
|
81335
81671
|
return { path: absPath, status: "skipped-exists", reason: "(already has VibeFrame block)" };
|
|
81336
81672
|
}
|
|
81337
81673
|
if (dryRun) return { path: absPath, status: "merged" };
|
|
81338
81674
|
const trailing = existing.endsWith("\n") ? "" : "\n";
|
|
81339
|
-
await
|
|
81675
|
+
await writeFile45(absPath, existing + trailing + additions, "utf-8");
|
|
81340
81676
|
return { path: absPath, status: "merged" };
|
|
81341
81677
|
}
|
|
81342
81678
|
function formatStatusIcon(status) {
|
|
@@ -81363,9 +81699,9 @@ init_storyboard_revise();
|
|
|
81363
81699
|
init_composer_resolve();
|
|
81364
81700
|
init_cost_tier();
|
|
81365
81701
|
init_output();
|
|
81366
|
-
import { readFile as
|
|
81367
|
-
import { existsSync as
|
|
81368
|
-
import { resolve as
|
|
81702
|
+
import { readFile as readFile40, writeFile as writeFile47 } from "node:fs/promises";
|
|
81703
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
81704
|
+
import { resolve as resolve56 } from "node:path";
|
|
81369
81705
|
var storyboardCommand = new Command("storyboard").description("Read, validate, and safely mutate STORYBOARD.md cue blocks").addHelpText("after", `
|
|
81370
81706
|
Examples:
|
|
81371
81707
|
$ vibe storyboard validate my-video --json
|
|
@@ -81377,7 +81713,7 @@ Examples:
|
|
|
81377
81713
|
`);
|
|
81378
81714
|
storyboardCommand.command("list").description("List beats, ids, cues, and durations from STORYBOARD.md").argument("[project-dir]", "Project directory", ".").action(async (projectDirArg) => {
|
|
81379
81715
|
const startedAt = Date.now();
|
|
81380
|
-
const projectDir =
|
|
81716
|
+
const projectDir = resolve56(projectDirArg);
|
|
81381
81717
|
const md = await readStoryboard(projectDir);
|
|
81382
81718
|
const parsed = parseStoryboard(md);
|
|
81383
81719
|
const data = {
|
|
@@ -81399,7 +81735,7 @@ storyboardCommand.command("list").description("List beats, ids, cues, and durati
|
|
|
81399
81735
|
});
|
|
81400
81736
|
storyboardCommand.command("get").description("Print one beat as structured JSON").argument("<project-dir>", "Project directory").argument("<beat>", "Beat id").action(async (projectDirArg, beatId) => {
|
|
81401
81737
|
const startedAt = Date.now();
|
|
81402
|
-
const projectDir =
|
|
81738
|
+
const projectDir = resolve56(projectDirArg);
|
|
81403
81739
|
const md = await readStoryboard(projectDir);
|
|
81404
81740
|
const beat = getStoryboardBeat(md, beatId);
|
|
81405
81741
|
if (!beat) {
|
|
@@ -81422,7 +81758,7 @@ storyboardCommand.command("get").description("Print one beat as structured JSON"
|
|
|
81422
81758
|
});
|
|
81423
81759
|
storyboardCommand.command("set").description("Update one cue in one beat without raw Markdown editing").argument("<project-dir>", "Project directory").argument("<beat>", "Beat id").argument("<key>", `Cue key: ${STORYBOARD_CUE_KEYS.join(" | ")}`).argument("[value...]", "Cue value. Use --json-value to pass a JSON scalar/object.").option("--json-value", "Parse value as JSON instead of a string").option("--unset", "Remove the cue key from the beat").action(async (projectDirArg, beatId, key, valueParts, options) => {
|
|
81424
81760
|
const startedAt = Date.now();
|
|
81425
|
-
const projectDir =
|
|
81761
|
+
const projectDir = resolve56(projectDirArg);
|
|
81426
81762
|
if (!options.unset && (!valueParts || valueParts.length === 0)) {
|
|
81427
81763
|
exitWithError(usageError("Cue value is required unless --unset is passed."));
|
|
81428
81764
|
}
|
|
@@ -81441,7 +81777,7 @@ storyboardCommand.command("set").description("Update one cue in one beat without
|
|
|
81441
81777
|
} catch (error) {
|
|
81442
81778
|
exitWithError(usageError(error instanceof Error ? error.message : String(error)));
|
|
81443
81779
|
}
|
|
81444
|
-
await
|
|
81780
|
+
await writeFile47(storyboardPath(projectDir), next, "utf-8");
|
|
81445
81781
|
const beat = getStoryboardBeat(next, beatId);
|
|
81446
81782
|
outputSuccess({
|
|
81447
81783
|
command: "storyboard set",
|
|
@@ -81457,7 +81793,7 @@ storyboardCommand.command("set").description("Update one cue in one beat without
|
|
|
81457
81793
|
});
|
|
81458
81794
|
storyboardCommand.command("move").description("Reorder beats safely").argument("<project-dir>", "Project directory").argument("<beat>", "Beat id to move").requiredOption("--after <beat>", "Place the beat after this beat id").action(async (projectDirArg, beatId, options) => {
|
|
81459
81795
|
const startedAt = Date.now();
|
|
81460
|
-
const projectDir =
|
|
81796
|
+
const projectDir = resolve56(projectDirArg);
|
|
81461
81797
|
const md = await readStoryboard(projectDir);
|
|
81462
81798
|
let next;
|
|
81463
81799
|
try {
|
|
@@ -81465,7 +81801,7 @@ storyboardCommand.command("move").description("Reorder beats safely").argument("
|
|
|
81465
81801
|
} catch (error) {
|
|
81466
81802
|
exitWithError(usageError(error instanceof Error ? error.message : String(error)));
|
|
81467
81803
|
}
|
|
81468
|
-
await
|
|
81804
|
+
await writeFile47(storyboardPath(projectDir), next, "utf-8");
|
|
81469
81805
|
const parsed = parseStoryboard(next);
|
|
81470
81806
|
outputSuccess({
|
|
81471
81807
|
command: "storyboard move",
|
|
@@ -81480,7 +81816,7 @@ storyboardCommand.command("move").description("Reorder beats safely").argument("
|
|
|
81480
81816
|
});
|
|
81481
81817
|
storyboardCommand.command("revise").description("Revise STORYBOARD.md from a request or source file").argument("<project-dir>", "Project directory").requiredOption("--from <brief>", "Revision request or path to a text/markdown file").option("-d, --duration <sec>", "Target total duration in seconds").option("--composer <provider>", "Revision LLM provider: claude|openai|gemini").option("--dry-run", "Preview the revised storyboard without writing").action(async (projectDirArg, options) => {
|
|
81482
81818
|
const startedAt = Date.now();
|
|
81483
|
-
const projectDir =
|
|
81819
|
+
const projectDir = resolve56(projectDirArg);
|
|
81484
81820
|
const brief = await readBrief(options.from, process.cwd());
|
|
81485
81821
|
const duration = options.duration ? Number.parseFloat(options.duration) : void 0;
|
|
81486
81822
|
if (duration !== void 0 && (!Number.isFinite(duration) || duration <= 0)) {
|
|
@@ -81512,7 +81848,7 @@ storyboardCommand.command("revise").description("Revise STORYBOARD.md from a req
|
|
|
81512
81848
|
});
|
|
81513
81849
|
storyboardCommand.command("validate").description("Validate cue blocks and beat ids").argument("[project-dir]", "Project directory", ".").action(async (projectDirArg) => {
|
|
81514
81850
|
const startedAt = Date.now();
|
|
81515
|
-
const projectDir =
|
|
81851
|
+
const projectDir = resolve56(projectDirArg);
|
|
81516
81852
|
const md = await readStoryboard(projectDir);
|
|
81517
81853
|
const result = validateStoryboardMarkdown(md);
|
|
81518
81854
|
if (isJsonMode()) {
|
|
@@ -81547,13 +81883,13 @@ storyboardCommand.command("validate").description("Validate cue blocks and beat
|
|
|
81547
81883
|
});
|
|
81548
81884
|
async function readStoryboard(projectDir) {
|
|
81549
81885
|
const path2 = storyboardPath(projectDir);
|
|
81550
|
-
if (!
|
|
81886
|
+
if (!existsSync43(path2)) {
|
|
81551
81887
|
exitWithError(generalError(`STORYBOARD.md not found at ${path2}`, `Run 'vibe init ${projectDir} --from "<brief>"' first.`));
|
|
81552
81888
|
}
|
|
81553
|
-
return
|
|
81889
|
+
return readFile40(path2, "utf-8");
|
|
81554
81890
|
}
|
|
81555
81891
|
function storyboardPath(projectDir) {
|
|
81556
|
-
return
|
|
81892
|
+
return resolve56(projectDir, "STORYBOARD.md");
|
|
81557
81893
|
}
|
|
81558
81894
|
function parseComposer(value) {
|
|
81559
81895
|
if (value === void 0) return void 0;
|
|
@@ -81561,9 +81897,9 @@ function parseComposer(value) {
|
|
|
81561
81897
|
exitWithError(usageError(`Invalid --composer: ${value}`, "Must be one of: claude, openai, gemini"));
|
|
81562
81898
|
}
|
|
81563
81899
|
async function readBrief(value, cwd) {
|
|
81564
|
-
const candidate =
|
|
81565
|
-
if (
|
|
81566
|
-
return
|
|
81900
|
+
const candidate = resolve56(cwd, value);
|
|
81901
|
+
if (existsSync43(candidate)) {
|
|
81902
|
+
return readFile40(candidate, "utf-8");
|
|
81567
81903
|
}
|
|
81568
81904
|
return value;
|
|
81569
81905
|
}
|
|
@@ -81596,7 +81932,7 @@ init_esm();
|
|
|
81596
81932
|
init_source();
|
|
81597
81933
|
init_build_plan();
|
|
81598
81934
|
init_output();
|
|
81599
|
-
import { resolve as
|
|
81935
|
+
import { resolve as resolve59 } from "node:path";
|
|
81600
81936
|
var VALID_STAGES = ["assets", "compose", "sync", "render", "all"];
|
|
81601
81937
|
var VALID_MODES = ["agent", "batch", "auto"];
|
|
81602
81938
|
var VALID_TTS_PROVIDERS = ["auto", "elevenlabs", "kokoro"];
|
|
@@ -81644,7 +81980,7 @@ var planCommand = new Command("plan").description("Read STORYBOARD.md and show b
|
|
|
81644
81980
|
)
|
|
81645
81981
|
);
|
|
81646
81982
|
}
|
|
81647
|
-
const projectDir =
|
|
81983
|
+
const projectDir = resolve59(projectDirArg);
|
|
81648
81984
|
const plan = await createBuildPlan({
|
|
81649
81985
|
projectDir,
|
|
81650
81986
|
stage,
|
|
@@ -81789,8 +82125,8 @@ init_scene_build();
|
|
|
81789
82125
|
init_build_plan();
|
|
81790
82126
|
init_storyboard_parse();
|
|
81791
82127
|
init_output();
|
|
81792
|
-
import { resolve as
|
|
81793
|
-
import { readFileSync as readFileSync3, existsSync as
|
|
82128
|
+
import { resolve as resolve64, join as join24 } from "node:path";
|
|
82129
|
+
import { readFileSync as readFileSync3, existsSync as existsSync48 } from "node:fs";
|
|
81794
82130
|
var VALID_MODES2 = ["agent", "batch", "auto"];
|
|
81795
82131
|
var VALID_STAGES2 = ["assets", "compose", "sync", "render", "all"];
|
|
81796
82132
|
var VALID_IMAGE_PROVIDERS2 = ["openai", "gemini", "grok"];
|
|
@@ -81807,7 +82143,7 @@ Examples:
|
|
|
81807
82143
|
Advanced equivalent: \`vibe scene build\`.`
|
|
81808
82144
|
).action(async (projectDirArg, options) => {
|
|
81809
82145
|
const startedAt = Date.now();
|
|
81810
|
-
const projectDir =
|
|
82146
|
+
const projectDir = resolve64(projectDirArg);
|
|
81811
82147
|
const mode = String(options.mode ?? "auto");
|
|
81812
82148
|
if (!VALID_MODES2.includes(mode)) {
|
|
81813
82149
|
exitWithError(
|
|
@@ -82153,8 +82489,8 @@ function buildPlanValidationFailureData(plan) {
|
|
|
82153
82489
|
};
|
|
82154
82490
|
}
|
|
82155
82491
|
function estimateBuildCost(params) {
|
|
82156
|
-
const storyboardPath2 =
|
|
82157
|
-
if (!
|
|
82492
|
+
const storyboardPath2 = join24(params.projectDir, "STORYBOARD.md");
|
|
82493
|
+
if (!existsSync48(storyboardPath2)) return null;
|
|
82158
82494
|
let beats = 0;
|
|
82159
82495
|
try {
|
|
82160
82496
|
const md = readFileSync3(storyboardPath2, "utf-8");
|
|
@@ -82298,7 +82634,7 @@ init_source();
|
|
|
82298
82634
|
init_ora();
|
|
82299
82635
|
init_scene_render();
|
|
82300
82636
|
init_output();
|
|
82301
|
-
import { resolve as
|
|
82637
|
+
import { resolve as resolve65 } from "node:path";
|
|
82302
82638
|
var VALID_FPS = [24, 30, 60];
|
|
82303
82639
|
var VALID_QUALITIES = ["draft", "standard", "high"];
|
|
82304
82640
|
var VALID_FORMATS = ["mp4", "webm", "mov"];
|
|
@@ -82309,7 +82645,7 @@ Examples:
|
|
|
82309
82645
|
|
|
82310
82646
|
Alias note: this is the project-level entrypoint for \`vibe scene render\`.`).action(async (projectDirArg, options) => {
|
|
82311
82647
|
const startedAt = Date.now();
|
|
82312
|
-
const projectDir =
|
|
82648
|
+
const projectDir = resolve65(projectDirArg);
|
|
82313
82649
|
const fps = parseFps(String(options.fps));
|
|
82314
82650
|
const quality = parseQuality(String(options.quality));
|
|
82315
82651
|
const format = parseFormat(String(options.format));
|
|
@@ -82432,7 +82768,7 @@ init_source();
|
|
|
82432
82768
|
init_cost_tier();
|
|
82433
82769
|
init_status_jobs();
|
|
82434
82770
|
init_output();
|
|
82435
|
-
import { resolve as
|
|
82771
|
+
import { resolve as resolve66 } from "node:path";
|
|
82436
82772
|
var statusCommand = new Command("status").description("Inspect local async jobs and project workflow status").addHelpText("after", `
|
|
82437
82773
|
Examples:
|
|
82438
82774
|
$ vibe status job job_abc123 --json
|
|
@@ -82443,7 +82779,7 @@ Examples:
|
|
|
82443
82779
|
statusCommand.command("job").description("Show one async job status").argument("<job-id>", "Local job id from a no-wait command").option("--project <dir>", "Project directory containing .vibeframe/jobs").option("--no-refresh", "Read local job record only; do not call provider APIs").option("--wait", "Wait for completion when the provider status helper supports it").option("-o, --output <path>", "Download result media when complete").action(async (jobId, options) => {
|
|
82444
82780
|
const startedAt = Date.now();
|
|
82445
82781
|
try {
|
|
82446
|
-
const projectDir = options.project ?
|
|
82782
|
+
const projectDir = options.project ? resolve66(options.project) : findProjectRoot();
|
|
82447
82783
|
const record = await readJobRecord(jobId, projectDir);
|
|
82448
82784
|
if (!record) {
|
|
82449
82785
|
exitWithError(generalError(`Job not found: ${jobId}`, `Run 'vibe status project ${projectDir} --json' to list known jobs.`));
|
|
@@ -82471,7 +82807,7 @@ applyTier(statusCommand.commands[statusCommand.commands.length - 1], "free");
|
|
|
82471
82807
|
statusCommand.command("project").description("Summarize build, review, and async job status for a project").argument("[project-dir]", "VibeFrame project directory", ".").option("--refresh", "Refresh active supported jobs before summarizing").action(async (projectDirArg, options) => {
|
|
82472
82808
|
const startedAt = Date.now();
|
|
82473
82809
|
try {
|
|
82474
|
-
const result = await inspectProjectStatus(
|
|
82810
|
+
const result = await inspectProjectStatus(resolve66(projectDirArg), {
|
|
82475
82811
|
refresh: options.refresh === true
|
|
82476
82812
|
});
|
|
82477
82813
|
if (isJsonMode()) {
|
|
@@ -82567,8 +82903,8 @@ init_composer_resolve();
|
|
|
82567
82903
|
init_cost_tier();
|
|
82568
82904
|
init_scene_build_mode();
|
|
82569
82905
|
init_output();
|
|
82570
|
-
import { existsSync as
|
|
82571
|
-
import { resolve as
|
|
82906
|
+
import { existsSync as existsSync49 } from "node:fs";
|
|
82907
|
+
import { resolve as resolve67 } from "node:path";
|
|
82572
82908
|
var COMMAND_KEY_MAP = getCommandKeyMap();
|
|
82573
82909
|
var FREE_COMMANDS = [
|
|
82574
82910
|
"edit silence-cut",
|
|
@@ -82695,14 +83031,14 @@ async function runDiagnostics() {
|
|
|
82695
83031
|
installed = false;
|
|
82696
83032
|
}
|
|
82697
83033
|
} else if (toolName === "chrome") {
|
|
82698
|
-
const { existsSync:
|
|
82699
|
-
const { homedir:
|
|
82700
|
-
const { join:
|
|
83034
|
+
const { existsSync: existsSync55 } = await import("node:fs");
|
|
83035
|
+
const { homedir: homedir7 } = await import("node:os");
|
|
83036
|
+
const { join: join27 } = await import("node:path");
|
|
82701
83037
|
const chromePaths = [
|
|
82702
83038
|
process.env.HYPERFRAMES_CHROME_PATH,
|
|
82703
83039
|
process.env.CHROME_PATH,
|
|
82704
|
-
|
|
82705
|
-
|
|
83040
|
+
join27(
|
|
83041
|
+
homedir7(),
|
|
82706
83042
|
".cache",
|
|
82707
83043
|
"puppeteer",
|
|
82708
83044
|
"chrome-headless-shell",
|
|
@@ -82716,7 +83052,7 @@ async function runDiagnostics() {
|
|
|
82716
83052
|
"/usr/bin/chromium",
|
|
82717
83053
|
"/usr/bin/chromium-browser"
|
|
82718
83054
|
];
|
|
82719
|
-
installed = chromePaths.some((p) => p &&
|
|
83055
|
+
installed = chromePaths.some((p) => p && existsSync55(p));
|
|
82720
83056
|
} else {
|
|
82721
83057
|
installed = commandExists(toolName);
|
|
82722
83058
|
}
|
|
@@ -82756,7 +83092,7 @@ async function runDiagnostics() {
|
|
|
82756
83092
|
}
|
|
82757
83093
|
const projectFiles = ["AGENTS.md", "CLAUDE.md", "vibe.project.yaml"].map((rel) => ({
|
|
82758
83094
|
path: rel,
|
|
82759
|
-
exists:
|
|
83095
|
+
exists: existsSync49(resolve67(cwd, rel))
|
|
82760
83096
|
}));
|
|
82761
83097
|
const projectInitialized = projectFiles.some((f) => f.exists);
|
|
82762
83098
|
const nearestProjectConfigPath = await findProjectConfigPath(cwd);
|
|
@@ -82775,8 +83111,8 @@ async function runDiagnostics() {
|
|
|
82775
83111
|
} catch (err) {
|
|
82776
83112
|
if (!(err instanceof ComposerResolveError)) throw err;
|
|
82777
83113
|
}
|
|
82778
|
-
const sceneProjectInCwd =
|
|
82779
|
-
const skillInstalled =
|
|
83114
|
+
const sceneProjectInCwd = existsSync49(resolve67(cwd, "STORYBOARD.md"));
|
|
83115
|
+
const skillInstalled = existsSync49(resolve67(cwd, "SKILL.md"));
|
|
82780
83116
|
return {
|
|
82781
83117
|
system: {
|
|
82782
83118
|
node: { version: nodeVersion, ok: true },
|
|
@@ -83123,6 +83459,198 @@ function pickNextStep(results, hasMissingProviders) {
|
|
|
83123
83459
|
return null;
|
|
83124
83460
|
}
|
|
83125
83461
|
|
|
83462
|
+
// src/commands/host.ts
|
|
83463
|
+
init_esm();
|
|
83464
|
+
init_source();
|
|
83465
|
+
init_exec_safe();
|
|
83466
|
+
init_cost_tier();
|
|
83467
|
+
import { resolve as resolve68 } from "node:path";
|
|
83468
|
+
init_output();
|
|
83469
|
+
var hostCommand = new Command("host").description("Set up Codex, Claude, and Cursor app integrations").addHelpText(
|
|
83470
|
+
"after",
|
|
83471
|
+
`
|
|
83472
|
+
Examples:
|
|
83473
|
+
$ vibe host list --json
|
|
83474
|
+
$ vibe host setup all Print MCP/project config snippets
|
|
83475
|
+
$ vibe host setup cursor --write Write .cursor/mcp.json
|
|
83476
|
+
$ vibe host doctor all --json Check host-app readiness
|
|
83477
|
+
`
|
|
83478
|
+
);
|
|
83479
|
+
hostCommand.command("list").description("List supported app hosts and integration surfaces").action(() => {
|
|
83480
|
+
const startedAt = Date.now();
|
|
83481
|
+
const hosts = hostDefinitions(resolve68(".")).map((host) => ({
|
|
83482
|
+
id: host.id,
|
|
83483
|
+
label: host.label,
|
|
83484
|
+
surfaces: host.surfaces,
|
|
83485
|
+
guidanceFiles: host.guidanceFiles,
|
|
83486
|
+
notes: host.notes
|
|
83487
|
+
}));
|
|
83488
|
+
if (isJsonMode()) {
|
|
83489
|
+
outputSuccess({ command: "host list", startedAt, data: { hosts } });
|
|
83490
|
+
return;
|
|
83491
|
+
}
|
|
83492
|
+
console.log();
|
|
83493
|
+
console.log(source_default.bold.cyan("Supported Host Apps"));
|
|
83494
|
+
console.log(source_default.dim("\u2500".repeat(60)));
|
|
83495
|
+
for (const host of hosts) {
|
|
83496
|
+
console.log(` ${source_default.bold(host.label)} ${source_default.dim(`(${host.id})`)}`);
|
|
83497
|
+
console.log(source_default.dim(` surfaces: ${host.surfaces.join(", ")}`));
|
|
83498
|
+
if (host.guidanceFiles.length > 0) {
|
|
83499
|
+
console.log(source_default.dim(` files: ${host.guidanceFiles.join(", ")}`));
|
|
83500
|
+
}
|
|
83501
|
+
}
|
|
83502
|
+
console.log();
|
|
83503
|
+
});
|
|
83504
|
+
applyTier(hostCommand.commands[hostCommand.commands.length - 1], "free");
|
|
83505
|
+
hostCommand.command("setup").description("Print or write Codex/Claude/Cursor MCP and project integration config").argument("[host]", `Host target: ${HOST_SELECTIONS.join(" | ")}`, "all").argument("[project-dir]", "Project directory for project-scoped config", ".").option("--write", "Write config files instead of printing snippets only").option("--dry-run", "Show file actions without writing").option("--force", "Replace an existing vibeframe MCP entry").action(async (hostArg, projectDirArg, options) => {
|
|
83506
|
+
const startedAt = Date.now();
|
|
83507
|
+
const selection = validateHostSelection(hostArg);
|
|
83508
|
+
const projectDir = resolve68(projectDirArg);
|
|
83509
|
+
const ids = resolveHostSelection(selection);
|
|
83510
|
+
const defs = hostDefinitions(projectDir).filter((host) => ids.includes(host.id));
|
|
83511
|
+
const plans = [];
|
|
83512
|
+
for (const host of defs) {
|
|
83513
|
+
plans.push(
|
|
83514
|
+
await planHostSetup(host, projectDir, {
|
|
83515
|
+
write: Boolean(options.write),
|
|
83516
|
+
dryRun: Boolean(options.dryRun),
|
|
83517
|
+
force: Boolean(options.force)
|
|
83518
|
+
})
|
|
83519
|
+
);
|
|
83520
|
+
}
|
|
83521
|
+
if (isJsonMode()) {
|
|
83522
|
+
outputSuccess({
|
|
83523
|
+
command: "host setup",
|
|
83524
|
+
startedAt,
|
|
83525
|
+
...options.dryRun ? { dryRun: true } : {},
|
|
83526
|
+
data: {
|
|
83527
|
+
projectDir,
|
|
83528
|
+
selection,
|
|
83529
|
+
write: Boolean(options.write),
|
|
83530
|
+
hosts: plans.map(serializeSetupPlan)
|
|
83531
|
+
},
|
|
83532
|
+
warnings: plans.flatMap((plan) => plan.warnings)
|
|
83533
|
+
});
|
|
83534
|
+
return;
|
|
83535
|
+
}
|
|
83536
|
+
printSetupPlans(plans, { write: Boolean(options.write), dryRun: Boolean(options.dryRun) });
|
|
83537
|
+
});
|
|
83538
|
+
applyTier(hostCommand.commands[hostCommand.commands.length - 1], "free");
|
|
83539
|
+
hostCommand.command("doctor").description("Check Codex/Claude/Cursor app integration readiness").argument("[host]", `Host target: ${HOST_SELECTIONS.join(" | ")}`, "all").argument("[project-dir]", "Project directory to inspect", ".").action(async (hostArg, projectDirArg) => {
|
|
83540
|
+
const startedAt = Date.now();
|
|
83541
|
+
const selection = validateHostSelection(hostArg);
|
|
83542
|
+
const projectDir = resolve68(projectDirArg);
|
|
83543
|
+
const ids = resolveHostSelection(selection);
|
|
83544
|
+
const defs = hostDefinitions(projectDir).filter((host) => ids.includes(host.id));
|
|
83545
|
+
const hosts = await Promise.all(defs.map((host) => inspectHost(host, projectDir)));
|
|
83546
|
+
const system = {
|
|
83547
|
+
vibe: commandExists("vibe"),
|
|
83548
|
+
npx: commandExists("npx")
|
|
83549
|
+
};
|
|
83550
|
+
const warnings = [
|
|
83551
|
+
...system.vibe ? [] : ["vibe binary not found on PATH"],
|
|
83552
|
+
...system.npx ? [] : ["npx not found on PATH; MCP stdio config needs npx"],
|
|
83553
|
+
...hosts.flatMap((host) => host.warnings)
|
|
83554
|
+
];
|
|
83555
|
+
if (isJsonMode()) {
|
|
83556
|
+
outputSuccess({
|
|
83557
|
+
command: "host doctor",
|
|
83558
|
+
startedAt,
|
|
83559
|
+
data: {
|
|
83560
|
+
projectDir,
|
|
83561
|
+
selection,
|
|
83562
|
+
system,
|
|
83563
|
+
hosts: hosts.map(serializeDoctorResult)
|
|
83564
|
+
},
|
|
83565
|
+
warnings
|
|
83566
|
+
});
|
|
83567
|
+
return;
|
|
83568
|
+
}
|
|
83569
|
+
printDoctor(hosts, system, warnings);
|
|
83570
|
+
});
|
|
83571
|
+
applyTier(hostCommand.commands[hostCommand.commands.length - 1], "free");
|
|
83572
|
+
function validateHostSelection(value) {
|
|
83573
|
+
if (HOST_SELECTIONS.includes(value)) return value;
|
|
83574
|
+
exitWithError(
|
|
83575
|
+
usageError(`Invalid host target: ${value}`, `Must be one of: ${HOST_SELECTIONS.join(", ")}`)
|
|
83576
|
+
);
|
|
83577
|
+
}
|
|
83578
|
+
function serializeSetupPlan(plan) {
|
|
83579
|
+
return {
|
|
83580
|
+
id: plan.host.id,
|
|
83581
|
+
label: plan.host.label,
|
|
83582
|
+
surfaces: plan.host.surfaces,
|
|
83583
|
+
configPath: plan.configPath,
|
|
83584
|
+
snippet: plan.snippet,
|
|
83585
|
+
...plan.command ? { command: plan.command } : {},
|
|
83586
|
+
files: plan.files,
|
|
83587
|
+
warnings: plan.warnings,
|
|
83588
|
+
nextSteps: plan.nextSteps
|
|
83589
|
+
};
|
|
83590
|
+
}
|
|
83591
|
+
function serializeDoctorResult(result) {
|
|
83592
|
+
return {
|
|
83593
|
+
id: result.host.id,
|
|
83594
|
+
label: result.host.label,
|
|
83595
|
+
surfaces: result.host.surfaces,
|
|
83596
|
+
configPath: result.configPath,
|
|
83597
|
+
configured: result.configured,
|
|
83598
|
+
guidanceFiles: result.guidanceFiles,
|
|
83599
|
+
warnings: result.warnings,
|
|
83600
|
+
nextSteps: result.nextSteps
|
|
83601
|
+
};
|
|
83602
|
+
}
|
|
83603
|
+
function printSetupPlans(plans, opts) {
|
|
83604
|
+
console.log();
|
|
83605
|
+
console.log(source_default.bold.cyan("VibeFrame Host Setup"));
|
|
83606
|
+
console.log(source_default.dim("\u2500".repeat(60)));
|
|
83607
|
+
if (!opts.write) {
|
|
83608
|
+
console.log(source_default.dim("Snippet mode \u2014 no files were changed. Pass --write to apply."));
|
|
83609
|
+
} else if (opts.dryRun) {
|
|
83610
|
+
console.log(source_default.dim("Dry run \u2014 no files were changed."));
|
|
83611
|
+
}
|
|
83612
|
+
for (const plan of plans) {
|
|
83613
|
+
console.log();
|
|
83614
|
+
console.log(source_default.bold(plan.host.label) + source_default.dim(` (${plan.host.id})`));
|
|
83615
|
+
console.log(source_default.dim(`Config: ${plan.configPath}`));
|
|
83616
|
+
if (plan.command) console.log(source_default.dim(`Command: ${plan.command}`));
|
|
83617
|
+
console.log();
|
|
83618
|
+
console.log(plan.snippet);
|
|
83619
|
+
if (plan.files.length > 0) {
|
|
83620
|
+
console.log();
|
|
83621
|
+
for (const file of plan.files) {
|
|
83622
|
+
console.log(` ${formatAction(file.status)} ${file.path}${file.reason ? source_default.dim(` ${file.reason}`) : ""}`);
|
|
83623
|
+
}
|
|
83624
|
+
}
|
|
83625
|
+
for (const warning of plan.warnings) console.log(source_default.yellow(` Warning: ${warning}`));
|
|
83626
|
+
}
|
|
83627
|
+
console.log();
|
|
83628
|
+
}
|
|
83629
|
+
function printDoctor(hosts, system, warnings) {
|
|
83630
|
+
console.log();
|
|
83631
|
+
console.log(source_default.bold.cyan("VibeFrame Host Doctor"));
|
|
83632
|
+
console.log(source_default.dim("\u2500".repeat(60)));
|
|
83633
|
+
console.log(` vibe: ${system.vibe ? source_default.green("OK") : source_default.red("MISSING")}`);
|
|
83634
|
+
console.log(` npx: ${system.npx ? source_default.green("OK") : source_default.red("MISSING")}`);
|
|
83635
|
+
console.log();
|
|
83636
|
+
for (const host of hosts) {
|
|
83637
|
+
console.log(source_default.bold(host.host.label) + source_default.dim(` (${host.host.id})`));
|
|
83638
|
+
console.log(` MCP config: ${host.configured ? source_default.green("OK") : source_default.yellow("missing")} ${source_default.dim(host.configPath)}`);
|
|
83639
|
+
for (const file of host.guidanceFiles) {
|
|
83640
|
+
const ok = file.status !== "missing";
|
|
83641
|
+
console.log(` ${ok ? source_default.green("OK") : source_default.yellow("MISSING")} ${source_default.dim(file.path)}`);
|
|
83642
|
+
}
|
|
83643
|
+
console.log();
|
|
83644
|
+
}
|
|
83645
|
+
for (const warning of warnings) console.log(source_default.yellow(`Warning: ${warning}`));
|
|
83646
|
+
}
|
|
83647
|
+
function formatAction(status) {
|
|
83648
|
+
if (status === "wrote" || status === "merged") return source_default.green("\u2713");
|
|
83649
|
+
if (status.startsWith("would")) return source_default.cyan("\u2192");
|
|
83650
|
+
if (status === "missing") return source_default.yellow("!");
|
|
83651
|
+
return source_default.dim("\u25CB");
|
|
83652
|
+
}
|
|
83653
|
+
|
|
83126
83654
|
// src/commands/demo.ts
|
|
83127
83655
|
init_esm();
|
|
83128
83656
|
init_source();
|
|
@@ -83131,10 +83659,10 @@ init_exec_safe();
|
|
|
83131
83659
|
init_detect();
|
|
83132
83660
|
init_ai_edit();
|
|
83133
83661
|
init_output();
|
|
83134
|
-
import { resolve as
|
|
83135
|
-
import { existsSync as
|
|
83136
|
-
import { mkdir as
|
|
83137
|
-
var DEMO_DIR =
|
|
83662
|
+
import { resolve as resolve69 } from "node:path";
|
|
83663
|
+
import { existsSync as existsSync50 } from "node:fs";
|
|
83664
|
+
import { mkdir as mkdir26, rm as rm4 } from "node:fs/promises";
|
|
83665
|
+
var DEMO_DIR = resolve69(process.cwd(), ".vibeframe-demo");
|
|
83138
83666
|
async function generateTestVideo(outputPath) {
|
|
83139
83667
|
const filter = [
|
|
83140
83668
|
// Video: color bars with text
|
|
@@ -83163,7 +83691,7 @@ async function generateTestVideo(outputPath) {
|
|
|
83163
83691
|
"-y",
|
|
83164
83692
|
outputPath
|
|
83165
83693
|
], { timeout: 3e4, maxBuffer: 50 * 1024 * 1024 });
|
|
83166
|
-
return
|
|
83694
|
+
return existsSync50(outputPath);
|
|
83167
83695
|
} catch {
|
|
83168
83696
|
try {
|
|
83169
83697
|
await execSafe("ffmpeg", [
|
|
@@ -83189,7 +83717,7 @@ async function generateTestVideo(outputPath) {
|
|
|
83189
83717
|
"-y",
|
|
83190
83718
|
outputPath
|
|
83191
83719
|
], { timeout: 3e4, maxBuffer: 50 * 1024 * 1024 });
|
|
83192
|
-
return
|
|
83720
|
+
return existsSync50(outputPath);
|
|
83193
83721
|
} catch {
|
|
83194
83722
|
return false;
|
|
83195
83723
|
}
|
|
@@ -83213,8 +83741,8 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83213
83741
|
console.log(source_default.dim(" " + "\u2500".repeat(50)));
|
|
83214
83742
|
console.log();
|
|
83215
83743
|
}
|
|
83216
|
-
await
|
|
83217
|
-
const testVideo =
|
|
83744
|
+
await mkdir26(DEMO_DIR, { recursive: true });
|
|
83745
|
+
const testVideo = resolve69(DEMO_DIR, "test-input.mp4");
|
|
83218
83746
|
const genSpinner = !isJson ? ora("Generating test video...").start() : null;
|
|
83219
83747
|
const generated = await generateTestVideo(testVideo);
|
|
83220
83748
|
if (!generated) {
|
|
@@ -83243,7 +83771,7 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83243
83771
|
name: "Silence Cut",
|
|
83244
83772
|
description: "Removing silent segments",
|
|
83245
83773
|
run: async () => {
|
|
83246
|
-
const output =
|
|
83774
|
+
const output = resolve69(DEMO_DIR, "silence-cut.mp4");
|
|
83247
83775
|
const r = await executeSilenceCut({ videoPath: testVideo, outputPath: output, padding: 0.1 });
|
|
83248
83776
|
if (r.success && r.totalDuration && r.silentDuration) {
|
|
83249
83777
|
return { success: true, detail: `Removed ${r.silentDuration.toFixed(1)}s silence (${r.totalDuration.toFixed(1)}s \u2192 ${(r.totalDuration - r.silentDuration).toFixed(1)}s)` };
|
|
@@ -83255,7 +83783,7 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83255
83783
|
name: "Noise Reduce",
|
|
83256
83784
|
description: "Reducing background noise",
|
|
83257
83785
|
run: async () => {
|
|
83258
|
-
const output =
|
|
83786
|
+
const output = resolve69(DEMO_DIR, "noise-reduced.mp4");
|
|
83259
83787
|
const r = await executeNoiseReduce({ inputPath: testVideo, outputPath: output, strength: "medium" });
|
|
83260
83788
|
return { success: r.success, detail: r.success ? `Cleaned audio \u2192 ${output}` : r.error };
|
|
83261
83789
|
}
|
|
@@ -83264,7 +83792,7 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83264
83792
|
name: "Fade Effects",
|
|
83265
83793
|
description: "Adding fade in/out",
|
|
83266
83794
|
run: async () => {
|
|
83267
|
-
const output =
|
|
83795
|
+
const output = resolve69(DEMO_DIR, "faded.mp4");
|
|
83268
83796
|
const r = await executeFade({ videoPath: testVideo, outputPath: output, fadeIn: 1, fadeOut: 1 });
|
|
83269
83797
|
return { success: r.success, detail: r.success ? `1s fade in + 1s fade out \u2192 ${output}` : r.error };
|
|
83270
83798
|
}
|
|
@@ -83331,20 +83859,20 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83331
83859
|
|
|
83332
83860
|
// src/commands/context.ts
|
|
83333
83861
|
init_esm();
|
|
83334
|
-
import { existsSync as
|
|
83335
|
-
import { readFile as
|
|
83336
|
-
import { resolve as
|
|
83862
|
+
import { existsSync as existsSync51 } from "node:fs";
|
|
83863
|
+
import { readFile as readFile45 } from "node:fs/promises";
|
|
83864
|
+
import { resolve as resolve70, dirname as dirname24 } from "node:path";
|
|
83337
83865
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
83338
83866
|
var __filename = fileURLToPath2(import.meta.url);
|
|
83339
|
-
var __dirname =
|
|
83867
|
+
var __dirname = dirname24(__filename);
|
|
83340
83868
|
function resolveContextPath(baseDir = __dirname) {
|
|
83341
83869
|
const candidates = [
|
|
83342
83870
|
// Bundled package layout: packages/cli/dist/index.js -> packages/cli/CONTEXT.md
|
|
83343
|
-
|
|
83871
|
+
resolve70(baseDir, "../CONTEXT.md"),
|
|
83344
83872
|
// Source/dev layout: packages/cli/src/commands/context.ts -> packages/cli/CONTEXT.md
|
|
83345
|
-
|
|
83873
|
+
resolve70(baseDir, "../../CONTEXT.md")
|
|
83346
83874
|
];
|
|
83347
|
-
return candidates.find((candidate) =>
|
|
83875
|
+
return candidates.find((candidate) => existsSync51(candidate)) ?? null;
|
|
83348
83876
|
}
|
|
83349
83877
|
var contextCommand = new Command("context").description("Print CLI context/guidelines for AI agent integration").option("--format <format>", "Output format: markdown | json", "markdown").action(async (_options, cmd) => {
|
|
83350
83878
|
const options = {
|
|
@@ -83434,7 +83962,7 @@ var contextCommand = new Command("context").description("Print CLI context/guide
|
|
|
83434
83962
|
try {
|
|
83435
83963
|
const contextPath = resolveContextPath();
|
|
83436
83964
|
if (!contextPath) throw new Error("CONTEXT.md not found");
|
|
83437
|
-
const content = await
|
|
83965
|
+
const content = await readFile45(contextPath, "utf-8");
|
|
83438
83966
|
console.log(
|
|
83439
83967
|
content.replace(
|
|
83440
83968
|
"## Mental model",
|
|
@@ -84376,7 +84904,7 @@ async function startAgent(options = {}) {
|
|
|
84376
84904
|
console.log();
|
|
84377
84905
|
console.log(source_default.dim(" Commands: exit \xB7 reset \xB7 tools \xB7 context"));
|
|
84378
84906
|
console.log();
|
|
84379
|
-
return new Promise((
|
|
84907
|
+
return new Promise((resolve83) => {
|
|
84380
84908
|
if (typeof process.stdin.ref === "function") {
|
|
84381
84909
|
process.stdin.ref();
|
|
84382
84910
|
}
|
|
@@ -84483,7 +85011,7 @@ async function startAgent(options = {}) {
|
|
|
84483
85011
|
clearInterval(keepalive);
|
|
84484
85012
|
console.log();
|
|
84485
85013
|
console.log(source_default.dim("Goodbye!"));
|
|
84486
|
-
|
|
85014
|
+
resolve83();
|
|
84487
85015
|
});
|
|
84488
85016
|
rl.prompt();
|
|
84489
85017
|
});
|
|
@@ -84756,8 +85284,8 @@ init_source();
|
|
|
84756
85284
|
init_config();
|
|
84757
85285
|
init_schema();
|
|
84758
85286
|
init_api_key();
|
|
84759
|
-
import { access as access9, writeFile as
|
|
84760
|
-
import { dirname as
|
|
85287
|
+
import { access as access9, writeFile as writeFile59, mkdir as mkdir29 } from "node:fs/promises";
|
|
85288
|
+
import { dirname as dirname26 } from "node:path";
|
|
84761
85289
|
var BANNER_SHOWN_PATH = `${USER_CONFIG_DIR}/.banner-shown`;
|
|
84762
85290
|
async function isFirstRun() {
|
|
84763
85291
|
try {
|
|
@@ -84776,8 +85304,8 @@ async function isFirstRun() {
|
|
|
84776
85304
|
}
|
|
84777
85305
|
async function markBannerShown() {
|
|
84778
85306
|
try {
|
|
84779
|
-
await
|
|
84780
|
-
await
|
|
85307
|
+
await mkdir29(dirname26(BANNER_SHOWN_PATH), { recursive: true });
|
|
85308
|
+
await writeFile59(BANNER_SHOWN_PATH, (/* @__PURE__ */ new Date()).toISOString());
|
|
84781
85309
|
} catch {
|
|
84782
85310
|
}
|
|
84783
85311
|
}
|
|
@@ -84912,6 +85440,7 @@ this section shows the typical entry points by use case):
|
|
|
84912
85440
|
vibe schema --list --surface public Compact first-run command catalog
|
|
84913
85441
|
vibe schema generate.video JSON schema for any command
|
|
84914
85442
|
vibe context Agent integration quickstart
|
|
85443
|
+
vibe host setup all Configure Codex/Claude/Cursor app integrations
|
|
84915
85444
|
vibe agent Optional built-in agent when you do not use Claude Code/Codex/etc.
|
|
84916
85445
|
|
|
84917
85446
|
Common-flag note: most commands accept --dry-run to preview cost/output
|
|
@@ -85013,6 +85542,7 @@ program2.addCommand(buildCommand);
|
|
|
85013
85542
|
program2.addCommand(renderCommand);
|
|
85014
85543
|
program2.addCommand(statusCommand);
|
|
85015
85544
|
program2.addCommand(doctorCommand);
|
|
85545
|
+
program2.addCommand(hostCommand);
|
|
85016
85546
|
program2.addCommand(demoCommand, { hidden: true });
|
|
85017
85547
|
program2.addCommand(runCommand);
|
|
85018
85548
|
program2.addCommand(agentCommand);
|