@vibeframe/cli 0.82.0 → 0.84.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 +219 -18
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -35862,6 +35862,45 @@ var init_video = __esm({
|
|
|
35862
35862
|
}
|
|
35863
35863
|
});
|
|
35864
35864
|
|
|
35865
|
+
// src/commands/_shared/cost-tier.ts
|
|
35866
|
+
function applyTier(cmd, tier) {
|
|
35867
|
+
cmd[COST_TIER_KEY] = tier;
|
|
35868
|
+
const colored = TIER_COLOR[tier](`Cost: ${tier} (${TIER_DESCRIPTION[tier]})`);
|
|
35869
|
+
cmd.addHelpText("after", `
|
|
35870
|
+
${colored}
|
|
35871
|
+
`);
|
|
35872
|
+
return cmd;
|
|
35873
|
+
}
|
|
35874
|
+
function getCostTier(cmd) {
|
|
35875
|
+
return cmd[COST_TIER_KEY];
|
|
35876
|
+
}
|
|
35877
|
+
function applyTiers(parent, tiers) {
|
|
35878
|
+
for (const cmd of parent.commands) {
|
|
35879
|
+
const tier = tiers[cmd.name()];
|
|
35880
|
+
if (tier) applyTier(cmd, tier);
|
|
35881
|
+
}
|
|
35882
|
+
}
|
|
35883
|
+
var TIER_DESCRIPTION, TIER_COLOR, COST_TIER_KEY;
|
|
35884
|
+
var init_cost_tier = __esm({
|
|
35885
|
+
"src/commands/_shared/cost-tier.ts"() {
|
|
35886
|
+
"use strict";
|
|
35887
|
+
init_source();
|
|
35888
|
+
TIER_DESCRIPTION = {
|
|
35889
|
+
"free": "FFmpeg only, no API call",
|
|
35890
|
+
"low": "$0.01\u2013$0.10 per call",
|
|
35891
|
+
"high": "$1\u2013$5 per call",
|
|
35892
|
+
"very-high": "$5\u2013$50+ per call"
|
|
35893
|
+
};
|
|
35894
|
+
TIER_COLOR = {
|
|
35895
|
+
"free": source_default.green,
|
|
35896
|
+
"low": source_default.cyan,
|
|
35897
|
+
"high": source_default.yellow,
|
|
35898
|
+
"very-high": source_default.red
|
|
35899
|
+
};
|
|
35900
|
+
COST_TIER_KEY = Symbol.for("@vibeframe/cli.costTier");
|
|
35901
|
+
}
|
|
35902
|
+
});
|
|
35903
|
+
|
|
35865
35904
|
// src/commands/generate.ts
|
|
35866
35905
|
var generate_exports = {};
|
|
35867
35906
|
__export(generate_exports, {
|
|
@@ -35873,6 +35912,10 @@ __export(generate_exports, {
|
|
|
35873
35912
|
executeStoryboard: () => executeStoryboard,
|
|
35874
35913
|
generateCommand: () => generateCommand
|
|
35875
35914
|
});
|
|
35915
|
+
function tierLast(parent, tier) {
|
|
35916
|
+
const newest = parent.commands[parent.commands.length - 1];
|
|
35917
|
+
if (newest) applyTier(newest, tier);
|
|
35918
|
+
}
|
|
35876
35919
|
var generateCommand;
|
|
35877
35920
|
var init_generate = __esm({
|
|
35878
35921
|
"src/commands/generate.ts"() {
|
|
@@ -35891,6 +35934,7 @@ var init_generate = __esm({
|
|
|
35891
35934
|
init_video_extend();
|
|
35892
35935
|
init_image();
|
|
35893
35936
|
init_video();
|
|
35937
|
+
init_cost_tier();
|
|
35894
35938
|
init_sound_effect();
|
|
35895
35939
|
init_music_status();
|
|
35896
35940
|
init_background();
|
|
@@ -35928,18 +35972,31 @@ Run 'vibe schema generate.<command>' for structured parameter info.
|
|
|
35928
35972
|
`
|
|
35929
35973
|
);
|
|
35930
35974
|
registerImageCommand(generateCommand);
|
|
35975
|
+
tierLast(generateCommand, "high");
|
|
35931
35976
|
registerVideoCommand(generateCommand);
|
|
35977
|
+
tierLast(generateCommand, "very-high");
|
|
35932
35978
|
registerSpeechCommand(generateCommand);
|
|
35979
|
+
tierLast(generateCommand, "low");
|
|
35933
35980
|
registerSoundEffectCommand(generateCommand);
|
|
35981
|
+
tierLast(generateCommand, "low");
|
|
35934
35982
|
registerMusicCommand(generateCommand);
|
|
35983
|
+
tierLast(generateCommand, "low");
|
|
35935
35984
|
registerMusicStatusCommand(generateCommand);
|
|
35985
|
+
tierLast(generateCommand, "free");
|
|
35936
35986
|
registerStoryboardCommand(generateCommand);
|
|
35987
|
+
tierLast(generateCommand, "high");
|
|
35937
35988
|
registerMotionCommand(generateCommand);
|
|
35989
|
+
tierLast(generateCommand, "high");
|
|
35938
35990
|
registerThumbnailCommand(generateCommand);
|
|
35991
|
+
tierLast(generateCommand, "free");
|
|
35939
35992
|
registerBackgroundCommand(generateCommand);
|
|
35993
|
+
tierLast(generateCommand, "high");
|
|
35940
35994
|
registerVideoStatusCommand(generateCommand);
|
|
35995
|
+
tierLast(generateCommand, "free");
|
|
35941
35996
|
registerVideoCancelCommand(generateCommand);
|
|
35997
|
+
tierLast(generateCommand, "free");
|
|
35942
35998
|
registerVideoExtendCommand(generateCommand);
|
|
35999
|
+
tierLast(generateCommand, "very-high");
|
|
35943
36000
|
}
|
|
35944
36001
|
});
|
|
35945
36002
|
|
|
@@ -37238,7 +37295,7 @@ var init_ai_edit = __esm({
|
|
|
37238
37295
|
import { resolve as resolve28, extname as extname5, basename as basename7 } from "node:path";
|
|
37239
37296
|
import { existsSync as existsSync22 } from "node:fs";
|
|
37240
37297
|
function registerEditCommands(aiCommand) {
|
|
37241
|
-
aiCommand.command("silence-cut").alias("sc").description("Remove silent segments from video (FFmpeg default, or Gemini for smart detection)").argument("<video>", "Video file path").option("-o, --output <path>", "Output file path (default: <name>-cut.<ext>)").option("--noise <dB>", "Silence threshold in dB (default: -30)", "-30").option("-d, --min-duration <seconds>", "Minimum silence duration to cut (default: 0.5)", "0.5").option("--padding <seconds>", "Padding around non-silent segments (default: 0.1)", "0.1").option("--analyze-only", "Only detect silence, don't cut").option("--use-gemini", "Use Gemini Video Understanding for context-aware silence detection").option("-m, --model <model>", "Gemini model (default: flash)").option("--low-res", "Low resolution mode for longer videos (Gemini only)").option("-k, --api-key <key>", "Google API key override (or set GOOGLE_API_KEY env)").option("--dry-run", "Preview parameters without executing").addHelpText("after", `
|
|
37298
|
+
aiCommand.command("silence-cut").alias("sc").description("Remove silent segments from video (FFmpeg default, or Gemini for smart detection)").argument("<video>", "Video file path").option("-o, --output <path>", "Output file path (default: <name>-cut.<ext>)").option("--noise <dB>", "Silence threshold in dB (default: -30)", "-30").option("-d, --min-duration <seconds>", "Minimum silence duration to cut (default: 0.5)", "0.5").option("--padding <seconds>", "Padding around non-silent segments (default: 0.1)", "0.1").option("--analyze-only", "(deprecated \u2014 use `vibe detect silence`) Only detect silence, don't cut").option("--use-gemini", "Use Gemini Video Understanding for context-aware silence detection").option("-m, --model <model>", "Gemini model (default: flash)").option("--low-res", "Low resolution mode for longer videos (Gemini only)").option("-k, --api-key <key>", "Google API key override (or set GOOGLE_API_KEY env)").option("--dry-run", "Preview parameters without executing").addHelpText("after", `
|
|
37242
37299
|
Examples:
|
|
37243
37300
|
$ vibe edit silence-cut interview.mp4 -o clean.mp4
|
|
37244
37301
|
$ vibe ed sc podcast.mp4 -o trimmed.mp4 --noise -25 --min-duration 1.0
|
|
@@ -37263,6 +37320,13 @@ No API key needed (FFmpeg only). Use --use-gemini for smart detection (requires
|
|
|
37263
37320
|
const name = basename7(videoPath, ext);
|
|
37264
37321
|
const outputPath = options.output || `${name}-cut${ext}`;
|
|
37265
37322
|
const useGemini = options.useGemini || false;
|
|
37323
|
+
if (options.analyzeOnly) {
|
|
37324
|
+
console.error(
|
|
37325
|
+
source_default.yellow(
|
|
37326
|
+
"\u26A0 --analyze-only is deprecated. Use `vibe detect silence` for read-only detection. Will be removed in v1.0."
|
|
37327
|
+
)
|
|
37328
|
+
);
|
|
37329
|
+
}
|
|
37266
37330
|
if (options.dryRun) {
|
|
37267
37331
|
outputSuccess({
|
|
37268
37332
|
command: "edit silence-cut",
|
|
@@ -38485,6 +38549,7 @@ var init_edit_cmd = __esm({
|
|
|
38485
38549
|
init_ai_fill_gaps();
|
|
38486
38550
|
init_output();
|
|
38487
38551
|
init_validate();
|
|
38552
|
+
init_cost_tier();
|
|
38488
38553
|
editCommand = new Command("edit").alias("ed").description(
|
|
38489
38554
|
"Edit and post-process media (silence-cut, caption, grade, reframe, upscale...)"
|
|
38490
38555
|
).addHelpText(
|
|
@@ -39232,6 +39297,26 @@ Run 'vibe schema edit.<command>' for structured parameter info.
|
|
|
39232
39297
|
exitWithError(generalError(`Video upscaling failed: ${msg}`));
|
|
39233
39298
|
}
|
|
39234
39299
|
});
|
|
39300
|
+
applyTiers(editCommand, {
|
|
39301
|
+
// free — FFmpeg only
|
|
39302
|
+
"noise-reduce": "free",
|
|
39303
|
+
"fade": "free",
|
|
39304
|
+
"text-overlay": "free",
|
|
39305
|
+
"interpolate": "free",
|
|
39306
|
+
// low — Whisper / single LLM call
|
|
39307
|
+
"silence-cut": "low",
|
|
39308
|
+
"caption": "low",
|
|
39309
|
+
"translate-srt": "low",
|
|
39310
|
+
"jump-cut": "low",
|
|
39311
|
+
"grade": "low",
|
|
39312
|
+
"speed-ramp": "low",
|
|
39313
|
+
// high — vision LLM or image gen
|
|
39314
|
+
"reframe": "high",
|
|
39315
|
+
"image": "high",
|
|
39316
|
+
"upscale": "high",
|
|
39317
|
+
// very-high — video gen per gap
|
|
39318
|
+
"fill-gaps": "very-high"
|
|
39319
|
+
});
|
|
39235
39320
|
}
|
|
39236
39321
|
});
|
|
39237
39322
|
|
|
@@ -50622,6 +50707,7 @@ var init_detect = __esm({
|
|
|
50622
50707
|
init_exec_safe();
|
|
50623
50708
|
init_output();
|
|
50624
50709
|
init_validate();
|
|
50710
|
+
init_cost_tier();
|
|
50625
50711
|
detectCommand = new Command("detect").description("Auto-detect scenes, beats, and silences in media");
|
|
50626
50712
|
detectCommand.command("scenes").description("Detect scene changes in video").argument("<video>", "Video file path").option("--threshold <value>", "Scene change threshold (0-1)", "0.3").option("-o, --output <path>", "Output JSON file with timestamps").option("--project <path>", "Add scenes as clips to project").option("--dry-run", "Preview parameters without executing").action(async (videoPath, options) => {
|
|
50627
50713
|
const startedAt = Date.now();
|
|
@@ -50913,6 +50999,11 @@ var init_detect = __esm({
|
|
|
50913
50999
|
exitWithError(generalError(`Beat detection failed: ${msg}`));
|
|
50914
51000
|
}
|
|
50915
51001
|
});
|
|
51002
|
+
applyTiers(detectCommand, {
|
|
51003
|
+
"scenes": "free",
|
|
51004
|
+
"silence": "free",
|
|
51005
|
+
"beats": "free"
|
|
51006
|
+
});
|
|
50916
51007
|
}
|
|
50917
51008
|
});
|
|
50918
51009
|
|
|
@@ -50942,7 +51033,7 @@ function listWalkthroughs() {
|
|
|
50942
51033
|
function isWalkthroughTopic(value) {
|
|
50943
51034
|
return typeof value === "string" && WALKTHROUGH_TOPICS.includes(value);
|
|
50944
51035
|
}
|
|
50945
|
-
var SCENE_WALKTHROUGH, PIPELINE_WALKTHROUGH, META, CONTENT, WALKTHROUGH_TOPICS;
|
|
51036
|
+
var SCENE_WALKTHROUGH, PIPELINE_WALKTHROUGH, ARCHITECTURE_WALKTHROUGH, META, CONTENT, WALKTHROUGH_TOPICS;
|
|
50946
51037
|
var init_walkthroughs = __esm({
|
|
50947
51038
|
"src/commands/_shared/walkthroughs/walkthroughs.ts"() {
|
|
50948
51039
|
"use strict";
|
|
@@ -51182,6 +51273,59 @@ When the user has a working shell sequence, extract steps:
|
|
|
51182
51273
|
|
|
51183
51274
|
The \`compose\` action is the catch-all assembly step (audio mux, video
|
|
51184
51275
|
overlay, etc.) \u2014 useful at the tail of a pipeline.
|
|
51276
|
+
`;
|
|
51277
|
+
ARCHITECTURE_WALKTHROUGH = `# vibe agent / build / run \u2014 when to pick which
|
|
51278
|
+
|
|
51279
|
+
The CLI has three orchestrating commands that coordinate other primitives:
|
|
51280
|
+
\`vibe agent\`, \`vibe build\`, \`vibe run\`. New users routinely ask which one
|
|
51281
|
+
they want for a given task. The full audit lives in
|
|
51282
|
+
[\`docs/cli-architecture.md\`](../../../docs/cli-architecture.md); this
|
|
51283
|
+
walkthrough is the operator-facing summary.
|
|
51284
|
+
|
|
51285
|
+
## TL;DR
|
|
51286
|
+
|
|
51287
|
+
| | \`vibe agent\` | \`vibe build\` | \`vibe run\` |
|
|
51288
|
+
|---|---|---|---|
|
|
51289
|
+
| **Driving input** | natural-language prompt | \`STORYBOARD.md\` | YAML pipeline file |
|
|
51290
|
+
| **Interactivity** | REPL or one-shot | one-shot | one-shot |
|
|
51291
|
+
| **Reproducibility** | none | high (idempotent) | highest (checkpointed) |
|
|
51292
|
+
| **Budget caps** | per-session max-turns | none | \`--budget-usd\`, \`--budget-tokens\`, \`--max-errors\` |
|
|
51293
|
+
| **Resume after crash** | no | re-invoke | \`--resume\` |
|
|
51294
|
+
| **Best for** | exploration | finished script | repeatable workflows |
|
|
51295
|
+
|
|
51296
|
+
## Decision tree
|
|
51297
|
+
|
|
51298
|
+
- "I want to play, I'll know it when I see it" \u2192 \`vibe agent\`
|
|
51299
|
+
- "I have a finished script + visual identity" \u2192 \`vibe build\`
|
|
51300
|
+
- "I want this to run again next month" \u2192 \`vibe run\`
|
|
51301
|
+
|
|
51302
|
+
If two seem to fit, pick the rightmost one \u2014 more reproducible, less surprise.
|
|
51303
|
+
|
|
51304
|
+
## Cost-tier awareness (v0.83+)
|
|
51305
|
+
|
|
51306
|
+
Every primitive subcommand carries a cost tier (\`free\` / \`low\` / \`high\` /
|
|
51307
|
+
\`very-high\`). \`vibe schema --list\` exposes the tier as JSON, and each
|
|
51308
|
+
\`vibe <group> <sub> --help\` page shows it as a colored footer. Use
|
|
51309
|
+
\`vibe doctor --test-keys\` before kicking off any high-cost orchestrator \u2014
|
|
51310
|
+
a single bad key wastes time and money.
|
|
51311
|
+
|
|
51312
|
+
## Cross-command primitives
|
|
51313
|
+
|
|
51314
|
+
All three commands ultimately call the same primitives:
|
|
51315
|
+
\`generate\` / \`edit\` / \`audio\` / \`inspect\` / \`detect\` / \`remix\`. The
|
|
51316
|
+
agent calls them through a tool manifest; \`build\` calls a curated subset
|
|
51317
|
+
(TTS + image + compose + render); \`run\` exposes 55+ actions one per primitive.
|
|
51318
|
+
|
|
51319
|
+
## Known overlap
|
|
51320
|
+
|
|
51321
|
+
- \`vibe build\` is conceptually a 4-step pipeline; \`vibe run\` could express
|
|
51322
|
+
the same flow but build's STORYBOARD.md input + opinionated defaults are
|
|
51323
|
+
the value-add.
|
|
51324
|
+
- \`vibe agent\`'s tool registry currently exposes primitives, not
|
|
51325
|
+
orchestrators. Adding \`vibe.build\` / \`vibe.run\` as agent tools is on the
|
|
51326
|
+
table for a future major.
|
|
51327
|
+
- \`vibe run --resume\` has no analog in build/agent; build's idempotent
|
|
51328
|
+
re-invoke covers the common case.
|
|
51185
51329
|
`;
|
|
51186
51330
|
META = {
|
|
51187
51331
|
scene: {
|
|
@@ -51220,13 +51364,32 @@ overlay, etc.) \u2014 useful at the tail of a pipeline.
|
|
|
51220
51364
|
"vibe schema --list",
|
|
51221
51365
|
"vibe doctor"
|
|
51222
51366
|
]
|
|
51367
|
+
},
|
|
51368
|
+
architecture: {
|
|
51369
|
+
title: "vibe agent / build / run \u2014 when to pick which",
|
|
51370
|
+
summary: "Compare the three orchestrating commands on the dimensions that actually decide the choice",
|
|
51371
|
+
steps: [
|
|
51372
|
+
"Pick agent for exploration (NL prompt, REPL, no checkpoints).",
|
|
51373
|
+
"Pick build for STORYBOARD.md \u2192 MP4 with opinionated defaults.",
|
|
51374
|
+
"Pick run for repeatable, budget-capped, checkpointed YAML pipelines.",
|
|
51375
|
+
"Run `vibe doctor --test-keys` before any high-cost orchestrator to validate keys upfront.",
|
|
51376
|
+
"Use `vibe schema --list` (cost field, v0.84) to plan the budget per step before kicking off `vibe run --budget-usd`."
|
|
51377
|
+
],
|
|
51378
|
+
relatedCommands: [
|
|
51379
|
+
"vibe agent",
|
|
51380
|
+
"vibe build",
|
|
51381
|
+
"vibe run",
|
|
51382
|
+
"vibe doctor",
|
|
51383
|
+
"vibe schema --list"
|
|
51384
|
+
]
|
|
51223
51385
|
}
|
|
51224
51386
|
};
|
|
51225
51387
|
CONTENT = {
|
|
51226
51388
|
scene: SCENE_WALKTHROUGH,
|
|
51227
|
-
pipeline: PIPELINE_WALKTHROUGH
|
|
51389
|
+
pipeline: PIPELINE_WALKTHROUGH,
|
|
51390
|
+
architecture: ARCHITECTURE_WALKTHROUGH
|
|
51228
51391
|
};
|
|
51229
|
-
WALKTHROUGH_TOPICS = ["scene", "pipeline"];
|
|
51392
|
+
WALKTHROUGH_TOPICS = ["scene", "pipeline", "architecture"];
|
|
51230
51393
|
}
|
|
51231
51394
|
});
|
|
51232
51395
|
|
|
@@ -51326,25 +51489,36 @@ var init_key_live_test = __esm({
|
|
|
51326
51489
|
signal
|
|
51327
51490
|
)
|
|
51328
51491
|
},
|
|
51329
|
-
//
|
|
51330
|
-
//
|
|
51331
|
-
//
|
|
51332
|
-
|
|
51492
|
+
// Runway: /v1/organization is a read-only GET that returns tier info
|
|
51493
|
+
// (free, doesn't consume credits). Requires the X-Runway-Version
|
|
51494
|
+
// header alongside the Bearer token — without it the request 401s.
|
|
51495
|
+
runway: {
|
|
51496
|
+
name: "Runway",
|
|
51497
|
+
test: (key, signal) => getOk(
|
|
51498
|
+
"https://api.dev.runwayml.com/v1/organization",
|
|
51499
|
+
{
|
|
51500
|
+
Authorization: `Bearer ${key}`,
|
|
51501
|
+
"X-Runway-Version": "2024-11-06"
|
|
51502
|
+
},
|
|
51503
|
+
signal
|
|
51504
|
+
)
|
|
51505
|
+
},
|
|
51506
|
+
// The three below still have no cheap authenticated GET as of v0.83:
|
|
51507
|
+
// fal lacks a documented validation endpoint, Kling auth is per-
|
|
51508
|
+
// request HMAC-signed, ImgBB's only authenticated route is image
|
|
51509
|
+
// upload. Surface them as `skipped` so the user knows we didn't
|
|
51510
|
+
// blank-check.
|
|
51333
51511
|
fal: {
|
|
51334
51512
|
name: "fal.ai",
|
|
51335
|
-
test: async () => ({ ok: false, skipped: true, message: "no
|
|
51513
|
+
test: async () => ({ ok: false, skipped: true, message: "no auth-only endpoint published" })
|
|
51336
51514
|
},
|
|
51337
51515
|
kling: {
|
|
51338
51516
|
name: "Kling",
|
|
51339
|
-
test: async () => ({ ok: false, skipped: true, message: "HMAC
|
|
51340
|
-
},
|
|
51341
|
-
runway: {
|
|
51342
|
-
name: "Runway",
|
|
51343
|
-
test: async () => ({ ok: false, skipped: true, message: "POST-only API" })
|
|
51517
|
+
test: async () => ({ ok: false, skipped: true, message: "per-request HMAC; can't test cheaply" })
|
|
51344
51518
|
},
|
|
51345
51519
|
imgbb: {
|
|
51346
51520
|
name: "ImgBB",
|
|
51347
|
-
test: async () => ({ ok: false, skipped: true, message: "
|
|
51521
|
+
test: async () => ({ ok: false, skipped: true, message: "only auth route is image upload" })
|
|
51348
51522
|
}
|
|
51349
51523
|
};
|
|
51350
51524
|
}
|
|
@@ -62651,7 +62825,7 @@ init_source();
|
|
|
62651
62825
|
// package.json
|
|
62652
62826
|
var package_default = {
|
|
62653
62827
|
name: "@vibeframe/cli",
|
|
62654
|
-
version: "0.
|
|
62828
|
+
version: "0.84.0",
|
|
62655
62829
|
description: "VibeFrame CLI - natural language video editing from the terminal",
|
|
62656
62830
|
private: false,
|
|
62657
62831
|
license: "MIT",
|
|
@@ -63819,6 +63993,7 @@ init_ai_review();
|
|
|
63819
63993
|
init_output();
|
|
63820
63994
|
init_sanitize();
|
|
63821
63995
|
init_validate();
|
|
63996
|
+
init_cost_tier();
|
|
63822
63997
|
import { readFile as readFile23, writeFile as writeFile30 } from "node:fs/promises";
|
|
63823
63998
|
import { resolve as resolve33 } from "node:path";
|
|
63824
63999
|
var inspectCommand = new Command("inspect").description("Inspect media using AI (images, videos, YouTube URLs)").addHelpText(
|
|
@@ -63916,6 +64091,7 @@ inspectCommand.command("media").description("Analyze any media: images, videos,
|
|
|
63916
64091
|
exitWithError(apiError(`Analysis failed: ${error.message}`));
|
|
63917
64092
|
}
|
|
63918
64093
|
});
|
|
64094
|
+
applyTier(inspectCommand.commands[inspectCommand.commands.length - 1], "low");
|
|
63919
64095
|
inspectCommand.command("video").description("Analyze video using Gemini (summarize, Q&A, extract info)").argument("<source>", "Video file path or YouTube URL").argument("<prompt>", "Analysis prompt (e.g., 'Summarize this video')").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("-m, --model <model>", "Model: flash (default), flash-2.5, pro", "flash").option("--fps <number>", "Frames per second (default: 1, higher for action)").option("--start <seconds>", "Start offset in seconds (for clipping)").option("--end <seconds>", "End offset in seconds (for clipping)").option("--low-res", "Use low resolution mode (fewer tokens, longer videos)").option("--verbose", "Show token usage").option("--fields <fields>", "Comma-separated fields to include in output (e.g., response,model)").option("--dry-run", "Preview parameters without executing").action(async (source, prompt3, options) => {
|
|
63920
64096
|
const startedAt = Date.now();
|
|
63921
64097
|
try {
|
|
@@ -63992,7 +64168,9 @@ inspectCommand.command("video").description("Analyze video using Gemini (summari
|
|
|
63992
64168
|
exitWithError(apiError(`Video analysis failed: ${error.message}`));
|
|
63993
64169
|
}
|
|
63994
64170
|
});
|
|
64171
|
+
applyTier(inspectCommand.commands[inspectCommand.commands.length - 1], "low");
|
|
63995
64172
|
registerReviewCommand(inspectCommand);
|
|
64173
|
+
applyTier(inspectCommand.commands[inspectCommand.commands.length - 1], "low");
|
|
63996
64174
|
inspectCommand.command("suggest").description("Get AI edit suggestions using Gemini").argument("<project>", "Timeline file or directory").argument("<instruction>", "Natural language instruction").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("--apply", "Apply the first suggestion automatically").option("--dry-run", "Preview parameters without executing").action(async (projectPath, instruction, options) => {
|
|
63997
64175
|
const startedAt = Date.now();
|
|
63998
64176
|
try {
|
|
@@ -64063,6 +64241,7 @@ inspectCommand.command("suggest").description("Get AI edit suggestions using Gem
|
|
|
64063
64241
|
exitWithError(apiError(`AI suggestion failed: ${error.message}`));
|
|
64064
64242
|
}
|
|
64065
64243
|
});
|
|
64244
|
+
applyTier(inspectCommand.commands[inspectCommand.commands.length - 1], "low");
|
|
64066
64245
|
|
|
64067
64246
|
// src/commands/audio.ts
|
|
64068
64247
|
init_esm();
|
|
@@ -64072,6 +64251,7 @@ init_dist2();
|
|
|
64072
64251
|
init_api_key();
|
|
64073
64252
|
init_exec_safe();
|
|
64074
64253
|
init_subtitle();
|
|
64254
|
+
init_cost_tier();
|
|
64075
64255
|
init_ai_helpers();
|
|
64076
64256
|
init_output();
|
|
64077
64257
|
init_validate();
|
|
@@ -64579,6 +64759,14 @@ audioCommand.command("duck").description("Auto-duck background music when voice
|
|
|
64579
64759
|
exitWithError(generalError(`Audio ducking failed: ${msg}`));
|
|
64580
64760
|
}
|
|
64581
64761
|
});
|
|
64762
|
+
applyTiers(audioCommand, {
|
|
64763
|
+
"transcribe": "low",
|
|
64764
|
+
"list-voices": "low",
|
|
64765
|
+
"isolate": "low",
|
|
64766
|
+
"clone-voice": "low",
|
|
64767
|
+
"dub": "high",
|
|
64768
|
+
"duck": "free"
|
|
64769
|
+
});
|
|
64582
64770
|
|
|
64583
64771
|
// src/commands/remix.ts
|
|
64584
64772
|
init_esm();
|
|
@@ -64769,6 +64957,7 @@ function registerScriptPipelineCommands(aiCommand) {
|
|
|
64769
64957
|
init_ai_highlights();
|
|
64770
64958
|
init_ai_animated_caption();
|
|
64771
64959
|
init_output();
|
|
64960
|
+
init_cost_tier();
|
|
64772
64961
|
var remixCommand = new Command("remix").description(
|
|
64773
64962
|
"Transform existing media (highlights, auto-shorts, animated captions, regenerate-scene)"
|
|
64774
64963
|
).addHelpText(
|
|
@@ -64910,10 +65099,17 @@ Required API Key: OPENAI_API_KEY (Whisper transcription)
|
|
|
64910
65099
|
exitWithError(generalError(`Animated caption failed: ${msg}`));
|
|
64911
65100
|
}
|
|
64912
65101
|
});
|
|
65102
|
+
applyTiers(remixCommand, {
|
|
65103
|
+
"regenerate-scene": "very-high",
|
|
65104
|
+
"highlights": "high",
|
|
65105
|
+
"auto-shorts": "high",
|
|
65106
|
+
"animated-caption": "low"
|
|
65107
|
+
});
|
|
64913
65108
|
|
|
64914
65109
|
// src/commands/schema.ts
|
|
64915
65110
|
init_esm();
|
|
64916
65111
|
init_output();
|
|
65112
|
+
init_cost_tier();
|
|
64917
65113
|
var schemaCommand = new Command("schema").description("Show JSON schema for a CLI command").argument("[command]", "Command path (e.g., generate.image, edit.silence-cut)").option("--list", "List all available command paths").action((commandPath, options) => {
|
|
64918
65114
|
const program3 = schemaCommand.parent;
|
|
64919
65115
|
if (!program3) {
|
|
@@ -64970,15 +65166,18 @@ function listCommands(program3) {
|
|
|
64970
65166
|
if (subCmds.length === 0) {
|
|
64971
65167
|
const desc = group.description() || "";
|
|
64972
65168
|
if (desc.toLowerCase().includes("deprecated")) continue;
|
|
64973
|
-
|
|
65169
|
+
const cost = getCostTier(group);
|
|
65170
|
+
commands.push({ path: name, description: desc, ...cost ? { cost } : {} });
|
|
64974
65171
|
continue;
|
|
64975
65172
|
}
|
|
64976
65173
|
for (const sub of subCmds) {
|
|
64977
65174
|
const desc = sub.description() || "";
|
|
64978
65175
|
if (desc.toLowerCase().includes("deprecated")) continue;
|
|
65176
|
+
const cost = getCostTier(sub);
|
|
64979
65177
|
commands.push({
|
|
64980
65178
|
path: `${name}.${sub.name()}`,
|
|
64981
|
-
description: desc
|
|
65179
|
+
description: desc,
|
|
65180
|
+
...cost ? { cost } : {}
|
|
64982
65181
|
});
|
|
64983
65182
|
}
|
|
64984
65183
|
}
|
|
@@ -65106,9 +65305,11 @@ function buildSchema(cmd, toolName) {
|
|
|
65106
65305
|
}
|
|
65107
65306
|
properties[name] = prop;
|
|
65108
65307
|
}
|
|
65308
|
+
const cost = getCostTier(cmd);
|
|
65109
65309
|
return {
|
|
65110
65310
|
name: toolName,
|
|
65111
65311
|
description: cmd.description(),
|
|
65312
|
+
...cost ? { cost } : {},
|
|
65112
65313
|
parameters: {
|
|
65113
65314
|
type: "object",
|
|
65114
65315
|
properties,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.84.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.84.0",
|
|
187
|
+
"@vibeframe/core": "0.84.0"
|
|
188
188
|
},
|
|
189
189
|
"engines": {
|
|
190
190
|
"node": ">=20"
|