@vibeframe/cli 0.27.0 → 0.29.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/LICENSE +21 -0
- package/dist/agent/adapters/index.d.ts +1 -0
- package/dist/agent/adapters/index.d.ts.map +1 -1
- package/dist/agent/adapters/index.js +5 -0
- package/dist/agent/adapters/index.js.map +1 -1
- package/dist/agent/adapters/openrouter.d.ts +16 -0
- package/dist/agent/adapters/openrouter.d.ts.map +1 -0
- package/dist/agent/adapters/openrouter.js +100 -0
- package/dist/agent/adapters/openrouter.js.map +1 -0
- package/dist/agent/types.d.ts +1 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +3 -1
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/setup.js +5 -2
- package/dist/commands/setup.js.map +1 -1
- package/dist/config/schema.d.ts +2 -1
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +2 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/index.js +0 -0
- package/package.json +16 -12
- package/.turbo/turbo-build.log +0 -4
- package/.turbo/turbo-lint.log +0 -21
- package/.turbo/turbo-test.log +0 -689
- package/src/agent/adapters/claude.ts +0 -143
- package/src/agent/adapters/gemini.ts +0 -159
- package/src/agent/adapters/index.ts +0 -61
- package/src/agent/adapters/ollama.ts +0 -231
- package/src/agent/adapters/openai.ts +0 -116
- package/src/agent/adapters/xai.ts +0 -119
- package/src/agent/index.ts +0 -251
- package/src/agent/memory/index.ts +0 -151
- package/src/agent/prompts/system.ts +0 -106
- package/src/agent/tools/ai-editing.ts +0 -845
- package/src/agent/tools/ai-generation.ts +0 -1073
- package/src/agent/tools/ai-pipeline.ts +0 -1055
- package/src/agent/tools/ai.ts +0 -21
- package/src/agent/tools/batch.ts +0 -429
- package/src/agent/tools/e2e.test.ts +0 -545
- package/src/agent/tools/export.ts +0 -184
- package/src/agent/tools/filesystem.ts +0 -237
- package/src/agent/tools/index.ts +0 -150
- package/src/agent/tools/integration.test.ts +0 -775
- package/src/agent/tools/media.ts +0 -697
- package/src/agent/tools/project.ts +0 -313
- package/src/agent/tools/timeline.ts +0 -951
- package/src/agent/types.ts +0 -68
- package/src/commands/agent.ts +0 -340
- package/src/commands/ai-analyze.ts +0 -429
- package/src/commands/ai-animated-caption.ts +0 -390
- package/src/commands/ai-audio.ts +0 -941
- package/src/commands/ai-broll.ts +0 -490
- package/src/commands/ai-edit-cli.ts +0 -658
- package/src/commands/ai-edit.ts +0 -1542
- package/src/commands/ai-fill-gaps.ts +0 -566
- package/src/commands/ai-helpers.ts +0 -65
- package/src/commands/ai-highlights.ts +0 -1303
- package/src/commands/ai-image.ts +0 -761
- package/src/commands/ai-motion.ts +0 -347
- package/src/commands/ai-narrate.ts +0 -451
- package/src/commands/ai-review.ts +0 -309
- package/src/commands/ai-script-pipeline-cli.ts +0 -1710
- package/src/commands/ai-script-pipeline.ts +0 -1365
- package/src/commands/ai-suggest-edit.ts +0 -264
- package/src/commands/ai-video-fx.ts +0 -445
- package/src/commands/ai-video.ts +0 -915
- package/src/commands/ai-viral.ts +0 -595
- package/src/commands/ai-visual-fx.ts +0 -601
- package/src/commands/ai.test.ts +0 -627
- package/src/commands/ai.ts +0 -307
- package/src/commands/analyze.ts +0 -282
- package/src/commands/audio.ts +0 -644
- package/src/commands/batch.test.ts +0 -279
- package/src/commands/batch.ts +0 -440
- package/src/commands/detect.ts +0 -329
- package/src/commands/doctor.ts +0 -237
- package/src/commands/edit-cmd.ts +0 -1014
- package/src/commands/export.ts +0 -918
- package/src/commands/generate.ts +0 -2146
- package/src/commands/media.ts +0 -177
- package/src/commands/output.ts +0 -142
- package/src/commands/pipeline.ts +0 -398
- package/src/commands/project.test.ts +0 -127
- package/src/commands/project.ts +0 -149
- package/src/commands/sanitize.ts +0 -60
- package/src/commands/schema.ts +0 -130
- package/src/commands/setup.ts +0 -509
- package/src/commands/timeline.test.ts +0 -499
- package/src/commands/timeline.ts +0 -529
- package/src/commands/validate.ts +0 -77
- package/src/config/config.test.ts +0 -197
- package/src/config/index.ts +0 -125
- package/src/config/schema.ts +0 -82
- package/src/engine/index.ts +0 -2
- package/src/engine/project.test.ts +0 -702
- package/src/engine/project.ts +0 -439
- package/src/index.ts +0 -146
- package/src/utils/api-key.test.ts +0 -41
- package/src/utils/api-key.ts +0 -247
- package/src/utils/audio.ts +0 -83
- package/src/utils/exec-safe.ts +0 -75
- package/src/utils/first-run.ts +0 -52
- package/src/utils/provider-resolver.ts +0 -56
- package/src/utils/remotion.ts +0 -951
- package/src/utils/subtitle.test.ts +0 -227
- package/src/utils/subtitle.ts +0 -169
- package/src/utils/tty.ts +0 -196
- package/tsconfig.json +0 -20
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module ai-suggest-edit
|
|
3
|
-
* @description AI suggest, edit, and storyboard CLI commands.
|
|
4
|
-
*
|
|
5
|
-
* ## Commands: vibe ai suggest, vibe ai edit, vibe ai storyboard
|
|
6
|
-
* ## Dependencies: Gemini, OpenAI, Claude
|
|
7
|
-
*
|
|
8
|
-
* Extracted from ai.ts as part of modularisation.
|
|
9
|
-
* ai.ts calls registerSuggestEditCommands(aiCommand).
|
|
10
|
-
* @see MODELS.md for AI model configuration
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { type Command } from 'commander';
|
|
14
|
-
import { readFile, writeFile } from 'node:fs/promises';
|
|
15
|
-
import { resolve } from 'node:path';
|
|
16
|
-
import chalk from 'chalk';
|
|
17
|
-
import ora from 'ora';
|
|
18
|
-
import {
|
|
19
|
-
GeminiProvider,
|
|
20
|
-
OpenAIProvider,
|
|
21
|
-
ClaudeProvider,
|
|
22
|
-
} from '@vibeframe/ai-providers';
|
|
23
|
-
import { Project, type ProjectFile } from '../engine/index.js';
|
|
24
|
-
import { getApiKey } from '../utils/api-key.js';
|
|
25
|
-
import { formatTime, applySuggestion } from './ai-helpers.js';
|
|
26
|
-
import { executeCommand } from './ai.js';
|
|
27
|
-
|
|
28
|
-
export function registerSuggestEditCommands(ai: Command): void {
|
|
29
|
-
ai
|
|
30
|
-
.command("suggest")
|
|
31
|
-
.description("Get AI edit suggestions using Gemini")
|
|
32
|
-
.argument("<project>", "Project file path")
|
|
33
|
-
.argument("<instruction>", "Natural language instruction")
|
|
34
|
-
.option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)")
|
|
35
|
-
.option("--apply", "Apply the first suggestion automatically")
|
|
36
|
-
.action(async (projectPath: string, instruction: string, options) => {
|
|
37
|
-
try {
|
|
38
|
-
const apiKey = await getApiKey("GOOGLE_API_KEY", "Google", options.apiKey);
|
|
39
|
-
if (!apiKey) {
|
|
40
|
-
console.error(chalk.red("Google API key required. Use --api-key or set GOOGLE_API_KEY"));
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const spinner = ora("Initializing Gemini...").start();
|
|
45
|
-
|
|
46
|
-
const filePath = resolve(process.cwd(), projectPath);
|
|
47
|
-
const content = await readFile(filePath, "utf-8");
|
|
48
|
-
const data: ProjectFile = JSON.parse(content);
|
|
49
|
-
const project = Project.fromJSON(data);
|
|
50
|
-
|
|
51
|
-
const gemini = new GeminiProvider();
|
|
52
|
-
await gemini.initialize({ apiKey });
|
|
53
|
-
|
|
54
|
-
spinner.text = "Analyzing...";
|
|
55
|
-
const clips = project.getClips();
|
|
56
|
-
const suggestions = await gemini.autoEdit(clips, instruction);
|
|
57
|
-
|
|
58
|
-
spinner.succeed(chalk.green(`Found ${suggestions.length} suggestion(s)`));
|
|
59
|
-
|
|
60
|
-
console.log();
|
|
61
|
-
console.log(chalk.bold.cyan("Edit Suggestions"));
|
|
62
|
-
console.log(chalk.dim("─".repeat(60)));
|
|
63
|
-
|
|
64
|
-
for (let i = 0; i < suggestions.length; i++) {
|
|
65
|
-
const sug = suggestions[i];
|
|
66
|
-
console.log();
|
|
67
|
-
console.log(chalk.yellow(`[${i + 1}] ${sug.type.toUpperCase()}`));
|
|
68
|
-
console.log(` ${sug.description}`);
|
|
69
|
-
console.log(chalk.dim(` Confidence: ${(sug.confidence * 100).toFixed(0)}%`));
|
|
70
|
-
console.log(chalk.dim(` Clips: ${sug.clipIds.join(", ")}`));
|
|
71
|
-
console.log(chalk.dim(` Params: ${JSON.stringify(sug.params)}`));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (options.apply && suggestions.length > 0) {
|
|
75
|
-
console.log();
|
|
76
|
-
spinner.start("Applying first suggestion...");
|
|
77
|
-
|
|
78
|
-
const sug = suggestions[0];
|
|
79
|
-
const applied = applySuggestion(project, sug);
|
|
80
|
-
|
|
81
|
-
if (applied) {
|
|
82
|
-
await writeFile(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
83
|
-
spinner.succeed(chalk.green("Suggestion applied"));
|
|
84
|
-
} else {
|
|
85
|
-
spinner.warn(chalk.yellow("Could not apply suggestion automatically"));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
console.log();
|
|
90
|
-
} catch (error) {
|
|
91
|
-
console.error(chalk.red("AI suggestion failed"));
|
|
92
|
-
console.error(error);
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
ai
|
|
98
|
-
.command("edit")
|
|
99
|
-
.description("Edit timeline using natural language (GPT-powered)")
|
|
100
|
-
.argument("<project>", "Project file path")
|
|
101
|
-
.argument("<instruction>", "Natural language command (e.g., 'trim all clips to 5 seconds')")
|
|
102
|
-
.option("-k, --api-key <key>", "OpenAI API key (or set OPENAI_API_KEY env)")
|
|
103
|
-
.option("--dry-run", "Show commands without executing")
|
|
104
|
-
.action(async (projectPath: string, instruction: string, options) => {
|
|
105
|
-
try {
|
|
106
|
-
const apiKey = await getApiKey("OPENAI_API_KEY", "OpenAI", options.apiKey);
|
|
107
|
-
if (!apiKey) {
|
|
108
|
-
console.error(chalk.red("OpenAI API key required. Use --api-key or set OPENAI_API_KEY"));
|
|
109
|
-
process.exit(1);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const spinner = ora("Parsing command...").start();
|
|
113
|
-
|
|
114
|
-
const filePath = resolve(process.cwd(), projectPath);
|
|
115
|
-
const content = await readFile(filePath, "utf-8");
|
|
116
|
-
const data: ProjectFile = JSON.parse(content);
|
|
117
|
-
const project = Project.fromJSON(data);
|
|
118
|
-
|
|
119
|
-
const gpt = new OpenAIProvider();
|
|
120
|
-
await gpt.initialize({ apiKey });
|
|
121
|
-
|
|
122
|
-
const clips = project.getClips();
|
|
123
|
-
const tracks = project.getTracks().map((t) => t.id);
|
|
124
|
-
|
|
125
|
-
const result = await gpt.parseCommand(instruction, { clips, tracks });
|
|
126
|
-
|
|
127
|
-
if (!result.success) {
|
|
128
|
-
spinner.fail(chalk.red(result.error || "Failed to parse command"));
|
|
129
|
-
process.exit(1);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (result.clarification) {
|
|
133
|
-
spinner.warn(chalk.yellow(result.clarification));
|
|
134
|
-
process.exit(0);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (result.commands.length === 0) {
|
|
138
|
-
spinner.warn(chalk.yellow("No commands generated"));
|
|
139
|
-
process.exit(0);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
spinner.succeed(chalk.green(`Parsed ${result.commands.length} command(s)`));
|
|
143
|
-
|
|
144
|
-
console.log();
|
|
145
|
-
console.log(chalk.bold.cyan("Commands to execute:"));
|
|
146
|
-
console.log(chalk.dim("─".repeat(60)));
|
|
147
|
-
|
|
148
|
-
for (const cmd of result.commands) {
|
|
149
|
-
console.log();
|
|
150
|
-
console.log(chalk.yellow(`▸ ${cmd.action.toUpperCase()}`));
|
|
151
|
-
console.log(` ${cmd.description}`);
|
|
152
|
-
if (cmd.clipIds.length > 0) {
|
|
153
|
-
console.log(chalk.dim(` Clips: ${cmd.clipIds.join(", ")}`));
|
|
154
|
-
}
|
|
155
|
-
console.log(chalk.dim(` Params: ${JSON.stringify(cmd.params)}`));
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (options.dryRun) {
|
|
159
|
-
console.log();
|
|
160
|
-
console.log(chalk.dim("Dry run - no changes made"));
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
console.log();
|
|
165
|
-
spinner.start("Executing commands...");
|
|
166
|
-
|
|
167
|
-
let executed = 0;
|
|
168
|
-
for (const cmd of result.commands) {
|
|
169
|
-
const success = executeCommand(project, cmd);
|
|
170
|
-
if (success) executed++;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
await writeFile(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
|
|
174
|
-
|
|
175
|
-
spinner.succeed(chalk.green(`Executed ${executed}/${result.commands.length} commands`));
|
|
176
|
-
console.log();
|
|
177
|
-
} catch (error) {
|
|
178
|
-
console.error(chalk.red("AI edit failed"));
|
|
179
|
-
console.error(error);
|
|
180
|
-
process.exit(1);
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
ai
|
|
185
|
-
.command("storyboard")
|
|
186
|
-
.description("Generate video storyboard from content using Claude")
|
|
187
|
-
.argument("<content>", "Content to analyze (text or file path)")
|
|
188
|
-
.option("-k, --api-key <key>", "Anthropic API key (or set ANTHROPIC_API_KEY env)")
|
|
189
|
-
.option("-o, --output <path>", "Output JSON file path")
|
|
190
|
-
.option("-d, --duration <sec>", "Target total duration in seconds")
|
|
191
|
-
.option("-f, --file", "Treat content argument as file path")
|
|
192
|
-
.option("-c, --creativity <level>", "Creativity level: low (default, consistent) or high (varied, unexpected)", "low")
|
|
193
|
-
.action(async (content: string, options) => {
|
|
194
|
-
try {
|
|
195
|
-
const apiKey = await getApiKey("ANTHROPIC_API_KEY", "Anthropic", options.apiKey);
|
|
196
|
-
if (!apiKey) {
|
|
197
|
-
console.error(chalk.red("Anthropic API key required. Use --api-key or set ANTHROPIC_API_KEY"));
|
|
198
|
-
process.exit(1);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Validate creativity level
|
|
202
|
-
const creativity = options.creativity?.toLowerCase();
|
|
203
|
-
if (creativity && creativity !== "low" && creativity !== "high") {
|
|
204
|
-
console.error(chalk.red("Invalid creativity level. Use 'low' or 'high'."));
|
|
205
|
-
process.exit(1);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
let textContent = content;
|
|
209
|
-
if (options.file) {
|
|
210
|
-
const filePath = resolve(process.cwd(), content);
|
|
211
|
-
textContent = await readFile(filePath, "utf-8");
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const spinnerText = creativity === "high"
|
|
215
|
-
? "Analyzing content with high creativity..."
|
|
216
|
-
: "Analyzing content...";
|
|
217
|
-
const spinner = ora(spinnerText).start();
|
|
218
|
-
|
|
219
|
-
const claude = new ClaudeProvider();
|
|
220
|
-
await claude.initialize({ apiKey });
|
|
221
|
-
|
|
222
|
-
const segments = await claude.analyzeContent(
|
|
223
|
-
textContent,
|
|
224
|
-
options.duration ? parseFloat(options.duration) : undefined,
|
|
225
|
-
{ creativity: creativity as "low" | "high" | undefined }
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
if (segments.length === 0) {
|
|
229
|
-
spinner.fail(chalk.red("Could not generate storyboard"));
|
|
230
|
-
process.exit(1);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
spinner.succeed(chalk.green(`Generated ${segments.length} segments`));
|
|
234
|
-
|
|
235
|
-
console.log();
|
|
236
|
-
console.log(chalk.bold.cyan("Storyboard"));
|
|
237
|
-
console.log(chalk.dim("─".repeat(60)));
|
|
238
|
-
|
|
239
|
-
for (const seg of segments) {
|
|
240
|
-
console.log();
|
|
241
|
-
console.log(chalk.yellow(`[${seg.index + 1}] ${formatTime(seg.startTime)} - ${formatTime(seg.startTime + seg.duration)}`));
|
|
242
|
-
console.log(` ${seg.description}`);
|
|
243
|
-
console.log(chalk.dim(` Visuals: ${seg.visuals}`));
|
|
244
|
-
if (seg.audio) {
|
|
245
|
-
console.log(chalk.dim(` Audio: ${seg.audio}`));
|
|
246
|
-
}
|
|
247
|
-
if (seg.textOverlays && seg.textOverlays.length > 0) {
|
|
248
|
-
console.log(chalk.dim(` Text: ${seg.textOverlays.join(", ")}`));
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
console.log();
|
|
252
|
-
|
|
253
|
-
if (options.output) {
|
|
254
|
-
const outputPath = resolve(process.cwd(), options.output);
|
|
255
|
-
await writeFile(outputPath, JSON.stringify(segments, null, 2), "utf-8");
|
|
256
|
-
console.log(chalk.green(`Saved to: ${outputPath}`));
|
|
257
|
-
}
|
|
258
|
-
} catch (error) {
|
|
259
|
-
console.error(chalk.red("Storyboard generation failed"));
|
|
260
|
-
console.error(error);
|
|
261
|
-
process.exit(1);
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
}
|