@vibeframe/cli 0.104.1 → 0.104.2

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.
Files changed (2) hide show
  1. package/dist/index.js +63 -36
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -26008,21 +26008,8 @@ async function prompt(question, hidden = false) {
26008
26008
  });
26009
26009
  }
26010
26010
  async function getApiKey(envVar, providerName, optionValue) {
26011
- if (optionValue) {
26012
- return optionValue;
26013
- }
26014
- const providerKey = providerKeyForEnvVar(envVar);
26015
- if (providerKey) {
26016
- const configKey = await getApiKeyFromConfig(providerKey);
26017
- if (configKey) {
26018
- return configKey;
26019
- }
26020
- }
26021
- loadEnv();
26022
- const envValue = getEnvValue2(envVar);
26023
- if (envValue) {
26024
- return envValue;
26025
- }
26011
+ const configuredKey = await getConfiguredApiKey(envVar, optionValue);
26012
+ if (configuredKey) return configuredKey;
26026
26013
  if (!process.stdin.isTTY) {
26027
26014
  return null;
26028
26015
  }
@@ -26043,6 +26030,19 @@ async function getApiKey(envVar, providerName, optionValue) {
26043
26030
  }
26044
26031
  return apiKey.trim();
26045
26032
  }
26033
+ async function getConfiguredApiKey(envVar, optionValue, options = {}) {
26034
+ if (optionValue) return optionValue;
26035
+ const providerKey = providerKeyForEnvVar(envVar);
26036
+ if (providerKey) {
26037
+ const configKey = await getApiKeyFromConfig(providerKey, { cwd: options.cwd });
26038
+ if (configKey) return configKey;
26039
+ }
26040
+ loadEnv();
26041
+ return getEnvValue2(envVar);
26042
+ }
26043
+ async function hasConfiguredApiKey(envVar, optionValue, options = {}) {
26044
+ return Boolean(await getConfiguredApiKey(envVar, optionValue, options));
26045
+ }
26046
26046
  function hasApiKey(envVar) {
26047
26047
  loadEnv();
26048
26048
  return !!getEnvValue2(envVar);
@@ -26139,7 +26139,7 @@ var init_api_key = __esm({
26139
26139
 
26140
26140
  // src/commands/_shared/tts-resolve.ts
26141
26141
  async function resolveTtsProvider(preferred = "auto") {
26142
- const choice = preferred === "auto" ? hasApiKey("ELEVENLABS_API_KEY") ? "elevenlabs" : "kokoro" : preferred;
26142
+ const choice = preferred === "auto" ? await getConfiguredApiKey("ELEVENLABS_API_KEY") ? "elevenlabs" : "kokoro" : preferred;
26143
26143
  if (choice === "elevenlabs") {
26144
26144
  return buildElevenLabs();
26145
26145
  }
@@ -26183,7 +26183,6 @@ var init_tts_resolve = __esm({
26183
26183
  "use strict";
26184
26184
  init_dist2();
26185
26185
  init_api_key();
26186
- init_api_key();
26187
26186
  TtsKeyMissingError = class extends Error {
26188
26187
  constructor(provider) {
26189
26188
  super(
@@ -26554,6 +26553,25 @@ consult this file \u2014 run the generate command directly.
26554
26553
  Browse named styles: \`vibe scene list-styles\`. Re-seed from one with
26555
26554
  \`vibe scene init . --visual-style "Swiss Pulse"\` (idempotent).
26556
26555
 
26556
+ ## Provider keys and project scope
26557
+
26558
+ Use VibeFrame CLI generation for project assets:
26559
+ \`vibe generate image|video|speech ...\`. This lets VibeFrame use keys
26560
+ from \`vibe setup --scope project\`.
26561
+
26562
+ Project-scope keys may live in a parent directory, for example
26563
+ \`../.vibeframe/config.yaml\` when this scene was created by
26564
+ \`vibe init launch\`. The \`vibe\` CLI searches upward automatically, so do
26565
+ not decide keys are missing just because \`.vibeframe/config.yaml\` is not
26566
+ inside this scene folder.
26567
+
26568
+ To verify scope without exposing secrets, run \`vibe doctor --json\` from
26569
+ this directory and inspect \`data.scope.activeScope\` plus
26570
+ \`data.scope.project.configPath\`. Never print config contents. Do not use
26571
+ a host agent's built-in image/audio generation tool for VibeFrame project
26572
+ assets unless the user explicitly requests an external, non-VibeFrame
26573
+ asset.
26574
+
26557
26575
  ## Skills \u2014 USE THESE FIRST
26558
26576
 
26559
26577
  @SKILL.md
@@ -32190,7 +32208,7 @@ import { resolve as resolve18 } from "node:path";
32190
32208
  import { writeFile as writeFile15 } from "node:fs/promises";
32191
32209
  async function executeSoundEffect(options) {
32192
32210
  try {
32193
- const apiKey = hasApiKey("ELEVENLABS_API_KEY") ? await getApiKeyFromConfig("elevenlabs") || process.env.ELEVENLABS_API_KEY : null;
32211
+ const apiKey = await getConfiguredApiKey("ELEVENLABS_API_KEY");
32194
32212
  if (!apiKey)
32195
32213
  return {
32196
32214
  success: false,
@@ -32289,7 +32307,6 @@ var init_sound_effect = __esm({
32289
32307
  init_ora();
32290
32308
  init_dist2();
32291
32309
  init_api_key();
32292
- init_config();
32293
32310
  init_output();
32294
32311
  init_validate();
32295
32312
  }
@@ -32298,7 +32315,7 @@ var init_sound_effect = __esm({
32298
32315
  // src/commands/generate/music-status.ts
32299
32316
  async function executeMusicStatus(options) {
32300
32317
  try {
32301
- const apiKey = options.apiKey ?? (hasApiKey("REPLICATE_API_TOKEN") ? await getApiKeyFromConfig("replicate") || process.env.REPLICATE_API_TOKEN : null);
32318
+ const apiKey = await getConfiguredApiKey("REPLICATE_API_TOKEN", options.apiKey);
32302
32319
  if (!apiKey)
32303
32320
  return { success: false, error: "REPLICATE_API_TOKEN required for music status" };
32304
32321
  const replicate = new ReplicateProvider();
@@ -32371,7 +32388,6 @@ var init_music_status = __esm({
32371
32388
  init_source();
32372
32389
  init_dist2();
32373
32390
  init_api_key();
32374
- init_config();
32375
32391
  init_output();
32376
32392
  }
32377
32393
  });
@@ -32452,7 +32468,7 @@ import { resolve as resolve19, dirname as dirname4 } from "node:path";
32452
32468
  import { writeFile as writeFile16, mkdir as mkdir8 } from "node:fs/promises";
32453
32469
  async function executeBackground(options) {
32454
32470
  try {
32455
- const apiKey = options.apiKey ?? (hasApiKey("OPENAI_API_KEY") ? await getApiKeyFromConfig("openai") || process.env.OPENAI_API_KEY : null);
32471
+ const apiKey = await getConfiguredApiKey("OPENAI_API_KEY", options.apiKey);
32456
32472
  if (!apiKey)
32457
32473
  return { success: false, error: "OPENAI_API_KEY required for background generation" };
32458
32474
  const openaiImage = new OpenAIImageProvider();
@@ -32583,7 +32599,6 @@ var init_background = __esm({
32583
32599
  init_ora();
32584
32600
  init_dist2();
32585
32601
  init_api_key();
32586
- init_config();
32587
32602
  init_output();
32588
32603
  init_validate();
32589
32604
  }
@@ -33249,7 +33264,7 @@ import { resolve as resolve21 } from "node:path";
33249
33264
  import { writeFile as writeFile18 } from "node:fs/promises";
33250
33265
  async function executeSpeech(options) {
33251
33266
  try {
33252
- const apiKey = hasApiKey("ELEVENLABS_API_KEY") ? await getApiKeyFromConfig("elevenlabs") || process.env.ELEVENLABS_API_KEY : null;
33267
+ const apiKey = await getConfiguredApiKey("ELEVENLABS_API_KEY");
33253
33268
  if (!apiKey)
33254
33269
  return {
33255
33270
  success: false,
@@ -33464,7 +33479,6 @@ var init_speech = __esm({
33464
33479
  init_dist2();
33465
33480
  init_api_key();
33466
33481
  init_tty();
33467
- init_config();
33468
33482
  init_output();
33469
33483
  init_validate();
33470
33484
  }
@@ -33817,7 +33831,7 @@ async function executeVideoGenerate(options) {
33817
33831
  fal: "FAL_API_KEY"
33818
33832
  };
33819
33833
  const envKey = envKeyMap[provider] || "";
33820
- const key = apiKey || (hasApiKey(envKey) ? process.env[envKey] : void 0);
33834
+ const key = await getConfiguredApiKey(envKey, apiKey);
33821
33835
  if (!key) return { success: false, error: `${envKeyMap[provider]} required for ${provider}` };
33822
33836
  let referenceImage;
33823
33837
  let referenceImageBuffer;
@@ -35073,7 +35087,7 @@ async function executeMusic(options) {
35073
35087
  try {
35074
35088
  const provider = options.provider || "elevenlabs";
35075
35089
  if (provider === "elevenlabs") {
35076
- const apiKey2 = hasApiKey("ELEVENLABS_API_KEY") ? await getApiKeyFromConfig("elevenlabs") || process.env.ELEVENLABS_API_KEY : null;
35090
+ const apiKey2 = await getConfiguredApiKey("ELEVENLABS_API_KEY");
35077
35091
  if (!apiKey2)
35078
35092
  return {
35079
35093
  success: false,
@@ -35093,7 +35107,7 @@ async function executeMusic(options) {
35093
35107
  await writeFile23(outputPath2, result2.audioBuffer);
35094
35108
  return { success: true, outputPath: outputPath2, provider: "elevenlabs", duration: duration2 };
35095
35109
  }
35096
- const apiKey = hasApiKey("REPLICATE_API_TOKEN") ? await getApiKeyFromConfig("replicate") || process.env.REPLICATE_API_TOKEN : null;
35110
+ const apiKey = await getConfiguredApiKey("REPLICATE_API_TOKEN");
35097
35111
  if (!apiKey)
35098
35112
  return {
35099
35113
  success: false,
@@ -35328,7 +35342,6 @@ var init_music = __esm({
35328
35342
  init_ora();
35329
35343
  init_dist2();
35330
35344
  init_api_key();
35331
- init_config();
35332
35345
  init_output();
35333
35346
  init_validate();
35334
35347
  init_status_jobs();
@@ -36395,7 +36408,7 @@ Examples:
36395
36408
  )
36396
36409
  );
36397
36410
  }
36398
- if (providerEnvMap[provider] && !hasApiKey(providerEnvMap[provider]) && !options.apiKey) {
36411
+ if (providerEnvMap[provider] && !await hasConfiguredApiKey(providerEnvMap[provider], options.apiKey)) {
36399
36412
  const resolved = resolveProvider("image");
36400
36413
  if (resolved) {
36401
36414
  log(source_default.dim(` ${provider} key not found. Using ${resolved.label} instead.`));
@@ -37835,7 +37848,7 @@ Examples:
37835
37848
  );
37836
37849
  provider = "seedance";
37837
37850
  }
37838
- if (videoEnvMap[provider] && !hasApiKey(videoEnvMap[provider]) && !options.apiKey) {
37851
+ if (videoEnvMap[provider] && !await hasConfiguredApiKey(videoEnvMap[provider], options.apiKey)) {
37839
37852
  const resolved = resolveProvider("video");
37840
37853
  if (resolved) {
37841
37854
  log(source_default.dim(` ${provider} key not found. Using ${resolved.label} instead.`));
@@ -71384,7 +71397,7 @@ init_source();
71384
71397
  // package.json
71385
71398
  var package_default = {
71386
71399
  name: "@vibeframe/cli",
71387
- version: "0.104.1",
71400
+ version: "0.104.2",
71388
71401
  description: "VibeFrame CLI - natural language video editing from the terminal",
71389
71402
  private: false,
71390
71403
  license: "MIT",
@@ -80212,11 +80225,25 @@ When you run vibe commands programmatically:
80212
80225
  echo '{"video":"long.mp4","count":3,"aspect":"9:16"}' | vibe remix auto-shorts --stdin --json
80213
80226
  \`\`\`
80214
80227
 
80215
- ## Provider keys
80228
+ ## Provider keys and project scope
80229
+
80230
+ Prefer \`vibe setup --scope project\` for project-local keys. It writes
80231
+ \`.vibeframe/config.yaml\` in the setup directory; when you work from a
80232
+ nested scene directory, the \`vibe\` CLI automatically searches parent
80233
+ directories and uses the nearest project config. Do not assume the config
80234
+ file must exist in the current subdirectory.
80235
+
80236
+ Run \`vibe doctor --json\` from the directory where you will run commands
80237
+ and check \`data.scope.project.configPath\` / \`data.scope.activeScope\` before
80238
+ deciding keys are missing. Never print or copy config file contents.
80239
+
80240
+ For generated project assets, use VibeFrame commands such as
80241
+ \`vibe generate image|video|speech ...\` so these project-scope keys are
80242
+ used. Do not switch to a host agent's built-in image/audio generation tool
80243
+ unless the user explicitly asks for a non-VibeFrame asset.
80216
80244
 
80217
- API keys live in \`.env\` (gitignored). Copy \`.env.example\` to start. Run
80218
- \`vibe doctor\` to see which keys are currently detected and which providers
80219
- they unlock.
80245
+ \`.env\` is still supported as a gitignored fallback. Copy \`.env.example\`
80246
+ to start if you prefer environment variables.
80220
80247
 
80221
80248
  ### Composition rules (scene HTML)
80222
80249
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeframe/cli",
3
- "version": "0.104.1",
3
+ "version": "0.104.2",
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.104.1",
187
- "@vibeframe/core": "0.104.1"
186
+ "@vibeframe/ai-providers": "0.104.2",
187
+ "@vibeframe/core": "0.104.2"
188
188
  },
189
189
  "engines": {
190
190
  "node": ">=20"