@amg555/frameforge-mcp 2.3.1 → 2.3.3

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 (52) hide show
  1. package/.mcp.json +2 -4
  2. package/CHANGELOG.md +20 -1
  3. package/CLAUDE.md +154 -18
  4. package/README.md +16 -12
  5. package/SECURITY.md +1 -3
  6. package/install.sh +1 -1
  7. package/package.json +7 -3
  8. package/plugins/video-pipeline/.claude-plugin/plugin.json +19 -0
  9. package/plugins/video-pipeline/skills/html-renderer/SKILL.md +292 -0
  10. package/plugins/video-pipeline/skills/video-pipeline/SKILL.md +308 -0
  11. package/plugins/video-pipeline/skills/video-pipeline/assets/project/ANIMATION_GUIDE.md +257 -0
  12. package/plugins/video-pipeline/skills/video-pipeline/assets/project/STORYBOARD.md +77 -0
  13. package/plugins/video-pipeline/skills/video-pipeline/assets/project/index.html +80 -0
  14. package/plugins/video-pipeline/skills/video-pipeline/assets/project/pipeline/briefings/diagram-author.md +43 -0
  15. package/plugins/video-pipeline/skills/video-pipeline/assets/project/pipeline/briefings/orchestrator.md +56 -0
  16. package/plugins/video-pipeline/skills/video-pipeline/assets/project/pipeline/briefings/scene-author.md +42 -0
  17. package/plugins/video-pipeline/skills/video-pipeline/assets/project/reel/engine.css +140 -0
  18. package/plugins/video-pipeline/skills/video-pipeline/assets/project/reel/engine.js +870 -0
  19. package/plugins/video-pipeline/skills/video-pipeline/assets/project/reel/virtual-clock.js +138 -0
  20. package/plugins/video-pipeline/skills/video-pipeline/references/mcp-tools.md +167 -0
  21. package/plugins/video-pipeline/skills/video-pipeline/references/providers.md +163 -0
  22. package/scripts/db-migrate.js +112 -0
  23. package/scripts/deep-validate.js +326 -0
  24. package/scripts/generate-initial-assets.js +342 -0
  25. package/scripts/html-renderer/new-project.mjs +408 -0
  26. package/scripts/html-renderer/transcribe.py +294 -0
  27. package/src/asset-library/README.md +2 -2
  28. package/src/asset-library/asset-library.js +1 -1
  29. package/src/cli/doctor.js +31 -1
  30. package/src/cli/make.js +52 -71
  31. package/src/cli/setup-keys.js +24 -19
  32. package/src/fact-checker/review-gate.js +5 -1
  33. package/src/harness/bin/harness.mjs +324 -0
  34. package/src/harness/lib/browser.mjs +137 -0
  35. package/src/harness/lib/capture.mjs +161 -0
  36. package/src/harness/lib/encode.mjs +89 -0
  37. package/src/harness/lib/jobs.mjs +135 -0
  38. package/src/harness/lib/pixels.mjs +137 -0
  39. package/src/harness/lib/sheets.mjs +164 -0
  40. package/src/harness/lib/verify-purity.mjs +119 -0
  41. package/src/harness/test/fixtures/broken-scene.html +27 -0
  42. package/src/harness/test/fixtures/reference-scene.html +23 -0
  43. package/src/harness/test/fixtures/sample-script.json +18 -0
  44. package/src/mcp-server/server.js +318 -66
  45. package/src/pipeline/external-adapter.js +55 -15
  46. package/src/pipeline/providers.js +46 -0
  47. package/src/pipeline/telemetry.js +1 -0
  48. package/src/utils/log-redaction.js +5 -3
  49. package/src/video-renderer/renderer.js +12 -4
  50. package/src/worker/server-render-free.js +2 -3
  51. package/src/workflows/assets.js +20 -43
  52. package/src/workflows/ingest.js +5 -5
package/.mcp.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "remote": "CLOUDFLARE REMOTE MCP: Connects via edge URL. Saves ~80% prompt context tokens in your IDE."
7
7
  },
8
8
  "_paths": {
9
- "agent-first": "Path 1 — your IDE writes scenes, FrameForge renders. Only TTS + image keys needed. No LLM key.",
9
+ "agent-first": "Path 1 — your IDE writes scenes, FrameForge renders with code-driven animations & user media. Only TTS needed. No LLM key.",
10
10
  "auto-research": "Path 2 — FrameForge researches and scripts autonomously. Requires PROVIDER_LLM + its key."
11
11
  },
