@officexapp/vidfarm-devcli 0.21.45 → 0.21.47

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 (39) hide show
  1. package/.agents/skills/editor-capabilities/SKILL.md +2 -0
  2. package/.agents/skills/vidfarm/SKILL.md +60 -7
  3. package/.agents/skills/vidfarm/harnesses/explainer.HARNESS.md +1 -1
  4. package/.agents/skills/vidfarm/harnesses/product-demo.HARNESS.md +2 -0
  5. package/.agents/skills/vidfarm/harnesses/short-form.HARNESS.md +1 -0
  6. package/.agents/skills/vidfarm/recipes/local-edit-render-approve.md +1 -1
  7. package/.agents/skills/vidfarm/references/agent-included-imagegen.md +75 -0
  8. package/.agents/skills/vidfarm/references/assets-and-sourcing.md +71 -2
  9. package/.agents/skills/vidfarm/references/automation-and-local-dev.md +13 -6
  10. package/.agents/skills/vidfarm/references/browser-harness.md +93 -0
  11. package/.agents/skills/vidfarm/references/editor-workflows.md +22 -0
  12. package/SKILL.director.md +337 -16
  13. package/SKILL.md +45 -4
  14. package/dist/src/cli.js +210 -4
  15. package/dist/src/devcli/agent-imagegen.js +181 -0
  16. package/dist/src/devcli/browser-harness.js +384 -0
  17. package/dist/src/devcli/clip-store.js +41 -3
  18. package/dist/src/devcli/cost-mode.js +23 -3
  19. package/dist/src/devcli/doctor.js +52 -3
  20. package/dist/src/devcli/hyperframes-cli.js +11 -1
  21. package/dist/src/devcli/local-render.js +4 -7
  22. package/dist/src/devcli/marketplace-gigs.js +651 -0
  23. package/dist/src/devcli/qa-check.js +89 -1
  24. package/dist/src/devcli/shared-folder.js +387 -0
  25. package/dist/src/devcli/stills.js +4 -8
  26. package/dist/src/lib/ffprobe-path.js +64 -0
  27. package/dist/src/lib/render-media-prep.js +2 -11
  28. package/dist/src/services/clip-curation/ffmpeg.js +4 -15
  29. package/dist/src/services/clip-curation/local-agent.js +6 -2
  30. package/experiments.md +2 -2
  31. package/marketplace.md +549 -0
  32. package/package.json +21 -10
  33. package/public/assets/file-directory-app.js +34 -34
  34. package/public/serve-shells/library-files.html +5 -1
  35. package/public/serve-shells/library-raws.html +10 -1
  36. package/public/serve-shells/tools-clipper.html +5 -1
  37. package/public/serve-shells/tools-image.html +5 -1
  38. package/public/serve-shells/tools-video.html +5 -1
  39. package/crowdsourcing.md +0 -157
@@ -143,6 +143,8 @@ You author into HTML, which makes it dangerously easy to build a **web page inst
143
143
  - **Gradient text fills, neon border glows, elevation shadows, glassmorphism**, navbars, hero sections, feature grids, `<ul>` bullet lists, tables, "as seen in" strips.
144
144
  - **Web-default type** — Inter/Roboto/system-ui/Arial/Helvetica at weight 400–600 and 16–24px.
145
145
 
146
+ **NO LAYOUT TEMPLATES — judge the whole frame, not just the element.** Everything above judges one element, and a frame can pass element-by-element and still be a web page. The archetype: a **modal** — backdrop dimmed and blurred out of focus, and floating on it a rounded bordered box with a big headline, a smaller support line, and a fat CTA button. **The stack is the tell, not the box:** strip the border, the fill and the capsule, keep headline → subheadline → CTA centred in a well with even margins, and it still reads as a landing page — the viewer recognizes the *shape* before reading a word. Banned at frame level: a modal/dialog floating over a receded backdrop · the hero triplet and its cousins (title + kicker + logo lockup, question + answer + URL) · a full-frame dim wash used to stage a floating block (a legibility band on ONE caption is legal; a page-wide wash is not) · nav / hero / feature-row / testimonial / footer sections · a blurred website screenshot as the background plate · a centred content column with document margins. **Fix: unstack it into time** — headline is the hook at `start:0`, the support line lands on the next cut, the CTA is spoken or a bare caption on the last frame. Before you place any text group ask: *am I arranging words relative to each other, or relative to the picture?* Relative to each other = layout = web. Two on-screen text runs at once is the ceiling.
147
+
146
148
  **Greppable smell test:** typing `btn`, `badge`, `chip`, `tag`, `card`, `panel`, `container`, `row`/`col-`, `hero`, `cta`, `rounded-full`, `shadow-lg`, `backdrop-blur`, `bg-gradient-to-r`, `border border-…` → **stop and rewrite as timed text on footage.** A re-theme onto a SaaS/product subject is exactly where this creeps in — do NOT import the brand's website design language into the video.
147
149
 
148
150
  **ALLOWED / encouraged:** arrows (drawn or animated), circle / scribble / underline highlight strokes, **italics**, ALL-CAPS, a single word in a pop color, mixed weights, inline emoji (sparingly), transparent cut-out stickers via `create-overlay`, and mock social UI (iMessage bubbles, a TikTok comment card, a countdown bar) — all native to the platform.
@@ -58,15 +58,33 @@ For local, wallet-free work, Vidfarm runs on a **three-part toolchain** a deskto
58
58
  ```bash
59
59
  npm install -g @officexapp/vidfarm-devcli # the `vidfarm` orchestrator
60
60
  npm install -g hyperframes # Vidfarm's open-source render/animation engine (whitelabel)
61
- # ffmpeg: use a system install (brew install ffmpeg / apt install ffmpeg) or the
62
- # bundled ffmpeg-static that ships with the devcli — a PATH ffmpeg is honored first.
63
61
  vidfarm doctor # verifies all three (+ Chrome) in one shot
64
62
  ```
65
63
 
64
+ **Install ffmpeg only if `doctor` asks for it.** The devcli bundles `ffmpeg-static` plus a
65
+ per-platform ffprobe, which covers macOS, Linux, and Windows x64 out of the box. A system
66
+ ffmpeg on PATH is honored first, so add one (`brew install ffmpeg` / `apt install ffmpeg` /
67
+ `winget install Gyan.FFmpeg`) only when `doctor` reports ffmpeg missing. Installing it up
68
+ front is the single most common wasted setup step.
69
+
70
+ **Windows setup notes** (run these in PowerShell, not Git Bash or cmd):
71
+
72
+ | Symptom | Cause | Fix |
73
+ |---|---|---|
74
+ | `npm i -g` takes many minutes | Defender scans every extracted file | `Add-MpPreference -ExclusionPath "$env:APPDATA\npm", "$env:APPDATA\npm-cache", "$env:LOCALAPPDATA\npm-cache"` |
75
+ | `node-gyp` / `MSB` errors during install | `better-sqlite3` has no prebuilt binary for this Node ABI | **Ignore it.** It is an OPTIONAL dependency; only `vidfarm clips` needs it. To enable it, install "Desktop development with C++" from the Visual Studio Installer. |
76
+ | `doctor` reports ffmpeg missing on a Surface / Copilot+ PC | Windows on ARM has no prebuilt ffmpeg | Install a system ffmpeg and put it on PATH |
77
+ | `brew: command not found` | The agent followed a macOS instruction | ffmpeg is already bundled — skip the step |
78
+
79
+ Never treat a `better-sqlite3` build error as a failed install. Run `vidfarm doctor` and read
80
+ the `clip library` line: it states plainly whether anything is actually unavailable.
81
+
66
82
  - **`vidfarm` devcli** — the orchestrator: auth, discovery, pull/edit/render loops, primitives, and the local `serve` editor. It wraps the same REST API and shells out to the two engines below for local compute.
67
83
  - **`ffmpeg`** — the media engine the devcli drives for **every local media op**: greenscreen/chroma-key (`vidfarm remove-greenscreen --local`), demux for STT/captions, clip cutting (`raws scan`), stills, audio trims. It's a **hard requirement** (`vidfarm doctor` fails without it); `ffmpeg-static` is bundled, but install a system ffmpeg if doctor flags it.
68
84
  - **`hyperframes`** — **Vidfarm's own render/animation engine, open-source under a whitelabel.** *Vidfarm renders ARE hyperframes renders* — same composition/animation/render capability, Vidfarm-branded. The devcli bundles it and exposes it directly as **`vidfarm hf <subcommand>`** (render, capture, validate, preview, `remove-background` ONNX matting, transcribe, beats…). Installing it standalone (`npm i -g hyperframes`) makes local render / TTS / STT / matting run **natively** instead of a slow `npx -y hyperframes` fallback.
69
85
 
86
+ **The optional fourth tool — `browser-harness`, for free footage sourcing.** Not part of the render toolchain; it is what makes the *sourcing* half free. It attaches you to the user's own running Chrome over CDP, so you can drive Google Videos / Images / News and download media yourself instead of calling the **paid** `video-search` / `image-search` / `news-search` / `download-video` primitives. `vidfarm browser setup` installs it (via `uv`) and prints the one Chrome step the user must do; `vidfarm browse <videos|images|news|page> "<query>"` mints the recipe for a job; `vidfarm doctor` reports it as `browser control`. **Offer it to every free-plan user and everyone in cost mode `minimize` before you tell them a search needs a paid plan** — it takes a minute and costs nothing. Ask first: it drives their personal browser. Full page: `references/browser-harness.md`.
87
+
70
88
  Because `hyperframes` is Vidfarm's whitelabel, **treat it as Vidfarm**: never route it through an external HeyGen/vendor account, and keep `HYPERFRAMES_SKIP_SKILLS=1` + `HYPERFRAMES_NO_TELEMETRY=1` set so it stays pinned and never phones home (the devcli sets these for its children automatically). Run `vidfarm doctor` at session start to confirm the trio is healthy before any local loop.
71
89
 
72
90
  Use this skill when the user wants to:
@@ -87,7 +105,7 @@ Vidfarm work can burn real AI credits on the user's wallet / provider keys. **Sa
87
105
 
88
106
  | Mode | Cost per video | What it means |
89
107
  |---|---|---|
90
- | **minimize** | **$0 — explicitly free** | free local compute + free stock media only; billed AI is refused without `--yes` |
108
+ | **minimize** | **$0 — explicitly free** | free local compute + free stock media, plus any image generation YOUR OWN agent subscription already includes; billed AI is refused without `--yes` |
91
109
  | **hybrid** *(recommended)* | **~$0.01–$1** | free where it's free; pay AI only where it clearly wins |
92
110
  | **rich-ai** | **$1+** | AI video gen mints **reusable greenscreen raws**, then hyperframes HTML/CSS motion remixes them with the rest of the library — the footage is saved and reused later |
93
111
  | **pure-videogen** | **$5+** | every shot is generated: text script → image storyboard → frame-by-frame scene generation. No reuse, no HTML motion |
@@ -98,6 +116,8 @@ Vidfarm work can burn real AI credits on the user's wallet / provider keys. **Sa
98
116
  - **Check the keyless sources first — Openverse and iconify.** Openverse (CC/CC0 **music, SFX, and images**) and iconify (**icons**) need **no account or key at all**, so they always work in `minimize` mode. Prefer them for BGM, sound effects, icons, and CC imagery before anything else.
