@vibeframe/cli 0.91.6 → 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 +398 -178
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -31969,7 +31969,10 @@ async function promptMultiSelect(_question, options, defaultSelected = [], opts
|
|
|
31969
31969
|
if (finished) return;
|
|
31970
31970
|
if (char === "\r" || char === "\n") {
|
|
31971
31971
|
if (pickFocused && !userToggled) {
|
|
31972
|
-
|
|
31972
|
+
const hasDefaultSelection = selected.some(Boolean);
|
|
31973
|
+
if (!opts.preserveDefaultSelectionOnEnter || !hasDefaultSelection) {
|
|
31974
|
+
for (let i = 0; i < selected.length; i++) selected[i] = false;
|
|
31975
|
+
}
|
|
31973
31976
|
selected[cursor] = true;
|
|
31974
31977
|
render();
|
|
31975
31978
|
}
|
|
@@ -62959,7 +62962,7 @@ init_source();
|
|
|
62959
62962
|
// package.json
|
|
62960
62963
|
var package_default = {
|
|
62961
62964
|
name: "@vibeframe/cli",
|
|
62962
|
-
version: "0.91.
|
|
62965
|
+
version: "0.91.8",
|
|
62963
62966
|
description: "VibeFrame CLI - natural language video editing from the terminal",
|
|
62964
62967
|
private: false,
|
|
62965
62968
|
license: "MIT",
|
|
@@ -69960,14 +69963,19 @@ var VALID_SCOPES = ["user", "project"];
|
|
|
69960
69963
|
function parseScope(raw) {
|
|
69961
69964
|
const v = String(raw ?? "user");
|
|
69962
69965
|
if (!VALID_SCOPES.includes(v)) {
|
|
69963
|
-
exitWithError(
|
|
69964
|
-
`Invalid --scope: ${v}`,
|
|
69965
|
-
|
|
69966
|
-
));
|
|
69966
|
+
exitWithError(
|
|
69967
|
+
generalError(`Invalid --scope: ${v}`, `Must be one of: ${VALID_SCOPES.join(", ")}`)
|
|
69968
|
+
);
|
|
69967
69969
|
}
|
|
69968
69970
|
return v;
|
|
69969
69971
|
}
|
|
69970
|
-
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(
|
|
69971
69979
|
"--scope <scope>",
|
|
69972
69980
|
"Where to save: 'user' (~/.vibeframe/config.yaml, shared) or 'project' (./.vibeframe/config.yaml, gitignored, this project only)",
|
|
69973
69981
|
"user"
|
|
@@ -70017,10 +70025,12 @@ Exit codes (non-interactive):
|
|
|
70017
70025
|
return;
|
|
70018
70026
|
}
|
|
70019
70027
|
if (!hasTTY()) {
|
|
70020
|
-
exitWithError(
|
|
70021
|
-
|
|
70022
|
-
|
|
70023
|
-
|
|
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
|
+
);
|
|
70024
70034
|
}
|
|
70025
70035
|
try {
|
|
70026
70036
|
await runSetupWizard(options.full, scope);
|
|
@@ -70037,24 +70047,50 @@ var AI_FEATURES = [
|
|
|
70037
70047
|
desc: "generate + edit",
|
|
70038
70048
|
defaultProvider: "OpenAI gpt-image-2 (Artificial Analysis #1, since v0.56)",
|
|
70039
70049
|
alsoAvailable: "Gemini Nano Banana, Grok Imagine",
|
|
70040
|
-
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
|
+
],
|
|
70041
70059
|
providerChoices: [
|
|
70042
70060
|
{
|
|
70043
70061
|
label: "OpenAI gpt-image-2",
|
|
70044
70062
|
desc: "recommended default, image generation + editing",
|
|
70045
|
-
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
|
+
},
|
|
70046
70070
|
defaultFor: { kind: "image", value: "openai" }
|
|
70047
70071
|
},
|
|
70048
70072
|
{
|
|
70049
70073
|
label: "Gemini",
|
|
70050
70074
|
desc: "Google image generation + multimodal analysis",
|
|
70051
|
-
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
|
+
},
|
|
70052
70082
|
defaultFor: { kind: "image", value: "gemini" }
|
|
70053
70083
|
},
|
|
70054
70084
|
{
|
|
70055
70085
|
label: "Grok",
|
|
70056
70086
|
desc: "xAI image generation",
|
|
70057
|
-
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
|
+
},
|
|
70058
70094
|
defaultFor: { kind: "image", value: "grok" }
|
|
70059
70095
|
}
|
|
70060
70096
|
],
|
|
@@ -70065,36 +70101,74 @@ var AI_FEATURES = [
|
|
|
70065
70101
|
desc: "generate + extend",
|
|
70066
70102
|
defaultProvider: "Seedance 2.0 via fal.ai (Artificial Analysis #2 t2v + i2v, since v0.57)",
|
|
70067
70103
|
alsoAvailable: "Grok Imagine, Kling, Runway Gen-4.5, Google Veo",
|
|
70068
|
-
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
|
+
],
|
|
70069
70113
|
providerChoices: [
|
|
70070
70114
|
{
|
|
70071
70115
|
label: "Seedance 2.0 via fal.ai",
|
|
70072
70116
|
desc: "recommended default, text-to-video + image-to-video",
|
|
70073
|
-
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
|
+
},
|
|
70074
70124
|
defaultFor: { kind: "video", value: "seedance" }
|
|
70075
70125
|
},
|
|
70076
70126
|
{
|
|
70077
70127
|
label: "Grok",
|
|
70078
70128
|
desc: "xAI video generation with audio",
|
|
70079
|
-
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
|
+
},
|
|
70080
70136
|
defaultFor: { kind: "video", value: "grok" }
|
|
70081
70137
|
},
|
|
70082
70138
|
{
|
|
70083
70139
|
label: "Kling",
|
|
70084
70140
|
desc: "Kling v2.5/v3 video generation",
|
|
70085
|
-
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
|
+
},
|
|
70086
70148
|
defaultFor: { kind: "video", value: "kling" }
|
|
70087
70149
|
},
|
|
70088
70150
|
{
|
|
70089
70151
|
label: "Runway",
|
|
70090
70152
|
desc: "Runway Gen-4.5 video generation",
|
|
70091
|
-
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
|
+
},
|
|
70092
70160
|
defaultFor: { kind: "video", value: "runway" }
|
|
70093
70161
|
},
|
|
70094
70162
|
{
|
|
70095
70163
|
label: "Veo",
|
|
70096
70164
|
desc: "Google Veo video generation",
|
|
70097
|
-
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
|
+
},
|
|
70098
70172
|
defaultFor: { kind: "video", value: "veo" }
|
|
70099
70173
|
}
|
|
70100
70174
|
],
|
|
@@ -70105,12 +70179,26 @@ var AI_FEATURES = [
|
|
|
70105
70179
|
desc: "TTS, SFX, music, voice clone",
|
|
70106
70180
|
defaultProvider: "ElevenLabs (paid, premium quality) \u2014 falls back to local Kokoro when no key (free, since v0.54)",
|
|
70107
70181
|
alsoAvailable: "Replicate MusicGen (music only)",
|
|
70108
|
-
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
|
+
],
|
|
70109
70191
|
providerChoices: [
|
|
70110
70192
|
{
|
|
70111
70193
|
label: "ElevenLabs",
|
|
70112
70194
|
desc: "premium TTS, SFX, music, voice clone",
|
|
70113
|
-
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
|
+
}
|
|
70114
70202
|
},
|
|
70115
70203
|
{
|
|
70116
70204
|
label: "Kokoro local",
|
|
@@ -70120,7 +70208,13 @@ var AI_FEATURES = [
|
|
|
70120
70208
|
{
|
|
70121
70209
|
label: "Replicate MusicGen",
|
|
70122
70210
|
desc: "background music generation",
|
|
70123
|
-
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
|
+
}
|
|
70124
70218
|
}
|
|
70125
70219
|
],
|
|
70126
70220
|
tryCommand: 'vibe generate speech "Hello world" -o hello.mp3'
|
|
@@ -70131,8 +70225,20 @@ var AI_FEATURES = [
|
|
|
70131
70225
|
defaultProvider: "Whisper (transcription) + Claude (reasoning)",
|
|
70132
70226
|
alsoAvailable: "",
|
|
70133
70227
|
keys: [
|
|
70134
|
-
{
|
|
70135
|
-
|
|
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
|
+
}
|
|
70136
70242
|
],
|
|
70137
70243
|
tryCommand: "vibe edit caption video.mp4 -o captioned.mp4"
|
|
70138
70244
|
}
|
|
@@ -70150,6 +70256,27 @@ function applyProviderDefault(config2, choice) {
|
|
|
70150
70256
|
config2.defaults.videoProvider = choice.defaultFor.value;
|
|
70151
70257
|
}
|
|
70152
70258
|
}
|
|
70259
|
+
function isProviderChoiceConfigured(config2, choice) {
|
|
70260
|
+
if (choice.key) {
|
|
70261
|
+
const value = config2.providers[choice.key.configKey];
|
|
70262
|
+
if (value) return true;
|
|
70263
|
+
}
|
|
70264
|
+
if (choice.defaultFor?.kind === "image") {
|
|
70265
|
+
return config2.defaults.imageProvider === choice.defaultFor.value;
|
|
70266
|
+
}
|
|
70267
|
+
if (choice.defaultFor?.kind === "video") {
|
|
70268
|
+
return config2.defaults.videoProvider === choice.defaultFor.value;
|
|
70269
|
+
}
|
|
70270
|
+
return false;
|
|
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
|
+
}
|
|
70153
70280
|
function mergeSelectedFeatures(current, next) {
|
|
70154
70281
|
const merged = [...current];
|
|
70155
70282
|
for (const feature of next) {
|
|
@@ -70168,10 +70295,12 @@ async function runNonInteractiveSetup(opts) {
|
|
|
70168
70295
|
const changes = [];
|
|
70169
70296
|
if (opts.provider) {
|
|
70170
70297
|
if (!VALID_LLM_PROVIDERS.includes(opts.provider)) {
|
|
70171
|
-
exitWithError(
|
|
70172
|
-
|
|
70173
|
-
|
|
70174
|
-
|
|
70298
|
+
exitWithError(
|
|
70299
|
+
generalError(
|
|
70300
|
+
`Invalid --provider: ${opts.provider}`,
|
|
70301
|
+
`Must be one of: ${VALID_LLM_PROVIDERS.join(", ")}`
|
|
70302
|
+
)
|
|
70303
|
+
);
|
|
70175
70304
|
}
|
|
70176
70305
|
if (config2.llm.provider !== opts.provider) {
|
|
70177
70306
|
config2.llm.provider = opts.provider;
|
|
@@ -70238,7 +70367,11 @@ async function runNonInteractiveSetup(opts) {
|
|
|
70238
70367
|
}
|
|
70239
70368
|
if (failures > 0) {
|
|
70240
70369
|
console.error();
|
|
70241
|
-
console.error(
|
|
70370
|
+
console.error(
|
|
70371
|
+
source_default.red(
|
|
70372
|
+
`Verification failed: ${failures} key${failures === 1 ? "" : "s"} returned non-2xx.`
|
|
70373
|
+
)
|
|
70374
|
+
);
|
|
70242
70375
|
process.exit(7);
|
|
70243
70376
|
}
|
|
70244
70377
|
}
|
|
@@ -70247,15 +70380,11 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70247
70380
|
console.log();
|
|
70248
70381
|
const cfgPath = getConfigPath(scope).replace(homedir5(), "~");
|
|
70249
70382
|
const scopeNote = scope === "project" ? "applies to this project only \xB7 add .vibeframe/ to .gitignore" : "applies to every project for this user";
|
|
70250
|
-
console.log(
|
|
70251
|
-
source_default.bold.magenta("VibeFrame Setup") + source_default.bold(` \u2014 ${scope} scope`)
|
|
70252
|
-
);
|
|
70383
|
+
console.log(source_default.bold.magenta("VibeFrame Setup") + source_default.bold(` \u2014 ${scope} scope`));
|
|
70253
70384
|
console.log(source_default.dim(`${cfgPath} \xB7 ${scopeNote}`));
|
|
70254
70385
|
if (scope === "user") {
|
|
70255
70386
|
console.log(
|
|
70256
|
-
source_default.dim(
|
|
70257
|
-
"Tip: for per-project keys, cd into a project and run: vibe setup --scope project"
|
|
70258
|
-
)
|
|
70387
|
+
source_default.dim("Tip: for per-project keys, cd into a project and run: vibe setup --scope project")
|
|
70259
70388
|
);
|
|
70260
70389
|
}
|
|
70261
70390
|
console.log(source_default.dim("\u2500".repeat(40)));
|
|
@@ -70296,10 +70425,34 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70296
70425
|
if (topIndex === 2) {
|
|
70297
70426
|
config2.llm.provider = "claude";
|
|
70298
70427
|
const pipelineKeys = [
|
|
70299
|
-
{
|
|
70300
|
-
|
|
70301
|
-
|
|
70302
|
-
|
|
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
|
+
}
|
|
70303
70456
|
];
|
|
70304
70457
|
console.log(source_default.dim("2. API keys"));
|
|
70305
70458
|
console.log(source_default.bold("Pipeline requires these API keys:"));
|
|
@@ -70307,10 +70460,19 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
|
70307
70460
|
console.log();
|
|
70308
70461
|
await collectKeys(config2, pipelineKeys);
|
|
70309
70462
|
await saveConfig(config2, { scope });
|
|
70310
|
-
await completeOrContinue(
|
|
70463
|
+
await completeOrContinue(
|
|
70464
|
+
config2,
|
|
70465
|
+
"vibe build my-story/ # see CONTRIBUTING.md for STORYBOARD.md format",
|
|
70466
|
+
[],
|
|
70467
|
+
scope
|
|
70468
|
+
);
|
|
70311
70469
|
return;
|
|
70312
70470
|
}
|
|
70313
70471
|
const result = await runAIFeaturesSetup(config2, scope);
|
|
70472
|
+
if (result.back) {
|
|
70473
|
+
await completeOrContinue(config2, "vibe --help", [], scope);
|
|
70474
|
+
return;
|
|
70475
|
+
}
|
|
70314
70476
|
await saveConfig(config2, { scope });
|
|
70315
70477
|
await completeOrContinue(config2, result.tryCommand, result.selectedFeatures, scope);
|
|
70316
70478
|
}
|
|
@@ -70330,6 +70492,10 @@ async function completeOrContinue(config2, tryCommand, selectedFeatures, scope)
|
|
|
70330
70492
|
console.log();
|
|
70331
70493
|
if (action === 0) {
|
|
70332
70494
|
const result = await runAIFeaturesSetup(config2, scope);
|
|
70495
|
+
if (result.back) {
|
|
70496
|
+
await completeOrContinue(config2, tryCommand, selectedFeatures, scope);
|
|
70497
|
+
return;
|
|
70498
|
+
}
|
|
70333
70499
|
const mergedFeatures = mergeSelectedFeatures(selectedFeatures, result.selectedFeatures);
|
|
70334
70500
|
const mergedTryCommand = selectedFeatures.length > 0 ? tryCommand : result.tryCommand;
|
|
70335
70501
|
await saveConfig(config2, { scope });
|
|
@@ -70345,140 +70511,168 @@ async function completeOrContinue(config2, tryCommand, selectedFeatures, scope)
|
|
|
70345
70511
|
await showComplete(config2, tryCommand, selectedFeatures, scope);
|
|
70346
70512
|
}
|
|
70347
70513
|
async function runAIFeaturesSetup(config2, _scope) {
|
|
70348
|
-
|
|
70349
|
-
|
|
70350
|
-
|
|
70351
|
-
|
|
70352
|
-
|
|
70353
|
-
|
|
70354
|
-
|
|
70355
|
-
|
|
70356
|
-
|
|
70357
|
-
});
|
|
70358
|
-
const picked = await promptMultiSelect(
|
|
70359
|
-
source_default.cyan(" Pick (e.g. 1,3 or 'all'): "),
|
|
70360
|
-
featureLabels,
|
|
70361
|
-
[],
|
|
70362
|
-
{ pickFocusedOnEnter: true }
|
|
70363
|
-
);
|
|
70364
|
-
const selectedFeatures = picked.map((i) => AI_FEATURES[i]);
|
|
70365
|
-
console.log();
|
|
70366
|
-
if (selectedFeatures.length === 0) {
|
|
70367
|
-
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.`));
|
|
70368
70524
|
console.log();
|
|
70369
|
-
|
|
70370
|
-
|
|
70371
|
-
|
|
70372
|
-
|
|
70373
|
-
|
|
70374
|
-
|
|
70375
|
-
|
|
70376
|
-
|
|
70377
|
-
|
|
70378
|
-
|
|
70379
|
-
|
|
70380
|
-
|
|
70381
|
-
|
|
70382
|
-
|
|
70383
|
-
}
|
|
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)) {
|
|
70384
70542
|
console.log();
|
|
70385
|
-
|
|
70386
|
-
|
|
70387
|
-
|
|
70388
|
-
|
|
70389
|
-
|
|
70390
|
-
|
|
70391
|
-
defaultHint,
|
|
70392
|
-
source_default.dim(`- ${choice.desc}`),
|
|
70393
|
-
keyHint
|
|
70394
|
-
].filter(Boolean).join(" ");
|
|
70395
|
-
});
|
|
70396
|
-
const pickedProviders = await promptMultiSelect(
|
|
70397
|
-
source_default.cyan(" Providers (arrow + enter picks one, space adds more): "),
|
|
70398
|
-
providerLabels,
|
|
70399
|
-
defaultSelected,
|
|
70400
|
-
{ pickFocusedOnEnter: true }
|
|
70401
|
-
);
|
|
70402
|
-
const selectedChoices = pickedProviders.map((i) => feature.providerChoices[i]);
|
|
70403
|
-
const defaultChoice = selectedChoices.find((choice) => choice.defaultFor);
|
|
70404
|
-
if (defaultChoice) {
|
|
70405
|
-
applyProviderDefault(config2, defaultChoice);
|
|
70406
|
-
}
|
|
70407
|
-
for (const choice of selectedChoices) {
|
|
70408
|
-
if (choice.key) addUniqueKey(keysForFeature, choice.key);
|
|
70409
|
-
}
|
|
70410
|
-
if (selectedChoices.some((choice) => choice.keyless)) {
|
|
70411
|
-
console.log(source_default.dim(" No API key needed for selected local provider(s)."));
|
|
70412
|
-
}
|
|
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."));
|
|
70413
70549
|
console.log();
|
|
70414
|
-
|
|
70415
|
-
for (const keyDef of feature.keys) {
|
|
70416
|
-
addUniqueKey(keysForFeature, keyDef);
|
|
70417
|
-
}
|
|
70550
|
+
return { tryCommand: "vibe --help", selectedFeatures: [] };
|
|
70418
70551
|
}
|
|
70419
|
-
plannedKeys
|
|
70420
|
-
|
|
70421
|
-
|
|
70422
|
-
|
|
70423
|
-
|
|
70424
|
-
|
|
70425
|
-
|
|
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
|
+
);
|
|
70426
70560
|
console.log();
|
|
70427
|
-
const collectedKeys = /* @__PURE__ */ new Set();
|
|
70428
70561
|
for (const feature of selectedFeatures) {
|
|
70429
|
-
const keysForFeature =
|
|
70430
|
-
if (
|
|
70431
|
-
|
|
70432
|
-
|
|
70433
|
-
|
|
70434
|
-
|
|
70435
|
-
|
|
70436
|
-
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
|
+
}
|
|
70437
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."));
|
|
70438
70613
|
console.log();
|
|
70439
|
-
|
|
70440
|
-
|
|
70441
|
-
|
|
70614
|
+
const collectedKeys = /* @__PURE__ */ new Set();
|
|
70615
|
+
for (const feature of selectedFeatures) {
|
|
70616
|
+
const keysForFeature = plannedKeys.get(feature.label) ?? [];
|
|
70617
|
+
if (keysForFeature.length === 0) {
|
|
70442
70618
|
continue;
|
|
70443
70619
|
}
|
|
70444
|
-
|
|
70445
|
-
|
|
70446
|
-
|
|
70447
|
-
|
|
70448
|
-
const value = configValue || envValue;
|
|
70449
|
-
const source = configValue ? "config" : ".env";
|
|
70450
|
-
console.log(` ${source_default.green("\u2713")} ${keyDef.name.padEnd(14)} ${maskApiKey(value)} ${source_default.dim(`(${source})`)}`);
|
|
70451
|
-
collectedKeys.add(keyDef.configKey);
|
|
70452
|
-
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}`));
|
|
70453
70624
|
}
|
|
70454
|
-
console.log(
|
|
70455
|
-
|
|
70456
|
-
|
|
70457
|
-
|
|
70458
|
-
|
|
70459
|
-
|
|
70460
|
-
|
|
70461
|
-
const
|
|
70462
|
-
|
|
70463
|
-
|
|
70464
|
-
|
|
70465
|
-
|
|
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);
|
|
70466
70661
|
} else {
|
|
70467
|
-
console.log(
|
|
70662
|
+
console.log(
|
|
70663
|
+
` ${source_default.yellow("\u26A0")} Skipped ${source_default.dim(`(set ${keyDef.envVar} in .env later)`)}`
|
|
70664
|
+
);
|
|
70468
70665
|
}
|
|
70469
|
-
collectedKeys.add(keyDef.configKey);
|
|
70470
|
-
} else {
|
|
70471
|
-
console.log(` ${source_default.yellow("\u26A0")} Skipped ${source_default.dim(`(set ${keyDef.envVar} in .env later)`)}`);
|
|
70472
70666
|
}
|
|
70667
|
+
console.log();
|
|
70473
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)."));
|
|
70474
70672
|
console.log();
|
|
70475
70673
|
}
|
|
70476
|
-
|
|
70477
|
-
console.log(source_default.dim("4. API keys"));
|
|
70478
|
-
console.log(source_default.dim(" No API keys needed for the selected provider(s)."));
|
|
70479
|
-
console.log();
|
|
70674
|
+
return { tryCommand: selectedFeatures[0].tryCommand, selectedFeatures };
|
|
70480
70675
|
}
|
|
70481
|
-
return { tryCommand: selectedFeatures[0].tryCommand, selectedFeatures };
|
|
70482
70676
|
}
|
|
70483
70677
|
async function collectKeys(config2, keys) {
|
|
70484
70678
|
loadEnv();
|
|
@@ -70486,11 +70680,15 @@ async function collectKeys(config2, keys) {
|
|
|
70486
70680
|
const configValue = config2.providers[keyDef.configKey];
|
|
70487
70681
|
const envValue = process.env[keyDef.envVar];
|
|
70488
70682
|
if (configValue) {
|
|
70489
|
-
console.log(
|
|
70683
|
+
console.log(
|
|
70684
|
+
` ${source_default.green("\u2713")} ${keyDef.name.padEnd(14)} ${maskApiKey(configValue)} ${source_default.dim("(config)")}`
|
|
70685
|
+
);
|
|
70490
70686
|
continue;
|
|
70491
70687
|
}
|
|
70492
70688
|
if (envValue) {
|
|
70493
|
-
console.log(
|
|
70689
|
+
console.log(
|
|
70690
|
+
` ${source_default.green("\u2713")} ${keyDef.name.padEnd(14)} ${maskApiKey(envValue)} ${source_default.dim("(.env)")}`
|
|
70691
|
+
);
|
|
70494
70692
|
continue;
|
|
70495
70693
|
}
|
|
70496
70694
|
console.log(source_default.dim(` ${keyDef.what}`));
|
|
@@ -70504,12 +70702,16 @@ async function collectKeys(config2, keys) {
|
|
|
70504
70702
|
config2.providers[keyDef.configKey] = trimmed;
|
|
70505
70703
|
const fmt = validateKeyFormat(keyDef.configKey, trimmed);
|
|
70506
70704
|
if (!fmt.ok && fmt.expected) {
|
|
70507
|
-
console.log(
|
|
70705
|
+
console.log(
|
|
70706
|
+
` ${source_default.yellow("\u26A0")} Saved, but format looks unusual ${source_default.dim(`(expected ${fmt.expected})`)}`
|
|
70707
|
+
);
|
|
70508
70708
|
} else {
|
|
70509
70709
|
console.log(` ${source_default.green("\u2713")} Saved`);
|
|
70510
70710
|
}
|
|
70511
70711
|
} else {
|
|
70512
|
-
console.log(
|
|
70712
|
+
console.log(
|
|
70713
|
+
` ${source_default.yellow("\u26A0")} Skipped ${source_default.dim(`(set ${keyDef.envVar} in .env later)`)}`
|
|
70714
|
+
);
|
|
70513
70715
|
}
|
|
70514
70716
|
}
|
|
70515
70717
|
console.log();
|
|
@@ -70546,37 +70748,41 @@ async function runCustomSetup(config2, scope = "user", opts = {}) {
|
|
|
70546
70748
|
for (const p of allProviders) {
|
|
70547
70749
|
const existing = config2.providers[p.key];
|
|
70548
70750
|
if (existing) {
|
|
70549
|
-
console.log(
|
|
70751
|
+
console.log(
|
|
70752
|
+
` ${source_default.green("\u2713")} ${p.name.padEnd(12)} ${maskApiKey(existing)} ${source_default.dim(p.desc)}`
|
|
70753
|
+
);
|
|
70550
70754
|
const change = await promptConfirm(source_default.cyan(" Update?"), false);
|
|
70551
70755
|
if (change) {
|
|
70552
70756
|
console.log(source_default.dim(` Get key: ${p.url} [o] open in browser`));
|
|
70553
|
-
const newKey = await promptHidden(
|
|
70554
|
-
source_default.cyan(" New key: "),
|
|
70555
|
-
{ openHotkeyUrl: p.url }
|
|
70556
|
-
);
|
|
70757
|
+
const newKey = await promptHidden(source_default.cyan(" New key: "), { openHotkeyUrl: p.url });
|
|
70557
70758
|
if (newKey.trim()) {
|
|
70558
70759
|
const trimmed = newKey.trim();
|
|
70559
70760
|
config2.providers[p.key] = trimmed;
|
|
70560
70761
|
const fmt = validateKeyFormat(p.key, trimmed);
|
|
70561
70762
|
if (!fmt.ok && fmt.expected) {
|
|
70562
|
-
console.log(
|
|
70763
|
+
console.log(
|
|
70764
|
+
source_default.yellow(` \u26A0 Updated, but format looks unusual (expected ${fmt.expected})`)
|
|
70765
|
+
);
|
|
70563
70766
|
} else {
|
|
70564
70767
|
console.log(source_default.green(" \u2713 Updated"));
|
|
70565
70768
|
}
|
|
70566
70769
|
}
|
|
70567
70770
|
}
|
|
70568
70771
|
} else {
|
|
70569
|
-
console.log(
|
|
70570
|
-
|
|
70571
|
-
|
|
70572
|
-
|
|
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
|
+
)
|
|
70573
70776
|
);
|
|
70777
|
+
const newKey = await promptHidden(source_default.cyan(` ${p.env}: `), { openHotkeyUrl: p.url });
|
|
70574
70778
|
if (newKey.trim()) {
|
|
70575
70779
|
const trimmed = newKey.trim();
|
|
70576
70780
|
config2.providers[p.key] = trimmed;
|
|
70577
70781
|
const fmt = validateKeyFormat(p.key, trimmed);
|
|
70578
70782
|
if (!fmt.ok && fmt.expected) {
|
|
70579
|
-
console.log(
|
|
70783
|
+
console.log(
|
|
70784
|
+
` ${source_default.yellow("\u26A0")} Saved, but format looks unusual ${source_default.dim(`(expected ${fmt.expected})`)}`
|
|
70785
|
+
);
|
|
70580
70786
|
} else {
|
|
70581
70787
|
console.log(` ${source_default.green("\u2713")} Saved`);
|
|
70582
70788
|
}
|
|
@@ -70613,14 +70819,20 @@ async function showComplete(config2, defaultTryCommand, features = [], scope = "
|
|
|
70613
70819
|
}
|
|
70614
70820
|
console.log();
|
|
70615
70821
|
console.log(source_default.bold(" Next steps:"));
|
|
70616
|
-
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
|
+
);
|
|
70617
70827
|
const hostDetected = detectedAgentHosts().length > 0;
|
|
70618
70828
|
for (const w of listWalkthroughs()) {
|
|
70619
70829
|
const cmd = `vibe walkthrough ${w.topic}`.padEnd(26);
|
|
70620
70830
|
const tag = hostDetected && w.topic === "scene" ? source_default.cyan(" (recommended)") : "";
|
|
70621
70831
|
console.log(source_default.dim(` ${cmd}${w.summary}${tag}`));
|
|
70622
70832
|
}
|
|
70623
|
-
console.log(
|
|
70833
|
+
console.log(
|
|
70834
|
+
source_default.dim(" vibe doctor --test-keys Live-check each provider key against its API")
|
|
70835
|
+
);
|
|
70624
70836
|
console.log(source_default.dim(" vibe doctor Check system health + available commands"));
|
|
70625
70837
|
console.log(source_default.dim(" vibe schema --list Discover every command"));
|
|
70626
70838
|
console.log(source_default.dim(" vibe setup Re-run user-scope setup anytime"));
|
|
@@ -70755,7 +70967,11 @@ async function showConfig(opts = { verbose: false }) {
|
|
|
70755
70967
|
}
|
|
70756
70968
|
}
|
|
70757
70969
|
if (!verbose && unsetCount > 0) {
|
|
70758
|
-
console.log(
|
|
70970
|
+
console.log(
|
|
70971
|
+
source_default.dim(
|
|
70972
|
+
` (${unsetCount} provider${unsetCount === 1 ? "" : "s"} unset \u2014 run with --verbose to list)`
|
|
70973
|
+
)
|
|
70974
|
+
);
|
|
70759
70975
|
}
|
|
70760
70976
|
console.log();
|
|
70761
70977
|
if (verbose) {
|
|
@@ -70767,8 +70983,12 @@ async function showConfig(opts = { verbose: false }) {
|
|
|
70767
70983
|
}
|
|
70768
70984
|
console.log(source_default.bold("Resolution order:"));
|
|
70769
70985
|
console.log(source_default.dim(" 1. --api-key CLI option"));
|
|
70770
|
-
console.log(
|
|
70771
|
-
|
|
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
|
+
);
|
|
70772
70992
|
console.log(source_default.dim(" 3. .env / shell environment variables (process.env)"));
|
|
70773
70993
|
console.log();
|
|
70774
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"
|