@officexapp/vidfarm-devcli 0.21.39 → 0.21.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/editor-capabilities/SKILL.md +16 -0
- package/.agents/skills/vidfarm/SKILL.md +28 -4
- package/.agents/skills/vidfarm/harnesses/README.md +1 -0
- package/.agents/skills/vidfarm/harnesses/explainer.HARNESS.md +11 -0
- package/.agents/skills/vidfarm/harnesses/product-demo.HARNESS.md +2 -0
- package/.agents/skills/vidfarm/harnesses/product-explainer.HARNESS.md +242 -0
- package/.agents/skills/vidfarm/recipes/bulk-scripting-with-a-harness.md +1 -1
- package/.agents/skills/vidfarm/recipes/cutout-graphics-for-explainers.md +2 -0
- package/.agents/skills/vidfarm/recipes/onboard-a-new-director.md +1 -0
- package/.agents/skills/vidfarm/references/automation-and-local-dev.md +20 -8
- package/.agents/skills/vidfarm/references/content-ideas.md +111 -0
- package/.agents/skills/vidfarm/references/editor-workflows.md +36 -3
- package/.agents/skills/vidfarm/references/onboarding.md +2 -0
- package/.agents/skills/vidfarm/references/primitives.md +67 -0
- package/.agents/skills/vidfarm-media/SKILL.md +50 -0
- package/SKILL.director.md +270 -16
- package/SKILL.md +1 -1
- package/crowdsourcing.md +49 -1
- package/dist/src/cli.js +408 -19
- package/dist/src/devcli/cost-mode.js +8 -0
- package/dist/src/devcli/experiments.js +10 -5
- package/dist/src/devcli/qa-check.js +74 -0
- package/dist/src/devcli/skill-docs.js +103 -0
- package/experiments.md +33 -2
- package/package.json +4 -1
|
@@ -84,7 +84,7 @@ vidfarm qa ./work --harness hooks --harness ./brand/HOUSE.md # built-in + your o
|
|
|
84
84
|
|
|
85
85
|
> Don't confuse `HARNESS.md` with the `.harness/` directory `vidfarm pull` writes. That directory is machine-generated context (`context.json`, `agent-guide.md`), regenerated on every pull — never hand-edit it. `HARNESS.md` is the one the director owns.
|
|
86
86
|
|
|
87
|
-
Bundled bases (`vidfarm harness list`, files under `.agents/skills/vidfarm/harnesses/`): **`short-form`** (the default — the four charges hook/loop/payoff/bait + the standalone rule), **`hooks`** (hook-variant batches: chunk-1 legibility, the unguessable test, the anti-patterns that only show up at volume), **`ugc-testimonial`**, **`explainer`**, **`product-demo
|
|
87
|
+
Bundled bases (`vidfarm harness list`, files under `.agents/skills/vidfarm/harnesses/`): **`short-form`** (the default — the four charges hook/loop/payoff/bait + the standalone rule), **`hooks`** (hook-variant batches: chunk-1 legibility, the unguessable test, the anti-patterns that only show up at volume), **`ugc-testimonial`**, **`explainer`**, **`product-demo`**, **`product-explainer`** (introducing a brand nobody has heard of, with no usable screen footage: the plain-English line by t=5s, the ≤3-text-run sticker-led open, VO + music bed, and the assignment method that stops N client videos converging). Each is a *starting point to edit*, never a house style to conform to — the parts that matter most are the parts the director adds. A harness can also be any file anywhere: `--harness ./campaigns/q3/RULES.md` is fully supported, and `VIDFARM_HARNESS=./work/HARNESS.md` sets a default for a whole run.
|
|
88
88
|
|
|
89
89
|
**The format is two halves, and the split is deliberate:** a front-matter `checks:` block the CLI settles deterministically (duration, aspect, `hook_words_max`, `forbid_text`, `first_frame_text`, … — full key list in `harnesses/README.md`), and every `- [ ]` checkbox in the body, which comes back as a **review item for you to answer**. "Is the withheld answer one the viewer can't supply themselves?" is a judgment call; a linter claiming to settle it would be lying. **Answer the review items honestly in your report** — the CLI prints them precisely because it can't.
|
|
90
90
|
|
|
@@ -286,7 +286,9 @@ The licensed harness also carries the **generative build workflow** guidance (ch
|
|
|
286
286
|
| `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`. |
|
|
287
287
|
| `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`. |
|
|
288
288
|
| `vidfarm wallet [--job <id>\|--tracer <t>] [--limit <n>]` | `GET /api/v1/user/me/wallet` | cost log: balance + lifetime spend + recent charges. `--job <renderJobId>` prints **what that one video cost** (sums its charges); `--tracer <t>` sums a tracer. Cloud-only; readable on the free plan too (shows $0.00). Aliases: `spend`, `costs` |
|
|
289
|
-
| `vidfarm
|
|
289
|
+
| `vidfarm iconscout "<query>" [--asset icon\|illustration\|3d\|lottie] [--style sticker] [--free\|--premium] [--sort …] [--limit n]` | `GET /api/v1/primitives/iconscout/search` | **The cheap alternative to AI image generation.** Designer-made icons, STICKERS, illustrations, 3D props and Lottie. Reach for this BEFORE `generate image` for any of those: an AI attempt costs cents, needs a prompt loop, and rarely returns a clean transparent vector, while IconScout hands back a finished SVG / transparent PNG on the first try. **Search is FREE and never gates.** Needs **no key** — vidfarm's own IconScout account serves it. Aliases: `icons`, `stickers` |
|
|
290
|
+
| `vidfarm iconscout get <uuid> [--format svg\|png\|…] [--size px] [--out file]` | `POST /api/v1/primitives/iconscout/download` | Download one asset to a durable vidfarm URL you can place. A **free** asset costs $0 (honour the returned `attribution`); a **premium** asset runs on vidfarm's IconScout subscription for a few cents on the wallet — still under one AI attempt. Saving your own `iconscout` key makes downloads free. Idempotent per uuid+format. |
|
|
291
|
+
| `vidfarm provider-keys` / `vidfarm add-provider-key <p> <secret>` | `GET`·`POST /api/v1/user/me/provider-keys` | manage AI keys. `iconscout` is the one provider that packs TWO values into one secret: `<client_id>:<client_secret>` |
|
|
290
292
|
| `vidfarm upload <file> [--folder <path>]` | presign → S3 PUT → finalize (`.../temporary-files/presign` + `.../temporary-files`) | upload → durable URL (ephemeral, 30-day TTL; prefer `--folder temp` for scratch). Goes direct to S3, so large files (up to **200 MB**) bypass the ~6 MB Lambda body limit |
|
|
291
293
|
| `vidfarm download <url> [dest]` | (streams any URL to disk) | download media from a **direct** media URL. Free — no plan, no job |
|
|
292
294
|
| `vidfarm download-video <url> [--quality best\|hd\|full_hd]` | `POST /api/v1/primitives/videos/download` + poll | **download a video FROM A WEBSITE** (YouTube/TikTok/IG/X/other supported posts) into durable Vidfarm media; photo/carousel posts return an ordered slideshow. **PAID PLAN** (wallet-billed resolver; free plans get 402). Aliases: `download-post`, `download-url` |
|
|
@@ -306,11 +308,12 @@ The licensed harness also carries the **generative build workflow** guidance (ch
|
|
|
306
308
|
| `vidfarm raws preset list\|run\|save` / `raws export <ids…> --to <dir>` | (local library) | saved queries; copy raw MP4s out |
|
|
307
309
|
| `vidfarm lint <dir\|composition.html>` | (local static validation) | pre-publish composition check: timing, overlaps, preset names, media src |
|
|
308
310
|
| `vidfarm stills <dir> [--at 0,2.5,…] [--sheet]` | (local in-process render of PNG frames) | visually verify an edit without a full render. **`--sheet` also tiles them into one contact sheet** (`<out>/contact-sheet.png`, `--sheet-out`/`--sheet-width` to tune) — the whole-video review pass: read it as ONE image and sequence-level drift (uneven margins, three type sizes, a wandering accent colour, N identical beats, a jarring join) becomes obvious where per-scene checks never see it |
|
|
309
|
-
| `vidfarm qa <dir\|composition.html> [--harness <name\|path>…] [--json] [--strict]` | (local static QA — **devcli-only**, no cloud/REST twin) | **social-native QA: HTML slop + first frame + font regime. Run it on EVERY video you produce.** `--harness` grades against a HARNESS.md too (stackable). Free, instant, feedback-only |
|
|
311
|
+
| `vidfarm qa <dir\|composition.html> [--harness <name\|path>…] [--json] [--strict] [--max-revisions <n>] [--reset-revisions]` | (local static QA — **devcli-only**, no cloud/REST twin) | **social-native QA: HTML slop + first frame + font regime. Run it on EVERY video you produce.** `--harness` grades against a HARNESS.md too (stackable). Free, instant, feedback-only. **Optional** — nothing calls it, skipping it is fine, and watching the render is the review that counts. **Revision governor:** it counts how many times the composition CHANGED between passes (a re-run on an untouched file is free) and after **1 revision** withholds the findings and says stop — the base case that keeps an autonomous agent out of a qa→fix→qa loop. State lives in `.vidfarm-qa-state.json` beside the composition; `--max-revisions <n>` raises it (`0` disables), `--reset-revisions` starts over |
|
|
310
312
|
| `vidfarm harness list\|show <ref> [--dna <strand>]\|init <name> [--out <path>]\|derive <forkId\|dir>\|check <dir>` | (local — **devcli-only**) | **HARNESS.md: the reusable AI harness for one format or template.** `init` copies a bundled base to edit; `derive` turns a decomposed template's DNA into one ("give me the harness for this template_id"); `check` is `vidfarm qa` under the harness noun |
|
|
311
313
|
| `vidfarm doctor` | (local environment triage) | check ffmpeg/node/keys/agent CLI/poisoned env + list local serve/preview processes before debugging anything else; `--kill-orphans` reaps dead servers squatting ports (fixes the "Waiting for preview server…" hang) |
|
|
312
314
|
| `vidfarm skills list\|add <name>\|update` | `GET /skill-pack/index.json` · `/skill-pack/:name/*` | install/refresh skill packs (see "Skill packs — import on demand") |
|
|
313
|
-
| `vidfarm skill ls\|show <path>\|search "<term>"\|path` | (local — **offline, no account**) | **Read this pack straight off disk.** A full copy ships inside the devcli tarball and is pinned to the installed version. `search` greps all
|
|
315
|
+
| `vidfarm skill ls\|topics\|show <path\|topic>\|search "<term>"\|path` | (local — **offline, no account**) | **Read this pack straight off disk.** A full copy ships inside the devcli tarball and is pinned to the installed version. `search` greps all 23 files at once — the cheapest way to find one paragraph without loading a whole reference. **`topics` is the spoken-name index** (meme-recaption, product-explainer, captions, first-frame, blurred-plate, density, avatar, dedupe, …) and `show <topic>` prints just that SECTION, not the 650-line file it lives in |
|
|
316
|
+
| `vidfarm ideas [topic] [--topic "<offer>"] [--family <name>] [--families] [--count <n>] [--json]` | (local — **offline, free, no AI call**) | **"What should I post?"** — the 50-frame content-idea angle bank, read out of `references/content-ideas.md` so the CLI and the skill never drift. `--topic` fills every frame with the director's offer as a starter line; `--count` samples across families instead of truncating. It hands over frames, not finished titles — sharpen each one, then write hook/loop/payoff/bait |
|
|
314
317
|
| `vidfarm tts "…" --engine local` / `vidfarm stt <file> --engine whisper` | (keyless LOCAL engines: Kokoro-82M TTS, whisper.cpp STT) | narration + word-timestamp transcripts with zero keys and zero accounts |
|
|
315
318
|
| `vidfarm remove-background <video\|image>` | (local ONNX matting — free) | transparent-subject media for occlusion captions/cutouts (arbitrary/messy background; for a FLAT solid background use `remove-background-greenscreen`) |
|
|
316
319
|
| `vidfarm capture <url>` | (local headless-Chrome capture) | website screenshots/assets for website-to-video flows |
|
|
@@ -322,7 +325,7 @@ The licensed harness also carries the **generative build workflow** guidance (ch
|
|
|
322
325
|
|
|
323
326
|
**Approving a locally rendered MP4 (the URL-first rule + the durability rule).** The approve route (`POST /api/v1/approved/posts`) and every media-taking route accept a `url`, never raw file bytes — so you never "upload to approve" in one shot. An approved post is a **permanent** share page, so the media must live in **durable My Files**, not the 30-day temp store (a temp-hosted video would 404 the share page after 30 days). The correct sequence for a big local file is: (1) `POST /api/v1/user/me/attachments/presign` with `{ file_name, content_type, size_bytes }` → (2) PUT the raw bytes to the returned presigned S3 URL → (3) `POST /api/v1/user/me/attachments` (finalize) → use the returned durable `viewUrl` as the approve media `url`. `vidfarm approve --video ./final.mp4` does all of this automatically (durable by default; up to **200 MB**). Never POST a large file as multipart to `.../attachments/upload` against the cloud host: that path proxies through Lambda and caps near 6 MB (it exists only as a fallback for local-storage `vidfarm serve` boxes). Only use the temp-store route (`.../temporary-files/*`, or `vidfarm approve --temp`) for a **throwaway** preview you don't mind losing in 30 days.
|
|
324
327
|
|
|
325
|
-
## `vidfarm qa` — the social-native QA pass (devcli-only,
|
|
328
|
+
## `vidfarm qa` — the social-native QA pass (devcli-only, OPTIONAL)
|
|
326
329
|
|
|
327
330
|
```bash
|
|
328
331
|
vidfarm qa ./work # human-readable findings + verdict
|
|
@@ -332,12 +335,14 @@ vidfarm qa ./work --harness hooks # + grade against a HARNESS.md (repeatab
|
|
|
332
335
|
# auto-discovers ./work/HARNESS.md)
|
|
333
336
|
```
|
|
334
337
|
|
|
335
|
-
**
|
|
338
|
+
**It is OPTIONAL.** Nothing requires it, and skipping it is a legitimate choice — **watching the render is the review that actually counts**, and a clean `qa` is not one. When you do run it, it is free and instant (pure DOM, no ffmpeg/Chrome/network), and it is the only automated check for the thing that most often ruins an agent-made video: **HTML slop**. Compositions are authored in HTML, so an agent's web-page instincts leak straight onto the frame as landing-page furniture that appears on every website and in **zero** real TikToks.
|
|
336
339
|
|
|
337
340
|
It also judges **one frame on its own terms: t=0**, because that frame becomes the thumbnail every feed and share sheet freezes on (see `references/editor-workflows.md`, "The first frame is the thumbnail"). Pair it with `vidfarm stills ./work --at 0` — QA finds the structural cause, the still shows you the actual poster.
|
|
338
341
|
|
|
339
342
|
**It is feedback, not a gate.** Default exit code is **0** even when it finds slop; nothing in the render or publish path calls it; it never runs automatically. `--strict` exists only if you deliberately want a CI failure. A finding you disagree with is fine to ignore and say so — it is a lint, not a verdict on the work.
|
|
340
343
|
|
|
344
|
+
**One fix round is the default, not two.** The revision governor stops at **1** revision: the first pass names the slop, one fix clears it, and a second round is nearly always an agent polishing its own taste rather than removing a defect. **The human owns that number** — `--max-revisions <n>` raises it whenever they want another round, `0` disables the governor entirely, and `--reset-revisions` starts the count over. Never raise it on your own initiative to keep a loop alive; ask.
|
|
345
|
+
|
|
341
346
|
**It is a BLOCKLIST, not an allowlist.** It names specific known-bad web patterns. Everything it doesn't name is legal, so a weird, ugly, hand-made, or wildly stylized composition passes untouched. It will never push your videos toward one house style — if it fires on a genuine creative choice, that's a bug in the rule, not in your video.
|
|
342
347
|
|
|
343
348
|
What it flags:
|
|
@@ -385,9 +390,9 @@ The four modes, quoted as **cost per finished video**. The first two are spend p
|
|
|
385
390
|
|
|
386
391
|
**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.
|
|
387
392
|
|
|
388
|
-
`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.
|
|
393
|
+
`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.
|
|
389
394
|
|
|
390
|
-
- **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.
|
|
395
|
+
- **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`.
|
|
391
396
|
- **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”).
|
|
392
397
|
- **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.
|
|
393
398
|
- **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.
|
|
@@ -485,12 +490,19 @@ Installing `@officexapp/vidfarm-devcli` puts a **complete copy of this pack on d
|
|
|
485
490
|
|
|
486
491
|
```bash
|
|
487
492
|
vidfarm skill ls # every file, with sizes
|
|
493
|
+
vidfarm skill topics # the craft by SPOKEN name → file § section
|
|
488
494
|
vidfarm skill show primitives # shorthand resolves to references/primitives.md
|
|
495
|
+
vidfarm skill show meme-recaption # a TOPIC prints just that section
|
|
489
496
|
vidfarm skill show harnesses/README.md # or an exact path
|
|
490
497
|
vidfarm skill search "greenscreen" # grep all of it — find the paragraph, then open that file
|
|
491
498
|
vidfarm skill path # where the bundled copy lives
|
|
499
|
+
|
|
500
|
+
vidfarm ideas --families # the 50-frame idea bank, by family
|
|
501
|
+
vidfarm ideas --topic "bookkeeping for trades" --count 20
|
|
492
502
|
```
|
|
493
503
|
|
|
504
|
+
**Ask by topic before you ask by file.** `vidfarm skill topics` maps what a director actually says ("how do I write a meme recaption?", "product explainer", "captions", "first frame", "density") to the exact section that answers it, and `skill show <topic>` prints that section alone. Opening `editor-workflows.md` to find 25 lines is the expensive way to get the same paragraph.
|
|
505
|
+
|
|
494
506
|
**Prefer `skill search` over opening a big reference.** `editor-workflows.md` is ~650 lines and `automation-and-local-dev.md` ~520; a grep that returns `references/primitives.md:214` costs almost nothing and tells you exactly which file to load.
|
|
495
507
|
|
|
496
508
|
Two things this does NOT mean:
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
## Content ideas — the angle bank
|
|
2
|
+
|
|
3
|
+
Read this when a director says **"give me content ideas"**, "what should I post", "I need 30 videos for the month", "I'm out of ideas", or when a batch run needs N *different* videos instead of N variants of one video.
|
|
4
|
+
|
|
5
|
+
**What this is.** A fixed bank of **50 content frames**. A frame is a reusable shape for a video's subject — not a hook line, not a script. You take the director's topic (their offer, their niche, their product, their audience's world) and pour it into a frame: `the rise of` + `dropshipping supplements` → *"The rise of the supplement dropship store"*. One topic against 50 frames is 50 distinct videos, and they do not read as repeats, because each frame changes what the video is *about*, not just how it opens.
|
|
6
|
+
|
|
7
|
+
**How to use it (the loop).**
|
|
8
|
+
|
|
9
|
+
1. **Get the topic.** In priority order: read the director's **`OFFER.md`** if one exists (see `onboarding.md`); **if they named a URL** — "content ideas for my offer example.com" — **fetch the site and read it** (home page, plus the pricing and about pages when they exist) and pull the offer, the audience, the promise, the objections, and the product vocabulary straight off the page; otherwise ask for the offer, the niche, and the audience in one question. Never generate ideas against a topic you guessed. When you work from a URL, **state the offer you read back in one line before the list** ("Reading example.com: a $49/mo bookkeeping tool for solo trades") so the director can correct it before you produce 20 ideas off a wrong premise — and offer to save that line plus the ideas as `OFFER.md` + `content-ideas.md` in their folder.
|
|
10
|
+
2. **Pick frames, don't dump the list.** Choose 10–20 frames that actually fit the topic and the audience's awareness stage — a solution-unaware audience wants `what everyone gets wrong` and `how it works`; a product-aware audience wants `then vs now`, `cheap vs expensive`, `one decision that changed everything`. Say the frame name next to each idea so the director can ask for more of that shape.
|
|
11
|
+
3. **Write each idea as a title, not a frame.** Output `"The one pricing mistake that killed our first 400 orders"`, not `"one mistake that changed everything — about pricing"`. A frame that stays abstract is not an idea yet.
|
|
12
|
+
4. **Then run it through the hook harness.** A content idea is the *subject*; it is not the four charges. Every idea a director picks still needs hook / loop / payoff / bait written before the timeline — `references/hooks-and-virality.md`. The frames on this list are deliberately curiosity-shaped, which makes the loop easy to name, but never skip that pass.
|
|
13
|
+
5. **Batch it properly.** If the director wants the whole set produced, that is scripting mode with a `HARNESS.md` — `recipes/bulk-scripting-with-a-harness.md`. One frame per video, one line in the plan file.
|
|
14
|
+
|
|
15
|
+
**Give lots when asked.** "Give me content ideas" means volume. Return **20+ titled ideas** by default, grouped by frame family, not three polite suggestions. The director prunes; you supply.
|
|
16
|
+
|
|
17
|
+
### The 50 frames
|
|
18
|
+
|
|
19
|
+
**Arc & subject frames — what the video is the story of**
|
|
20
|
+
|
|
21
|
+
- the history of
|
|
22
|
+
- the rise of
|
|
23
|
+
- the fall of
|
|
24
|
+
- the future of
|
|
25
|
+
- the psychology of
|
|
26
|
+
- the science of
|
|
27
|
+
- the business of
|
|
28
|
+
- the evolution of
|
|
29
|
+
|
|
30
|
+
**Superlative frames — the extreme case carries the video**
|
|
31
|
+
|
|
32
|
+
- the biggest mistakes
|
|
33
|
+
- the biggest successes
|
|
34
|
+
- the biggest failures
|
|
35
|
+
|
|
36
|
+
**Hidden-knowledge frames — the strongest curiosity loops on the list**
|
|
37
|
+
|
|
38
|
+
- the hidden side
|
|
39
|
+
- the untold story
|
|
40
|
+
- what really happened
|
|
41
|
+
- what everyone gets wrong
|
|
42
|
+
- what nobody noticed
|
|
43
|
+
|
|
44
|
+
**Mechanism & cause frames — the explainer shapes**
|
|
45
|
+
|
|
46
|
+
- how it works
|
|
47
|
+
- why it works
|
|
48
|
+
- why it failed
|
|
49
|
+
- why it became popular
|
|
50
|
+
- why it disappeared
|
|
51
|
+
|
|
52
|
+
**Change-over-time frames**
|
|
53
|
+
|
|
54
|
+
- how it changed
|
|
55
|
+
- how it started
|
|
56
|
+
- how it ended
|
|
57
|
+
- what happened next
|
|
58
|
+
- before it existed
|
|
59
|
+
- after it disappeared
|
|
60
|
+
|
|
61
|
+
**Contrast frames — two-column videos, and the easiest to build visually**
|
|
62
|
+
|
|
63
|
+
- then vs now
|
|
64
|
+
- old vs new
|
|
65
|
+
- best vs worst
|
|
66
|
+
- winner vs loser
|
|
67
|
+
- myth vs reality
|
|
68
|
+
- expectation vs reality
|
|
69
|
+
- beginner vs expert
|
|
70
|
+
- cheap vs expensive
|
|
71
|
+
- simple vs complicated
|
|
72
|
+
- cause vs effect
|
|
73
|
+
- problem vs solution
|
|
74
|
+
- theory vs evidence
|
|
75
|
+
- past vs future
|
|
76
|
+
|
|
77
|
+
**Pivot frames — one thing turned everything**
|
|
78
|
+
|
|
79
|
+
- one decision that changed everything
|
|
80
|
+
- one mistake that changed everything
|
|
81
|
+
- one person who changed everything
|
|
82
|
+
- one event that changed everything
|
|
83
|
+
- the chain reaction
|
|
84
|
+
|
|
85
|
+
**Completionist frames — long-form and carousel shapes**
|
|
86
|
+
|
|
87
|
+
- the complete timeline
|
|
88
|
+
- the complete story
|
|
89
|
+
- the complete guide
|
|
90
|
+
- the complete breakdown
|
|
91
|
+
- the rabbit hole
|
|
92
|
+
|
|
93
|
+
### Frame → format notes
|
|
94
|
+
|
|
95
|
+
The frame also suggests how to build it, which saves a planning round:
|
|
96
|
+
|
|
97
|
+
| Frame family | Natural format | Build notes |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| Contrast (`then vs now`, `cheap vs expensive`) | Split screen or A/B beat pairs | Cheapest to produce — two stills or two clips per beat. Great for the cutout/sticker explainer style. |
|
|
100
|
+
| Hidden-knowledge (`what nobody noticed`, `the untold story`) | Talking head, or footage + kinetic captions | The loop writes itself; state the timestamp it closes at anyway. |
|
|
101
|
+
| Mechanism (`how it works`, `why it works`) | Faceless explainer with cutouts | House style applies — white stage, word-pop captions, female TTS. See `recipes/cutout-graphics-for-explainers.md`. |
|
|
102
|
+
| Arc (`the rise of`, `the history of`) | Montage over narration, dated beats | Source footage from the free public raws catalog first (`vidfarm public-raws`). |
|
|
103
|
+
| Pivot (`one decision that changed everything`) | Single-story short, cold open on the aftermath | Open on the consequence, then rewind. |
|
|
104
|
+
| Completionist (`the complete timeline`) | Longer piece, or a numbered series | Usually better as N videos than one long one — one entry per short. |
|
|
105
|
+
|
|
106
|
+
### Do not
|
|
107
|
+
|
|
108
|
+
- **Do not hand back the raw 50-item list as the answer.** The list is your instrument; ideas applied to the director's topic are the deliverable.
|
|
109
|
+
- **Do not stack two frames in one title** ("the untold story of why it failed"). One frame per video, or the video has two subjects and lands neither.
|
|
110
|
+
- **Do not use a frame the topic can't honestly fill.** `the untold story of` a two-week-old product is a lie the audience catches. Pick a frame the facts support.
|
|
111
|
+
- **Do not treat the frame as the hook.** "The history of X" spoken flat at `start:0` is a banned opener shape — the hook still has to name a situation. `references/hooks-and-virality.md`.
|
|
@@ -52,8 +52,13 @@ How to work it:
|
|
|
52
52
|
2. **Match the intensity of the clip to the size of the feeling.** The comedy is the mismatch: a tiny pain + a wildly over-the-top reaction clip, or a small win + a stadium-scale celebration. Choose the pain/win that the existing clip's energy already fits, rather than fighting the footage.
|
|
53
53
|
3. **Keep the meme's grammar** — `me when…` / `POV: you…` / `my clients when…` / `us after…`. Swap the subject to whoever owns the feeling (the customer, the founder, the team), keep the frame.
|
|
54
54
|
4. **Never name the product in the line.** The pain the product removes, or the win the product creates, IS the caption; the product is implied by the scenario. A viewer should want to tag a friend, not click "skip ad". Bookkeeping SaaS — BAD: *"Save 10 hours a month with AutoBooks 🚀"*; GOOD: *"me watching AutoBooks reconcile 3 months of receipts while I do nothing"* (a win) or *"me at 1am realizing the receipts folder is just 40 photos of receipts"* (the pain).
|
|
55
|
-
5. **
|
|
56
|
-
|
|
55
|
+
5. **The line must make sense to a stranger to the offer — the cold-viewer test.** Before you ship a recaption, read it as a person who works in the niche but has NEVER heard of the product, the brand, the feature names, or the category jargon. If they cannot get the joke in one read, the caption failed, no matter how clever it is to the team. Most of a good recaption is niche **experience** (the day, the client, the tool everyone already uses, the shared annoyance); the offer gets a small implied mention at most, and often none.
|
|
56
|
+
- **Write about the niche, not the feature.** A meme about a product feature needs product context to land, so it lands only on people who already bought. A meme about the niche's lived experience lands on everybody in the niche — which is the whole point of a meme ad.
|
|
57
|
+
- BAD (needs product context): *"me after the auto-reconcile v2 sync finally clears"* — "auto-reconcile v2" means nothing to a cold viewer. GOOD: *"me at 1am matching bank lines to receipts by hand"*.
|
|
58
|
+
- **Test:** cover the brand and the feature names. If the caption still reads as a true, funny moment from the audience's week, keep it. If it turns into nonsense, rewrite it around the feeling instead of the feature.
|
|
59
|
+
- **No inside jokes, no invented vocabulary, no setups that only the founder's demo explains.** Slang the niche already uses is fine; slang only the product uses is not.
|
|
60
|
+
6. **One short punchy line**, matching the original's brevity, tone, and comedic timing. If the original was two stacked lines (setup / payoff), keep two — pain on top, reaction beneath.
|
|
61
|
+
7. **Batch it.** One meme clip + a list of ten pains and ten wins is ten videos. Enumerate the audience's pains and wins once, then recaption the same clip (or a small set of clips) across the whole list — this is the highest-output, lowest-cost loop in Vidfarm.
|
|
57
62
|
|
|
58
63
|
If the user insists on explicit ad copy in the recaption, say once that it flattens the joke, then give them the pain/win version alongside what they asked for.
|
|
59
64
|
|
|
@@ -443,6 +448,34 @@ Both `<video>` elements carry `class="clip"` with the **same `src`, `data-start`
|
|
|
443
448
|
|
|
444
449
|
**Editor-surface caveat:** layer-level blur is not an `editor_action` property, so the two-layer version can't be assembled from the editor alone — **bake the plate with ffmpeg and drop it in as one full-canvas `cover` layer**. That's the path for `set_layer_media` / `vidfarm place` work, and it's why the pre-bake is the recommended default rather than the HTML variant.
|
|
445
450
|
|
|
451
|
+
### Orient the cold viewer in the first 3 seconds (before the hook does its job)
|
|
452
|
+
|
|
453
|
+
**The viewer has no context, did not choose this video, and has never heard of the subject.** A video written by somebody who knows the subject starts where *they* are — mid-thought, on the interesting part — and the first three seconds only parse for people who already have the context. This is a different defect from a weak hook: **the hook makes a stranger want to watch; orientation makes watching possible.** A perfect hook on an unoriented open still loses them.
|
|
454
|
+
|
|
455
|
+
By **~3 seconds** a stranger must be able to answer three questions:
|
|
456
|
+
|
|
457
|
+
1. **What am I looking at?** — the **category noun** ("a language app", "a receipt scanner", "a fixtures site"). Not the feature, not the brand promise.
|
|
458
|
+
2. **Who is it for?**
|
|
459
|
+
3. **Why is this on my screen?** — the situation.
|
|
460
|
+
|
|
461
|
+
**The signatures of an unoriented open.** Each is a rebuild of the first beat, not a polish pass:
|
|
462
|
+
|
|
463
|
+
- **A pronoun with no referent** — "it just works", "this changes everything", "here's how they do it". The viewer cannot resolve *it* / *this* / *they*, so the line carries nothing.
|
|
464
|
+
- **Starting at step three** — the process already running, the dashboard already full, the metaphor already mid-payoff. Show the situation that causes step one.
|
|
465
|
+
- **A late subject** — an abstract open whose meaning arrives at 6s has spent the seconds that decide whether anyone reaches 6s.
|
|
466
|
+
- **Insider vocabulary** — a brand-internal noun, a product's own feature name, a category word only customers use, or an **acronym**. Never open on an acronym.
|
|
467
|
+
- **A detail crop** that reads as texture until you know the whole. Establish, then push in.
|
|
468
|
+
|
|
469
|
+
**What replaces it — both channels in the same beat:**
|
|
470
|
+
|
|
471
|
+
- **An easy image.** One subject, large, already in motion, legible at a glance and at thumbnail scale. If a stranger has to *read* the picture to understand it, it is not an orienting image. A relevant die-cut sticker or cutout names the category before a word is read — usually the cheapest orientation there is.
|
|
472
|
+
- **An easy line.** The first spoken sentence is **one clause, ≤12 words, everyday vocabulary, a concrete noun and a verb** — no subordinate clause, no list, no wordplay — and it **names the category**. Say the brand name once, plainly.
|
|
473
|
+
- **The situation, not the label.** "The end of the month, and your receipts are in a shoebox" orients; "expense automation" does not. Same instinct as the hook standard's situations-over-labels.
|
|
474
|
+
|
|
475
|
+
**Orientation costs one sentence, not one beat.** It *replaces* the wind-up ("so today I want to talk about…"); it never precedes it, and it never licenses a logo, a title card, or a fade from black. Density and the banned-openers list are unchanged — you are making the first sentence do its job, not adding an intro.
|
|
476
|
+
|
|
477
|
+
**Test it on the render, never on the script** (the script always looks clear to the person who wrote it): play the **first 3 seconds only** to somebody with no context, then stop. They should say what kind of thing this is and roughly who it is for. "Something about audio" is a fail. The fullest form of this rule, with the format-specific structure around it, is `harnesses/product-explainer.HARNESS.md` → Rule 0 (`vidfarm harness show product-explainer`).
|
|
478
|
+
|
|
446
479
|
### The opening frame is the post's thumbnail
|
|
447
480
|
|
|
448
481
|
**The composition's first frame (t=0) is the still that represents the whole video before anyone presses play** — it's the poster on the approved-post share page, the `/discover` card, the autoplay-off feed preview, and the file/scrubber thumbnail. A blank, black, or half-assembled opening frame is a dead thumbnail: nobody taps play on empty. Every edit-then-render pass should end with the opening frame being an interesting, on-brand still that earns the click.
|
|
@@ -518,7 +551,7 @@ Compositions are authored in HTML, so the single most common way an AI-edited vi
|
|
|
518
551
|
- **Emoji inline in text** (sparingly), **sticker/cut-out overlays** on transparent PNG (`create-overlay`), mock social UI when the format calls for it (iMessage bubbles, a TikTok comment card, a fake DM, a countdown/progress bar) — these are native artifacts of the platform, not web furniture.
|
|
519
552
|
- **Full-bleed footage** with text sitting directly on it.
|
|
520
553
|
|
|
521
|
-
**On devcli there's a checker: `vidfarm qa <dir|composition.html>`.** Free, instant, local-only — a blocklist pass for everything above plus the font regime and safe zone, with a concrete fix per finding. **
|
|
554
|
+
**On devcli there's a checker: `vidfarm qa <dir|composition.html>`.** Free, instant, local-only — a blocklist pass for everything above plus the font regime and safe zone, with a concrete fix per finding. **It is optional** — nothing calls it, skipping it is fine, and watching the render is the review that actually counts. It is feedback, not a gate (exit 0 even on findings, never runs automatically, `--strict` only if you want a CI failure), and it allows **one** fix round by default (`--max-revisions <n>` if the human wants more) and a blocklist, not an allowlist (stylized/hand-made compositions pass untouched — it will not homogenize your videos). Every run — including a clean one — ends with a **`▶ NOW WATCH THE VIDEO`** block, because the check never rendered or saw the video and a green tick is not a review; do those steps before you tell anyone the video is done. No cloud/REST twin: the web copilot enforces this standard by hand. Details in `references/automation-and-local-dev.md` ("`vidfarm qa`").
|
|
522
555
|
|
|
523
556
|
### TikTok-native caption standard (position + font + background) — always adhere
|
|
524
557
|
|
|
@@ -8,8 +8,10 @@ The point of onboarding is to build **durable, reusable context** in My Files, n
|
|
|
8
8
|
2. **Awareness level** (Eugene Schwartz — problem-aware, solution-unaware, …) → `awareness-levels.md`. If it's genuinely unknown after thinking it through, note that ads for **every** level should be made and tested. Use `brainstorm/awareness_stages`.
|
|
9
9
|
3. **Persuasive angles** → `persuasive-angles.md`, via `brainstorm/angles`.
|
|
10
10
|
4. **Hooks** → `ad-hooks.md`, via `brainstorm/hooks`. **Grade what comes back against `references/hooks-and-virality.md`** — the three gates, situation-vs-label, and the unguessable test — instead of shipping the raw list. And never rank a generated batch with the same reasoning that wrote it; the rubric catches defects, it doesn't pick winners.
|
|
11
|
+
4b. **Content ideas** → `content-ideas.md` in their offer folder. Once the offer and awareness stage are known, work the 50-frame angle bank in `references/content-ideas.md` against the topic and save 20+ titled ideas. This is what the director actually posts from between chats, and it is the answer to "what should I post?" for the next month.
|
|
11
12
|
5. **Brand assets & demos** — ask if they have logos/mascots/themes (suggest a `/brand-assets/` folder, e.g. `/brand-assets/logo.png`) or product demos / screen recordings (suggest a `/product-demos/` folder). `browse_files list` / `vidfarm files` first to see what they already uploaded; filenames should be descriptive and every asset worth finding later should get **notes** (`annotate-file` / `browse_files annotate`) so `files --search` works months from now. If they have a recurring character/mascot, set up its `/files/characters/<slug>/` trio now — `<character_id>.json` (e.g. `character_zara.json`) + `character_sprite_card.png` + `character_about.md` (see "Recurring characters are first-class").
|
|
12
13
|
6. **Budget** — ask roughly what they want to spend per video, and map it to the Cost spectrum (free reuse+local render → pennies for cloud render → ~$1 for some AI scenes → $10+ for heavy AI gen). This sets which approach you default to and whether AI **video** generation is on the table (ask permission before using it; image gen is cheap and fine). Budget can also be revisited per editor project.
|
|
14
|
+
- **While you're on money, set the graphics default: IconScout, not AI image generation.** Any icon, sticker, illustration, 3D prop, or Lottie should come from `vidfarm iconscout "<meaning>" --style sticker` — a designer's finished transparent asset on the first try, for a fraction of one AI attempt. **It needs no key and no setup**: vidfarm's own IconScout account serves it, search is free, and free assets download for $0 (a credit line is the only price). Say this out loud during onboarding — it's the single biggest per-video saving a new director can adopt on day one, and it holds in **every** cost mode, not just `minimize`. A director who already pays IconScout can save their own key once (`vidfarm add-provider-key iconscout "<client_id>:<client_secret>"`, or **Settings → Developer**) and then downloads cost them nothing here.
|
|
13
15
|
7. **Recommend & adapt a template** — pair what you now know about the offer against the decomposed template catalog (`GET /discover/feed?q=<offer>`, read each result's `promotions`/`keywords`/`summary`), recommend the best 3-6, then fork and **modify** the winner to fit their offer. Prefer already-decomposed templates so the director skips the ~$0.10 decompose cost.
|
|
14
16
|
|
|
15
17
|
**Assume multiple offers.** My Files is multi-offer (see the My Files section) — namescope every onboarding artifact under the right product/offer/region folder (`acme-skincare/OFFER.md`, not a bare `OFFER.md`) so one brand's context never bleeds into another's. When a director keeps several offers in one flat folder, name the files `OFFER_ACME_SKINCARE.md` / `OFFER_ACME_SUPPLEMENTS.md` instead.
|
|
@@ -379,6 +379,73 @@ Generate spoken narration audio from text. **`use_wallet_credits` defaults true*
|
|
|
379
379
|
- Billing: wallet-billed on the platform ElevenLabs key (default); free/BYOK when `use_wallet_credits: false` and the caller's own key serves it.
|
|
380
380
|
- devcli: `vidfarm tts "…" --style "…"` runs LOCAL-FIRST on your own env key (no job); add `--cloud` for the ElevenLabs platform job (`--own-key` = your key). `vidfarm voices` lists voices.
|
|
381
381
|
|
|
382
|
+
## Primitive: iconscout (designer icons, stickers, illustrations, 3D, Lottie)
|
|
383
|
+
|
|
384
|
+
**The cheap alternative to AI image generation.** Before you call `images/generate` for an
|
|
385
|
+
icon, sticker, illustration, 3D prop, or Lottie animation — don't. A designer already drew
|
|
386
|
+
it. An AI attempt costs cents, needs a prompt loop, and rarely returns a clean transparent
|
|
387
|
+
vector; IconScout returns a finished SVG or transparent PNG on the first try.
|
|
388
|
+
|
|
389
|
+
**Needs no key.** Vidfarm's own IconScout account serves the request. A customer only saves
|
|
390
|
+
their own `iconscout` provider key if they already pay IconScout — then their downloads
|
|
391
|
+
cost nothing here.
|
|
392
|
+
|
|
393
|
+
### Search — free, synchronous, no wallet cost
|
|
394
|
+
|
|
395
|
+
`GET /api/v1/primitives/iconscout/search`
|
|
396
|
+
|
|
397
|
+
| Query | Values |
|
|
398
|
+
| --- | --- |
|
|
399
|
+
| `q` | search text (required) |
|
|
400
|
+
| `asset` | `icon` (default), `illustration`, `3d`, `lottie`, `ai_image` |
|
|
401
|
+
| `price` | `free`, `premium`, `all` (default) |
|
|
402
|
+
| `style` | comma list: `sticker`, `flat`, `line`, `glyph`, `gradient`, `isometric`, `rounded`, `doodle`, `dualtone`, `colored-outline`, `tile` — **`style=sticker` is the STICKER path** |
|
|
403
|
+
| `format` | comma list; filters to assets available in those formats |
|
|
404
|
+
| `sort` | `relevant` (default), `popular`, `latest`, `featured` |
|
|
405
|
+
| `page`, `limit` | `limit` default 30, max 100 |
|
|
406
|
+
|
|
407
|
+
Returns `{ query, asset, page, per_page, total, last_page, count, account, download_usd,
|
|
408
|
+
items: [{ uuid, asset, name, price, is_free, preview_url, source_page, formats }] }`.
|
|
409
|
+
|
|
410
|
+
`account` is `platform` (vidfarm's subscription — premium downloads bill the wallet) or
|
|
411
|
+
`byok` (the customer's own key — nothing bills). **`preview_url` is a thumbnail, not the
|
|
412
|
+
asset** — download before placing anything.
|
|
413
|
+
|
|
414
|
+
### Download — durable URL, billed only on premium+platform
|
|
415
|
+
|
|
416
|
+
`POST /api/v1/primitives/iconscout/download` — body `{ uuid, format?, width?, height? }`
|
|
417
|
+
|
|
418
|
+
Formats by asset: icon `svg`/`png` · illustration `svg`/`png`/`eps` · 3d
|
|
419
|
+
`png`/`gltf`/`glb`/`obj`/`fbx`/`blend` · lottie `json`/`lottie`/`gif`/`mp4` · ai_image
|
|
420
|
+
`png`/`jpg`. `format` defaults to the first valid one. `width`/`height` apply to raster
|
|
421
|
+
formats only; vector formats force 0.
|
|
422
|
+
|
|
423
|
+
The bytes are copied into durable vidfarm storage before IconScout's own signed URL
|
|
424
|
+
expires, so the returned `url` is stable and placeable. Returns `{ url, file_name,
|
|
425
|
+
content_type, size_bytes, format, asset, name, uuid, is_free, source_page, account, billed,
|
|
426
|
+
charged_usd, attribution_required, attribution }`.
|
|
427
|
+
|
|
428
|
+
**Cost.** Free assets: $0, but `attribution_required` is true — honour the returned
|
|
429
|
+
`attribution` credit. Premium assets on the platform account: a few cents on the wallet
|
|
430
|
+
(`ICONSCOUT_DOWNLOAD_USD`). Repeat downloads of the same `uuid` + `format` are idempotent
|
|
431
|
+
and bill once. A premium asset with no active subscription returns **402** with
|
|
432
|
+
`subscription_required: true` — search `price=free` instead.
|
|
433
|
+
|
|
434
|
+
devcli: `vidfarm iconscout "<query>" --style sticker --free`, then
|
|
435
|
+
`vidfarm iconscout get <uuid> --format svg`.
|
|
436
|
+
|
|
437
|
+
Example:
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
curl "$VIDFARM_BASE/api/v1/primitives/iconscout/search?q=pineapple&asset=icon&style=sticker&price=free&limit=5" \
|
|
441
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY"
|
|
442
|
+
|
|
443
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/iconscout/download" \
|
|
444
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
445
|
+
-H "content-type: application/json" \
|
|
446
|
+
-d '{ "uuid": "99d2b880-09f7-11eb-992f-0242ac140003", "format": "svg" }'
|
|
447
|
+
```
|
|
448
|
+
|
|
382
449
|
## Primitive: audio/voices (list ElevenLabs voices)
|
|
383
450
|
|
|
384
451
|
`GET /api/v1/primitives/audio/voices` returns the ElevenLabs voice catalog — `{ scope, default_voice_id, voice_library_url, voices: [{ voice_id, name, category, labels, description, preview_url }] }`. Default scope is vidfarm's platform account; add `?use_wallet_credits=false` to list the voices on the customer's OWN saved ElevenLabs key. Pick a `voice_id` and pass it as `voice` to `/audio/speech`. devcli: `vidfarm voices` (`--own-key` for the user's account).
|
|
@@ -140,12 +140,15 @@ Same ownership rule, resolved through the file directory:
|
|
|
140
140
|
- **Generate on the user's keys** — `vidfarm generate image|video --prompt "…"` (BYOK primitives; `--place <dir>` drops the result straight into a composition).
|
|
141
141
|
- **"Create an avatar" — a talking head, on the user's keys** — `vidfarm avatar "<who they are>" --say "<their line>" [--ref headshot.png] [--aspect-ratio 9:16]` (`POST /api/v1/primitives/videos/create-avatar`). An avatar is always a **video of someone speaking, with lip-synced audio** — never a still portrait, never mute. It's shot on an exact-key-color **greenscreen** plate and keyed off it in the same job, so you get a **transparent presenter** (audio preserved) to composite over any background; `--ref` (headshot or `character_sprite_card.png`) keeps the face on-model across videos, `--local` keys the plate for free with ffmpeg. AI video is the priciest generation here — offer the free `talking-head` raws shelf first when the user is cost-conscious.
|
|
142
142
|
- **Search the free stock catalog** — `vidfarm media search "<meaning>" --type <image|vector|icon|video|bgm|sfx>` (shorthand: `vidfarm media icon "home"`). Returns royalty-free, commercial-safe results, each tagged with its license — honor `attribution` when `attribution_required` is true. Web/API equivalent: `GET /api/v1/primitives/media/search?type=&q=&limit=`.
|
|
143
|
+
- **Buy the graphic instead of generating it — IconScout** — `vidfarm iconscout "<meaning>" --style sticker` (`GET /api/v1/primitives/iconscout/search`), then `vidfarm iconscout get <uuid> --format svg` (`POST /api/v1/primitives/iconscout/download`). Designer-made **icons, STICKERS, illustrations, 3D props and Lottie**. **This is the default path for any of those — reach for it BEFORE `generate image`.** An AI attempt costs cents, needs a prompt loop, and rarely returns a clean transparent vector; IconScout returns a finished SVG or transparent PNG on the first try. **Search is free.** Free assets download for $0 (a credit line is the only price); premium downloads run on vidfarm's own IconScout subscription for a few cents on the wallet. Works with **no key at all** — see below.
|
|
143
144
|
- Never scrape or hotlink arbitrary third-party pages; the catalog above is the sanctioned licensed source, and a capture workflow's own screenshots + the user's brand assets are always fair game.
|
|
144
145
|
|
|
145
146
|
### Free media catalog — sources & keys
|
|
146
147
|
|
|
147
148
|
In **cost-mode `minimize`**, prefer these keyless sources before spending anything: **Openverse** (CC/CC0 music, SFX, images) and **iconify** (icons) need no account or key, so they always resolve at $0. Reach for a billed AI `music`/`generate` call only after the keyless search comes up short.
|
|
148
149
|
|
|
150
|
+
In **every** cost mode, an icon / sticker / illustration / 3D prop / Lottie should come from **IconScout**, not from an image model. `vidfarm iconscout "<meaning>" --free` costs $0 and beats a generated sticker on cleanliness (real transparent vectors, consistent style sets). In `minimize`, stay on `--free`; in `hybrid` and above, a premium download at a few cents still undercuts a single AI attempt.
|
|
151
|
+
|
|
149
152
|
Icons + CC images/audio are **keyless**. Pixabay (stock photos/vectors/video) is
|
|
150
153
|
**BYOK** — each user saves their own free Pixabay key, exactly like their OpenAI /
|
|
151
154
|
Gemini keys, through the same provider-key surface (Settings → Bring your own keys,
|
|
@@ -158,6 +161,7 @@ it never counts as a qualified AI provider and never touches editor chat.
|
|
|
158
161
|
| **iconify** | `icon` (SVG) | keyless — always on |
|
|
159
162
|
| **openverse** | `image` (CC), `bgm`, `sfx` (CC/CC0 audio) | keyless — always on |
|
|
160
163
|
| **pixabay** | `image`, `vector`, `video` (photos/illustrations/stock video) | **BYOK** — the user's own free `pixabay` provider key |
|
|
164
|
+
| **iconscout** | `icon`, sticker, `illustration`, `3d`, `lottie` (designer assets) | **none needed** — runs on vidfarm's account; BYOK optional |
|
|
161
165
|
|
|
162
166
|
**Check for the key before assuming it's missing.** A short `image`/`vector`/`video`
|
|
163
167
|
result (or `providers_used` omitting `pixabay`) usually means no Pixabay key — but it
|
|
@@ -174,3 +178,49 @@ never touches editor chat, so it's exactly what cost-mode `minimize` wants for $
|
|
|
174
178
|
sourcing. Icons, CC images, and bgm/sfx keep working without any key. (An operator may
|
|
175
179
|
still set a platform `PIXABAY_API_KEY` server-side as a fallback for users who haven't
|
|
176
180
|
saved their own, but the default posture is bring-your-own.)
|
|
181
|
+
|
|
182
|
+
### IconScout — the cheap alternative to AI graphics
|
|
183
|
+
|
|
184
|
+
**Rule: never generate an icon, sticker, illustration, 3D prop or Lottie with an image
|
|
185
|
+
model until IconScout has come up empty.** A designer already drew it, it is already a
|
|
186
|
+
clean transparent vector, and it costs a fraction of one AI attempt.
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
vidfarm iconscout "pineapple" --style sticker --free # search (FREE, no wallet cost)
|
|
190
|
+
vidfarm iconscout "rocket" --asset 3d # 3D props
|
|
191
|
+
vidfarm iconscout "loading" --asset lottie # Lottie animations
|
|
192
|
+
vidfarm iconscout get <uuid> --format svg # → durable vidfarm URL
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
REST equivalents:
|
|
196
|
+
- `GET /api/v1/primitives/iconscout/search?q=&asset=&price=&style=&sort=&page=&limit=`
|
|
197
|
+
- `POST /api/v1/primitives/iconscout/download` — body `{ uuid, format?, width?, height? }`
|
|
198
|
+
|
|
199
|
+
| | |
|
|
200
|
+
| --- | --- |
|
|
201
|
+
| `asset` | `icon` (default), `illustration`, `3d`, `lottie`, `ai_image` |
|
|
202
|
+
| `style` | `sticker`, `flat`, `line`, `glyph`, `gradient`, `isometric`, `rounded`, `doodle`, `dualtone`, `colored-outline`, `tile` |
|
|
203
|
+
| `price` | `free`, `premium`, `all` (default) |
|
|
204
|
+
| formats | icon `svg`/`png` · illustration `svg`/`png`/`eps` · 3d `png`/`gltf`/`glb`/`obj`/`fbx`/`blend` · lottie `json`/`lottie`/`gif`/`mp4` |
|
|
205
|
+
|
|
206
|
+
**Cost.** Search is always free. A **free** asset downloads for $0 but requires the
|
|
207
|
+
returned `attribution` credit — honour it. A **premium** asset runs on vidfarm's own
|
|
208
|
+
IconScout subscription and bills a few cents to the wallet (`download_usd` in the search
|
|
209
|
+
response, `charged_usd` on the download). Re-downloading the same asset in the same
|
|
210
|
+
format is idempotent and bills once.
|
|
211
|
+
|
|
212
|
+
**No key needed.** Unlike Pixabay, IconScout works out of the box — vidfarm's account
|
|
213
|
+
serves the request. A user only saves their own key if they already pay IconScout, in
|
|
214
|
+
which case their downloads cost nothing here. That key is the one provider key that packs
|
|
215
|
+
**two** values into one secret:
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
vidfarm add-provider-key iconscout "<client_id>:<client_secret>"
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Create the pair at <https://iconscout.com/api>, or add it under **Settings → Developer**
|
|
222
|
+
(<https://vidfarm.cc/settings/developer>). Like `pixabay`, it is a catalog key, not an AI
|
|
223
|
+
key — it never counts as a qualified AI provider and never touches editor chat.
|
|
224
|
+
|
|
225
|
+
**`preview_url` is a thumbnail, not the asset.** Always `iconscout get` before placing
|
|
226
|
+
something in a composition; the search response's preview is too small to render well.
|