99
117
  - **Icons, STICKERS, illustrations, 3D props and Lottie come from IconScout, not from an image model — in EVERY cost mode.** `vidfarm iconscout "<meaning>" --style sticker --free` searches a designer catalog for $0 (search is always free; a free asset downloads for $0 and only asks for a credit line). It needs **no key at all** — vidfarm's own IconScout account serves it. An AI attempt costs cents, needs a prompt loop, and rarely returns a clean transparent vector, so this wins on price *and* on quality. `vidfarm iconscout get <uuid> --format svg` turns a result into a durable URL you can place. In `hybrid` and above, a premium download costs a few cents on the wallet — still less than one generated image. Full detail in the `vidfarm-media` skill.
100
118
  - **Pixabay key** unlocks the photos/vectors/stock-video slots (music/SFX/icons/CC images are keyless). It's a **free** stock-media key, not an AI key. Don't assume it's missing when a search comes up short — it **may already be saved**: check `vidfarm provider-keys` (or the web app's **Settings → Bring your own keys** / <https://vidfarm.cc/settings/developer>). If it isn't, the user grabs a free one at <https://pixabay.com/api/docs/> and saves it once — `vidfarm add-provider-key pixabay <key>`, the Settings surface, or by handing the key to their desktop AI agent to run that command. After it's saved, cost-mode `minimize` sourcing works end-to-end at $0.
119
+ - **Footage searching is free too — set up browser control instead of hitting the paywall.** `video-search`, `image-search`, `news-search` and `download-video` are paid plans only, and they are the routes an agent reaches for the moment someone says "find me a clip of X". Do not answer that with a 402. `vidfarm browser setup` installs browser-harness so you drive the user's own Chrome, and `vidfarm browse videos "<the shot>"` gives you Google Videos / Images / News for $0 on their own logged-in session. Ask before installing (it's their personal browser), then work the same query craft you'd use on the paid route. Full page: `references/browser-harness.md`.
120
+ - **Use YOUR OWN image generation if this agent subscription includes it — it is free, and it stays free in `minimize`.** `minimize` means "$0 per video", not "no AI images". Google Antigravity and Gemini CLI include Gemini image generation (Nano Banana / Imagen); OpenAI Codex / ChatGPT include `gpt-image`. **Claude Code does not — Anthropic ships no image model**, so a Claude session drops to the rungs below instead. When you do have the tool, generating the graphic yourself bills Vidfarm $0 and the provider $0 extra, so it is allowed in every cost mode and needs no `--yes`. `vidfarm agent-image --check` says whether you have it; `vidfarm agent-image "<subject>" --items "a,b,c"` prints the prompt, the key-plate rules and the cut + import commands. Free stock, IconScout and `mask` still come FIRST — a designer's vector beats a generated one — but this beats going without, and it beats making the user do it by hand. Full page: `references/agent-included-imagegen.md`.
101
121
  - **You can still get CUSTOM art in `minimize` — hand the prompt to the user and let a free image generator do it.** Stock and `mask` only cover art that already exists somewhere; when the video genuinely needs a bespoke graphic, **don't conclude "we can't" and don't quietly bill `generate`**. Write the prompt and ask the user to paste it into a **free** image generator — <https://meta.ai>, free-tier ChatGPT, or a free Hugging Face image Space (<https://huggingface.co/spaces>) — then hand the PNG back with `vidfarm put-file` (or drag it into **My Files** in the web app). $0, zero wallet spend. Full loop + the prompt template: **“Free manual image-gen”** below.
102
122
  - **hybrid** *(recommend this)* — **~$0.01–$1 per video, on their BYOK key.** Free where it's free; pay for AI only where it clearly wins (a hero shot, a voice you can't fake locally). A mostly-hyperframes video with one generated image lands near the low end; a few AI images plus premium narration approaches the high end.
103
123
  - **Narration starts free here too.** In BOTH `minimize` and `hybrid`, a bare `vidfarm tts "…"` runs the keyless local Kokoro-82M voice — no flag needed. Ask for a premium voice explicitly (`--style`, `--voice <provider preset>`, `--provider`, `--own-key`, or `--cloud`) when the piece needs one, and say so out loud so the user knows what they're paying for. `rich-ai` skips the free default entirely. If the local engine isn't installed on their machine, the run falls back to their provider key / cloud automatically and prints why.
@@ -154,7 +174,35 @@ Cost mode answers *how much money may I spend*. It does not answer *how much of
154
174
 
155
175
  **And say where the premium voices come from, because users assume wrong.** The full ElevenLabs catalog is reachable **through vidfarm's own ElevenLabs connection** — no ElevenLabs account, API key, or subscription on the user's side; narration just spends **vidfarm wallet credits** (pennies each). In `hybrid` that is a real option to put on the table next to the free voices, not a locked door. `--own-key` is only for users who already have an ElevenLabs key and would rather bill their own account.
156
176
 
157
- **Raw-clip sourcing has a ladder — hand it to the human only at the bottom rung.** In order: (1) **your own browser control**, if you have it drive the search and download yourself; (2) **Vidfarm cloud** — `vidfarm clipper <url>` / `vidfarm raws scan <url> --cloud` resolves and mines the video for you; (3) the **free public raws catalog** — `vidfarm public-raws --category <shelf>`; (4) **the user**, when you're fully local/keyless or when human taste matters. That last rung is `vidfarm handoff raws --keywords "villa construction,pouring concrete" --platforms tiktok,youtube --purpose "<what the clips are for>"` — it prints the keywords, tells them to google a downloader (a *search*, not a link that rots), and names the import command for when the folder is ready (`vidfarm clipper ./downloads/<file>.mp4`, or `vidfarm raws scan` to mine a long one).
177
+ **Raw-clip sourcing has a ladder — hand it to the human only at the bottom rung.** In order: (1) **your own browser control** and you can always have it: `vidfarm browser setup` installs browser-harness in about a minute, then `vidfarm browse videos "<the shot>"` drives the user's own Chrome through Google Videos/Images/News for $0, which is the free substitute for the paid search and download primitives (`references/browser-harness.md`); (2) **Vidfarm cloud** — `vidfarm clipper <url>` / `vidfarm raws scan <url> --cloud` resolves and mines the video for you; (3) the **free public raws catalog** — `vidfarm public-raws --category <shelf>`; (4) **the user**, when you're fully local/keyless or when human taste matters. That last rung is `vidfarm handoff raws --keywords "villa construction,pouring concrete" --platforms tiktok,youtube --purpose "<what the clips are for>"` — it prints the keywords, tells them to google a downloader (a *search*, not a link that rots), and names the import command for when the folder is ready (`vidfarm clipper ./downloads/<file>.mp4`, or `vidfarm raws scan` to mine a long one).
178
+
179
+ ## Production has PHASES — plan, then collect the raws, THEN build
180
+
181
+ **Most video work is not one pass.** The failure that costs the most is starting the timeline before you know what footage you have: you build to a shot you assumed existed, discover it doesn't, and either pay to generate it or rewrite the beat you already built. Separate the phases and that whole class of rework disappears.
182
+
183
+ 1. **Plan** — the shot list, before any asset exists. `vidfarm storyboard ./work --init --frames "Hook,Problem,Reveal,CTA"`, each frame with its `scene` line and `voiceover`. A plan is free to redo; a rendered scene is not.
184
+ 2. **Collect** — fill the shot pool against that list. One sourcing pass for the WHOLE video (or the whole batch), not one lookup per beat. Everything lands in the searchable local library, so the next video starts with a pool instead of an empty folder.
185
+ 3. **Build** — only now open the timeline, with every beat already backed by a real asset.
186
+ 4. **Review and cut** — the holistic pass, then delete the beats the video survives without.
187
+
188
+ **How aggressively to run phase 2 depends on the cost mode.** This is the single biggest lever on both quality and spend:
189
+
190
+ - **`minimize` — the collection phase is the whole job. Budget most of your effort here.** You have no generation to fall back on, so the pool has to be good, and it can be: work the ladder in order and stop at the first rung that answers the beat.
191
+ 1. `vidfarm public-raws --categories` then `--category <shelf>` — pre-tagged, free, already cut to short-form. Check this first, every time.
192
+ 2. `vidfarm media search "<meaning>" --type <bgm|sfx|image|vector|video>` (keyless via openverse/iconify) and `vidfarm iconscout "<meaning>" --free` for icons, stickers, illustrations and props.
193
+ 3. `vidfarm raws search "<meaning>"` — what the director already owns from previous videos.
194
+ 4. **Browser control** — `vidfarm browse videos "<the shot>"` drives the user's own Chrome for $0 (`references/browser-harness.md`). This is the free substitute for the paid `video-search` / `image-search` / `news-search` / `download-video` primitives. **Set it up rather than declaring the shot unavailable.**
195
+ 5. Mine what you found: `vidfarm raws scan <url|file>` for a pool, `vidfarm clipper` for one exact cut. Free and local.
196
+
197
+ Being cheap here does **not** mean being worse. One long source mined into eight tagged raws costs $0 and covers more beats than one generated clip would. Cutting a real clip three different ways is free; generating three shots is not.
198
+
199
+ - **`minimize` + `interactive` — buy quality with the user's hands, not their wallet.** Two checkpoints beat any amount of autonomous cleverness, so **ask for them explicitly instead of quietly doing without**: (1) hand them the shot list and let them search TikTok/YouTube themselves and drop the files in a folder — a human eye picks better footage than any keyword extraction (`vidfarm handoff raws --keywords "…" --purpose "…"`); (2) hand them ONE image prompt for a free frontier web generator and get a whole sticker sheet back (`vidfarm handoff image --theme "…" --items "a,b,c"` → `vidfarm sticker-pack`). Free web image models are typically better per image than what an API budget buys. Direct them like an editor — name the shot, the framing, how many, and where to put them — don't hand over a vague request.
200
+
201
+ - **`hybrid`** — collect free first, then spend on the gaps the pool genuinely cannot cover. Now AI image generation is on the table for the one hero graphic, and `vidfarm avatar` for a presenter. Keep AI *video* generation for beats where nothing static will do. The order still matters: knowing what the pool is missing is what makes the spend small.
202
+
203
+ - **`rich-ai` / `pure-videogen`** — the collection phase becomes a **generation** phase, and it moves earlier rather than disappearing. `rich-ai`: generate the cast and props as reusable greenscreen raws, key them once, save them to the library, then animate in HTML — so the spend amortizes across every later video. `pure-videogen`: script → storyboard stills → scene-by-scene generation, in that order, with `vidfarm sequence` running the pipeline. Even here, **search what already exists before generating it** (`raws search`, then `public-raws`) — regenerating an asset you already own is the most common avoidable spend in these modes.
204
+
205
+ **Say the phase out loud when you switch.** "I'm going to collect footage for all four beats first, then build" sets the right expectation and gets you the interactive checkpoints while they're still cheap. Deciding to source mid-build is how a $0 video turns into a $3 one.
158
206
 
159
207
  ## Default stance
160
208
 
