@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,545 +0,0 @@
1
- /**
2
- * E2E Tests: AI Pipeline Tools with Real API Calls
3
- *
4
- * ⚠️ WARNING: These tests make REAL API calls and incur COSTS!
5
- *
6
- * To run these tests:
7
- * RUN_E2E=1 pnpm vitest run src/agent/tools/e2e.test.ts
8
- *
9
- * Required API keys (set in ~/.vibeframe/config.yaml or env):
10
- * - ANTHROPIC_API_KEY (Claude - storyboard)
11
- * - GOOGLE_API_KEY (Gemini - image, video analysis)
12
- * - OPENAI_API_KEY (Whisper - transcription)
13
- * - ELEVENLABS_API_KEY (TTS)
14
- *
15
- * Estimated costs per full run:
16
- * - ai_gemini_video: ~$0.01-0.05 (depending on video length)
17
- * - ai_storyboard: ~$0.01-0.02
18
- * - ai_image (gemini): Free tier available
19
- * - ai_tts: ~$0.01-0.05 (depending on text length)
20
- * - ai_script_to_video (images-only): ~$0.05-0.20
21
- * - ai_highlights (with Gemini): ~$0.05-0.20
22
- *
23
- * Total estimated cost: $0.10-0.50 per full run
24
- */
25
-
26
- import { describe, it, expect, beforeAll, afterAll } from "vitest";
27
- import { existsSync, mkdirSync } from "node:fs";
28
- import { resolve, join } from "node:path";
29
- import { execSync } from "node:child_process";
30
- import { ToolRegistry } from "./index.js";
31
- import { registerAITools } from "./ai.js";
32
- import type { AgentContext } from "../types.js";
33
-
34
- // Skip all tests unless RUN_E2E is set
35
- const RUN_E2E = process.env.RUN_E2E === "1" || process.env.RUN_E2E === "true";
36
-
37
- // Test output directory
38
- const TEST_OUTPUT_DIR = resolve(process.cwd(), ".e2e-test-output");
39
-
40
- // Mock context for tool execution
41
- const createContext = (subdir?: string): AgentContext => ({
42
- workingDirectory: subdir ? join(TEST_OUTPUT_DIR, subdir) : TEST_OUTPUT_DIR,
43
- projectPath: null,
44
- });
45
-
46
- // Check if required API keys are available
47
- function checkApiKey(keyName: string): boolean {
48
- // Check environment
49
- if (process.env[keyName]) return true;
50
-
51
- // Check config file
52
- try {
53
- const configPath = resolve(
54
- process.env.HOME || "~",
55
- ".vibeframe",
56
- "config.yaml"
57
- );
58
- if (existsSync(configPath)) {
59
- const content = execSync(`cat "${configPath}"`, { encoding: "utf-8" });
60
- const keyMapping: Record<string, string> = {
61
- GOOGLE_API_KEY: "google:",
62
- ANTHROPIC_API_KEY: "anthropic:",
63
- OPENAI_API_KEY: "openai:",
64
- ELEVENLABS_API_KEY: "elevenlabs:",
65
- };
66
- if (keyMapping[keyName] && content.includes(keyMapping[keyName])) {
67
- return true;
68
- }
69
- }
70
- } catch {
71
- // Ignore errors
72
- }
73
- return false;
74
- }
75
-
76
- // Print cost warning
77
- function printCostWarning() {
78
- console.log("\n");
79
- console.log("⚠️ ═══════════════════════════════════════════════════════════");
80
- console.log("⚠️ E2E TESTS - REAL API CALLS - COSTS WILL BE INCURRED");
81
- console.log("⚠️ ═══════════════════════════════════════════════════════════");
82
- console.log("⚠️ Estimated cost: $0.10-0.50 per full run");
83
- console.log("⚠️ ═══════════════════════════════════════════════════════════");
84
- console.log("\n");
85
- }
86
-
87
- describe.skipIf(!RUN_E2E)("E2E: AI Pipeline Tools", () => {
88
- let registry: ToolRegistry;
89
-
90
- beforeAll(() => {
91
- printCostWarning();
92
-
93
- // Setup registry
94
- registry = new ToolRegistry();
95
- registerAITools(registry);
96
-
97
- // Create test output directory
98
- if (!existsSync(TEST_OUTPUT_DIR)) {
99
- mkdirSync(TEST_OUTPUT_DIR, { recursive: true });
100
- }
101
-
102
- console.log(`📁 Test output directory: ${TEST_OUTPUT_DIR}`);
103
- });
104
-
105
- afterAll(() => {
106
- console.log("\n");
107
- console.log("✅ E2E tests completed");
108
- console.log(`📁 Output files saved to: ${TEST_OUTPUT_DIR}`);
109
- console.log("💡 Run 'rm -rf .e2e-test-output' to clean up");
110
- console.log("\n");
111
- });
112
-
113
- describe("analyze_video", () => {
114
- const hasKey = checkApiKey("GOOGLE_API_KEY");
115
-
116
- it.skipIf(!hasKey)(
117
- "analyzes a sample video with Gemini",
118
- async () => {
119
- console.log("\n🎬 Testing ai_gemini_video...");
120
-
121
- // Create a simple test video using FFmpeg
122
- const testVideoPath = join(TEST_OUTPUT_DIR, "test-video.mp4");
123
-
124
- if (!existsSync(testVideoPath)) {
125
- console.log(" Creating test video with FFmpeg...");
126
- try {
127
- execSync(
128
- `ffmpeg -f lavfi -i color=c=blue:s=320x240:d=3 -f lavfi -i anullsrc=r=44100:cl=stereo -t 3 -c:v libx264 -c:a aac "${testVideoPath}" -y`,
129
- { stdio: "pipe" }
130
- );
131
- } catch {
132
- console.log(" ⚠️ FFmpeg not available, skipping video creation");
133
- return;
134
- }
135
- }
136
-
137
- const handler = registry.getHandler("analyze_video");
138
- expect(handler).toBeDefined();
139
-
140
- const result = await handler!(
141
- {
142
- source: testVideoPath,
143
- prompt: "Describe what you see in this video in one sentence.",
144
- model: "flash",
145
- },
146
- createContext()
147
- );
148
-
149
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
150
- if (result.success) {
151
- console.log(` Response: ${result.output.substring(0, 100)}...`);
152
- } else {
153
- console.log(` Error: ${result.error}`);
154
- }
155
-
156
- expect(result.success).toBe(true);
157
- expect(result.output).toBeTruthy();
158
- },
159
- 60000 // 60s timeout
160
- );
161
-
162
- it.skipIf(!hasKey)(
163
- "handles YouTube URL",
164
- async () => {
165
- console.log("\n🎬 Testing ai_gemini_video with YouTube URL...");
166
-
167
- const handler = registry.getHandler("analyze_video");
168
-
169
- // Use a short, public domain video
170
- const result = await handler!(
171
- {
172
- source: "https://www.youtube.com/watch?v=jNQXAC9IVRw", // "Me at the zoo" - first YouTube video
173
- prompt: "What is shown in this video? Answer in one sentence.",
174
- model: "flash",
175
- },
176
- createContext()
177
- );
178
-
179
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
180
- if (result.success) {
181
- console.log(` Response: ${result.output.substring(0, 100)}...`);
182
- } else {
183
- console.log(` Error: ${result.error}`);
184
- }
185
-
186
- // YouTube support may vary, so we just check it doesn't crash
187
- expect(result).toBeDefined();
188
- },
189
- 120000 // 120s timeout for YouTube
190
- );
191
- });
192
-
193
- describe("generate_storyboard", () => {
194
- const hasKey = checkApiKey("ANTHROPIC_API_KEY");
195
-
196
- it.skipIf(!hasKey)(
197
- "generates storyboard from script",
198
- async () => {
199
- console.log("\n📝 Testing ai_storyboard...");
200
-
201
- const handler = registry.getHandler("generate_storyboard");
202
- expect(handler).toBeDefined();
203
-
204
- const result = await handler!(
205
- {
206
- script: "A robot learns to dance. First awkward moves, then graceful spins.",
207
- targetDuration: 10,
208
- output: "test-storyboard.json",
209
- },
210
- createContext()
211
- );
212
-
213
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
214
- if (result.success) {
215
- console.log(` Output: ${result.output.substring(0, 150)}...`);
216
- } else {
217
- console.log(` Error: ${result.error}`);
218
- }
219
-
220
- expect(result.success).toBe(true);
221
- },
222
- 60000
223
- );
224
- });
225
-
226
- describe("generate_image", () => {
227
- const hasGeminiKey = checkApiKey("GOOGLE_API_KEY");
228
-
229
- it.skipIf(!hasGeminiKey)(
230
- "generates image with Gemini",
231
- async () => {
232
- console.log("\n🖼️ Testing ai_image (Gemini)...");
233
-
234
- const handler = registry.getHandler("generate_image");
235
- expect(handler).toBeDefined();
236
-
237
- const result = await handler!(
238
- {
239
- prompt: "A simple blue square on white background",
240
- output: "test-image-gemini.png",
241
- provider: "gemini",
242
- },
243
- createContext()
244
- );
245
-
246
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
247
- if (result.success) {
248
- console.log(` Output: ${result.output}`);
249
- const imagePath = join(TEST_OUTPUT_DIR, "test-image-gemini.png");
250
- console.log(` File exists: ${existsSync(imagePath)}`);
251
- } else {
252
- console.log(` Error: ${result.error}`);
253
- }
254
-
255
- expect(result.success).toBe(true);
256
- },
257
- 60000
258
- );
259
- });
260
-
261
- describe("generate_speech", () => {
262
- const hasKey = checkApiKey("ELEVENLABS_API_KEY");
263
-
264
- it.skipIf(!hasKey)(
265
- "generates speech from text",
266
- async () => {
267
- console.log("\n🎙️ Testing ai_tts...");
268
-
269
- const handler = registry.getHandler("generate_speech");
270
- expect(handler).toBeDefined();
271
-
272
- const result = await handler!(
273
- {
274
- text: "Hello, this is a test of the text to speech system.",
275
- output: "test-tts.mp3",
276
- },
277
- createContext()
278
- );
279
-
280
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
281
- if (result.success) {
282
- console.log(` Output: ${result.output}`);
283
- const audioPath = join(TEST_OUTPUT_DIR, "test-tts.mp3");
284
- console.log(` File exists: ${existsSync(audioPath)}`);
285
- } else {
286
- console.log(` Error: ${result.error}`);
287
- }
288
-
289
- expect(result.success).toBe(true);
290
- },
291
- 30000
292
- );
293
- });
294
-
295
- describe("generate_sound_effect", () => {
296
- const hasKey = checkApiKey("ELEVENLABS_API_KEY");
297
-
298
- it.skipIf(!hasKey)(
299
- "generates sound effect",
300
- async () => {
301
- console.log("\n🔊 Testing ai_sfx...");
302
-
303
- const handler = registry.getHandler("generate_sound_effect");
304
- expect(handler).toBeDefined();
305
-
306
- const result = await handler!(
307
- {
308
- prompt: "short beep notification sound",
309
- output: "test-sfx.mp3",
310
- duration: 1,
311
- },
312
- createContext()
313
- );
314
-
315
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
316
- if (result.success) {
317
- console.log(` Output: ${result.output}`);
318
- } else {
319
- console.log(` Error: ${result.error}`);
320
- }
321
-
322
- expect(result.success).toBe(true);
323
- },
324
- 30000
325
- );
326
- });
327
-
328
- describe("pipeline_script_to_video (images-only)", () => {
329
- const hasClaudeKey = checkApiKey("ANTHROPIC_API_KEY");
330
- const hasGeminiKey = checkApiKey("GOOGLE_API_KEY");
331
- const hasTTSKey = checkApiKey("ELEVENLABS_API_KEY");
332
-
333
- it.skipIf(!hasClaudeKey || !hasGeminiKey)(
334
- "generates images from script (no video, no voiceover)",
335
- async () => {
336
- console.log("\n🎬 Testing ai_script_to_video (images-only)...");
337
- console.log(" ⚠️ This test may take 1-2 minutes");
338
-
339
- // Create subdirectory for this test
340
- const outputDir = join(TEST_OUTPUT_DIR, "script-to-video-test");
341
- if (!existsSync(outputDir)) {
342
- mkdirSync(outputDir, { recursive: true });
343
- }
344
-
345
- const handler = registry.getHandler("pipeline_script_to_video");
346
- expect(handler).toBeDefined();
347
-
348
- const result = await handler!(
349
- {
350
- script: "A sunrise over mountains. Birds flying in the sky.",
351
- outputDir: "script-to-video-test",
352
- imageProvider: "gemini",
353
- imagesOnly: true,
354
- noVoiceover: true,
355
- },
356
- createContext()
357
- );
358
-
359
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
360
- if (result.success) {
361
- console.log(` Output: ${result.output.substring(0, 200)}...`);
362
-
363
- // Check if files were created
364
- const storyboardPath = join(outputDir, "storyboard.json");
365
- console.log(` Storyboard exists: ${existsSync(storyboardPath)}`);
366
- } else {
367
- console.log(` Error: ${result.error}`);
368
- }
369
-
370
- expect(result.success).toBe(true);
371
- },
372
- 180000 // 3 minutes timeout
373
- );
374
-
375
- it.skipIf(!hasClaudeKey || !hasGeminiKey || !hasTTSKey)(
376
- "generates images with voiceover (no video)",
377
- async () => {
378
- console.log("\n🎬 Testing ai_script_to_video (images + voiceover)...");
379
- console.log(" ⚠️ This test may take 2-3 minutes");
380
-
381
- const outputDir = join(TEST_OUTPUT_DIR, "script-to-video-with-tts");
382
- if (!existsSync(outputDir)) {
383
- mkdirSync(outputDir, { recursive: true });
384
- }
385
-
386
- const handler = registry.getHandler("pipeline_script_to_video");
387
-
388
- const result = await handler!(
389
- {
390
- script: "Welcome to our demo. This is amazing technology.",
391
- outputDir: "script-to-video-with-tts",
392
- imageProvider: "gemini",
393
- imagesOnly: true,
394
- // voiceover enabled by default
395
- },
396
- createContext()
397
- );
398
-
399
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
400
- if (result.success) {
401
- console.log(` Output: ${result.output.substring(0, 200)}...`);
402
- } else {
403
- console.log(` Error: ${result.error}`);
404
- }
405
-
406
- expect(result.success).toBe(true);
407
- },
408
- 300000 // 5 minutes timeout
409
- );
410
- });
411
-
412
- describe("pipeline_highlights (with Gemini)", () => {
413
- const hasGeminiKey = checkApiKey("GOOGLE_API_KEY");
414
-
415
- it.skipIf(!hasGeminiKey)(
416
- "extracts highlights from video using Gemini",
417
- async () => {
418
- console.log("\n🎯 Testing ai_highlights (Gemini)...");
419
-
420
- // Create test video with FFmpeg
421
- const testVideoPath = join(TEST_OUTPUT_DIR, "test-highlights-video.mp4");
422
-
423
- if (!existsSync(testVideoPath)) {
424
- console.log(" Creating 10s test video with FFmpeg...");
425
- try {
426
- // Create a 10 second video with changing colors
427
- execSync(
428
- `ffmpeg -f lavfi -i "color=c=red:s=320x240:d=3,format=yuv420p[v0];` +
429
- `color=c=green:s=320x240:d=4,format=yuv420p[v1];` +
430
- `color=c=blue:s=320x240:d=3,format=yuv420p[v2];` +
431
- `[v0][v1][v2]concat=n=3:v=1:a=0" ` +
432
- `-f lavfi -i anullsrc=r=44100:cl=stereo -t 10 ` +
433
- `-c:v libx264 -c:a aac "${testVideoPath}" -y`,
434
- { stdio: "pipe" }
435
- );
436
- } catch {
437
- console.log(" ⚠️ FFmpeg not available, skipping");
438
- return;
439
- }
440
- }
441
-
442
- const handler = registry.getHandler("pipeline_highlights");
443
- expect(handler).toBeDefined();
444
-
445
- const result = await handler!(
446
- {
447
- media: testVideoPath,
448
- useGemini: true,
449
- count: 2,
450
- criteria: "all",
451
- },
452
- createContext()
453
- );
454
-
455
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
456
- if (result.success) {
457
- console.log(` Output: ${result.output.substring(0, 200)}...`);
458
- } else {
459
- console.log(` Error: ${result.error}`);
460
- }
461
-
462
- // May not find highlights in simple test video, but should not error
463
- expect(result.success).toBe(true);
464
- },
465
- 120000
466
- );
467
- });
468
-
469
- describe("pipeline_auto_shorts (analyze-only)", () => {
470
- const hasGeminiKey = checkApiKey("GOOGLE_API_KEY");
471
-
472
- it.skipIf(!hasGeminiKey)(
473
- "analyzes video for shorts (no generation)",
474
- async () => {
475
- console.log("\n📱 Testing ai_auto_shorts (analyze-only)...");
476
-
477
- const testVideoPath = join(TEST_OUTPUT_DIR, "test-highlights-video.mp4");
478
-
479
- // Reuse video from highlights test or create if needed
480
- if (!existsSync(testVideoPath)) {
481
- console.log(" Creating test video...");
482
- try {
483
- execSync(
484
- `ffmpeg -f lavfi -i color=c=blue:s=320x240:d=10 -f lavfi -i anullsrc=r=44100:cl=stereo -t 10 -c:v libx264 -c:a aac "${testVideoPath}" -y`,
485
- { stdio: "pipe" }
486
- );
487
- } catch {
488
- console.log(" ⚠️ FFmpeg not available, skipping");
489
- return;
490
- }
491
- }
492
-
493
- const handler = registry.getHandler("pipeline_auto_shorts");
494
- expect(handler).toBeDefined();
495
-
496
- const result = await handler!(
497
- {
498
- video: testVideoPath,
499
- analyzeOnly: true,
500
- useGemini: true,
501
- count: 1,
502
- },
503
- createContext()
504
- );
505
-
506
- console.log(` Result: ${result.success ? "✅" : "❌"}`);
507
- if (result.success) {
508
- console.log(` Output: ${result.output.substring(0, 200)}...`);
509
- } else {
510
- console.log(` Error: ${result.error}`);
511
- }
512
-
513
- expect(result.success).toBe(true);
514
- },
515
- 120000
516
- );
517
- });
518
- });
519
-
520
- // Summary test to show what was tested
521
- describe.skipIf(!RUN_E2E)("E2E Summary", () => {
522
- it("prints API key status", () => {
523
- console.log("\n");
524
- console.log("📊 API Key Status:");
525
- console.log("─".repeat(50));
526
-
527
- const keys = [
528
- { name: "GOOGLE_API_KEY", desc: "Gemini (image, video)" },
529
- { name: "ANTHROPIC_API_KEY", desc: "Claude (storyboard)" },
530
- { name: "OPENAI_API_KEY", desc: "Whisper (transcription)" },
531
- { name: "ELEVENLABS_API_KEY", desc: "TTS, SFX" },
532
- { name: "RUNWAY_API_SECRET", desc: "Video generation" },
533
- { name: "KLING_API_KEY", desc: "Video generation" },
534
- ];
535
-
536
- for (const key of keys) {
537
- const hasKey = checkApiKey(key.name);
538
- const status = hasKey ? "✅" : "❌";
539
- console.log(` ${status} ${key.name.padEnd(25)} - ${key.desc}`);
540
- }
541
-
542
- console.log("─".repeat(50));
543
- console.log("\n");
544
- });
545
- });