12
12
 
@@ -17,8 +17,7 @@
17
17
  "command": "node",
18
18
  "args": ["src/mcp-server/stdio.js"],
19
19
  "env": {
20
- "PROVIDER_TTS": "edge-tts",
21
- "PROVIDER_IMAGE": "pollinations"
20
+ "PROVIDER_TTS": "edge-tts"
22
21
  }
23
22
  },
24
23
 
@@ -28,7 +27,6 @@
28
27
  "args": ["src/mcp-server/server.js"],
29
28
  "env": {
30
29
  "PROVIDER_TTS": "edge-tts",
31
- "PROVIDER_IMAGE": "pollinations",
32
30
  "MCP_PORT": "3210"
33
31
  }
34
32
  },
package/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@ All notable changes to FrameForge are documented here.
4
4
 
5
5
  ---
6
6
 
7
+ ## [2.3.2] — 2026-11-06
8
+
9
+ ### Added
10
+
11
+ - **Tool 18: `export_to_editor`** — send a finished animation MP4 + EDL to any local editing app via an HTTP bridge: Premiere Pro (`:7777`), DaVinci Resolve (`:8080`), CapCut (`:9090`), After Effects (`:7878`), or Remotion (`:3001`). Pass `editorUrl` to override any port. Bridge setup docs: `docs/editor-bridges/`.
12
+ - **VoxForge TTS provider** (`PROVIDER_TTS=voxforge`) — named first-class provider in `TTSProvider`. Tries `/v1/audio/speech` (OpenAI-compatible) then falls back to `/v1/tts`. Configured via `VOXFORGE_URL`, `VOXFORGE_KEY`, `VOXFORGE_VOICE`, `VOXFORGE_MODEL`. Also surfaced in `multi_voice_tts` platform enum and `setup-keys.js` wizard.
13
+ - **Editing app presets in `ExternalAdapter`** — `premiere`, `resolve`, `capcut`, `aftereffects` (local bridge), `kling` (cloud), plus updated `voxforge` preset pointing to `/v1/audio/speech`.
14
+ - **`render_animation` mode `"kit"`** — now exposed in the MCP tool enum. Generates an EDL file in `out/` for import into Premiere / Resolve.
15
+
16
+ ### Changed
17
+
18
+ - **`CLAUDE.md`**: code-driven animation promoted to **primary path**; FFmpeg + AI images demoted to "quick draft"; new sections for VoxForge voice and editor bridge workflow; tool table reorganised into Primary / Secondary / Auto-research groups (18 tools).
19
+ - **`START_HERE.md`**: opening question set updated to surface animated explainer as a first-class format choice.
20
+ - **`setup-keys.js`**: VoxForge added to TTS provider menu (second option, right after edge-tts). Four new config keys persisted: `VOXFORGE_URL`, `VOXFORGE_KEY`, `VOXFORGE_VOICE`, `VOXFORGE_MODEL`.
21
+ - **`scripts/deep-validate.js`**: +3 checks (`export_to_editor`, `voxforge`, tool count label updated to 18).
22
+ - Version bump: `2.3.1` → `2.3.2` across all version strings.
23
+
24
+ ---
25
+
7
26
  ## [2.3.1] — 2026-11-04
8
27
 
9
28
  ### Added
@@ -32,7 +51,7 @@ All notable changes to FrameForge are documented here.
32
51
  - `scripts/verify.py` — 7-gate quality verification (same gates as `QualityGate`)
33
52
  - `scripts/transcribe.py` — Whisper word-level caption outline generator (`openai-whisper`, free local)
34
53
  - `scripts/capture.mjs` — headless Playwright screenshot for b-roll (site, tweet, URL)
35
- - `scripts/stock.py` — Pexels stock footage/image downloader (free API key); Pollinations fallback for images
54
+ - `scripts/stock.py` — Pexels stock footage/image downloader (free API key) with user media asset stubs
36
55
  - `scripts/html-renderer/new-project.mjs` updated: copies real engine files instead of writing stubs; includes all 8 scripts
