@vibeframe/cli 0.91.7 → 0.91.8
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 +381 -179
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -62962,7 +62962,7 @@ init_source();
|
|
|
62962
62962
|
// package.json
|
|
62963
62963
|
var package_default = {
|
|
62964
62964
|
name: "@vibeframe/cli",
|
|
62965
|
-
version: "0.91.
|
|
62965
|
+
version: "0.91.8",
|
|
62966
62966
|
description: "VibeFrame CLI - natural language video editing from the terminal",
|
|
62967
62967
|
private: false,
|
|
62968
62968
|
license: "MIT",
|
|
@@ -69963,14 +69963,19 @@ var VALID_SCOPES = ["user", "project"];
|
|
|
69963
69963
|
function parseScope(raw) {
|
|
69964
69964
|
const v = String(raw ?? "user");
|
|
69965
69965
|
if (!VALID_SCOPES.includes(v)) {
|
|
69966
|
-
exitWithError(
|
|
69967
|
-
`Invalid --scope: ${v}`,
|
|
69968
|
-
|
|
69969
|
-
));
|
|
69966
|
+
exitWithError(
|
|
69967
|
+
generalError(`Invalid --scope: ${v}`, `Must be one of: ${VALID_SCOPES.join(", ")}`)
|
|
69968
|
+
);
|
|
69970
69969
|
}
|
|
69971
69970
|
return v;
|
|
69972
69971
|
}
|
|
69973
|
-
var setupCommand = new Command("setup").description("Configure VibeFrame (LLM provider, API keys)").option("--reset", "Reset configuration to defaults").option("--full", "Run full setup with all optional providers").option("--show", "Show current configuration (for debugging)").option(
|
|
69972
|
+
var setupCommand = new Command("setup").description("Configure VibeFrame (LLM provider, API keys)").option("--reset", "Reset configuration to defaults").option("--full", "Run full setup with all optional providers").option("--show", "Show current configuration (for debugging)").option(
|
|
69973
|
+
"-v, --verbose",
|
|
69974
|
+
"With --show: include unset providers + Resolution order + Defaults block"
|
|
69975
|
+
).option("--claude-code", "Show Claude Code integration guide").option("-y, --yes", "Non-interactive: write config without prompting (CI / devcontainer)").option(
|
|
69976
|
+
"--provider <id>",
|
|
69977
|
+
"Set the Agent LLM provider (claude | openai | gemini | xai | openrouter | ollama)"
|
|
69978
|
+
).option("--import-env", "Promote API keys from .env / shell env into config.yaml").option("--test", "After save, live-test each configured key (exits 7 if any FAIL)").option(
|
|
69974
69979
|
"--scope <scope>",
|
|
69975
69980
|
"Where to save: 'user' (~/.vibeframe/config.yaml, shared) or 'project' (./.vibeframe/config.yaml, gitignored, this project only)",
|
|
69976
69981
|
"user"
|
|
@@ -70020,10 +70025,12 @@ Exit codes (non-interactive):
|
|
|
70020
70025
|
return;
|
|
70021
70026
|
}
|
|
70022
70027
|
if (!hasTTY()) {
|
|
70023
|
-
exitWithError(
|
|
70024
|
-
|
|
70025
|
-
|
|
70026
|
-
|
|
70028
|
+
exitWithError(
|
|
70029
|
+
generalError(
|
|
70030
|
+
"Interactive setup requires a terminal.",
|
|
70031
|
+
"Run 'vibe setup' directly from your terminal, or use 'vibe setup --yes --provider <id> --import-env' for CI."
|
|
70032
|
+
)
|
|
70033
|
+
);
|
|
70027
70034
|
}
|
|
70028
70035
|
try {
|
|
70029
70036
|
await runSetupWizard(options.full, scope);
|
|
@@ -70040,24 +70047,50 @@ var AI_FEATURES = [
|
|
|
70040
70047
|
desc: "generate + edit",
|
|
70041
70048
|
defaultProvider: "OpenAI gpt-image-2 (Artificial Analysis #1, since v0.56)",
|
|
70042
70049
|
alsoAvailable: "Gemini Nano Banana, Grok Imagine",
|
|
70043
|
-
keys: [
|
|
70050
|
+
keys: [
|
|
70051
|
+
{
|
|
70052
|
+
configKey: "openai",
|
|
70053
|
+
envVar: "OPENAI_API_KEY",
|
|
70054
|
+
name: "OpenAI",
|
|
70055
|
+
url: "https://platform.openai.com/api-keys",
|
|
70056
|
+
what: "gpt-image-2 image generation + editing (also Whisper, Agent)"
|
|
70057
|
+
}
|
|
70058
|
+
],
|
|
70044
70059
|
providerChoices: [
|
|
70045
70060
|
{
|
|
70046
70061
|
label: "OpenAI gpt-image-2",
|
|
70047
70062
|
desc: "recommended default, image generation + editing",
|
|
70048
|
-
key: {
|
|
70063
|
+
key: {
|
|
70064
|
+
configKey: "openai",
|
|
70065
|
+
envVar: "OPENAI_API_KEY",
|
|
70066
|
+
name: "OpenAI",
|
|
70067
|
+
url: "https://platform.openai.com/api-keys",
|
|
70068
|
+
what: "gpt-image-2 image generation + editing (also Whisper, Agent)"
|
|
70069
|
+
},
|
|
70049
70070
|
defaultFor: { kind: "image", value: "openai" }
|
|
70050
70071
|
},
|
|
70051
70072
|
{
|
|
70052
70073
|
label: "Gemini",
|
|
70053
70074
|
desc: "Google image generation + multimodal analysis",
|
|
70054
|
-
key: {
|
|
70075
|
+
key: {
|
|
70076
|
+
configKey: "google",
|
|
70077
|
+
envVar: "GOOGLE_API_KEY",
|
|
70078
|
+
name: "Google",
|
|
70079
|
+
url: "https://aistudio.google.com/apikey",
|
|
70080
|
+
what: "Gemini image generation and multimodal analysis"
|
|
70081
|
+
},
|
|
70055
70082
|
defaultFor: { kind: "image", value: "gemini" }
|
|
70056
70083
|
},
|
|
70057
70084
|
{
|
|
70058
70085
|
label: "Grok",
|
|
70059
70086
|
desc: "xAI image generation",
|
|
70060
|
-
key: {
|
|
70087
|
+
key: {
|
|
70088
|
+
configKey: "xai",
|
|
70089
|
+
envVar: "XAI_API_KEY",
|
|
70090
|
+
name: "xAI",
|
|
70091
|
+
url: "https://console.x.ai/",
|
|
70092
|
+
what: "Grok image generation and Agent"
|
|
70093
|
+
},
|
|
70061
70094
|
defaultFor: { kind: "image", value: "grok" }
|
|
70062
70095
|
}
|
|
70063
70096
|
],
|
|
@@ -70068,36 +70101,74 @@ var AI_FEATURES = [
|
|
|
70068
70101
|
desc: "generate + extend",
|
|
70069
70102
|
defaultProvider: "Seedance 2.0 via fal.ai (Artificial Analysis #2 t2v + i2v, since v0.57)",
|
|
70070
70103
|
alsoAvailable: "Grok Imagine, Kling, Runway Gen-4.5, Google Veo",
|
|
70071
|
-
keys: [
|
|
70104
|
+
keys: [
|
|
70105
|
+
{
|
|
70106
|
+
configKey: "fal",
|
|
70107
|
+
envVar: "FAL_KEY",
|
|
70108
|
+
name: "Seedance 2.0 (via fal.ai)",
|
|
70109
|
+
url: "https://fal.ai/dashboard/keys",
|
|
70110
|
+
what: "ByteDance Seedance 2.0 text-to-video and image-to-video"
|
|
70111
|
+
}
|
|
70112
|
+
],
|
|
70072
70113
|
providerChoices: [
|
|
70073
70114
|
{
|
|
70074
70115
|
label: "Seedance 2.0 via fal.ai",
|
|
70075
70116
|
desc: "recommended default, text-to-video + image-to-video",
|
|
70076
|
-
key: {
|
|
70117
|
+
key: {
|
|
70118
|
+
configKey: "fal",
|
|
70119
|
+
envVar: "FAL_KEY",
|
|
70120
|
+
name: "Seedance 2.0 (via fal.ai)",
|
|
70121
|
+
url: "https://fal.ai/dashboard/keys",
|
|
70122
|
+
what: "ByteDance Seedance 2.0 text-to-video and image-to-video"
|
|
70123
|
+
},
|
|
70077
70124
|
defaultFor: { kind: "video", value: "seedance" }
|
|
70078
70125
|
},
|
|
70079
70126
|
{
|
|
70080
70127
|
label: "Grok",
|
|
70081
70128
|
desc: "xAI video generation with audio",
|
|
70082
|
-
key: {
|
|
70129
|
+
key: {
|
|
70130
|
+
configKey: "xai",
|
|
70131
|
+
envVar: "XAI_API_KEY",
|
|
70132
|
+
name: "xAI",
|
|
70133
|
+
url: "https://console.x.ai/",
|
|
70134
|
+
what: "Grok video generation and Agent"
|
|
70135
|
+
},
|
|
70083
70136
|
defaultFor: { kind: "video", value: "grok" }
|
|
70084
70137
|
},
|
|
70085
70138
|
{
|
|
70086
70139
|
label: "Kling",
|
|
70087
70140
|
desc: "Kling v2.5/v3 video generation",
|
|
70088
|
-
key: {
|
|
70141
|
+
key: {
|
|
70142
|
+
configKey: "kling",
|
|
70143
|
+
envVar: "KLING_API_KEY",
|
|
70144
|
+
name: "Kling",
|
|
70145
|
+
url: "https://platform.klingai.com/",
|
|
70146
|
+
what: "Kling video generation"
|
|
70147
|
+
},
|
|
70089
70148
|
defaultFor: { kind: "video", value: "kling" }
|
|
70090
70149
|
},
|
|
70091
70150
|
{
|
|
70092
70151
|
label: "Runway",
|
|
70093
70152
|
desc: "Runway Gen-4.5 video generation",
|
|
70094
|
-
key: {
|
|
70153
|
+
key: {
|
|
70154
|
+
configKey: "runway",
|
|
70155
|
+
envVar: "RUNWAY_API_SECRET",
|
|
70156
|
+
name: "Runway",
|
|
70157
|
+
url: "https://app.runwayml.com/settings/api-keys",
|
|
70158
|
+
what: "Runway Gen-4.5 video generation"
|
|
70159
|
+
},
|
|
70095
70160
|
defaultFor: { kind: "video", value: "runway" }
|
|
70096
70161
|
},
|
|
70097
70162
|
{
|
|
70098
70163
|
label: "Veo",
|
|
70099
70164
|
desc: "Google Veo video generation",
|
|
70100
|
-
key: {
|
|
70165
|
+
key: {
|
|
70166
|
+
configKey: "google",
|
|
70167
|
+
envVar: "GOOGLE_API_KEY",
|
|
70168
|
+
name: "Google",
|
|
70169
|
+
url: "https://aistudio.google.com/apikey",
|
|
70170
|
+
what: "Google Veo video generation"
|
|
70171
|
+
},
|
|
70101
70172
|
defaultFor: { kind: "video", value: "veo" }
|
|
70102
70173
|
}
|
|
70103
70174
|
],
|
|
@@ -70108,12 +70179,26 @@ var AI_FEATURES = [
|
|
|
70108
70179
|
desc: "TTS, SFX, music, voice clone",
|
|
70109
70180
|
defaultProvider: "ElevenLabs (paid, premium quality) \u2014 falls back to local Kokoro when no key (free, since v0.54)",
|
|
70110
70181
|
alsoAvailable: "Replicate MusicGen (music only)",
|
|
70111
|
-
keys: [
|
|
70182
|
+
keys: [
|
|
70183
|
+
{
|
|
70184
|
+
configKey: "elevenlabs",
|
|
70185
|
+
envVar: "ELEVENLABS_API_KEY",
|
|
70186
|
+
name: "ElevenLabs",
|
|
70187
|
+
url: "https://elevenlabs.io/app/settings/api-keys",
|
|
70188
|
+
what: "Text-to-speech, sound effects, music, voice cloning (skip to use local Kokoro)"
|
|
70189
|
+
}
|
|
70190
|
+
],
|
|
70112
70191
|
providerChoices: [
|
|
70113
70192
|
{
|
|
70114
70193
|
label: "ElevenLabs",
|
|
70115
70194
|
desc: "premium TTS, SFX, music, voice clone",
|
|
70116
|
-
key: {
|
|
70195
|
+
key: {
|
|
70196
|
+
configKey: "elevenlabs",
|
|
70197
|
+
envVar: "ELEVENLABS_API_KEY",
|
|
70198
|
+
name: "ElevenLabs",
|
|
70199
|
+
url: "https://elevenlabs.io/app/settings/api-keys",
|
|
70200
|
+
what: "Text-to-speech, sound effects, music, voice cloning"
|
|
70201
|
+
}
|
|
70117
70202
|
},
|
|
70118
70203
|
{
|
|
70119
70204
|
label: "Kokoro local",
|
|
@@ -70123,7 +70208,13 @@ var AI_FEATURES = [
|
|
|
70123
70208
|
{
|
|
70124
70209
|
label: "Replicate MusicGen",
|
|
70125
70210
|
desc: "background music generation",
|
|
70126
|
-
key: {
|
|
70211
|
+
key: {
|
|
70212
|
+
configKey: "replicate",
|
|
70213
|
+
envVar: "REPLICATE_API_TOKEN",
|
|
70214
|
+
name: "Replicate",
|
|
70215
|
+
url: "https://replicate.com/account/api-tokens",
|
|
70216
|
+
what: "MusicGen background music"
|
|
70217
|
+
}
|
|
70127
70218
|
}
|
|
70128
70219
|
],
|
|
70129
70220
|
tryCommand: 'vibe generate speech "Hello world" -o hello.mp3'
|
|
@@ -70134,8 +70225,20 @@ var AI_FEATURES = [
|
|
|
70134
70225
|
defaultProvider: "Whisper (transcription) + Claude (reasoning)",
|
|
70135
70226
|
alsoAvailable: "",
|
|
70136
70227
|
keys: [
|
|
70137
|
-
{
|
|
70138
|
-
|
|
70228
|
+
{
|
|
70229
|
+
configKey: "openai",
|
|
70230
|
+
envVar: "OPENAI_API_KEY",
|
|
70231
|
+
name: "OpenAI",
|
|
70232
|
+
url: "https://platform.openai.com/api-keys",
|
|
70233
|
+
what: "Whisper transcription (captions, jump-cut)"
|
|
70234
|
+
},
|
|
70235
|
+
{
|
|
70236
|
+
configKey: "anthropic",
|
|
70237
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
70238
|
+
name: "Anthropic",
|
|
70239
|
+
url: "https://console.anthropic.com/settings/keys",
|
|
70240
|
+
what: "Claude (color grade, reframe, motion graphics)"
|
|
70241
|
+
}
|
|
70139
70242
|
],
|
|
70140
70243
|
tryCommand: "vibe edit caption video.mp4 -o captioned.mp4"
|
|
70141
70244
|
}
|
|
@@ -70166,6 +70269,14 @@ function isProviderChoiceConfigured(config2, choice) {
|
|
|
70166
70269
|
}
|
|
70167
70270
|
return false;
|
|
70168
70271
|
}
|
|
70272
|
+
function isFeatureConfigured(config2, feature) {
|
|
70273
|
+
if (feature.providerChoices?.some((choice) => isProviderChoiceConfigured(config2, choice))) {
|
|
70274
|
+
return true;
|
|
70275
|
+
}
|
|
70276
|
+
return feature.keys.some(
|
|
70277
|
+
(keyDef) => Boolean(config2.providers[keyDef.configKey])
|
|
70278
|
+
);
|
|
70279
|
+
}
|
|
70169
70280
|
function mergeSelectedFeatures(current, next) {
|
|
70170
70281
|
const merged = [...current];
|
|
70171
70282
|
for (const feature of next) {
|
|
@@ -70184,10 +70295,12 @@ async function runNonInteractiveSetup(opts) {
|
|
|
70184
70295
|
const changes = [];
|
|
70185
70296
|
if (opts.provider) {
|
|
70186
70297
|
if (!VALID_LLM_PROVIDERS.includes(opts.provider)) {
|
|
70187
|
-
exitWithError(
|
|
70188
|
-
|
|
70189
|
-
|
|
70190
|
-
|
|
70298
|
+
exitWithError(
|
|
70299
|
+
generalError(
|
|
70300
|
+
`Invalid --provider: ${opts.provider}`,
|
|
70301
|
+
`Must be one of: ${VALID_LLM_PROVIDERS.join(", ")}`
|
|
70302
|
+
)
|
|
70303
|
+
);
|
|
70191
70304
|
}
|
|
70192
70305
|
if (config2.llm.provider !== opts.provider) {
|
|
70193
70306
|
config2.llm.provider = opts.provider;
|
|
@@ -70254,7 +70367,11 @@ async function runNonInteractiveSetup(opts) {
|
|
|
70254
70367
|
}
|
|
70255
70368
|
if (failures > 0) {
|
|
70256
70369
|
console.error();
|
|
70257
|
-
console.error(
|
|
70370
|
+
console.error(
|
|
70371
|
+
source_default.red(
|
|
70372
|
+
`Verification failed: ${failures} key${failures === 1 ? "" : "s"} returned non-2xx.`
|
|
70373
|
+
)
|
|
70374
|
+
);
|
|
70258
70375
|
process.exit(7);
|
|
70259
70376
|
}
|
|
70260
70377
|
}
|
|
@@ -70263,15 +70380,11 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70263
70380
|
console.log();
|
|
70264
70381
|
const cfgPath = getConfigPath(scope).replace(homedir5(), "~");
|
|
70265
70382
|
const scopeNote = scope === "project" ? "applies to this project only \xB7 add .vibeframe/ to .gitignore" : "applies to every project for this user";
|
|
70266
|
-
console.log(
|
|
70267
|
-
source_default.bold.magenta("VibeFrame Setup") + source_default.bold(` \u2014 ${scope} scope`)
|
|
70268
|
-
);
|
|
70383
|
+
console.log(source_default.bold.magenta("VibeFrame Setup") + source_default.bold(` \u2014 ${scope} scope`));
|
|
70269
70384
|
console.log(source_default.dim(`${cfgPath} \xB7 ${scopeNote}`));
|
|
70270
70385
|
if (scope === "user") {
|
|
70271
70386
|
console.log(
|
|
70272
|
-
source_default.dim(
|
|
70273
|
-
"Tip: for per-project keys, cd into a project and run: vibe setup --scope project"
|
|
70274
|
-
)
|
|
70387
|
+
source_default.dim("Tip: for per-project keys, cd into a project and run: vibe setup --scope project")
|
|
70275
70388
|
);
|
|
70276
70389
|
}
|
|
70277
70390
|
console.log(source_default.dim("\u2500".repeat(40)));
|
|
@@ -70312,10 +70425,34 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70312
70425
|
if (topIndex === 2) {
|
|
70313
70426
|
config2.llm.provider = "claude";
|
|
70314
70427
|
const pipelineKeys = [
|
|
70315
|
-
{
|
|
70316
|
-
|
|
70317
|
-
|
|
70318
|
-
|
|
70428
|
+
{
|
|
70429
|
+
configKey: "anthropic",
|
|
70430
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
70431
|
+
name: "Anthropic",
|
|
70432
|
+
url: "https://console.anthropic.com/settings/keys",
|
|
70433
|
+
what: "Claude \u2014 storyboard generation + reasoning"
|
|
70434
|
+
},
|
|
70435
|
+
{
|
|
70436
|
+
configKey: "openai",
|
|
70437
|
+
envVar: "OPENAI_API_KEY",
|
|
70438
|
+
name: "OpenAI",
|
|
70439
|
+
url: "https://platform.openai.com/api-keys",
|
|
70440
|
+
what: "gpt-image-2 image generation (default since v0.56) + Whisper word-level transcribe"
|
|
70441
|
+
},
|
|
70442
|
+
{
|
|
70443
|
+
configKey: "fal",
|
|
70444
|
+
envVar: "FAL_KEY",
|
|
70445
|
+
name: "fal.ai",
|
|
70446
|
+
url: "https://fal.ai/dashboard/keys",
|
|
70447
|
+
what: "Seedance 2.0 \u2014 video generation, default since v0.57"
|
|
70448
|
+
},
|
|
70449
|
+
{
|
|
70450
|
+
configKey: "elevenlabs",
|
|
70451
|
+
envVar: "ELEVENLABS_API_KEY",
|
|
70452
|
+
name: "ElevenLabs",
|
|
70453
|
+
url: "https://elevenlabs.io/app/settings/api-keys",
|
|
70454
|
+
what: "Text-to-speech narration + music (skip to use local Kokoro)"
|
|
70455
|
+
}
|
|
70319
70456
|
];
|
|
70320
70457
|
console.log(source_default.dim("2. API keys"));
|
|
70321
70458
|
console.log(source_default.bold("Pipeline requires these API keys:"));
|
|
@@ -70323,10 +70460,19 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70323
70460
|
console.log();
|
|
70324
70461
|
await collectKeys(config2, pipelineKeys);
|
|
70325
70462
|
await saveConfig(config2, { scope });
|
|
70326
|
-
await completeOrContinue(
|
|
70463
|
+
await completeOrContinue(
|
|
70464
|
+
config2,
|
|
70465
|
+
"vibe build my-story/ # see CONTRIBUTING.md for STORYBOARD.md format",
|
|
70466
|
+
[],
|
|
70467
|
+
scope
|
|
70468
|
+
);
|
|
70327
70469
|
return;
|
|
70328
70470
|
}
|
|
70329
70471
|
const result = await runAIFeaturesSetup(config2, scope);
|
|
70472
|
+
if (result.back) {
|
|
70473
|
+
await completeOrContinue(config2, "vibe --help", [], scope);
|
|
70474
|
+
return;
|
|
70475
|
+
}
|
|
70330
70476
|
await saveConfig(config2, { scope });
|
|
70331
70477
|
await completeOrContinue(config2, result.tryCommand, result.selectedFeatures, scope);
|
|
70332
70478
|
}
|
|
@@ -70346,6 +70492,10 @@ async function completeOrContinue(config2, tryCommand, selectedFeatures, scope)
|
|
|
70346
70492
|
console.log();
|
|
70347
70493
|
if (action === 0) {
|
|
70348
70494
|
const result = await runAIFeaturesSetup(config2, scope);
|
|
70495
|
+
if (result.back) {
|
|
70496
|
+
await completeOrContinue(config2, tryCommand, selectedFeatures, scope);
|
|
70497
|
+
return;
|
|
70498
|
+
}
|
|
70349
70499
|
const mergedFeatures = mergeSelectedFeatures(selectedFeatures, result.selectedFeatures);
|
|
70350
70500
|
const mergedTryCommand = selectedFeatures.length > 0 ? tryCommand : result.tryCommand;
|
|
70351
70501
|
await saveConfig(config2, { scope });
|
|
@@ -70361,142 +70511,168 @@ async function completeOrContinue(config2, tryCommand, selectedFeatures, scope)
|
|
|
70361
70511
|
await showComplete(config2, tryCommand, selectedFeatures, scope);
|
|
70362
70512
|
}
|
|
70363
70513
|
async function runAIFeaturesSetup(config2, _scope) {
|
|
70364
|
-
|
|
70365
|
-
|
|
70366
|
-
|
|
70367
|
-
|
|
70368
|
-
|
|
70369
|
-
|
|
70370
|
-
|
|
70371
|
-
|
|
70372
|
-
|
|
70373
|
-
});
|
|
70374
|
-
const picked = await promptMultiSelect(
|
|
70375
|
-
source_default.cyan(" Pick (e.g. 1,3 or 'all'): "),
|
|
70376
|
-
featureLabels,
|
|
70377
|
-
[],
|
|
70378
|
-
{ pickFocusedOnEnter: true }
|
|
70379
|
-
);
|
|
70380
|
-
const selectedFeatures = picked.map((i) => AI_FEATURES[i]);
|
|
70381
|
-
console.log();
|
|
70382
|
-
if (selectedFeatures.length === 0) {
|
|
70383
|
-
console.log(source_default.dim(" No features selected. You can re-run setup anytime."));
|
|
70514
|
+
featureSelection: for (; ; ) {
|
|
70515
|
+
console.log(source_default.dim("2. Features"));
|
|
70516
|
+
console.log(source_default.bold("Which AI features do you need?"));
|
|
70517
|
+
console.log(
|
|
70518
|
+
source_default.dim(
|
|
70519
|
+
` ${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.`
|
|
70520
|
+
)
|
|
70521
|
+
);
|
|
70522
|
+
console.log(source_default.dim(" Shortcut: enter alone picks only the highlighted feature."));
|
|
70523
|
+
console.log(source_default.dim(` Select ${source_default.bold("Back")} to return to the setup checkpoint.`));
|
|
70384
70524
|
console.log();
|
|
70385
|
-
|
|
70386
|
-
|
|
70387
|
-
|
|
70388
|
-
|
|
70389
|
-
|
|
70390
|
-
|
|
70391
|
-
|
|
70392
|
-
|
|
70393
|
-
|
|
70394
|
-
|
|
70395
|
-
|
|
70396
|
-
|
|
70397
|
-
|
|
70398
|
-
|
|
70399
|
-
}
|
|
70525
|
+
const backIndex = AI_FEATURES.length;
|
|
70526
|
+
const featureLabels = [
|
|
70527
|
+
...AI_FEATURES.map((f) => {
|
|
70528
|
+
const keyCount = f.keys.length;
|
|
70529
|
+
const tag = source_default.dim(`${keyCount} key${keyCount > 1 ? "s" : ""}`);
|
|
70530
|
+
return `${f.label} ${source_default.dim(`(${f.desc})`)} ${tag}`;
|
|
70531
|
+
}),
|
|
70532
|
+
`Back ${source_default.dim("(return to setup checkpoint)")}`
|
|
70533
|
+
];
|
|
70534
|
+
const configuredFeatures = AI_FEATURES.map((feature) => isFeatureConfigured(config2, feature));
|
|
70535
|
+
const picked = await promptMultiSelect(
|
|
70536
|
+
source_default.cyan(" Pick (e.g. 1,3 or 'all'): "),
|
|
70537
|
+
featureLabels,
|
|
70538
|
+
[...configuredFeatures, false],
|
|
70539
|
+
{ pickFocusedOnEnter: true, preserveDefaultSelectionOnEnter: true }
|
|
70540
|
+
);
|
|
70541
|
+
if (picked.includes(backIndex)) {
|
|
70400
70542
|
console.log();
|
|
70401
|
-
|
|
70402
|
-
|
|
70403
|
-
|
|
70404
|
-
|
|
70405
|
-
|
|
70406
|
-
|
|
70407
|
-
return [
|
|
70408
|
-
choice.label,
|
|
70409
|
-
defaultHint,
|
|
70410
|
-
source_default.dim(`- ${choice.desc}`),
|
|
70411
|
-
keyHint
|
|
70412
|
-
].filter(Boolean).join(" ");
|
|
70413
|
-
});
|
|
70414
|
-
const pickedProviders = await promptMultiSelect(
|
|
70415
|
-
source_default.cyan(" Providers (arrow + enter picks one, space adds more): "),
|
|
70416
|
-
providerLabels,
|
|
70417
|
-
defaultSelected,
|
|
70418
|
-
{ pickFocusedOnEnter: true, preserveDefaultSelectionOnEnter: true }
|
|
70419
|
-
);
|
|
70420
|
-
const selectedChoices = pickedProviders.map((i) => feature.providerChoices[i]);
|
|
70421
|
-
const defaultChoice = selectedChoices.find((choice) => choice.defaultFor);
|
|
70422
|
-
if (defaultChoice) {
|
|
70423
|
-
applyProviderDefault(config2, defaultChoice);
|
|
70424
|
-
}
|
|
70425
|
-
for (const choice of selectedChoices) {
|
|
70426
|
-
if (choice.key) addUniqueKey(keysForFeature, choice.key);
|
|
70427
|
-
}
|
|
70428
|
-
if (selectedChoices.some((choice) => choice.keyless)) {
|
|
70429
|
-
console.log(source_default.dim(" No API key needed for selected local provider(s)."));
|
|
70430
|
-
}
|
|
70543
|
+
return { tryCommand: "vibe --help", selectedFeatures: [], back: true };
|
|
70544
|
+
}
|
|
70545
|
+
const selectedFeatures = picked.filter((i) => i < AI_FEATURES.length).map((i) => AI_FEATURES[i]);
|
|
70546
|
+
console.log();
|
|
70547
|
+
if (selectedFeatures.length === 0) {
|
|
70548
|
+
console.log(source_default.dim(" No features selected. You can re-run setup anytime."));
|
|
70431
70549
|
console.log();
|
|
70432
|
-
|
|
70433
|
-
for (const keyDef of feature.keys) {
|
|
70434
|
-
addUniqueKey(keysForFeature, keyDef);
|
|
70435
|
-
}
|
|
70550
|
+
return { tryCommand: "vibe --help", selectedFeatures: [] };
|
|
70436
70551
|
}
|
|
70437
|
-
plannedKeys
|
|
70438
|
-
|
|
70439
|
-
|
|
70440
|
-
|
|
70441
|
-
|
|
70442
|
-
|
|
70443
|
-
|
|
70552
|
+
const plannedKeys = /* @__PURE__ */ new Map();
|
|
70553
|
+
console.log(source_default.dim("3. Providers"));
|
|
70554
|
+
console.log(source_default.bold("Choose providers for each selected feature"));
|
|
70555
|
+
console.log(
|
|
70556
|
+
source_default.dim(
|
|
70557
|
+
` Recommended default is highlighted. Press ${source_default.bold("enter")} to pick the highlighted provider, or ${source_default.bold("space")} to choose multiple.`
|
|
70558
|
+
)
|
|
70559
|
+
);
|
|
70444
70560
|
console.log();
|
|
70445
|
-
const collectedKeys = /* @__PURE__ */ new Set();
|
|
70446
70561
|
for (const feature of selectedFeatures) {
|
|
70447
|
-
const keysForFeature =
|
|
70448
|
-
if (
|
|
70449
|
-
|
|
70450
|
-
|
|
70451
|
-
|
|
70452
|
-
|
|
70453
|
-
|
|
70454
|
-
console.log(
|
|
70562
|
+
const keysForFeature = [];
|
|
70563
|
+
if (feature.providerChoices && feature.providerChoices.length > 0) {
|
|
70564
|
+
console.log(source_default.bold.cyan(` ${feature.label}`));
|
|
70565
|
+
console.log(source_default.dim(` Default path: ${feature.defaultProvider}`));
|
|
70566
|
+
if (feature.alsoAvailable) {
|
|
70567
|
+
console.log(source_default.dim(` Alternatives: ${feature.alsoAvailable}`));
|
|
70568
|
+
}
|
|
70569
|
+
console.log();
|
|
70570
|
+
const defaultSelected = feature.providerChoices.map(
|
|
70571
|
+
(choice) => isProviderChoiceConfigured(config2, choice)
|
|
70572
|
+
);
|
|
70573
|
+
const providerLabels = feature.providerChoices.map((choice) => {
|
|
70574
|
+
const keyHint = choice.keyless ? source_default.dim("no key") : choice.key ? source_default.dim(choice.key.envVar) : source_default.dim("no key");
|
|
70575
|
+
const defaultHint = choice === feature.providerChoices?.[0] ? source_default.dim("recommended default") : "";
|
|
70576
|
+
return [choice.label, defaultHint, source_default.dim(`- ${choice.desc}`), keyHint].filter(Boolean).join(" ");
|
|
70577
|
+
});
|
|
70578
|
+
const backProviderIndex = providerLabels.length;
|
|
70579
|
+
const pickedProviders = await promptMultiSelect(
|
|
70580
|
+
source_default.cyan(" Providers (arrow + enter picks one, space adds more): "),
|
|
70581
|
+
[...providerLabels, `Back ${source_default.dim("(choose different features)")}`],
|
|
70582
|
+
[...defaultSelected, false],
|
|
70583
|
+
{ pickFocusedOnEnter: true, preserveDefaultSelectionOnEnter: true }
|
|
70584
|
+
);
|
|
70585
|
+
if (pickedProviders.includes(backProviderIndex)) {
|
|
70586
|
+
console.log();
|
|
70587
|
+
continue featureSelection;
|
|
70588
|
+
}
|
|
70589
|
+
const selectedChoices = pickedProviders.filter((i) => i < feature.providerChoices.length).map((i) => feature.providerChoices[i]);
|
|
70590
|
+
const defaultChoice = selectedChoices.find((choice) => choice.defaultFor);
|
|
70591
|
+
if (defaultChoice) {
|
|
70592
|
+
applyProviderDefault(config2, defaultChoice);
|
|
70593
|
+
}
|
|
70594
|
+
for (const choice of selectedChoices) {
|
|
70595
|
+
if (choice.key) addUniqueKey(keysForFeature, choice.key);
|
|
70596
|
+
}
|
|
70597
|
+
if (selectedChoices.some((choice) => choice.keyless)) {
|
|
70598
|
+
console.log(source_default.dim(" No API key needed for selected local provider(s)."));
|
|
70599
|
+
}
|
|
70600
|
+
console.log();
|
|
70601
|
+
} else {
|
|
70602
|
+
for (const keyDef of feature.keys) {
|
|
70603
|
+
addUniqueKey(keysForFeature, keyDef);
|
|
70604
|
+
}
|
|
70455
70605
|
}
|
|
70606
|
+
plannedKeys.set(feature.label, keysForFeature);
|
|
70607
|
+
}
|
|
70608
|
+
const needsKeys = [...plannedKeys.values()].some((keys) => keys.length > 0);
|
|
70609
|
+
if (needsKeys) {
|
|
70610
|
+
console.log(source_default.dim("4. API keys"));
|
|
70611
|
+
console.log(source_default.bold("API Keys"));
|
|
70612
|
+
console.log(source_default.dim(" Saved locally, never shared. Press Enter to skip."));
|
|
70456
70613
|
console.log();
|
|
70457
|
-
|
|
70458
|
-
|
|
70459
|
-
|
|
70614
|
+
const collectedKeys = /* @__PURE__ */ new Set();
|
|
70615
|
+
for (const feature of selectedFeatures) {
|
|
70616
|
+
const keysForFeature = plannedKeys.get(feature.label) ?? [];
|
|
70617
|
+
if (keysForFeature.length === 0) {
|
|
70460
70618
|
continue;
|
|
70461
70619
|
}
|
|
70462
|
-
|
|
70463
|
-
|
|
70464
|
-
|
|
70465
|
-
|
|
70466
|
-
const value = configValue || envValue;
|
|
70467
|
-
const source = configValue ? "config" : ".env";
|
|
70468
|
-
console.log(` ${source_default.green("\u2713")} ${keyDef.name.padEnd(14)} ${maskApiKey(value)} ${source_default.dim(`(${source})`)}`);
|
|
70469
|
-
collectedKeys.add(keyDef.configKey);
|
|
70470
|
-
continue;
|
|
70620
|
+
console.log(source_default.bold.cyan(` ${feature.label}`));
|
|
70621
|
+
console.log(source_default.dim(` Default: ${feature.defaultProvider}`));
|
|
70622
|
+
if (feature.alsoAvailable) {
|
|
70623
|
+
console.log(source_default.dim(` Also available: ${feature.alsoAvailable}`));
|
|
70471
70624
|
}
|
|
70472
|
-
console.log(
|
|
70473
|
-
|
|
70474
|
-
|
|
70475
|
-
|
|
70476
|
-
|
|
70477
|
-
|
|
70478
|
-
|
|
70479
|
-
const
|
|
70480
|
-
|
|
70481
|
-
|
|
70482
|
-
|
|
70483
|
-
|
|
70625
|
+
console.log();
|
|
70626
|
+
for (const keyDef of keysForFeature) {
|
|
70627
|
+
if (collectedKeys.has(keyDef.configKey)) {
|
|
70628
|
+
console.log(` ${source_default.green("\u2713")} ${keyDef.name.padEnd(14)} (already set above)`);
|
|
70629
|
+
continue;
|
|
70630
|
+
}
|
|
70631
|
+
loadEnv();
|
|
70632
|
+
const configValue = config2.providers[keyDef.configKey];
|
|
70633
|
+
const envValue = process.env[keyDef.envVar];
|
|
70634
|
+
if (configValue || envValue) {
|
|
70635
|
+
const value = configValue || envValue;
|
|
70636
|
+
const source = configValue ? "config" : ".env";
|
|
70637
|
+
console.log(
|
|
70638
|
+
` ${source_default.green("\u2713")} ${keyDef.name.padEnd(14)} ${maskApiKey(value)} ${source_default.dim(`(${source})`)}`
|
|
70639
|
+
);
|
|
70640
|
+
collectedKeys.add(keyDef.configKey);
|
|
70641
|
+
continue;
|
|
70642
|
+
}
|
|
70643
|
+
console.log(source_default.dim(` ${keyDef.what}`));
|
|
70644
|
+
console.log(source_default.dim(` Get key: ${keyDef.url} [o] open in browser`));
|
|
70645
|
+
const newKey = await promptHidden(
|
|
70646
|
+
source_default.cyan(` ${keyDef.name.padEnd(14)} ${source_default.dim(keyDef.envVar)}: `),
|
|
70647
|
+
{ openHotkeyUrl: keyDef.url }
|
|
70648
|
+
);
|
|
70649
|
+
if (newKey.trim()) {
|
|
70650
|
+
const trimmed = newKey.trim();
|
|
70651
|
+
config2.providers[keyDef.configKey] = trimmed;
|
|
70652
|
+
const fmt = validateKeyFormat(keyDef.configKey, trimmed);
|
|
70653
|
+
if (!fmt.ok && fmt.expected) {
|
|
70654
|
+
console.log(
|
|
70655
|
+
` ${source_default.yellow("\u26A0")} Saved, but format looks unusual ${source_default.dim(`(expected ${fmt.expected})`)}`
|
|
70656
|
+
);
|
|
70657
|
+
} else {
|
|
70658
|
+
console.log(` ${source_default.green("\u2713")} Saved`);
|
|
70659
|
+
}
|
|
70660
|
+
collectedKeys.add(keyDef.configKey);
|
|
70484
70661
|
} else {
|
|
70485
|
-
console.log(
|
|
70662
|
+
console.log(
|
|
70663
|
+
` ${source_default.yellow("\u26A0")} Skipped ${source_default.dim(`(set ${keyDef.envVar} in .env later)`)}`
|
|
70664
|
+
);
|
|
70486
70665
|
}
|
|
70487
|
-
collectedKeys.add(keyDef.configKey);
|
|
70488
|
-
} else {
|
|
70489
|
-
console.log(` ${source_default.yellow("\u26A0")} Skipped ${source_default.dim(`(set ${keyDef.envVar} in .env later)`)}`);
|
|
70490
70666
|
}
|
|
70667
|
+
console.log();
|
|
70491
70668
|
}
|
|
70669
|
+
} else {
|
|
70670
|
+
console.log(source_default.dim("4. API keys"));
|
|
70671
|
+
console.log(source_default.dim(" No API keys needed for the selected provider(s)."));
|
|
70492
70672
|
console.log();
|
|
70493
70673
|
}
|
|
70494
|
-
|
|
70495
|
-
console.log(source_default.dim("4. API keys"));
|
|
70496
|
-
console.log(source_default.dim(" No API keys needed for the selected provider(s)."));
|
|
70497
|
-
console.log();
|
|
70674
|
+
return { tryCommand: selectedFeatures[0].tryCommand, selectedFeatures };
|
|
70498
70675
|
}
|
|
70499
|
-
return { tryCommand: selectedFeatures[0].tryCommand, selectedFeatures };
|
|
70500
70676
|
}
|
|
70501
70677
|
async function collectKeys(config2, keys) {
|
|
70502
70678
|
loadEnv();
|
|
@@ -70504,11 +70680,15 @@ async function collectKeys(config2, keys) {
|
|
|
70504
70680
|
const configValue = config2.providers[keyDef.configKey];
|
|
70505
70681
|
const envValue = process.env[keyDef.envVar];
|
|
70506
70682
|
if (configValue) {
|
|
70507
|
-
console.log(
|
|
70683
|
+
console.log(
|
|
70684
|
+
` ${source_default.green("\u2713")} ${keyDef.name.padEnd(14)} ${maskApiKey(configValue)} ${source_default.dim("(config)")}`
|
|
70685
|
+
);
|
|
70508
70686
|
continue;
|
|
70509
70687
|
}
|
|
70510
70688
|
if (envValue) {
|
|
70511
|
-
console.log(
|
|
70689
|
+
console.log(
|
|
70690
|
+
` ${source_default.green("\u2713")} ${keyDef.name.padEnd(14)} ${maskApiKey(envValue)} ${source_default.dim("(.env)")}`
|
|
70691
|
+
);
|
|
70512
70692
|
continue;
|
|
70513
70693
|
}
|
|
70514
70694
|
console.log(source_default.dim(` ${keyDef.what}`));
|
|
@@ -70522,12 +70702,16 @@ async function collectKeys(config2, keys) {
|
|
|
70522
70702
|
config2.providers[keyDef.configKey] = trimmed;
|
|
70523
70703
|
const fmt = validateKeyFormat(keyDef.configKey, trimmed);
|
|
70524
70704
|
if (!fmt.ok && fmt.expected) {
|
|
70525
|
-
console.log(
|
|
70705
|
+
console.log(
|
|
70706
|
+
` ${source_default.yellow("\u26A0")} Saved, but format looks unusual ${source_default.dim(`(expected ${fmt.expected})`)}`
|
|
70707
|
+
);
|
|
70526
70708
|
} else {
|
|
70527
70709
|
console.log(` ${source_default.green("\u2713")} Saved`);
|
|
70528
70710
|
}
|
|
70529
70711
|
} else {
|
|
70530
|
-
console.log(
|
|
70712
|
+
console.log(
|
|
70713
|
+
` ${source_default.yellow("\u26A0")} Skipped ${source_default.dim(`(set ${keyDef.envVar} in .env later)`)}`
|
|
70714
|
+
);
|
|
70531
70715
|
}
|
|
70532
70716
|
}
|
|
70533
70717
|
console.log();
|
|
@@ -70564,37 +70748,41 @@ async function runCustomSetup(config2, scope = "user", opts = {}) {
|
|
|
70564
70748
|
for (const p of allProviders) {
|
|
70565
70749
|
const existing = config2.providers[p.key];
|
|
70566
70750
|
if (existing) {
|
|
70567
|
-
console.log(
|
|
70751
|
+
console.log(
|
|
70752
|
+
` ${source_default.green("\u2713")} ${p.name.padEnd(12)} ${maskApiKey(existing)} ${source_default.dim(p.desc)}`
|
|
70753
|
+
);
|
|
70568
70754
|
const change = await promptConfirm(source_default.cyan(" Update?"), false);
|
|
70569
70755
|
if (change) {
|
|
70570
70756
|
console.log(source_default.dim(` Get key: ${p.url} [o] open in browser`));
|
|
70571
|
-
const newKey = await promptHidden(
|
|
70572
|
-
source_default.cyan(" New key: "),
|
|
70573
|
-
{ openHotkeyUrl: p.url }
|
|
70574
|
-
);
|
|
70757
|
+
const newKey = await promptHidden(source_default.cyan(" New key: "), { openHotkeyUrl: p.url });
|
|
70575
70758
|
if (newKey.trim()) {
|
|
70576
70759
|
const trimmed = newKey.trim();
|
|
70577
70760
|
config2.providers[p.key] = trimmed;
|
|
70578
70761
|
const fmt = validateKeyFormat(p.key, trimmed);
|
|
70579
70762
|
if (!fmt.ok && fmt.expected) {
|
|
70580
|
-
console.log(
|
|
70763
|
+
console.log(
|
|
70764
|
+
source_default.yellow(` \u26A0 Updated, but format looks unusual (expected ${fmt.expected})`)
|
|
70765
|
+
);
|
|
70581
70766
|
} else {
|
|
70582
70767
|
console.log(source_default.green(" \u2713 Updated"));
|
|
70583
70768
|
}
|
|
70584
70769
|
}
|
|
70585
70770
|
}
|
|
70586
70771
|
} else {
|
|
70587
|
-
console.log(
|
|
70588
|
-
|
|
70589
|
-
|
|
70590
|
-
|
|
70772
|
+
console.log(
|
|
70773
|
+
source_default.dim(
|
|
70774
|
+
` ${source_default.dim("\u25CB")} ${p.name.padEnd(12)} ${source_default.dim(p.desc)} Get key: ${p.url} [o] open`
|
|
70775
|
+
)
|
|
70591
70776
|
);
|
|
70777
|
+
const newKey = await promptHidden(source_default.cyan(` ${p.env}: `), { openHotkeyUrl: p.url });
|
|
70592
70778
|
if (newKey.trim()) {
|
|
70593
70779
|
const trimmed = newKey.trim();
|
|
70594
70780
|
config2.providers[p.key] = trimmed;
|
|
70595
70781
|
const fmt = validateKeyFormat(p.key, trimmed);
|
|
70596
70782
|
if (!fmt.ok && fmt.expected) {
|
|
70597
|
-
console.log(
|
|
70783
|
+
console.log(
|
|
70784
|
+
` ${source_default.yellow("\u26A0")} Saved, but format looks unusual ${source_default.dim(`(expected ${fmt.expected})`)}`
|
|
70785
|
+
);
|
|
70598
70786
|
} else {
|
|
70599
70787
|
console.log(` ${source_default.green("\u2713")} Saved`);
|
|
70600
70788
|
}
|
|
@@ -70631,14 +70819,20 @@ async function showComplete(config2, defaultTryCommand, features = [], scope = "
|
|
|
70631
70819
|
}
|
|
70632
70820
|
console.log();
|
|
70633
70821
|
console.log(source_default.bold(" Next steps:"));
|
|
70634
|
-
console.log(
|
|
70822
|
+
console.log(
|
|
70823
|
+
source_default.dim(
|
|
70824
|
+
" cd <project>; vibe init Scaffold AGENTS.md / CLAUDE.md / .env.example (project scope)"
|
|
70825
|
+
)
|
|
70826
|
+
);
|
|
70635
70827
|
const hostDetected = detectedAgentHosts().length > 0;
|
|
70636
70828
|
for (const w of listWalkthroughs()) {
|
|
70637
70829
|
const cmd = `vibe walkthrough ${w.topic}`.padEnd(26);
|
|
70638
70830
|
const tag = hostDetected && w.topic === "scene" ? source_default.cyan(" (recommended)") : "";
|
|
70639
70831
|
console.log(source_default.dim(` ${cmd}${w.summary}${tag}`));
|
|
70640
70832
|
}
|
|
70641
|
-
console.log(
|
|
70833
|
+
console.log(
|
|
70834
|
+
source_default.dim(" vibe doctor --test-keys Live-check each provider key against its API")
|
|
70835
|
+
);
|
|
70642
70836
|
console.log(source_default.dim(" vibe doctor Check system health + available commands"));
|
|
70643
70837
|
console.log(source_default.dim(" vibe schema --list Discover every command"));
|
|
70644
70838
|
console.log(source_default.dim(" vibe setup Re-run user-scope setup anytime"));
|
|
@@ -70773,7 +70967,11 @@ async function showConfig(opts = { verbose: false }) {
|
|
|
70773
70967
|
}
|
|
70774
70968
|
}
|
|
70775
70969
|
if (!verbose && unsetCount > 0) {
|
|
70776
|
-
console.log(
|
|
70970
|
+
console.log(
|
|
70971
|
+
source_default.dim(
|
|
70972
|
+
` (${unsetCount} provider${unsetCount === 1 ? "" : "s"} unset \u2014 run with --verbose to list)`
|
|
70973
|
+
)
|
|
70974
|
+
);
|
|
70777
70975
|
}
|
|
70778
70976
|
console.log();
|
|
70779
70977
|
if (verbose) {
|
|
@@ -70785,8 +70983,12 @@ async function showConfig(opts = { verbose: false }) {
|
|
|
70785
70983
|
}
|
|
70786
70984
|
console.log(source_default.bold("Resolution order:"));
|
|
70787
70985
|
console.log(source_default.dim(" 1. --api-key CLI option"));
|
|
70788
|
-
console.log(
|
|
70789
|
-
|
|
70986
|
+
console.log(
|
|
70987
|
+
source_default.dim(` 2. Active config scope: ${activeScope === "project" ? projectPath : userPath}`)
|
|
70988
|
+
);
|
|
70989
|
+
console.log(
|
|
70990
|
+
source_default.dim(` (project takes priority when present at cwd; user is ignored in that case)`)
|
|
70991
|
+
);
|
|
70790
70992
|
console.log(source_default.dim(" 3. .env / shell environment variables (process.env)"));
|
|
70791
70993
|
console.log();
|
|
70792
70994
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/cli",
|
|
3
|
-
"version": "0.91.
|
|
3
|
+
"version": "0.91.8",
|
|
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.8",
|
|
187
|
+
"@vibeframe/core": "0.91.8"
|
|
188
188
|
},
|
|
189
189
|
"engines": {
|
|
190
190
|
"node": ">=20"
|