@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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agent/adapters/index.d.ts +1 -0
  3. package/dist/agent/adapters/index.d.ts.map +1 -1
  4. package/dist/agent/adapters/index.js +5 -0
  5. package/dist/agent/adapters/index.js.map +1 -1
  6. package/dist/agent/adapters/openrouter.d.ts +16 -0
  7. package/dist/agent/adapters/openrouter.d.ts.map +1 -0
  8. package/dist/agent/adapters/openrouter.js +100 -0
  9. package/dist/agent/adapters/openrouter.js.map +1 -0
  10. package/dist/agent/types.d.ts +1 -1
  11. package/dist/agent/types.d.ts.map +1 -1
  12. package/dist/commands/agent.d.ts.map +1 -1
  13. package/dist/commands/agent.js +3 -1
  14. package/dist/commands/agent.js.map +1 -1
  15. package/dist/commands/setup.js +5 -2
  16. package/dist/commands/setup.js.map +1 -1
  17. package/dist/config/schema.d.ts +2 -1
  18. package/dist/config/schema.d.ts.map +1 -1
  19. package/dist/config/schema.js +2 -0
  20. package/dist/config/schema.js.map +1 -1
  21. package/dist/index.js +0 -0
  22. package/package.json +16 -12
  23. package/.turbo/turbo-build.log +0 -4
  24. package/.turbo/turbo-lint.log +0 -21
  25. package/.turbo/turbo-test.log +0 -689
  26. package/src/agent/adapters/claude.ts +0 -143
  27. package/src/agent/adapters/gemini.ts +0 -159
  28. package/src/agent/adapters/index.ts +0 -61
  29. package/src/agent/adapters/ollama.ts +0 -231
  30. package/src/agent/adapters/openai.ts +0 -116
  31. package/src/agent/adapters/xai.ts +0 -119
  32. package/src/agent/index.ts +0 -251
  33. package/src/agent/memory/index.ts +0 -151
  34. package/src/agent/prompts/system.ts +0 -106
  35. package/src/agent/tools/ai-editing.ts +0 -845
  36. package/src/agent/tools/ai-generation.ts +0 -1073
  37. package/src/agent/tools/ai-pipeline.ts +0 -1055
  38. package/src/agent/tools/ai.ts +0 -21
  39. package/src/agent/tools/batch.ts +0 -429
  40. package/src/agent/tools/e2e.test.ts +0 -545
  41. package/src/agent/tools/export.ts +0 -184
  42. package/src/agent/tools/filesystem.ts +0 -237
  43. package/src/agent/tools/index.ts +0 -150
  44. package/src/agent/tools/integration.test.ts +0 -775
  45. package/src/agent/tools/media.ts +0 -697
  46. package/src/agent/tools/project.ts +0 -313
  47. package/src/agent/tools/timeline.ts +0 -951
  48. package/src/agent/types.ts +0 -68
  49. package/src/commands/agent.ts +0 -340
  50. package/src/commands/ai-analyze.ts +0 -429
  51. package/src/commands/ai-animated-caption.ts +0 -390
  52. package/src/commands/ai-audio.ts +0 -941
  53. package/src/commands/ai-broll.ts +0 -490
  54. package/src/commands/ai-edit-cli.ts +0 -658
  55. package/src/commands/ai-edit.ts +0 -1542
  56. package/src/commands/ai-fill-gaps.ts +0 -566
  57. package/src/commands/ai-helpers.ts +0 -65
  58. package/src/commands/ai-highlights.ts +0 -1303
  59. package/src/commands/ai-image.ts +0 -761
  60. package/src/commands/ai-motion.ts +0 -347
  61. package/src/commands/ai-narrate.ts +0 -451
  62. package/src/commands/ai-review.ts +0 -309
  63. package/src/commands/ai-script-pipeline-cli.ts +0 -1710
  64. package/src/commands/ai-script-pipeline.ts +0 -1365
  65. package/src/commands/ai-suggest-edit.ts +0 -264
  66. package/src/commands/ai-video-fx.ts +0 -445
  67. package/src/commands/ai-video.ts +0 -915
  68. package/src/commands/ai-viral.ts +0 -595
  69. package/src/commands/ai-visual-fx.ts +0 -601
  70. package/src/commands/ai.test.ts +0 -627
  71. package/src/commands/ai.ts +0 -307
  72. package/src/commands/analyze.ts +0 -282
  73. package/src/commands/audio.ts +0 -644
  74. package/src/commands/batch.test.ts +0 -279
  75. package/src/commands/batch.ts +0 -440
  76. package/src/commands/detect.ts +0 -329
  77. package/src/commands/doctor.ts +0 -237
  78. package/src/commands/edit-cmd.ts +0 -1014
  79. package/src/commands/export.ts +0 -918
  80. package/src/commands/generate.ts +0 -2146
  81. package/src/commands/media.ts +0 -177
  82. package/src/commands/output.ts +0 -142
  83. package/src/commands/pipeline.ts +0 -398
  84. package/src/commands/project.test.ts +0 -127
  85. package/src/commands/project.ts +0 -149
  86. package/src/commands/sanitize.ts +0 -60
  87. package/src/commands/schema.ts +0 -130
  88. package/src/commands/setup.ts +0 -509
  89. package/src/commands/timeline.test.ts +0 -499
  90. package/src/commands/timeline.ts +0 -529
  91. package/src/commands/validate.ts +0 -77
  92. package/src/config/config.test.ts +0 -197
  93. package/src/config/index.ts +0 -125
  94. package/src/config/schema.ts +0 -82
  95. package/src/engine/index.ts +0 -2
  96. package/src/engine/project.test.ts +0 -702
  97. package/src/engine/project.ts +0 -439
  98. package/src/index.ts +0 -146
  99. package/src/utils/api-key.test.ts +0 -41
  100. package/src/utils/api-key.ts +0 -247
  101. package/src/utils/audio.ts +0 -83
  102. package/src/utils/exec-safe.ts +0 -75
  103. package/src/utils/first-run.ts +0 -52
  104. package/src/utils/provider-resolver.ts +0 -56
  105. package/src/utils/remotion.ts +0 -951
  106. package/src/utils/subtitle.test.ts +0 -227
  107. package/src/utils/subtitle.ts +0 -169
  108. package/src/utils/tty.ts +0 -196
  109. package/tsconfig.json +0 -20