37
56
  - **Tool 14: `get_job_status`** — MCP tool to poll a job queued by `queue_full_pipeline`. Returns `{ status, stage, result, error }`. Added to `src/mcp-server/server.js`; automatically available on stdio transport. 5 new tests.
38
57
  - **Cloudflare KV rate limiter** — sliding-window 100 req/hr per bearer token. SHA-256-hashed key stored in `RATE_LIMITS` KV namespace. Returns HTTP 429 + `Retry-After` when exceeded. KV binding documented in `cloudflare-mcp/wrangler.toml`. Rate-limiting skipped when KV not bound (local dev).
package/CLAUDE.md CHANGED
@@ -50,7 +50,7 @@ If you're not sure what a tool does — call it with the obvious parameters. The
50
50
 
51
51
  1. **Never write driver/helper scripts** to work around a tool's missing parameter. If you think a parameter is missing, check the tool schema again — it's probably there (`voice`, `language`, `orientation`, `parallelism`, `skipImages`, `skipTts`).
52
52
  2. **Never write a v2 or v3 of a script.** If the first approach fails, report the error and ask the user what to do.
53
- 3. **Never retry a provider failure yourself.** The pipeline has retry logic built in. If Pollinations rate-limits: report it, suggest `PROVIDER_IMAGE=falai`, and stop.
53
+ 3. **Never retry a provider failure yourself.** The pipeline has retry logic built in. If a provider fails: report it and stop.
54
54
  4. **Never restart the MCP server.** The server picks up env from its launch context. If a voice or provider needs to change, set the right parameter in the tool call — `voice`, `language`, `parallelism`.
55
55
  5. **One tool call, then wait for the result.** Do not queue multiple tool calls before seeing what the first one returned.
56
56
 
@@ -58,9 +58,11 @@ If you're not sure what a tool does — call it with the obvious parameters. The
58
58
 
59
59
  ## THREE PATHS — PICK ONE
60
60
 
61
- ### Path 1 — You write the scenes (default, no LLM key needed)
61
+ > **The primary path is Path 2 (code-driven animation).** Every frame is a pure function of time `t`, rendered by Playwright + FFmpeg. This is what produces the high-quality, viral-style motion graphics clips. Path 1 (FFmpeg + AI images) is the fast fallback when Playwright is unavailable or the user wants a quick draft. Path 3 (auto-research) is for unattended batch.
62
62
 
63
- Your IDE model writes the scenes. FrameForge generates TTS + AI images + renders with FFmpeg.
63
+ ### Path 1 — You write the scenes (code animation & user media)
64
+
65
+ Your IDE model writes the scenes. FrameForge synthesizes TTS, binds user media (`image_path` / `video_path`) or procedural kinetic typography, and renders with FFmpeg.
64
66
 
65
67
  ```
66
68
  create_video_from_script({
@@ -68,15 +70,16 @@ create_video_from_script({
68
70
  {
69
71
  narration: "Text spoken aloud by the voice.",
70
72
  caption: "OVERLAY TEXT", // max 40 chars, burned into video
71
- visual_description: "image prompt for AI" // be specific and descriptive
73
+ visual_description: "concept description", // used for card styling
74
+ image_path: "assets/photo.jpg", // optional: user manual image
75
+ video_path: "assets/clip.mp4" // optional: user manual video clip
72
76
  }
73
77
  ],
74
78
  title: "My Video",
75
79
  orientation: "landscape", // "landscape" (1920×1080) or "portrait" (1080×1920 for Shorts/Reels)
76
80
  voice: "ml-IN-MidhunNeural", // optional: any edge-tts voice ID (auto-selected from language if omitted)
77
81
  language: "ml", // optional: BCP-47 code — auto-selects voice (ml, hi, ta, te, zh, ja, ...)
78
- imageStyle: "flat design, white background, bold primary colors",
79
- parallelism: 1, // keep at 1 for Pollinations; raise to 4 only with falai/replicate
82
+ parallelism: 1,
80
83
  withMusic: true
81
84
  })
82
85
  ```
@@ -88,13 +91,13 @@ Output files appear in `.frameforge-files/`:
88
91
  - `short_1_<id>.mp4` — auto-extracted vertical Short
89
92
  - `video_meta.json` — title, description, tags
90
93
 
