@vibeframe/cli 0.27.0 → 0.30.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 (118) 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/ai-edit-cli.d.ts.map +1 -1
  16. package/dist/commands/ai-edit-cli.js +18 -0
  17. package/dist/commands/ai-edit-cli.js.map +1 -1
  18. package/dist/commands/generate.js +14 -0
  19. package/dist/commands/generate.js.map +1 -1
  20. package/dist/commands/schema.d.ts +1 -0
  21. package/dist/commands/schema.d.ts.map +1 -1
  22. package/dist/commands/schema.js +122 -21
  23. package/dist/commands/schema.js.map +1 -1
  24. package/dist/commands/setup.js +5 -2
  25. package/dist/commands/setup.js.map +1 -1
  26. package/dist/config/schema.d.ts +2 -1
  27. package/dist/config/schema.d.ts.map +1 -1
  28. package/dist/config/schema.js +2 -0
  29. package/dist/config/schema.js.map +1 -1
  30. package/dist/index.js +0 -0
  31. package/package.json +16 -12
  32. package/.turbo/turbo-build.log +0 -4
  33. package/.turbo/turbo-lint.log +0 -21
  34. package/.turbo/turbo-test.log +0 -689
  35. package/src/agent/adapters/claude.ts +0 -143
  36. package/src/agent/adapters/gemini.ts +0 -159
  37. package/src/agent/adapters/index.ts +0 -61
  38. package/src/agent/adapters/ollama.ts +0 -231
  39. package/src/agent/adapters/openai.ts +0 -116
  40. package/src/agent/adapters/xai.ts +0 -119
  41. package/src/agent/index.ts +0 -251
  42. package/src/agent/memory/index.ts +0 -151
  43. package/src/agent/prompts/system.ts +0 -106
  44. package/src/agent/tools/ai-editing.ts +0 -845
  45. package/src/agent/tools/ai-generation.ts +0 -1073
  46. package/src/agent/tools/ai-pipeline.ts +0 -1055
  47. package/src/agent/tools/ai.ts +0 -21
  48. package/src/agent/tools/batch.ts +0 -429
  49. package/src/agent/tools/e2e.test.ts +0 -545
  50. package/src/agent/tools/export.ts +0 -184
  51. package/src/agent/tools/filesystem.ts +0 -237
  52. package/src/agent/tools/index.ts +0 -150
  53. package/src/agent/tools/integration.test.ts +0 -775
  54. package/src/agent/tools/media.ts +0 -697
  55. package/src/agent/tools/project.ts +0 -313
  56. package/src/agent/tools/timeline.ts +0 -951
  57. package/src/agent/types.ts +0 -68
  58. package/src/commands/agent.ts +0 -340
  59. package/src/commands/ai-analyze.ts +0 -429
  60. package/src/commands/ai-animated-caption.ts +0 -390
  61. package/src/commands/ai-audio.ts +0 -941
  62. package/src/commands/ai-broll.ts +0 -490
  63. package/src/commands/ai-edit-cli.ts +0 -658
  64. package/src/commands/ai-edit.ts +0 -1542
  65. package/src/commands/ai-fill-gaps.ts +0 -566
  66. package/src/commands/ai-helpers.ts +0 -65
  67. package/src/commands/ai-highlights.ts +0 -1303
  68. package/src/commands/ai-image.ts +0 -761
  69. package/src/commands/ai-motion.ts +0 -347
  70. package/src/commands/ai-narrate.ts +0 -451
  71. package/src/commands/ai-review.ts +0 -309
  72. package/src/commands/ai-script-pipeline-cli.ts +0 -1710
  73. package/src/commands/ai-script-pipeline.ts +0 -1365
  74. package/src/commands/ai-suggest-edit.ts +0 -264
  75. package/src/commands/ai-video-fx.ts +0 -445
  76. package/src/commands/ai-video.ts +0 -915
  77. package/src/commands/ai-viral.ts +0 -595
  78. package/src/commands/ai-visual-fx.ts +0 -601
  79. package/src/commands/ai.test.ts +0 -627
  80. package/src/commands/ai.ts +0 -307
  81. package/src/commands/analyze.ts +0 -282
  82. package/src/commands/audio.ts +0 -644
  83. package/src/commands/batch.test.ts +0 -279
  84. package/src/commands/batch.ts +0 -440
  85. package/src/commands/detect.ts +0 -329
  86. package/src/commands/doctor.ts +0 -237
  87. package/src/commands/edit-cmd.ts +0 -1014
  88. package/src/commands/export.ts +0 -918
  89. package/src/commands/generate.ts +0 -2146
  90. package/src/commands/media.ts +0 -177
  91. package/src/commands/output.ts +0 -142
  92. package/src/commands/pipeline.ts +0 -398
  93. package/src/commands/project.test.ts +0 -127
  94. package/src/commands/project.ts +0 -149
  95. package/src/commands/sanitize.ts +0 -60
  96. package/src/commands/schema.ts +0 -130
  97. package/src/commands/setup.ts +0 -509
  98. package/src/commands/timeline.test.ts +0 -499
  99. package/src/commands/timeline.ts +0 -529
  100. package/src/commands/validate.ts +0 -77
  101. package/src/config/config.test.ts +0 -197
  102. package/src/config/index.ts +0 -125
  103. package/src/config/schema.ts +0 -82
  104. package/src/engine/index.ts +0 -2
  105. package/src/engine/project.test.ts +0 -702
  106. package/src/engine/project.ts +0 -439
  107. package/src/index.ts +0 -146
  108. package/src/utils/api-key.test.ts +0 -41
  109. package/src/utils/api-key.ts +0 -247
  110. package/src/utils/audio.ts +0 -83
  111. package/src/utils/exec-safe.ts +0 -75
  112. package/src/utils/first-run.ts +0 -52
  113. package/src/utils/provider-resolver.ts +0 -56
  114. package/src/utils/remotion.ts +0 -951
  115. package/src/utils/subtitle.test.ts +0 -227
  116. package/src/utils/subtitle.ts +0 -169
  117. package/src/utils/tty.ts +0 -196
  118. 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
- }