@vibeframe/cli 0.81.0 → 0.82.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 +165 -128
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -51230,6 +51230,126 @@ overlay, etc.) \u2014 useful at the tail of a pipeline.
|
|
|
51230
51230
|
}
|
|
51231
51231
|
});
|
|
51232
51232
|
|
|
51233
|
+
// src/utils/key-live-test.ts
|
|
51234
|
+
var key_live_test_exports = {};
|
|
51235
|
+
__export(key_live_test_exports, {
|
|
51236
|
+
isTestableProvider: () => isTestableProvider,
|
|
51237
|
+
testKey: () => testKey
|
|
51238
|
+
});
|
|
51239
|
+
async function getOk(url, headers, signal) {
|
|
51240
|
+
try {
|
|
51241
|
+
const res = await fetch(url, { method: "GET", headers, signal });
|
|
51242
|
+
if (res.ok) return { ok: true, status: res.status };
|
|
51243
|
+
return {
|
|
51244
|
+
ok: false,
|
|
51245
|
+
status: res.status,
|
|
51246
|
+
message: `${res.status} ${res.statusText || ""}`.trim()
|
|
51247
|
+
};
|
|
51248
|
+
} catch (err) {
|
|
51249
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
51250
|
+
return { ok: false, message: msg };
|
|
51251
|
+
}
|
|
51252
|
+
}
|
|
51253
|
+
async function testKey(configKey, key, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
51254
|
+
const tester = TESTERS[configKey];
|
|
51255
|
+
if (!tester) {
|
|
51256
|
+
return { ok: false, skipped: true, message: "no tester registered" };
|
|
51257
|
+
}
|
|
51258
|
+
const ctrl = new AbortController();
|
|
51259
|
+
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
51260
|
+
try {
|
|
51261
|
+
return await tester.test(key, ctrl.signal);
|
|
51262
|
+
} finally {
|
|
51263
|
+
clearTimeout(timer);
|
|
51264
|
+
}
|
|
51265
|
+
}
|
|
51266
|
+
function isTestableProvider(configKey) {
|
|
51267
|
+
const t = TESTERS[configKey];
|
|
51268
|
+
if (!t) return false;
|
|
51269
|
+
return true;
|
|
51270
|
+
}
|
|
51271
|
+
var DEFAULT_TIMEOUT_MS, TESTERS;
|
|
51272
|
+
var init_key_live_test = __esm({
|
|
51273
|
+
"src/utils/key-live-test.ts"() {
|
|
51274
|
+
"use strict";
|
|
51275
|
+
DEFAULT_TIMEOUT_MS = 5e3;
|
|
51276
|
+
TESTERS = {
|
|
51277
|
+
anthropic: {
|
|
51278
|
+
name: "Anthropic",
|
|
51279
|
+
test: (key, signal) => getOk(
|
|
51280
|
+
"https://api.anthropic.com/v1/models",
|
|
51281
|
+
{ "x-api-key": key, "anthropic-version": "2023-06-01" },
|
|
51282
|
+
signal
|
|
51283
|
+
)
|
|
51284
|
+
},
|
|
51285
|
+
openai: {
|
|
51286
|
+
name: "OpenAI",
|
|
51287
|
+
test: (key, signal) => getOk(
|
|
51288
|
+
"https://api.openai.com/v1/models",
|
|
51289
|
+
{ Authorization: `Bearer ${key}` },
|
|
51290
|
+
signal
|
|
51291
|
+
)
|
|
51292
|
+
},
|
|
51293
|
+
google: {
|
|
51294
|
+
name: "Google",
|
|
51295
|
+
test: (key, signal) => getOk(
|
|
51296
|
+
`https://generativelanguage.googleapis.com/v1beta/models?key=${encodeURIComponent(key)}`,
|
|
51297
|
+
{},
|
|
51298
|
+
signal
|
|
51299
|
+
)
|
|
51300
|
+
},
|
|
51301
|
+
xai: {
|
|
51302
|
+
name: "xAI",
|
|
51303
|
+
test: (key, signal) => getOk(
|
|
51304
|
+
"https://api.x.ai/v1/models",
|
|
51305
|
+
{ Authorization: `Bearer ${key}` },
|
|
51306
|
+
signal
|
|
51307
|
+
)
|
|
51308
|
+
},
|
|
51309
|
+
elevenlabs: {
|
|
51310
|
+
name: "ElevenLabs",
|
|
51311
|
+
test: (key, signal) => getOk("https://api.elevenlabs.io/v1/user", { "xi-api-key": key }, signal)
|
|
51312
|
+
},
|
|
51313
|
+
replicate: {
|
|
51314
|
+
name: "Replicate",
|
|
51315
|
+
test: (key, signal) => getOk(
|
|
51316
|
+
"https://api.replicate.com/v1/account",
|
|
51317
|
+
{ Authorization: `Bearer ${key}` },
|
|
51318
|
+
signal
|
|
51319
|
+
)
|
|
51320
|
+
},
|
|
51321
|
+
openrouter: {
|
|
51322
|
+
name: "OpenRouter",
|
|
51323
|
+
test: (key, signal) => getOk(
|
|
51324
|
+
"https://openrouter.ai/api/v1/models",
|
|
51325
|
+
{ Authorization: `Bearer ${key}` },
|
|
51326
|
+
signal
|
|
51327
|
+
)
|
|
51328
|
+
},
|
|
51329
|
+
// The four below have no cheap authenticated GET — providing a tester
|
|
51330
|
+
// would either consume a paid API call (fal, Runway), require HMAC
|
|
51331
|
+
// signing per request (Kling), or burn an image upload (ImgBB). We
|
|
51332
|
+
// surface them as `skipped` so the user knows we didn't blank-check.
|
|
51333
|
+
fal: {
|
|
51334
|
+
name: "fal.ai",
|
|
51335
|
+
test: async () => ({ ok: false, skipped: true, message: "no list endpoint" })
|
|
51336
|
+
},
|
|
51337
|
+
kling: {
|
|
51338
|
+
name: "Kling",
|
|
51339
|
+
test: async () => ({ ok: false, skipped: true, message: "HMAC-signed; can't test cheaply" })
|
|
51340
|
+
},
|
|
51341
|
+
runway: {
|
|
51342
|
+
name: "Runway",
|
|
51343
|
+
test: async () => ({ ok: false, skipped: true, message: "POST-only API" })
|
|
51344
|
+
},
|
|
51345
|
+
imgbb: {
|
|
51346
|
+
name: "ImgBB",
|
|
51347
|
+
test: async () => ({ ok: false, skipped: true, message: "would consume an upload" })
|
|
51348
|
+
}
|
|
51349
|
+
};
|
|
51350
|
+
}
|
|
51351
|
+
});
|
|
51352
|
+
|
|
51233
51353
|
// src/pipeline/renderers/chrome.ts
|
|
51234
51354
|
import { existsSync as existsSync32 } from "node:fs";
|
|
51235
51355
|
import { homedir as homedir5 } from "node:os";
|
|
@@ -51999,126 +52119,6 @@ var init_scene_build = __esm({
|
|
|
51999
52119
|
}
|
|
52000
52120
|
});
|
|
52001
52121
|
|
|
52002
|
-
// src/utils/key-live-test.ts
|
|
52003
|
-
var key_live_test_exports = {};
|
|
52004
|
-
__export(key_live_test_exports, {
|
|
52005
|
-
isTestableProvider: () => isTestableProvider,
|
|
52006
|
-
testKey: () => testKey
|
|
52007
|
-
});
|
|
52008
|
-
async function getOk(url, headers, signal) {
|
|
52009
|
-
try {
|
|
52010
|
-
const res = await fetch(url, { method: "GET", headers, signal });
|
|
52011
|
-
if (res.ok) return { ok: true, status: res.status };
|
|
52012
|
-
return {
|
|
52013
|
-
ok: false,
|
|
52014
|
-
status: res.status,
|
|
52015
|
-
message: `${res.status} ${res.statusText || ""}`.trim()
|
|
52016
|
-
};
|
|
52017
|
-
} catch (err) {
|
|
52018
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
52019
|
-
return { ok: false, message: msg };
|
|
52020
|
-
}
|
|
52021
|
-
}
|
|
52022
|
-
async function testKey(configKey, key, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
52023
|
-
const tester = TESTERS[configKey];
|
|
52024
|
-
if (!tester) {
|
|
52025
|
-
return { ok: false, skipped: true, message: "no tester registered" };
|
|
52026
|
-
}
|
|
52027
|
-
const ctrl = new AbortController();
|
|
52028
|
-
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
52029
|
-
try {
|
|
52030
|
-
return await tester.test(key, ctrl.signal);
|
|
52031
|
-
} finally {
|
|
52032
|
-
clearTimeout(timer);
|
|
52033
|
-
}
|
|
52034
|
-
}
|
|
52035
|
-
function isTestableProvider(configKey) {
|
|
52036
|
-
const t = TESTERS[configKey];
|
|
52037
|
-
if (!t) return false;
|
|
52038
|
-
return true;
|
|
52039
|
-
}
|
|
52040
|
-
var DEFAULT_TIMEOUT_MS, TESTERS;
|
|
52041
|
-
var init_key_live_test = __esm({
|
|
52042
|
-
"src/utils/key-live-test.ts"() {
|
|
52043
|
-
"use strict";
|
|
52044
|
-
DEFAULT_TIMEOUT_MS = 5e3;
|
|
52045
|
-
TESTERS = {
|
|
52046
|
-
anthropic: {
|
|
52047
|
-
name: "Anthropic",
|
|
52048
|
-
test: (key, signal) => getOk(
|
|
52049
|
-
"https://api.anthropic.com/v1/models",
|
|
52050
|
-
{ "x-api-key": key, "anthropic-version": "2023-06-01" },
|
|
52051
|
-
signal
|
|
52052
|
-
)
|
|
52053
|
-
},
|
|
52054
|
-
openai: {
|
|
52055
|
-
name: "OpenAI",
|
|
52056
|
-
test: (key, signal) => getOk(
|
|
52057
|
-
"https://api.openai.com/v1/models",
|
|
52058
|
-
{ Authorization: `Bearer ${key}` },
|
|
52059
|
-
signal
|
|
52060
|
-
)
|
|
52061
|
-
},
|
|
52062
|
-
google: {
|
|
52063
|
-
name: "Google",
|
|
52064
|
-
test: (key, signal) => getOk(
|
|
52065
|
-
`https://generativelanguage.googleapis.com/v1beta/models?key=${encodeURIComponent(key)}`,
|
|
52066
|
-
{},
|
|
52067
|
-
signal
|
|
52068
|
-
)
|
|
52069
|
-
},
|
|
52070
|
-
xai: {
|
|
52071
|
-
name: "xAI",
|
|
52072
|
-
test: (key, signal) => getOk(
|
|
52073
|
-
"https://api.x.ai/v1/models",
|
|
52074
|
-
{ Authorization: `Bearer ${key}` },
|
|
52075
|
-
signal
|
|
52076
|
-
)
|
|
52077
|
-
},
|
|
52078
|
-
elevenlabs: {
|
|
52079
|
-
name: "ElevenLabs",
|
|
52080
|
-
test: (key, signal) => getOk("https://api.elevenlabs.io/v1/user", { "xi-api-key": key }, signal)
|
|
52081
|
-
},
|
|
52082
|
-
replicate: {
|
|
52083
|
-
name: "Replicate",
|
|
52084
|
-
test: (key, signal) => getOk(
|
|
52085
|
-
"https://api.replicate.com/v1/account",
|
|
52086
|
-
{ Authorization: `Bearer ${key}` },
|
|
52087
|
-
signal
|
|
52088
|
-
)
|
|
52089
|
-
},
|
|
52090
|
-
openrouter: {
|
|
52091
|
-
name: "OpenRouter",
|
|
52092
|
-
test: (key, signal) => getOk(
|
|
52093
|
-
"https://openrouter.ai/api/v1/models",
|
|
52094
|
-
{ Authorization: `Bearer ${key}` },
|
|
52095
|
-
signal
|
|
52096
|
-
)
|
|
52097
|
-
},
|
|
52098
|
-
// The four below have no cheap authenticated GET — providing a tester
|
|
52099
|
-
// would either consume a paid API call (fal, Runway), require HMAC
|
|
52100
|
-
// signing per request (Kling), or burn an image upload (ImgBB). We
|
|
52101
|
-
// surface them as `skipped` so the user knows we didn't blank-check.
|
|
52102
|
-
fal: {
|
|
52103
|
-
name: "fal.ai",
|
|
52104
|
-
test: async () => ({ ok: false, skipped: true, message: "no list endpoint" })
|
|
52105
|
-
},
|
|
52106
|
-
kling: {
|
|
52107
|
-
name: "Kling",
|
|
52108
|
-
test: async () => ({ ok: false, skipped: true, message: "HMAC-signed; can't test cheaply" })
|
|
52109
|
-
},
|
|
52110
|
-
runway: {
|
|
52111
|
-
name: "Runway",
|
|
52112
|
-
test: async () => ({ ok: false, skipped: true, message: "POST-only API" })
|
|
52113
|
-
},
|
|
52114
|
-
imgbb: {
|
|
52115
|
-
name: "ImgBB",
|
|
52116
|
-
test: async () => ({ ok: false, skipped: true, message: "would consume an upload" })
|
|
52117
|
-
}
|
|
52118
|
-
};
|
|
52119
|
-
}
|
|
52120
|
-
});
|
|
52121
|
-
|
|
52122
52122
|
// src/pipeline/resolver.ts
|
|
52123
52123
|
function resolveStepParams(params, completedSteps) {
|
|
52124
52124
|
const resolved = {};
|
|
@@ -62651,7 +62651,7 @@ init_source();
|
|
|
62651
62651
|
// package.json
|
|
62652
62652
|
var package_default = {
|
|
62653
62653
|
name: "@vibeframe/cli",
|
|
62654
|
-
version: "0.
|
|
62654
|
+
version: "0.82.0",
|
|
62655
62655
|
description: "VibeFrame CLI - natural language video editing from the terminal",
|
|
62656
62656
|
private: false,
|
|
62657
62657
|
license: "MIT",
|
|
@@ -69581,13 +69581,17 @@ var VALID_LLM_PROVIDERS = [
|
|
|
69581
69581
|
"xai",
|
|
69582
69582
|
"openrouter"
|
|
69583
69583
|
];
|
|
69584
|
-
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").addHelpText(
|
|
69584
|
+
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)").addHelpText(
|
|
69585
69585
|
"after",
|
|
69586
69586
|
`
|
|
69587
69587
|
Non-interactive examples (no TTY required):
|
|
69588
|
-
vibe setup --yes --provider claude --import-env
|
|
69589
|
-
vibe setup --yes --import-env
|
|
69590
|
-
vibe setup --yes --provider openai
|
|
69588
|
+
vibe setup --yes --provider claude --import-env Bootstrap CI / devcontainer
|
|
69589
|
+
vibe setup --yes --import-env --test Persist .env keys + verify each one
|
|
69590
|
+
vibe setup --yes --provider openai Just switch the agent provider
|
|
69591
|
+
|
|
69592
|
+
Exit codes (non-interactive):
|
|
69593
|
+
0 success 7 --test verification failed (one or more keys returned non-2xx)
|
|
69594
|
+
2 usage error (other codes match the rest of the CLI: 4/5/6 = auth/api/network)
|
|
69591
69595
|
`
|
|
69592
69596
|
).action(async (options) => {
|
|
69593
69597
|
if (options.claudeCode) {
|
|
@@ -69609,7 +69613,8 @@ Non-interactive examples (no TTY required):
|
|
|
69609
69613
|
if (wantsNonInteractive) {
|
|
69610
69614
|
await runNonInteractiveSetup({
|
|
69611
69615
|
provider: options.provider,
|
|
69612
|
-
importEnv: Boolean(options.importEnv)
|
|
69616
|
+
importEnv: Boolean(options.importEnv),
|
|
69617
|
+
test: Boolean(options.test)
|
|
69613
69618
|
});
|
|
69614
69619
|
return;
|
|
69615
69620
|
}
|
|
@@ -69716,6 +69721,37 @@ async function runNonInteractiveSetup(opts) {
|
|
|
69716
69721
|
for (const w of warnings) {
|
|
69717
69722
|
console.error(source_default.yellow(`\u26A0 ${w}`));
|
|
69718
69723
|
}
|
|
69724
|
+
if (opts.test) {
|
|
69725
|
+
const { testKey: testKey2 } = await Promise.resolve().then(() => (init_key_live_test(), key_live_test_exports));
|
|
69726
|
+
console.log();
|
|
69727
|
+
console.log(source_default.bold("Live key tests"));
|
|
69728
|
+
let failures = 0;
|
|
69729
|
+
let tested = 0;
|
|
69730
|
+
for (const meta of getAllApiKeys()) {
|
|
69731
|
+
const value = config2.providers[meta.configKey];
|
|
69732
|
+
if (!value) continue;
|
|
69733
|
+
tested++;
|
|
69734
|
+
const result = await testKey2(meta.configKey, value);
|
|
69735
|
+
const label = meta.label.padEnd(12);
|
|
69736
|
+
if (result.skipped) {
|
|
69737
|
+
console.log(source_default.dim(` SKIP ${label} ${result.message ?? "no test available"}`));
|
|
69738
|
+
} else if (result.ok) {
|
|
69739
|
+
console.log(source_default.green(` \u2713 ${label}`) + source_default.dim(` ${result.status}`));
|
|
69740
|
+
} else {
|
|
69741
|
+
failures++;
|
|
69742
|
+
const detail = result.message ?? `status ${result.status ?? "?"}`;
|
|
69743
|
+
console.log(source_default.red(` \u2717 ${label}`) + source_default.dim(` ${detail}`));
|
|
69744
|
+
}
|
|
69745
|
+
}
|
|
69746
|
+
if (tested === 0) {
|
|
69747
|
+
console.log(source_default.dim(" (no keys configured to test)"));
|
|
69748
|
+
}
|
|
69749
|
+
if (failures > 0) {
|
|
69750
|
+
console.error();
|
|
69751
|
+
console.error(source_default.red(`Verification failed: ${failures} key${failures === 1 ? "" : "s"} returned non-2xx.`));
|
|
69752
|
+
process.exit(7);
|
|
69753
|
+
}
|
|
69754
|
+
}
|
|
69719
69755
|
}
|
|
69720
69756
|
async function runSetupWizard(fullSetup = false) {
|
|
69721
69757
|
console.log();
|
|
@@ -69981,6 +70017,7 @@ async function showComplete(config2, defaultTryCommand, features = []) {
|
|
|
69981
70017
|
const tag = hostDetected && w.topic === "scene" ? source_default.cyan(" (recommended)") : "";
|
|
69982
70018
|
console.log(source_default.dim(` ${cmd}${w.summary}${tag}`));
|
|
69983
70019
|
}
|
|
70020
|
+
console.log(source_default.dim(" vibe doctor --test-keys Live-check each provider key against its API"));
|
|
69984
70021
|
console.log(source_default.dim(" vibe doctor Check system health + available commands"));
|
|
69985
70022
|
console.log(source_default.dim(" vibe schema --list Discover every command"));
|
|
69986
70023
|
console.log(source_default.dim(" vibe setup Re-run user-scope setup anytime"));
|
|
@@ -72709,10 +72746,10 @@ function showFirstRunBanner() {
|
|
|
72709
72746
|
console.log(` ${source_default.white("2.")} ${source_default.green("vibe doctor")} Check system health`);
|
|
72710
72747
|
console.log(` ${source_default.white("3.")} ${source_default.green("vibe --help")} See all commands`);
|
|
72711
72748
|
console.log();
|
|
72712
|
-
console.log(source_default.dim("
|
|
72749
|
+
console.log(source_default.dim(" Try without keys:"));
|
|
72750
|
+
console.log(` ${source_default.green("vibe demo")} Run sample edits on a test video`);
|
|
72713
72751
|
console.log(source_default.dim(" vibe edit silence-cut video.mp4 -o clean.mp4"));
|
|
72714
72752
|
console.log(source_default.dim(" vibe detect scenes video.mp4"));
|
|
72715
|
-
console.log(source_default.dim(" vibe edit fade video.mp4 -o faded.mp4 --fade-in 1 --fade-out 1"));
|
|
72716
72753
|
console.log();
|
|
72717
72754
|
}
|
|
72718
72755
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.82.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.82.0",
|
|
187
|
+
"@vibeframe/core": "0.82.0"
|
|
188
188
|
},
|
|
189
189
|
"engines": {
|
|
190
190
|
"node": ">=20"
|