@vibeframe/cli 0.89.0 → 0.91.0
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 +220 -89
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -14296,7 +14296,7 @@ function getCommandKeyMap() {
|
|
|
14296
14296
|
function getSetupProviders() {
|
|
14297
14297
|
return [...apiKeyRegistry.values()].filter((k) => k.showInSetup).map((k) => ({
|
|
14298
14298
|
key: k.configKey,
|
|
14299
|
-
name: k.
|
|
14299
|
+
name: getDisplayLabelForApiKey(k.configKey),
|
|
14300
14300
|
env: k.envVar,
|
|
14301
14301
|
desc: k.setupDescription ?? "",
|
|
14302
14302
|
url: k.envExampleUrl
|
|
@@ -14308,6 +14308,16 @@ function getAllApiKeys() {
|
|
|
14308
14308
|
function getKeyFormat(configKey) {
|
|
14309
14309
|
return apiKeyRegistry.get(configKey)?.keyFormat;
|
|
14310
14310
|
}
|
|
14311
|
+
function getDisplayLabelForApiKey(configKey) {
|
|
14312
|
+
const apiKey = apiKeyRegistry.get(configKey);
|
|
14313
|
+
if (!apiKey)
|
|
14314
|
+
return configKey;
|
|
14315
|
+
const provider = [...providerRegistry2.values()].find((p) => p.apiKey === configKey && p.displayName && p.gateway);
|
|
14316
|
+
if (provider?.displayName && provider.gateway) {
|
|
14317
|
+
return `${provider.displayName} (via ${provider.gateway})`;
|
|
14318
|
+
}
|
|
14319
|
+
return apiKey.label;
|
|
14320
|
+
}
|
|
14311
14321
|
function getAllProviders() {
|
|
14312
14322
|
return [...providerRegistry2.values()];
|
|
14313
14323
|
}
|
|
@@ -24412,7 +24422,7 @@ var init_FalProvider = __esm({
|
|
|
24412
24422
|
VALID_ASPECTS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16", "auto"];
|
|
24413
24423
|
FalProvider = class {
|
|
24414
24424
|
constructor() {
|
|
24415
|
-
this.id = "
|
|
24425
|
+
this.id = "seedance";
|
|
24416
24426
|
this.name = "fal.ai (Seedance 2.0)";
|
|
24417
24427
|
this.description = "fal.ai hosting ByteDance Seedance 2.0 \u2014 Artificial Analysis #2 on both text-to-video and image-to-video leaderboards";
|
|
24418
24428
|
this.capabilities = ["text-to-video", "image-to-video"];
|
|
@@ -24511,11 +24521,13 @@ var init_fal = __esm({
|
|
|
24511
24521
|
init_FalProvider();
|
|
24512
24522
|
init_define_provider();
|
|
24513
24523
|
defineProvider({
|
|
24514
|
-
id: "
|
|
24515
|
-
label: "
|
|
24524
|
+
id: "seedance",
|
|
24525
|
+
label: "Seedance 2.0",
|
|
24516
24526
|
displayName: "Seedance 2.0",
|
|
24517
24527
|
gateway: "fal.ai",
|
|
24518
|
-
|
|
24528
|
+
// `fal` is a deprecated v0.x alias kept so existing scripts keep working.
|
|
24529
|
+
// Will be removed at the 1.0 cut (see docs/1.0-readiness.md).
|
|
24530
|
+
aliases: ["fal"],
|
|
24519
24531
|
models: ["seedance-2.0", "seedance-2.0-fast"],
|
|
24520
24532
|
capabilities: ["text-to-video", "image-to-video", "native-audio"],
|
|
24521
24533
|
apiKey: "fal",
|
|
@@ -25216,6 +25228,7 @@ __export(dist_exports2, {
|
|
|
25216
25228
|
getAllProviders: () => getAllProviders,
|
|
25217
25229
|
getBestProviderForCapability: () => getBestProviderForCapability,
|
|
25218
25230
|
getCommandKeyMap: () => getCommandKeyMap,
|
|
25231
|
+
getDisplayLabelForApiKey: () => getDisplayLabelForApiKey,
|
|
25219
25232
|
getKeyFormat: () => getKeyFormat,
|
|
25220
25233
|
getProviderEnvVars: () => getProviderEnvVars,
|
|
25221
25234
|
getProvidersFor: () => getProvidersFor,
|
|
@@ -25690,32 +25703,81 @@ var init_schema = __esm({
|
|
|
25690
25703
|
import { resolve as resolve4 } from "node:path";
|
|
25691
25704
|
import { homedir } from "node:os";
|
|
25692
25705
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, access as access2 } from "node:fs/promises";
|
|
25693
|
-
|
|
25706
|
+
function getProjectConfigDir(cwd = process.cwd()) {
|
|
25707
|
+
return resolve4(cwd, ".vibeframe");
|
|
25708
|
+
}
|
|
25709
|
+
function getProjectConfigPath(cwd = process.cwd()) {
|
|
25710
|
+
return resolve4(getProjectConfigDir(cwd), "config.yaml");
|
|
25711
|
+
}
|
|
25712
|
+
function getConfigPath(scope, cwd) {
|
|
25713
|
+
return scope === "project" ? getProjectConfigPath(cwd) : USER_CONFIG_PATH;
|
|
25714
|
+
}
|
|
25715
|
+
function getConfigDir(scope, cwd) {
|
|
25716
|
+
return scope === "project" ? getProjectConfigDir(cwd) : USER_CONFIG_DIR;
|
|
25717
|
+
}
|
|
25718
|
+
async function fileExists(path2) {
|
|
25694
25719
|
try {
|
|
25695
|
-
await access2(
|
|
25696
|
-
|
|
25697
|
-
|
|
25698
|
-
|
|
25699
|
-
|
|
25700
|
-
|
|
25701
|
-
|
|
25702
|
-
|
|
25703
|
-
|
|
25704
|
-
|
|
25705
|
-
|
|
25706
|
-
|
|
25720
|
+
await access2(path2);
|
|
25721
|
+
return true;
|
|
25722
|
+
} catch {
|
|
25723
|
+
return false;
|
|
25724
|
+
}
|
|
25725
|
+
}
|
|
25726
|
+
async function getActiveScope(cwd) {
|
|
25727
|
+
return await fileExists(getProjectConfigPath(cwd)) ? "project" : "user";
|
|
25728
|
+
}
|
|
25729
|
+
function applyDefaults(parsed) {
|
|
25730
|
+
const defaults = createDefaultConfig();
|
|
25731
|
+
return {
|
|
25732
|
+
...defaults,
|
|
25733
|
+
...parsed,
|
|
25734
|
+
llm: { ...defaults.llm, ...parsed.llm },
|
|
25735
|
+
providers: { ...defaults.providers, ...parsed.providers },
|
|
25736
|
+
defaults: { ...defaults.defaults, ...parsed.defaults },
|
|
25737
|
+
repl: { ...defaults.repl, ...parsed.repl }
|
|
25738
|
+
};
|
|
25739
|
+
}
|
|
25740
|
+
async function readConfigFile(path2) {
|
|
25741
|
+
if (!await fileExists(path2)) return null;
|
|
25742
|
+
try {
|
|
25743
|
+
const content = await readFile2(path2, "utf-8");
|
|
25744
|
+
const parsed = (0, import_yaml.parse)(content);
|
|
25745
|
+
return applyDefaults(parsed);
|
|
25707
25746
|
} catch {
|
|
25708
25747
|
return null;
|
|
25709
25748
|
}
|
|
25710
25749
|
}
|
|
25711
|
-
async function
|
|
25712
|
-
|
|
25713
|
-
|
|
25714
|
-
|
|
25715
|
-
|
|
25716
|
-
|
|
25717
|
-
|
|
25718
|
-
|
|
25750
|
+
async function loadConfig(options = {}) {
|
|
25751
|
+
const { scope, cwd, merge } = options;
|
|
25752
|
+
if (merge) {
|
|
25753
|
+
const user = await readConfigFile(USER_CONFIG_PATH);
|
|
25754
|
+
const project2 = await readConfigFile(getProjectConfigPath(cwd));
|
|
25755
|
+
if (!user && !project2) return null;
|
|
25756
|
+
if (!user) return project2;
|
|
25757
|
+
if (!project2) return user;
|
|
25758
|
+
return {
|
|
25759
|
+
...user,
|
|
25760
|
+
...project2,
|
|
25761
|
+
llm: { ...user.llm, ...project2.llm },
|
|
25762
|
+
providers: { ...user.providers, ...project2.providers },
|
|
25763
|
+
defaults: { ...user.defaults, ...project2.defaults },
|
|
25764
|
+
repl: { ...user.repl, ...project2.repl }
|
|
25765
|
+
};
|
|
25766
|
+
}
|
|
25767
|
+
if (scope) {
|
|
25768
|
+
return readConfigFile(getConfigPath(scope, cwd));
|
|
25769
|
+
}
|
|
25770
|
+
const project = await readConfigFile(getProjectConfigPath(cwd));
|
|
25771
|
+
if (project) return project;
|
|
25772
|
+
return readConfigFile(USER_CONFIG_PATH);
|
|
25773
|
+
}
|
|
25774
|
+
async function saveConfig(config2, options = {}) {
|
|
25775
|
+
const scope = options.scope ?? "user";
|
|
25776
|
+
const dir = getConfigDir(scope, options.cwd);
|
|
25777
|
+
const path2 = getConfigPath(scope, options.cwd);
|
|
25778
|
+
await mkdir2(dir, { recursive: true });
|
|
25779
|
+
const content = (0, import_yaml.stringify)(config2, { indent: 2, lineWidth: 0 });
|
|
25780
|
+
await writeFile2(path2, content, "utf-8");
|
|
25719
25781
|
}
|
|
25720
25782
|
async function isConfigured() {
|
|
25721
25783
|
const config2 = await loadConfig();
|
|
@@ -25737,20 +25799,19 @@ async function getApiKeyFromConfig(providerKey) {
|
|
|
25737
25799
|
return config2.providers[providerKey];
|
|
25738
25800
|
}
|
|
25739
25801
|
const envVar = PROVIDER_ENV_VARS[providerKey];
|
|
25740
|
-
if (envVar)
|
|
25741
|
-
return process.env[envVar];
|
|
25742
|
-
}
|
|
25802
|
+
if (envVar) return process.env[envVar];
|
|
25743
25803
|
return void 0;
|
|
25744
25804
|
}
|
|
25745
|
-
var import_yaml,
|
|
25805
|
+
var import_yaml, USER_CONFIG_DIR, USER_CONFIG_PATH, CONFIG_PATH;
|
|
25746
25806
|
var init_config = __esm({
|
|
25747
25807
|
"src/config/index.ts"() {
|
|
25748
25808
|
"use strict";
|
|
25749
25809
|
import_yaml = __toESM(require_dist(), 1);
|
|
25750
25810
|
init_schema();
|
|
25751
25811
|
init_schema();
|
|
25752
|
-
|
|
25753
|
-
|
|
25812
|
+
USER_CONFIG_DIR = resolve4(homedir(), ".vibeframe");
|
|
25813
|
+
USER_CONFIG_PATH = resolve4(USER_CONFIG_DIR, "config.yaml");
|
|
25814
|
+
CONFIG_PATH = USER_CONFIG_PATH;
|
|
25754
25815
|
}
|
|
25755
25816
|
});
|
|
25756
25817
|
|
|
@@ -26277,9 +26338,8 @@ vibe scene lint --json # structured output for agent loops
|
|
|
26277
26338
|
`;
|
|
26278
26339
|
}
|
|
26279
26340
|
function buildSceneGitignore() {
|
|
26280
|
-
return `# VibeFrame caches
|
|
26281
|
-
.vibeframe/
|
|
26282
|
-
.vibeframe/checkpoints/
|
|
26341
|
+
return `# VibeFrame \u2014 caches, checkpoints, and project-scope config.yaml (may contain API keys)
|
|
26342
|
+
.vibeframe/
|
|
26283
26343
|
|
|
26284
26344
|
# Render outputs
|
|
26285
26345
|
renders/*.mp4
|
|
@@ -35437,9 +35497,9 @@ var init_ai_script_pipeline = __esm({
|
|
|
35437
35497
|
import { resolve as resolve26 } from "node:path";
|
|
35438
35498
|
import { readFile as readFile14, writeFile as writeFile24 } from "node:fs/promises";
|
|
35439
35499
|
function registerVideoCommand(parent) {
|
|
35440
|
-
parent.command("video").alias("vid").description("Generate video using AI (Seedance, Grok, Kling, Runway, or Veo)").argument("[prompt]", "Text prompt describing the video (interactive if omitted)").option("-p, --provider <provider>", "Provider: seedance (ByteDance Seedance 2.0 via fal.ai), grok, kling, runway, veo. `fal` is a
|
|
35500
|
+
parent.command("video").alias("vid").description("Generate video using AI (Seedance, Grok, Kling, Runway, or Veo)").argument("[prompt]", "Text prompt describing the video (interactive if omitted)").option("-p, --provider <provider>", "Provider: seedance (ByteDance Seedance 2.0 via fal.ai), grok, kling, runway, veo. `fal` is a deprecated v0.x alias for seedance and will be removed in 1.0.").option("-k, --api-key <key>", "API key (or set FAL_KEY / XAI_API_KEY / RUNWAY_API_SECRET / KLING_API_KEY / GOOGLE_API_KEY env)").option("-o, --output <path>", "Output file path (downloads video)").option("-i, --image <path>", "Reference image for image-to-video").option(
|
|
35441
35501
|
"-d, --duration <sec>",
|
|
35442
|
-
"Duration in seconds. Seedance accepts 4-15
|
|
35502
|
+
"Duration in seconds. Seedance accepts 4-15; Kling accepts 5 or 10; Veo maps to 6 or 8.",
|
|
35443
35503
|
"5"
|
|
35444
35504
|
).option("-r, --ratio <ratio>", "Aspect ratio: 16:9, 9:16, or 1:1 (auto-detected from image if omitted)").option("--seed <number>", "Random seed for reproducibility (Runway only)").option("--mode <mode>", "Generation mode: std or pro (Kling only)", "std").option("--seedance-model <model>", "Seedance variant: quality or fast (fal.ai only)", "quality").option("--negative <prompt>", "Negative prompt - what to avoid (Kling/Veo)").option("--resolution <res>", "Video resolution: 720p, 1080p, 4k (Veo only)").option("--last-frame <path>", "Last frame image for frame interpolation (Veo only)").option("--ref-images <paths...>", "Reference images for character consistency (Veo 3.1 only, max 3)").option("--person <mode>", "Person generation: allow_all, allow_adult (Veo only)").option("--veo-model <model>", "Veo model: 3.0, 3.1, 3.1-fast (default: 3.1-fast)", "3.1-fast").option("--runway-model <model>", "Runway model: gen4.5 (default, text+image-to-video), gen4_turbo (image-to-video only)", "gen4.5").option("--no-wait", "Start generation and return task ID without waiting").option("--dry-run", "Preview parameters without executing").addHelpText("after", `
|
|
35445
35505
|
Examples:
|
|
@@ -35485,8 +35545,7 @@ Examples:
|
|
|
35485
35545
|
veo: "GOOGLE_API_KEY",
|
|
35486
35546
|
kling: "KLING_API_KEY",
|
|
35487
35547
|
runway: "RUNWAY_API_SECRET",
|
|
35488
|
-
seedance: "FAL_KEY"
|
|
35489
|
-
fal: "FAL_KEY"
|
|
35548
|
+
seedance: "FAL_KEY"
|
|
35490
35549
|
};
|
|
35491
35550
|
let provider;
|
|
35492
35551
|
if (options.provider) {
|
|
@@ -35495,9 +35554,17 @@ Examples:
|
|
|
35495
35554
|
exitWithError(
|
|
35496
35555
|
usageError(
|
|
35497
35556
|
`Invalid provider: ${provider}`,
|
|
35498
|
-
"Available providers: seedance, grok, kling, runway, veo. `fal` is a
|
|
35557
|
+
"Available providers: seedance, grok, kling, runway, veo. `fal` is a deprecated alias for seedance."
|
|
35558
|
+
)
|
|
35559
|
+
);
|
|
35560
|
+
}
|
|
35561
|
+
if (provider === "fal") {
|
|
35562
|
+
process.stderr.write(
|
|
35563
|
+
source_default.yellow(
|
|
35564
|
+
"Note: `-p fal` is a deprecated alias for `-p seedance` and will be removed in 1.0.\n"
|
|
35499
35565
|
)
|
|
35500
35566
|
);
|
|
35567
|
+
provider = "seedance";
|
|
35501
35568
|
}
|
|
35502
35569
|
if (videoEnvMap[provider] && !hasApiKey(videoEnvMap[provider]) && !options.apiKey) {
|
|
35503
35570
|
const resolved = resolveProvider("video");
|
|
@@ -35558,7 +35625,7 @@ Examples:
|
|
|
35558
35625
|
data: {
|
|
35559
35626
|
params: {
|
|
35560
35627
|
prompt: prompt3,
|
|
35561
|
-
provider
|
|
35628
|
+
provider,
|
|
35562
35629
|
duration: options.duration,
|
|
35563
35630
|
ratio: options.ratio,
|
|
35564
35631
|
image: options.image,
|
|
@@ -35577,16 +35644,14 @@ Examples:
|
|
|
35577
35644
|
kling: "KLING_API_KEY",
|
|
35578
35645
|
veo: "GOOGLE_API_KEY",
|
|
35579
35646
|
grok: "XAI_API_KEY",
|
|
35580
|
-
seedance: "FAL_KEY"
|
|
35581
|
-
fal: "FAL_KEY"
|
|
35647
|
+
seedance: "FAL_KEY"
|
|
35582
35648
|
};
|
|
35583
35649
|
const providerNameMap = {
|
|
35584
35650
|
runway: "Runway",
|
|
35585
35651
|
kling: "Kling",
|
|
35586
35652
|
veo: "Veo",
|
|
35587
35653
|
grok: "Grok",
|
|
35588
|
-
seedance: "Seedance 2.0 via fal.ai"
|
|
35589
|
-
fal: "Seedance 2.0 via fal.ai"
|
|
35654
|
+
seedance: "Seedance 2.0 via fal.ai"
|
|
35590
35655
|
};
|
|
35591
35656
|
const envKey = envKeyMap[provider];
|
|
35592
35657
|
const providerName = providerNameMap[provider];
|
|
@@ -35805,7 +35870,7 @@ Examples:
|
|
|
35805
35870
|
},
|
|
35806
35871
|
3e5
|
|
35807
35872
|
);
|
|
35808
|
-
} else if (provider === "
|
|
35873
|
+
} else if (provider === "seedance") {
|
|
35809
35874
|
const fal = new FalProvider();
|
|
35810
35875
|
await fal.initialize({ apiKey });
|
|
35811
35876
|
let falImage = referenceImage;
|
|
@@ -62845,7 +62910,7 @@ init_source();
|
|
|
62845
62910
|
// package.json
|
|
62846
62911
|
var package_default = {
|
|
62847
62912
|
name: "@vibeframe/cli",
|
|
62848
|
-
version: "0.
|
|
62913
|
+
version: "0.91.0",
|
|
62849
62914
|
description: "VibeFrame CLI - natural language video editing from the terminal",
|
|
62850
62915
|
private: false,
|
|
62851
62916
|
license: "MIT",
|
|
@@ -69840,13 +69905,34 @@ var VALID_LLM_PROVIDERS = [
|
|
|
69840
69905
|
"xai",
|
|
69841
69906
|
"openrouter"
|
|
69842
69907
|
];
|
|
69843
|
-
var
|
|
69908
|
+
var VALID_SCOPES = ["user", "project"];
|
|
69909
|
+
function parseScope(raw) {
|
|
69910
|
+
const v = String(raw ?? "user");
|
|
69911
|
+
if (!VALID_SCOPES.includes(v)) {
|
|
69912
|
+
exitWithError(generalError(
|
|
69913
|
+
`Invalid --scope: ${v}`,
|
|
69914
|
+
`Must be one of: ${VALID_SCOPES.join(", ")}`
|
|
69915
|
+
));
|
|
69916
|
+
}
|
|
69917
|
+
return v;
|
|
69918
|
+
}
|
|
69919
|
+
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("-v, --verbose", "With --show: include unset providers + Resolution order + Defaults block").option("--claude-code", "Show Claude Code integration guide").option("-y, --yes", "Non-interactive: write config without prompting (CI / devcontainer)").option("--provider <id>", "Set the Agent LLM provider (claude | openai | gemini | xai | openrouter | ollama)").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(
|
|
69920
|
+
"--scope <scope>",
|
|
69921
|
+
"Where to save: 'user' (~/.vibeframe/config.yaml, shared) or 'project' (./.vibeframe/config.yaml, gitignored, this project only)",
|
|
69922
|
+
"user"
|
|
69923
|
+
).addHelpText(
|
|
69844
69924
|
"after",
|
|
69845
69925
|
`
|
|
69846
69926
|
Non-interactive examples (no TTY required):
|
|
69847
69927
|
vibe setup --yes --provider claude --import-env Bootstrap CI / devcontainer
|
|
69848
69928
|
vibe setup --yes --import-env --test Persist .env keys + verify each one
|
|
69849
69929
|
vibe setup --yes --provider openai Just switch the agent provider
|
|
69930
|
+
vibe setup --scope project --yes --import-env Project-only setup (./.vibeframe/config.yaml)
|
|
69931
|
+
|
|
69932
|
+
Scopes:
|
|
69933
|
+
user (default) ~/.vibeframe/config.yaml \u2014 shared across every project
|
|
69934
|
+
project ./.vibeframe/config.yaml \u2014 gitignored, isolates keys/defaults to this directory
|
|
69935
|
+
When a project config exists at the cwd, it is used and the user file is ignored.
|
|
69850
69936
|
|
|
69851
69937
|
Exit codes (non-interactive):
|
|
69852
69938
|
0 success 7 --test verification failed (one or more keys returned non-2xx)
|
|
@@ -69861,11 +69947,12 @@ Exit codes (non-interactive):
|
|
|
69861
69947
|
await showConfig({ verbose: Boolean(options.verbose) });
|
|
69862
69948
|
return;
|
|
69863
69949
|
}
|
|
69950
|
+
const scope = parseScope(options.scope);
|
|
69864
69951
|
if (options.reset) {
|
|
69865
69952
|
const config2 = createDefaultConfig();
|
|
69866
|
-
await saveConfig(config2);
|
|
69953
|
+
await saveConfig(config2, { scope });
|
|
69867
69954
|
console.log(source_default.green("\u2713 Configuration reset to defaults"));
|
|
69868
|
-
console.log(source_default.dim(` Saved to: ${
|
|
69955
|
+
console.log(source_default.dim(` Saved to: ${getConfigPath(scope)}`));
|
|
69869
69956
|
return;
|
|
69870
69957
|
}
|
|
69871
69958
|
const wantsNonInteractive = Boolean(options.yes) || !hasTTY() && (options.provider || options.importEnv);
|
|
@@ -69873,7 +69960,8 @@ Exit codes (non-interactive):
|
|
|
69873
69960
|
await runNonInteractiveSetup({
|
|
69874
69961
|
provider: options.provider,
|
|
69875
69962
|
importEnv: Boolean(options.importEnv),
|
|
69876
|
-
test: Boolean(options.test)
|
|
69963
|
+
test: Boolean(options.test),
|
|
69964
|
+
scope
|
|
69877
69965
|
});
|
|
69878
69966
|
return;
|
|
69879
69967
|
}
|
|
@@ -69884,7 +69972,7 @@ Exit codes (non-interactive):
|
|
|
69884
69972
|
));
|
|
69885
69973
|
}
|
|
69886
69974
|
try {
|
|
69887
|
-
await runSetupWizard(options.full);
|
|
69975
|
+
await runSetupWizard(options.full, scope);
|
|
69888
69976
|
closeTTYStream();
|
|
69889
69977
|
process.exit(0);
|
|
69890
69978
|
} catch (err) {
|
|
@@ -69906,7 +69994,7 @@ var AI_FEATURES = [
|
|
|
69906
69994
|
desc: "generate + extend",
|
|
69907
69995
|
defaultProvider: "Seedance 2.0 via fal.ai (Artificial Analysis #2 t2v + i2v, since v0.57)",
|
|
69908
69996
|
alsoAvailable: "Grok Imagine, Kling, Runway Gen-4.5, Google Veo",
|
|
69909
|
-
keys: [{ configKey: "fal", envVar: "FAL_KEY", name: "fal.ai", url: "https://fal.ai/dashboard/keys", what: "ByteDance Seedance 2.0 text-to-video and image-to-video" }],
|
|
69997
|
+
keys: [{ configKey: "fal", envVar: "FAL_KEY", name: "Seedance 2.0 (via fal.ai)", url: "https://fal.ai/dashboard/keys", what: "ByteDance Seedance 2.0 text-to-video and image-to-video" }],
|
|
69910
69998
|
tryCommand: 'vibe generate video "ocean waves" -o waves.mp4'
|
|
69911
69999
|
},
|
|
69912
70000
|
{
|
|
@@ -69930,7 +70018,8 @@ var AI_FEATURES = [
|
|
|
69930
70018
|
}
|
|
69931
70019
|
];
|
|
69932
70020
|
async function runNonInteractiveSetup(opts) {
|
|
69933
|
-
|
|
70021
|
+
const scope = opts.scope ?? "user";
|
|
70022
|
+
let config2 = await loadConfig({ scope });
|
|
69934
70023
|
if (!config2) {
|
|
69935
70024
|
config2 = createDefaultConfig();
|
|
69936
70025
|
}
|
|
@@ -69967,9 +70056,9 @@ async function runNonInteractiveSetup(opts) {
|
|
|
69967
70056
|
changes.push(`imported ${importedCount} key${importedCount === 1 ? "" : "s"} from env`);
|
|
69968
70057
|
}
|
|
69969
70058
|
}
|
|
69970
|
-
await saveConfig(config2);
|
|
69971
|
-
console.log(source_default.green(
|
|
69972
|
-
console.log(source_default.dim(` Config: ${
|
|
70059
|
+
await saveConfig(config2, { scope });
|
|
70060
|
+
console.log(source_default.green(`\u2713 Setup complete (non-interactive, ${scope} scope)`));
|
|
70061
|
+
console.log(source_default.dim(` Config: ${getConfigPath(scope)}`));
|
|
69973
70062
|
if (changes.length > 0) {
|
|
69974
70063
|
for (const c of changes) {
|
|
69975
70064
|
console.log(source_default.dim(` ${c}`));
|
|
@@ -70012,20 +70101,21 @@ async function runNonInteractiveSetup(opts) {
|
|
|
70012
70101
|
}
|
|
70013
70102
|
}
|
|
70014
70103
|
}
|
|
70015
|
-
async function runSetupWizard(fullSetup = false) {
|
|
70104
|
+
async function runSetupWizard(fullSetup = false, scope = "user") {
|
|
70016
70105
|
console.log();
|
|
70017
|
-
|
|
70106
|
+
const scopeLabel = scope === "project" ? source_default.dim(` \u2014 project scope (${getConfigPath("project")})`) : source_default.dim(" \u2014 user scope");
|
|
70107
|
+
console.log(source_default.bold.magenta("VibeFrame Setup") + scopeLabel);
|
|
70018
70108
|
console.log(source_default.dim("\u2500".repeat(40)));
|
|
70019
70109
|
console.log();
|
|
70020
70110
|
const hosts = detectedAgentHosts();
|
|
70021
70111
|
console.log(source_default.dim(`Agent hosts: ${summariseAgentHosts(hosts)}`));
|
|
70022
70112
|
console.log();
|
|
70023
|
-
let config2 = await loadConfig();
|
|
70113
|
+
let config2 = await loadConfig({ scope });
|
|
70024
70114
|
if (!config2) {
|
|
70025
70115
|
config2 = createDefaultConfig();
|
|
70026
70116
|
}
|
|
70027
70117
|
if (fullSetup) {
|
|
70028
|
-
await runCustomSetup(config2);
|
|
70118
|
+
await runCustomSetup(config2, scope);
|
|
70029
70119
|
return;
|
|
70030
70120
|
}
|
|
70031
70121
|
console.log(source_default.dim("1. Goal"));
|
|
@@ -70040,12 +70130,12 @@ async function runSetupWizard(fullSetup = false) {
|
|
|
70040
70130
|
const topIndex = await promptSelect(source_default.cyan(" Select [1-4]: "), topLabels, 0);
|
|
70041
70131
|
console.log();
|
|
70042
70132
|
if (topIndex === 0) {
|
|
70043
|
-
await saveConfig(config2);
|
|
70044
|
-
await showComplete(config2, "vibe edit silence-cut video.mp4 -o clean.mp4");
|
|
70133
|
+
await saveConfig(config2, { scope });
|
|
70134
|
+
await showComplete(config2, "vibe edit silence-cut video.mp4 -o clean.mp4", [], scope);
|
|
70045
70135
|
return;
|
|
70046
70136
|
}
|
|
70047
70137
|
if (topIndex === 3) {
|
|
70048
|
-
await runCustomSetup(config2);
|
|
70138
|
+
await runCustomSetup(config2, scope);
|
|
70049
70139
|
return;
|
|
70050
70140
|
}
|
|
70051
70141
|
if (topIndex === 2) {
|
|
@@ -70061,8 +70151,8 @@ async function runSetupWizard(fullSetup = false) {
|
|
|
70061
70151
|
console.log(source_default.dim(" Saved locally, never shared. Press Enter to skip."));
|
|
70062
70152
|
console.log();
|
|
70063
70153
|
await collectKeys(config2, pipelineKeys);
|
|
70064
|
-
await saveConfig(config2);
|
|
70065
|
-
await showComplete(config2, "vibe build my-story/ # see CONTRIBUTING.md for STORYBOARD.md format");
|
|
70154
|
+
await saveConfig(config2, { scope });
|
|
70155
|
+
await showComplete(config2, "vibe build my-story/ # see CONTRIBUTING.md for STORYBOARD.md format", [], scope);
|
|
70066
70156
|
return;
|
|
70067
70157
|
}
|
|
70068
70158
|
console.log(source_default.dim("2. Features"));
|
|
@@ -70083,8 +70173,8 @@ async function runSetupWizard(fullSetup = false) {
|
|
|
70083
70173
|
if (selectedFeatures.length === 0) {
|
|
70084
70174
|
console.log(source_default.dim(" No features selected. You can re-run setup anytime."));
|
|
70085
70175
|
console.log();
|
|
70086
|
-
await saveConfig(config2);
|
|
70087
|
-
await showComplete(config2, "vibe --help", []);
|
|
70176
|
+
await saveConfig(config2, { scope });
|
|
70177
|
+
await showComplete(config2, "vibe --help", [], scope);
|
|
70088
70178
|
return;
|
|
70089
70179
|
}
|
|
70090
70180
|
console.log(source_default.dim("3. API keys"));
|
|
@@ -70136,8 +70226,8 @@ async function runSetupWizard(fullSetup = false) {
|
|
|
70136
70226
|
}
|
|
70137
70227
|
console.log();
|
|
70138
70228
|
}
|
|
70139
|
-
await saveConfig(config2);
|
|
70140
|
-
await showComplete(config2, selectedFeatures[0].tryCommand, selectedFeatures);
|
|
70229
|
+
await saveConfig(config2, { scope });
|
|
70230
|
+
await showComplete(config2, selectedFeatures[0].tryCommand, selectedFeatures, scope);
|
|
70141
70231
|
}
|
|
70142
70232
|
async function collectKeys(config2, keys) {
|
|
70143
70233
|
loadEnv();
|
|
@@ -70173,7 +70263,7 @@ async function collectKeys(config2, keys) {
|
|
|
70173
70263
|
}
|
|
70174
70264
|
console.log();
|
|
70175
70265
|
}
|
|
70176
|
-
async function runCustomSetup(config2) {
|
|
70266
|
+
async function runCustomSetup(config2, scope = "user") {
|
|
70177
70267
|
console.log(source_default.bold("1. Agent LLM Provider") + source_default.dim(" (for vibe agent)"));
|
|
70178
70268
|
console.log(source_default.dim(" Only needed if you use the interactive Agent mode."));
|
|
70179
70269
|
console.log();
|
|
@@ -70243,14 +70333,15 @@ async function runCustomSetup(config2) {
|
|
|
70243
70333
|
}
|
|
70244
70334
|
}
|
|
70245
70335
|
console.log();
|
|
70246
|
-
await saveConfig(config2);
|
|
70247
|
-
await showComplete(config2, "vibe doctor");
|
|
70336
|
+
await saveConfig(config2, { scope });
|
|
70337
|
+
await showComplete(config2, "vibe doctor", [], scope);
|
|
70248
70338
|
}
|
|
70249
|
-
async function showComplete(config2, defaultTryCommand, features = []) {
|
|
70339
|
+
async function showComplete(config2, defaultTryCommand, features = [], scope = "user") {
|
|
70250
70340
|
console.log(source_default.dim("\u2500".repeat(40)));
|
|
70251
70341
|
console.log(source_default.green.bold("\u2713 Setup complete!"));
|
|
70252
70342
|
console.log();
|
|
70253
|
-
|
|
70343
|
+
const scopeNote = scope === "project" ? source_default.dim(" (project scope)") : source_default.dim(" (user scope)");
|
|
70344
|
+
console.log(source_default.dim(` Config: ${getConfigPath(scope)}${scopeNote}`));
|
|
70254
70345
|
console.log();
|
|
70255
70346
|
const primaryTry = features.length > 1 ? features[0].tryCommand : defaultTryCommand;
|
|
70256
70347
|
if (features.length > 1) {
|
|
@@ -70340,13 +70431,22 @@ async function showConfig(opts = { verbose: false }) {
|
|
|
70340
70431
|
hasCwdEnv = true;
|
|
70341
70432
|
} catch {
|
|
70342
70433
|
}
|
|
70434
|
+
const activeScope = await getActiveScope();
|
|
70435
|
+
const userPath = USER_CONFIG_PATH;
|
|
70436
|
+
const projectPath = getConfigPath("project");
|
|
70437
|
+
const userExists = await loadConfig({ scope: "user" }) !== null;
|
|
70438
|
+
const projectExists = await loadConfig({ scope: "project" }) !== null;
|
|
70343
70439
|
console.log();
|
|
70344
70440
|
console.log(source_default.bold.magenta("VibeFrame Configuration"));
|
|
70345
70441
|
console.log(source_default.dim("\u2500".repeat(40)));
|
|
70346
70442
|
console.log();
|
|
70347
|
-
|
|
70443
|
+
const userMark = activeScope === "user" && userExists ? source_default.cyan("\u2190 active") : userExists ? source_default.dim("(present)") : source_default.dim("(missing)");
|
|
70444
|
+
const projectMark = activeScope === "project" ? source_default.cyan("\u2190 active") : projectExists ? source_default.dim("(present)") : source_default.dim("(missing)");
|
|
70445
|
+
console.log(source_default.dim(`Scopes:`));
|
|
70446
|
+
console.log(source_default.dim(` user ${userPath} ${userMark}`));
|
|
70447
|
+
console.log(source_default.dim(` project ${projectPath} ${projectMark}`));
|
|
70348
70448
|
if (hasCwdEnv) {
|
|
70349
|
-
console.log(source_default.dim(`
|
|
70449
|
+
console.log(source_default.dim(` .env ${cwdEnvPath} ${source_default.dim("(env vars override config)")}`));
|
|
70350
70450
|
}
|
|
70351
70451
|
console.log();
|
|
70352
70452
|
const config2 = await loadConfig();
|
|
@@ -70414,9 +70514,9 @@ async function showConfig(opts = { verbose: false }) {
|
|
|
70414
70514
|
}
|
|
70415
70515
|
console.log(source_default.bold("Resolution order:"));
|
|
70416
70516
|
console.log(source_default.dim(" 1. --api-key CLI option"));
|
|
70417
|
-
console.log(source_default.dim(` 2. ${
|
|
70418
|
-
console.log(source_default.dim(
|
|
70419
|
-
console.log(source_default.dim("
|
|
70517
|
+
console.log(source_default.dim(` 2. Active config scope: ${activeScope === "project" ? projectPath : userPath}`));
|
|
70518
|
+
console.log(source_default.dim(` (project takes priority when present at cwd; user is ignored in that case)`));
|
|
70519
|
+
console.log(source_default.dim(" 3. .env / shell environment variables (process.env)"));
|
|
70420
70520
|
console.log();
|
|
70421
70521
|
}
|
|
70422
70522
|
}
|
|
@@ -71551,6 +71651,9 @@ async function runDiagnostics() {
|
|
|
71551
71651
|
exists: existsSync36(resolve50(cwd, rel))
|
|
71552
71652
|
}));
|
|
71553
71653
|
const projectInitialized = projectFiles.some((f) => f.exists);
|
|
71654
|
+
const projectConfigPath = getProjectConfigPath(cwd);
|
|
71655
|
+
const projectConfigExists = existsSync36(projectConfigPath);
|
|
71656
|
+
const activeScope = await getActiveScope(cwd);
|
|
71554
71657
|
const hosts = detectAgentHosts();
|
|
71555
71658
|
const detectedNames = hosts.filter((h) => h.detected).map((h) => h.label);
|
|
71556
71659
|
const recommendedMode = resolveSceneBuildMode({});
|
|
@@ -71573,8 +71676,15 @@ async function runDiagnostics() {
|
|
|
71573
71676
|
...Object.keys(optionalTools).length > 0 ? { optionalTools } : {}
|
|
71574
71677
|
},
|
|
71575
71678
|
scope: {
|
|
71679
|
+
activeScope,
|
|
71576
71680
|
user: { configured: configExists, configPath: CONFIG_PATH },
|
|
71577
|
-
project: {
|
|
71681
|
+
project: {
|
|
71682
|
+
cwd,
|
|
71683
|
+
initialized: projectInitialized,
|
|
71684
|
+
files: projectFiles,
|
|
71685
|
+
configPath: projectConfigPath,
|
|
71686
|
+
configFileExists: projectConfigExists
|
|
71687
|
+
},
|
|
71578
71688
|
agentHosts: { detected: detectedNames, summary: summariseAgentHosts(hosts) },
|
|
71579
71689
|
sceneComposer: {
|
|
71580
71690
|
recommendedMode,
|
|
@@ -71647,16 +71757,30 @@ function printReport(results, opts = { verbose: false }) {
|
|
|
71647
71757
|
}
|
|
71648
71758
|
console.log();
|
|
71649
71759
|
console.log(source_default.bold(" Scope"));
|
|
71760
|
+
const userActive = results.scope.activeScope === "user" && results.scope.user.configured;
|
|
71761
|
+
const projectActive = results.scope.activeScope === "project";
|
|
71762
|
+
const activeMark = source_default.cyan(" \u2190 active");
|
|
71650
71763
|
if (results.scope.user.configured) {
|
|
71651
|
-
console.log(
|
|
71764
|
+
console.log(
|
|
71765
|
+
` Cfg(user) ${source_default.green("OK")} ${source_default.dim(results.scope.user.configPath)}${userActive ? activeMark : ""}`
|
|
71766
|
+
);
|
|
71652
71767
|
} else {
|
|
71653
|
-
console.log(`
|
|
71768
|
+
console.log(` Cfg(user) ${source_default.yellow("NOT SET")} ${source_default.dim("Run: vibe setup")}`);
|
|
71769
|
+
}
|
|
71770
|
+
if (results.scope.project.configFileExists) {
|
|
71771
|
+
console.log(
|
|
71772
|
+
` Cfg(proj) ${source_default.green("OK")} ${source_default.dim(results.scope.project.configPath)}${projectActive ? activeMark : ""}`
|
|
71773
|
+
);
|
|
71774
|
+
} else {
|
|
71775
|
+
console.log(
|
|
71776
|
+
` Cfg(proj) ${source_default.dim("none")} ${source_default.dim(`Run: vibe setup --scope project (cwd: ${results.scope.project.cwd})`)}`
|
|
71777
|
+
);
|
|
71654
71778
|
}
|
|
71655
71779
|
if (results.scope.project.initialized) {
|
|
71656
71780
|
const present = results.scope.project.files.filter((f) => f.exists).map((f) => f.path);
|
|
71657
|
-
console.log(`
|
|
71781
|
+
console.log(` Init ${source_default.green("OK")} ${source_default.dim(present.join(", "))}`);
|
|
71658
71782
|
} else {
|
|
71659
|
-
console.log(`
|
|
71783
|
+
console.log(` Init ${source_default.yellow("NOT INIT")} ${source_default.dim(`Run: vibe init (cwd: ${results.scope.project.cwd})`)}`);
|
|
71660
71784
|
}
|
|
71661
71785
|
console.log(` Agents ${source_default.dim(results.scope.agentHosts.summary)}`);
|
|
71662
71786
|
if (verbose) {
|
|
@@ -71689,11 +71813,16 @@ function printReport(results, opts = { verbose: false }) {
|
|
|
71689
71813
|
console.log(source_default.bold(" API Keys"));
|
|
71690
71814
|
const configured = [];
|
|
71691
71815
|
const missing = [];
|
|
71816
|
+
const labelFor = (configKey, fallbackEnv) => {
|
|
71817
|
+
const label = getDisplayLabelForApiKey(configKey);
|
|
71818
|
+
return label === configKey ? fallbackEnv : label;
|
|
71819
|
+
};
|
|
71692
71820
|
for (const [name, info] of Object.entries(results.providers)) {
|
|
71693
71821
|
if (info.configured) {
|
|
71694
71822
|
configured.push(name);
|
|
71823
|
+
const label = labelFor(name, info.envVar);
|
|
71695
71824
|
console.log(
|
|
71696
|
-
` ${source_default.green("OK")} ${info.envVar.padEnd(
|
|
71825
|
+
` ${source_default.green("OK")} ${label.padEnd(28)} ${source_default.dim(info.envVar.padEnd(20))} ${source_default.dim(info.commands.join(", "))}`
|
|
71697
71826
|
);
|
|
71698
71827
|
} else {
|
|
71699
71828
|
missing.push(name);
|
|
@@ -71703,8 +71832,9 @@ function printReport(results, opts = { verbose: false }) {
|
|
|
71703
71832
|
if (verbose) {
|
|
71704
71833
|
for (const name of missing) {
|
|
71705
71834
|
const info = results.providers[name];
|
|
71835
|
+
const label = labelFor(name, info.envVar);
|
|
71706
71836
|
console.log(
|
|
71707
|
-
` ${source_default.red("--")} ${info.envVar.padEnd(
|
|
71837
|
+
` ${source_default.red("--")} ${label.padEnd(28)} ${source_default.dim(info.envVar.padEnd(20))} ${source_default.dim(info.commands.join(", "))}`
|
|
71708
71838
|
);
|
|
71709
71839
|
}
|
|
71710
71840
|
} else {
|
|
@@ -71812,8 +71942,9 @@ async function runLiveKeyTests(results) {
|
|
|
71812
71942
|
console.log();
|
|
71813
71943
|
}
|
|
71814
71944
|
function pickNextStep(results, hasMissingProviders) {
|
|
71815
|
-
|
|
71816
|
-
|
|
71945
|
+
const anyConfigured = results.scope.user.configured || results.scope.project.configFileExists;
|
|
71946
|
+
if (!anyConfigured) {
|
|
71947
|
+
return "Next: run 'vibe setup' (or 'vibe setup --scope project' to keep config inside the project) to configure API keys + LLM provider.";
|
|
71817
71948
|
}
|
|
71818
71949
|
if (!results.scope.project.initialized) {
|
|
71819
71950
|
return "Next: run 'vibe init' in your project directory to scaffold AGENTS.md / CLAUDE.md / .env.example.";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.91.0",
|
|
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.
|
|
187
|
-
"@vibeframe/core": "0.
|
|
186
|
+
"@vibeframe/ai-providers": "0.91.0",
|
|
187
|
+
"@vibeframe/core": "0.91.0"
|
|
188
188
|
},
|
|
189
189
|
"engines": {
|
|
190
190
|
"node": ">=20"
|