91
- > **No API keys needed.** `edge-tts` (voice) and `pollinations` (images) are both free. If Pollinations is slow, tell the user to set `PROVIDER_IMAGE=falai` in `.env`.
94
+ > **No API keys needed.** `edge-tts` (voice) runs offline and visual cards render procedurally with FFmpeg/Playwright. 100% deterministic, zero diffusion artifacts.
92
95
 
93
96
  ---
94
97
 
95
98
  ### Path 2 — Code-driven animated video (Playwright + FFmpeg, no AI images)
96
99
 
97
- Use this when: the user wants motion graphics, Pollinations is unavailable, or they ask for "animated", "code-rendered", "explainer", "reel", or "YouTube-style" video. Every frame is a pure function of time `t`.
100
+ Use this when: the user wants motion graphics, explainer, reel, or YouTube-style video. Every frame is a pure function of time `t`.
98
101
 
99
102
  > **Iron rule:** Never use `Math.random()`, `Date.now()`, `setTimeout`, or module-level mutable state in scene code. Use `hash(i)` from `reel/engine.js` for deterministic randomness.
100
103
 
@@ -207,9 +210,20 @@ get_job_status({ jobId }) // poll every 30s until status = "SUCCEEDED"
207
210
 
208
211
  ---
209
212
 
210
- ## ALL 17 MCP TOOLS
213
+ ## ALL 18 MCP TOOLS
211
214
 
212
- **No LLM key needed:**
215
+ **Primary — code-driven animation (no LLM key, no image gen API):**
216
+
217
+ | Tool | What it does |
218
+ |------|-------------|
219
+ | `scaffold_animation_project` | Scaffold a Playwright + FFmpeg animation project (engine, render scripts, STORYBOARD.md) |
220
+ | `validate_storyboard` | Enforce the 4 hard gates before any scene code |
221
+ | `render_animation` | Playwright renderer: `sheet` / `strip` / `storyboard` / `crop` / `full` / `mux` / `kit` / `look` |
222
+ | `multi_voice_tts` | TTS per-call: `edge-tts` · `elevenlabs` · `voxforge` · `azure` · `openai` · `webhook` |
223
+ | `export_to_editor` | Send finished animation to Premiere / Resolve / CapCut / After Effects / Remotion |
224
+ | `external_platform_call` | HTTP bridge to **any** app — pass `platformUrl` directly, no env setup needed |
225
+
226
+ **Secondary — FFmpeg + AI images (fast draft, no Playwright needed):**
213
227
 
214
228
  | Tool | What it does |
215
229
  |------|-------------|
@@ -219,15 +233,10 @@ get_job_status({ jobId }) // poll every 30s until status = "SUCCEEDED"
219
233
  | `edit_scenes` | Patch captions, swap media files, append scenes |
220
234
  | `assemble_video` | FFmpeg render + quality gate → master MP4 |
221
235
  | `render_tts` | Generate voice audio for one scene |
222
- | `multi_voice_tts` | Override TTS provider per call without touching `.env` |
223
236
  | `generate_scene_image` | Generate one scene image |
224
237
  | `publish_video` | Deliver via file copy or HTTP webhook |
225
- | `external_platform_call` | HTTP bridge to ElevenLabs, Runway, Replicate, etc. |
226
- | `scaffold_animation_project` | Create a code-driven animation project |
227
- | `validate_storyboard` | Check STORYBOARD.md against the 4-gate contract |
228
- | `render_animation` | Playwright renderer: sheet / strip / storyboard / crop / full / look |
229
238
 
230
- **Needs a free LLM key:**
239
+ **Auto-research (needs a free LLM key):**
231
240
 
232
241
  | Tool | What it does |
233
242
  |------|-------------|
@@ -238,6 +247,133 @@ get_job_status({ jobId }) // poll every 30s until status = "SUCCEEDED"
238
247
 
239
248
  ---
240
249
 
