@vibeframe/cli 0.106.4 → 0.106.6
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 +1108 -512
- package/dist/tools/adapters/mcp.js +5 -1
- package/dist/tools/define-tool.js +1 -0
- package/dist/tools/manifest/index.js +57 -23
- 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,
|
|
@@ -67063,7 +67076,7 @@ function summariseLint(result) {
|
|
|
67063
67076
|
fixed: result.fixed
|
|
67064
67077
|
};
|
|
67065
67078
|
}
|
|
67066
|
-
var SCENE_PRESETS2, sceneStylesSchema, sceneStylesTool, sceneInitSchema, sceneInitTool, sceneAddSchema, sceneAddTool, sceneLintSchema, sceneLintTool, sceneRepairSchema, sceneRepairTool, sceneRenderSchema, sceneRenderTool, sceneBuildSchema, sceneBuildTool, sceneInstallSkillSchema, sceneInstallSkillTool, sceneComposePromptsSchema, sceneComposePromptsTool, sceneTools;
|
|
67079
|
+
var SCENE_PRESETS2, PROJECT_DIR_DESCRIPTION, INIT_DIR_DESCRIPTION, sceneStylesSchema, sceneStylesTool, sceneInitSchema, sceneInitTool, sceneAddSchema, sceneAddTool, sceneLintSchema, sceneLintTool, sceneRepairSchema, sceneRepairTool, sceneRenderSchema, sceneRenderTool, sceneBuildSchema, sceneBuildTool, sceneInstallSkillSchema, sceneInstallSkillTool, sceneComposePromptsSchema, sceneComposePromptsTool, sceneTools;
|
|
67067
67080
|
var init_scene2 = __esm({
|
|
67068
67081
|
"src/tools/manifest/scene.ts"() {
|
|
67069
67082
|
"use strict";
|
|
@@ -67086,6 +67099,8 @@ var init_scene2 = __esm({
|
|
|
67086
67099
|
"kinetic-type",
|
|
67087
67100
|
"product-shot"
|
|
67088
67101
|
];
|
|
67102
|
+
PROJECT_DIR_DESCRIPTION = "Project directory. Defaults to the surface's cwd; in MCP hosts, relative paths resolve under the configured server workspace.";
|
|
67103
|
+
INIT_DIR_DESCRIPTION = "Project directory to create. Prefer a project name or workspace-relative path; in MCP hosts, relative paths resolve under the configured server workspace. Do not use /tmp or /home/claude unless the user explicitly asks.";
|
|
67089
67104
|
sceneStylesSchema = external_exports.object({
|
|
67090
67105
|
name: external_exports.string().optional().describe("Style name or slug (e.g. 'Swiss Pulse', 'swiss-pulse'). Omit to list all 8.")
|
|
67091
67106
|
});
|
|
@@ -67145,7 +67160,7 @@ var init_scene2 = __esm({
|
|
|
67145
67160
|
}
|
|
67146
67161
|
});
|
|
67147
67162
|
sceneInitSchema = external_exports.object({
|
|
67148
|
-
dir: external_exports.string().describe(
|
|
67163
|
+
dir: external_exports.string().describe(INIT_DIR_DESCRIPTION),
|
|
67149
67164
|
name: external_exports.string().optional().describe("Project name. Defaults to the directory basename."),
|
|
67150
67165
|
aspect: external_exports.enum(["16:9", "9:16", "1:1", "4:5"]).optional().describe("Aspect ratio. Default 16:9."),
|
|
67151
67166
|
duration: external_exports.number().optional().describe("Default root composition duration in seconds. Default 10.")
|
|
@@ -67157,7 +67172,7 @@ var init_scene2 = __esm({
|
|
|
67157
67172
|
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
67173
|
schema: sceneInitSchema,
|
|
67159
67174
|
async execute(args, ctx) {
|
|
67160
|
-
const dir =
|
|
67175
|
+
const dir = resolve73(ctx.workingDirectory, args.dir);
|
|
67161
67176
|
const result = await scaffoldSceneProject({
|
|
67162
67177
|
dir,
|
|
67163
67178
|
name: args.name,
|
|
@@ -67192,7 +67207,7 @@ var init_scene2 = __esm({
|
|
|
67192
67207
|
visuals: external_exports.string().optional().describe("Image prompt \u2014 generates assets/scene-<id>.png via the configured image provider."),
|
|
67193
67208
|
headline: external_exports.string().optional().describe("Visible headline text. Defaults to the humanised scene name."),
|
|
67194
67209
|
kicker: external_exports.string().optional().describe("Small label above the headline (used by 'explainer' and 'product-shot' presets)."),
|
|
67195
|
-
projectDir: external_exports.string().optional().describe(
|
|
67210
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION),
|
|
67196
67211
|
insertInto: external_exports.string().optional().describe("Root composition file (relative to projectDir). Default 'index.html'."),
|
|
67197
67212
|
imageProvider: external_exports.enum(["gemini", "openai"]).optional().describe("Image provider for visuals. Default 'gemini'."),
|
|
67198
67213
|
voice: external_exports.string().optional().describe("ElevenLabs voice id or name."),
|
|
@@ -67207,7 +67222,7 @@ var init_scene2 = __esm({
|
|
|
67207
67222
|
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
67223
|
schema: sceneAddSchema,
|
|
67209
67224
|
async execute(args, ctx) {
|
|
67210
|
-
const projectDir = args.projectDir ?
|
|
67225
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67211
67226
|
const result = await executeSceneAdd({
|
|
67212
67227
|
name: args.name,
|
|
67213
67228
|
preset: args.preset ?? "simple",
|
|
@@ -67253,7 +67268,7 @@ var init_scene2 = __esm({
|
|
|
67253
67268
|
}
|
|
67254
67269
|
});
|
|
67255
67270
|
sceneLintSchema = external_exports.object({
|
|
67256
|
-
projectDir: external_exports.string().optional().describe(
|
|
67271
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION),
|
|
67257
67272
|
root: external_exports.string().optional().describe("Root composition file relative to projectDir. Default 'index.html'."),
|
|
67258
67273
|
fix: external_exports.boolean().optional().describe('Apply mechanical auto-fixes (currently: missing class="clip").')
|
|
67259
67274
|
});
|
|
@@ -67264,7 +67279,7 @@ var init_scene2 = __esm({
|
|
|
67264
67279
|
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
67280
|
schema: sceneLintSchema,
|
|
67266
67281
|
async execute(args, ctx) {
|
|
67267
|
-
const projectDir = args.projectDir ?
|
|
67282
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67268
67283
|
const result = await runProjectLint({
|
|
67269
67284
|
projectDir,
|
|
67270
67285
|
rootRel: args.root,
|
|
@@ -67290,7 +67305,7 @@ var init_scene2 = __esm({
|
|
|
67290
67305
|
}
|
|
67291
67306
|
});
|
|
67292
67307
|
sceneRepairSchema = external_exports.object({
|
|
67293
|
-
projectDir: external_exports.string().optional().describe(
|
|
67308
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION),
|
|
67294
67309
|
root: external_exports.string().optional().describe("Root composition file relative to projectDir. Default 'index.html'."),
|
|
67295
67310
|
dryRun: external_exports.boolean().optional().describe("Preview deterministic repairs without writing files.")
|
|
67296
67311
|
});
|
|
@@ -67301,7 +67316,7 @@ var init_scene2 = __esm({
|
|
|
67301
67316
|
description: "Apply deterministic mechanical scene repairs. Currently uses the safe lint auto-fix allow-list and never performs semantic creative rewrites.",
|
|
67302
67317
|
schema: sceneRepairSchema,
|
|
67303
67318
|
async execute(args, ctx) {
|
|
67304
|
-
const projectDir = args.projectDir ?
|
|
67319
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67305
67320
|
const result = await executeSceneRepair({
|
|
67306
67321
|
projectDir,
|
|
67307
67322
|
rootRel: args.root,
|
|
@@ -67319,7 +67334,7 @@ var init_scene2 = __esm({
|
|
|
67319
67334
|
}
|
|
67320
67335
|
});
|
|
67321
67336
|
sceneRenderSchema = external_exports.object({
|
|
67322
|
-
projectDir: external_exports.string().optional().describe(
|
|
67337
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION),
|
|
67323
67338
|
root: external_exports.string().optional().describe("Root composition file relative to projectDir. Default 'index.html'."),
|
|
67324
67339
|
beat: external_exports.string().optional().describe("Render only one storyboard beat using a temporary root."),
|
|
67325
67340
|
output: external_exports.string().optional().describe("Output file path (relative paths resolve against projectDir)."),
|
|
@@ -67335,7 +67350,7 @@ var init_scene2 = __esm({
|
|
|
67335
67350
|
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
67351
|
schema: sceneRenderSchema,
|
|
67337
67352
|
async execute(args, ctx) {
|
|
67338
|
-
const projectDir = args.projectDir ?
|
|
67353
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67339
67354
|
const result = await executeSceneRender({
|
|
67340
67355
|
projectDir,
|
|
67341
67356
|
root: args.root,
|
|
@@ -67374,7 +67389,7 @@ var init_scene2 = __esm({
|
|
|
67374
67389
|
});
|
|
67375
67390
|
sceneBuildSchema = external_exports.object({
|
|
67376
67391
|
projectDir: external_exports.string().optional().describe(
|
|
67377
|
-
"Project directory containing STORYBOARD.md, DESIGN.md, index.html. Defaults to the surface's cwd."
|
|
67392
|
+
"Project directory containing STORYBOARD.md, DESIGN.md, index.html. Defaults to the surface's cwd; in MCP hosts, relative paths resolve under the configured server workspace."
|
|
67378
67393
|
),
|
|
67379
67394
|
stage: external_exports.enum(["assets", "compose", "sync", "render", "all"]).optional().describe("Build stage to run. Default all."),
|
|
67380
67395
|
beat: external_exports.string().optional().describe("Restrict asset/compose work to one beat id."),
|
|
@@ -67409,7 +67424,7 @@ var init_scene2 = __esm({
|
|
|
67409
67424
|
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
67425
|
schema: sceneBuildSchema,
|
|
67411
67426
|
async execute(args, ctx) {
|
|
67412
|
-
const projectDir = args.projectDir ?
|
|
67427
|
+
const projectDir = args.projectDir ? resolve73(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
67413
67428
|
const result = await executeSceneBuild({
|
|
67414
67429
|
projectDir,
|
|
67415
67430
|
stage: args.stage,
|
|
@@ -67489,7 +67504,7 @@ var init_scene2 = __esm({
|
|
|
67489
67504
|
});
|
|
67490
67505
|
sceneInstallSkillSchema = external_exports.object({
|
|
67491
67506
|
projectDir: external_exports.string().describe(
|
|
67492
|
-
"Project directory containing STORYBOARD.md / DESIGN.md. Required to keep cross-host calls explicit
|
|
67507
|
+
"Project directory containing STORYBOARD.md / DESIGN.md. Required to keep cross-host calls explicit; in MCP hosts, relative paths resolve under the configured server workspace."
|
|
67493
67508
|
),
|
|
67494
67509
|
host: external_exports.enum(["claude-code", "cursor", "auto", "all"]).optional().describe(
|
|
67495
67510
|
"Host layout target. 'auto' (default) detects installed agent hosts; 'all' writes every layout; 'claude-code' / 'cursor' force a single host. Codex / Aider read the universal SKILL.md via AGENTS.md so don't need a host-specific layout."
|
|
@@ -67506,7 +67521,7 @@ var init_scene2 = __esm({
|
|
|
67506
67521
|
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
67522
|
schema: sceneInstallSkillSchema,
|
|
67508
67523
|
async execute(args, ctx) {
|
|
67509
|
-
const projectDir =
|
|
67524
|
+
const projectDir = resolve73(ctx.workingDirectory, args.projectDir);
|
|
67510
67525
|
const hostFlag = args.host ?? "auto";
|
|
67511
67526
|
const hosts = (() => {
|
|
67512
67527
|
if (hostFlag === "all") return ["all"];
|
|
@@ -67539,7 +67554,7 @@ var init_scene2 = __esm({
|
|
|
67539
67554
|
});
|
|
67540
67555
|
sceneComposePromptsSchema = external_exports.object({
|
|
67541
67556
|
projectDir: external_exports.string().describe(
|
|
67542
|
-
"Project directory containing STORYBOARD.md / DESIGN.md. Required to keep cross-host calls explicit."
|
|
67557
|
+
"Project directory containing STORYBOARD.md / DESIGN.md. Required to keep cross-host calls explicit; in MCP hosts, relative paths resolve under the configured server workspace."
|
|
67543
67558
|
),
|
|
67544
67559
|
beat: external_exports.string().optional().describe(
|
|
67545
67560
|
"Restrict the plan to a single beat by id (e.g. 'hook', '1'). Omit to emit every beat in the storyboard."
|
|
@@ -67552,7 +67567,7 @@ var init_scene2 = __esm({
|
|
|
67552
67567
|
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
67568
|
schema: sceneComposePromptsSchema,
|
|
67554
67569
|
async execute(args, ctx) {
|
|
67555
|
-
const projectDir =
|
|
67570
|
+
const projectDir = resolve73(ctx.workingDirectory, args.projectDir);
|
|
67556
67571
|
const result = await getComposePrompts({
|
|
67557
67572
|
projectDir,
|
|
67558
67573
|
beatId: args.beat
|
|
@@ -68180,14 +68195,14 @@ var init_edit = __esm({
|
|
|
68180
68195
|
});
|
|
68181
68196
|
|
|
68182
68197
|
// src/commands/ai-suggest-edit.ts
|
|
68183
|
-
import { readFile as
|
|
68184
|
-
import { resolve as
|
|
68198
|
+
import { readFile as readFile48, writeFile as writeFile52 } from "node:fs/promises";
|
|
68199
|
+
import { resolve as resolve74 } from "node:path";
|
|
68185
68200
|
async function executeSuggestEdit(options) {
|
|
68186
68201
|
try {
|
|
68187
68202
|
const apiKey = options.apiKey ?? process.env.GOOGLE_API_KEY;
|
|
68188
68203
|
if (!apiKey) return { success: false, error: "GOOGLE_API_KEY required for suggest" };
|
|
68189
|
-
const filePath =
|
|
68190
|
-
const content = await
|
|
68204
|
+
const filePath = resolve74(process.cwd(), options.projectPath);
|
|
68205
|
+
const content = await readFile48(filePath, "utf-8");
|
|
68191
68206
|
const data = JSON.parse(content);
|
|
68192
68207
|
const project = Project.fromJSON(data);
|
|
68193
68208
|
const gemini = new GeminiProvider();
|
|
@@ -68198,7 +68213,7 @@ async function executeSuggestEdit(options) {
|
|
|
68198
68213
|
const first = suggestions[0];
|
|
68199
68214
|
const applied = applySuggestion(project, first);
|
|
68200
68215
|
if (applied) {
|
|
68201
|
-
await
|
|
68216
|
+
await writeFile52(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
68202
68217
|
return {
|
|
68203
68218
|
success: true,
|
|
68204
68219
|
suggestions,
|
|
@@ -68227,8 +68242,8 @@ var init_ai_suggest_edit = __esm({
|
|
|
68227
68242
|
});
|
|
68228
68243
|
|
|
68229
68244
|
// src/tools/manifest/inspect.ts
|
|
68230
|
-
import { resolve as
|
|
68231
|
-
var inspectProjectTool, inspectRenderTool, analyzeMediaTool, analyzeVideoTool, analyzeReviewTool, analyzeSuggestTool, inspectTools;
|
|
68245
|
+
import { resolve as resolve75 } from "node:path";
|
|
68246
|
+
var PROJECT_DIR_DESCRIPTION2, inspectProjectTool, inspectRenderTool, analyzeMediaTool, analyzeVideoTool, analyzeReviewTool, analyzeSuggestTool, inspectTools;
|
|
68232
68247
|
var init_inspect = __esm({
|
|
68233
68248
|
"src/tools/manifest/inspect.ts"() {
|
|
68234
68249
|
"use strict";
|
|
@@ -68239,28 +68254,33 @@ var init_inspect = __esm({
|
|
|
68239
68254
|
init_ai_suggest_edit();
|
|
68240
68255
|
init_scene_inspect();
|
|
68241
68256
|
init_render_inspect();
|
|
68257
|
+
PROJECT_DIR_DESCRIPTION2 = "Project directory. Defaults to the surface's cwd; in MCP hosts, relative paths resolve under the configured server workspace.";
|
|
68242
68258
|
inspectProjectTool = defineTool({
|
|
68243
68259
|
name: "inspect_project",
|
|
68244
68260
|
category: "analyze",
|
|
68245
68261
|
cost: "free",
|
|
68246
68262
|
description: "Local project inspection: checks STORYBOARD.md, DESIGN.md, config, build-report, scene lint, composition files, and referenced assets. Writes review-report.json by default.",
|
|
68247
68263
|
schema: external_exports.object({
|
|
68248
|
-
projectDir: external_exports.string().optional().describe(
|
|
68264
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION2),
|
|
68249
68265
|
beat: external_exports.string().optional().describe("Inspect only one storyboard beat where beat-scoped checks apply."),
|
|
68250
68266
|
outputPath: external_exports.string().optional().describe("Optional review report path. Defaults to <project>/review-report.json."),
|
|
68251
68267
|
report: external_exports.boolean().optional().describe("Write review-report.json. Default true.")
|
|
68252
68268
|
}),
|
|
68253
68269
|
async execute(args, ctx) {
|
|
68254
|
-
const projectDir = args.projectDir ?
|
|
68270
|
+
const projectDir = args.projectDir ? resolve75(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68255
68271
|
const result = await inspectProject({
|
|
68256
68272
|
projectDir,
|
|
68257
68273
|
beatId: args.beat,
|
|
68258
|
-
outputPath: args.outputPath ?
|
|
68274
|
+
outputPath: args.outputPath ? resolve75(ctx.workingDirectory, args.outputPath) : void 0,
|
|
68259
68275
|
writeReport: args.report !== false
|
|
68260
68276
|
});
|
|
68261
68277
|
return {
|
|
68262
68278
|
success: result.status !== "fail",
|
|
68263
|
-
data:
|
|
68279
|
+
data: {
|
|
68280
|
+
...result,
|
|
68281
|
+
workingDirectory: ctx.workingDirectory,
|
|
68282
|
+
projectDir
|
|
68283
|
+
},
|
|
68264
68284
|
error: result.status === "fail" ? `${result.issues.filter((issue) => issue.severity === "error").length} project inspection error(s)` : void 0,
|
|
68265
68285
|
humanLines: [
|
|
68266
68286
|
`${result.status === "pass" ? "\u2705" : result.status === "warn" ? "\u26A0\uFE0F" : "\u274C"} Project inspection ${result.status} \u2014 score ${result.score}/100`,
|
|
@@ -68275,7 +68295,7 @@ var init_inspect = __esm({
|
|
|
68275
68295
|
cost: "low",
|
|
68276
68296
|
description: "Render inspection: runs cheap local video checks by default, optionally adds Gemini AI review with ai: true, and writes review-report.json by default.",
|
|
68277
68297
|
schema: external_exports.object({
|
|
68278
|
-
projectDir: external_exports.string().optional().describe(
|
|
68298
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION2),
|
|
68279
68299
|
beat: external_exports.string().optional().describe("Inspect a render for one storyboard beat."),
|
|
68280
68300
|
videoPath: external_exports.string().optional().describe("Rendered video path. Defaults to build-report outputPath or latest renders/* video."),
|
|
68281
68301
|
outputPath: external_exports.string().optional().describe("Optional review report path. Defaults to <project>/review-report.json."),
|
|
@@ -68285,20 +68305,24 @@ var init_inspect = __esm({
|
|
|
68285
68305
|
dryRun: external_exports.boolean().optional().describe("Preview resolved inputs without probing video or calling Gemini.")
|
|
68286
68306
|
}),
|
|
68287
68307
|
async execute(args, ctx) {
|
|
68288
|
-
const projectDir = args.projectDir ?
|
|
68308
|
+
const projectDir = args.projectDir ? resolve75(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68289
68309
|
if (args.dryRun) {
|
|
68290
68310
|
const result2 = await previewInspectRender({
|
|
68291
68311
|
projectDir,
|
|
68292
68312
|
beatId: args.beat,
|
|
68293
|
-
videoPath: args.videoPath ?
|
|
68294
|
-
outputPath: args.outputPath ?
|
|
68313
|
+
videoPath: args.videoPath ? resolve75(ctx.workingDirectory, args.videoPath) : void 0,
|
|
68314
|
+
outputPath: args.outputPath ? resolve75(ctx.workingDirectory, args.outputPath) : void 0,
|
|
68295
68315
|
writeReport: args.report !== false,
|
|
68296
68316
|
ai: args.ai === true,
|
|
68297
68317
|
model: args.model
|
|
68298
68318
|
});
|
|
68299
68319
|
return {
|
|
68300
68320
|
success: true,
|
|
68301
|
-
data:
|
|
68321
|
+
data: {
|
|
68322
|
+
...result2,
|
|
68323
|
+
workingDirectory: ctx.workingDirectory,
|
|
68324
|
+
projectDir
|
|
68325
|
+
},
|
|
68302
68326
|
humanLines: [
|
|
68303
68327
|
`Render inspection dry-run \u2014 ${result2.videoPath ? "render found" : "render missing"}`,
|
|
68304
68328
|
...result2.reportPath ? [`report: ${result2.reportPath}`] : []
|
|
@@ -68308,15 +68332,19 @@ var init_inspect = __esm({
|
|
|
68308
68332
|
const result = await inspectRender({
|
|
68309
68333
|
projectDir,
|
|
68310
68334
|
beatId: args.beat,
|
|
68311
|
-
videoPath: args.videoPath ?
|
|
68312
|
-
outputPath: args.outputPath ?
|
|
68335
|
+
videoPath: args.videoPath ? resolve75(ctx.workingDirectory, args.videoPath) : void 0,
|
|
68336
|
+
outputPath: args.outputPath ? resolve75(ctx.workingDirectory, args.outputPath) : void 0,
|
|
68313
68337
|
writeReport: args.report !== false,
|
|
68314
68338
|
ai: args.ai === true,
|
|
68315
68339
|
model: args.model
|
|
68316
68340
|
});
|
|
68317
68341
|
return {
|
|
68318
68342
|
success: result.status !== "fail",
|
|
68319
|
-
data:
|
|
68343
|
+
data: {
|
|
68344
|
+
...result,
|
|
68345
|
+
workingDirectory: ctx.workingDirectory,
|
|
68346
|
+
projectDir
|
|
68347
|
+
},
|
|
68320
68348
|
error: result.status === "fail" ? `${result.issues.filter((issue) => issue.severity === "error").length} render inspection error(s)` : void 0,
|
|
68321
68349
|
humanLines: [
|
|
68322
68350
|
`${result.status === "pass" ? "\u2705" : result.status === "warn" ? "\u26A0\uFE0F" : "\u274C"} Render inspection ${result.status} \u2014 score ${result.score}/100`,
|
|
@@ -68700,7 +68728,7 @@ var init_generate2 = __esm({
|
|
|
68700
68728
|
schema: external_exports.object({
|
|
68701
68729
|
description: external_exports.string().describe("Background description / image prompt."),
|
|
68702
68730
|
aspect: external_exports.enum(["16:9", "9:16", "1:1"]).optional().describe("Aspect ratio. Default '16:9'."),
|
|
68703
|
-
output: external_exports.string().optional().describe("Output PNG path. Relative paths resolve against the surface's cwd.")
|
|
68731
|
+
output: external_exports.string().optional().describe("Output PNG path. Relative paths resolve against the surface's cwd; in MCP hosts, that is the configured server workspace.")
|
|
68704
68732
|
}),
|
|
68705
68733
|
async execute(args) {
|
|
68706
68734
|
const result = await executeBackground(args);
|
|
@@ -68899,15 +68927,15 @@ var init_generate2 = __esm({
|
|
|
68899
68927
|
});
|
|
68900
68928
|
|
|
68901
68929
|
// src/tools/manifest/storyboard.ts
|
|
68902
|
-
import { existsSync as
|
|
68903
|
-
import { readFile as
|
|
68904
|
-
import { resolve as
|
|
68930
|
+
import { existsSync as existsSync54 } from "node:fs";
|
|
68931
|
+
import { readFile as readFile49, writeFile as writeFile53 } from "node:fs/promises";
|
|
68932
|
+
import { resolve as resolve76 } from "node:path";
|
|
68905
68933
|
async function readStoryboard2(projectDir) {
|
|
68906
|
-
const path2 =
|
|
68907
|
-
if (!
|
|
68908
|
-
return { path: path2, markdown: await
|
|
68934
|
+
const path2 = resolve76(projectDir, "STORYBOARD.md");
|
|
68935
|
+
if (!existsSync54(path2)) return null;
|
|
68936
|
+
return { path: path2, markdown: await readFile49(path2, "utf-8") };
|
|
68909
68937
|
}
|
|
68910
|
-
var projectDirSchema, storyboardListTool, storyboardValidateTool, storyboardGetTool, storyboardSetTool, storyboardMoveTool, storyboardReviseTool, planTool, storyboardTools;
|
|
68938
|
+
var PROJECT_DIR_DESCRIPTION3, projectDirSchema, storyboardListTool, storyboardValidateTool, storyboardGetTool, storyboardSetTool, storyboardMoveTool, storyboardReviseTool, planTool, storyboardTools;
|
|
68911
68939
|
var init_storyboard2 = __esm({
|
|
68912
68940
|
"src/tools/manifest/storyboard.ts"() {
|
|
68913
68941
|
"use strict";
|
|
@@ -68917,8 +68945,9 @@ var init_storyboard2 = __esm({
|
|
|
68917
68945
|
init_storyboard_edit();
|
|
68918
68946
|
init_storyboard_revise();
|
|
68919
68947
|
init_build_plan();
|
|
68948
|
+
PROJECT_DIR_DESCRIPTION3 = "Project directory. Defaults to the surface's cwd; in MCP hosts, relative paths resolve under the configured server workspace.";
|
|
68920
68949
|
projectDirSchema = external_exports.object({
|
|
68921
|
-
projectDir: external_exports.string().optional().describe(
|
|
68950
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3)
|
|
68922
68951
|
});
|
|
68923
68952
|
storyboardListTool = defineTool({
|
|
68924
68953
|
name: "storyboard_list",
|
|
@@ -68927,7 +68956,7 @@ var init_storyboard2 = __esm({
|
|
|
68927
68956
|
description: "List beats, ids, durations, and cue blocks from a project's STORYBOARD.md.",
|
|
68928
68957
|
schema: projectDirSchema,
|
|
68929
68958
|
async execute(args, ctx) {
|
|
68930
|
-
const projectDir = args.projectDir ?
|
|
68959
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68931
68960
|
const file = await readStoryboard2(projectDir);
|
|
68932
68961
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
68933
68962
|
const parsed = parseStoryboard(file.markdown);
|
|
@@ -68953,7 +68982,7 @@ var init_storyboard2 = __esm({
|
|
|
68953
68982
|
description: "Validate STORYBOARD.md beat ids and cue blocks.",
|
|
68954
68983
|
schema: projectDirSchema,
|
|
68955
68984
|
async execute(args, ctx) {
|
|
68956
|
-
const projectDir = args.projectDir ?
|
|
68985
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68957
68986
|
const file = await readStoryboard2(projectDir);
|
|
68958
68987
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
68959
68988
|
const result = validateStoryboardMarkdown(file.markdown);
|
|
@@ -68982,11 +69011,11 @@ var init_storyboard2 = __esm({
|
|
|
68982
69011
|
cost: "free",
|
|
68983
69012
|
description: "Return one STORYBOARD.md beat as structured data.",
|
|
68984
69013
|
schema: external_exports.object({
|
|
68985
|
-
projectDir: external_exports.string().optional().describe(
|
|
69014
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
|
|
68986
69015
|
beat: external_exports.string().describe("Beat id to return.")
|
|
68987
69016
|
}),
|
|
68988
69017
|
async execute(args, ctx) {
|
|
68989
|
-
const projectDir = args.projectDir ?
|
|
69018
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68990
69019
|
const file = await readStoryboard2(projectDir);
|
|
68991
69020
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
68992
69021
|
const beat = getStoryboardBeat(file.markdown, args.beat);
|
|
@@ -69004,7 +69033,7 @@ var init_storyboard2 = __esm({
|
|
|
69004
69033
|
cost: "free",
|
|
69005
69034
|
description: "Set or unset one cue on one beat in STORYBOARD.md.",
|
|
69006
69035
|
schema: external_exports.object({
|
|
69007
|
-
projectDir: external_exports.string().optional().describe(
|
|
69036
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
|
|
69008
69037
|
beat: external_exports.string().describe("Beat id to mutate."),
|
|
69009
69038
|
key: external_exports.string().describe("Cue key to set."),
|
|
69010
69039
|
value: external_exports.string().optional().describe("Cue value. Required unless unset is true."),
|
|
@@ -69012,7 +69041,7 @@ var init_storyboard2 = __esm({
|
|
|
69012
69041
|
unset: external_exports.boolean().optional().describe("Remove the cue key.")
|
|
69013
69042
|
}),
|
|
69014
69043
|
async execute(args, ctx) {
|
|
69015
|
-
const projectDir = args.projectDir ?
|
|
69044
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
69016
69045
|
const file = await readStoryboard2(projectDir);
|
|
69017
69046
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
69018
69047
|
try {
|
|
@@ -69023,7 +69052,7 @@ var init_storyboard2 = __esm({
|
|
|
69023
69052
|
value,
|
|
69024
69053
|
unset: args.unset
|
|
69025
69054
|
});
|
|
69026
|
-
await
|
|
69055
|
+
await writeFile53(file.path, next, "utf-8");
|
|
69027
69056
|
return {
|
|
69028
69057
|
success: true,
|
|
69029
69058
|
data: { beat: args.beat, key: args.key },
|
|
@@ -69040,12 +69069,12 @@ var init_storyboard2 = __esm({
|
|
|
69040
69069
|
cost: "free",
|
|
69041
69070
|
description: "Move one beat after another beat in STORYBOARD.md.",
|
|
69042
69071
|
schema: external_exports.object({
|
|
69043
|
-
projectDir: external_exports.string().optional().describe(
|
|
69072
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
|
|
69044
69073
|
beat: external_exports.string().describe("Beat id to move."),
|
|
69045
69074
|
after: external_exports.string().describe("Beat id that should precede the moved beat.")
|
|
69046
69075
|
}),
|
|
69047
69076
|
async execute(args, ctx) {
|
|
69048
|
-
const projectDir = args.projectDir ?
|
|
69077
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
69049
69078
|
const file = await readStoryboard2(projectDir);
|
|
69050
69079
|
if (!file) return { success: false, error: `STORYBOARD.md not found in ${projectDir}` };
|
|
69051
69080
|
try {
|
|
@@ -69053,7 +69082,7 @@ var init_storyboard2 = __esm({
|
|
|
69053
69082
|
beatId: args.beat,
|
|
69054
69083
|
afterBeatId: args.after
|
|
69055
69084
|
});
|
|
69056
|
-
await
|
|
69085
|
+
await writeFile53(file.path, next, "utf-8");
|
|
69057
69086
|
return {
|
|
69058
69087
|
success: true,
|
|
69059
69088
|
data: { beat: args.beat, after: args.after },
|
|
@@ -69070,14 +69099,14 @@ var init_storyboard2 = __esm({
|
|
|
69070
69099
|
cost: "low",
|
|
69071
69100
|
description: "Revise an existing STORYBOARD.md from a natural-language request. Reads project context, validates the revised storyboard, and writes unless dryRun is true.",
|
|
69072
69101
|
schema: external_exports.object({
|
|
69073
|
-
projectDir: external_exports.string().optional().describe(
|
|
69102
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
|
|
69074
69103
|
request: external_exports.string().describe("Revision request, e.g. 'make the hook punchier and shorten to 30 seconds'."),
|
|
69075
69104
|
durationSec: external_exports.number().optional().describe("Target total duration in seconds."),
|
|
69076
69105
|
composer: external_exports.enum(["claude", "openai", "gemini"]).optional().describe("Revision LLM provider. Defaults to project config or available API keys."),
|
|
69077
69106
|
dryRun: external_exports.boolean().optional().describe("Preview the revised storyboard without writing.")
|
|
69078
69107
|
}),
|
|
69079
69108
|
async execute(args, ctx) {
|
|
69080
|
-
const projectDir = args.projectDir ?
|
|
69109
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
69081
69110
|
const result = await executeStoryboardRevision({
|
|
69082
69111
|
projectDir,
|
|
69083
69112
|
request: args.request,
|
|
@@ -69101,7 +69130,7 @@ var init_storyboard2 = __esm({
|
|
|
69101
69130
|
cost: "free",
|
|
69102
69131
|
description: "Read STORYBOARD.md and return the build plan, missing artifacts, provider needs, and estimated cost.",
|
|
69103
69132
|
schema: external_exports.object({
|
|
69104
|
-
projectDir: external_exports.string().optional().describe(
|
|
69133
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
|
|
69105
69134
|
stage: external_exports.enum(["assets", "compose", "sync", "render", "all"]).optional().describe("Stage to plan. Default all."),
|
|
69106
69135
|
beat: external_exports.string().optional().describe("Restrict the plan to one beat id."),
|
|
69107
69136
|
mode: external_exports.enum(["agent", "batch", "auto"]).optional().describe("Build mode. Default auto."),
|
|
@@ -69120,7 +69149,7 @@ var init_storyboard2 = __esm({
|
|
|
69120
69149
|
force: external_exports.boolean().optional().describe("Plan regeneration even when outputs exist.")
|
|
69121
69150
|
}),
|
|
69122
69151
|
async execute(args, ctx) {
|
|
69123
|
-
const projectDir = args.projectDir ?
|
|
69152
|
+
const projectDir = args.projectDir ? resolve76(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
69124
69153
|
const plan = await createBuildPlan({
|
|
69125
69154
|
projectDir,
|
|
69126
69155
|
stage: args.stage,
|
|
@@ -69163,9 +69192,9 @@ var init_storyboard2 = __esm({
|
|
|
69163
69192
|
});
|
|
69164
69193
|
|
|
69165
69194
|
// src/tools/manifest/remix.ts
|
|
69166
|
-
import { writeFile as
|
|
69195
|
+
import { writeFile as writeFile54 } from "node:fs/promises";
|
|
69167
69196
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
69168
|
-
import { join as
|
|
69197
|
+
import { join as join25 } from "node:path";
|
|
69169
69198
|
var pipelineHighlightsTool, pipelineAutoShortsTool, pipelineRunTool, pipelineRegenerateSceneTool, remixTools;
|
|
69170
69199
|
var init_remix = __esm({
|
|
69171
69200
|
"src/tools/manifest/remix.ts"() {
|
|
@@ -69273,8 +69302,8 @@ var init_remix = __esm({
|
|
|
69273
69302
|
let resolvedPath = args.pipelinePath;
|
|
69274
69303
|
let tempPath;
|
|
69275
69304
|
if (args.pipelineYaml) {
|
|
69276
|
-
tempPath =
|
|
69277
|
-
await
|
|
69305
|
+
tempPath = join25(tmpdir4(), `vibe-mcp-pipeline-${Date.now()}.yaml`);
|
|
69306
|
+
await writeFile54(tempPath, args.pipelineYaml, "utf-8");
|
|
69278
69307
|
resolvedPath = tempPath;
|
|
69279
69308
|
}
|
|
69280
69309
|
try {
|
|
@@ -69441,15 +69470,15 @@ var init_detect2 = __esm({
|
|
|
69441
69470
|
});
|
|
69442
69471
|
|
|
69443
69472
|
// src/tools/manifest/_project-io.ts
|
|
69444
|
-
import { readFile as
|
|
69473
|
+
import { readFile as readFile50, writeFile as writeFile55 } from "node:fs/promises";
|
|
69445
69474
|
async function loadProject2(projectPath, cwd) {
|
|
69446
69475
|
const absPath = await resolveTimelineFile(projectPath, cwd);
|
|
69447
|
-
const content = await
|
|
69476
|
+
const content = await readFile50(absPath, "utf-8");
|
|
69448
69477
|
const data = JSON.parse(content);
|
|
69449
69478
|
return { project: Project.fromJSON(data), absPath };
|
|
69450
69479
|
}
|
|
69451
69480
|
async function saveProject(absPath, project) {
|
|
69452
|
-
await
|
|
69481
|
+
await writeFile55(absPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
69453
69482
|
}
|
|
69454
69483
|
var init_project_io = __esm({
|
|
69455
69484
|
"src/tools/manifest/_project-io.ts"() {
|
|
@@ -69460,8 +69489,8 @@ var init_project_io = __esm({
|
|
|
69460
69489
|
});
|
|
69461
69490
|
|
|
69462
69491
|
// src/tools/manifest/timeline.ts
|
|
69463
|
-
import { mkdir as
|
|
69464
|
-
import { basename as basename23, resolve as
|
|
69492
|
+
import { mkdir as mkdir28, writeFile as writeFile56 } from "node:fs/promises";
|
|
69493
|
+
import { basename as basename23, resolve as resolve77 } from "node:path";
|
|
69465
69494
|
var MEDIA_TYPES, timelineCreateTool, timelineInfoTool, timelineAddSourceTool, timelineAddClipTool, timelineSplitClipTool, timelineTrimClipTool, timelineMoveClipTool, timelineDeleteClipTool, timelineDuplicateClipTool, timelineAddEffectTool, timelineAddTrackTool, timelineListTool, timelineTools;
|
|
69466
69495
|
var init_timeline = __esm({
|
|
69467
69496
|
"src/tools/manifest/timeline.ts"() {
|
|
@@ -69497,18 +69526,18 @@ var init_timeline = __esm({
|
|
|
69497
69526
|
fps: external_exports.number().optional().describe("Frames per second (default: 30)")
|
|
69498
69527
|
}),
|
|
69499
69528
|
async execute(args, ctx) {
|
|
69500
|
-
const projectName = args.name === "." ? basename23(ctx.workingDirectory) : basename23(
|
|
69529
|
+
const projectName = args.name === "." ? basename23(ctx.workingDirectory) : basename23(resolve77(ctx.workingDirectory, args.name));
|
|
69501
69530
|
const project = new Project(projectName);
|
|
69502
69531
|
if (args.fps) project.setFrameRate(args.fps);
|
|
69503
69532
|
let outputPath;
|
|
69504
69533
|
if (args.outputPath) {
|
|
69505
|
-
outputPath =
|
|
69534
|
+
outputPath = resolve77(ctx.workingDirectory, args.outputPath);
|
|
69506
69535
|
} else {
|
|
69507
|
-
const dirPath =
|
|
69508
|
-
await
|
|
69509
|
-
outputPath =
|
|
69536
|
+
const dirPath = resolve77(ctx.workingDirectory, args.name);
|
|
69537
|
+
await mkdir28(dirPath, { recursive: true });
|
|
69538
|
+
outputPath = resolve77(dirPath, TIMELINE_FILENAME);
|
|
69510
69539
|
}
|
|
69511
|
-
await
|
|
69540
|
+
await writeFile56(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
69512
69541
|
return {
|
|
69513
69542
|
success: true,
|
|
69514
69543
|
data: { name: projectName, outputPath },
|
|
@@ -69556,7 +69585,7 @@ var init_timeline = __esm({
|
|
|
69556
69585
|
}),
|
|
69557
69586
|
async execute(args, ctx) {
|
|
69558
69587
|
const { project, absPath } = await loadProject2(args.projectPath, ctx.workingDirectory);
|
|
69559
|
-
const mediaPath =
|
|
69588
|
+
const mediaPath = resolve77(ctx.workingDirectory, args.mediaPath);
|
|
69560
69589
|
const ext = mediaPath.split(".").pop()?.toLowerCase() ?? "";
|
|
69561
69590
|
const source = project.addSource({
|
|
69562
69591
|
name: args.name ?? mediaPath.split("/").pop() ?? "media",
|
|
@@ -69784,8 +69813,8 @@ var init_timeline = __esm({
|
|
|
69784
69813
|
});
|
|
69785
69814
|
|
|
69786
69815
|
// src/tools/manifest/project.ts
|
|
69787
|
-
import { resolve as
|
|
69788
|
-
import { writeFile as
|
|
69816
|
+
import { resolve as resolve78 } from "node:path";
|
|
69817
|
+
import { writeFile as writeFile57 } from "node:fs/promises";
|
|
69789
69818
|
var projectCreateTool, projectInfoTool, projectTools;
|
|
69790
69819
|
var init_project2 = __esm({
|
|
69791
69820
|
"src/tools/manifest/project.ts"() {
|
|
@@ -69807,10 +69836,10 @@ var init_project2 = __esm({
|
|
|
69807
69836
|
fps: external_exports.number().optional().describe("Frames per second (default: 30)")
|
|
69808
69837
|
}),
|
|
69809
69838
|
async execute(args, ctx) {
|
|
69810
|
-
const outputPath =
|
|
69839
|
+
const outputPath = resolve78(ctx.workingDirectory, args.outputPath ?? `${args.name}.vibe.json`);
|
|
69811
69840
|
const project = new Project(args.name);
|
|
69812
69841
|
if (args.fps) project.setFrameRate(args.fps);
|
|
69813
|
-
await
|
|
69842
|
+
await writeFile57(outputPath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
69814
69843
|
return {
|
|
69815
69844
|
success: true,
|
|
69816
69845
|
data: { name: args.name, outputPath },
|
|
@@ -69853,8 +69882,8 @@ var init_project2 = __esm({
|
|
|
69853
69882
|
});
|
|
69854
69883
|
|
|
69855
69884
|
// src/commands/export.ts
|
|
69856
|
-
import { readFile as
|
|
69857
|
-
import { resolve as
|
|
69885
|
+
import { readFile as readFile51, access as access7 } from "node:fs/promises";
|
|
69886
|
+
import { resolve as resolve79, basename as basename24 } from "node:path";
|
|
69858
69887
|
import { spawn as spawn3 } from "node:child_process";
|
|
69859
69888
|
function timelineBaseName(path2) {
|
|
69860
69889
|
const name = basename24(path2);
|
|
@@ -69922,7 +69951,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
69922
69951
|
};
|
|
69923
69952
|
}
|
|
69924
69953
|
const filePath = await resolveTimelineFile(projectPath);
|
|
69925
|
-
const content = await
|
|
69954
|
+
const content = await readFile51(filePath, "utf-8");
|
|
69926
69955
|
const data = JSON.parse(content);
|
|
69927
69956
|
const project = Project.fromJSON(data);
|
|
69928
69957
|
const summary = project.getSummary();
|
|
@@ -69932,7 +69961,7 @@ async function runExport(projectPath, outputPath, options = {}) {
|
|
|
69932
69961
|
message: "Project has no clips to export"
|
|
69933
69962
|
};
|
|
69934
69963
|
}
|
|
69935
|
-
const finalOutputPath =
|
|
69964
|
+
const finalOutputPath = resolve79(process.cwd(), outputPath);
|
|
69936
69965
|
const basePresetSettings = getPresetSettings(preset, summary.aspectRatio);
|
|
69937
69966
|
const presetSettings = applyCustomOverrides(basePresetSettings, { bitrate, fps, resolution, codec });
|
|
69938
69967
|
const clips = project.getClips().sort((a, b) => a.startTime - b.startTime);
|
|
@@ -70328,7 +70357,7 @@ function buildFFmpegArgs(clips, sources, presetSettings, outputPath, options, so
|
|
|
70328
70357
|
return args;
|
|
70329
70358
|
}
|
|
70330
70359
|
function runFFmpegProcess(ffmpegPath, args, onProgress) {
|
|
70331
|
-
return new Promise((
|
|
70360
|
+
return new Promise((resolve83, reject) => {
|
|
70332
70361
|
const ffmpeg = spawn3(ffmpegPath, args, {
|
|
70333
70362
|
stdio: ["pipe", "pipe", "pipe"]
|
|
70334
70363
|
});
|
|
@@ -70352,7 +70381,7 @@ function runFFmpegProcess(ffmpegPath, args, onProgress) {
|
|
|
70352
70381
|
});
|
|
70353
70382
|
ffmpeg.on("close", (code) => {
|
|
70354
70383
|
if (code === 0) {
|
|
70355
|
-
|
|
70384
|
+
resolve83();
|
|
70356
70385
|
} else {
|
|
70357
70386
|
const errorMatch = stderr.match(/Error.*$/m);
|
|
70358
70387
|
const errorMsg = errorMatch ? errorMatch[0] : `FFmpeg exited with code ${code}`;
|
|
@@ -70488,17 +70517,17 @@ function getPresetSettings(preset, aspectRatio2) {
|
|
|
70488
70517
|
}
|
|
70489
70518
|
async function runHyperframesExport(projectPath, options, spinner2, startedAt) {
|
|
70490
70519
|
spinner2.text = "Loading project...";
|
|
70491
|
-
const { readFile:
|
|
70492
|
-
const { resolve:
|
|
70520
|
+
const { readFile: readFile53 } = await import("node:fs/promises");
|
|
70521
|
+
const { resolve: resolve83 } = await import("node:path");
|
|
70493
70522
|
const { Project: Project2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
|
|
70494
70523
|
const { createHyperframesBackend: createHyperframesBackend2 } = await Promise.resolve().then(() => (init_hyperframes(), hyperframes_exports));
|
|
70495
70524
|
const { exitWithError: exitWithError2, generalError: generalError2, outputSuccess: outputSuccess2 } = await Promise.resolve().then(() => (init_output(), output_exports));
|
|
70496
70525
|
const chalk2 = (await Promise.resolve().then(() => (init_source(), source_exports))).default;
|
|
70497
70526
|
const filePath = await resolveTimelineFile(projectPath);
|
|
70498
|
-
const content = await
|
|
70527
|
+
const content = await readFile53(filePath, "utf-8");
|
|
70499
70528
|
const project = Project2.fromJSON(JSON.parse(content));
|
|
70500
70529
|
const state = project.getState();
|
|
70501
|
-
const outputPath = options.output ?
|
|
70530
|
+
const outputPath = options.output ? resolve83(process.cwd(), options.output) : resolve83(process.cwd(), `${timelineBaseName(projectPath)}.${options.format ?? "mp4"}`);
|
|
70502
70531
|
const quality = ["draft", "standard", "high"].includes(options.preset ?? "") ? options.preset : "standard";
|
|
70503
70532
|
const backend = createHyperframesBackend2();
|
|
70504
70533
|
spinner2.text = "Rendering with Hyperframes...";
|
|
@@ -70617,7 +70646,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
70617
70646
|
}
|
|
70618
70647
|
spinner2.text = "Loading project...";
|
|
70619
70648
|
const filePath = await resolveTimelineFile(projectPath);
|
|
70620
|
-
const content = await
|
|
70649
|
+
const content = await readFile51(filePath, "utf-8");
|
|
70621
70650
|
const data = JSON.parse(content);
|
|
70622
70651
|
const project = Project.fromJSON(data);
|
|
70623
70652
|
const summary = project.getSummary();
|
|
@@ -70625,7 +70654,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
70625
70654
|
spinner2.fail("Project has no clips to export");
|
|
70626
70655
|
exitWithError(usageError("Project has no clips to export"));
|
|
70627
70656
|
}
|
|
70628
|
-
const outputPath = options.output ?
|
|
70657
|
+
const outputPath = options.output ? resolve79(process.cwd(), options.output) : resolve79(
|
|
70629
70658
|
process.cwd(),
|
|
70630
70659
|
`${timelineBaseName(projectPath)}.${options.format}`
|
|
70631
70660
|
);
|
|
@@ -70709,7 +70738,7 @@ Run 'vibe schema export' for structured parameter info.`).action(async (projectP
|
|
|
70709
70738
|
});
|
|
70710
70739
|
|
|
70711
70740
|
// src/tools/manifest/export.ts
|
|
70712
|
-
import { resolve as
|
|
70741
|
+
import { resolve as resolve80 } from "node:path";
|
|
70713
70742
|
var exportVideoTool, exportTools;
|
|
70714
70743
|
var init_export2 = __esm({
|
|
70715
70744
|
"src/tools/manifest/export.ts"() {
|
|
@@ -70730,8 +70759,8 @@ var init_export2 = __esm({
|
|
|
70730
70759
|
overwrite: external_exports.boolean().optional().describe("Overwrite existing output file (default: false)")
|
|
70731
70760
|
}),
|
|
70732
70761
|
async execute(args, ctx) {
|
|
70733
|
-
const projectPath =
|
|
70734
|
-
const outputPath =
|
|
70762
|
+
const projectPath = resolve80(ctx.workingDirectory, args.projectPath);
|
|
70763
|
+
const outputPath = resolve80(ctx.workingDirectory, args.outputPath);
|
|
70735
70764
|
const result = await runExport(projectPath, outputPath, {
|
|
70736
70765
|
preset: args.preset,
|
|
70737
70766
|
format: args.format,
|
|
@@ -70750,8 +70779,8 @@ var init_export2 = __esm({
|
|
|
70750
70779
|
});
|
|
70751
70780
|
|
|
70752
70781
|
// src/tools/manifest/agent-only.ts
|
|
70753
|
-
import { readFile as
|
|
70754
|
-
import { resolve as
|
|
70782
|
+
import { readFile as readFile52, writeFile as writeFile58, readdir as readdir7, stat as stat9, access as access8, unlink as unlink4 } from "node:fs/promises";
|
|
70783
|
+
import { resolve as resolve81, join as join26, basename as basename25, extname as extname16 } from "node:path";
|
|
70755
70784
|
function matchPattern(filename, pattern) {
|
|
70756
70785
|
const regex2 = new RegExp(
|
|
70757
70786
|
"^" + pattern.replace(/\./g, "\\.").replace(/\*/g, ".*").replace(/\?/g, ".") + "$",
|
|
@@ -70829,12 +70858,12 @@ var init_agent_only = __esm({
|
|
|
70829
70858
|
async execute(args, ctx) {
|
|
70830
70859
|
const dirPath = args.path ?? ".";
|
|
70831
70860
|
try {
|
|
70832
|
-
const absPath =
|
|
70861
|
+
const absPath = resolve81(ctx.workingDirectory, dirPath);
|
|
70833
70862
|
const entries = await readdir7(absPath, { withFileTypes: true });
|
|
70834
70863
|
const results = [];
|
|
70835
70864
|
for (const entry of entries) {
|
|
70836
70865
|
if (args.pattern && !matchPattern(entry.name, args.pattern)) continue;
|
|
70837
|
-
const fullPath =
|
|
70866
|
+
const fullPath = join26(absPath, entry.name);
|
|
70838
70867
|
const stats = await stat9(fullPath);
|
|
70839
70868
|
if (entry.isDirectory()) {
|
|
70840
70869
|
results.push(`[DIR] ${entry.name}/`);
|
|
@@ -70860,8 +70889,8 @@ var init_agent_only = __esm({
|
|
|
70860
70889
|
}),
|
|
70861
70890
|
async execute(args, ctx) {
|
|
70862
70891
|
try {
|
|
70863
|
-
const absPath =
|
|
70864
|
-
const content = await
|
|
70892
|
+
const absPath = resolve81(ctx.workingDirectory, args.path);
|
|
70893
|
+
const content = await readFile52(absPath, "utf-8");
|
|
70865
70894
|
const maxLength = 4e3;
|
|
70866
70895
|
const truncated = content.length > maxLength;
|
|
70867
70896
|
const output = truncated ? content.substring(0, maxLength) + "\n... (truncated)" : content;
|
|
@@ -70883,8 +70912,8 @@ var init_agent_only = __esm({
|
|
|
70883
70912
|
}),
|
|
70884
70913
|
async execute(args, ctx) {
|
|
70885
70914
|
try {
|
|
70886
|
-
const absPath =
|
|
70887
|
-
await
|
|
70915
|
+
const absPath = resolve81(ctx.workingDirectory, args.path);
|
|
70916
|
+
await writeFile58(absPath, args.content, "utf-8");
|
|
70888
70917
|
return { success: true, data: { bytes: args.content.length }, humanLines: [`File written: ${args.path} (${formatSize(args.content.length)})`] };
|
|
70889
70918
|
} catch (error) {
|
|
70890
70919
|
return { success: false, error: `Failed to write file: ${error instanceof Error ? error.message : String(error)}` };
|
|
@@ -70901,7 +70930,7 @@ var init_agent_only = __esm({
|
|
|
70901
70930
|
path: external_exports.string().describe("Path to check")
|
|
70902
70931
|
}),
|
|
70903
70932
|
async execute(args, ctx) {
|
|
70904
|
-
const absPath =
|
|
70933
|
+
const absPath = resolve81(ctx.workingDirectory, args.path);
|
|
70905
70934
|
try {
|
|
70906
70935
|
await access8(absPath);
|
|
70907
70936
|
const stats = await stat9(absPath);
|
|
@@ -70927,11 +70956,11 @@ var init_agent_only = __esm({
|
|
|
70927
70956
|
}),
|
|
70928
70957
|
async execute(args, ctx) {
|
|
70929
70958
|
try {
|
|
70930
|
-
const filePath =
|
|
70931
|
-
const content = await
|
|
70959
|
+
const filePath = resolve81(ctx.workingDirectory, args.project);
|
|
70960
|
+
const content = await readFile52(filePath, "utf-8");
|
|
70932
70961
|
const data = JSON.parse(content);
|
|
70933
70962
|
const project = Project.fromJSON(data);
|
|
70934
|
-
const dirPath =
|
|
70963
|
+
const dirPath = resolve81(ctx.workingDirectory, args.directory);
|
|
70935
70964
|
const filterExts = args.filter ? args.filter.split(",").map((e) => e.trim().toLowerCase()) : null;
|
|
70936
70965
|
const imageDuration = args.imageDuration ?? 5;
|
|
70937
70966
|
const recursive = args.recursive ?? false;
|
|
@@ -70939,7 +70968,7 @@ var init_agent_only = __esm({
|
|
|
70939
70968
|
const scanDir = async (dir) => {
|
|
70940
70969
|
const entries = await readdir7(dir, { withFileTypes: true });
|
|
70941
70970
|
for (const entry of entries) {
|
|
70942
|
-
const entryPath =
|
|
70971
|
+
const entryPath = join26(dir, entry.name);
|
|
70943
70972
|
if (entry.isDirectory() && recursive) {
|
|
70944
70973
|
await scanDir(entryPath);
|
|
70945
70974
|
} else if (entry.isFile()) {
|
|
@@ -70966,7 +70995,7 @@ var init_agent_only = __esm({
|
|
|
70966
70995
|
const source = project.addSource({ name: mediaName, type: mediaType, url: mediaFile, duration });
|
|
70967
70996
|
addedSources.push({ id: source.id, name: mediaName, type: mediaType });
|
|
70968
70997
|
}
|
|
70969
|
-
await
|
|
70998
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
70970
70999
|
return {
|
|
70971
71000
|
success: true,
|
|
70972
71001
|
data: { count: addedSources.length, sources: addedSources },
|
|
@@ -70997,8 +71026,8 @@ var init_agent_only = __esm({
|
|
|
70997
71026
|
}),
|
|
70998
71027
|
async execute(args, ctx) {
|
|
70999
71028
|
try {
|
|
71000
|
-
const filePath =
|
|
71001
|
-
const content = await
|
|
71029
|
+
const filePath = resolve81(ctx.workingDirectory, args.project);
|
|
71030
|
+
const content = await readFile52(filePath, "utf-8");
|
|
71002
71031
|
const data = JSON.parse(content);
|
|
71003
71032
|
const project = Project.fromJSON(data);
|
|
71004
71033
|
const sourceIds = args.sourceIds ?? [];
|
|
@@ -71034,7 +71063,7 @@ var init_agent_only = __esm({
|
|
|
71034
71063
|
createdClips.push({ id: clip.id, sourceName: source.name, startTime: currentTime, duration: source.duration });
|
|
71035
71064
|
currentTime += source.duration + gap;
|
|
71036
71065
|
}
|
|
71037
|
-
await
|
|
71066
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
71038
71067
|
const totalDuration = currentTime - gap - startTime;
|
|
71039
71068
|
return {
|
|
71040
71069
|
success: true,
|
|
@@ -71066,8 +71095,8 @@ var init_agent_only = __esm({
|
|
|
71066
71095
|
}),
|
|
71067
71096
|
async execute(args, ctx) {
|
|
71068
71097
|
try {
|
|
71069
|
-
const filePath =
|
|
71070
|
-
const content = await
|
|
71098
|
+
const filePath = resolve81(ctx.workingDirectory, args.project);
|
|
71099
|
+
const content = await readFile52(filePath, "utf-8");
|
|
71071
71100
|
const data = JSON.parse(content);
|
|
71072
71101
|
const project = Project.fromJSON(data);
|
|
71073
71102
|
const clipIds = args.clipIds ?? [];
|
|
@@ -71095,7 +71124,7 @@ var init_agent_only = __esm({
|
|
|
71095
71124
|
});
|
|
71096
71125
|
if (effect) appliedEffects.push({ clipId: clip.id, effectId: effect.id });
|
|
71097
71126
|
}
|
|
71098
|
-
await
|
|
71127
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
71099
71128
|
return {
|
|
71100
71129
|
success: true,
|
|
71101
71130
|
data: { applied: appliedEffects.length, effectType: args.effectType },
|
|
@@ -71120,7 +71149,7 @@ var init_agent_only = __esm({
|
|
|
71120
71149
|
async execute(args, ctx) {
|
|
71121
71150
|
try {
|
|
71122
71151
|
const filePath = await resolveTimelineFile(args.project, ctx.workingDirectory);
|
|
71123
|
-
const content = await
|
|
71152
|
+
const content = await readFile52(filePath, "utf-8");
|
|
71124
71153
|
const data = JSON.parse(content);
|
|
71125
71154
|
const project = Project.fromJSON(data);
|
|
71126
71155
|
const what = args.what ?? "clips";
|
|
@@ -71162,7 +71191,7 @@ var init_agent_only = __esm({
|
|
|
71162
71191
|
removed.sources++;
|
|
71163
71192
|
}
|
|
71164
71193
|
}
|
|
71165
|
-
await
|
|
71194
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
71166
71195
|
const parts = [];
|
|
71167
71196
|
if (removed.clips > 0) parts.push(`${removed.clips} clips`);
|
|
71168
71197
|
if (removed.tracks > 0) parts.push(`${removed.tracks} tracks`);
|
|
@@ -71195,7 +71224,7 @@ var init_agent_only = __esm({
|
|
|
71195
71224
|
async execute(args, ctx) {
|
|
71196
71225
|
try {
|
|
71197
71226
|
const filePath = await resolveTimelineFile(args.projectPath, ctx.workingDirectory);
|
|
71198
|
-
const content = await
|
|
71227
|
+
const content = await readFile52(filePath, "utf-8");
|
|
71199
71228
|
const data = JSON.parse(content);
|
|
71200
71229
|
const project = Project.fromJSON(data);
|
|
71201
71230
|
const updates = [];
|
|
@@ -71211,7 +71240,7 @@ var init_agent_only = __esm({
|
|
|
71211
71240
|
project.setFrameRate(args.fps);
|
|
71212
71241
|
updates.push(`Frame Rate: ${args.fps} fps`);
|
|
71213
71242
|
}
|
|
71214
|
-
await
|
|
71243
|
+
await writeFile58(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
71215
71244
|
return {
|
|
71216
71245
|
success: true,
|
|
71217
71246
|
data: { updates },
|
|
@@ -71344,7 +71373,7 @@ var init_agent_only = __esm({
|
|
|
71344
71373
|
}),
|
|
71345
71374
|
async execute(args, ctx) {
|
|
71346
71375
|
try {
|
|
71347
|
-
const absPath =
|
|
71376
|
+
const absPath = resolve81(ctx.workingDirectory, args.path);
|
|
71348
71377
|
const { stdout } = await execSafe(
|
|
71349
71378
|
"ffprobe",
|
|
71350
71379
|
["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", absPath],
|
|
@@ -71431,10 +71460,10 @@ Audio:`);
|
|
|
71431
71460
|
}),
|
|
71432
71461
|
async execute(args, ctx) {
|
|
71433
71462
|
try {
|
|
71434
|
-
const absInput =
|
|
71463
|
+
const absInput = resolve81(ctx.workingDirectory, args.input);
|
|
71435
71464
|
const ext = args.input.split(".").pop() || "mp4";
|
|
71436
71465
|
const baseName = args.input.replace(/\.[^/.]+$/, "");
|
|
71437
|
-
const outputPath = args.output ?
|
|
71466
|
+
const outputPath = args.output ? resolve81(ctx.workingDirectory, args.output) : resolve81(ctx.workingDirectory, `${baseName}-compressed.${ext}`);
|
|
71438
71467
|
const crfValues = { low: 28, medium: 23, high: 18 };
|
|
71439
71468
|
const crf = crfValues[args.quality ?? "medium"];
|
|
71440
71469
|
await execSafe(
|
|
@@ -71457,8 +71486,8 @@ Audio:`);
|
|
|
71457
71486
|
],
|
|
71458
71487
|
{ maxBuffer: 50 * 1024 * 1024 }
|
|
71459
71488
|
);
|
|
71460
|
-
const inputBuf = await
|
|
71461
|
-
const outputBuf = await
|
|
71489
|
+
const inputBuf = await readFile52(absInput);
|
|
71490
|
+
const outputBuf = await readFile52(outputPath);
|
|
71462
71491
|
const inputSize = inputBuf.length;
|
|
71463
71492
|
const outputSize = outputBuf.length;
|
|
71464
71493
|
const reduction = (inputSize - outputSize) / inputSize * 100;
|
|
@@ -71492,8 +71521,8 @@ Audio:`);
|
|
|
71492
71521
|
}),
|
|
71493
71522
|
async execute(args, ctx) {
|
|
71494
71523
|
try {
|
|
71495
|
-
const absInput =
|
|
71496
|
-
const absOutput =
|
|
71524
|
+
const absInput = resolve81(ctx.workingDirectory, args.input);
|
|
71525
|
+
const absOutput = resolve81(ctx.workingDirectory, args.output);
|
|
71497
71526
|
const codecMap = {
|
|
71498
71527
|
h264: "libx264",
|
|
71499
71528
|
h265: "libx265",
|
|
@@ -71544,11 +71573,11 @@ Audio:`);
|
|
|
71544
71573
|
};
|
|
71545
71574
|
}
|
|
71546
71575
|
try {
|
|
71547
|
-
const absOutput =
|
|
71576
|
+
const absOutput = resolve81(ctx.workingDirectory, args.output);
|
|
71548
71577
|
if (args.reencode) {
|
|
71549
71578
|
const ffmpegArgs = [];
|
|
71550
71579
|
for (const i of args.inputs) {
|
|
71551
|
-
ffmpegArgs.push("-i",
|
|
71580
|
+
ffmpegArgs.push("-i", resolve81(ctx.workingDirectory, i));
|
|
71552
71581
|
}
|
|
71553
71582
|
const filterComplex = args.inputs.map((_, i) => `[${i}:v][${i}:a]`).join("");
|
|
71554
71583
|
ffmpegArgs.push(
|
|
@@ -71563,9 +71592,9 @@ Audio:`);
|
|
|
71563
71592
|
);
|
|
71564
71593
|
await execSafe("ffmpeg", ffmpegArgs, { maxBuffer: 100 * 1024 * 1024 });
|
|
71565
71594
|
} else {
|
|
71566
|
-
const tempList =
|
|
71567
|
-
const listContent = args.inputs.map((i) => `file '${
|
|
71568
|
-
await
|
|
71595
|
+
const tempList = resolve81(ctx.workingDirectory, `concat-list-${Date.now()}.txt`);
|
|
71596
|
+
const listContent = args.inputs.map((i) => `file '${resolve81(ctx.workingDirectory, i)}'`).join("\n");
|
|
71597
|
+
await writeFile58(tempList, listContent, "utf-8");
|
|
71569
71598
|
try {
|
|
71570
71599
|
await execSafe(
|
|
71571
71600
|
"ffmpeg",
|
|
@@ -71659,14 +71688,15 @@ var init_walkthrough = __esm({
|
|
|
71659
71688
|
});
|
|
71660
71689
|
|
|
71661
71690
|
// src/tools/manifest/status.ts
|
|
71662
|
-
import { resolve as
|
|
71663
|
-
var statusJobTool, statusProjectTool, statusTools;
|
|
71691
|
+
import { resolve as resolve82 } from "node:path";
|
|
71692
|
+
var PROJECT_DIR_DESCRIPTION4, statusJobTool, statusProjectTool, statusTools;
|
|
71664
71693
|
var init_status = __esm({
|
|
71665
71694
|
"src/tools/manifest/status.ts"() {
|
|
71666
71695
|
"use strict";
|
|
71667
71696
|
init_zod();
|
|
71668
71697
|
init_define_tool();
|
|
71669
71698
|
init_status_jobs();
|
|
71699
|
+
PROJECT_DIR_DESCRIPTION4 = "Project directory. Defaults to the surface's cwd; in MCP hosts, relative paths resolve under the configured server workspace.";
|
|
71670
71700
|
statusJobTool = defineTool({
|
|
71671
71701
|
name: "status_job",
|
|
71672
71702
|
category: "status",
|
|
@@ -71674,13 +71704,13 @@ var init_status = __esm({
|
|
|
71674
71704
|
description: "Read one local async job record and optionally refresh supported provider status. Supports Runway/Kling video and Replicate music live checks.",
|
|
71675
71705
|
schema: external_exports.object({
|
|
71676
71706
|
jobId: external_exports.string().describe("Local job id returned by a no-wait command."),
|
|
71677
|
-
projectDir: external_exports.string().optional().describe("Project directory containing .vibeframe/jobs. Defaults to nearest project root."),
|
|
71707
|
+
projectDir: external_exports.string().optional().describe("Project directory containing .vibeframe/jobs. Defaults to nearest project root; in MCP hosts, relative paths resolve under the configured server workspace."),
|
|
71678
71708
|
refresh: external_exports.boolean().optional().describe("Call provider status APIs when supported. Default true."),
|
|
71679
71709
|
wait: external_exports.boolean().optional().describe("Wait for completion when supported."),
|
|
71680
71710
|
output: external_exports.string().optional().describe("Download result media to this path when complete.")
|
|
71681
71711
|
}),
|
|
71682
71712
|
async execute(args, ctx) {
|
|
71683
|
-
const projectDir = args.projectDir ?
|
|
71713
|
+
const projectDir = args.projectDir ? resolve82(ctx.workingDirectory, args.projectDir) : findProjectRoot(ctx.workingDirectory);
|
|
71684
71714
|
const record = await readJobRecord(args.jobId, projectDir);
|
|
71685
71715
|
if (!record) return { success: false, error: `Job not found: ${args.jobId}` };
|
|
71686
71716
|
const result = args.refresh === false ? makeJobStatusResult(record, {
|
|
@@ -71689,7 +71719,7 @@ var init_status = __esm({
|
|
|
71689
71719
|
warnings: []
|
|
71690
71720
|
}) : await refreshJobRecord(record, {
|
|
71691
71721
|
wait: args.wait,
|
|
71692
|
-
output: args.output ?
|
|
71722
|
+
output: args.output ? resolve82(ctx.workingDirectory, args.output) : void 0,
|
|
71693
71723
|
workingDirectory: ctx.workingDirectory
|
|
71694
71724
|
});
|
|
71695
71725
|
return {
|
|
@@ -71708,15 +71738,19 @@ var init_status = __esm({
|
|
|
71708
71738
|
cost: "free",
|
|
71709
71739
|
description: "Summarize build-report.json, review-report.json, and local async job records for a VibeFrame project.",
|
|
71710
71740
|
schema: external_exports.object({
|
|
71711
|
-
projectDir: external_exports.string().optional().describe(
|
|
71741
|
+
projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION4),
|
|
71712
71742
|
refresh: external_exports.boolean().optional().describe("Refresh active supported jobs before summarizing. Default false.")
|
|
71713
71743
|
}),
|
|
71714
71744
|
async execute(args, ctx) {
|
|
71715
|
-
const projectDir = args.projectDir ?
|
|
71745
|
+
const projectDir = args.projectDir ? resolve82(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
71716
71746
|
const result = await inspectProjectStatus(projectDir, { refresh: args.refresh === true });
|
|
71717
71747
|
return {
|
|
71718
71748
|
success: true,
|
|
71719
|
-
data:
|
|
71749
|
+
data: {
|
|
71750
|
+
...result,
|
|
71751
|
+
workingDirectory: ctx.workingDirectory,
|
|
71752
|
+
projectDir
|
|
71753
|
+
},
|
|
71720
71754
|
humanLines: [
|
|
71721
71755
|
`Project status: ${result.status} (${result.currentStage}), ${result.jobs.active} active job(s), ${result.jobs.failed} failed job(s)`,
|
|
71722
71756
|
...result.build ? [`build: ${result.build.phase ?? "unknown"}`] : [],
|
|
@@ -71994,8 +72028,8 @@ init_source();
|
|
|
71994
72028
|
// package.json
|
|
71995
72029
|
var package_default = {
|
|
71996
72030
|
name: "@vibeframe/cli",
|
|
71997
|
-
version: "0.106.
|
|
71998
|
-
description: "VibeFrame CLI -
|
|
72031
|
+
version: "0.106.6",
|
|
72032
|
+
description: "VibeFrame CLI - agentic video workflow runtime",
|
|
71999
72033
|
private: false,
|
|
72000
72034
|
license: "MIT",
|
|
72001
72035
|
repository: {
|
|
@@ -78013,9 +78047,9 @@ function parseLrc(lrcString) {
|
|
|
78013
78047
|
const minutes = Number.parseInt(match[1], 10);
|
|
78014
78048
|
const seconds = Number.parseInt(match[2], 10);
|
|
78015
78049
|
const ms = match[3].length === 3 ? Number.parseInt(match[3], 10) : Number.parseInt(match[3], 10) * 10;
|
|
78016
|
-
const
|
|
78050
|
+
const timestamp2 = (minutes * 60 + seconds) * 1e3 + ms;
|
|
78017
78051
|
const text = line.replace(TIMESTAMP_REGEX, "").trim();
|
|
78018
|
-
syncText.push({ timestamp, text });
|
|
78052
|
+
syncText.push({ timestamp: timestamp2, text });
|
|
78019
78053
|
}
|
|
78020
78054
|
}
|
|
78021
78055
|
return {
|
|
@@ -79170,12 +79204,12 @@ function resolveCopier() {
|
|
|
79170
79204
|
async function copyToClipboard(text) {
|
|
79171
79205
|
const opener = resolveCopier();
|
|
79172
79206
|
if (!opener) return false;
|
|
79173
|
-
return new Promise((
|
|
79207
|
+
return new Promise((resolve83) => {
|
|
79174
79208
|
let settled = false;
|
|
79175
79209
|
const finish = (ok) => {
|
|
79176
79210
|
if (settled) return;
|
|
79177
79211
|
settled = true;
|
|
79178
|
-
|
|
79212
|
+
resolve83(ok);
|
|
79179
79213
|
};
|
|
79180
79214
|
try {
|
|
79181
79215
|
const child = spawn2(opener.command, opener.args, {
|
|
@@ -80428,9 +80462,9 @@ init_source();
|
|
|
80428
80462
|
init_agent_host_detect();
|
|
80429
80463
|
init_scene_project();
|
|
80430
80464
|
init_visual_styles();
|
|
80431
|
-
import { existsSync as
|
|
80432
|
-
import { mkdir as
|
|
80433
|
-
import { basename as basename19, dirname as
|
|
80465
|
+
import { existsSync as existsSync41 } from "node:fs";
|
|
80466
|
+
import { mkdir as mkdir23, readFile as readFile38, writeFile as writeFile45 } from "node:fs/promises";
|
|
80467
|
+
import { basename as basename19, dirname as dirname19, resolve as resolve54 } from "node:path";
|
|
80434
80468
|
|
|
80435
80469
|
// src/commands/_shared/storyboard-draft.ts
|
|
80436
80470
|
init_scene_project();
|
|
@@ -80588,6 +80622,306 @@ function escapeRegExp2(value) {
|
|
|
80588
80622
|
init_project_config();
|
|
80589
80623
|
init_install_skill();
|
|
80590
80624
|
|
|
80625
|
+
// src/commands/_shared/host-integration.ts
|
|
80626
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
80627
|
+
import { mkdir as mkdir22, readFile as readFile37, writeFile as writeFile44 } from "node:fs/promises";
|
|
80628
|
+
import { homedir as homedir6 } from "node:os";
|
|
80629
|
+
import { dirname as dirname18, join as join19, resolve as resolve53 } from "node:path";
|
|
80630
|
+
var HOST_SELECTIONS = [
|
|
80631
|
+
"codex",
|
|
80632
|
+
"claude",
|
|
80633
|
+
"claude-code",
|
|
80634
|
+
"claude-desktop",
|
|
80635
|
+
"cursor",
|
|
80636
|
+
"all"
|
|
80637
|
+
];
|
|
80638
|
+
var VIBEFRAME_MCP_JSON = {
|
|
80639
|
+
command: "npx",
|
|
80640
|
+
args: ["-y", "@vibeframe/mcp-server"]
|
|
80641
|
+
};
|
|
80642
|
+
var CODEX_MCP_BLOCK = `[mcp_servers.vibeframe]
|
|
80643
|
+
command = "npx"
|
|
80644
|
+
args = ["-y", "@vibeframe/mcp-server"]
|
|
80645
|
+
enabled = true
|
|
80646
|
+
`;
|
|
80647
|
+
var CODEX_MANAGED_START = "# >>> VibeFrame MCP server >>>";
|
|
80648
|
+
var CODEX_MANAGED_END = "# <<< VibeFrame MCP server <<<";
|
|
80649
|
+
function hostDefinitions(_projectDir = process.cwd()) {
|
|
80650
|
+
return [
|
|
80651
|
+
{
|
|
80652
|
+
id: "codex",
|
|
80653
|
+
label: "OpenAI Codex",
|
|
80654
|
+
surfaces: ["shell", "project-guidance", "mcp"],
|
|
80655
|
+
guidanceFiles: ["AGENTS.md"],
|
|
80656
|
+
configPath: (dir) => join19(resolve53(dir), ".codex", "config.toml"),
|
|
80657
|
+
configKind: "codex-toml",
|
|
80658
|
+
notes: [
|
|
80659
|
+
"Codex reads AGENTS.md and can also load project-scoped .codex/config.toml after the project is trusted.",
|
|
80660
|
+
"Keep provider/auth keys in VibeFrame config or environment, not in project-local Codex config."
|
|
80661
|
+
]
|
|
80662
|
+
},
|
|
80663
|
+
{
|
|
80664
|
+
id: "claude-code",
|
|
80665
|
+
label: "Claude Code",
|
|
80666
|
+
surfaces: ["shell", "project-guidance", "mcp"],
|
|
80667
|
+
guidanceFiles: ["AGENTS.md", "CLAUDE.md", ".claude/skills/hyperframes/"],
|
|
80668
|
+
configPath: (dir) => join19(resolve53(dir), ".mcp.json"),
|
|
80669
|
+
configKind: "mcp-json",
|
|
80670
|
+
notes: [
|
|
80671
|
+
"Claude Code can drive vibe directly through shell plus AGENTS.md/CLAUDE.md.",
|
|
80672
|
+
"The MCP entry is optional and gives Claude Code a typed tool surface."
|
|
80673
|
+
]
|
|
80674
|
+
},
|
|
80675
|
+
{
|
|
80676
|
+
id: "claude-desktop",
|
|
80677
|
+
label: "Claude Desktop",
|
|
80678
|
+
surfaces: ["mcp"],
|
|
80679
|
+
guidanceFiles: [],
|
|
80680
|
+
configPath: (_dir) => claudeDesktopConfigPath(),
|
|
80681
|
+
configKind: "mcp-json",
|
|
80682
|
+
notes: [
|
|
80683
|
+
"Claude Desktop uses MCP config rather than project shell commands.",
|
|
80684
|
+
"With --write, VibeFrame backs up the existing config before merging."
|
|
80685
|
+
]
|
|
80686
|
+
},
|
|
80687
|
+
{
|
|
80688
|
+
id: "cursor",
|
|
80689
|
+
label: "Cursor",
|
|
80690
|
+
surfaces: ["shell", "project-guidance", "mcp"],
|
|
80691
|
+
guidanceFiles: ["AGENTS.md", ".cursor/rules/hyperframes.mdc"],
|
|
80692
|
+
configPath: (dir) => join19(resolve53(dir), ".cursor", "mcp.json"),
|
|
80693
|
+
configKind: "mcp-json",
|
|
80694
|
+
notes: [
|
|
80695
|
+
"Cursor can use AGENTS.md/rules for shell-driven work and .cursor/mcp.json for typed MCP tools."
|
|
80696
|
+
]
|
|
80697
|
+
}
|
|
80698
|
+
];
|
|
80699
|
+
}
|
|
80700
|
+
function resolveHostSelection(selection) {
|
|
80701
|
+
if (selection === "all") return ["codex", "claude-code", "claude-desktop", "cursor"];
|
|
80702
|
+
if (selection === "claude") return ["claude-code", "claude-desktop"];
|
|
80703
|
+
return [selection];
|
|
80704
|
+
}
|
|
80705
|
+
function vibeframeMcpJson(host, projectDir) {
|
|
80706
|
+
return host.id === "claude-desktop" ? { ...VIBEFRAME_MCP_JSON, cwd: resolve53(projectDir) } : { ...VIBEFRAME_MCP_JSON };
|
|
80707
|
+
}
|
|
80708
|
+
function renderHostSnippet(host, projectDir) {
|
|
80709
|
+
if (host.configKind === "codex-toml") return CODEX_MCP_BLOCK.trimEnd();
|
|
80710
|
+
return JSON.stringify({ mcpServers: { vibeframe: vibeframeMcpJson(host, projectDir) } }, null, 2);
|
|
80711
|
+
}
|
|
80712
|
+
function claudeCodeAddCommand() {
|
|
80713
|
+
return "claude mcp add vibeframe --scope project -- npx -y @vibeframe/mcp-server";
|
|
80714
|
+
}
|
|
80715
|
+
async function planHostSetup(host, projectDir, opts) {
|
|
80716
|
+
const configPath = host.configPath(projectDir);
|
|
80717
|
+
const snippet = renderHostSnippet(host, projectDir);
|
|
80718
|
+
const files = [];
|
|
80719
|
+
const warnings = [];
|
|
80720
|
+
const nextSteps = hostNextSteps(host);
|
|
80721
|
+
for (const relPath of host.guidanceFiles.filter((p) => !p.endsWith("/"))) {
|
|
80722
|
+
const absPath = join19(resolve53(projectDir), relPath);
|
|
80723
|
+
files.push({
|
|
80724
|
+
path: absPath,
|
|
80725
|
+
status: existsSync40(absPath) ? "skipped-exists" : "missing",
|
|
80726
|
+
reason: existsSync40(absPath) ? "already present" : "run vibe init --agent all first"
|
|
80727
|
+
});
|
|
80728
|
+
}
|
|
80729
|
+
if (!opts.write || opts.dryRun) {
|
|
80730
|
+
files.push({
|
|
80731
|
+
path: configPath,
|
|
80732
|
+
status: opts.write ? "would-merge" : "would-write",
|
|
80733
|
+
reason: opts.write ? "dry run" : "snippet only; pass --write to modify"
|
|
80734
|
+
});
|
|
80735
|
+
return { host, snippet, command: host.id === "claude-code" ? claudeCodeAddCommand() : void 0, configPath, files, warnings, nextSteps };
|
|
80736
|
+
}
|
|
80737
|
+
try {
|
|
80738
|
+
const action = host.configKind === "codex-toml" ? await mergeCodexToml(configPath, { force: opts.force === true }) : await mergeMcpJson(configPath, {
|
|
80739
|
+
server: vibeframeMcpJson(host, projectDir),
|
|
80740
|
+
force: opts.force === true,
|
|
80741
|
+
backup: host.id === "claude-desktop"
|
|
80742
|
+
});
|
|
80743
|
+
files.push(action);
|
|
80744
|
+
} catch (error) {
|
|
80745
|
+
warnings.push(error instanceof Error ? error.message : String(error));
|
|
80746
|
+
}
|
|
80747
|
+
return { host, snippet, command: host.id === "claude-code" ? claudeCodeAddCommand() : void 0, configPath, files, warnings, nextSteps };
|
|
80748
|
+
}
|
|
80749
|
+
async function inspectHost(host, projectDir) {
|
|
80750
|
+
const configPath = host.configPath(projectDir);
|
|
80751
|
+
const warnings = [];
|
|
80752
|
+
const nextSteps = hostNextSteps(host);
|
|
80753
|
+
const guidanceFiles = host.guidanceFiles.map((relPath) => {
|
|
80754
|
+
const absPath = relPath.endsWith("/") ? join19(resolve53(projectDir), relPath) : join19(resolve53(projectDir), relPath);
|
|
80755
|
+
return {
|
|
80756
|
+
path: absPath,
|
|
80757
|
+
status: existsSync40(absPath) ? "skipped-exists" : "missing",
|
|
80758
|
+
reason: existsSync40(absPath) ? "present" : "missing"
|
|
80759
|
+
};
|
|
80760
|
+
});
|
|
80761
|
+
let configured = false;
|
|
80762
|
+
if (existsSync40(configPath)) {
|
|
80763
|
+
try {
|
|
80764
|
+
const content = await readFile37(configPath, "utf-8");
|
|
80765
|
+
if (host.configKind === "codex-toml") {
|
|
80766
|
+
configured = /\[mcp_servers\.vibeframe\]/.test(content);
|
|
80767
|
+
} else {
|
|
80768
|
+
const json = JSON.parse(content);
|
|
80769
|
+
configured = hasVibeframeMcpServer(json);
|
|
80770
|
+
const server = readVibeframeMcpServer(json);
|
|
80771
|
+
if (host.id === "claude-desktop" && configured && !server?.cwd) {
|
|
80772
|
+
warnings.push(
|
|
80773
|
+
"Claude Desktop vibeframe MCP config has no cwd; run `vibe host setup claude-desktop <workspace> --write` to anchor relative paths."
|
|
80774
|
+
);
|
|
80775
|
+
}
|
|
80776
|
+
}
|
|
80777
|
+
} catch (error) {
|
|
80778
|
+
warnings.push(error instanceof Error ? error.message : String(error));
|
|
80779
|
+
}
|
|
80780
|
+
}
|
|
80781
|
+
return { host, configPath, configured, guidanceFiles, warnings, nextSteps };
|
|
80782
|
+
}
|
|
80783
|
+
async function mergeMcpJson(configPath, opts) {
|
|
80784
|
+
let root = {};
|
|
80785
|
+
const exists = existsSync40(configPath);
|
|
80786
|
+
if (exists) {
|
|
80787
|
+
const raw = await readFile37(configPath, "utf-8");
|
|
80788
|
+
try {
|
|
80789
|
+
root = raw.trim() ? JSON.parse(raw) : {};
|
|
80790
|
+
} catch (error) {
|
|
80791
|
+
throw new Error(`Invalid JSON in ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
80792
|
+
}
|
|
80793
|
+
}
|
|
80794
|
+
const mcpServers = typeof root.mcpServers === "object" && root.mcpServers !== null && !Array.isArray(root.mcpServers) ? root.mcpServers : {};
|
|
80795
|
+
if (mcpServers.vibeframe && !opts.force) {
|
|
80796
|
+
const existing = mcpServers.vibeframe;
|
|
80797
|
+
if (canAddMissingCwd(existing, opts.server)) {
|
|
80798
|
+
root.mcpServers = {
|
|
80799
|
+
...mcpServers,
|
|
80800
|
+
vibeframe: { ...existing, cwd: opts.server.cwd }
|
|
80801
|
+
};
|
|
80802
|
+
await mkdir22(dirname18(configPath), { recursive: true });
|
|
80803
|
+
if (exists && opts.backup) {
|
|
80804
|
+
await writeFile44(`${configPath}.bak-${timestamp()}`, await readFile37(configPath, "utf-8"), "utf-8");
|
|
80805
|
+
}
|
|
80806
|
+
await writeFile44(configPath, JSON.stringify(root, null, 2) + "\n", "utf-8");
|
|
80807
|
+
return { path: configPath, status: "merged", reason: "added cwd to existing vibeframe MCP server" };
|
|
80808
|
+
}
|
|
80809
|
+
return {
|
|
80810
|
+
path: configPath,
|
|
80811
|
+
status: "skipped-exists",
|
|
80812
|
+
reason: "vibeframe MCP server already exists; pass --force to replace"
|
|
80813
|
+
};
|
|
80814
|
+
}
|
|
80815
|
+
root.mcpServers = { ...mcpServers, vibeframe: opts.server };
|
|
80816
|
+
await mkdir22(dirname18(configPath), { recursive: true });
|
|
80817
|
+
if (exists && opts.backup) {
|
|
80818
|
+
await writeFile44(`${configPath}.bak-${timestamp()}`, await readFile37(configPath, "utf-8"), "utf-8");
|
|
80819
|
+
}
|
|
80820
|
+
await writeFile44(configPath, JSON.stringify(root, null, 2) + "\n", "utf-8");
|
|
80821
|
+
return { path: configPath, status: exists ? "merged" : "wrote" };
|
|
80822
|
+
}
|
|
80823
|
+
async function mergeCodexToml(configPath, opts) {
|
|
80824
|
+
const exists = existsSync40(configPath);
|
|
80825
|
+
const block = `${CODEX_MANAGED_START}
|
|
80826
|
+
${CODEX_MCP_BLOCK}${CODEX_MANAGED_END}`;
|
|
80827
|
+
if (!exists) {
|
|
80828
|
+
await mkdir22(dirname18(configPath), { recursive: true });
|
|
80829
|
+
await writeFile44(configPath, `#:schema https://developers.openai.com/codex/config-schema.json
|
|
80830
|
+
|
|
80831
|
+
${block}
|
|
80832
|
+
`, "utf-8");
|
|
80833
|
+
return { path: configPath, status: "wrote" };
|
|
80834
|
+
}
|
|
80835
|
+
const raw = await readFile37(configPath, "utf-8");
|
|
80836
|
+
if (raw.includes(CODEX_MANAGED_START)) {
|
|
80837
|
+
const updated = raw.replace(
|
|
80838
|
+
new RegExp(`${escapeRegExp3(CODEX_MANAGED_START)}[\\s\\S]*?${escapeRegExp3(CODEX_MANAGED_END)}`),
|
|
80839
|
+
block
|
|
80840
|
+
);
|
|
80841
|
+
await writeFile44(configPath, ensureTrailingNewline(updated), "utf-8");
|
|
80842
|
+
return { path: configPath, status: "merged", reason: "updated managed VibeFrame block" };
|
|
80843
|
+
}
|
|
80844
|
+
if (/\[mcp_servers\.vibeframe\]/.test(raw)) {
|
|
80845
|
+
if (!opts.force) {
|
|
80846
|
+
return {
|
|
80847
|
+
path: configPath,
|
|
80848
|
+
status: "skipped-exists",
|
|
80849
|
+
reason: "vibeframe MCP table already exists; pass --force to replace"
|
|
80850
|
+
};
|
|
80851
|
+
}
|
|
80852
|
+
const updated = raw.replace(/\n?\[mcp_servers\.vibeframe\][\s\S]*?(?=\n\[|$)/, `
|
|
80853
|
+
${block}
|
|
80854
|
+
`);
|
|
80855
|
+
await writeFile44(configPath, ensureTrailingNewline(updated), "utf-8");
|
|
80856
|
+
return { path: configPath, status: "merged", reason: "replaced existing VibeFrame MCP table" };
|
|
80857
|
+
}
|
|
80858
|
+
await writeFile44(configPath, `${ensureTrailingNewline(raw)}
|
|
80859
|
+
${block}
|
|
80860
|
+
`, "utf-8");
|
|
80861
|
+
return { path: configPath, status: "merged" };
|
|
80862
|
+
}
|
|
80863
|
+
function hasVibeframeMcpServer(value) {
|
|
80864
|
+
if (!value || typeof value !== "object") return false;
|
|
80865
|
+
const root = value;
|
|
80866
|
+
if (!root.mcpServers || typeof root.mcpServers !== "object") return false;
|
|
80867
|
+
return Object.prototype.hasOwnProperty.call(root.mcpServers, "vibeframe");
|
|
80868
|
+
}
|
|
80869
|
+
function readVibeframeMcpServer(value) {
|
|
80870
|
+
if (!value || typeof value !== "object") return null;
|
|
80871
|
+
const root = value;
|
|
80872
|
+
if (!root.mcpServers || typeof root.mcpServers !== "object" || Array.isArray(root.mcpServers)) return null;
|
|
80873
|
+
const server = root.mcpServers.vibeframe;
|
|
80874
|
+
if (!server || typeof server !== "object" || Array.isArray(server)) return null;
|
|
80875
|
+
return server;
|
|
80876
|
+
}
|
|
80877
|
+
function canAddMissingCwd(existing, target) {
|
|
80878
|
+
if (!target.cwd) return false;
|
|
80879
|
+
if (!existing || typeof existing !== "object" || Array.isArray(existing)) return false;
|
|
80880
|
+
const current = existing;
|
|
80881
|
+
if (current.cwd) return false;
|
|
80882
|
+
if (current.command !== target.command) return false;
|
|
80883
|
+
if (!Array.isArray(current.args)) return false;
|
|
80884
|
+
return JSON.stringify(current.args) === JSON.stringify(target.args);
|
|
80885
|
+
}
|
|
80886
|
+
function hostNextSteps(host) {
|
|
80887
|
+
if (host.id === "codex") {
|
|
80888
|
+
return [
|
|
80889
|
+
"Trust the project in Codex so .codex/config.toml is loaded.",
|
|
80890
|
+
"Run /mcp in Codex to confirm the vibeframe server is connected."
|
|
80891
|
+
];
|
|
80892
|
+
}
|
|
80893
|
+
if (host.id === "claude-code") {
|
|
80894
|
+
return [
|
|
80895
|
+
"Restart Claude Code or run /mcp to approve the project-scoped server.",
|
|
80896
|
+
"Use AGENTS.md/CLAUDE.md for shell-driven vibe workflows."
|
|
80897
|
+
];
|
|
80898
|
+
}
|
|
80899
|
+
if (host.id === "claude-desktop") {
|
|
80900
|
+
return ["Restart Claude Desktop after updating its MCP config."];
|
|
80901
|
+
}
|
|
80902
|
+
return ["Restart Cursor or reload MCP servers, then ask Cursor to use the vibeframe MCP tools."];
|
|
80903
|
+
}
|
|
80904
|
+
function claudeDesktopConfigPath() {
|
|
80905
|
+
const home = homedir6();
|
|
80906
|
+
if (process.platform === "darwin") {
|
|
80907
|
+
return join19(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
80908
|
+
}
|
|
80909
|
+
if (process.platform === "win32") {
|
|
80910
|
+
return join19(process.env.APPDATA ?? join19(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
|
|
80911
|
+
}
|
|
80912
|
+
return join19(home, ".config", "Claude", "claude_desktop_config.json");
|
|
80913
|
+
}
|
|
80914
|
+
function timestamp() {
|
|
80915
|
+
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
80916
|
+
}
|
|
80917
|
+
function ensureTrailingNewline(value) {
|
|
80918
|
+
return value.endsWith("\n") ? value : `${value}
|
|
80919
|
+
`;
|
|
80920
|
+
}
|
|
80921
|
+
function escapeRegExp3(value) {
|
|
80922
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
80923
|
+
}
|
|
80924
|
+
|
|
80591
80925
|
// src/commands/_shared/init-templates.ts
|
|
80592
80926
|
var AGENTS_MD = `# AGENTS.md
|
|
80593
80927
|
|
|
@@ -80628,6 +80962,8 @@ vibe schema --list # full machine-readable catalog (80+)
|
|
|
80628
80962
|
vibe schema --list --surface public # small first-run/product command surface
|
|
80629
80963
|
vibe schema generate.video # JSON Schema for any single command
|
|
80630
80964
|
vibe doctor # available providers + system health
|
|
80965
|
+
vibe host setup all # print Codex/Claude/Cursor app integration snippets
|
|
80966
|
+
vibe host doctor all --json # verify project guidance + MCP config
|
|
80631
80967
|
vibe guide motion # choose text-overlay vs motion-overlay vs generate motion
|
|
80632
80968
|
vibe guide scene # step-by-step authoring guide (scene)
|
|
80633
80969
|
vibe guide pipeline # step-by-step authoring guide (pipeline)
|
|
@@ -80752,6 +81088,22 @@ unless the user explicitly asks for a non-VibeFrame asset.
|
|
|
80752
81088
|
\`.env\` is still supported as a gitignored fallback. Copy \`.env.example\`
|
|
80753
81089
|
to start if you prefer environment variables.
|
|
80754
81090
|
|
|
81091
|
+
## App host setup
|
|
81092
|
+
|
|
81093
|
+
VibeFrame is CLI-first, not terminal-only. Codex, Claude Code, and Cursor can
|
|
81094
|
+
drive the same project through shell commands, and app hosts can also use
|
|
81095
|
+
VibeFrame's MCP server as a typed tool surface.
|
|
81096
|
+
|
|
81097
|
+
\`\`\`bash
|
|
81098
|
+
vibe host setup all # print snippets only
|
|
81099
|
+
vibe host setup all --write # write project/app config
|
|
81100
|
+
vibe host doctor all --json # verify readiness
|
|
81101
|
+
\`\`\`
|
|
81102
|
+
|
|
81103
|
+
Default setup is snippet-only; use \`--write\` when you want VibeFrame to merge
|
|
81104
|
+
the generated config. Keep provider keys in \`.vibeframe/config.yaml\`, user
|
|
81105
|
+
config, or env files \u2014 not in app host config.
|
|
81106
|
+
|
|
80755
81107
|
### Composition rules (scene HTML)
|
|
80756
81108
|
|
|
80757
81109
|
\`vibe init\` installs local composition rules into your project. The
|
|
@@ -80942,7 +81294,7 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80942
81294
|
).option(
|
|
80943
81295
|
"--from <brief>",
|
|
80944
81296
|
"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) => {
|
|
81297
|
+
).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
81298
|
const startedAt = Date.now();
|
|
80947
81299
|
const initType = String(options.type ?? "scene");
|
|
80948
81300
|
if (initType !== "scene" && initType !== "agent") {
|
|
@@ -80958,14 +81310,14 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80958
81310
|
usageError(`Invalid --agent: ${agent}`, `Must be one of: ${VALID_AGENTS.join(", ")}`)
|
|
80959
81311
|
);
|
|
80960
81312
|
}
|
|
80961
|
-
const projectDir =
|
|
81313
|
+
const projectDir = resolve54(projectDirArg);
|
|
80962
81314
|
const projectName = basename19(projectDir);
|
|
80963
81315
|
const targetHosts = resolveTargets(agent);
|
|
80964
81316
|
const wantsClaude = targetHosts.includes("claude-code");
|
|
80965
81317
|
const wantsGemini = targetHosts.includes("gemini-cli");
|
|
80966
81318
|
const wantsCrossTool = targetHosts.some((h) => h !== "claude-code");
|
|
80967
81319
|
const actions = [];
|
|
80968
|
-
if (!
|
|
81320
|
+
if (!existsSync41(projectDir)) {
|
|
80969
81321
|
if (options.dryRun) {
|
|
80970
81322
|
actions.push({
|
|
80971
81323
|
path: projectDir,
|
|
@@ -80973,13 +81325,13 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80973
81325
|
reason: "(would create directory)"
|
|
80974
81326
|
});
|
|
80975
81327
|
} else {
|
|
80976
|
-
await
|
|
81328
|
+
await mkdir23(projectDir, { recursive: true });
|
|
80977
81329
|
}
|
|
80978
81330
|
}
|
|
80979
81331
|
if (wantsCrossTool || !wantsClaude) {
|
|
80980
81332
|
actions.push(
|
|
80981
81333
|
await writeIfMissing(
|
|
80982
|
-
|
|
81334
|
+
resolve54(projectDir, "AGENTS.md"),
|
|
80983
81335
|
AGENTS_MD,
|
|
80984
81336
|
options.force,
|
|
80985
81337
|
options.dryRun
|
|
@@ -80989,7 +81341,7 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80989
81341
|
if (wantsClaude) {
|
|
80990
81342
|
actions.push(
|
|
80991
81343
|
await writeIfMissing(
|
|
80992
|
-
|
|
81344
|
+
resolve54(projectDir, "CLAUDE.md"),
|
|
80993
81345
|
CLAUDE_MD,
|
|
80994
81346
|
options.force,
|
|
80995
81347
|
options.dryRun
|
|
@@ -80999,7 +81351,7 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
80999
81351
|
if (wantsGemini) {
|
|
81000
81352
|
actions.push(
|
|
81001
81353
|
await writeIfMissing(
|
|
81002
|
-
|
|
81354
|
+
resolve54(projectDir, "GEMINI.md"),
|
|
81003
81355
|
GEMINI_MD,
|
|
81004
81356
|
options.force,
|
|
81005
81357
|
options.dryRun
|
|
@@ -81008,18 +81360,18 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
81008
81360
|
}
|
|
81009
81361
|
actions.push(
|
|
81010
81362
|
await writeIfMissing(
|
|
81011
|
-
|
|
81363
|
+
resolve54(projectDir, ".env.example"),
|
|
81012
81364
|
renderEnvExample(),
|
|
81013
81365
|
options.force,
|
|
81014
81366
|
options.dryRun
|
|
81015
81367
|
)
|
|
81016
81368
|
);
|
|
81017
81369
|
actions.push(
|
|
81018
|
-
await mergeGitignore(
|
|
81370
|
+
await mergeGitignore(resolve54(projectDir, ".gitignore"), GITIGNORE_ADDITIONS, options.dryRun)
|
|
81019
81371
|
);
|
|
81020
81372
|
actions.push(
|
|
81021
81373
|
await writeIfMissing(
|
|
81022
|
-
|
|
81374
|
+
resolve54(projectDir, VIBE_CONFIG_FILENAME),
|
|
81023
81375
|
projectConfigJson({ name: projectName }),
|
|
81024
81376
|
options.force,
|
|
81025
81377
|
options.dryRun
|
|
@@ -81027,12 +81379,20 @@ var initCommand = new Command("init").description("Scaffold a VibeFrame project
|
|
|
81027
81379
|
);
|
|
81028
81380
|
actions.push(
|
|
81029
81381
|
await writeIfMissing(
|
|
81030
|
-
|
|
81382
|
+
resolve54(projectDir, "vibe.project.yaml"),
|
|
81031
81383
|
renderProjectYaml({ name: projectName }),
|
|
81032
81384
|
options.force,
|
|
81033
81385
|
options.dryRun
|
|
81034
81386
|
)
|
|
81035
81387
|
);
|
|
81388
|
+
if (options.mcp === true) {
|
|
81389
|
+
actions.push(
|
|
81390
|
+
...await setupProjectMcpTargets(projectDir, targetHosts, {
|
|
81391
|
+
force: options.force === true,
|
|
81392
|
+
dryRun: options.dryRun === true
|
|
81393
|
+
})
|
|
81394
|
+
);
|
|
81395
|
+
}
|
|
81036
81396
|
if (isJsonMode()) {
|
|
81037
81397
|
outputSuccess({
|
|
81038
81398
|
command: "init",
|
|
@@ -81117,7 +81477,7 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81117
81477
|
)
|
|
81118
81478
|
);
|
|
81119
81479
|
}
|
|
81120
|
-
const projectDir =
|
|
81480
|
+
const projectDir = resolve54(projectDirArg);
|
|
81121
81481
|
const projectName = basename19(projectDir);
|
|
81122
81482
|
const groups = describeSceneScaffold({ dir: projectDir, profile });
|
|
81123
81483
|
const fromBrief = typeof options.from === "string" && options.from.trim() ? await readBriefOrLiteral(String(options.from), process.cwd()) : null;
|
|
@@ -81170,14 +81530,14 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81170
81530
|
aspect,
|
|
81171
81531
|
visualStyle
|
|
81172
81532
|
});
|
|
81173
|
-
const storyboardPath2 =
|
|
81174
|
-
const designPath =
|
|
81175
|
-
if (options.force || result.created.includes(storyboardPath2) || !
|
|
81176
|
-
await
|
|
81533
|
+
const storyboardPath2 = resolve54(projectDir, "STORYBOARD.md");
|
|
81534
|
+
const designPath = resolve54(projectDir, "DESIGN.md");
|
|
81535
|
+
if (options.force || result.created.includes(storyboardPath2) || !existsSync41(storyboardPath2)) {
|
|
81536
|
+
await writeFile45(storyboardPath2, draft.storyboardMd, "utf-8");
|
|
81177
81537
|
if (!result.created.includes(storyboardPath2)) result.created.push(storyboardPath2);
|
|
81178
81538
|
}
|
|
81179
|
-
if (options.force || result.created.includes(designPath) || !
|
|
81180
|
-
await
|
|
81539
|
+
if (options.force || result.created.includes(designPath) || !existsSync41(designPath)) {
|
|
81540
|
+
await writeFile45(designPath, draft.designMd, "utf-8");
|
|
81181
81541
|
if (!result.created.includes(designPath)) result.created.push(designPath);
|
|
81182
81542
|
}
|
|
81183
81543
|
draftWarnings.push(...draft.warnings);
|
|
@@ -81187,6 +81547,10 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81187
81547
|
projectDir,
|
|
81188
81548
|
hosts: deriveInstallHosts(detectedIds)
|
|
81189
81549
|
}) : { success: true, files: [], bundleVersion: "not-installed" };
|
|
81550
|
+
const mcpActions = options.mcp === true ? await setupProjectMcpTargets(projectDir, detectedIds, {
|
|
81551
|
+
force: options.force === true,
|
|
81552
|
+
dryRun: false
|
|
81553
|
+
}) : [];
|
|
81190
81554
|
if (isJsonMode()) {
|
|
81191
81555
|
outputSuccess({
|
|
81192
81556
|
command: "init",
|
|
@@ -81206,6 +81570,7 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81206
81570
|
groups: result.groups,
|
|
81207
81571
|
skillFiles: skillResult.files,
|
|
81208
81572
|
skillBundleVersion: skillResult.bundleVersion,
|
|
81573
|
+
mcpFiles: mcpActions,
|
|
81209
81574
|
warnings: draftWarnings
|
|
81210
81575
|
}
|
|
81211
81576
|
});
|
|
@@ -81243,6 +81608,10 @@ async function runSceneInit(projectDirArg, options, startedAt) {
|
|
|
81243
81608
|
for (const f of skillResult.files.filter((f2) => f2.status === "wrote")) {
|
|
81244
81609
|
console.log(source_default.green(` + ${f.path.replace(projectDir + "/", "")}`));
|
|
81245
81610
|
}
|
|
81611
|
+
for (const f of mcpActions) {
|
|
81612
|
+
const icon = f.status === "wrote" || f.status === "merged" ? source_default.green("+") : source_default.dim("\xB7");
|
|
81613
|
+
console.log(`${icon} ${f.path.replace(projectDir + "/", "")} ${source_default.dim(`(${f.status})`)}`);
|
|
81614
|
+
}
|
|
81246
81615
|
console.log();
|
|
81247
81616
|
console.log(source_default.dim(`Tip: cd ${projectDirArg} before running the next commands.`));
|
|
81248
81617
|
console.log();
|
|
@@ -81290,9 +81659,9 @@ function printGroup(label, files, projectDir) {
|
|
|
81290
81659
|
}
|
|
81291
81660
|
}
|
|
81292
81661
|
async function readBriefOrLiteral(value, cwd) {
|
|
81293
|
-
const candidate =
|
|
81294
|
-
if (
|
|
81295
|
-
return
|
|
81662
|
+
const candidate = resolve54(cwd, value);
|
|
81663
|
+
if (existsSync41(candidate)) {
|
|
81664
|
+
return readFile38(candidate, "utf-8");
|
|
81296
81665
|
}
|
|
81297
81666
|
return value;
|
|
81298
81667
|
}
|
|
@@ -81311,32 +81680,65 @@ function resolveTargets(agent) {
|
|
|
81311
81680
|
}
|
|
81312
81681
|
return [agent];
|
|
81313
81682
|
}
|
|
81683
|
+
async function setupProjectMcpTargets(projectDir, targetHosts, opts) {
|
|
81684
|
+
const ids = /* @__PURE__ */ new Set();
|
|
81685
|
+
if (targetHosts.includes("codex")) ids.add("codex");
|
|
81686
|
+
if (targetHosts.includes("claude-code")) ids.add("claude-code");
|
|
81687
|
+
if (targetHosts.includes("cursor")) ids.add("cursor");
|
|
81688
|
+
if (targetHosts.length === 0) {
|
|
81689
|
+
ids.add("codex");
|
|
81690
|
+
ids.add("claude-code");
|
|
81691
|
+
ids.add("cursor");
|
|
81692
|
+
}
|
|
81693
|
+
const actions = [];
|
|
81694
|
+
for (const host of hostDefinitions(projectDir).filter((h) => ids.has(h.id))) {
|
|
81695
|
+
const plan = await planHostSetup(host, projectDir, {
|
|
81696
|
+
write: true,
|
|
81697
|
+
dryRun: opts.dryRun,
|
|
81698
|
+
force: opts.force
|
|
81699
|
+
});
|
|
81700
|
+
const configAction = plan.files.find((file) => file.path === plan.configPath);
|
|
81701
|
+
if (!configAction) continue;
|
|
81702
|
+
actions.push({
|
|
81703
|
+
path: configAction.path,
|
|
81704
|
+
status: normalizeHostAction(configAction.status),
|
|
81705
|
+
reason: configAction.reason
|
|
81706
|
+
});
|
|
81707
|
+
}
|
|
81708
|
+
return actions;
|
|
81709
|
+
}
|
|
81710
|
+
function normalizeHostAction(status) {
|
|
81711
|
+
if (status === "merged") return "merged";
|
|
81712
|
+
if (status === "wrote") return "wrote";
|
|
81713
|
+
if (status === "skipped-exists") return "skipped-exists";
|
|
81714
|
+
return "would-write";
|
|
81715
|
+
}
|
|
81314
81716
|
async function writeIfMissing(absPath, content, force, dryRun) {
|
|
81315
|
-
const exists =
|
|
81717
|
+
const exists = existsSync41(absPath);
|
|
81316
81718
|
if (exists && !force) {
|
|
81317
81719
|
return { path: absPath, status: "skipped-exists", reason: "(use --force to overwrite)" };
|
|
81318
81720
|
}
|
|
81319
81721
|
if (dryRun) {
|
|
81320
81722
|
return { path: absPath, status: "would-write" };
|
|
81321
81723
|
}
|
|
81322
|
-
await
|
|
81323
|
-
await
|
|
81724
|
+
await mkdir23(dirname19(absPath), { recursive: true });
|
|
81725
|
+
await writeFile45(absPath, content, "utf-8");
|
|
81324
81726
|
return { path: absPath, status: "wrote" };
|
|
81325
81727
|
}
|
|
81326
81728
|
async function mergeGitignore(absPath, additions, dryRun) {
|
|
81327
81729
|
const marker = "# VibeFrame";
|
|
81328
|
-
if (!
|
|
81730
|
+
if (!existsSync41(absPath)) {
|
|
81329
81731
|
if (dryRun) return { path: absPath, status: "would-write" };
|
|
81330
|
-
await
|
|
81732
|
+
await writeFile45(absPath, additions.trimStart(), "utf-8");
|
|
81331
81733
|
return { path: absPath, status: "wrote" };
|
|
81332
81734
|
}
|
|
81333
|
-
const existing = await
|
|
81735
|
+
const existing = await readFile38(absPath, "utf-8");
|
|
81334
81736
|
if (existing.includes(marker)) {
|
|
81335
81737
|
return { path: absPath, status: "skipped-exists", reason: "(already has VibeFrame block)" };
|
|
81336
81738
|
}
|
|
81337
81739
|
if (dryRun) return { path: absPath, status: "merged" };
|
|
81338
81740
|
const trailing = existing.endsWith("\n") ? "" : "\n";
|
|
81339
|
-
await
|
|
81741
|
+
await writeFile45(absPath, existing + trailing + additions, "utf-8");
|
|
81340
81742
|
return { path: absPath, status: "merged" };
|
|
81341
81743
|
}
|
|
81342
81744
|
function formatStatusIcon(status) {
|
|
@@ -81363,9 +81765,9 @@ init_storyboard_revise();
|
|
|
81363
81765
|
init_composer_resolve();
|
|
81364
81766
|
init_cost_tier();
|
|
81365
81767
|
init_output();
|
|
81366
|
-
import { readFile as
|
|
81367
|
-
import { existsSync as
|
|
81368
|
-
import { resolve as
|
|
81768
|
+
import { readFile as readFile40, writeFile as writeFile47 } from "node:fs/promises";
|
|
81769
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
81770
|
+
import { resolve as resolve56 } from "node:path";
|
|
81369
81771
|
var storyboardCommand = new Command("storyboard").description("Read, validate, and safely mutate STORYBOARD.md cue blocks").addHelpText("after", `
|
|
81370
81772
|
Examples:
|
|
81371
81773
|
$ vibe storyboard validate my-video --json
|
|
@@ -81377,7 +81779,7 @@ Examples:
|
|
|
81377
81779
|
`);
|
|
81378
81780
|
storyboardCommand.command("list").description("List beats, ids, cues, and durations from STORYBOARD.md").argument("[project-dir]", "Project directory", ".").action(async (projectDirArg) => {
|
|
81379
81781
|
const startedAt = Date.now();
|
|
81380
|
-
const projectDir =
|
|
81782
|
+
const projectDir = resolve56(projectDirArg);
|
|
81381
81783
|
const md = await readStoryboard(projectDir);
|
|
81382
81784
|
const parsed = parseStoryboard(md);
|
|
81383
81785
|
const data = {
|
|
@@ -81399,7 +81801,7 @@ storyboardCommand.command("list").description("List beats, ids, cues, and durati
|
|
|
81399
81801
|
});
|
|
81400
81802
|
storyboardCommand.command("get").description("Print one beat as structured JSON").argument("<project-dir>", "Project directory").argument("<beat>", "Beat id").action(async (projectDirArg, beatId) => {
|
|
81401
81803
|
const startedAt = Date.now();
|
|
81402
|
-
const projectDir =
|
|
81804
|
+
const projectDir = resolve56(projectDirArg);
|
|
81403
81805
|
const md = await readStoryboard(projectDir);
|
|
81404
81806
|
const beat = getStoryboardBeat(md, beatId);
|
|
81405
81807
|
if (!beat) {
|
|
@@ -81422,7 +81824,7 @@ storyboardCommand.command("get").description("Print one beat as structured JSON"
|
|
|
81422
81824
|
});
|
|
81423
81825
|
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
81826
|
const startedAt = Date.now();
|
|
81425
|
-
const projectDir =
|
|
81827
|
+
const projectDir = resolve56(projectDirArg);
|
|
81426
81828
|
if (!options.unset && (!valueParts || valueParts.length === 0)) {
|
|
81427
81829
|
exitWithError(usageError("Cue value is required unless --unset is passed."));
|
|
81428
81830
|
}
|
|
@@ -81441,7 +81843,7 @@ storyboardCommand.command("set").description("Update one cue in one beat without
|
|
|
81441
81843
|
} catch (error) {
|
|
81442
81844
|
exitWithError(usageError(error instanceof Error ? error.message : String(error)));
|
|
81443
81845
|
}
|
|
81444
|
-
await
|
|
81846
|
+
await writeFile47(storyboardPath(projectDir), next, "utf-8");
|
|
81445
81847
|
const beat = getStoryboardBeat(next, beatId);
|
|
81446
81848
|
outputSuccess({
|
|
81447
81849
|
command: "storyboard set",
|
|
@@ -81457,7 +81859,7 @@ storyboardCommand.command("set").description("Update one cue in one beat without
|
|
|
81457
81859
|
});
|
|
81458
81860
|
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
81861
|
const startedAt = Date.now();
|
|
81460
|
-
const projectDir =
|
|
81862
|
+
const projectDir = resolve56(projectDirArg);
|
|
81461
81863
|
const md = await readStoryboard(projectDir);
|
|
81462
81864
|
let next;
|
|
81463
81865
|
try {
|
|
@@ -81465,7 +81867,7 @@ storyboardCommand.command("move").description("Reorder beats safely").argument("
|
|
|
81465
81867
|
} catch (error) {
|
|
81466
81868
|
exitWithError(usageError(error instanceof Error ? error.message : String(error)));
|
|
81467
81869
|
}
|
|
81468
|
-
await
|
|
81870
|
+
await writeFile47(storyboardPath(projectDir), next, "utf-8");
|
|
81469
81871
|
const parsed = parseStoryboard(next);
|
|
81470
81872
|
outputSuccess({
|
|
81471
81873
|
command: "storyboard move",
|
|
@@ -81480,7 +81882,7 @@ storyboardCommand.command("move").description("Reorder beats safely").argument("
|
|
|
81480
81882
|
});
|
|
81481
81883
|
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
81884
|
const startedAt = Date.now();
|
|
81483
|
-
const projectDir =
|
|
81885
|
+
const projectDir = resolve56(projectDirArg);
|
|
81484
81886
|
const brief = await readBrief(options.from, process.cwd());
|
|
81485
81887
|
const duration = options.duration ? Number.parseFloat(options.duration) : void 0;
|
|
81486
81888
|
if (duration !== void 0 && (!Number.isFinite(duration) || duration <= 0)) {
|
|
@@ -81512,7 +81914,7 @@ storyboardCommand.command("revise").description("Revise STORYBOARD.md from a req
|
|
|
81512
81914
|
});
|
|
81513
81915
|
storyboardCommand.command("validate").description("Validate cue blocks and beat ids").argument("[project-dir]", "Project directory", ".").action(async (projectDirArg) => {
|
|
81514
81916
|
const startedAt = Date.now();
|
|
81515
|
-
const projectDir =
|
|
81917
|
+
const projectDir = resolve56(projectDirArg);
|
|
81516
81918
|
const md = await readStoryboard(projectDir);
|
|
81517
81919
|
const result = validateStoryboardMarkdown(md);
|
|
81518
81920
|
if (isJsonMode()) {
|
|
@@ -81547,13 +81949,13 @@ storyboardCommand.command("validate").description("Validate cue blocks and beat
|
|
|
81547
81949
|
});
|
|
81548
81950
|
async function readStoryboard(projectDir) {
|
|
81549
81951
|
const path2 = storyboardPath(projectDir);
|
|
81550
|
-
if (!
|
|
81952
|
+
if (!existsSync43(path2)) {
|
|
81551
81953
|
exitWithError(generalError(`STORYBOARD.md not found at ${path2}`, `Run 'vibe init ${projectDir} --from "<brief>"' first.`));
|
|
81552
81954
|
}
|
|
81553
|
-
return
|
|
81955
|
+
return readFile40(path2, "utf-8");
|
|
81554
81956
|
}
|
|
81555
81957
|
function storyboardPath(projectDir) {
|
|
81556
|
-
return
|
|
81958
|
+
return resolve56(projectDir, "STORYBOARD.md");
|
|
81557
81959
|
}
|
|
81558
81960
|
function parseComposer(value) {
|
|
81559
81961
|
if (value === void 0) return void 0;
|
|
@@ -81561,9 +81963,9 @@ function parseComposer(value) {
|
|
|
81561
81963
|
exitWithError(usageError(`Invalid --composer: ${value}`, "Must be one of: claude, openai, gemini"));
|
|
81562
81964
|
}
|
|
81563
81965
|
async function readBrief(value, cwd) {
|
|
81564
|
-
const candidate =
|
|
81565
|
-
if (
|
|
81566
|
-
return
|
|
81966
|
+
const candidate = resolve56(cwd, value);
|
|
81967
|
+
if (existsSync43(candidate)) {
|
|
81968
|
+
return readFile40(candidate, "utf-8");
|
|
81567
81969
|
}
|
|
81568
81970
|
return value;
|
|
81569
81971
|
}
|
|
@@ -81596,7 +81998,7 @@ init_esm();
|
|
|
81596
81998
|
init_source();
|
|
81597
81999
|
init_build_plan();
|
|
81598
82000
|
init_output();
|
|
81599
|
-
import { resolve as
|
|
82001
|
+
import { resolve as resolve59 } from "node:path";
|
|
81600
82002
|
var VALID_STAGES = ["assets", "compose", "sync", "render", "all"];
|
|
81601
82003
|
var VALID_MODES = ["agent", "batch", "auto"];
|
|
81602
82004
|
var VALID_TTS_PROVIDERS = ["auto", "elevenlabs", "kokoro"];
|
|
@@ -81644,7 +82046,7 @@ var planCommand = new Command("plan").description("Read STORYBOARD.md and show b
|
|
|
81644
82046
|
)
|
|
81645
82047
|
);
|
|
81646
82048
|
}
|
|
81647
|
-
const projectDir =
|
|
82049
|
+
const projectDir = resolve59(projectDirArg);
|
|
81648
82050
|
const plan = await createBuildPlan({
|
|
81649
82051
|
projectDir,
|
|
81650
82052
|
stage,
|
|
@@ -81789,8 +82191,8 @@ init_scene_build();
|
|
|
81789
82191
|
init_build_plan();
|
|
81790
82192
|
init_storyboard_parse();
|
|
81791
82193
|
init_output();
|
|
81792
|
-
import { resolve as
|
|
81793
|
-
import { readFileSync as readFileSync3, existsSync as
|
|
82194
|
+
import { resolve as resolve64, join as join24 } from "node:path";
|
|
82195
|
+
import { readFileSync as readFileSync3, existsSync as existsSync48 } from "node:fs";
|
|
81794
82196
|
var VALID_MODES2 = ["agent", "batch", "auto"];
|
|
81795
82197
|
var VALID_STAGES2 = ["assets", "compose", "sync", "render", "all"];
|
|
81796
82198
|
var VALID_IMAGE_PROVIDERS2 = ["openai", "gemini", "grok"];
|
|
@@ -81807,7 +82209,7 @@ Examples:
|
|
|
81807
82209
|
Advanced equivalent: \`vibe scene build\`.`
|
|
81808
82210
|
).action(async (projectDirArg, options) => {
|
|
81809
82211
|
const startedAt = Date.now();
|
|
81810
|
-
const projectDir =
|
|
82212
|
+
const projectDir = resolve64(projectDirArg);
|
|
81811
82213
|
const mode = String(options.mode ?? "auto");
|
|
81812
82214
|
if (!VALID_MODES2.includes(mode)) {
|
|
81813
82215
|
exitWithError(
|
|
@@ -82153,8 +82555,8 @@ function buildPlanValidationFailureData(plan) {
|
|
|
82153
82555
|
};
|
|
82154
82556
|
}
|
|
82155
82557
|
function estimateBuildCost(params) {
|
|
82156
|
-
const storyboardPath2 =
|
|
82157
|
-
if (!
|
|
82558
|
+
const storyboardPath2 = join24(params.projectDir, "STORYBOARD.md");
|
|
82559
|
+
if (!existsSync48(storyboardPath2)) return null;
|
|
82158
82560
|
let beats = 0;
|
|
82159
82561
|
try {
|
|
82160
82562
|
const md = readFileSync3(storyboardPath2, "utf-8");
|
|
@@ -82298,7 +82700,7 @@ init_source();
|
|
|
82298
82700
|
init_ora();
|
|
82299
82701
|
init_scene_render();
|
|
82300
82702
|
init_output();
|
|
82301
|
-
import { resolve as
|
|
82703
|
+
import { resolve as resolve65 } from "node:path";
|
|
82302
82704
|
var VALID_FPS = [24, 30, 60];
|
|
82303
82705
|
var VALID_QUALITIES = ["draft", "standard", "high"];
|
|
82304
82706
|
var VALID_FORMATS = ["mp4", "webm", "mov"];
|
|
@@ -82309,7 +82711,7 @@ Examples:
|
|
|
82309
82711
|
|
|
82310
82712
|
Alias note: this is the project-level entrypoint for \`vibe scene render\`.`).action(async (projectDirArg, options) => {
|
|
82311
82713
|
const startedAt = Date.now();
|
|
82312
|
-
const projectDir =
|
|
82714
|
+
const projectDir = resolve65(projectDirArg);
|
|
82313
82715
|
const fps = parseFps(String(options.fps));
|
|
82314
82716
|
const quality = parseQuality(String(options.quality));
|
|
82315
82717
|
const format = parseFormat(String(options.format));
|
|
@@ -82432,7 +82834,7 @@ init_source();
|
|
|
82432
82834
|
init_cost_tier();
|
|
82433
82835
|
init_status_jobs();
|
|
82434
82836
|
init_output();
|
|
82435
|
-
import { resolve as
|
|
82837
|
+
import { resolve as resolve66 } from "node:path";
|
|
82436
82838
|
var statusCommand = new Command("status").description("Inspect local async jobs and project workflow status").addHelpText("after", `
|
|
82437
82839
|
Examples:
|
|
82438
82840
|
$ vibe status job job_abc123 --json
|
|
@@ -82443,7 +82845,7 @@ Examples:
|
|
|
82443
82845
|
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
82846
|
const startedAt = Date.now();
|
|
82445
82847
|
try {
|
|
82446
|
-
const projectDir = options.project ?
|
|
82848
|
+
const projectDir = options.project ? resolve66(options.project) : findProjectRoot();
|
|
82447
82849
|
const record = await readJobRecord(jobId, projectDir);
|
|
82448
82850
|
if (!record) {
|
|
82449
82851
|
exitWithError(generalError(`Job not found: ${jobId}`, `Run 'vibe status project ${projectDir} --json' to list known jobs.`));
|
|
@@ -82471,7 +82873,7 @@ applyTier(statusCommand.commands[statusCommand.commands.length - 1], "free");
|
|
|
82471
82873
|
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
82874
|
const startedAt = Date.now();
|
|
82473
82875
|
try {
|
|
82474
|
-
const result = await inspectProjectStatus(
|
|
82876
|
+
const result = await inspectProjectStatus(resolve66(projectDirArg), {
|
|
82475
82877
|
refresh: options.refresh === true
|
|
82476
82878
|
});
|
|
82477
82879
|
if (isJsonMode()) {
|
|
@@ -82567,8 +82969,8 @@ init_composer_resolve();
|
|
|
82567
82969
|
init_cost_tier();
|
|
82568
82970
|
init_scene_build_mode();
|
|
82569
82971
|
init_output();
|
|
82570
|
-
import { existsSync as
|
|
82571
|
-
import { resolve as
|
|
82972
|
+
import { existsSync as existsSync49 } from "node:fs";
|
|
82973
|
+
import { resolve as resolve67 } from "node:path";
|
|
82572
82974
|
var COMMAND_KEY_MAP = getCommandKeyMap();
|
|
82573
82975
|
var FREE_COMMANDS = [
|
|
82574
82976
|
"edit silence-cut",
|
|
@@ -82695,14 +83097,14 @@ async function runDiagnostics() {
|
|
|
82695
83097
|
installed = false;
|
|
82696
83098
|
}
|
|
82697
83099
|
} else if (toolName === "chrome") {
|
|
82698
|
-
const { existsSync:
|
|
82699
|
-
const { homedir:
|
|
82700
|
-
const { join:
|
|
83100
|
+
const { existsSync: existsSync55 } = await import("node:fs");
|
|
83101
|
+
const { homedir: homedir7 } = await import("node:os");
|
|
83102
|
+
const { join: join27 } = await import("node:path");
|
|
82701
83103
|
const chromePaths = [
|
|
82702
83104
|
process.env.HYPERFRAMES_CHROME_PATH,
|
|
82703
83105
|
process.env.CHROME_PATH,
|
|
82704
|
-
|
|
82705
|
-
|
|
83106
|
+
join27(
|
|
83107
|
+
homedir7(),
|
|
82706
83108
|
".cache",
|
|
82707
83109
|
"puppeteer",
|
|
82708
83110
|
"chrome-headless-shell",
|
|
@@ -82716,7 +83118,7 @@ async function runDiagnostics() {
|
|
|
82716
83118
|
"/usr/bin/chromium",
|
|
82717
83119
|
"/usr/bin/chromium-browser"
|
|
82718
83120
|
];
|
|
82719
|
-
installed = chromePaths.some((p) => p &&
|
|
83121
|
+
installed = chromePaths.some((p) => p && existsSync55(p));
|
|
82720
83122
|
} else {
|
|
82721
83123
|
installed = commandExists(toolName);
|
|
82722
83124
|
}
|
|
@@ -82756,7 +83158,7 @@ async function runDiagnostics() {
|
|
|
82756
83158
|
}
|
|
82757
83159
|
const projectFiles = ["AGENTS.md", "CLAUDE.md", "vibe.project.yaml"].map((rel) => ({
|
|
82758
83160
|
path: rel,
|
|
82759
|
-
exists:
|
|
83161
|
+
exists: existsSync49(resolve67(cwd, rel))
|
|
82760
83162
|
}));
|
|
82761
83163
|
const projectInitialized = projectFiles.some((f) => f.exists);
|
|
82762
83164
|
const nearestProjectConfigPath = await findProjectConfigPath(cwd);
|
|
@@ -82775,8 +83177,8 @@ async function runDiagnostics() {
|
|
|
82775
83177
|
} catch (err) {
|
|
82776
83178
|
if (!(err instanceof ComposerResolveError)) throw err;
|
|
82777
83179
|
}
|
|
82778
|
-
const sceneProjectInCwd =
|
|
82779
|
-
const skillInstalled =
|
|
83180
|
+
const sceneProjectInCwd = existsSync49(resolve67(cwd, "STORYBOARD.md"));
|
|
83181
|
+
const skillInstalled = existsSync49(resolve67(cwd, "SKILL.md"));
|
|
82780
83182
|
return {
|
|
82781
83183
|
system: {
|
|
82782
83184
|
node: { version: nodeVersion, ok: true },
|
|
@@ -83123,6 +83525,198 @@ function pickNextStep(results, hasMissingProviders) {
|
|
|
83123
83525
|
return null;
|
|
83124
83526
|
}
|
|
83125
83527
|
|
|
83528
|
+
// src/commands/host.ts
|
|
83529
|
+
init_esm();
|
|
83530
|
+
init_source();
|
|
83531
|
+
init_exec_safe();
|
|
83532
|
+
init_cost_tier();
|
|
83533
|
+
import { resolve as resolve68 } from "node:path";
|
|
83534
|
+
init_output();
|
|
83535
|
+
var hostCommand = new Command("host").description("Set up Codex, Claude, and Cursor app integrations").addHelpText(
|
|
83536
|
+
"after",
|
|
83537
|
+
`
|
|
83538
|
+
Examples:
|
|
83539
|
+
$ vibe host list --json
|
|
83540
|
+
$ vibe host setup all Print MCP/project config snippets
|
|
83541
|
+
$ vibe host setup cursor --write Write .cursor/mcp.json
|
|
83542
|
+
$ vibe host doctor all --json Check host-app readiness
|
|
83543
|
+
`
|
|
83544
|
+
);
|
|
83545
|
+
hostCommand.command("list").description("List supported app hosts and integration surfaces").action(() => {
|
|
83546
|
+
const startedAt = Date.now();
|
|
83547
|
+
const hosts = hostDefinitions(resolve68(".")).map((host) => ({
|
|
83548
|
+
id: host.id,
|
|
83549
|
+
label: host.label,
|
|
83550
|
+
surfaces: host.surfaces,
|
|
83551
|
+
guidanceFiles: host.guidanceFiles,
|
|
83552
|
+
notes: host.notes
|
|
83553
|
+
}));
|
|
83554
|
+
if (isJsonMode()) {
|
|
83555
|
+
outputSuccess({ command: "host list", startedAt, data: { hosts } });
|
|
83556
|
+
return;
|
|
83557
|
+
}
|
|
83558
|
+
console.log();
|
|
83559
|
+
console.log(source_default.bold.cyan("Supported Host Apps"));
|
|
83560
|
+
console.log(source_default.dim("\u2500".repeat(60)));
|
|
83561
|
+
for (const host of hosts) {
|
|
83562
|
+
console.log(` ${source_default.bold(host.label)} ${source_default.dim(`(${host.id})`)}`);
|
|
83563
|
+
console.log(source_default.dim(` surfaces: ${host.surfaces.join(", ")}`));
|
|
83564
|
+
if (host.guidanceFiles.length > 0) {
|
|
83565
|
+
console.log(source_default.dim(` files: ${host.guidanceFiles.join(", ")}`));
|
|
83566
|
+
}
|
|
83567
|
+
}
|
|
83568
|
+
console.log();
|
|
83569
|
+
});
|
|
83570
|
+
applyTier(hostCommand.commands[hostCommand.commands.length - 1], "free");
|
|
83571
|
+
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) => {
|
|
83572
|
+
const startedAt = Date.now();
|
|
83573
|
+
const selection = validateHostSelection(hostArg);
|
|
83574
|
+
const projectDir = resolve68(projectDirArg);
|
|
83575
|
+
const ids = resolveHostSelection(selection);
|
|
83576
|
+
const defs = hostDefinitions(projectDir).filter((host) => ids.includes(host.id));
|
|
83577
|
+
const plans = [];
|
|
83578
|
+
for (const host of defs) {
|
|
83579
|
+
plans.push(
|
|
83580
|
+
await planHostSetup(host, projectDir, {
|
|
83581
|
+
write: Boolean(options.write),
|
|
83582
|
+
dryRun: Boolean(options.dryRun),
|
|
83583
|
+
force: Boolean(options.force)
|
|
83584
|
+
})
|
|
83585
|
+
);
|
|
83586
|
+
}
|
|
83587
|
+
if (isJsonMode()) {
|
|
83588
|
+
outputSuccess({
|
|
83589
|
+
command: "host setup",
|
|
83590
|
+
startedAt,
|
|
83591
|
+
...options.dryRun ? { dryRun: true } : {},
|
|
83592
|
+
data: {
|
|
83593
|
+
projectDir,
|
|
83594
|
+
selection,
|
|
83595
|
+
write: Boolean(options.write),
|
|
83596
|
+
hosts: plans.map(serializeSetupPlan)
|
|
83597
|
+
},
|
|
83598
|
+
warnings: plans.flatMap((plan) => plan.warnings)
|
|
83599
|
+
});
|
|
83600
|
+
return;
|
|
83601
|
+
}
|
|
83602
|
+
printSetupPlans(plans, { write: Boolean(options.write), dryRun: Boolean(options.dryRun) });
|
|
83603
|
+
});
|
|
83604
|
+
applyTier(hostCommand.commands[hostCommand.commands.length - 1], "free");
|
|
83605
|
+
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) => {
|
|
83606
|
+
const startedAt = Date.now();
|
|
83607
|
+
const selection = validateHostSelection(hostArg);
|
|
83608
|
+
const projectDir = resolve68(projectDirArg);
|
|
83609
|
+
const ids = resolveHostSelection(selection);
|
|
83610
|
+
const defs = hostDefinitions(projectDir).filter((host) => ids.includes(host.id));
|
|
83611
|
+
const hosts = await Promise.all(defs.map((host) => inspectHost(host, projectDir)));
|
|
83612
|
+
const system = {
|
|
83613
|
+
vibe: commandExists("vibe"),
|
|
83614
|
+
npx: commandExists("npx")
|
|
83615
|
+
};
|
|
83616
|
+
const warnings = [
|
|
83617
|
+
...system.vibe ? [] : ["vibe binary not found on PATH"],
|
|
83618
|
+
...system.npx ? [] : ["npx not found on PATH; MCP stdio config needs npx"],
|
|
83619
|
+
...hosts.flatMap((host) => host.warnings)
|
|
83620
|
+
];
|
|
83621
|
+
if (isJsonMode()) {
|
|
83622
|
+
outputSuccess({
|
|
83623
|
+
command: "host doctor",
|
|
83624
|
+
startedAt,
|
|
83625
|
+
data: {
|
|
83626
|
+
projectDir,
|
|
83627
|
+
selection,
|
|
83628
|
+
system,
|
|
83629
|
+
hosts: hosts.map(serializeDoctorResult)
|
|
83630
|
+
},
|
|
83631
|
+
warnings
|
|
83632
|
+
});
|
|
83633
|
+
return;
|
|
83634
|
+
}
|
|
83635
|
+
printDoctor(hosts, system, warnings);
|
|
83636
|
+
});
|
|
83637
|
+
applyTier(hostCommand.commands[hostCommand.commands.length - 1], "free");
|
|
83638
|
+
function validateHostSelection(value) {
|
|
83639
|
+
if (HOST_SELECTIONS.includes(value)) return value;
|
|
83640
|
+
exitWithError(
|
|
83641
|
+
usageError(`Invalid host target: ${value}`, `Must be one of: ${HOST_SELECTIONS.join(", ")}`)
|
|
83642
|
+
);
|
|
83643
|
+
}
|
|
83644
|
+
function serializeSetupPlan(plan) {
|
|
83645
|
+
return {
|
|
83646
|
+
id: plan.host.id,
|
|
83647
|
+
label: plan.host.label,
|
|
83648
|
+
surfaces: plan.host.surfaces,
|
|
83649
|
+
configPath: plan.configPath,
|
|
83650
|
+
snippet: plan.snippet,
|
|
83651
|
+
...plan.command ? { command: plan.command } : {},
|
|
83652
|
+
files: plan.files,
|
|
83653
|
+
warnings: plan.warnings,
|
|
83654
|
+
nextSteps: plan.nextSteps
|
|
83655
|
+
};
|
|
83656
|
+
}
|
|
83657
|
+
function serializeDoctorResult(result) {
|
|
83658
|
+
return {
|
|
83659
|
+
id: result.host.id,
|
|
83660
|
+
label: result.host.label,
|
|
83661
|
+
surfaces: result.host.surfaces,
|
|
83662
|
+
configPath: result.configPath,
|
|
83663
|
+
configured: result.configured,
|
|
83664
|
+
guidanceFiles: result.guidanceFiles,
|
|
83665
|
+
warnings: result.warnings,
|
|
83666
|
+
nextSteps: result.nextSteps
|
|
83667
|
+
};
|
|
83668
|
+
}
|
|
83669
|
+
function printSetupPlans(plans, opts) {
|
|
83670
|
+
console.log();
|
|
83671
|
+
console.log(source_default.bold.cyan("VibeFrame Host Setup"));
|
|
83672
|
+
console.log(source_default.dim("\u2500".repeat(60)));
|
|
83673
|
+
if (!opts.write) {
|
|
83674
|
+
console.log(source_default.dim("Snippet mode \u2014 no files were changed. Pass --write to apply."));
|
|
83675
|
+
} else if (opts.dryRun) {
|
|
83676
|
+
console.log(source_default.dim("Dry run \u2014 no files were changed."));
|
|
83677
|
+
}
|
|
83678
|
+
for (const plan of plans) {
|
|
83679
|
+
console.log();
|
|
83680
|
+
console.log(source_default.bold(plan.host.label) + source_default.dim(` (${plan.host.id})`));
|
|
83681
|
+
console.log(source_default.dim(`Config: ${plan.configPath}`));
|
|
83682
|
+
if (plan.command) console.log(source_default.dim(`Command: ${plan.command}`));
|
|
83683
|
+
console.log();
|
|
83684
|
+
console.log(plan.snippet);
|
|
83685
|
+
if (plan.files.length > 0) {
|
|
83686
|
+
console.log();
|
|
83687
|
+
for (const file of plan.files) {
|
|
83688
|
+
console.log(` ${formatAction(file.status)} ${file.path}${file.reason ? source_default.dim(` ${file.reason}`) : ""}`);
|
|
83689
|
+
}
|
|
83690
|
+
}
|
|
83691
|
+
for (const warning of plan.warnings) console.log(source_default.yellow(` Warning: ${warning}`));
|
|
83692
|
+
}
|
|
83693
|
+
console.log();
|
|
83694
|
+
}
|
|
83695
|
+
function printDoctor(hosts, system, warnings) {
|
|
83696
|
+
console.log();
|
|
83697
|
+
console.log(source_default.bold.cyan("VibeFrame Host Doctor"));
|
|
83698
|
+
console.log(source_default.dim("\u2500".repeat(60)));
|
|
83699
|
+
console.log(` vibe: ${system.vibe ? source_default.green("OK") : source_default.red("MISSING")}`);
|
|
83700
|
+
console.log(` npx: ${system.npx ? source_default.green("OK") : source_default.red("MISSING")}`);
|
|
83701
|
+
console.log();
|
|
83702
|
+
for (const host of hosts) {
|
|
83703
|
+
console.log(source_default.bold(host.host.label) + source_default.dim(` (${host.host.id})`));
|
|
83704
|
+
console.log(` MCP config: ${host.configured ? source_default.green("OK") : source_default.yellow("missing")} ${source_default.dim(host.configPath)}`);
|
|
83705
|
+
for (const file of host.guidanceFiles) {
|
|
83706
|
+
const ok = file.status !== "missing";
|
|
83707
|
+
console.log(` ${ok ? source_default.green("OK") : source_default.yellow("MISSING")} ${source_default.dim(file.path)}`);
|
|
83708
|
+
}
|
|
83709
|
+
console.log();
|
|
83710
|
+
}
|
|
83711
|
+
for (const warning of warnings) console.log(source_default.yellow(`Warning: ${warning}`));
|
|
83712
|
+
}
|
|
83713
|
+
function formatAction(status) {
|
|
83714
|
+
if (status === "wrote" || status === "merged") return source_default.green("\u2713");
|
|
83715
|
+
if (status.startsWith("would")) return source_default.cyan("\u2192");
|
|
83716
|
+
if (status === "missing") return source_default.yellow("!");
|
|
83717
|
+
return source_default.dim("\u25CB");
|
|
83718
|
+
}
|
|
83719
|
+
|
|
83126
83720
|
// src/commands/demo.ts
|
|
83127
83721
|
init_esm();
|
|
83128
83722
|
init_source();
|
|
@@ -83131,10 +83725,10 @@ init_exec_safe();
|
|
|
83131
83725
|
init_detect();
|
|
83132
83726
|
init_ai_edit();
|
|
83133
83727
|
init_output();
|
|
83134
|
-
import { resolve as
|
|
83135
|
-
import { existsSync as
|
|
83136
|
-
import { mkdir as
|
|
83137
|
-
var DEMO_DIR =
|
|
83728
|
+
import { resolve as resolve69 } from "node:path";
|
|
83729
|
+
import { existsSync as existsSync50 } from "node:fs";
|
|
83730
|
+
import { mkdir as mkdir26, rm as rm4 } from "node:fs/promises";
|
|
83731
|
+
var DEMO_DIR = resolve69(process.cwd(), ".vibeframe-demo");
|
|
83138
83732
|
async function generateTestVideo(outputPath) {
|
|
83139
83733
|
const filter = [
|
|
83140
83734
|
// Video: color bars with text
|
|
@@ -83163,7 +83757,7 @@ async function generateTestVideo(outputPath) {
|
|
|
83163
83757
|
"-y",
|
|
83164
83758
|
outputPath
|
|
83165
83759
|
], { timeout: 3e4, maxBuffer: 50 * 1024 * 1024 });
|
|
83166
|
-
return
|
|
83760
|
+
return existsSync50(outputPath);
|
|
83167
83761
|
} catch {
|
|
83168
83762
|
try {
|
|
83169
83763
|
await execSafe("ffmpeg", [
|
|
@@ -83189,7 +83783,7 @@ async function generateTestVideo(outputPath) {
|
|
|
83189
83783
|
"-y",
|
|
83190
83784
|
outputPath
|
|
83191
83785
|
], { timeout: 3e4, maxBuffer: 50 * 1024 * 1024 });
|
|
83192
|
-
return
|
|
83786
|
+
return existsSync50(outputPath);
|
|
83193
83787
|
} catch {
|
|
83194
83788
|
return false;
|
|
83195
83789
|
}
|
|
@@ -83213,8 +83807,8 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83213
83807
|
console.log(source_default.dim(" " + "\u2500".repeat(50)));
|
|
83214
83808
|
console.log();
|
|
83215
83809
|
}
|
|
83216
|
-
await
|
|
83217
|
-
const testVideo =
|
|
83810
|
+
await mkdir26(DEMO_DIR, { recursive: true });
|
|
83811
|
+
const testVideo = resolve69(DEMO_DIR, "test-input.mp4");
|
|
83218
83812
|
const genSpinner = !isJson ? ora("Generating test video...").start() : null;
|
|
83219
83813
|
const generated = await generateTestVideo(testVideo);
|
|
83220
83814
|
if (!generated) {
|
|
@@ -83243,7 +83837,7 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83243
83837
|
name: "Silence Cut",
|
|
83244
83838
|
description: "Removing silent segments",
|
|
83245
83839
|
run: async () => {
|
|
83246
|
-
const output =
|
|
83840
|
+
const output = resolve69(DEMO_DIR, "silence-cut.mp4");
|
|
83247
83841
|
const r = await executeSilenceCut({ videoPath: testVideo, outputPath: output, padding: 0.1 });
|
|
83248
83842
|
if (r.success && r.totalDuration && r.silentDuration) {
|
|
83249
83843
|
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 +83849,7 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83255
83849
|
name: "Noise Reduce",
|
|
83256
83850
|
description: "Reducing background noise",
|
|
83257
83851
|
run: async () => {
|
|
83258
|
-
const output =
|
|
83852
|
+
const output = resolve69(DEMO_DIR, "noise-reduced.mp4");
|
|
83259
83853
|
const r = await executeNoiseReduce({ inputPath: testVideo, outputPath: output, strength: "medium" });
|
|
83260
83854
|
return { success: r.success, detail: r.success ? `Cleaned audio \u2192 ${output}` : r.error };
|
|
83261
83855
|
}
|
|
@@ -83264,7 +83858,7 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83264
83858
|
name: "Fade Effects",
|
|
83265
83859
|
description: "Adding fade in/out",
|
|
83266
83860
|
run: async () => {
|
|
83267
|
-
const output =
|
|
83861
|
+
const output = resolve69(DEMO_DIR, "faded.mp4");
|
|
83268
83862
|
const r = await executeFade({ videoPath: testVideo, outputPath: output, fadeIn: 1, fadeOut: 1 });
|
|
83269
83863
|
return { success: r.success, detail: r.success ? `1s fade in + 1s fade out \u2192 ${output}` : r.error };
|
|
83270
83864
|
}
|
|
@@ -83331,20 +83925,20 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
|
|
|
83331
83925
|
|
|
83332
83926
|
// src/commands/context.ts
|
|
83333
83927
|
init_esm();
|
|
83334
|
-
import { existsSync as
|
|
83335
|
-
import { readFile as
|
|
83336
|
-
import { resolve as
|
|
83928
|
+
import { existsSync as existsSync51 } from "node:fs";
|
|
83929
|
+
import { readFile as readFile45 } from "node:fs/promises";
|
|
83930
|
+
import { resolve as resolve70, dirname as dirname24 } from "node:path";
|
|
83337
83931
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
83338
83932
|
var __filename = fileURLToPath2(import.meta.url);
|
|
83339
|
-
var __dirname =
|
|
83933
|
+
var __dirname = dirname24(__filename);
|
|
83340
83934
|
function resolveContextPath(baseDir = __dirname) {
|
|
83341
83935
|
const candidates = [
|
|
83342
83936
|
// Bundled package layout: packages/cli/dist/index.js -> packages/cli/CONTEXT.md
|
|
83343
|
-
|
|
83937
|
+
resolve70(baseDir, "../CONTEXT.md"),
|
|
83344
83938
|
// Source/dev layout: packages/cli/src/commands/context.ts -> packages/cli/CONTEXT.md
|
|
83345
|
-
|
|
83939
|
+
resolve70(baseDir, "../../CONTEXT.md")
|
|
83346
83940
|
];
|
|
83347
|
-
return candidates.find((candidate) =>
|
|
83941
|
+
return candidates.find((candidate) => existsSync51(candidate)) ?? null;
|
|
83348
83942
|
}
|
|
83349
83943
|
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
83944
|
const options = {
|
|
@@ -83434,7 +84028,7 @@ var contextCommand = new Command("context").description("Print CLI context/guide
|
|
|
83434
84028
|
try {
|
|
83435
84029
|
const contextPath = resolveContextPath();
|
|
83436
84030
|
if (!contextPath) throw new Error("CONTEXT.md not found");
|
|
83437
|
-
const content = await
|
|
84031
|
+
const content = await readFile45(contextPath, "utf-8");
|
|
83438
84032
|
console.log(
|
|
83439
84033
|
content.replace(
|
|
83440
84034
|
"## Mental model",
|
|
@@ -84376,7 +84970,7 @@ async function startAgent(options = {}) {
|
|
|
84376
84970
|
console.log();
|
|
84377
84971
|
console.log(source_default.dim(" Commands: exit \xB7 reset \xB7 tools \xB7 context"));
|
|
84378
84972
|
console.log();
|
|
84379
|
-
return new Promise((
|
|
84973
|
+
return new Promise((resolve83) => {
|
|
84380
84974
|
if (typeof process.stdin.ref === "function") {
|
|
84381
84975
|
process.stdin.ref();
|
|
84382
84976
|
}
|
|
@@ -84483,7 +85077,7 @@ async function startAgent(options = {}) {
|
|
|
84483
85077
|
clearInterval(keepalive);
|
|
84484
85078
|
console.log();
|
|
84485
85079
|
console.log(source_default.dim("Goodbye!"));
|
|
84486
|
-
|
|
85080
|
+
resolve83();
|
|
84487
85081
|
});
|
|
84488
85082
|
rl.prompt();
|
|
84489
85083
|
});
|
|
@@ -84756,8 +85350,8 @@ init_source();
|
|
|
84756
85350
|
init_config();
|
|
84757
85351
|
init_schema();
|
|
84758
85352
|
init_api_key();
|
|
84759
|
-
import { access as access9, writeFile as
|
|
84760
|
-
import { dirname as
|
|
85353
|
+
import { access as access9, writeFile as writeFile59, mkdir as mkdir29 } from "node:fs/promises";
|
|
85354
|
+
import { dirname as dirname26 } from "node:path";
|
|
84761
85355
|
var BANNER_SHOWN_PATH = `${USER_CONFIG_DIR}/.banner-shown`;
|
|
84762
85356
|
async function isFirstRun() {
|
|
84763
85357
|
try {
|
|
@@ -84776,8 +85370,8 @@ async function isFirstRun() {
|
|
|
84776
85370
|
}
|
|
84777
85371
|
async function markBannerShown() {
|
|
84778
85372
|
try {
|
|
84779
|
-
await
|
|
84780
|
-
await
|
|
85373
|
+
await mkdir29(dirname26(BANNER_SHOWN_PATH), { recursive: true });
|
|
85374
|
+
await writeFile59(BANNER_SHOWN_PATH, (/* @__PURE__ */ new Date()).toISOString());
|
|
84781
85375
|
} catch {
|
|
84782
85376
|
}
|
|
84783
85377
|
}
|
|
@@ -84912,6 +85506,7 @@ this section shows the typical entry points by use case):
|
|
|
84912
85506
|
vibe schema --list --surface public Compact first-run command catalog
|
|
84913
85507
|
vibe schema generate.video JSON schema for any command
|
|
84914
85508
|
vibe context Agent integration quickstart
|
|
85509
|
+
vibe host setup all Configure Codex/Claude/Cursor app integrations
|
|
84915
85510
|
vibe agent Optional built-in agent when you do not use Claude Code/Codex/etc.
|
|
84916
85511
|
|
|
84917
85512
|
Common-flag note: most commands accept --dry-run to preview cost/output
|
|
@@ -85013,6 +85608,7 @@ program2.addCommand(buildCommand);
|
|
|
85013
85608
|
program2.addCommand(renderCommand);
|
|
85014
85609
|
program2.addCommand(statusCommand);
|
|
85015
85610
|
program2.addCommand(doctorCommand);
|
|
85611
|
+
program2.addCommand(hostCommand);
|
|
85016
85612
|
program2.addCommand(demoCommand, { hidden: true });
|
|
85017
85613
|
program2.addCommand(runCommand);
|
|
85018
85614
|
program2.addCommand(agentCommand);
|