@@ -1,21 +0,0 @@
1
- /**
2
- * AI Tools - Barrel module for all AI agent tools
3
- *
4
- * Delegates to three sub-modules:
5
- * - ai-generation.ts: Image, video, TTS, SFX, music, storyboard, motion (8 tools)
6
- * - ai-pipeline.ts: Script-to-video, highlights, auto-shorts, analysis, editing, regeneration (7 tools)
7
- * - ai-editing.ts: Text overlay, review, silence cut, jump cut, captions, noise reduce, fade, thumbnail, translate (9 tools)
8
- *
9
- * Total: 24 AI tools
10
- */
11
-
12
- import type { ToolRegistry } from "./index.js";
13
- import { registerGenerationTools } from "./ai-generation.js";
14
- import { registerPipelineTools } from "./ai-pipeline.js";
15
- import { registerEditingTools } from "./ai-editing.js";
16
-
17
- export function registerAITools(registry: ToolRegistry): void {
18
- registerGenerationTools(registry);
19
- registerPipelineTools(registry);
20
- registerEditingTools(registry);
21
- }
@@ -1,429 +0,0 @@
1
- /**
2
- * Batch Tools - Batch operations for processing multiple items
3
- */
4
-
5
- import { readFile, writeFile, readdir } from "node:fs/promises";
6
- import { resolve, basename, extname, join } from "node:path";
7
- import type { ToolRegistry, ToolHandler } from "./index.js";
8
- import type { ToolDefinition, ToolResult } from "../types.js";
9
- import { Project, type ProjectFile } from "../../engine/index.js";
10
- import type { MediaType, EffectType } from "@vibeframe/core/timeline";
11
- import { ffprobeDuration } from "../../utils/exec-safe.js";
12
-
13
- // Helper functions
14
- function detectMediaType(filePath: string): MediaType {
15
- const ext = extname(filePath).toLowerCase();
16
- const videoExts = [".mp4", ".mov", ".avi", ".mkv", ".webm", ".m4v"];
17
- const audioExts = [".mp3", ".wav", ".aac", ".flac", ".ogg", ".m4a"];
18
- const imageExts = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"];
19
-
20
- if (videoExts.includes(ext)) return "video";
21
- if (audioExts.includes(ext)) return "audio";
22
- if (imageExts.includes(ext)) return "image";
23
- return "video";
24
- }
25
-
26
- function isMediaFile(filePath: string): boolean {
27
- const ext = extname(filePath).toLowerCase();
28
- const mediaExts = [
29
- ".mp4", ".mov", ".avi", ".mkv", ".webm", ".m4v",
30
- ".mp3", ".wav", ".aac", ".flac", ".ogg", ".m4a",
31
- ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp",
32
- ];
33
- return mediaExts.includes(ext);
34
- }
35
-
36
- async function getMediaDuration(filePath: string): Promise<number> {
37
- try {
38
- return await ffprobeDuration(filePath);
39
- } catch {
40
- return 0;
41
- }
42
- }
43
-
44
- // Tool Definitions
45
-
46
- const batchImportDef: ToolDefinition = {
47
- name: "batch_import",
48
- description: "Import multiple media files from a directory into a project. Scans directory for video, audio, and image files.",
49
- parameters: {
50
- type: "object",
51
- properties: {
52
- project: {
53
- type: "string",
54
- description: "Project file path",
55
- },
56
- directory: {
57
- type: "string",
58
- description: "Directory containing media files to import",
59
- },
60
- recursive: {
61
- type: "boolean",
62
- description: "Search subdirectories recursively (default: false)",
63
- },
64
- filter: {
65
- type: "string",
66
- description: "Filter files by extension, comma-separated (e.g., '.mp4,.mov')",
67
- },
68
- imageDuration: {
69
- type: "number",
70
- description: "Default duration for images in seconds (default: 5)",
71
- },
72
- },
73
- required: ["project", "directory"],
74
- },
75
- };
76
-
77
- const batchConcatDef: ToolDefinition = {
78
- name: "batch_concat",
79
- description: "Concatenate multiple sources into sequential clips on the timeline",
80
- parameters: {
81
- type: "object",
82
- properties: {
83
- project: {
84
- type: "string",
85
- description: "Project file path",
86
- },
87
- sourceIds: {
88
- type: "array",
89
- items: { type: "string", description: "Source ID" },
90
- description: "Source IDs to concatenate. If empty with useAll=true, uses all sources.",
91
- },
92
- useAll: {
93
- type: "boolean",
94
- description: "Use all sources in the project (default: false)",
95
- },
96
- trackId: {
97
- type: "string",
98
- description: "Track to place clips on (auto-selects if not specified)",
99
- },
100
- startTime: {
101
- type: "number",
102
- description: "Starting time in seconds (default: 0)",
103
- },
104
- gap: {
105
- type: "number",
106
- description: "Gap between clips in seconds (default: 0)",
107
- },
108
- },
109
- required: ["project"],
110
- },
111
- };
112
-
113
- const batchApplyEffectDef: ToolDefinition = {
114
- name: "batch_apply_effect",
115
- description: "Apply an effect to multiple clips at once",
116
- parameters: {
117
- type: "object",
118
- properties: {
119
- project: {
120
- type: "string",
121
- description: "Project file path",
122
- },
123
- clipIds: {
124
- type: "array",
125
- items: { type: "string", description: "Clip ID" },
126
- description: "Clip IDs to apply effect to. If empty with useAll=true, applies to all clips.",
127
- },
128
- useAll: {
129
- type: "boolean",
130
- description: "Apply to all clips in the project (default: false)",
131
- },
132
- effectType: {
133
- type: "string",
134
- description: "Effect type to apply",
135
- enum: ["fadeIn", "fadeOut", "blur", "brightness", "contrast", "saturation", "speed", "volume"],
136
- },
137
- duration: {
138
- type: "number",
139
- description: "Effect duration in seconds (default: entire clip)",
140
- },
141
- params: {
142
- type: "object",
143
- description: "Effect-specific parameters",
144
- },
145
- },
146
- required: ["project", "effectType"],
147
- },
148
- };
149
-
150
- // Tool Handlers
151
-
152
- const batchImport: ToolHandler = async (args, context): Promise<ToolResult> => {
153
- const projectPath = args.project as string;
154
- const directory = args.directory as string;
155
- const recursive = args.recursive as boolean || false;
156
- const filterStr = args.filter as string | undefined;
157
- const imageDuration = (args.imageDuration as number) || 5;
158
-
159
- try {
160
- const filePath = resolve(context.workingDirectory, projectPath);
161
- const content = await readFile(filePath, "utf-8");
162
- const data: ProjectFile = JSON.parse(content);
163
- const project = Project.fromJSON(data);
164
-
165
- const dirPath = resolve(context.workingDirectory, directory);
166
- const filterExts = filterStr
167
- ? filterStr.split(",").map((e) => e.trim().toLowerCase())
168
- : null;
169
-
170
- // Collect media files
171
- const mediaFiles: string[] = [];
172
-
173
- const scanDir = async (dir: string): Promise<void> => {
174
- const entries = await readdir(dir, { withFileTypes: true });
175
-
176
- for (const entry of entries) {
177
- const entryPath = join(dir, entry.name);
178
-
179
- if (entry.isDirectory() && recursive) {
180
- await scanDir(entryPath);
181
- } else if (entry.isFile()) {
182
- const ext = extname(entry.name).toLowerCase();
183
- const matchesFilter = !filterExts || filterExts.includes(ext);
184
-
185
- if (matchesFilter && isMediaFile(entryPath)) {
186
- mediaFiles.push(entryPath);
187
- }
188
- }
189
- }
190
- };
191
-
192
- await scanDir(dirPath);
193
-
194
- if (mediaFiles.length === 0) {
195
- return {
196
- toolCallId: "",
197
- success: false,
198
- output: "",
199
- error: "No media files found in directory",
200
- };
201
- }
202
-
203
- // Sort files alphabetically
204
- mediaFiles.sort();
205
-
206
- const addedSources: { id: string; name: string; type: MediaType }[] = [];
207
-
208
- for (const mediaFile of mediaFiles) {
209
- const mediaName = basename(mediaFile);
210
- const mediaType = detectMediaType(mediaFile);
211
- let duration = imageDuration;
212
-
213
- // Get actual duration for video/audio
214
- if (mediaType !== "image") {
215
- const actualDuration = await getMediaDuration(mediaFile);
216
- if (actualDuration > 0) {
217
- duration = actualDuration;
218
- }
219
- }
220
-
221
- const source = project.addSource({
222
- name: mediaName,
223
- type: mediaType,
224
- url: mediaFile,
225
- duration,
226
- });
227
-
228
- addedSources.push({ id: source.id, name: mediaName, type: mediaType });
229
- }
230
-
231
- await writeFile(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
232
-
233
- // Build output
234
- const output = [
235
- `Imported ${addedSources.length} media files:`,
236
- "",
237
- ...addedSources.map((s) => ` + ${s.name} (${s.type})`),
238
- ];
239
-
240
- return {
241
- toolCallId: "",
242
- success: true,
243
- output: output.join("\n"),
244
- };
245
- } catch (error) {
246
- return {
247
- toolCallId: "",
248
- success: false,
249
- output: "",
250
- error: `Failed to import files: ${error instanceof Error ? error.message : String(error)}`,
251
- };
252
- }
253
- };
254
-
255
- const batchConcat: ToolHandler = async (args, context): Promise<ToolResult> => {
256
- const projectPath = args.project as string;
257
- const sourceIds = args.sourceIds as string[] || [];
258
- const useAll = args.useAll as boolean || false;
259
- const trackId = args.trackId as string | undefined;
260
- const startTime = (args.startTime as number) || 0;
261
- const gap = (args.gap as number) || 0;
262
-
263
- try {
264
- const filePath = resolve(context.workingDirectory, projectPath);
265
- const content = await readFile(filePath, "utf-8");
266
- const data: ProjectFile = JSON.parse(content);
267
- const project = Project.fromJSON(data);
268
-
269
- // Get sources to concatenate
270
- const sourcesToConcat = useAll
271
- ? project.getSources()
272
- : sourceIds.map((id) => project.getSource(id)).filter(Boolean);
273
-
274
- if (!sourcesToConcat || sourcesToConcat.length === 0) {
275
- return {
276
- toolCallId: "",
277
- success: false,
278
- output: "",
279
- error: "No sources to concatenate. Provide sourceIds or use useAll=true.",
280
- };
281
- }
282
-
283
- // Find or determine track
284
- let targetTrackId = trackId;
285
- if (!targetTrackId) {
286
- // Find first matching track type
287
- const firstSource = sourcesToConcat[0]!;
288
- const trackType = firstSource.type === "audio" ? "audio" : "video";
289
- const tracks = project.getTracksByType(trackType);
290
- if (tracks.length === 0) {
291
- return {
292
- toolCallId: "",
293
- success: false,
294
- output: "",
295
- error: `No ${trackType} track found. Create one first.`,
296
- };
297
- }
298
- targetTrackId = tracks[0].id;
299
- }
300
-
301
- // Create clips
302
- let currentTime = startTime;
303
- const createdClips: { id: string; sourceName: string; startTime: number; duration: number }[] = [];
304
-
305
- for (const source of sourcesToConcat) {
306
- if (!source) continue;
307
-
308
- const clip = project.addClip({
309
- sourceId: source.id,
310
- trackId: targetTrackId,
311
- startTime: currentTime,
312
- duration: source.duration,
313
- sourceStartOffset: 0,
314
- sourceEndOffset: source.duration,
315
- });
316
-
317
- createdClips.push({
318
- id: clip.id,
319
- sourceName: source.name,
320
- startTime: currentTime,
321
- duration: source.duration,
322
- });
323
-
324
- currentTime += source.duration + gap;
325
- }
326
-
327
- await writeFile(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
328
-
329
- // Build output
330
- const totalDuration = currentTime - gap - startTime;
331
- const output = [
332
- `Created ${createdClips.length} clips (total: ${totalDuration.toFixed(1)}s):`,
333
- "",
334
- ...createdClips.map((c) => ` ${c.sourceName} @ ${c.startTime.toFixed(1)}s (${c.duration.toFixed(1)}s)`),
335
- ];
336
-
337
- return {
338
- toolCallId: "",
339
- success: true,
340
- output: output.join("\n"),
341
- };
342
- } catch (error) {
343
- return {
344
- toolCallId: "",
345
- success: false,
346
- output: "",
347
- error: `Failed to concatenate: ${error instanceof Error ? error.message : String(error)}`,
348
- };
349
- }
350
- };
351
-
352
- const batchApplyEffect: ToolHandler = async (args, context): Promise<ToolResult> => {
353
- const projectPath = args.project as string;
354
- const clipIds = args.clipIds as string[] || [];
355
- const useAll = args.useAll as boolean || false;
356
- const effectType = args.effectType as EffectType;
357
- const duration = args.duration as number | undefined;
358
- const rawParams = (args.params as Record<string, unknown>) || {};
359
-
360
- try {
361
- const filePath = resolve(context.workingDirectory, projectPath);
362
- const content = await readFile(filePath, "utf-8");
363
- const data: ProjectFile = JSON.parse(content);
364
- const project = Project.fromJSON(data);
365
-
366
- // Get clips to apply effect to
367
- const targetClips = useAll
368
- ? project.getClips()
369
- : clipIds.map((id) => project.getClip(id)).filter(Boolean);
370
-
371
- if (!targetClips || targetClips.length === 0) {
372
- return {
373
- toolCallId: "",
374
- success: false,
375
- output: "",
376
- error: "No clips to apply effect to. Provide clipIds or use useAll=true.",
377
- };
378
- }
379
-
380
- // Prepare params
381
- const params: Record<string, string | number | boolean> = {};
382
- for (const [key, value] of Object.entries(rawParams)) {
383
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
384
- params[key] = value;
385
- }
386
- }
387
-
388
- // Apply effects
389
- const appliedEffects: { clipId: string; effectId: string }[] = [];
390
-
391
- for (const clip of targetClips) {
392
- if (!clip) continue;
393
-
394
- const effectDuration = duration ?? clip.duration;
395
- const effect = project.addEffect(clip.id, {
396
- type: effectType,
397
- startTime: 0,
398
- duration: effectDuration,
399
- params,
400
- });
401
-
402
- if (effect) {
403
- appliedEffects.push({ clipId: clip.id, effectId: effect.id });
404
- }
405
- }
406
-
407
- await writeFile(filePath, JSON.stringify(project.toJSON(), null, 2), "utf-8");
408
-
409
- return {
410
- toolCallId: "",
411
- success: true,
412
- output: `Applied ${effectType} effect to ${appliedEffects.length} clips`,
413
- };
414
- } catch (error) {
415
- return {
416
- toolCallId: "",
417
- success: false,
418
- output: "",
419
- error: `Failed to apply effect: ${error instanceof Error ? error.message : String(error)}`,
420
- };
421
- }
422
- };
423
-
424
- // Registration function
425
- export function registerBatchTools(registry: ToolRegistry): void {
426
- registry.register(batchImportDef, batchImport);
427
- registry.register(batchConcatDef, batchConcat);
428
- registry.register(batchApplyEffectDef, batchApplyEffect);
429
- }