250
+ ## VOICE — VoxForge custom audio
251
+
252
+ `multi_voice_tts` with `platform: "voxforge"` routes to your VoxForge instance:
253
+
254
+ ```
255
+ multi_voice_tts({
256
+ text: "Your narration.",
257
+ outputPath: ".frameforge-files/voice_0.m4a",
258
+ platform: "voxforge",
259
+ voice: "my-cloned-voice-id", // speaker ID from VoxForge
260
+ apiKey: "vf-..." // or set VOXFORGE_KEY in .env
261
+ })
262
+ ```
263
+
264
+ Set in `.env` for all calls:
265
+ ```
266
+ PROVIDER_TTS=voxforge
267
+ VOXFORGE_URL=https://api.voxforge.io # or your self-hosted URL
268
+ VOXFORGE_KEY=vf-...
269
+ VOXFORGE_VOICE=my-cloned-voice-id
270
+ ```
271
+
272
+ ---
273
+
274
+ ## CUSTOM APP MCP — connect any app instantly
275
+
276
+ `external_platform_call` connects to any HTTP app **without touching `.env`** — pass `platformUrl` directly:
277
+
278
+ ```
279
+ // Connect any custom app or MCP-enabled tool right now
280
+ external_platform_call({
281
+ action: "ingest",
282
+ platformUrl: "http://localhost:8080", // your app's base URL
283
+ platformKey: "optional-api-key", // omit if no auth
284
+ files: [".frameforge-files/final.mp4"]
285
+ })
286
+
287
+ // Drive editing operations in your custom app
288
+ external_platform_call({
289
+ action: "edit",
290
+ platformUrl: "http://localhost:8080",
291
+ operations: [
292
+ { op: "cut", at: 4.5 },
293
+ { op: "color", clip: 0, lut: "/luts/film.cube" },
294
+ { op: "caption", at: 2.0, duration: 3.0, text: "Intro", position: "bottom" },
295
+ { op: "transition", between: [0, 1], type: "dissolve", duration: 0.5 }
296
+ ]
297
+ })
298
+
299
+ // Use a named preset (auto-fills default paths for known apps)
300
+ external_platform_call({
301
+ action: "render",
302
+ platformName: "resolve", // premiere | resolve | runway | voxforge | capcut | ...
303
+ metadata: { exportPath: "/exports/final.mp4" }
304
+ })
305
+ ```
306
+
307
+ **Your app only needs to accept POST JSON.** FrameForge sends:
308
+ - `ingest` → `multipart/form-data` with the files
309
+ - `edit` → `{ operations: [...], source: "frameforge" }`
310
+ - `render` → `{ scenes: [...], productionId: "...", ...metadata }`
311
+ - `status` → `GET /<statusPath>/<jobId>`
312
+
313
+ ---
314
+
315
+ ## EDITOR BRIDGES — import and edit in external apps
316
+
317
+ `export_to_editor` supports four actions: **import**, **edit**, **render**, **status**.
318
+
319
+ ### Import a finished animation
320
+
321
+ ```
322
+ // Auto-generates EDL and imports MP4 + EDL into DaVinci Resolve
323
+ export_to_editor({ editor: "resolve", action: "import", projectDir: ".frameforge-files/my-anim/" })
324
+
325
+ // Premiere Pro (requires CEP companion server)
326
+ export_to_editor({ editor: "premiere", action: "import", projectDir: "..." })
327
+
328
+ // Explicit video path (no projectDir needed)
329
+ export_to_editor({ editor: "resolve", action: "import", videoPath: "/path/to/output.mp4" })
330
+ ```
331
+
332
+ ### Apply editing operations
333
+
334
+ ```
335
+ export_to_editor({
336
+ editor: "resolve",
337
+ action: "edit",
338
+ timelineName: "MyFilm",
339
+ operations: [
340
+ { op: "cut", at: 4.5 },
341
+ { op: "transition", between: [0, 1], type: "dissolve", duration: 0.5 },
342
+ { op: "color", clip: 0, lut: "/path/to/film.cube" },
343
+ { op: "caption", at: 2.0, duration: 3.0, text: "Chapter 1", position: "bottom" },
344
+ { op: "trim", clip: 1, startDelta: 0.3 },
345
+ { op: "speed", clip: 2, factor: 0.5 },
346
+ { op: "mute", clip: 3 },
347
+ { op: "swap", clip: 0, newPath: "/new/take.mp4" }
348
+ ]
349
+ })
350
+ ```
351
+
352
+ ### Trigger the editor's own render/export
353
+
354
+ ```
355
+ export_to_editor({ editor: "resolve", action: "render", exportPath: "/exports/final.mp4" })
356
+ // → returns { jobId }
357
+
358
+ export_to_editor({ editor: "resolve", action: "status", jobId: "..." })
359
+ // → returns { status, outputUrl }
360
+ ```
361
+
362
+ ### What's supported per editor
363
+
364
+ | Editor | import | edit ops | render | Notes |
365
+ |--------|--------|----------|--------|-------|
366
+ | `resolve` | ✅ | ✅ | ✅ | Built-in REST API (Resolve 18.6+). Enable in Preferences → System → General → "IP Remote Control". No bridge install needed. |
367
+ | `premiere` | ✅ | ✅ | ✅ | Requires CEP companion panel. See `docs/editor-bridges/premiere.md`. |
368
+ | `aftereffects` | ✅ | ✅ | ✅ | Requires AE REST bridge. See `docs/editor-bridges/aftereffects.md`. |
369
+ | `remotion` | ✅ | ✅ | ✅ | Remotion is code — operations patch composition props + trigger CLI render. No bridge. |
370
+ | `capcut` | ✅ | ❌ | ✅ | No public desktop edit API. Import + export only. |
371
+ | `custom` | ✅ | ✅ | ✅ | You define what the endpoint handles. |
372
+
373
+ **Override ports:** `RESOLVE_BRIDGE_URL`, `PREMIERE_BRIDGE_URL`, `CAPCUT_BRIDGE_URL`, `AE_BRIDGE_URL`
374
+
375
+ ---
376
+
241
377
  ## SCENE FIELDS
