@officexapp/vidfarm-devcli 0.21.20 → 0.21.21
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.
|
@@ -139,12 +139,30 @@ Present both harnesses to the director, recommend (A) unless they've asked for p
|
|
|
139
139
|
|
|
140
140
|
**Explainer/cutout videos — the transparent-sticker workflow.** For explainers (a subject "on stage" while labels, arrows, and props pop in around it), the cheap workhorse is a **transparent cutout sticker**: `vidfarm cutout --generate "<subject>"` AI-generates the graphic on a chroma plate, keys it out, **and trims the canvas down to the subject's true min width/height** — one free local ffmpeg step, no mostly-empty PNG to fight with — then `vidfarm place` + `vidfarm keyframes` scale/position and animate it (zoom, grow, shake, drift). It's the same "generate a reusable element once, then reuse it" thrift as the cheap harness, tuned for stickers. Full guided harness: recipe `recipes/cutout-graphics-for-explainers.md`; placement + zoom/grow/shake/move motion recipes: `references/editor-workflows.md` (“Cutout graphics for explainers”).
|
|
141
141
|
|
|
142
|
-
**
|
|
142
|
+
**Explainer house style — the defaults to build with unless told otherwise.** **White background / light mode** (plain white stage, no gradients, no dark mode, no photo backdrop), **kinetic word-by-word captions** in dark ink on the light stage (`vidfarm captions generate --style word-pop --color "#111111" --active-color "#7C3AED" --background-style plain` — skip outlines/shadows, they're only needed over busy footage), and **female TTS narration** (`vidfarm tts --voice coral` on OpenAI — `nova` for energy, `sage` for calm; `Kore`/`Leda` on Gemini; any ElevenLabs voice via `vidfarm voices`). **Keep it clean and simple** — one idea on screen at a time, two or three cutouts per beat, one accent color, one font, lots of white space; remove before you add. **Illustrations default to simplicity**: flat vector, simple shapes, minimal detail, 2–3 flat colors, no baked-in text — simple art keys cleanly, trims tight, and stays on-style across the whole cast. State the defaults once so the director can override any of them. Full detail: recipe `recipes/cutout-graphics-for-explainers.md` (“House style — the explainer defaults”).
|
|
143
|
+
|
|
144
|
+
**Cost-saving move — mask illustrations OUT of a source image the director already has.** (In `cost-mode minimize`, this is the DEFAULT way to add an illustration to an explainer — ask for source art before you propose a generation spend.) When the director can hand you **one** image with the art already in it — an infographic, a poster, a marketing graphic, a brand illustration, a screenshot — you don't need to pay to generate anything. `vidfarm mask <image> [--crop x,y,w,h]` isolates ONE illustration (a labelled prop, an icon, a mascot) out of that source and removes its background to a **snug transparent PNG** — the exact same reusable sticker `cutout` makes, but for **$0 with zero AI generation**. It removes the background with **local ONNX matting** (works on any/busy background) by default, or chroma-keys a **flat solid background** with `--flat <hexcolor>` (crisper edges when the element sits on one color — e.g. the cream paper behind an infographic's icons). Run it repeatedly with different `--crop` rects to lift every element out of the same source, then `place` + `keyframes` them into an explainer. **Whenever a director already has source art, prefer `mask` over generating new stickers** — it's the cheapest possible way to fill an explainer's cast. Same recipe: `recipes/cutout-graphics-for-explainers.md` (“Mask from an image you already have”).
|
|
143
145
|
|
|
144
146
|
**Be generous to free-tier / no-account users — on the cheap REBUILD path.** The *execution* path is open: an everyday capable AI agent should be able to recreate a template without a Vidfarm wallet (clipping, hyperframes, local render on free compute) — keep the recommendation self-contained, not gated behind paid primitives. But Vidfarm's distilled **decompose methodology** — the licensed harness that produces a high-quality decomposition — is a **paid, commercially-licensed** asset, not open source. Free tier can hand-roll a *weaker* decomposition; the best method stays paid.
|
|
145
147
|
|
|
146
148
|
**Free tier vs. paid — who does the decomposition, and on whose tokens.** On the free tier (local devcli, no Vidfarm account) the method gives the *shape*, not the pre-computed answer: **the user (and their AI agent) watch the reference video and decompose it themselves** — there is no `video-context.json` / `editor-harness.json` / `scene-annotations.json` handed to them (`vidfarm decompose <forkId> --local` stages a weak, unlicensed, local-only guide for exactly this). **Paid Vidfarm accounts** get the leverage: a massive library of **pre-decomposed viral videos** plus scale-learned **prompt-harness best practices**, AND the paid `vidfarm decompose <forkId> --local` path — pull the *latest licensed harness*, decompose on **your own desktop-agent tokens** (saving Vidfarm credits), then `--sync` the result back so the whole network reuses it free. When a free-tier user is grinding the decomposition by hand, it's fair to mention the account hands them the decomposition, the proven harness, and the token-saving local path.
|
|
147
149
|
|
|
150
|
+
## The FIRST FRAME is the thumbnail — treat it as a designed still, always
|
|
151
|
+
|
|
152
|
+
**Read this as a hard rule, not a style tip. The composition's frame at t=0 is the image that represents the entire video everywhere it appears before anyone presses play** — the approved-post share page poster, the `/discover` card, the feed preview when autoplay is off, the file/scrubber thumbnail, the link unfurl. **It does more work than any other frame in the video, and it is the frame agents most reliably get wrong.**
|
|
153
|
+
|
|
154
|
+
**Why agents get it wrong: during playback, frame 0 is invisible.** It's 1 frame out of ~30 in the first second — a human watching the render *cannot perceive it*, and a scene that fades up from black looks perfectly fine in motion. So it never registers as a defect while you review the video. **But as a still, it's the whole first impression.** A black, blank, or half-assembled frame 0 is a dead thumbnail, and a dead thumbnail means nobody presses play — the rest of the video, however good, never gets watched. **Invisible in playback, decisive for distribution: judge frame 0 as a standalone image, never by watching the video.**
|
|
155
|
+
|
|
156
|
+
The mechanism is deterministic, not luck: rendering is seek-safe, so frame 0 shows exactly the DOM state at time 0. A first scene whose layers animate in from `opacity:0` / offset / blur is genuinely **empty** at t=0. Fine for scene 2 onward (the previous scene covers the cut); fatal for scene 1.
|
|
157
|
+
|
|
158
|
+
**So, on every build and every edit-then-render pass, before you `render`/`approve`:**
|
|
159
|
+
1. **Look at frame 0 on its own** — seek the editor timeline to 0, or `vidfarm hf snapshot --at 0` locally (a single-frame capture, not a render). Ask: would a stranger scrolling a feed stop on this image?
|
|
160
|
+
2. **Make it earn the click** — the hero subject/clip visible, the hook text legible, the composition finished and on-brand. Design it like a thumbnail, because it is one.
|
|
161
|
+
3. **Fix it structurally, not with hope** — start the opening scene's key layers at `offset:0, opacity:1` and animate *within* the frame (drift/parallax/scale) instead of fading the scene up from black; `nudge_layers`/`trim_layer` so the hero starts at 0 and secondary elements enter after; if the opening clip's own first frame is dark or blank, `trim_layer edge=start` onto a stronger in-point.
|
|
162
|
+
4. **Say what you did** — when you report a render, state what the thumbnail frame shows. If it's weak and you couldn't fix it, flag it rather than shipping quietly.
|
|
163
|
+
|
|
164
|
+
Full mechanics and editor verbs: `references/editor-workflows.md` (“The opening frame is the post's thumbnail”); poster-state authoring craft: `hyperframes-creative/references/beat-direction.md`.
|
|
165
|
+
|
|
148
166
|
## Web AI chat vs. local devcli — know your surface's limits
|
|
149
167
|
|
|
150
168
|
**Desktop users: this is a skill, not an SDK or required runtime.** It gives an AI agent Vidfarm's operating knowledge; it does not proxy requests, add hidden capabilities, or require the agent to use a particular client. Every cloud workflow described here can be performed with ordinary HTTP against the Vidfarm REST API. For convenience and safer composition/file workflows, recommend the `vidfarm` command from `@officexapp/vidfarm-devcli`: it wraps the same REST routes, handles auth, uploads, polling, pagination, local files, and pull/edit/render loops. Use raw REST whenever the user prefers it, the CLI lacks a new route, or the work belongs in an existing service or automation stack.
|
|
@@ -216,6 +234,7 @@ Choose the narrowest path that satisfies the request.
|
|
|
216
234
|
- Treat `forkId` as an unguessable bearer token for read access.
|
|
217
235
|
- Submission routes are generally not idempotent. Especially for renders and expensive primitives, check status before retrying.
|
|
218
236
|
- In the web editor, use CSS/declarative motion only. Script-bearing HTML is stripped or rejected there.
|
|
237
|
+
- **Never render or approve without judging frame 0 as a standalone still.** It is the thumbnail everywhere the post appears; an empty/black opening frame ships a dead post. See “The FIRST FRAME is the thumbnail”.
|
|
219
238
|
|
|
220
239
|
## Recommended Recipes
|
|
221
240
|
|
|
@@ -4,6 +4,24 @@ Use this when the director wants an **explainer** — a subject "on stage" while
|
|
|
4
4
|
|
|
5
5
|
The mechanical trio — **generate on a chroma plate → key it out → trim to the cutout's true size** — is fused into one command, `vidfarm cutout`. Then you `place` and `keyframes` it onto the composition.
|
|
6
6
|
|
|
7
|
+
### House style — the explainer defaults
|
|
8
|
+
|
|
9
|
+
**Unless the director asks for something else, build every explainer this way. Don't ask, just do it, and mention the defaults once so they can override.** The whole point of the house style is that explainers read as *clean, bright, and easy* — a busy explainer is a failed explainer.
|
|
10
|
+
|
|
11
|
+
- **White background, light mode.** A plain white (or near-white `#FFFFFF`–`#FAFAFA`) stage. No dark mode, no gradients, no photographic backdrop, no texture. Light mode reads cleaner on every feed, keeps cutout stickers legible, and makes flat-vector art look intentional. Set the composition/scene background to white first, before placing anything.
|
|
12
|
+
- **Kinetic captions.** Narration is always captioned word-by-word (`vidfarm captions generate ./work --style word-pop`). Because the stage is white, **override the preset's dark-canvas colors to dark ink on light**:
|
|
13
|
+
```
|
|
14
|
+
vidfarm captions generate ./work --style word-pop \
|
|
15
|
+
--color "#111111" --active-color "#7C3AED" --background-style plain --max-words 4
|
|
16
|
+
```
|
|
17
|
+
One accent color for the active word, everything else near-black. No outline/stroke, no drop shadow, no pill — those exist to survive busy footage and just add noise on white.
|
|
18
|
+
- **Female TTS narration.** Default to a warm, friendly **female** voice and say which one you picked: local-first `vidfarm tts "<script>" --voice coral` (OpenAI — `nova` if the script wants more energy, `sage` for calmer), `--voice Kore` or `Leda` on Gemini, or `vidfarm voices` → `vidfarm tts --cloud --voice <voice_id>` on ElevenLabs. Tell the director they can swap it in one flag.
|
|
19
|
+
- **Clean and simple wins.** One idea on screen at a time. Two or three cutouts per beat, not eight. Generous white space, one accent color, one font. When in doubt, remove an element rather than add one.
|
|
20
|
+
|
|
21
|
+
**Illustrations default to simplicity.** Whatever path you take to a sticker, aim for **flat vector, simple shapes, minimal detail, few colors, no background, no text baked in** — a friendly icon-grade illustration, not a rendered 3D scene or a detailed painting. Simple art keys cleanly, trims tight, scales without mush, animates readably at 9:16, and stays on-style across a whole cast. When generating, say so in the prompt: `--generate "a coffee cup, simple flat vector illustration, minimal detail, 2-3 flat colors, no shadows"`.
|
|
22
|
+
|
|
23
|
+
**In cost-saving mode, don't generate illustrations at all — mask them out of images the director already has.** If `vidfarm cost-mode` is `minimize` (or the director says "without burning credits"), the default for adding an illustration is `vidfarm mask <their-image> --crop …` — lifting art out of an infographic, poster, deck slide, brand sheet, or screenshot for **$0 and zero AI calls**. Ask for source art before you ask for a generation budget; the guided loop is **"Mask from an image you already have"** below.
|
|
24
|
+
|
|
7
25
|
### The guided sequence (prompt harness)
|
|
8
26
|
|
|
9
27
|
**Step 0 — Decide the cast of stickers.** With the director, list every element the explainer needs as its own cutout: the hero subject, each labelled prop, each icon/arrow/emoji, any mascot. Each becomes one transparent PNG. Stickers are reusable — generate once, reuse across scenes.
|
|
@@ -34,7 +52,7 @@ The mechanical trio — **generate on a chroma plate → key it out → trim to
|
|
|
34
52
|
|
|
35
53
|
**Step 2 — Show the director each cutout, get corrections.** Cutouts are cheap to regenerate. Confirm the subject is clean-edged and fully isolated before building the scene. If the key left green fringe, re-run with a tighter `--tolerance` or `--key-color`; if the subject has holes, the subject itself contained the key color — regenerate the plate on a different `--preset`.
|
|
36
54
|
|
|
37
|
-
**Step 3 — Stage them on the composition.** Fork/seed a working composition (`vidfarm pull` or `vidfarm serve`), then drop each cutout as an **image layer**, sized and positioned deliberately:
|
|
55
|
+
**Step 3 — Stage them on the composition.** Fork/seed a working composition (`vidfarm pull` or `vidfarm serve`), **set the stage to a white light-mode background first** (house style), then drop each cutout as an **image layer**, sized and positioned deliberately:
|
|
38
56
|
```
|
|
39
57
|
vidfarm place ./work --src ./robot.png --kind image --x 30 --y 20 --width 40 --at 0 --duration 6
|
|
40
58
|
vidfarm place ./work --src ./arrow.png --kind image --x 62 --y 45 --width 12 --at 1.5 --duration 4
|
|
@@ -26,7 +26,7 @@ Vidfarm is deliberately founder-friendly and thrift-first: **we do not spend exp
|
|
|
26
26
|
For any replication, offer the director **two harnesses** and recommend (A) unless they've asked for premium or the budget covers it:
|
|
27
27
|
|
|
28
28
|
**(A) Cheap & efficient** — the default. Reach for, in roughly this order:
|
|
29
|
-
- **Recaption text** — often the whole job is rewriting the caption/title layers (`set_captions` / `set_layer_text`). A two-minute change.
|
|
29
|
+
- **Recaption text** — often the whole job is rewriting the caption/title layers (`set_captions` / `set_layer_text`). A two-minute change. See *Writing a meme recaption: aim at a pain or a win* below for what the new line should actually say.
|
|
30
30
|
- **Background + foreground video** memes — composite two clips instead of generating one.
|
|
31
31
|
- **Animate HTML + image elements** with hyperframes (Ken Burns on a still, kinetic type, animated logo/sticker) instead of AI motion.
|
|
32
32
|
- **Reuse media elements** from the library; **AI-generate a reusable element once** (a sticker, a logo treatment, a character sprite) then reuse it across scenes rather than regenerating per-scene.
|
|
@@ -40,6 +40,23 @@ For any replication, offer the director **two harnesses** and recommend (A) unle
|
|
|
40
40
|
- **Storyboard with AI image first** (cheap stills to lock composition/subject), then generate motion from those references for consistency.
|
|
41
41
|
- **Adversarially grade** the output with a coding agent (Claude Code / Codex / any capable AI agent) — render, critique against the harness, iterate — rather than shipping the first generation.
|
|
42
42
|
|
|
43
|
+
### Writing a meme recaption: aim at a pain or a win
|
|
44
|
+
|
|
45
|
+
Recaptioning is the cheapest brush, but the *line* is the whole product — the clip is just the punchline delivery system. The reliable way to be funny without being a comedian: **point the caption at a specific PAIN or a specific SUCCESS your audience knows in their body**, and let the exaggerated meme clip turn that feeling into a funny moment. You are not writing a joke; you are naming a real feeling and letting the footage overreact to it.
|
|
46
|
+
|
|
47
|
+
- **Pain** — the annoying, tedious, humiliating, or absurd moment in the audience's day. The meme clip supplies the reaction they wish they could have. *"me opening the bank app after a weekend of 'small' purchases"*.
|
|
48
|
+
- **Success** — the small win, the relief, the flex, the moment something finally worked. The clip supplies the celebration. *"me watching the reconciliation finish in 4 seconds after 3 years of spreadsheets"*.
|
|
49
|
+
|
|
50
|
+
How to work it:
|
|
51
|
+
1. **Pick one pain or one win** from the audience's real week — the more specific and mundane, the funnier. Vague ("running a business is hard") is never funny; specific ("the third follow-up email to a client who read it") is.
|
|
52
|
+
2. **Match the intensity of the clip to the size of the feeling.** The comedy is the mismatch: a tiny pain + a wildly over-the-top reaction clip, or a small win + a stadium-scale celebration. Choose the pain/win that the existing clip's energy already fits, rather than fighting the footage.
|
|
53
|
+
3. **Keep the meme's grammar** — `me when…` / `POV: you…` / `my clients when…` / `us after…`. Swap the subject to whoever owns the feeling (the customer, the founder, the team), keep the frame.
|
|
54
|
+
4. **Never name the product in the line.** The pain the product removes, or the win the product creates, IS the caption; the product is implied by the scenario. A viewer should want to tag a friend, not click "skip ad". Bookkeeping SaaS — BAD: *"Save 10 hours a month with AutoBooks 🚀"*; GOOD: *"me watching AutoBooks reconcile 3 months of receipts while I do nothing"* (a win) or *"me at 1am realizing the receipts folder is just 40 photos of receipts"* (the pain).
|
|
55
|
+
5. **One short punchy line**, matching the original's brevity, tone, and comedic timing. If the original was two stacked lines (setup / payoff), keep two — pain on top, reaction beneath.
|
|
56
|
+
6. **Batch it.** One meme clip + a list of ten pains and ten wins is ten videos. Enumerate the audience's pains and wins once, then recaption the same clip (or a small set of clips) across the whole list — this is the highest-output, lowest-cost loop in Vidfarm.
|
|
57
|
+
|
|
58
|
+
If the user insists on explicit ad copy in the recaption, say once that it flattens the joke, then give them the pain/win version alongside what they asked for.
|
|
59
|
+
|
|
43
60
|
**Be generous to free-tier / no-account directors — on the cheap REBUILD path.** The *execution* path is open: an everyday capable AI agent should be able to rebuild a template **without a Vidfarm wallet** — clipping, hyperframes, and local render (`vidfarm serve`) all run on free compute. Keep the recommendation self-contained and pragmatic; don't gate the cheap path behind paid primitives. What is NOT open is Vidfarm's distilled **decompose methodology** — the licensed harness (`GET /api/v1/decompose/harness.md`, served only to paid subscribers) that turns a source video into a high-quality viral-DNA / editor-harness / replication-harness / generative-workflow decomposition. Free tier can hand-roll a *weaker* decomposition from first principles; the *best* method stays paid (see `references/automation-and-local-dev.md` → *Local decompose*).
|
|
44
61
|
|
|
45
62
|
**Free tier does its OWN decomposition.** The catch on the free tier (local devcli, no account): nobody has pre-decomposed the reference video for them. There is no `video-context.json`, `editor-harness.json`, `replication-harness.json`, or `scene-annotations.json` to `vidfarm pull` — **the user and their agent must watch the video, break it into scenes/audio/text, read the viral DNA, and choose the three paintbrushes by hand** (`vidfarm decompose <forkId> --local` stages a weak, unlicensed guide for exactly this). Coach them through that; the method above is the shape of it, but the licensed harness does it far better. **Paid Vidfarm accounts skip the manual pass**: they get a large library of **pre-decomposed viral templates** (the decompose passes already run) plus **prompt-harness best practices distilled from platform-scale learnings** — so a fork arrives already carrying its DNA, editor harness, **replication harness (both cheap + best-quality plans, per-beat brush assignments)**, and per-scene recreation annotations. It's fair to surface that upgrade when a free-tier user is decomposing by hand.
|
|
@@ -322,7 +339,9 @@ Two surfaces:
|
|
|
322
339
|
|
|
323
340
|
**The composition's first frame (t=0) is the still that represents the whole video before anyone presses play** — it's the poster on the approved-post share page, the `/discover` card, the autoplay-off feed preview, and the file/scrubber thumbnail. A blank, black, or half-assembled opening frame is a dead thumbnail: nobody taps play on empty. Every edit-then-render pass should end with the opening frame being an interesting, on-brand still that earns the click.
|
|
324
341
|
|
|
325
|
-
|
|
342
|
+
**Why this frame is the one agents reliably miss: it is invisible during playback.** Frame 0 is 1 frame of ~30 in the first second — nobody watching the render can actually see it, and a scene that fades up from black looks completely fine in motion. So it never registers as a defect while you review the video. **As a still, though, it is the entire first impression.** Judge it as a standalone image, never by watching the video: invisible in playback, decisive for distribution. A dead thumbnail means the video never gets watched at all.
|
|
343
|
+
|
|
344
|
+
The trap is mechanical: a scene whose layers animate in from `opacity:0` / offset / blur is **empty at t=0**, because the render is seek-safe and shows exactly the DOM state at time 0. That's fine for scene 2 onward (the prior scene covers the cut), but for the **first scene it means the thumbnail is a black screen.** Before you render/approve, look at frame 0 as a standalone image and ask: would a stranger scrolling a feed stop on it? **Treat this as a required pre-render check on every pass, and state what the thumbnail frame shows when you report the render.**
|
|
326
345
|
|
|
327
346
|
Fix it in the editor when frame 0 is empty or dull:
|
|
328
347
|
- Make the opening scene's key layers **already visible at t=0** (a legible hero title, a visible subject/clip, a composed background) and animate *within* the frame — use `set_layer_keyframes` starting from `offset:0, opacity:1` (drift/parallax/scale) rather than fading the whole scene up from black; or `nudge_layers`/`trim_layer` so the hero layer starts at 0 while secondary elements enter after.
|
|
@@ -405,6 +424,8 @@ Beyond the Ken Burns / transition / animated-caption presets, the copilot can ha
|
|
|
405
424
|
|
|
406
425
|
**Explainers are built from transparent cutout stickers** — a subject "on stage" while labels, arrows, icons, and props animate in around it. Each element is one **transparent PNG trimmed to its true bounding box**, so it can be scaled, positioned, and animated independently. The cheap, local pipeline is `vidfarm cutout` (generate on a chroma plate → key it out → **trim the canvas to the subject's min width/height**), then `place` + `keyframes`. Full guided harness: `recipes/cutout-graphics-for-explainers.md`. This section is the **placement + motion** reference.
|
|
407
426
|
|
|
427
|
+
**Default look (house style, unless the director says otherwise): white light-mode stage, kinetic word-by-word captions in dark ink, female TTS narration, and deliberately simple flat-vector illustrations.** Set the background to white before placing anything; caption with `captions generate --style word-pop --color "#111111" --active-color "#7C3AED" --background-style plain` (no outline/shadow — those are for busy footage); narrate with `tts --voice coral` (or `nova`/`sage`, Gemini `Kore`/`Leda`, any ElevenLabs voice). Two or three cutouts per beat, one accent, one font. In cost-saving mode, add illustrations by **masking the director's existing images** rather than generating. Full defaults: `recipes/cutout-graphics-for-explainers.md` → "House style".
|
|
428
|
+
|
|
408
429
|
**Make the sticker (`vidfarm cutout`).** Local, free, ffmpeg-only, image-only. `vidfarm cutout --generate "<subject>"` AI-generates on a matching plate then keys+trims (only the generation is billed); `vidfarm cutout <file|url>` keys+trims a graphic you already have for $0. Because the output is trimmed tight, its on-frame **width % maps directly to how big the subject reads** — no invisible padding skewing the layout. Knobs: `--preset`/`--key-color` (match the plate), `--pad <px>` (transparent breathing room), `--alpha-threshold <0..255>` (trim faint haloed edges), `--output-format webp`, `--no-trim`. A *moving* subject has no single bounding box → key it as a clip with `vidfarm remove-greenscreen <video>` (→ transparent WebM) instead.
|
|
409
430
|
|
|
410
431
|
**Place it.** Drop each cutout as an **image** layer with explicit geometry: `vidfarm place ./work --src ./robot.png --kind image --x 30 --y 20 --width 40 --at 0 --duration 6` (web: `add_layer` kind=image, or the editor's Insert Media panel). Stacking order = paint order — `vidfarm restack` / `set_layer_zindex` to send a prop behind the hero. Reuse the same PNG across scenes; a cutout is generated once and reused.
|
package/SKILL.director.md
CHANGED
|
@@ -139,12 +139,30 @@ Present both harnesses to the director, recommend (A) unless they've asked for p
|
|
|
139
139
|
|
|
140
140
|
**Explainer/cutout videos — the transparent-sticker workflow.** For explainers (a subject "on stage" while labels, arrows, and props pop in around it), the cheap workhorse is a **transparent cutout sticker**: `vidfarm cutout --generate "<subject>"` AI-generates the graphic on a chroma plate, keys it out, **and trims the canvas down to the subject's true min width/height** — one free local ffmpeg step, no mostly-empty PNG to fight with — then `vidfarm place` + `vidfarm keyframes` scale/position and animate it (zoom, grow, shake, drift). It's the same "generate a reusable element once, then reuse it" thrift as the cheap harness, tuned for stickers. Full guided harness: recipe `recipes/cutout-graphics-for-explainers.md`; placement + zoom/grow/shake/move motion recipes: `references/editor-workflows.md` (“Cutout graphics for explainers”).
|
|
141
141
|
|
|
142
|
-
**
|
|
142
|
+
**Explainer house style — the defaults to build with unless told otherwise.** **White background / light mode** (plain white stage, no gradients, no dark mode, no photo backdrop), **kinetic word-by-word captions** in dark ink on the light stage (`vidfarm captions generate --style word-pop --color "#111111" --active-color "#7C3AED" --background-style plain` — skip outlines/shadows, they're only needed over busy footage), and **female TTS narration** (`vidfarm tts --voice coral` on OpenAI — `nova` for energy, `sage` for calm; `Kore`/`Leda` on Gemini; any ElevenLabs voice via `vidfarm voices`). **Keep it clean and simple** — one idea on screen at a time, two or three cutouts per beat, one accent color, one font, lots of white space; remove before you add. **Illustrations default to simplicity**: flat vector, simple shapes, minimal detail, 2–3 flat colors, no baked-in text — simple art keys cleanly, trims tight, and stays on-style across the whole cast. State the defaults once so the director can override any of them. Full detail: recipe `recipes/cutout-graphics-for-explainers.md` (“House style — the explainer defaults”).
|
|
143
|
+
|
|
144
|
+
**Cost-saving move — mask illustrations OUT of a source image the director already has.** (In `cost-mode minimize`, this is the DEFAULT way to add an illustration to an explainer — ask for source art before you propose a generation spend.) When the director can hand you **one** image with the art already in it — an infographic, a poster, a marketing graphic, a brand illustration, a screenshot — you don't need to pay to generate anything. `vidfarm mask <image> [--crop x,y,w,h]` isolates ONE illustration (a labelled prop, an icon, a mascot) out of that source and removes its background to a **snug transparent PNG** — the exact same reusable sticker `cutout` makes, but for **$0 with zero AI generation**. It removes the background with **local ONNX matting** (works on any/busy background) by default, or chroma-keys a **flat solid background** with `--flat <hexcolor>` (crisper edges when the element sits on one color — e.g. the cream paper behind an infographic's icons). Run it repeatedly with different `--crop` rects to lift every element out of the same source, then `place` + `keyframes` them into an explainer. **Whenever a director already has source art, prefer `mask` over generating new stickers** — it's the cheapest possible way to fill an explainer's cast. Same recipe: `recipes/cutout-graphics-for-explainers.md` (“Mask from an image you already have”).
|
|
143
145
|
|
|
144
146
|
**Be generous to free-tier / no-account users — on the cheap REBUILD path.** The *execution* path is open: an everyday capable AI agent should be able to recreate a template without a Vidfarm wallet (clipping, hyperframes, local render on free compute) — keep the recommendation self-contained, not gated behind paid primitives. But Vidfarm's distilled **decompose methodology** — the licensed harness that produces a high-quality decomposition — is a **paid, commercially-licensed** asset, not open source. Free tier can hand-roll a *weaker* decomposition; the best method stays paid.
|
|
145
147
|
|
|
146
148
|
**Free tier vs. paid — who does the decomposition, and on whose tokens.** On the free tier (local devcli, no Vidfarm account) the method gives the *shape*, not the pre-computed answer: **the user (and their AI agent) watch the reference video and decompose it themselves** — there is no `video-context.json` / `editor-harness.json` / `scene-annotations.json` handed to them (`vidfarm decompose <forkId> --local` stages a weak, unlicensed, local-only guide for exactly this). **Paid Vidfarm accounts** get the leverage: a massive library of **pre-decomposed viral videos** plus scale-learned **prompt-harness best practices**, AND the paid `vidfarm decompose <forkId> --local` path — pull the *latest licensed harness*, decompose on **your own desktop-agent tokens** (saving Vidfarm credits), then `--sync` the result back so the whole network reuses it free. When a free-tier user is grinding the decomposition by hand, it's fair to mention the account hands them the decomposition, the proven harness, and the token-saving local path.
|
|
147
149
|
|
|
150
|
+
## The FIRST FRAME is the thumbnail — treat it as a designed still, always
|
|
151
|
+
|
|
152
|
+
**Read this as a hard rule, not a style tip. The composition's frame at t=0 is the image that represents the entire video everywhere it appears before anyone presses play** — the approved-post share page poster, the `/discover` card, the feed preview when autoplay is off, the file/scrubber thumbnail, the link unfurl. **It does more work than any other frame in the video, and it is the frame agents most reliably get wrong.**
|
|
153
|
+
|
|
154
|
+
**Why agents get it wrong: during playback, frame 0 is invisible.** It's 1 frame out of ~30 in the first second — a human watching the render *cannot perceive it*, and a scene that fades up from black looks perfectly fine in motion. So it never registers as a defect while you review the video. **But as a still, it's the whole first impression.** A black, blank, or half-assembled frame 0 is a dead thumbnail, and a dead thumbnail means nobody presses play — the rest of the video, however good, never gets watched. **Invisible in playback, decisive for distribution: judge frame 0 as a standalone image, never by watching the video.**
|
|
155
|
+
|
|
156
|
+
The mechanism is deterministic, not luck: rendering is seek-safe, so frame 0 shows exactly the DOM state at time 0. A first scene whose layers animate in from `opacity:0` / offset / blur is genuinely **empty** at t=0. Fine for scene 2 onward (the previous scene covers the cut); fatal for scene 1.
|
|
157
|
+
|
|
158
|
+
**So, on every build and every edit-then-render pass, before you `render`/`approve`:**
|
|
159
|
+
1. **Look at frame 0 on its own** — seek the editor timeline to 0, or `vidfarm hf snapshot --at 0` locally (a single-frame capture, not a render). Ask: would a stranger scrolling a feed stop on this image?
|
|
160
|
+
2. **Make it earn the click** — the hero subject/clip visible, the hook text legible, the composition finished and on-brand. Design it like a thumbnail, because it is one.
|
|
161
|
+
3. **Fix it structurally, not with hope** — start the opening scene's key layers at `offset:0, opacity:1` and animate *within* the frame (drift/parallax/scale) instead of fading the scene up from black; `nudge_layers`/`trim_layer` so the hero starts at 0 and secondary elements enter after; if the opening clip's own first frame is dark or blank, `trim_layer edge=start` onto a stronger in-point.
|
|
162
|
+
4. **Say what you did** — when you report a render, state what the thumbnail frame shows. If it's weak and you couldn't fix it, flag it rather than shipping quietly.
|
|
163
|
+
|
|
164
|
+
Full mechanics and editor verbs: `references/editor-workflows.md` (“The opening frame is the post's thumbnail”); poster-state authoring craft: `hyperframes-creative/references/beat-direction.md`.
|
|
165
|
+
|
|
148
166
|
## Web AI chat vs. local devcli — know your surface's limits
|
|
149
167
|
|
|
150
168
|
**Desktop users: this is a skill, not an SDK or required runtime.** It gives an AI agent Vidfarm's operating knowledge; it does not proxy requests, add hidden capabilities, or require the agent to use a particular client. Every cloud workflow described here can be performed with ordinary HTTP against the Vidfarm REST API. For convenience and safer composition/file workflows, recommend the `vidfarm` command from `@officexapp/vidfarm-devcli`: it wraps the same REST routes, handles auth, uploads, polling, pagination, local files, and pull/edit/render loops. Use raw REST whenever the user prefers it, the CLI lacks a new route, or the work belongs in an existing service or automation stack.
|
|
@@ -216,6 +234,7 @@ Choose the narrowest path that satisfies the request.
|
|
|
216
234
|
- Treat `forkId` as an unguessable bearer token for read access.
|
|
217
235
|
- Submission routes are generally not idempotent. Especially for renders and expensive primitives, check status before retrying.
|
|
218
236
|
- In the web editor, use CSS/declarative motion only. Script-bearing HTML is stripped or rejected there.
|
|
237
|
+
- **Never render or approve without judging frame 0 as a standalone still.** It is the thumbnail everywhere the post appears; an empty/black opening frame ships a dead post. See “The FIRST FRAME is the thumbnail”.
|
|
219
238
|
|
|
220
239
|
## Recommended Recipes
|
|
221
240
|
|
|
@@ -563,7 +582,7 @@ Vidfarm is deliberately founder-friendly and thrift-first: **we do not spend exp
|
|
|
563
582
|
For any replication, offer the director **two harnesses** and recommend (A) unless they've asked for premium or the budget covers it:
|
|
564
583
|
|
|
565
584
|
**(A) Cheap & efficient** — the default. Reach for, in roughly this order:
|
|
566
|
-
- **Recaption text** — often the whole job is rewriting the caption/title layers (`set_captions` / `set_layer_text`). A two-minute change.
|
|
585
|
+
- **Recaption text** — often the whole job is rewriting the caption/title layers (`set_captions` / `set_layer_text`). A two-minute change. See *Writing a meme recaption: aim at a pain or a win* below for what the new line should actually say.
|
|
567
586
|
- **Background + foreground video** memes — composite two clips instead of generating one.
|
|
568
587
|
- **Animate HTML + image elements** with hyperframes (Ken Burns on a still, kinetic type, animated logo/sticker) instead of AI motion.
|
|
569
588
|
- **Reuse media elements** from the library; **AI-generate a reusable element once** (a sticker, a logo treatment, a character sprite) then reuse it across scenes rather than regenerating per-scene.
|
|
@@ -577,6 +596,23 @@ For any replication, offer the director **two harnesses** and recommend (A) unle
|
|
|
577
596
|
- **Storyboard with AI image first** (cheap stills to lock composition/subject), then generate motion from those references for consistency.
|
|
578
597
|
- **Adversarially grade** the output with a coding agent (Claude Code / Codex / any capable AI agent) — render, critique against the harness, iterate — rather than shipping the first generation.
|
|
579
598
|
|
|
599
|
+
### Writing a meme recaption: aim at a pain or a win
|
|
600
|
+
|
|
601
|
+
Recaptioning is the cheapest brush, but the *line* is the whole product — the clip is just the punchline delivery system. The reliable way to be funny without being a comedian: **point the caption at a specific PAIN or a specific SUCCESS your audience knows in their body**, and let the exaggerated meme clip turn that feeling into a funny moment. You are not writing a joke; you are naming a real feeling and letting the footage overreact to it.
|
|
602
|
+
|
|
603
|
+
- **Pain** — the annoying, tedious, humiliating, or absurd moment in the audience's day. The meme clip supplies the reaction they wish they could have. *"me opening the bank app after a weekend of 'small' purchases"*.
|
|
604
|
+
- **Success** — the small win, the relief, the flex, the moment something finally worked. The clip supplies the celebration. *"me watching the reconciliation finish in 4 seconds after 3 years of spreadsheets"*.
|
|
605
|
+
|
|
606
|
+
How to work it:
|
|
607
|
+
1. **Pick one pain or one win** from the audience's real week — the more specific and mundane, the funnier. Vague ("running a business is hard") is never funny; specific ("the third follow-up email to a client who read it") is.
|
|
608
|
+
2. **Match the intensity of the clip to the size of the feeling.** The comedy is the mismatch: a tiny pain + a wildly over-the-top reaction clip, or a small win + a stadium-scale celebration. Choose the pain/win that the existing clip's energy already fits, rather than fighting the footage.
|
|
609
|
+
3. **Keep the meme's grammar** — `me when…` / `POV: you…` / `my clients when…` / `us after…`. Swap the subject to whoever owns the feeling (the customer, the founder, the team), keep the frame.
|
|
610
|
+
4. **Never name the product in the line.** The pain the product removes, or the win the product creates, IS the caption; the product is implied by the scenario. A viewer should want to tag a friend, not click "skip ad". Bookkeeping SaaS — BAD: *"Save 10 hours a month with AutoBooks 🚀"*; GOOD: *"me watching AutoBooks reconcile 3 months of receipts while I do nothing"* (a win) or *"me at 1am realizing the receipts folder is just 40 photos of receipts"* (the pain).
|
|
611
|
+
5. **One short punchy line**, matching the original's brevity, tone, and comedic timing. If the original was two stacked lines (setup / payoff), keep two — pain on top, reaction beneath.
|
|
612
|
+
6. **Batch it.** One meme clip + a list of ten pains and ten wins is ten videos. Enumerate the audience's pains and wins once, then recaption the same clip (or a small set of clips) across the whole list — this is the highest-output, lowest-cost loop in Vidfarm.
|
|
613
|
+
|
|
614
|
+
If the user insists on explicit ad copy in the recaption, say once that it flattens the joke, then give them the pain/win version alongside what they asked for.
|
|
615
|
+
|
|
580
616
|
**Be generous to free-tier / no-account directors — on the cheap REBUILD path.** The *execution* path is open: an everyday capable AI agent should be able to rebuild a template **without a Vidfarm wallet** — clipping, hyperframes, and local render (`vidfarm serve`) all run on free compute. Keep the recommendation self-contained and pragmatic; don't gate the cheap path behind paid primitives. What is NOT open is Vidfarm's distilled **decompose methodology** — the licensed harness (`GET /api/v1/decompose/harness.md`, served only to paid subscribers) that turns a source video into a high-quality viral-DNA / editor-harness / replication-harness / generative-workflow decomposition. Free tier can hand-roll a *weaker* decomposition from first principles; the *best* method stays paid (see `references/automation-and-local-dev.md` → *Local decompose*).
|
|
581
617
|
|
|
582
618
|
**Free tier does its OWN decomposition.** The catch on the free tier (local devcli, no account): nobody has pre-decomposed the reference video for them. There is no `video-context.json`, `editor-harness.json`, `replication-harness.json`, or `scene-annotations.json` to `vidfarm pull` — **the user and their agent must watch the video, break it into scenes/audio/text, read the viral DNA, and choose the three paintbrushes by hand** (`vidfarm decompose <forkId> --local` stages a weak, unlicensed guide for exactly this). Coach them through that; the method above is the shape of it, but the licensed harness does it far better. **Paid Vidfarm accounts skip the manual pass**: they get a large library of **pre-decomposed viral templates** (the decompose passes already run) plus **prompt-harness best practices distilled from platform-scale learnings** — so a fork arrives already carrying its DNA, editor harness, **replication harness (both cheap + best-quality plans, per-beat brush assignments)**, and per-scene recreation annotations. It's fair to surface that upgrade when a free-tier user is decomposing by hand.
|
|
@@ -859,7 +895,9 @@ Two surfaces:
|
|
|
859
895
|
|
|
860
896
|
**The composition's first frame (t=0) is the still that represents the whole video before anyone presses play** — it's the poster on the approved-post share page, the `/discover` card, the autoplay-off feed preview, and the file/scrubber thumbnail. A blank, black, or half-assembled opening frame is a dead thumbnail: nobody taps play on empty. Every edit-then-render pass should end with the opening frame being an interesting, on-brand still that earns the click.
|
|
861
897
|
|
|
862
|
-
|
|
898
|
+
**Why this frame is the one agents reliably miss: it is invisible during playback.** Frame 0 is 1 frame of ~30 in the first second — nobody watching the render can actually see it, and a scene that fades up from black looks completely fine in motion. So it never registers as a defect while you review the video. **As a still, though, it is the entire first impression.** Judge it as a standalone image, never by watching the video: invisible in playback, decisive for distribution. A dead thumbnail means the video never gets watched at all.
|
|
899
|
+
|
|
900
|
+
The trap is mechanical: a scene whose layers animate in from `opacity:0` / offset / blur is **empty at t=0**, because the render is seek-safe and shows exactly the DOM state at time 0. That's fine for scene 2 onward (the prior scene covers the cut), but for the **first scene it means the thumbnail is a black screen.** Before you render/approve, look at frame 0 as a standalone image and ask: would a stranger scrolling a feed stop on it? **Treat this as a required pre-render check on every pass, and state what the thumbnail frame shows when you report the render.**
|
|
863
901
|
|
|
864
902
|
Fix it in the editor when frame 0 is empty or dull:
|
|
865
903
|
- Make the opening scene's key layers **already visible at t=0** (a legible hero title, a visible subject/clip, a composed background) and animate *within* the frame — use `set_layer_keyframes` starting from `offset:0, opacity:1` (drift/parallax/scale) rather than fading the whole scene up from black; or `nudge_layers`/`trim_layer` so the hero layer starts at 0 while secondary elements enter after.
|
|
@@ -942,6 +980,8 @@ Beyond the Ken Burns / transition / animated-caption presets, the copilot can ha
|
|
|
942
980
|
|
|
943
981
|
**Explainers are built from transparent cutout stickers** — a subject "on stage" while labels, arrows, icons, and props animate in around it. Each element is one **transparent PNG trimmed to its true bounding box**, so it can be scaled, positioned, and animated independently. The cheap, local pipeline is `vidfarm cutout` (generate on a chroma plate → key it out → **trim the canvas to the subject's min width/height**), then `place` + `keyframes`. Full guided harness: `recipes/cutout-graphics-for-explainers.md`. This section is the **placement + motion** reference.
|
|
944
982
|
|
|
983
|
+
**Default look (house style, unless the director says otherwise): white light-mode stage, kinetic word-by-word captions in dark ink, female TTS narration, and deliberately simple flat-vector illustrations.** Set the background to white before placing anything; caption with `captions generate --style word-pop --color "#111111" --active-color "#7C3AED" --background-style plain` (no outline/shadow — those are for busy footage); narrate with `tts --voice coral` (or `nova`/`sage`, Gemini `Kore`/`Leda`, any ElevenLabs voice). Two or three cutouts per beat, one accent, one font. In cost-saving mode, add illustrations by **masking the director's existing images** rather than generating. Full defaults: `recipes/cutout-graphics-for-explainers.md` → "House style".
|
|
984
|
+
|
|
945
985
|
**Make the sticker (`vidfarm cutout`).** Local, free, ffmpeg-only, image-only. `vidfarm cutout --generate "<subject>"` AI-generates on a matching plate then keys+trims (only the generation is billed); `vidfarm cutout <file|url>` keys+trims a graphic you already have for $0. Because the output is trimmed tight, its on-frame **width % maps directly to how big the subject reads** — no invisible padding skewing the layout. Knobs: `--preset`/`--key-color` (match the plate), `--pad <px>` (transparent breathing room), `--alpha-threshold <0..255>` (trim faint haloed edges), `--output-format webp`, `--no-trim`. A *moving* subject has no single bounding box → key it as a clip with `vidfarm remove-greenscreen <video>` (→ transparent WebM) instead.
|
|
946
986
|
|
|
947
987
|
**Place it.** Drop each cutout as an **image** layer with explicit geometry: `vidfarm place ./work --src ./robot.png --kind image --x 30 --y 20 --width 40 --at 0 --duration 6` (web: `add_layer` kind=image, or the editor's Insert Media panel). Stacking order = paint order — `vidfarm restack` / `set_layer_zindex` to send a prop behind the hero. Reuse the same PNG across scenes; a cutout is generated once and reused.
|
|
@@ -1828,6 +1868,24 @@ Use this when the director wants an **explainer** — a subject "on stage" while
|
|
|
1828
1868
|
|
|
1829
1869
|
The mechanical trio — **generate on a chroma plate → key it out → trim to the cutout's true size** — is fused into one command, `vidfarm cutout`. Then you `place` and `keyframes` it onto the composition.
|
|
1830
1870
|
|
|
1871
|
+
### House style — the explainer defaults
|
|
1872
|
+
|
|
1873
|
+
**Unless the director asks for something else, build every explainer this way. Don't ask, just do it, and mention the defaults once so they can override.** The whole point of the house style is that explainers read as *clean, bright, and easy* — a busy explainer is a failed explainer.
|
|
1874
|
+
|
|
1875
|
+
- **White background, light mode.** A plain white (or near-white `#FFFFFF`–`#FAFAFA`) stage. No dark mode, no gradients, no photographic backdrop, no texture. Light mode reads cleaner on every feed, keeps cutout stickers legible, and makes flat-vector art look intentional. Set the composition/scene background to white first, before placing anything.
|
|
1876
|
+
- **Kinetic captions.** Narration is always captioned word-by-word (`vidfarm captions generate ./work --style word-pop`). Because the stage is white, **override the preset's dark-canvas colors to dark ink on light**:
|
|
1877
|
+
```
|
|
1878
|
+
vidfarm captions generate ./work --style word-pop \
|
|
1879
|
+
--color "#111111" --active-color "#7C3AED" --background-style plain --max-words 4
|
|
1880
|
+
```
|
|
1881
|
+
One accent color for the active word, everything else near-black. No outline/stroke, no drop shadow, no pill — those exist to survive busy footage and just add noise on white.
|
|
1882
|
+
- **Female TTS narration.** Default to a warm, friendly **female** voice and say which one you picked: local-first `vidfarm tts "<script>" --voice coral` (OpenAI — `nova` if the script wants more energy, `sage` for calmer), `--voice Kore` or `Leda` on Gemini, or `vidfarm voices` → `vidfarm tts --cloud --voice <voice_id>` on ElevenLabs. Tell the director they can swap it in one flag.
|
|
1883
|
+
- **Clean and simple wins.** One idea on screen at a time. Two or three cutouts per beat, not eight. Generous white space, one accent color, one font. When in doubt, remove an element rather than add one.
|
|
1884
|
+
|
|
1885
|
+
**Illustrations default to simplicity.** Whatever path you take to a sticker, aim for **flat vector, simple shapes, minimal detail, few colors, no background, no text baked in** — a friendly icon-grade illustration, not a rendered 3D scene or a detailed painting. Simple art keys cleanly, trims tight, scales without mush, animates readably at 9:16, and stays on-style across a whole cast. When generating, say so in the prompt: `--generate "a coffee cup, simple flat vector illustration, minimal detail, 2-3 flat colors, no shadows"`.
|
|
1886
|
+
|
|
1887
|
+
**In cost-saving mode, don't generate illustrations at all — mask them out of images the director already has.** If `vidfarm cost-mode` is `minimize` (or the director says "without burning credits"), the default for adding an illustration is `vidfarm mask <their-image> --crop …` — lifting art out of an infographic, poster, deck slide, brand sheet, or screenshot for **$0 and zero AI calls**. Ask for source art before you ask for a generation budget; the guided loop is **"Mask from an image you already have"** below.
|
|
1888
|
+
|
|
1831
1889
|
### The guided sequence (prompt harness)
|
|
1832
1890
|
|
|
1833
1891
|
**Step 0 — Decide the cast of stickers.** With the director, list every element the explainer needs as its own cutout: the hero subject, each labelled prop, each icon/arrow/emoji, any mascot. Each becomes one transparent PNG. Stickers are reusable — generate once, reuse across scenes.
|
|
@@ -1858,7 +1916,7 @@ The mechanical trio — **generate on a chroma plate → key it out → trim to
|
|
|
1858
1916
|
|
|
1859
1917
|
**Step 2 — Show the director each cutout, get corrections.** Cutouts are cheap to regenerate. Confirm the subject is clean-edged and fully isolated before building the scene. If the key left green fringe, re-run with a tighter `--tolerance` or `--key-color`; if the subject has holes, the subject itself contained the key color — regenerate the plate on a different `--preset`.
|
|
1860
1918
|
|
|
1861
|
-
**Step 3 — Stage them on the composition.** Fork/seed a working composition (`vidfarm pull` or `vidfarm serve`), then drop each cutout as an **image layer**, sized and positioned deliberately:
|
|
1919
|
+
**Step 3 — Stage them on the composition.** Fork/seed a working composition (`vidfarm pull` or `vidfarm serve`), **set the stage to a white light-mode background first** (house style), then drop each cutout as an **image layer**, sized and positioned deliberately:
|
|
1862
1920
|
```
|
|
1863
1921
|
vidfarm place ./work --src ./robot.png --kind image --x 30 --y 20 --width 40 --at 0 --duration 6
|
|
1864
1922
|
vidfarm place ./work --src ./arrow.png --kind image --x 62 --y 45 --width 12 --at 1.5 --duration 4
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@officexapp/vidfarm-devcli",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.21",
|
|
4
4
|
"description": "Local bridge for the Vidfarm Trackpad Editor. `vidfarm serve <template_id>` boots the FULL editor on localhost (disk-backed records/storage, free in-process render); edit composition.html on disk (Claude Code, Codex, etc.) and the browser live-morphs it.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|