@amg555/frameforge-mcp 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +38 -10
- package/CHANGELOG.md +16 -0
- package/CLAUDE.md +45 -3
- package/README.md +20 -2
- package/START_HERE.md +89 -33
- package/package.json +5 -5
- package/src/cli/setup-keys.js +17 -3
- package/src/mcp-server/server.js +1 -1
|
@@ -1,17 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frameforge",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
},
|
|
3
|
+
"displayName": "FrameForge — AI Video Production",
|
|
4
|
+
"description": "Full AI video production engine. Produce short-form reels (1080×1920), YouTube videos (1920×1080), or code-driven animated explainers — directly from your IDE. Playwright + FFmpeg renders every frame. 17 MCP tools.",
|
|
5
|
+
"version": "2.3.1",
|
|
6
|
+
"homepage": "https://github.com/AMG555/FrameForge",
|
|
8
7
|
"plugins": [
|
|
9
8
|
{
|
|
10
9
|
"name": "video-pipeline",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
"path": "plugins/video-pipeline/.claude-plugin/plugin.json",
|
|
11
|
+
"skills": [
|
|
12
|
+
{
|
|
13
|
+
"name": "video-pipeline",
|
|
14
|
+
"displayName": "FrameForge Video Pipeline",
|
|
15
|
+
"description": "End-to-end video production: research → script → TTS → images → render → publish. Three paths: (1) IDE writes scenes (most common, no API key), (2) code-driven Playwright animation, (3) auto-research pipeline. 17 MCP tools.",
|
|
16
|
+
"triggerPhrases": [
|
|
17
|
+
"make a video about",
|
|
18
|
+
"produce a reel on",
|
|
19
|
+
"create a short",
|
|
20
|
+
"edit this into a reel",
|
|
21
|
+
"make an explainer",
|
|
22
|
+
"animated video",
|
|
23
|
+
"code-driven video",
|
|
24
|
+
"generate video",
|
|
25
|
+
"run the pipeline",
|
|
26
|
+
"publish video",
|
|
27
|
+
"overnight batch",
|
|
28
|
+
"queue videos"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
15
32
|
}
|
|
16
|
-
]
|
|
33
|
+
],
|
|
34
|
+
"mcpServer": {
|
|
35
|
+
"command": "npx",
|
|
36
|
+
"args": ["--yes", "--package=@amg555/frameforge-mcp", "frameforge-mcp"],
|
|
37
|
+
"description": "Runs the FrameForge MCP server via npx (no install needed). Requires ffmpeg and edge-tts on PATH."
|
|
38
|
+
},
|
|
39
|
+
"requirements": {
|
|
40
|
+
"node": ">=18.0.0",
|
|
41
|
+
"binaries": ["ffmpeg", "ffprobe"],
|
|
42
|
+
"optional": ["edge-tts", "python3"],
|
|
43
|
+
"notes": "edge-tts: pip install edge-tts. Playwright (for code-driven animation): npm install playwright && npx playwright install chromium (run once in project dir)."
|
|
44
|
+
}
|
|
17
45
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@ All notable changes to FrameForge are documented here.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [2.3.1] — 2026-11-04
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`.claude-plugin/marketplace.json`** — Claude Code plugin marketplace registration. FrameForge is now discoverable via `claude plugin marketplace add AMG555/FrameForge`.
|
|
12
|
+
- **`plugins/video-pipeline/.claude-plugin/plugin.json`** — per-plugin manifest for the video-pipeline skill.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **`src/cli/setup-keys.js`** — `skip` is now the **default** option in the LLM provider menu. Users who write their own scenes (the most common path) are no longer forced through an API key section.
|
|
17
|
+
- **`CLAUDE.md`** — Path 2 expanded: transcript/`cuePhrase()` word-sync workflow, `video_job.py` spend-capped batch, golden stills regression test, hook variants (A/B testing opening shots), mobile crop check, still-review budget.
|
|
18
|
+
- **`START_HERE.md`** — restructured into three named paths (A: IDE-scenes, B: code-driven animation, C: auto-research). Reel vs. YouTube format choice surfaced in opening questions. Path B includes transcription, hook variants, and storyboard gate.
|
|
19
|
+
- Version bump: `2.3.0` → `2.3.1` across all version strings.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
7
23
|
## [2.3.0] — 2026-11-02
|
|
8
24
|
|
|
9
25
|
### Added
|
package/CLAUDE.md
CHANGED
|
@@ -94,10 +94,14 @@ Output files appear in `.frameforge-files/`:
|
|
|
94
94
|
|
|
95
95
|
### Path 2 — Code-driven animated video (Playwright + FFmpeg, no AI images)
|
|
96
96
|
|
|
97
|
-
Use this when: the user wants motion graphics, Pollinations is unavailable, or they ask for "animated"
|
|
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`.
|
|
98
98
|
|
|
99
99
|
> **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
100
|
|
|
101
|
+
**Pick a format first:**
|
|
102
|
+
- **Reel / Short / TikTok** → `width: 1080, height: 1920` (portrait 9:16)
|
|
103
|
+
- **YouTube / Explainer** → `width: 1920, height: 1080` (landscape 16:9)
|
|
104
|
+
|
|
101
105
|
**Step 0 — Beat sheet first. Always. No exceptions.**
|
|
102
106
|
|
|
103
107
|
Before writing any scene code, reply to the user with:
|
|
@@ -106,17 +110,22 @@ Before writing any scene code, reply to the user with:
|
|
|
106
110
|
|
|
107
111
|
**Stop and wait for approval before Step 1.** Fixing a beat sheet costs one message. Rewriting a finished scene costs everything.
|
|
108
112
|
|
|
109
|
-
**Step 1 — Generate TTS
|
|
113
|
+
**Step 1 — Generate TTS and transcription (exact timing is ground truth):**
|
|
110
114
|
```
|
|
111
115
|
multi_voice_tts({ text: "Full narration text.", outputPath: ".frameforge-files/voice_0.m4a" })
|
|
112
116
|
```
|
|
117
|
+
Then transcribe for word-level timestamps (required for `cuePhrase()` sync):
|
|
118
|
+
```
|
|
119
|
+
// run in projectDir after scaffold: python scripts/transcribe.py .frameforge-files/voice_0.m4a
|
|
120
|
+
// → produces voice_0.captions.json with per-word start/end times
|
|
121
|
+
```
|
|
113
122
|
|
|
114
123
|
**Step 2 — Scaffold the project:**
|
|
115
124
|
```
|
|
116
125
|
scaffold_animation_project({
|
|
117
126
|
outDir: ".frameforge-files/my-animation/",
|
|
118
127
|
title: "My Video",
|
|
119
|
-
width: 1920, height: 1080,
|
|
128
|
+
width: 1920, height: 1080, // or 1080×1920 for portrait reel
|
|
120
129
|
scenes: [{ narration: "...", caption: "...", visual_description: "..." }],
|
|
121
130
|
audioPath: ".frameforge-files/voice_0.m4a"
|
|
122
131
|
})
|
|
@@ -138,16 +147,49 @@ validate_storyboard({ storyboardPath: ".frameforge-files/my-animation/STORYBOARD
|
|
|
138
147
|
- Read `ANIMATION_GUIDE.md` in the project folder first
|
|
139
148
|
- Every style must be a **pure function of `t`**
|
|
140
149
|
- Use `layer('name').on(t => ({ ...styles }))` for each scene
|
|
150
|
+
- Sync animation to narration using `cuePhrase('the exact words spoken')` — this reads `voice_0.captions.json` and returns the frame when those words start. **The build fails if the phrase isn't found**, so re-recording VO can never silently desync the animation.
|
|
141
151
|
|
|
142
152
|
**Step 5 — Pre-flight, then stills, then full render:**
|
|
143
153
|
```
|
|
144
154
|
render_animation({ projectDir: ".frameforge-files/my-animation/", mode: "look" }) // fonts, assets, NaN checks
|
|
145
155
|
render_animation({ projectDir: ".frameforge-files/my-animation/", mode: "sheet" }) // contact sheet — inspect this
|
|
146
156
|
render_animation({ projectDir: ".frameforge-files/my-animation/", mode: "strip", timestamps: [2.1, 2.6] }) // motion check
|
|
157
|
+
render_animation({ projectDir: ".frameforge-files/my-animation/", mode: "crop", timestamps: ["9:16", 3.0] }) // mobile check
|
|
147
158
|
render_animation({ projectDir: ".frameforge-files/my-animation/", mode: "full",
|
|
148
159
|
audioPath: ".frameforge-files/voice_0.m4a" }) // only after stills pass
|
|
149
160
|
```
|
|
150
161
|
|
|
162
|
+
**Still review budget (minimum, before full render):**
|
|
163
|
+
- At least one `sheet` per shot
|
|
164
|
+
- One `strip` per key motion or transition
|
|
165
|
+
- One `crop` per story-carrying face or detail
|
|
166
|
+
|
|
167
|
+
**Step 6 — Optional: hook variants**
|
|
168
|
+
|
|
169
|
+
For reels and Shorts, make 2–3 versions with different opening hooks:
|
|
170
|
+
- Change only the first shot (0s–3s) in `edit.js`
|
|
171
|
+
- `render_animation({ mode: "stills", timestamps: [0.0, 1.5, 3.0] })` to compare openings
|
|
172
|
+
- Full render each variant, deliver as `hook_a.mp4`, `hook_b.mp4`, etc.
|
|
173
|
+
|
|
174
|
+
**Step 7 — Optional: unattended / spend-capped batch**
|
|
175
|
+
```
|
|
176
|
+
// run from projectDir
|
|
177
|
+
python scripts/video_job.py submit --spec spec.json --max-usd 2.00
|
|
178
|
+
// → { jobId } — detached process, survives your session closing
|
|
179
|
+
python scripts/video_job.py status --id <jobId>
|
|
180
|
+
python scripts/video_job.py result --id <jobId>
|
|
181
|
+
```
|
|
182
|
+
Each step only starts if the running cost won't exceed `--max-usd`. Receipts go to `jobs/receipts.jsonl`.
|
|
183
|
+
|
|
184
|
+
**Step 8 — Golden stills regression test (before any refactor)**
|
|
185
|
+
|
|
186
|
+
After the video passes QC, save the test stills:
|
|
187
|
+
```
|
|
188
|
+
render_animation({ projectDir, mode: "storyboard" }) // 4 keyframes, file to out/storyboard.jpg
|
|
189
|
+
// → copy out/storyboard.jpg to test/golden/storyboard.jpg
|
|
190
|
+
```
|
|
191
|
+
Before future refactors, re-run and compare. If pixels shift, the refactor broke determinism.
|
|
192
|
+
|
|
151
193
|
> Requires one-time setup in the project directory: `npm install playwright && npx playwright install chromium`
|
|
152
194
|
|
|
153
195
|
---
|
package/README.md
CHANGED
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
**Any IDE. Any topic. Any style. 1080p videos from a single prompt.**
|
|
8
8
|
|
|
9
|
+
[](https://www.npmjs.com/package/@amg555/frameforge-mcp)
|
|
9
10
|
[](LICENSE)
|
|
10
11
|
[](https://nodejs.org/)
|
|
11
|
-
[](CHANGELOG.md)
|
|
12
13
|
[](https://modelcontextprotocol.io/)
|
|
13
14
|
[](#testing)
|
|
14
15
|
|
|
@@ -272,6 +273,16 @@ Every video passes 7 checks before delivery. Any failure blocks the output.
|
|
|
272
273
|
|
|
273
274
|
## CLI commands
|
|
274
275
|
|
|
276
|
+
**Via npx (no clone needed):**
|
|
277
|
+
|
|
278
|
+
| Command | What it does |
|
|
279
|
+
|---------|-------------|
|
|
280
|
+
| `npx --package=@amg555/frameforge-mcp frameforge-setup` | Interactive key wizard — saves to `~/.frameforge/config.json` |
|
|
281
|
+
| `npx --package=@amg555/frameforge-mcp frameforge-doctor` | Check Node, FFmpeg, edge-tts, and env vars |
|
|
282
|
+
| `npx --package=@amg555/frameforge-mcp frameforge --topic "..."` | Full pipeline: research → render → deliver |
|
|
283
|
+
|
|
284
|
+
**Via cloned repo:**
|
|
285
|
+
|
|
275
286
|
| Command | What it does |
|
|
276
287
|
|---------|-------------|
|
|
277
288
|
| `npm run doctor` | Check Node, FFmpeg, edge-tts, and env vars |
|
|
@@ -323,7 +334,14 @@ Report vulnerabilities: [SECURITY.md](SECURITY.md)
|
|
|
323
334
|
|
|
324
335
|
## Deployment
|
|
325
336
|
|
|
326
|
-
**
|
|
337
|
+
**npx (no install — recommended for users):**
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
npx --package=@amg555/frameforge-mcp frameforge-setup
|
|
341
|
+
# then add the IDE config from the quickstart above
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**VPS / Pi / self-hosted (cloned repo):**
|
|
327
345
|
|
|
328
346
|
```bash
|
|
329
347
|
git clone https://github.com/AMG555/FrameForge.git && cd FrameForge
|
package/START_HERE.md
CHANGED
|
@@ -17,18 +17,20 @@ produce it — from research through render to final MP4.
|
|
|
17
17
|
|
|
18
18
|
## Opening Message (say this verbatim to the user)
|
|
19
19
|
|
|
20
|
-
> 👋 I'm your FrameForge video studio. I can make
|
|
21
|
-
> documentary clips, tutorials, or any video you describe — using AI research, voiceover,
|
|
22
|
-
> animated scenes, and a full render pipeline.
|
|
20
|
+
> 👋 I'm your FrameForge video studio. I can make:
|
|
23
21
|
>
|
|
24
|
-
>
|
|
22
|
+
> - **Short-form reels** (Instagram, TikTok, YouTube Shorts — 15–60s, 9:16 portrait)
|
|
23
|
+
> - **YouTube videos** (explainers, tutorials, long-form — 3–15 min, 16:9 landscape)
|
|
24
|
+
> - **Code-driven animated explainers** (motion graphics, no stock images needed — any length)
|
|
25
|
+
>
|
|
26
|
+
> Let's start with a few quick questions:
|
|
25
27
|
>
|
|
26
28
|
> 1. **What's the topic or idea?** (e.g. "How black holes form", "5 tips for sourdough bread", "A travel reel about Tokyo")
|
|
27
|
-
> 2. **
|
|
28
|
-
> 3. **
|
|
29
|
-
> 4. **
|
|
29
|
+
> 2. **Format?** `Reel / Short / TikTok (9:16)` · `YouTube video (16:9)` · `Animated explainer (any)`
|
|
30
|
+
> 3. **Style?** `educational` · `comedic` · `documentary` · `cinematic` · `tutorial` · or describe your own
|
|
31
|
+
> 4. **How long?** `Short (15–60s)` · `Medium (1–3 min)` · `Long (5–10 min)`
|
|
30
32
|
> 5. **Voice?** `Auto-select` · or name a style: `professional narrator`, `friendly teacher`, `energetic host`
|
|
31
|
-
> 6. **Any images or
|
|
33
|
+
> 6. **Any footage, images, or audio to include?** (paste file paths, or say "generate everything")
|
|
32
34
|
>
|
|
33
35
|
> Answer as many or as few as you like. I'll fill in the rest.
|
|
34
36
|
|
|
@@ -36,16 +38,24 @@ produce it — from research through render to final MP4.
|
|
|
36
38
|
|
|
37
39
|
## After the User Answers — Agent Instructions
|
|
38
40
|
|
|
39
|
-
Once you have the user's answers,
|
|
41
|
+
Once you have the user's answers, choose the right render path and follow it precisely.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Render Paths
|
|
40
46
|
|
|
41
|
-
###
|
|
47
|
+
### PATH A — IDE-written scenes (fastest, most common)
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
Use for: any video where you (the IDE agent) write the narration and visual descriptions.
|
|
50
|
+
No LLM key needed — FrameForge generates TTS + AI images and renders with FFmpeg.
|
|
51
|
+
|
|
52
|
+
**Step A1 — Beat Sheet Gate (MANDATORY)**
|
|
53
|
+
|
|
54
|
+
Before calling any render tool, produce a beat sheet and **stop** — wait for approval:
|
|
45
55
|
|
|
46
56
|
```
|
|
47
57
|
BEAT SHEET — "<title>"
|
|
48
|
-
Duration: Xs | Style: <style> | Format: <
|
|
58
|
+
Duration: Xs | Style: <style> | Format: <landscape/portrait>
|
|
49
59
|
|
|
50
60
|
Scene 1 [0:00–0:08] <what happens + what the viewer learns> → TRANSITION
|
|
51
61
|
Scene 2 [0:08–0:18] <what happens + what the viewer learns> → TRANSITION
|
|
@@ -56,43 +66,89 @@ Voice: <voice description>
|
|
|
56
66
|
Visual style: <1-sentence description>
|
|
57
67
|
```
|
|
58
68
|
|
|
59
|
-
Gate rules —
|
|
69
|
+
Gate rules — revise if ANY are true:
|
|
60
70
|
- A scene has no event (action that changes something)
|
|
61
71
|
- Two scenes share the same timestamp range
|
|
62
72
|
- Any seam is missing a transition label
|
|
63
|
-
-
|
|
73
|
+
- Total duration doesn't match requested length ±10%
|
|
64
74
|
|
|
65
|
-
|
|
75
|
+
**Step A2 — Render**
|
|
66
76
|
|
|
67
|
-
|
|
77
|
+
```
|
|
78
|
+
create_video_from_script({
|
|
79
|
+
scenes: [ { narration: "...", caption: "...", visual_description: "...", camera_hint: "zoom_in" } ],
|
|
80
|
+
title: "My Video",
|
|
81
|
+
orientation: "landscape", // "portrait" for Reels/Shorts/TikTok
|
|
82
|
+
voice: "en-US-BrianNeural", // or use language: "en"
|
|
83
|
+
withMusic: true
|
|
84
|
+
})
|
|
85
|
+
```
|
|
68
86
|
|
|
69
|
-
|
|
87
|
+
**Step A3 — Publish**
|
|
70
88
|
|
|
71
|
-
|
|
89
|
+
Ask: "Save locally, or deliver somewhere?" Then call `publish_video`.
|
|
72
90
|
|
|
73
|
-
|
|
74
|
-
`voice` from the user's answers. The script must match the beat sheet scene-for-scene.
|
|
91
|
+
---
|
|
75
92
|
|
|
76
|
-
###
|
|
93
|
+
### PATH B — Code-driven animated video (motion graphics, explainers, reels)
|
|
77
94
|
|
|
78
|
-
|
|
79
|
-
|
|
95
|
+
Use for: motion graphics, animated explainers, reels that must look high-quality without stock images.
|
|
96
|
+
Requires one-time: `npm install playwright && npx playwright install chromium` (run in the project dir).
|
|
80
97
|
|
|
81
|
-
|
|
98
|
+
**Step B1 — Beat sheet first (same gate as Path A — MANDATORY)**
|
|
82
99
|
|
|
83
|
-
|
|
100
|
+
**Step B2 — TTS and transcription**
|
|
84
101
|
|
|
85
|
-
|
|
86
|
-
|
|
102
|
+
```
|
|
103
|
+
multi_voice_tts({ text: "Full narration.", outputPath: ".frameforge-files/voice_0.m4a" })
|
|
104
|
+
// After scaffolding: python scripts/transcribe.py .frameforge-files/voice_0.m4a
|
|
105
|
+
// → voice_0.captions.json — word timestamps for cuePhrase() sync
|
|
106
|
+
```
|
|
87
107
|
|
|
88
|
-
|
|
89
|
-
preview. Show the user the sheet path and ask if they want any changes.
|
|
108
|
+
**Step B3 — Scaffold**
|
|
90
109
|
|
|
91
|
-
|
|
110
|
+
```
|
|
111
|
+
scaffold_animation_project({
|
|
112
|
+
outDir: ".frameforge-files/my-animation/",
|
|
113
|
+
title: "My Video",
|
|
114
|
+
width: 1920, height: 1080, // 1080×1920 for portrait reels
|
|
115
|
+
scenes: [...],
|
|
116
|
+
audioPath: ".frameforge-files/voice_0.m4a"
|
|
117
|
+
})
|
|
118
|
+
```
|
|
92
119
|
|
|
93
|
-
|
|
120
|
+
**Step B4 — Validate STORYBOARD.md**
|
|
94
121
|
|
|
95
|
-
|
|
122
|
+
```
|
|
123
|
+
validate_storyboard({ storyboardPath: ".frameforge-files/my-animation/STORYBOARD.md" })
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Step B5 — Write `edit.js`, then stills, then full render**
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
render_animation({ projectDir: "...", mode: "look" }) // pre-flight
|
|
130
|
+
render_animation({ projectDir: "...", mode: "sheet" }) // one sheet per shot
|
|
131
|
+
render_animation({ projectDir: "...", mode: "strip", timestamps: [2.1, 2.6] }) // motion check
|
|
132
|
+
render_animation({ projectDir: "...", mode: "full", audioPath: ".frameforge-files/voice_0.m4a" })
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**For reels: make 2–3 hook variants** (change only the first 3s of `edit.js`, full-render each):
|
|
136
|
+
```
|
|
137
|
+
render_animation({ projectDir: "...", mode: "stills", timestamps: [0.0, 1.5, 3.0] })
|
|
138
|
+
// deliver hook_a.mp4, hook_b.mp4 so the user can A/B test
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### PATH C — Auto-research (needs `PROVIDER_LLM` + key in `.env`)
|
|
144
|
+
|
|
145
|
+
Use for: overnight batch, topics where you want FrameForge to research and script everything.
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
queue_full_pipeline({ topic: "How GPS works", style: "educational" })
|
|
149
|
+
→ { jobId }
|
|
150
|
+
get_job_status({ jobId }) // poll every 30s
|
|
151
|
+
```
|
|
96
152
|
|
|
97
153
|
---
|
|
98
154
|
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amg555/frameforge-mcp",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
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"
|
|
7
7
|
},
|
|
8
8
|
"main": "src/mcp-server/server.js",
|
|
9
9
|
"bin": {
|
|
10
|
-
"frameforge":
|
|
11
|
-
"frameforge-mcp":
|
|
12
|
-
"frameforge-setup":
|
|
10
|
+
"frameforge": "src/cli/make.js",
|
|
11
|
+
"frameforge-mcp": "src/mcp-server/stdio.js",
|
|
12
|
+
"frameforge-setup": "src/cli/setup-keys.js",
|
|
13
13
|
"frameforge-doctor": "src/cli/doctor.js"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
@@ -55,6 +55,6 @@
|
|
|
55
55
|
"license": "MIT",
|
|
56
56
|
"repository": {
|
|
57
57
|
"type": "git",
|
|
58
|
-
"url": "https://github.com/AMG555/FrameForge"
|
|
58
|
+
"url": "git+https://github.com/AMG555/FrameForge.git"
|
|
59
59
|
}
|
|
60
60
|
}
|
package/src/cli/setup-keys.js
CHANGED
|
@@ -171,6 +171,15 @@ async function main() {
|
|
|
171
171
|
This wizard writes your provider API keys to: ${path.resolve(outFile)}
|
|
172
172
|
Keys are never sent anywhere — they stay on your machine.
|
|
173
173
|
Press Enter to accept a default. Ctrl+C to cancel.
|
|
174
|
+
|
|
175
|
+
✅ No keys are required to make videos.
|
|
176
|
+
Your IDE writes the scenes — FrameForge uses free providers by default:
|
|
177
|
+
• edge-tts — free voice (no account)
|
|
178
|
+
• pollinations — free images (no account)
|
|
179
|
+
• FFmpeg — free local render (already on your machine)
|
|
180
|
+
|
|
181
|
+
You only need keys for the auto-research pipeline (FrameForge writes the
|
|
182
|
+
script itself). Skip those sections if you plan to write scenes yourself.
|
|
174
183
|
`);
|
|
175
184
|
|
|
176
185
|
const cfg = {};
|
|
@@ -178,22 +187,27 @@ Press Enter to accept a default. Ctrl+C to cancel.
|
|
|
178
187
|
// ── LLM ──────────────────────────────────────────────────────────────────
|
|
179
188
|
section('1 / 5 — LLM Provider (research + script generation)');
|
|
180
189
|
console.log(' Used for: researching topics, writing scripts, fact-checking.');
|
|
190
|
+
console.log(' ⚡ SKIP THIS if your IDE agent writes the scenes (most common path).');
|
|
181
191
|
console.log(' Free option: Groq (no credit card needed for free tier).\n');
|
|
182
192
|
|
|
183
193
|
cfg.PROVIDER_LLM = await menu('Choose LLM provider', [
|
|
194
|
+
['skip', '⏭ Skip — I write my own scenes (most common, no key needed)'],
|
|
184
195
|
['groq', 'Groq — free, fast (llama-3.3-70b). Get key: console.groq.com'],
|
|
185
196
|
['cerebras', 'Cerebras — fastest inference (2000+ tok/s). Get key: cloud.cerebras.ai'],
|
|
197
|
+
['gemini', 'Google Gemini 2.0 Flash — free tier. Get key: aistudio.google.com'],
|
|
186
198
|
['openrouter', 'OpenRouter — all models with one key. Get key: openrouter.ai'],
|
|
187
199
|
['anthropic', 'Anthropic Claude Sonnet 4.5. Get key: console.anthropic.com'],
|
|
188
|
-
['gemini', 'Google Gemini 2.0 Flash. Get key: aistudio.google.com'],
|
|
189
200
|
['mistral', 'Mistral Large. Get key: console.mistral.ai'],
|
|
190
201
|
['together', 'Together AI Llama-3.3-70B-Turbo. Get key: api.together.ai'],
|
|
191
202
|
['openai', 'OpenAI GPT-4o. Get key: platform.openai.com'],
|
|
192
203
|
['ollama', 'Ollama — fully local, no key needed. Install: ollama.com'],
|
|
193
204
|
['webhook', 'Custom/VoxForge/any OpenAI-compatible endpoint'],
|
|
194
|
-
], '
|
|
205
|
+
], 'skip');
|
|
195
206
|
|
|
196
|
-
if (cfg.PROVIDER_LLM === '
|
|
207
|
+
if (cfg.PROVIDER_LLM === 'skip') {
|
|
208
|
+
console.log(' ✅ LLM skipped — your IDE will write scenes via create_video_from_script.\n');
|
|
209
|
+
cfg.PROVIDER_LLM = undefined; // don't write to config
|
|
210
|
+
} else if (cfg.PROVIDER_LLM === 'groq') {
|
|
197
211
|
cfg.GROQ_API_KEY = await askSecret(' Groq API key (starts with gsk_)');
|
|
198
212
|
} else if (cfg.PROVIDER_LLM === 'cerebras') {
|
|
199
213
|
cfg.CEREBRAS_API_KEY = await askSecret(' Cerebras API key');
|
package/src/mcp-server/server.js
CHANGED