242
378
 
243
379
  | Field | Required | Notes |
@@ -300,9 +436,9 @@ Supply any of these per scene — FrameForge only generates what you don't suppl
300
436
  **`create_video_from_script` returns `passed: false`:** Check `qcReport.checks` for the failed gate:
301
437
  - `resolution`: an `image_path` file has wrong dimensions — use `visual_description` instead
302
438
  - `no_audio`: TTS failed — check `edge-tts` is installed
303
- - `black_frames`: image generation failed for a scene — tell user about Pollinations and suggest `PROVIDER_IMAGE=falai`
439
+ - `black_frames`: visual asset invalid — verify image_path / video_path file paths or use default code-driven visual cards
304
440
 
305
- **Image generation fails silently:** FrameForge falls back to a dark background automatically. The video still renders.
441
+ **Visual fallback:** FrameForge renders crisp code-driven animated cards automatically when no manual media is supplied. The video always renders cleanly.
306
442
 
307
443
  **Any other tool error:** Report the exact error message to the user. Do not attempt to fix it by editing source files.
308
444
 
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  [![npm](https://img.shields.io/npm/v/@amg555/frameforge-mcp.svg?label=npm)](https://www.npmjs.com/package/@amg555/frameforge-mcp)
10
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
11
11
  [![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org/)
12
- [![Version](https://img.shields.io/badge/version-2.3.1-blue.svg)](CHANGELOG.md)
12
+ [![Version](https://img.shields.io/badge/version-2.3.3-blue.svg)](CHANGELOG.md)
13
13
  [![MCP Spec](https://img.shields.io/badge/MCP-2024--11--05-blue.svg)](https://modelcontextprotocol.io/)
14
14
  [![Tests](https://img.shields.io/badge/tests-512%20passing-brightgreen.svg)](#testing)
15
15
 
@@ -135,7 +135,7 @@ short_1_<id>.mp4 → auto-extracted 9:16 vertical Short
135
135
  video_meta.json → title, description, tags, chapters
136
136
  ```
137
137
 
138
- **No API keys required for this path.** `edge-tts` (voice) and `pollinations` (images) are both free with no account. If Pollinations is slow, add `FALAI_API_KEY` and set `PROVIDER_IMAGE=falai`.
138
+ **No API keys required for this path.** `edge-tts` (voice) runs offline and visual cards render procedurally via FFmpeg/Playwright. 100% deterministic, zero diffusion flaws.
139
139
 
140
140
  ---
141
141
 
@@ -143,7 +143,7 @@ video_meta.json → title, description, tags, chapters
143
143
 
144
144
  ### Your IDE writes the script — no LLM key needed
145
145
 
146
- Your IDE's model writes the scenes. FrameForge only runs FFmpeg, TTS, and image generation. Use `create_video_from_script`. This is the fastest path and what most people want.
146
+ Your IDE's model writes the scenes. FrameForge runs FFmpeg, TTS, and code-driven kinetic animations or user media. Use `create_video_from_script`. This is the fastest path and what most people want.
147
147
 
148
148
  ### FrameForge researches and scripts itself
149
149
 
@@ -226,17 +226,21 @@ Switch any provider with one `.env` change — no code changes.
226
226
 
227
227
  Set `PROVIDER_TTS=<name>`.
228
228
 
229
- **Images**
229
+ **Visuals & Media**
230
230
 
231
- | Provider | Free? | Key needed |
232
- |----------|-------|------------|
233
- | `pollinations` | ✅ free, no account | none — **default** |
234
- | `falai` | ✅ free tier | `FALAI_API_KEY` at fal.ai |
235
- | `replicate` | paid | `REPLICATE_API_KEY` |
236
- | `dalle` | paid | `OPENAI_API_KEY` |
237
- | `webhook` | — | `WEBHOOK_IMAGE_URL` |
231
+ FrameForge is **code-driven first**: scenes render via crisp vector animations, kinetic typography, and user-provided media (clips, b-roll, photos) — zero diffusion artifacts, zero AI slop, 100% deterministic.
232
+
233
+ | Visual Mode / Provider | Type | Key needed |
234
+ |------------------------|------|------------|
235
+ | `code-driven` | **Default** — kinetic cards, typography, spring motion | none — **recommended default** |
236
+ | `user-media` | User-supplied `image_path` or `video_path` in scene | none |
237
+ | `pollinations` | Optional AI diffusion (opt-in via `--ai-images`) | none |
238
+ | `falai` | Optional AI diffusion (fast FLUX) | `FALAI_API_KEY` at fal.ai |
239
+ | `replicate` | Optional AI diffusion (FLUX-schnell) | `REPLICATE_API_KEY` |
240
+ | `dalle` | Optional AI diffusion (DALL-E 3) | `OPENAI_API_KEY` |
241
+ | `webhook` | Custom image/video generation endpoint | `WEBHOOK_IMAGE_URL` |
238
242
 
239
- Set `PROVIDER_IMAGE=<name>`.
243
+ Set `ENABLE_AI_IMAGES=true` or pass `--ai-images` only if you explicitly want AI diffusion images. Default is clean code-driven animation.
240
244
 
241
245
  **LLM — only for the auto-research path**
242
246
 
package/SECURITY.md CHANGED
@@ -49,7 +49,7 @@ prefer to remain anonymous.
49
49
 
50
50
  ### Network
51
51
  - FFmpeg calls use `-nostdin` to prevent interactive prompts from blocking.
52
- - All outbound HTTP calls (Pollinations, search APIs, webhook endpoints) use
52
+ - All outbound HTTP calls (search APIs, webhook endpoints) use
53
53
  Node.js `https` with explicit timeouts and no silent redirects beyond 5 hops.
54
54
 
55
55
  ### Cloudflare Workers
@@ -64,8 +64,6 @@ prefer to remain anonymous.
64
64
  - The LLM fallback in `FactChecker._querySources()` produces synthesized
65
65
  sources when no `SEARCH_API_KEY` is set. These are not real citations and
66
66
  should not be presented as authoritative without a real search provider.
67
- - Pollinations.ai image requests are unauthenticated — do not include
68
- private or sensitive content in image prompts.
69
67
  - `PUBLISH_WEBHOOK_URL` and `REVIEW_NOTIFY_URL` receivers are trusted
70
68
  endpoints; ensure they are authenticated on your side before deploying
71
69
  to production.
package/install.sh CHANGED
@@ -50,7 +50,7 @@ done
50
50
  if command -v edge-tts >/dev/null 2>&1; then
51
51
  echo " edge-tts $(command -v edge-tts) (free TTS, no key)"
52
52
  else
53
- echo " edge-tts not found — run: npm install -g edge-tts"
53
+ echo " edge-tts not found — run: pip install edge-tts"
54
54
  fi
55
55
 
56
56
  echo
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amg555/frameforge-mcp",
3
- "version": "2.3.1",
3
+ "version": "2.3.3",
4
4
  "description": "FrameForge — AI video production engine for agentic IDEs. npx @amg555/frameforge-mcp. FFmpeg + TTS run on your machine. 17 MCP tools.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -10,10 +10,14 @@
10
10
  "frameforge": "src/cli/make.js",
11
11
  "frameforge-mcp": "src/mcp-server/stdio.js",
12
12
  "frameforge-setup": "src/cli/setup-keys.js",
13
- "frameforge-doctor": "src/cli/doctor.js"
13
+ "frameforge-doctor": "src/cli/doctor.js",
14
+ "frameforge-harness": "src/harness/bin/harness.mjs"
14
15
  },
15
16
  "scripts": {
16
17
  "make": "node src/cli/make.js",
18
+ "harness": "node src/harness/bin/harness.mjs",
19
+ "harness:doctor": "node src/harness/bin/harness.mjs doctor",
20
+ "harness:verify": "node src/harness/bin/harness.mjs verify",
17
21
  "setup": "node src/cli/setup-keys.js",
18
22
  "setup:check": "node src/cli/setup-keys.js --check",
19
23
  "doctor": "node src/cli/doctor.js",
@@ -26,7 +30,7 @@
26
30
  "start:local-render": "cross-env RENDER_MODE=full WORKER_PORT=3211 node src/worker/server-render-free.js",
27
31
  "db:migrate": "node scripts/db-migrate.js",
28
32
  "validate": "node scripts/deep-validate.js",
29
- "test": "node --test src/pipeline/retry-policy.test.js src/pipeline/telemetry.test.js src/pipeline/artifact-manifest.test.js src/pipeline/artifact-retention.test.js src/pipeline/external-adapter.test.js src/workflows/publishing.test.js src/workflows/script.test.js src/animation/animation-system.test.js src/fact-checker/review-gate.test.js src/fact-checker/checker.test.js src/utils/log-redaction.test.js src/worker/server-render-free.test.js src/worker/server.test.js src/mcp-server/server.test.js src/quality-gate/gate.test.js src/shorts-extractor/extractor.test.js src/audio-mixer/mixer.test.js src/video-renderer/renderer.test.js plugins/video-pipeline/skills/video-pipeline/assets/project/reel/engine.test.js src/integration.test.js",
33
+ "test": "node --test src/pipeline/retry-policy.test.js src/pipeline/telemetry.test.js src/pipeline/artifact-manifest.test.js src/pipeline/artifact-retention.test.js src/pipeline/external-adapter.test.js src/workflows/publishing.test.js src/workflows/script.test.js src/animation/animation-system.test.js src/fact-checker/review-gate.test.js src/fact-checker/checker.test.js src/utils/log-redaction.test.js src/worker/server-render-free.test.js src/worker/server.test.js src/mcp-server/server.test.js src/quality-gate/gate.test.js src/shorts-extractor/extractor.test.js src/audio-mixer/mixer.test.js src/video-renderer/renderer.test.js plugins/video-pipeline/skills/video-pipeline/assets/project/reel/engine.test.js src/harness/lib/pixels.test.js src/harness/lib/verify-purity.test.js src/harness/harness.test.js src/integration.test.js",
30
34
  "lint": "echo 'No linter configured — add eslint for production'",
31
35
  "check-credentials": "node src/utils/log-redaction.js",
32
36
  "generate-assets": "node scripts/generate-initial-assets.js",
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "video-pipeline",
3
+ "displayName": "FrameForge Video Pipeline",
4
+ "version": "2.3.1",
5
+ "description": "End-to-end AI video production. IDE writes scenes → FrameForge renders. Or: scaffold a Playwright+ffmpeg code-driven animation. Or: auto-research and script the video.",
6
+ "skills": [
7
+ {
8
+ "name": "video-pipeline",
9
+ "path": "skills/video-pipeline/SKILL.md",
10
+ "displayName": "Video Pipeline",
11
+ "description": "17 MCP tools: create_video_from_script, scaffold_animation_project, render_animation, validate_storyboard, multi_voice_tts, ingest_media, edit_scenes, research_topic, write_script, queue_full_pipeline, and more."
12
+ }
13
+ ],
14
+ "mcpServer": {
15
+ "command": "npx",
16
+ "args": ["--yes", "--package=@amg555/frameforge-mcp", "frameforge-mcp"],
17
+ "description": "Starts the FrameForge MCP server. No install needed — npx pulls from npm."
18
+ }
19
+ }