@@ -320,6 +368,7 @@ You may be running as the **in-web AI chat** (the /editor copilot, the chat dock
320
368
  - **Determine the surface before claiming capabilities.** The web chat has only its declared tools and REST routes. It cannot execute arbitrary JavaScript/Python, open a shell, create a local repository script, or use the user's filesystem. Never tell a web-chat user that you ran code or wrote a script unless a dedicated declared tool actually did so. A desktop coding agent has a real shell and filesystem and MAY write/run scripts, perform arbitrary local computations over paginated API results, create reports/CSVs/JSON, edit composition files, and orchestrate long devcli workflows within the user's authorization.
321
369
  - **The web AI chat can do all three paintbrushes** — clip raws, author HTML/hyperframe motion, and generate AI media — and it drives edits directly on the live timeline. Keep small-to-medium jobs here: text/caption swaps, a scene or two replaced, single generations, captions, approve/schedule. Just do them.
322
370
  - **No HTML slop — a video is not a web page.** Compositions are authored in HTML, so the #1 tell of an AI-edited video is landing-page furniture: gradient CTA "buttons" ("Sign Up for a Free Trial →"), rows of benefit chips/badges ("✓ No Credit Card Needed"), frosted/bordered cards holding a gradient headline + a URL, feature grids, bullet lists, web-default type (Inter/Roboto/Arial at weight 400-600). None of that exists in a real TikTok/Reel — **nothing in a video is clickable**. **The test is the native-editor test: could you have made this element with the tools inside TikTok's own editor?** That toolset is font / color / stroke / shadow / tight text box / alignment / rotation / animation presets, plus stickers, emoji, drawn marks and clips — it has no padded capsule, no border, no gradient fill, no blur panel, no card. If you reached past it, cut it. That includes **a single lonely pill around a stat or label** — `( 10 hrs / week )`, `( STEP 2 )`, `( EP.01 )`: being alone doesn't make a badge native, and the only legitimate capsule in a video is the active-word `spotlight`/`karaoke` highlight, which moves with the spoken word. Emphasize a stat the way the editor would instead: bigger, heavier, ALL-CAPS, an accent color, a hand-drawn circle, or its own beat. If you are typing `btn` / `badge` / `chip` / `card` / `rounded-full` / `shadow-lg` / `backdrop-blur` / `bg-gradient-to-r` — or a `border-radius` over ~8px on anything filled that holds words — stop and rewrite it as timed text on the footage. Arrows, scribble/underline marks, italics, ALL-CAPS, single-word color pops, emoji, transparent cut-out stickers, and mock social UI (iMessage bubbles, comment cards) are all *fine* — they're native to the platform.
371
+ - **And judge the WHOLE FRAME, not just the elements — no layout templates.** The rule above judges one element at a time, and a frame can pass it element-by-element while still being a web page. The archetype is the **modal**: the backdrop dimmed and blurred out of focus, and floating on it a rounded bordered box holding a big headline, a smaller support line, and a fat CTA button. **The stack is the tell, not the box** — strip the border, the fill and the capsule, keep headline → subheadline → CTA centred in a well with even margins, and it still reads as a landing page, because the viewer recognizes the *shape* before reading a word. Banned at frame level: the modal/dialog floating over a receded backdrop; the hero triplet (and its cousins: title + kicker + logo lockup, question + answer + URL); a full-frame dim wash used to stage a floating block; nav/hero/feature-row/testimonial/footer sections; a blurred website screenshot as the background plate; a centred content column with document margins. **The fix is always to unstack it into time**: the headline is the hook at t=0, the support line lands on the next cut, the CTA is *spoken* or a bare caption on the last frame — a viewer reads one line at a time anyway, so you lose nothing and gain pacing. Self-check before placing any text group: *am I arranging words relative to each other, or relative to the picture?* Relative to each other = layout = web. Two text runs at once is the ceiling. Verify on a still (`vidfarm stills ./work --at <t>`) — if it could be a screenshot of a website, rebuild the beat. `vidfarm qa` catches the mechanical half (`layout-template`, `modal-scrim`).
323
372
  - **Orient the cold viewer in the first 3 seconds — the hook makes them want to watch, orientation makes watching possible.** The viewer has no context, did not choose this video, and has never heard of the subject, so by **~3s** they must be able to say **what kind of thing this is** (the *category noun*), **who it is for**, and **why it is on their screen** (the situation). The failure is not a bad first frame — it is a good video that **starts at beat two**, and the author cannot see it because the author already knows. Signatures, each a rebuild of the first beat: a **pronoun with no referent** ("it just works", "this changes everything"), **starting at step three** (the process already running, the dashboard already full), a **metaphor whose subject lands at 6s**, **insider vocabulary or an acronym** in the first line, a **detail crop** that reads as texture. Replace it with both channels in one beat — an **easy image** (one large subject, already moving, legible at a glance and at thumbnail scale; a relevant cutout names the category before a word is read) and an **easy line** (one clause, ≤12 words, everyday words, concrete noun + verb, the category named, brand name said once) — and give the **situation, not the label**. **It costs one sentence, not one beat**: it replaces the wind-up line, never precedes it, and never licenses a logo, a title card, or a fade from black. Test on the render, not the script: play the first 3s only to somebody with no context — "something about audio" is a fail. Full standard: `references/editor-workflows.md` (“Orient the cold viewer”); fullest form with structure: `vidfarm harness show product-explainer` (Rule 0).
324
373
  - **Every video gets the four charges — hook, loop, payoff, bait — and you write them BEFORE you touch the timeline.** This is the largest quality delta in the product and it costs nothing: most agent-made videos fail on structure, not polish, because the timeline is the fun part so it gets built first and the words get retrofitted. Invert it: (1) write the **hook line as text** — a complete clause, subject + verb, no jargon, naming a **situation** ("I've quit six businesses"), never a label ("anonymity") — and put it on screen at `start:0`; (2) name the **curiosity loop** and the timestamp it closes at, *inside this video* (if you can't state the timestamp, there is no loop, and the withheld answer must be one the viewer **can't guess**); (3) name the **payoff** — shown, not summarized, landing before the final beat; (4) write the **bait** — one ask in the final beat and in the post caption. Then build. Chunk 1 is read before any audio (muted autoplay is the default), so the text hook does more work than the spoken one. Full harness — the three gates, banned openers, loop mechanics, compliance, and diagnosis-by-charge — in `references/hooks-and-virality.md`; the checkable form is `vidfarm harness show hooks`.
325
374
  - **Then CUT it — every second must earn its place, and most don't.** Assume your first assembly is **30–50% too long**. Run the **deletion test** on every beat: delete it; if the video still makes sense and the payoff still lands, it stays deleted. Whatever survives must serve one of the four charges — "it gives context" is not a charge. Cut on sight: intros/logo stings, the wind-up sentence before the claim ("so I wanted to talk about…"), restatement, inter-sentence silence over ~0.35s, real-time process, establishing shots, reading what's already on screen, and any tail after the last word. **Always ripple the hole closed** (`vidfarm ripple <dir> --at <sec> --delta -<sec>`) — a cut that leaves a gap turns fluff into dead air, which is worse. Density is **not** speed: the held comedic beat, the payoff playing out, and a cue's readability keep their seconds (cut *words*, not the time text is on screen). Length is an **output**, not a plan — a brief that dictates a duration ordered fluff. `vidfarm qa` flags the mechanical half (`dead-air`, `dead-tail`, `slow-scene`); the craft is `references/hooks-and-virality.md` → "Density".
@@ -351,6 +400,8 @@ You may be running as the **in-web AI chat** (the /editor copilot, the chat dock
351
400
  | `references/core-workflows.md` | ~360 ln | Template discovery, auth, fork → render → approve → share, versioning, cost/wallet, marketplace orders, dedupe-before-publish |
352
401
  | `references/editor-workflows.md` | ~650 ln | **The biggest read.** Timeline editing, decompose, captions, transitions, motion, AI placement, the caption standard, the editor action verbs |
353
402
  | `references/assets-and-sourcing.md` | ~275 ln | **Google search for footage** (the query playbook), raws hunts, clip scanning, My Files, recurring characters, downloading media off a URL, social recycle |
403
+ | `references/agent-included-imagegen.md` | ~70 ln | **Free custom art without spending.** Image generation the AGENT's own subscription already includes (Antigravity / Gemini CLI, Codex / ChatGPT — Claude Code has none): why it is allowed in cost mode `minimize`, `vidfarm agent-image --check` / the brief command, where it sits on the asset ladder, and the honest limits |
404
+ | `references/browser-harness.md` | ~85 ln | **Free-plan sourcing, and cost mode `minimize`.** Driving the user's own Chrome with browser-harness as the $0 substitute for the paid video-search / image-search / news-search / download-video primitives: setup, the browse recipes, the raws collection loop, the interactive hand-off, and the licensing/etiquette limits |
354
405
  | `references/automation-and-local-dev.md` | ~520 ln | **Big.** The whole `vidfarm` command table, REST automation, scripting/bulk mode, `HARNESS.md`, local serve loop, skill packs |
355
406
  | `references/primitives.md` | ~530 ln | **Big.** One-shot primitive routes: video/image/news search, TTS, STT, music, avatars, overlays, greenscreen, inpaint, background removal, product placement |
356
407
  | `references/hooks-and-virality.md` | ~295 ln | **Before writing ANY hook, caption script, or re-theme**, and before a hook-variant batch. The four charges, three gates, banned openers, loop mechanics. This is the craft; the rest of the pack is mechanics |
@@ -418,12 +469,14 @@ The File Index above says what each file *is*; this says which one a given ask m
418
469
  2. If the user already knows the goal and needs a suitable template, read `references/core-workflows.md` and use the template discovery flow.
419
470
  3. If the task is “change this video,” read `references/editor-workflows.md`.
420
471
  4. If the task is “find footage” or “use our existing assets,” read `references/assets-and-sourcing.md`.
421
- 4b. If the task is **“download this video/audio off a website”** (a pasted YouTube / TikTok / Instagram / X post URL the user wants the actual file from), Vidfarm does that for you on a **paid plan** — `POST /api/v1/primitives/videos/download` (or `/audio/download`), devcli `vidfarm download-video <url>` / `vidfarm download-audio <url>`. **Free plan → do not call it; walk the user through opening the URL in Chrome and downloading it from the page, then `vidfarm put-file` the local file in for $0.** Details in `references/assets-and-sourcing.md` → `references/primitives.md`.
472
+ 4b. If the task is **“download this video/audio off a website”** (a pasted YouTube / TikTok / Instagram / X post URL the user wants the actual file from), Vidfarm does that for you on a **paid plan** — `POST /api/v1/primitives/videos/download` (or `/audio/download`), devcli `vidfarm download-video <url>` / `vidfarm download-audio <url>`. **Free plan → do not call it; get the file out of Chrome instead. Best: `vidfarm browser setup` + `vidfarm browse page "<url>"` so YOU drive their Chrome and save it (`references/browser-harness.md`); otherwise walk the user through opening the URL and downloading it from the page. Either way `vidfarm put-file` brings the local file in for $0.** Details in `references/assets-and-sourcing.md` → `references/primitives.md`.
422
473
  4c. If the task is **“turn this Reddit/X thread, subreddit, or account into a video”** — “tweet to TikTok”, “Reddit to TikTok”, “make a video from this thread”, “what are the top comments saying” — run `vidfarm recycle <source>` (or `POST /api/v1/primitives/social/recycle`) with the URL. It **decomposes** the source into raw JSON (text, comment tree, media URLs, author pics, stats) and hands it back unranked so YOU pick what to remix. **Paid plan; `max_records` is the spend ceiling.** Brokers the reddit-lead-gen / x-lead-gen OfficeX apps, so it waits out their async job for you. Details in `references/assets-and-sourcing.md` → `references/primitives.md`.
423
474
  4d. If the task is **“post this again / to several accounts / on another platform”**, or you are about to publish or bulk-produce at all — that is **deduplication**. Run `vidfarm dedupe <mp4> [--variants N]` on the **exported file** (free, local ffmpeg, no re-render), then approve/schedule each variant. **Ask the operator whether they want deduplicated copies, and how many, BEFORE the render/bulk run** — deciding after means paying for a second render. Details in `references/core-workflows.md` → *Deduplicate before you publish* and `references/primitives.md` → *Primitive: media_dedupe*.
424
475
  4e. If the ask contains the word **“harness”** — *“create me a harness”*, *“update the harness for this format”*, *“give me the harness for this template_id”* — that is a known, named process, not a vague request. Read `harnesses/README.md` (the three phrasings and the format), then `recipes/bulk-scripting-with-a-harness.md` if the job is a batch. The third phrasing means the **decomposition**: `vidfarm harness derive <forkId>`.
425
- 4f. If the task is **“find me footage / a clip of X”** and the free catalog and public raws shelves do not have it, **search Google before you generate anything**: `vidfarm video-search "<shot>"` returns real source URLs (TikTok, YouTube, Pexels, archive.org) which go straight into `vidfarm raws scan <url>` (mine clips) or `vidfarm download-video <url>` (collect the file). `vidfarm image-search` does the same for stills. **Paid plans only, flat $0.0003 per call** — cheaper than one AI image attempt by two orders of magnitude, so it is almost always worth one wide search first. Query craft matters more than anything else here: `references/assets-and-sourcing.md` → *Google search for footage*. **A public video is not a licensed video** — check rights before reuse.
426
- 4g. If the ask is **timely** — “make a video about what just happened”, newsjacking, “what's trending in <niche> this week” — run `vidfarm news-search "<topic>" --fresh w` for the STORY, then `vidfarm video-search` for the VISUALS. Two stages, never one query. Full method: `https://vidfarm.cc/experimental/google-news-to-video.md`.
476
+ 4f. If the task is **“find me footage / a clip of X”** and the free catalog and public raws shelves do not have it, **search Google before you generate anything**: `vidfarm video-search "<shot>"` returns real source URLs (TikTok, YouTube, Pexels, archive.org) which go straight into `vidfarm raws scan <url>` (mine clips) or `vidfarm download-video <url>` (collect the file). `vidfarm image-search` does the same for stills. **Paid plans only, flat $0.0003 per call** — cheaper than one AI image attempt by two orders of magnitude, so it is almost always worth one wide search first. **On a free plan or in `minimize`, browse the same searches yourself for $0** — `vidfarm browse videos|images "<shot>"` (see 4h). Query craft matters more than anything else here: `references/assets-and-sourcing.md` → *Google search for footage*. **A public video is not a licensed video** — check rights before reuse.
477
+ 4g. If the ask is **timely** — “make a video about what just happened”, newsjacking, “what's trending in <niche> this week” — run `vidfarm news-search "<topic>" --fresh w` for the STORY, then `vidfarm video-search` for the VISUALS. Two stages, never one query. Free plan / `minimize`: the same two stages as `vidfarm browse news "<topic>"` then `vidfarm browse videos "<the thing>"`, for $0 (see 4h). Full method: `https://vidfarm.cc/experimental/google-news-to-video.md`.
478
+ 4h. If any of 4b / 4f / 4g would cost money the user doesn't want to spend — a **free plan**, a `402`, or cost mode **`minimize`** — the answer is **browser control, not an apology**. `vidfarm browser setup` installs browser-harness (drives the user's own Chrome, ~1 minute, $0, no account), then `vidfarm browse videos|images|news|page "<query|url>"` substitutes for `video-search` / `image-search` / `news-search` / `download-video`. Ask before installing — it is their personal browser. Read `references/browser-harness.md`.
479
+ 4i. If the ask is a **whole video or a batch** rather than one lookup, run it in phases — **plan the shot list, collect the raws for every beat, then build** (SKILL.md → *Production has PHASES*). How hard you work the collection phase is set by the cost mode: in `minimize` it is most of the job and it is where quality comes from; in `hybrid` you collect free first and pay only for the gaps; in `rich-ai` / `pure-videogen` it becomes a generation phase that still starts with searching what already exists.
427
480
  5. If the task is scripted, local, CI-driven, or `vidfarm serve`-based, read `references/automation-and-local-dev.md`.
428
481
  5b. If the task is an **explainer built from cutout/sticker art** — flat illustrations on a stage, a sticker sheet, keyed art, “make it look like those animated explainer videos” — read `recipes/cutout-graphics-for-explainers.md`. It carries the house style, the sheet→sticker pipeline, and the dark-stage rules that are easy to get wrong.
429
482
  5c. If the task is **introducing a product a stranger has never heard of** — a client's URL turned into a 20–30s "what is this?" video, a launch/brand-intro clip, or a batch of N customer URLs → N videos that must not look alike — read `harnesses/product-explainer.HARNESS.md`. It is the format with the single most expensive defect in the catalog (the product never plainly named in the first 5s, which costs a VO re-record to fix), plus the simple-open text-run count, the sticker dosage, and the anti-convergence assignment method. Use `product-demo` instead when you actually have the UI on screen.
@@ -77,7 +77,7 @@ The mechanical form: compare each caption phrase against the words on screen in
77
77
 
78
78
  ### Rule 7 — production floor
79
79
 
80
- Captions verbatim in the font regime and safe zone · frame 0 states the claim (it is the thumbnail, and for this format it's usually pure typography, which makes it the *easiest* format to get a good thumbnail from — no excuse for a black open) · no HTML slop: an explainer's subject matter drags authors toward feature grids, comparison tables, and card layouts, and those are exactly the banned web furniture. A comparison is an animated before/after, not a two-column table.
80
+ Captions verbatim in the font regime and safe zone · frame 0 states the claim (it is the thumbnail, and for this format it's usually pure typography, which makes it the *easiest* format to get a good thumbnail from — no excuse for a black open) · no HTML slop: an explainer's subject matter drags authors toward feature grids, comparison tables, and card layouts, and those are exactly the banned web furniture. A comparison is an animated before/after, not a two-column table. Nor a **layout template**: a headline + subheadline + CTA stacked in a centred well is a web hero even with every border and fill stripped off, and a dimmed-plus-blurred backdrop staging a floating block is a modal. Unstack it into time — one thought per beat.
81
81
 
82
82
  ## Bulk-generation notes
83
83
 
@@ -28,6 +28,8 @@ For showing a real product doing a real thing. This is the format with the **hig
28
28
 
29
29
  A demo shows the screen changing. Everything else — the value prop, the pricing, the benefits, the logos — is a landing page that happens to be rendered as video, and it converts like one (i.e. it doesn't, in a feed).
30
30
 
31
+ **The layout trap, and it is the one this format falls into.** The classic failure frame here is a **modal**: the product's site blurred and dimmed behind, and floating on it a rounded bordered box with a headline, a support line, and a CTA button. The stack is the tell, not the box — strip the border, the fill and the capsule and it still reads as a web page, because the viewer recognizes the shape before reading a word. Never arrange words relative to *each other*; arrange them relative to the *picture*, one line per beat. Show the real UI **full-bleed and in focus** (that is legitimate footage) or don't show it — a blurred screenshot used as a background plate means the frame is a screen recording of a web page. The end card is the other repeat offender: brand + tagline + offer + URL stacked in one well is a hero section. Pick one line, say the rest. Full rule: `references/editor-workflows.md` → "The layout-template rule"; `vidfarm qa` flags the mechanical half (`layout-template`, `modal-scrim`).
32
+
31
33
  ## Structure
32
34
 
33
35
  | Beat | Job |
@@ -100,6 +100,7 @@ Not an accessibility afterthought: captions are how the hook, the loop, and the
100
100
  - **One to three words per line, one line at a time.** A block of full sentences doesn't get read. Long narration is paged into 3–5-word kinetic cues (`captions generate --style word-pop|spotlight`), never held as one static block.
101
101
  - **Placed in the quietest region of the frame**, measured off a still — not dropped on the default lower third.
102
102
  - **Cards are timed text over footage** — never a card UI, table, chip row, or frosted panel (`vidfarm qa` flags those as slop).
103
+ - **A card is ONE line, never a stack.** Headline + subheadline + CTA in one frame is a web hero, with or without a box around it — the stack is the tell. Unstack it into time: one thought per beat. Same for the backdrop: never dim *and* blur the picture to float a block on top of it, and never use a blurred website screenshot as the plate.
103
104
  - **Max ~3 standalone cards per video:** one for the loop, one for the payoff, one for the bait.
104
105
 
105
106
  #### Caption PLACEMENT is measured off the frame, before styling is decided
@@ -7,7 +7,7 @@ Use this when a coding agent is doing the work locally or the user wants a repro
7
7
  3. Read `./work/.harness/agent-guide.md` and `./work/.harness/context.json` before editing.
8
8
  4. Make deterministic edits to `composition.html` and optionally `composition.json`.
9
9
  5. Validate with `vidfarm lint` or `vidfarm stills` when useful. **Always look at `vidfarm stills ./work --at 0`** — that frame becomes the thumbnail, so it must not be black, empty, or mid-fade.
10
- 6. **QA before you render: `vidfarm qa ./work`.** Free, instant, devcli-only. It blocklists HTML slop (CTA buttons, benefit chip rows, a lone pill around a static stat/label, frosted cards, gradient text, web-page classes/fonts), checks the caption font regime + safe zone, flags oversized captions and static walls of text, and flags a blank/fading first frame (the thumbnail). It cannot see pixels, so *where in the frame* the caption sits is still on you — which is why every run ends with a **`▶ NOW WATCH THE VIDEO`** block: render, `vidfarm stills ./work --sheet`, open the contact sheet, and judge each caption against its actual picture. Do that before you report the video as done. Feedback only — exit 0 even on findings, never automatic — but it catches the #1 tell of an agent-made video, so run it on every production. Fix what's real, ignore what's a deliberate style call, then render.
10
+ 6. **QA before you render: `vidfarm qa ./work`.** Free, instant, devcli-only. It blocklists HTML slop (CTA buttons, benefit chip rows, a lone pill around a static stat/label, frosted cards, gradient text, web-page classes/fonts) and the frame-level version of it (`layout-template`: a headline + subheadline + CTA stack, `modal-scrim`: a blurred-and-dimmed backdrop staging a floating block), checks the caption font regime + safe zone, flags oversized captions and static walls of text, and flags a blank/fading first frame (the thumbnail). It cannot see pixels, so *where in the frame* the caption sits is still on you — which is why every run ends with a **`▶ NOW WATCH THE VIDEO`** block: render, `vidfarm stills ./work --sheet`, open the contact sheet, and judge each caption against its actual picture. Do that before you report the video as done. Feedback only — exit 0 even on findings, never automatic — but it catches the #1 tell of an agent-made video, so run it on every production. Fix what's real, ignore what's a deliberate style call, then render.
11
11
  7. Render with `vidfarm render <forkId> --dir ./work --wait`.
12
12
  7b. **Review the render as a whole before you approve — this is the step that most changes quality.** `vidfarm qa` and `lint` are static checks on the DOM; neither can see the video. Tile ~12 stills into one contact sheet and read it as an image — `vidfarm stills ./work --sheet` does both in one command (add `--at 0,2,4,…` to pick the timestamps): consistent margins, one type scale, one accent colour, deliberate pacing, no jarring join, no dead band under top-anchored content, end card settled ≥2s before the last frame. Compare frames from two different scenes — a frozen render (overlay pass without `-loop 1`, assets outside the composition root) passes duration, frame-count and audio-hash checks while every frame is identical. Check the mix by measurement, not by ear. Full method + the six most common defects: `references/reviewing-renders.md`.
13
13
  8. **Ask about deduplication before you approve** — "is this going out more than once (several accounts, another platform, a re-post later)?" If yes, run `vidfarm dedupe ./final.mp4 [--variants N]` on the **exported** MP4 (free, local ffmpeg, no re-render) and approve each variant separately. Asking here rather than after publication is what avoids paying for a second render. See `references/core-workflows.md` → *Deduplicate before you publish*.
@@ -0,0 +1,75 @@
1
+ ## Image generation your own subscription already includes — free custom art in `minimize`
2
+
3
+ Vidfarm does not need to sell you an image model when the agent driving the terminal already has one. **If your own runtime includes image generation at no extra charge, that is a $0 rung on the asset ladder** — and it is the only free rung that produces *bespoke* art with no manual step and no waiting on the human.
4
+
5
+ This is the same house pattern as `vidfarm consult`: the devcli writes the brief, the agent already in the terminal executes it.
6
+
7
+ ### Who has it
8
+
9
+ | Host agent | Image generation included? | The tool |
10
+ |---|---|---|
11
+ | **Google Antigravity** | **Yes** | Gemini image generation (Nano Banana / Imagen) — part of the Gemini subscription |
12
+ | **Gemini CLI** | **Yes** | same |
13
+ | **OpenAI Codex / ChatGPT** | **Yes** | `gpt-image` — part of the ChatGPT plan |
14
+ | **Claude Code** | **No** | Anthropic ships no image model. There is nothing to fall back on |
15
+ | OpenCode / Cursor / anything else | **Depends on the configured model** | check your own tool list |
16
+
17
+ `vidfarm agent-image --check` prints this table plus a guess at the current host from its env markers. **The env guess is a hint. You are the authority** — look at your own tool list. Claiming a tool you don't have wastes a turn; missing one you do have costs the user money.
18
+
19
+ ### Why this is allowed in `minimize`
20
+
21
+ `minimize` means **$0 per video**, not "no AI". The rule it enforces is *do not bill the user's provider key or wallet by surprise*. Generation the user already paid for in a flat monthly subscription bills neither:
22
+
23
+ - Vidfarm charges **$0** — no primitive is called, no job is created, no wallet debit.
24
+ - The provider charges **$0 extra** — the capability is inside the plan the user is already on.
25
+
26
+ So the ladder in `minimize` is:
27
+
28
+ 1. **Free stock** — `vidfarm media search "<meaning>" --type image|vector` (Openverse is keyless).
29
+ 2. **IconScout** — `vidfarm iconscout "<meaning>" --free` for any icon, sticker, illustration, 3D prop or Lottie. Still beats generation on price *and* on quality: a designer's finished transparent vector, no prompt loop.
30
+ 3. **Art the director already owns** — `vidfarm mask <image> --crop x,y,w,h` lifts an element out of a screenshot, infographic or their own site for $0.
31
+ 4. **Your own included image generation** — this page. Bespoke art, $0, no human step.
32
+ 5. **The human hand-off** — `vidfarm handoff image --theme "…" --items "a,b,c"`; they paste it into a free web generator.
33
+ 6. **Billed generation** — `vidfarm generate image` (~$0.01–$0.05 on their own key). In `minimize` this needs the user's explicit `--yes`.
34
+
35
+ Rungs 1–3 come first even when you *do* have a free image tool: a real photo or a designer's vector still beats a generated approximation for most props, and it costs zero turns.
36
+
37
+ ### The command
38
+
39
+ ```bash
40
+ vidfarm agent-image --check # do I have this here?
41
+ vidfarm agent-image "cozy farm props" --items "barn,tractor,hay bale"
42
+ vidfarm agent-image "a smiling mascot pineapple" --single --out ./mascot.png
43
+ vidfarm agent-image "…" --items "…" --folder greenscreen/props # name the import folder
44
+ vidfarm agent-image "…" --json # the brief as data
45
+ ```
46
+
47
+ It prints the generation prompt, the plate rules, and the two follow-up commands. It calls nothing and costs nothing — printing a brief is free in every cost mode.
48
+
49
+ Flags mirror `vidfarm handoff image`: `--items`, `--style`, `--key-color`, `--out-dir`, `--grid`, `--single`, `--zoned`, plus `--out` (where you save the generated file) and `--folder` (where the finished asset is imported).
50
+
51
+ ### The loop
52
+
53
+ ```bash
54
+ # 1. get the brief
55
+ vidfarm agent-image "cozy farm props" --items "barn,tractor,hay bale"
56
+
57
+ # 2. generate with YOUR OWN tool, using the printed prompt, saving to ./sheet.png
58
+ # (no vidfarm command — this step is your runtime's image tool)
59
+
60
+ # 3. cut it locally for $0
61
+ vidfarm sticker-pack ./sheet.png --items "barn,tractor,hay bale" --out-dir ./stickers
62
+
63
+ # 4. persist it so the next video reuses it for free
64
+ vidfarm put-file ./stickers/barn.png --folder greenscreen/props --notes "flat vector barn, transparent"
65
+ ```
66
+
67
+ **The prompt body is shared verbatim with `vidfarm handoff image`.** A plate that keys cleanly and art that survives the cut are the same craft whoever runs the generator: one flat chroma plate, generous spacing, nothing touching or bleeding off the frame edge, crisp outer edges with no glow or drop shadow. The plate color is picked *against the subject* — green art on a green plate keys holes through the artwork — and the command tells you when it moved the plate and why. Details: `references/assets-and-sourcing.md` and the sticker-pack rules in `recipes/cutout-graphics-for-explainers.md`.
68
+
69
+ ### The honest limits
70
+
71
+ - **Do not pretend.** If you have no image tool, say so and drop to the next rung. A fabricated image path is worse than a $0.02 spend.
72
+ - **Look at what you generated.** The cut is only as good as the plate. A soft edge, two objects touching, or an object cropped at the frame edge all produce a broken sticker — re-generate rather than shipping it.
73
+ - **It is still generated art.** Every "prefer a real asset over a generated one" rule in the pack still applies: an icon from IconScout looks better than a generated icon, and the free stock photo looks better than a generated photo. Free does not mean *first*.
74
+ - **It does not extend to video.** No agent subscription currently includes video generation, so AI *video* is still a billed Vidfarm primitive gated by cost mode. This rung is images only.
75
+ - **Say what you did.** When a graphic in the deliverable came from your own image tool rather than from stock or a paid job, tell the user — they are entitled to know what the video is made of, and it is the proof that `minimize` really did cost $0.
@@ -12,7 +12,11 @@ vidfarm news-search "AI startup funding announced" --fresh w
12
12
 
13
13
  REST twins: `GET /api/v1/primitives/video-search`, `/image-search`, `/news-search` (`?q=…&max_results=…`). Field-level reference in `references/primitives.md`.
14
14
 
15
- **Paid plans only · flat $0.0003 per call**, whatever the result count — so ask for one **wide** page rather than paging twice. On a free plan use the free catalog (`vidfarm media search`) and the public raws shelves instead.
15
+ **Paid plans only · flat $0.0003 per call**, whatever the result count — so ask for one **wide** page rather than paging twice.
16
+
17
+ **On a free plan, or in cost mode `minimize`, run the same searches yourself for $0.** `vidfarm browser setup` installs browser-harness (about a minute, no account, no key), and then `vidfarm browse videos|images|news "<query>"` drives the user's own Chrome through the same Google surfaces. You read the SERP instead of receiving ranked JSON, but the query craft below is identical and the results are the same web. Set it up rather than telling a free user the search needs a paid plan — full page, including the download substitute for `download-video`, in `references/browser-harness.md`. The free catalog (`vidfarm media search`, `vidfarm iconscout --free`) and the public raws shelves are still the cheaper first stop.
18
+
19
+ **Collect for the whole video, not one beat at a time.** Whichever route you use, sourcing is a *phase*: plan the shot list, run one pass that fills every beat, then build. See SKILL.md → *Production has PHASES*.
16
20
 
17
21
  **A public video is not a licensed video.** These searches return links with no licence attached. For client work prefer, in order: public domain → CC0 → CC BY (with credit) → stock with an explicit commercial licence → written permission from the creator. Save the source URL **and** the licence page every time.
18
22
 
@@ -91,7 +95,7 @@ Both are async primitive jobs — poll `GET /api/v1/primitives/jobs/:jobId` unti
91
95
 
92
96
  **PAID PLANS ONLY.** These ride a paid third-party resolver billed to the wallet, so a free-plan customer gets `402 insufficient_funds`. Check the plan / cost mode before promising it.
93
97
 
94
- **Free-plan users — the fallback is Chrome, and it works:** tell them (or, if you have browser automation, do it yourself) to **open the URL in Chrome and download the video from there** — right-click → *Save video as*, the downloads pane, DevTools → Network, or a Googled `"<platform> video downloader"` site in that same session. Then bring the local file in for free with `vidfarm put-file ./the-file.mp4 --folder <folder>` or the web uploader. Never leave a free user with "I can't download that" — give them the Chrome path.
98
+ **Free-plan users — the fallback is Chrome, and it works.** Best case, do it yourself: `vidfarm browser setup` gives you browser-harness and `vidfarm browse page "<url>"` prints the recipe for pulling the media element off the page in the user's own logged-in session — which reaches posts an anonymous resolver cannot (`references/browser-harness.md`). Otherwise tell them to **open the URL in Chrome and download the video from there** — right-click → *Save video as*, the downloads pane, DevTools → Network, or a Googled `"<platform> video downloader"` site in that same session. Then bring the local file in for free with `vidfarm put-file ./the-file.mp4 --folder <folder>` or the web uploader. Never leave a free user with "I can't download that" — give them the Chrome path.
95
99
 
96
100
  **Pulling the trending song off a post is a normal, expected use of `download-audio`.** Do not refuse it and do not swap in a generic royalty-free bed instead. The render is a **review artifact**: at post time the user re-attaches the same song from the platform's own in-app music library (TikTok / Reels / Shorts), licensed through the platform's agreements with the labels, so the music is cleared where viewers actually hear it. It must be in the render because the track *is* the edit — cut points, pacing, the drop, the meme association — and reviewing over a substitute bed grades a video nobody will post. Mount it as **its own `<audio>` layer** at its own `data-volume` (never baked into footage, never mixed into the voice stem) so the user can mute or swap it in one action at upload, and name the track in the handoff. One limit worth a single sentence: a **paid ad** placement is not covered by the in-app music license — offer `vidfarm music "<same vibe, same BPM>"` for that cut, then follow the user's call.
97
101
 
@@ -268,8 +272,73 @@ Minting or editing a link is **paid** (unlike the rest of the directory routes,
268
272
 
269
273
  A token is scoped to **exactly one subfolder and everything under it** — never a sibling, never a parent, so a leaked link cannot walk the rest of the drive. The shared base folder itself can never be renamed or deleted through its own token. Owner routes: `GET|POST /api/v1/user/me/directory/shares`, `PATCH|DELETE …/shares/<token>` (`{ path, mode, label }`; `disabled: true` cuts a link off instantly and is reversible). Public routes, no auth: `GET /api/v1/share/:token/directory` (`?path=`), `POST /api/v1/share/:token/directory/search` `{ query, path?, mode? }`, plus `…/directory/folders`, `…/directory/rename`, `…/directory/delete`, `…/attachments/upload`. The human page is `/directory/preview/<token>/<path…>`.
270
274
 
275
+ **Uploading over ~6 MB through a share link:** `…/attachments/upload` is a multipart POST through the API Lambda, whose request body caps at about 6 MB — a bigger file answers **413** before the handler runs. Use the two-step presigned path instead (the share page's own uploader does): `POST /api/v1/share/:token/attachments/presign` `{ file_name, content_type?, size_bytes?, folder_path? }` → `{ transport: "presigned", file_id, storage_key, folder_path, upload: { method, url, headers } }`; PUT the raw bytes to `upload.url` with those headers; then `POST /api/v1/share/:token/attachments/finalize` `{ file_id, file_name, content_type, size_bytes, storage_key, folder_path }` to record the file. A server with no presigned transport answers `transport: "server"` and you post the multipart form. Ceiling is the owner's own: 200 MB.
276
+
271
277
  In the UI: the file explorer's folder kebab → **Share…**, the `⤴ Share` toolbar button, and the folder kebabs on `/library` (**Raws** and **Approved** tabs). `⤴ Manage Shares` lists every token you own.
272
278
 
279
+ **Working a link you were GIVEN — `vidfarm shared` (no account, no API key).** This is the visitor side, and it is how a gigworker's agent collaborates on a client's drive. `<link>` is the URL from the task brief (or a bare `dsh_…` token plus `--host`):
280
+
281
+ ```bash
282
+ vidfarm shared info "$LINK" # folder, mode, what you may do
283
+ vidfarm shared ls "$LINK" [subfolder] # browse
284
+ vidfarm shared search "$LINK" "founder talking head, no captions"
285
+ vidfarm shared get "$LINK" hero.mp4 --out ./work # one file (--all for the folder)
286
+ vidfarm shared mkdir "$LINK" task-014-yvette # your own subfolder (upload/edit)
287
+ vidfarm shared put "$LINK" final.mp4 --subfolder task-014-yvette
288
+ ```
289
+
290
+ `shared put` runs presign → PUT → finalize, so it is not bound by the ~6 MB multipart ceiling; it falls back to multipart automatically when the server has no presigned transport.
291
+
292
+ **The crowdsourcing pattern (DollarPlatoon custom-request vending machine).** Two links per campaign, minted once and reused across every task:
293
+
294
+ ```bash
295
+ vidfarm directory share /files/crowdsourced/acme --mode upload --label "Acme drop box"
296
+ vidfarm directory share /raws/acme-brand --mode read --label "Acme footage (read only)"
297
+ ```
298
+
299
+ Put both in the task payload as plain fields — `assets_link` (read), `upload_link` (upload), `upload_subfolder` — and state the proof requirement: *"create your subfolder in the upload link, put the MP4 + project files there, and submit the public MP4 url as the proof"*. Organize the drop box one of two ways, and say which in the task: **worker-named subfolder** (one link for the whole campaign, each worker runs `shared mkdir`) or **task-owned subfolder** (pre-create `/…/acme/task-014` and mint the link onto *that* folder, so a worker on one task cannot see another's). Collect with the ordinary owner commands (`directory ls`, `directory search --path …`) and close the batch with `directory share-update <token> --disable`. Editors who only need footage get a `read` link on `/raws` — vector search included, nothing writable.
300
+
301
+ **Driving the machines from the terminal — `vidfarm gigs`.** The whole loop is scriptable, from both sides, and the two halves of a task (the brief and the files) are posted together:
302
+
303
+ ```bash
304
+ # CLIENT (paid plan — the DollarPlatoon key comes from your vidfarm account)
305
+ vidfarm gigs machines # your two standing machines + gig ids + invite links
306
+ vidfarm gigs add-task --task "60s explainer for acme.com" --price 0.50 --tags shortform \
307
+ --assets-link "$READ_LINK" --upload-link "$DROP_LINK" --subfolder task-014 \
308
+ --proof "MP4 in your subfolder" --proof "public MP4 url in the proof body"
309
+ vidfarm gigs ring-bell --title "Acme wants 7 shorts this week" --machine custom_requests
310
+ vidfarm gigs tasks # what is still unclaimed in the FIFO queue
311
+ vidfarm gigs proofs --status pending # what came back, with the playable link
312
+ vidfarm gigs approve PRF_01H… --feedback "Great hook, keeping it."
313
+ vidfarm gigs reject PRF_01H… --tag not_selected # a pass — costs the worker NO reputation
314
+
315
+ # GIGWORKER (free, no vidfarm account: export DOLLARPLATOON_API_KEY=…)
316
+ vidfarm gigs join-feed && vidfarm gigs feed # join read-only, then see who wants videos right now
317
+ vidfarm gigs join <invite-url> # or --registry to list every joinable machine
318
+ # BEFORE working it, check the machine is funded — see the warning below
319
+ curl -s -H "x-api-key: $DOLLARPLATOON_API_KEY" \
320
+ "https://dollarplatoon.com/api/gigs/<gig-id>" | jq '{available_funds, reserved_funds}'
321
+ vidfarm gigs work # work waiting across every machine you joined
322
+ vidfarm gigs claim <gig-id> # claim off the FIFO queue — note the task id
323
+ vidfarm gigs submit <gig-id> --task <task-id> --proof https://…/final.mp4
324
+ ```
325
+
326
+ Key resolution is `--dp-key` → `DOLLARPLATOON_API_KEY` → `GIGDESK_API_KEY` → the paid account's own key via `GET /api/v1/user/me/marketplace`. **Review promptly: silence is approval** — an unreviewed proof auto-approves after the gig's review timeout (default 48h) and you pay for it.
327
+
328
+ **Warn the gigworker off an empty machine.** A gig is a vending machine with its own on-chain balance, and `available_funds: 0` means it cannot pay, no matter how good the delivery is. Read `available_funds` on `GET /gigs/:id` before doing any work, and tell the worker plainly what it says:
329
+
330
+ - **`0`** — do not work it yet. The proof can be approved and still sit unpaid indefinitely; nothing obliges the client to top up.
331
+ - **less than the task price** — partial coverage only. The submit response carries `"warning": "Warning: gig available funds are less than the task price"` and still accepts the proof, so acceptance is not a promise of payment.
332
+ - **`reserved_funds`** is already committed to proofs ahead of this one. Judge payability on `available_funds` alone, never on the sum.
333
+ - Budget the **10% platform fee**: a $1.00 payout draws $1.10, so a $5.00 machine covers four $1.00 videos, not five.
334
+ - Compare the funds against the **task** price, not the gig's. The gig `price` is a default only; a task may carry its own, and `price: null` (`price_tbd`) means the client names the amount at approval.
335
+
336
+ Funds never move between gigs, so one funded machine says nothing about the client's other machines — check each one. Pair the funding check with the client's reputation score before committing a batch.
337
+
338
+ The upstream contract lives at **https://dollarplatoon.com/skill.md** (an index; the gigworker playbook is `skill/gigworkers.md`, funding and fees are `skill/payouts.md`). Read it rather than guessing a field name — `GET /gigs/:id` carries `price`, `terms`, `available_funds`, `reserved_funds`, `review_timeout` and `distribution`, and there is no `price_per_proof`.
339
+
340
+ A link is a **bearer credential**: whoever holds it has that mode. Prefer `upload` over `edit` for crowdsourcing (nobody can delete a colleague's work), keep one link per campaign rather than one per worker, and disable it the day the batch closes. **Free tier fallback:** minting is paid, so a free user puts a Google Drive / Dropbox / WeTransfer folder URL into the same `assets_link` / `upload_link` fields — worker agents treat them as plain URLs. What is lost: vector search, the scoped subtree, and the one-command `vidfarm shared put`.
341
+
273
342
  Two things to know. **Search is included in `read`** — that is what makes a shared folder useful to a gigworker's AI agent: it finds footage by meaning instead of paging through folders. The query embedding is billed to the **folder's owner**, not the visitor. And **only `/files` and `/temp` accept direct uploads** — `/raws`, `/approved` and `/projects` have no plain-upload backend even for the owner (raws are scanned/imported, approved posts are published renders, projects are fork storage), so an `upload` link there only creates folders. To crowdsource footage, share a `/files` folder for `upload` and import the contributions into `/raws` yourself.
274
343
 
275
344
  The web copilot exposes the same three as `browse_files action=rename|move|copy`. If you rename or move a character's folder, update the `id`, `sprite_card_path`, and `about_path` inside its manifest to match (and rename the `<character_id>.json` file itself).
@@ -2,7 +2,7 @@
2
2
 
3
3
  A free (unpaid) account's `vidfarm-api-key` is a **real key**: it authenticates on every route, and `vidfarm login` / `whoami` work normally. Plan is enforced per route, not at auth:
4
4
 
5
- - **Free on any plan** — `GET /api/v1/user/me` (identity), `/api/v1/user/me/provider-keys` (bring-your-own-key), `GET /api/v1/user/me/wallet` (reads $0.00), `GET /api/v1/user/me/tasks`, and the `/api/v1/user/me/directory*` file-tree routes (browse, search, folder, rename, move, copy) — but **not** `…/directory/shares*`: minting a public share link is paid. Visiting someone's link (`/api/v1/share/:token/*`, `/directory/preview/*`) needs no account at all.
5
+ - **Free on any plan** — `GET /api/v1/user/me` (identity), `/api/v1/user/me/provider-keys` (bring-your-own-key), `GET /api/v1/user/me/wallet` (reads $0.00), `GET /api/v1/user/me/tasks`, and the `/api/v1/user/me/directory*` file-tree routes (browse, search, folder, rename, move, copy) — but **not** `…/directory/shares*`: minting a public share link is paid. Visiting someone's link (`/api/v1/share/:token/*`, `/directory/preview/*`) needs no account at all. **The marketplace is paid-only end to end** — every `/marketplace*` page and route (the agent directory included) answers the upgrade wall for a free account, the sidebar Marketplace link is hidden for them, and the two DollarPlatoon vending machines are provisioned on the paid plan (on upgrade, for an account that started free).
6
6
  - **Paid routes answer `402 { type: "upgrade_required", upgrade_url: "/pricing", run_locally_url: "/help" }`** — never a 401. A `401` means the key is missing/invalid/revoked, so don't tell a free user to re-authenticate when they hit a 402.
7
7
  - When you see a 402: say plainly that the action needs a paid plan, then offer the two real paths — upgrade at `/pricing`, or keep going for free locally (`vidfarm serve`, local render, local decompose, own-provider keys).
8
8
 
@@ -281,8 +281,11 @@ The licensed harness also carries the **generative build workflow** guidance (ch
281
281
  | `vidfarm whoami` | `GET /api/v1/user/me` | who am I (also prints the active cost mode) |
282
282
  | `vidfarm cost-mode [minimize\|hybrid\|rich-ai\|pure-videogen]` | (local `~/.vidfarm/cost-mode.json`) | show/set the money-saving preference every billed command respects; no arg = show + explain each; `--clear` forgets it |
283
283
  | `vidfarm mode [interactive\|autonomous]` | local (`~/.vidfarm/interaction-mode.json`) | **The SECOND preference axis — ask it alongside cost mode.** Is the human in the loop? `interactive` = at checkpoints you hand them a copy-paste brief (an image prompt for a FREE web generator; a keyword list for sourcing clips) and they hand files back — usually BETTER output, and in `minimize` the only way to get custom art at all. `autonomous` = you finish solo within the budget. Independent of cost mode: every cost mode runs either way. No arg prints the pair + the explainer to relay; `--clear` forgets; per-run `--interactive`/`--autonomous`. Aliases: `interaction-mode`, `interaction`. |
284
+ | `vidfarm browser [status\|setup\|doctor]` | local (installs [browser-harness](https://github.com/browser-use/browser-harness) via `uv`) | **Free browser sourcing — the $0 substitute for the PAID `video-search` / `image-search` / `news-search` / `download-video` primitives.** `setup` runs `uv tool install --python 3.12 --upgrade --force browser-harness`, writes browser-harness's own SKILL.md into `.agents/skills/browser-harness/`, and prints the one step nothing can automate: Chrome → `chrome://inspect/#remote-debugging` → tick *Allow remote debugging* (macOS may then need `browser-harness mac-approve`). After that you drive the user's own logged-in Chrome over CDP. `status` = what's installed, `doctor` = connection check. `vidfarm doctor` reports it as `browser control` (⚠ when absent — it is optional, not required). **Offer it to every free-plan user and everyone in `cost-mode minimize` before saying a search needs a paid plan**, and ask first: it drives their personal browser. Aliases: `browser-harness`, `bh`. Full page: `references/browser-harness.md`. |
285
+ | `vidfarm browse <videos\|images\|news\|page> "<query\|url>" [--limit N] [--legacy] [--run] [--json]` | local (pure text; `--run` pipes into browser-harness) | **The browse recipe for one sourcing job**: which Google surface to open (`udm=7` videos · `udm=2` images · `udm=12` news; `--legacy` for the old `tbm=…`), what to extract off the page, and the vidfarm command it feeds (`raws scan` / `clipper` / `put-file`). Prints rather than runs by default — Google's markup moves, so an agent that reads and adapts the recipe beats one that runs it blind; `--run` when you have already browsed successfully this session. `page` mode substitutes for `download-video` by pulling the media element off the post in the user's own session. |
286
+ | `vidfarm agent-image "<subject>" [--items "a,b,c"] [--single] [--out ./sheet.png] [--folder <f>] [--check]` | local (pure text) | **Image generation the AGENT already pays for — free in EVERY cost mode, `minimize` included.** Google Antigravity / Gemini CLI (Nano Banana / Imagen) and OpenAI Codex / ChatGPT (`gpt-image`) include image generation in the subscription; **Claude Code does not** — Anthropic ships no image model. Prints the generation prompt (the same key-plate craft as `handoff image`), the steps, the local cut (`sticker-pack`/`cutout`) and the `put-file` import. Calls nothing and spends nothing, so it never gates and needs no `--yes`. `--check` (or no args) reports whether this host has the capability, from env markers plus the known-hosts table — **a hint only; your own tool list is the authority, so never claim a tool you do not have**. Free stock, `iconscout` and `mask` still come first. Aliases: `agent-imagegen`, `own-image`, `native-image`. Full page: `references/agent-included-imagegen.md`. |
284
287
  | `vidfarm handoff image --theme "<what>" [--items "a,b,c"] [--style …] [--single]` | local (pure text) | **The interactive-mode IMAGE brief.** Prints the exact prompt, the numbered steps, the free tools (meta.ai / ChatGPT / Gemini / HF Spaces) and the follow-up command. Defaults to a **sticker pack**: ONE sheet holding every item on a chroma plate → `vidfarm sticker-pack` splits it for $0. Picks a plate the art won't collide with (green art → magenta plate), spells out what the local keyer actually needs (a crisp silhouette in a different color from the plate, sealed shapes, clear gaps between items — hollow art and plate-colored detail INSIDE a shape are fine now), and carries that `--key-color` into the follow-up. `--single` for one subject. `--zoned` asks instead for a color-block sheet (one panel colour per item) and hands back a `--zones RxC` follow-up — worth it when the pack's own colors fight one plate, but leave it off for a free consumer tool that may not follow a grid. |
285
- | `vidfarm handoff raws --keywords "a,b" [--platforms tiktok,youtube] [--count N] [--purpose "…"]` | local (pure text) | **The interactive-mode CLIP-SOURCING brief** — the bottom rung of the sourcing ladder (browser control → `clipper`/`raws scan --cloud` → public raws → the human). Prints what to search, how to download (a Google *search* for a downloader, never a link that rots), and the import command for when the folder is ready. |
288
+ | `vidfarm handoff raws --keywords "a,b" [--platforms tiktok,youtube] [--count N] [--purpose "…"]` | local (pure text) | **The interactive-mode CLIP-SOURCING brief** — the bottom rung of the sourcing ladder (browser control via `vidfarm browser setup` + `vidfarm browse` → `clipper`/`raws scan --cloud` → public raws → the human). Prints what to search, how to download (a Google *search* for a downloader, never a link that rots), and the import command for when the folder is ready. |
286
289
  | `vidfarm consult [coldstart\|awareness\|angles\|hooks\|placement]` | local (pure text) | **The consultation / brainstorm chain, KEYLESS.** Offer `vidfarm ideas` first — the interview is the deeper step a director opts into after they have seen a list of ideas, not the price of entry. The cloud runs these five steps as `brainstorm/*` primitives that need a provider key or wallet credits; this prints the **identical prompt** (same source module, so they cannot drift) for the agent already in the terminal to answer itself — $0, no key, no network. Bare `consult` = the map of the four chain steps and which artifacts already exist. Auto-reads `OFFER.md` / `OFFER_<NAME>.md` from `--dir` (two offer files → it makes you name one rather than guessing the wrong product); `--offer` takes a path **or** the offer text, and a path that resolves to nothing is an error, never silently treated as the offer. `--count` mirrors the cloud bounds. **`coldstart --short` is the short-form interview**: six fixed questions (offer line, price/checkout, best customer, their complaint verbatim, dream outcome, do they know this product category exists) instead of 12-30 generated ones — instant, identical every run, and still enough for every later step. Interview only, and it takes no `--count`. **Every step reads and appends `CONTEXT.md` in `--dir`** — the durable answer file, so a later session in a new terminal starts warm instead of re-interviewing the director. Tell the director the interview is skippable before you ask anything; mark skipped answers `UNKNOWN` and carry on. `--refs` inlines the full `SELLING_*.md` documents for byte parity — off by default because it is ~34KB of your context, and the brief points at `references/hooks-and-virality.md` instead. Each step names the artifact it writes (`OFFER.md` → `awareness-levels.md` → `persuasive-angles.md` → `ad-hooks.md`) and the next command. Aliases: `consultation`, `brainstorm`. Flow: `references/onboarding.md`. |
287
290
  | `vidfarm storyboard [dir] [--init] [--frames "Title\|scene,…"] [--json]` | local (`STORYBOARD.md` / `SCRIPT.md`) | **The plan pass, and a core part of the composition format.** Scaffolds/reads the project's `STORYBOARD.md`: ordered frames with `duration`/`status`/`src`/`scene`/`voiceover`. The Vidfarm editor renders this file in its **Storyboard** view (contact sheet + per-frame comments + `outline → built → animated` progress), so it's the cheapest place to get a director's approval before building. Not to be confused with `vidfarm sequence` (which GENERATES storyboard images for the pure-videogen pipeline). Alias: `plan`. |
288
291
  | `vidfarm experiment [dir] [--init] [round …] [log <video> …] [--json]` | local (`EXPERIMENTS_DIARY.md`) | **Ad testing over weeks, not one video.** Owns the campaign ledger and ONLY that: sizes each round (`videos ÷ capacity = epochs`, where capacity is the SUM of per-channel posting rates — `--channels "tiktok_a x2, li_a 3/week, fb_a paused"` — and epoch slots are dealt out in proportion, warning on `channel-overposted`), ranks the north-star metric, flags outliers vs the median, and lints the method — two variables in one structured round, a winner promoted off one post, results read at mixed ages, a structured round handed to gigworkers, unspent capacity. Feedback, not a gate (exits 0). Also carries the FORMAT decision into planning: `--init` prints the copywriting-led menu (b-roll / talking head / process / loop background / satisfying / lifestyle / POV quote) and records the pick in Setup, which every round inherits. Two writes: `round --videos N --variable angle …` and `log <video> --comments N --channel <acct> --source flockposter --age 48h` (ALWAYS pass `--channel`: it keeps a per-account median so each video is ranked against its own account, not the fleet — account health moves numbers by multiples — and a second account's reading counts as the retest that clears `account-health-confound`) (or `log <video> --posted --channel <id>`, which only RECORDS a post). It deliberately does not re-wrap `channels` (capacity), `harness`/`qa` (constants), `handoff` (briefs), `dedupe` (per-channel copies) or `approve`+`schedule` (posting). Method: <https://vidfarm.cc/experiments.md>. Alias: `experiments`. |
@@ -299,7 +302,7 @@ The licensed harness also carries the **generative build workflow** guidance (ch
299
302
  | `vidfarm download-audio <url>` | `POST /api/v1/primitives/audio/download` + poll | download just the AUDIO track (music/voice) off a website post into a durable audio file. **PAID PLAN**. Alias: `download-post-audio` |
300
303
  | `vidfarm recycle <source>` | `POST /api/v1/primitives/social/recycle` + poll | RECYCLE a Reddit/X source into reusable JSON ("tweet to tiktok", "reddit to tiktok"): thread + comments, subreddit threads, X thread + replies, or an account's posts — text, author + avatar, stats, media URLs. `--out` saves the full payload. **PAID PLAN**. Aliases: `recycle-social`, `tweet-to-video`, `reddit-to-video` |
301
304
 
302
- > **Free plan / `cost-mode minimize`:** both download commands are gated by `guardBilled` and will refuse or warn. The free path is **Chrome**: open the URL in a real browser, save the file off the page (right-click → *Save video as*, downloads pane, or a Googled `"<platform> video downloader"` site), then `vidfarm put-file ./the-file.mp4 --folder <folder>` to bring it in for $0. The CLI prints these steps on a 402. Never tell a free user the video simply can't be downloaded.
305
+ > **Free plan / `cost-mode minimize`:** both download commands are gated by `guardBilled` and will refuse or warn. The free path is **Chrome** and you can drive it yourself: `vidfarm browser setup` then `vidfarm browse page "<url>"` (see `references/browser-harness.md`). Otherwise the user opens the URL in a real browser and saves the file off the page (right-click → *Save video as*, downloads pane, or a Googled `"<platform> video downloader"` site), then `vidfarm put-file ./the-file.mp4 --folder <folder>` to bring it in for $0. The CLI prints these steps on a 402. Never tell a free user the video simply can't be downloaded.
303
306
  | `vidfarm files [--folder <path>]` | `GET /api/v1/user/me/attachments` | list My Files assets + folders |
304
307
  | `vidfarm files --search "…" [--folder <path>]` | `POST /api/v1/user/me/attachments/search` | find My Files assets by MEANING (keyword + vector over name/folder/notes) |
305
308
  | `vidfarm get-file <id> [dest] [--print]` | (resolve id → view_url, then stream/print) | read one My Files asset |
@@ -357,6 +360,8 @@ What it flags:
357
360
  | `badge-chip-row` | error | 2+ sibling small rounded filled tags — the "✓ No Credit Card Needed · ✓ 30-Min Trial" strip |
358
361
  | `static-pill` | error | ONE filled, padded, ≥20px-radius capsule around static text — a stat/label badge like "10 hrs / week", "STEP 2", "EP.01". Skips active-word `spotlight`/`karaoke` highlights (the only legitimate pill) and mock social UI (chat bubbles, comment cards — mark yours `data-vf-mock-ui` if the heuristic misses it) |
359
362
  | `card-panel` / `glass-card` | error | A rounded box with a border/shadow/`backdrop-filter` wrapping 2+ elements. A tight legibility **band** (radius ≤8px, one text run, no border/shadow) stays legal |
363
+ | `layout-template` | error | The frame composed like a **page**: 3+ stacked text blocks in one container ending in a call to action — headline + subheading + CTA, the web hero/modal body. Fires with or without the box around it, because the STACK is the tell. Three stacked lines with no CTA are a legitimate title card and pass |
364
+ | `modal-scrim` | error | A full-frame backdrop that is **blurred AND dimmed** — the website-modal staging that pushes the picture back so a floating block pops. Blur alone passes (the blurred fill behind a 16:9 clip in a 9:16 frame is a real technique); it needs the dimming too, and a bed faded under `opacity:0.25` is an ambient texture wash, not staging, so it passes as well |
360
365
  | `gradient-text` | error | `background-clip:text` gradient headline fills |
361
366
  | `clickable-element` | error/warn | `<button>`, `<form>`, `<input>`; `<a href>` warns |
362
367
  | `web-framework-classes` | error/warn | Bootstrap/Tailwind class tokens (`btn`, `badge`, `card`, `hero`, `col-*`, `rounded-full`, `shadow-lg`, `backdrop-blur`, `bg-gradient-to-*`) or a linked CSS framework. A `<script>` CDN for GSAP/anime.js is fine |
@@ -387,16 +392,17 @@ The four modes, quoted as **cost per finished video**. The first two are spend p
387
392
 
388
393
  | Mode | Per video | Posture |
389
394
  |---|---|---|
390
- | `minimize` | **$0 — explicitly free** | free local engines + free stock media only; billed ops refuse without `--yes` |
395
+ | `minimize` | **$0 — explicitly free** | free local engines + free stock media, plus any image generation the AGENT's own subscription already includes; billed ops refuse without `--yes` |
391
396
  | `hybrid` *(default recommendation)* | **~$0.01–$1** | free where free, AI where it clearly wins; each billed op prints its cost |
392
397
  | `rich-ai` | **$1+** | AI video gen mints **reusable greenscreen raws** (saved to the library, reused later); motion is hyperframes HTML/CSS over the keyed raws |
393
398
  | `pure-videogen` | **$5+** | script in text → storyboard in images → frame-by-frame scene generation. No reuse, no HTML motion |
394
399
 
395
400
  **All of it bills to the user's own AI provider keys (BYOK)** — the keys saved with `vidfarm add-provider-key <provider> <key>` or at **Settings → Bring your own keys** (<https://vidfarm.cc/settings/developer>). The model providers charge those keys directly; Vidfarm wallet credits only come into play when the user deliberately runs on the platform key instead of their own. So `minimize` isn't "cheap", it's **zero**: nothing reaches a paid key at all.
396
401
 
397
- `vidfarm cost-mode <minimize|hybrid|rich-ai|pure-videogen>` records a single spend preference (in `~/.vidfarm/cost-mode.json`) that every **billed** command honors: `generate`, `music`, `decompose`, `inspiration-decompose`, `create`, `replicate`, `inpaint`, `create-overlay`, `cutout --generate` (only the generation step; a bare `cutout` on an existing graphic is free), and the cloud paths of `render --target cloud`, `tts --cloud`, `stt --cloud`, `remove-greenscreen` (non-`--local`), `dedupe --cloud`. FREE local engines never gate (`render` local default, `tts --engine local`, `stt --engine whisper`, `remove-greenscreen --local`, `dedupe --local`, `cutout` on a file/url, all the file-editing verbs). `vidfarm media search` (the free stock catalog — pixabay/openverse/iconify music, SFX, images, icons, stock video) is also free and never gates. `vidfarm iconscout` **search** is free and never gates either; only `vidfarm iconscout get` on a PREMIUM asset can spend (a few cents on the wallet), and free assets cost $0. `vidfarm video-search` / `image-search` / `news-search` (Google) are **paid-plan** but flat **$0.0003 per call** — two orders of magnitude under one AI image attempt — so they do not gate in any cost mode; in `minimize`, one wide search beats one generation every time.
402
+ `vidfarm cost-mode <minimize|hybrid|rich-ai|pure-videogen>` records a single spend preference (in `~/.vidfarm/cost-mode.json`) that every **billed** command honors: `generate`, `music`, `decompose`, `inspiration-decompose`, `create`, `replicate`, `inpaint`, `create-overlay`, `cutout --generate` (only the generation step; a bare `cutout` on an existing graphic is free), and the cloud paths of `render --target cloud`, `tts --cloud`, `stt --cloud`, `remove-greenscreen` (non-`--local`), `dedupe --cloud`. FREE local engines never gate (`render` local default, `tts --engine local`, `stt --engine whisper`, `remove-greenscreen --local`, `dedupe --local`, `cutout` on a file/url, all the file-editing verbs). `vidfarm media search` (the free stock catalog — pixabay/openverse/iconify music, SFX, images, icons, stock video) is also free and never gates. `vidfarm iconscout` **search** is free and never gates either; only `vidfarm iconscout get` on a PREMIUM asset can spend (a few cents on the wallet), and free assets cost $0. `vidfarm video-search` / `image-search` / `news-search` (Google) are **paid-plan** but flat **$0.0003 per call** — two orders of magnitude under one AI image attempt — so they do not gate in any cost mode; in `minimize`, one wide search beats one generation every time. They are still **paid-plan** routes, though — on a free plan they 402, and the answer there is `vidfarm browser setup` + `vidfarm browse videos|images|news "<query>"`, which is free and never gates.
398
403
 
399
404
  - **minimize ($0 videos)** — a billed op is **refused** unless you add `--yes`; the error names the free local alternative (which now includes the matching `vidfarm media search` for music/SFX/image/video). Use this to guarantee no surprise AI spend. Before paying to generate music, sound effects, or images, try `vidfarm media search "<meaning>" --type <bgm|sfx|image|vector|icon|video>` first — free royalty-free assets instead of a billed `music`/`generate` call. **Check the keyless sources first — Openverse (CC/CC0 music, SFX, images) and iconify (icons) need no account at all**, so they always work in `minimize`. Photos/vectors/stock-video need a **free Pixabay key** that **may already be saved** — check `vidfarm provider-keys` (or web **Settings → Bring your own keys** / <https://vidfarm.cc/settings/developer>) before assuming a short result means "no key." If absent, save one once: `vidfarm add-provider-key pixabay <key>` (free key from <https://pixabay.com/api/docs/>), the Settings surface, or hand it to the desktop AI agent to run that command. **For icons, STICKERS, illustrations, 3D props and Lottie, use `vidfarm iconscout "<meaning>" --style sticker --free` instead** — it needs no key at all, search is free, and free assets download for $0 (a credit line is the only price). Prefer it over a generated graphic in every mode, not just `minimize`.
405
+ - **minimize can use IMAGE GENERATION — when the agent already owns it.** `minimize` bans *billed* AI, not AI. If the agent driving the terminal includes image generation in its own subscription — **Google Antigravity / Gemini CLI (Nano Banana / Imagen) and OpenAI Codex / ChatGPT (`gpt-image`) do; Claude Code does NOT**, because Anthropic ships no image model — then generating a graphic costs Vidfarm $0 and the provider $0 extra, so it is allowed with no `--yes` and no gate. `vidfarm agent-image --check` reports whether this host has it (env sniffing + a known-hosts table — treat it as a hint and check your own tool list); `vidfarm agent-image "<subject>" --items "a,b,c"` prints the prompt, the plate rules and the cut + import commands. Order on the ladder: free stock → `iconscout` → `mask` → **your own image tool** → the human hand-off below → a confirmed billed `generate`. It is images only — no agent subscription includes video generation, so AI video stays gated. Full page: `references/agent-included-imagegen.md`.
400
406
  - **minimize still gets CUSTOM images — via a free manual generator.** A refused `generate` is not the end of the road. Offer the user the manual loop (ask once, then make it the session default): **you write the prompt → they run it free in <https://meta.ai>, free-tier ChatGPT, or a free Hugging Face image Space (<https://huggingface.co/spaces>) → they hand the PNG back** via `vidfarm put-file ./sheet.png` or web **My Files**. Ask for **one sheet holding every graphic you need**, gridded on a **flat pure-green plate** (`#00FF00`), no text — one round trip instead of N, which saves the user's time and your tokens. Then split it locally for $0: `vidfarm mask ./sheet.png --crop x,y,w,h --flat "#00FF00" --out prop-a.png`, once per element (drop `--flat` and let local ONNX matting handle it if the tool ignored the green background). Full prompt template + loop: recipe `recipes/cutout-graphics-for-explainers.md` (“Free manual image-gen”).
401
407
  - **hybrid (~$0.01–$1 per video)** *(default recommendation)* — billed ops run but print a one-line cost notice each, charged to the user's BYOK key.
402
408
  - **rich-ai ($1+ per video)** — billed ops run without gating; cost is still printed. AI *video* generation is the line item that pushes a video well past $1 — quote it before running. Spend it on **reusable greenscreen raws**, not on finished shots: `vidfarm avatar "<who>" --say "<line>"` for presenters, `vidfarm create-overlay "<subject>"` / `cutout --generate` for props and illustrations, or `generate video` prompted onto a flat key-color plate. The primitives key the plate in the same job and also hand back `greenscreen_source_url`, so re-keying at a different tolerance is free. Then **animate in hyperframes HTML/CSS over the keyed raws** — generated seconds cost money, motion doesn't — and **persist every asset**: `vidfarm put-file ./keyed.webm --folder greenscreen/<name> --notes "<what it is, when to reuse it>"` (notes are vector-embedded → `vidfarm files --search`), or `vidfarm clipper ./generated.mp4 --folder greenscreen-cast --name "<name>"` for footage-shaped raws in `/raws`. Both stores are **local by default** under `~/.vidfarm`; on a **paid/Pro plan** mirror them with `vidfarm sync push /files` and `vidfarm sync push /raws` (`sync pull` elsewhere, `--dry-run` first). Before generating, always search what already exists — `vidfarm raws search "<meaning>"` then `vidfarm public-raws --category greenscreen --query "<meaning>"`. That is what makes the mode amortize: the next video can reuse the same cast in `hybrid`/`minimize` for ~$0.
@@ -424,7 +430,8 @@ Local, wallet-free Vidfarm is a **three-part toolchain** that composes — insta
424
430
  ```bash
425
431
  npm install -g @officexapp/vidfarm-devcli # the `vidfarm` orchestrator
426
432
  npm install -g hyperframes # Vidfarm's open-source render/animation engine (whitelabel)
427
- brew install ffmpeg # or apt install ffmpeg a system ffmpeg on PATH is honored first; ffmpeg-static is bundled as a fallback
433
+ # ffmpeg is BUNDLED (ffmpeg-static + a per-platform ffprobe) install one only if doctor asks:
434
+ # brew install ffmpeg / apt install ffmpeg / winget install Gyan.FFmpeg
428
435
  vidfarm doctor # ✓/⚠/✗ for node, ffmpeg, hyperframes, Chrome, auth, keys, skills
429
436
  ```
430
437