@vibeframe/cli 0.91.3 → 0.91.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/index.js +111 -20
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -31683,6 +31683,18 @@ var init_open_url = __esm({
|
|
|
31683
31683
|
// src/utils/tty.ts
|
|
31684
31684
|
import { createInterface as createInterface2 } from "node:readline";
|
|
31685
31685
|
import { ReadStream } from "node:tty";
|
|
31686
|
+
function splitTTYInput(chunk) {
|
|
31687
|
+
const tokens = [];
|
|
31688
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
31689
|
+
if (chunk[i] === "\x1B" && chunk[i + 1] === "[" && i + 2 < chunk.length) {
|
|
31690
|
+
tokens.push(chunk.slice(i, i + 3));
|
|
31691
|
+
i += 2;
|
|
31692
|
+
} else {
|
|
31693
|
+
tokens.push(chunk[i]);
|
|
31694
|
+
}
|
|
31695
|
+
}
|
|
31696
|
+
return tokens;
|
|
31697
|
+
}
|
|
31686
31698
|
function getTTYInputStream() {
|
|
31687
31699
|
if (process.stdin.isTTY) {
|
|
31688
31700
|
return process.stdin;
|
|
@@ -31736,14 +31748,16 @@ async function prompt2(question) {
|
|
|
31736
31748
|
async function promptHidden(question, opts = {}) {
|
|
31737
31749
|
const input = getTTYInputStream();
|
|
31738
31750
|
return new Promise((resolve64) => {
|
|
31739
|
-
process.stdout.write(question);
|
|
31740
31751
|
let value = "";
|
|
31741
31752
|
if (typeof input.setRawMode === "function") {
|
|
31742
31753
|
input.setRawMode(true);
|
|
31743
31754
|
input.resume();
|
|
31744
31755
|
input.setEncoding("utf8");
|
|
31745
|
-
|
|
31756
|
+
let finished = false;
|
|
31757
|
+
const handleChar = (char) => {
|
|
31758
|
+
if (finished) return;
|
|
31746
31759
|
if (char === "\n" || char === "\r" || char === "") {
|
|
31760
|
+
finished = true;
|
|
31747
31761
|
input.setRawMode(false);
|
|
31748
31762
|
input.removeListener("data", onData);
|
|
31749
31763
|
process.stdout.write("\n");
|
|
@@ -31764,10 +31778,14 @@ async function promptHidden(question, opts = {}) {
|
|
|
31764
31778
|
process.stdout.write("*".repeat(char.length));
|
|
31765
31779
|
}
|
|
31766
31780
|
};
|
|
31781
|
+
const onData = (chunk) => {
|
|
31782
|
+
for (const char of splitTTYInput(chunk)) handleChar(char);
|
|
31783
|
+
};
|
|
31767
31784
|
input.on("data", onData);
|
|
31785
|
+
process.stdout.write(question);
|
|
31768
31786
|
} else {
|
|
31769
31787
|
const rl = createInterface2({ input, output: process.stdout });
|
|
31770
|
-
rl.question(
|
|
31788
|
+
rl.question(question, (answer) => {
|
|
31771
31789
|
rl.close();
|
|
31772
31790
|
resolve64(answer);
|
|
31773
31791
|
});
|
|
@@ -31796,8 +31814,11 @@ async function promptSelect(_question, options, defaultIndex = 0) {
|
|
|
31796
31814
|
input.setRawMode(true);
|
|
31797
31815
|
input.resume();
|
|
31798
31816
|
input.setEncoding("utf8");
|
|
31799
|
-
|
|
31817
|
+
let finished = false;
|
|
31818
|
+
const handleChar = (char) => {
|
|
31819
|
+
if (finished) return;
|
|
31800
31820
|
if (char === "\r" || char === "\n") {
|
|
31821
|
+
finished = true;
|
|
31801
31822
|
input.setRawMode(false);
|
|
31802
31823
|
input.removeListener("data", onData);
|
|
31803
31824
|
process.stdout.write("\n");
|
|
@@ -31814,6 +31835,7 @@ async function promptSelect(_question, options, defaultIndex = 0) {
|
|
|
31814
31835
|
render();
|
|
31815
31836
|
} else if (char >= "1" && char <= String(options.length)) {
|
|
31816
31837
|
selected = parseInt(char, 10) - 1;
|
|
31838
|
+
finished = true;
|
|
31817
31839
|
input.setRawMode(false);
|
|
31818
31840
|
input.removeListener("data", onData);
|
|
31819
31841
|
render();
|
|
@@ -31821,6 +31843,9 @@ async function promptSelect(_question, options, defaultIndex = 0) {
|
|
|
31821
31843
|
resolve64(selected);
|
|
31822
31844
|
}
|
|
31823
31845
|
};
|
|
31846
|
+
const onData = (chunk) => {
|
|
31847
|
+
for (const char of splitTTYInput(chunk)) handleChar(char);
|
|
31848
|
+
};
|
|
31824
31849
|
input.on("data", onData);
|
|
31825
31850
|
});
|
|
31826
31851
|
}
|
|
@@ -31861,8 +31886,11 @@ async function promptConfirm(question, defaultYes = true) {
|
|
|
31861
31886
|
input.setRawMode(true);
|
|
31862
31887
|
input.resume();
|
|
31863
31888
|
input.setEncoding("utf8");
|
|
31864
|
-
|
|
31889
|
+
let finished = false;
|
|
31890
|
+
const handleChar = (char) => {
|
|
31891
|
+
if (finished) return;
|
|
31865
31892
|
if (char === "\r" || char === "\n") {
|
|
31893
|
+
finished = true;
|
|
31866
31894
|
input.setRawMode(false);
|
|
31867
31895
|
input.removeListener("data", onData);
|
|
31868
31896
|
resolve64(selected === 0);
|
|
@@ -31875,18 +31903,23 @@ async function promptConfirm(question, defaultYes = true) {
|
|
|
31875
31903
|
render();
|
|
31876
31904
|
} else if (char === "y" || char === "Y") {
|
|
31877
31905
|
selected = 0;
|
|
31906
|
+
finished = true;
|
|
31878
31907
|
input.setRawMode(false);
|
|
31879
31908
|
input.removeListener("data", onData);
|
|
31880
31909
|
render();
|
|
31881
31910
|
resolve64(true);
|
|
31882
31911
|
} else if (char === "n" || char === "N") {
|
|
31883
31912
|
selected = 1;
|
|
31913
|
+
finished = true;
|
|
31884
31914
|
input.setRawMode(false);
|
|
31885
31915
|
input.removeListener("data", onData);
|
|
31886
31916
|
render();
|
|
31887
31917
|
resolve64(false);
|
|
31888
31918
|
}
|
|
31889
31919
|
};
|
|
31920
|
+
const onData = (chunk) => {
|
|
31921
|
+
for (const char of splitTTYInput(chunk)) handleChar(char);
|
|
31922
|
+
};
|
|
31890
31923
|
input.on("data", onData);
|
|
31891
31924
|
});
|
|
31892
31925
|
}
|
|
@@ -31931,13 +31964,16 @@ async function promptMultiSelect(_question, options, defaultSelected = [], opts
|
|
|
31931
31964
|
}
|
|
31932
31965
|
resolve64(result);
|
|
31933
31966
|
};
|
|
31934
|
-
|
|
31967
|
+
let finished = false;
|
|
31968
|
+
const handleChar = (char) => {
|
|
31969
|
+
if (finished) return;
|
|
31935
31970
|
if (char === "\r" || char === "\n") {
|
|
31936
31971
|
if (pickFocused && !userToggled) {
|
|
31937
31972
|
for (let i = 0; i < selected.length; i++) selected[i] = false;
|
|
31938
31973
|
selected[cursor] = true;
|
|
31939
31974
|
render();
|
|
31940
31975
|
}
|
|
31976
|
+
finished = true;
|
|
31941
31977
|
finish();
|
|
31942
31978
|
} else if (char === "") {
|
|
31943
31979
|
input.setRawMode(false);
|
|
@@ -31965,6 +32001,9 @@ async function promptMultiSelect(_question, options, defaultSelected = [], opts
|
|
|
31965
32001
|
render();
|
|
31966
32002
|
}
|
|
31967
32003
|
};
|
|
32004
|
+
const onData = (chunk) => {
|
|
32005
|
+
for (const char of splitTTYInput(chunk)) handleChar(char);
|
|
32006
|
+
};
|
|
31968
32007
|
input.on("data", onData);
|
|
31969
32008
|
});
|
|
31970
32009
|
}
|
|
@@ -62920,7 +62959,7 @@ init_source();
|
|
|
62920
62959
|
// package.json
|
|
62921
62960
|
var package_default = {
|
|
62922
62961
|
name: "@vibeframe/cli",
|
|
62923
|
-
version: "0.91.
|
|
62962
|
+
version: "0.91.6",
|
|
62924
62963
|
description: "VibeFrame CLI - natural language video editing from the terminal",
|
|
62925
62964
|
private: false,
|
|
62926
62965
|
license: "MIT",
|
|
@@ -63084,6 +63123,7 @@ var package_default = {
|
|
|
63084
63123
|
start: "tsx src/index.ts",
|
|
63085
63124
|
lint: "eslint --ext .ts,.tsx src/",
|
|
63086
63125
|
test: "vitest",
|
|
63126
|
+
pretest: "node build.js",
|
|
63087
63127
|
prepublishOnly: "node build.js"
|
|
63088
63128
|
},
|
|
63089
63129
|
dependencies: {
|
|
@@ -70110,6 +70150,15 @@ function applyProviderDefault(config2, choice) {
|
|
|
70110
70150
|
config2.defaults.videoProvider = choice.defaultFor.value;
|
|
70111
70151
|
}
|
|
70112
70152
|
}
|
|
70153
|
+
function mergeSelectedFeatures(current, next) {
|
|
70154
|
+
const merged = [...current];
|
|
70155
|
+
for (const feature of next) {
|
|
70156
|
+
if (!merged.some((f) => f.label === feature.label)) {
|
|
70157
|
+
merged.push(feature);
|
|
70158
|
+
}
|
|
70159
|
+
}
|
|
70160
|
+
return merged;
|
|
70161
|
+
}
|
|
70113
70162
|
async function runNonInteractiveSetup(opts) {
|
|
70114
70163
|
const scope = opts.scope ?? "user";
|
|
70115
70164
|
let config2 = await loadConfig({ scope });
|
|
@@ -70235,11 +70284,13 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70235
70284
|
console.log();
|
|
70236
70285
|
if (topIndex === 0) {
|
|
70237
70286
|
await saveConfig(config2, { scope });
|
|
70238
|
-
await
|
|
70287
|
+
await completeOrContinue(config2, "vibe edit silence-cut video.mp4 -o clean.mp4", [], scope);
|
|
70239
70288
|
return;
|
|
70240
70289
|
}
|
|
70241
70290
|
if (topIndex === 3) {
|
|
70242
|
-
await runCustomSetup(config2, scope);
|
|
70291
|
+
await runCustomSetup(config2, scope, { showComplete: false });
|
|
70292
|
+
await saveConfig(config2, { scope });
|
|
70293
|
+
await completeOrContinue(config2, "vibe doctor --test-keys", [], scope);
|
|
70243
70294
|
return;
|
|
70244
70295
|
}
|
|
70245
70296
|
if (topIndex === 2) {
|
|
@@ -70256,9 +70307,44 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70256
70307
|
console.log();
|
|
70257
70308
|
await collectKeys(config2, pipelineKeys);
|
|
70258
70309
|
await saveConfig(config2, { scope });
|
|
70259
|
-
await
|
|
70310
|
+
await completeOrContinue(config2, "vibe build my-story/ # see CONTRIBUTING.md for STORYBOARD.md format", [], scope);
|
|
70260
70311
|
return;
|
|
70261
70312
|
}
|
|
70313
|
+
const result = await runAIFeaturesSetup(config2, scope);
|
|
70314
|
+
await saveConfig(config2, { scope });
|
|
70315
|
+
await completeOrContinue(config2, result.tryCommand, result.selectedFeatures, scope);
|
|
70316
|
+
}
|
|
70317
|
+
async function completeOrContinue(config2, tryCommand, selectedFeatures, scope) {
|
|
70318
|
+
console.log(source_default.dim("Setup checkpoint"));
|
|
70319
|
+
console.log(source_default.bold("Anything else to configure?"));
|
|
70320
|
+
console.log();
|
|
70321
|
+
const action = await promptSelect(
|
|
70322
|
+
source_default.cyan(" Next: "),
|
|
70323
|
+
[
|
|
70324
|
+
`Add or update AI features ${source_default.dim("(images, videos, audio, editing)")}`,
|
|
70325
|
+
`Open full provider list ${source_default.dim("(every supported provider)")}`,
|
|
70326
|
+
"Finish setup"
|
|
70327
|
+
],
|
|
70328
|
+
2
|
|
70329
|
+
);
|
|
70330
|
+
console.log();
|
|
70331
|
+
if (action === 0) {
|
|
70332
|
+
const result = await runAIFeaturesSetup(config2, scope);
|
|
70333
|
+
const mergedFeatures = mergeSelectedFeatures(selectedFeatures, result.selectedFeatures);
|
|
70334
|
+
const mergedTryCommand = selectedFeatures.length > 0 ? tryCommand : result.tryCommand;
|
|
70335
|
+
await saveConfig(config2, { scope });
|
|
70336
|
+
await completeOrContinue(config2, mergedTryCommand, mergedFeatures, scope);
|
|
70337
|
+
return;
|
|
70338
|
+
}
|
|
70339
|
+
if (action === 1) {
|
|
70340
|
+
await runCustomSetup(config2, scope, { showComplete: false });
|
|
70341
|
+
await saveConfig(config2, { scope });
|
|
70342
|
+
await completeOrContinue(config2, tryCommand, selectedFeatures, scope);
|
|
70343
|
+
return;
|
|
70344
|
+
}
|
|
70345
|
+
await showComplete(config2, tryCommand, selectedFeatures, scope);
|
|
70346
|
+
}
|
|
70347
|
+
async function runAIFeaturesSetup(config2, _scope) {
|
|
70262
70348
|
console.log(source_default.dim("2. Features"));
|
|
70263
70349
|
console.log(source_default.bold("Which AI features do you need?"));
|
|
70264
70350
|
console.log(source_default.dim(` ${source_default.bold("Most users pick more than one.")} Press ${source_default.bold("space")} on each feature you want, then ${source_default.bold("enter")} to confirm.`));
|
|
@@ -70280,14 +70366,12 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70280
70366
|
if (selectedFeatures.length === 0) {
|
|
70281
70367
|
console.log(source_default.dim(" No features selected. You can re-run setup anytime."));
|
|
70282
70368
|
console.log();
|
|
70283
|
-
|
|
70284
|
-
await showComplete(config2, "vibe --help", [], scope);
|
|
70285
|
-
return;
|
|
70369
|
+
return { tryCommand: "vibe --help", selectedFeatures: [] };
|
|
70286
70370
|
}
|
|
70287
70371
|
const plannedKeys = /* @__PURE__ */ new Map();
|
|
70288
70372
|
console.log(source_default.dim("3. Providers"));
|
|
70289
70373
|
console.log(source_default.bold("Choose providers for each selected feature"));
|
|
70290
|
-
console.log(source_default.dim(` Recommended default is highlighted. Press ${source_default.bold("enter")} to pick
|
|
70374
|
+
console.log(source_default.dim(` Recommended default is highlighted. Press ${source_default.bold("enter")} to pick the highlighted provider, or ${source_default.bold("space")} to choose multiple.`));
|
|
70291
70375
|
console.log();
|
|
70292
70376
|
for (const feature of selectedFeatures) {
|
|
70293
70377
|
const keysForFeature = [];
|
|
@@ -70298,10 +70382,16 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70298
70382
|
console.log(source_default.dim(` Alternatives: ${feature.alsoAvailable}`));
|
|
70299
70383
|
}
|
|
70300
70384
|
console.log();
|
|
70301
|
-
const defaultSelected = feature.providerChoices.map((
|
|
70385
|
+
const defaultSelected = feature.providerChoices.map(() => false);
|
|
70302
70386
|
const providerLabels = feature.providerChoices.map((choice) => {
|
|
70303
70387
|
const keyHint = choice.keyless ? source_default.dim("no key") : choice.key ? source_default.dim(choice.key.envVar) : source_default.dim("no key");
|
|
70304
|
-
|
|
70388
|
+
const defaultHint = choice === feature.providerChoices?.[0] ? source_default.dim("recommended default") : "";
|
|
70389
|
+
return [
|
|
70390
|
+
choice.label,
|
|
70391
|
+
defaultHint,
|
|
70392
|
+
source_default.dim(`- ${choice.desc}`),
|
|
70393
|
+
keyHint
|
|
70394
|
+
].filter(Boolean).join(" ");
|
|
70305
70395
|
});
|
|
70306
70396
|
const pickedProviders = await promptMultiSelect(
|
|
70307
70397
|
source_default.cyan(" Providers (arrow + enter picks one, space adds more): "),
|
|
@@ -70388,8 +70478,7 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70388
70478
|
console.log(source_default.dim(" No API keys needed for the selected provider(s)."));
|
|
70389
70479
|
console.log();
|
|
70390
70480
|
}
|
|
70391
|
-
|
|
70392
|
-
await showComplete(config2, selectedFeatures[0].tryCommand, selectedFeatures, scope);
|
|
70481
|
+
return { tryCommand: selectedFeatures[0].tryCommand, selectedFeatures };
|
|
70393
70482
|
}
|
|
70394
70483
|
async function collectKeys(config2, keys) {
|
|
70395
70484
|
loadEnv();
|
|
@@ -70425,7 +70514,7 @@ async function collectKeys(config2, keys) {
|
|
|
70425
70514
|
}
|
|
70426
70515
|
console.log();
|
|
70427
70516
|
}
|
|
70428
|
-
async function runCustomSetup(config2, scope = "user") {
|
|
70517
|
+
async function runCustomSetup(config2, scope = "user", opts = {}) {
|
|
70429
70518
|
console.log(source_default.bold("1. Agent LLM Provider") + source_default.dim(" (for vibe agent)"));
|
|
70430
70519
|
console.log(source_default.dim(" Only needed if you use the interactive Agent mode."));
|
|
70431
70520
|
console.log();
|
|
@@ -70496,7 +70585,9 @@ async function runCustomSetup(config2, scope = "user") {
|
|
|
70496
70585
|
}
|
|
70497
70586
|
console.log();
|
|
70498
70587
|
await saveConfig(config2, { scope });
|
|
70499
|
-
|
|
70588
|
+
if (opts.showComplete !== false) {
|
|
70589
|
+
await showComplete(config2, "vibe doctor", [], scope);
|
|
70590
|
+
}
|
|
70500
70591
|
}
|
|
70501
70592
|
async function showComplete(config2, defaultTryCommand, features = [], scope = "user") {
|
|
70502
70593
|
console.log(source_default.dim("\u2500".repeat(40)));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/cli",
|
|
3
|
-
"version": "0.91.
|
|
3
|
+
"version": "0.91.6",
|
|
4
4
|
"description": "VibeFrame CLI - natural language video editing from the terminal",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -183,8 +183,8 @@
|
|
|
183
183
|
"tsx": "^4.21.0",
|
|
184
184
|
"typescript": "^5.3.3",
|
|
185
185
|
"vitest": "^1.2.2",
|
|
186
|
-
"@vibeframe/ai-providers": "0.91.
|
|
187
|
-
"@vibeframe/core": "0.91.
|
|
186
|
+
"@vibeframe/ai-providers": "0.91.6",
|
|
187
|
+
"@vibeframe/core": "0.91.6"
|
|
188
188
|
},
|
|
189
189
|
"engines": {
|
|
190
190
|
"node": ">=20"
|
|
@@ -195,6 +195,7 @@
|
|
|
195
195
|
"dev": "tsc --watch",
|
|
196
196
|
"start": "tsx src/index.ts",
|
|
197
197
|
"lint": "eslint --ext .ts,.tsx src/",
|
|
198
|
-
"test": "vitest"
|
|
198
|
+
"test": "vitest",
|
|
199
|
+
"pretest": "node build.js"
|
|
199
200
|
}
|
|
200
201
|
}
|